Wikielele. DNS · self-hosted DNS analytics
docs for
back to the dashboard

The installer

Every step install.sh takes, why it takes it, and every flag it accepts.

operatorAssumes a terminal, Docker, and editing a config file.page 5 of 24

Seven steps, each of which handles something that actually goes wrong. It is safe to run twice: every step checks for what it is about to create.

Watching it run#

On a fresh Pi with nothing installed, start to finish. The pauses are real; most of the elapsed time is Docker pulling images.

Against a Pi-hole that is already running, start to finish. Shorter than the AdGuard path by exactly the two steps it no longer has to do: there is no resolver to install and no argument about port 53.

install.sh
install.sh

What each step does#

  1. 01

    Checks the machine

    Architecture, distribution and free disk. It warns rather than stops when the box is unusual, and stops only where carrying on would break something: an unsupported OS, no root and no sudo.
  2. 02

    Docker

    If missing, offers the official get.docker.com script. If present but not running, it says so and stops rather than trying to start a service it did not install. It adds the invoking user to the docker group when run under sudo.
  3. 03

    AdGuard HomePi-hole

    Skipped if one is already answering on 3001 or 3000, or if you passed --agh-url. Otherwise it runs the official image on the host network so it can bind , with work and conf directories bind-mounted under the install directory. If holds it, the installer offers to disable the stub listener.Never installed, only found. It reads /api/info/version and stops here if the answer is v5, because every later step would fail in a less obvious way. Port 53 is not touched: Pi-hole is already bound to it, and the stub-resolver dance was settled when you installed Pi-hole.
  4. 04

    Checks credentials before writing them

    One authenticated GET /control/status.One POST /api/auth to exchange the password for a session, then one GET /api/queries to prove the session can actually read the log — authenticating and being allowed to read are separate failures on Pi-hole, and only the second one matters here. A 401 stops the install with a message about the password rather than leaving you with a container that restarts forever. A connection failure is reported as unreachable, which is a different problem.
  5. 05

    Writes the configuration

    .env at chmod 600 because it holds your admin password, and a compose file with the history bind-mounted to ./data so it is somewhere you can find and copy. Existing files are never overwritten without asking.
  6. 06

    Pulls and starts

    docker compose pull then up -d.
  7. 07

    Waits for evidence

    Polls /api/health for up to eighty seconds, then reads /api/ingest/status and reports how many queries were already ingested, so the install ends with a fact rather than a claim.

Flags#

FlagEffect
--with-adguardInstall AdGuard Home without asking
--dashboard-onlyAssume AdGuard Home exists; never install it
--agh-url URLPoint at an existing instance, e.g. http://192.168.1.10:3000
--agh-user / --agh-passSupply credentials non-interactively
--port NDashboard port, default 3000
--agh-port NAdGuard Home admin port, default 3001
--dir PATHInstall directory, default /opt/elele-dns
--image REFContainer image, for pinning a version or a fork
-y, --yesTake every default, ask nothing
--dry-runPrint every action, change nothing
--uninstallStop and remove the dashboard, keeping data and AdGuard Home
FlagEffect
--pihole-url URLPoint at your Pi-hole, e.g. http://192.168.1.10. Implies --dashboard-only
--pihole-passSupply the app password non-interactively
--dashboard-onlyNever install a resolver. Implied by --pihole-url
--port NDashboard port, default 3000
--dir PATHInstall directory, default /opt/elele-dns
--image REFContainer image, for pinning a version or a fork
-y, --yesTake every default, ask nothing
--dry-runPrint every action, change nothing
--uninstallStop and remove the dashboard, keeping data and Pi-hole

The AdGuard flags (--with-adguard, --agh-url, --agh-port, --agh-user, --agh-pass) still exist and still work; they are simply not part of this path, and passing both sets is refused rather than silently resolved in one direction.

If you would rather not pipe it into a root shell#

Every example so far begins curl … | sudo bash, which asks you to give a URL root on the machine that answers DNS for your whole house. Declining that is a reasonable instinct, and nothing here depends on it. The installer is one self-contained file, so fetching it, reading it, and then running it gets you to exactly the same place:

curl -fsSL https://dns.elele.dev/install.sh -o install.sh
less install.sh          # or open it in whatever you read code in
chmod +x install.sh
sudo ./install.sh

The copy you read is the copy that runs. That file is authored in the application repository as public/install.sh and mirrored out to every place that serves it, so what is published here and what you just reviewed are the same bytes. Add --dry-run if you would rather watch it decide before letting it act.

Common invocations#

Everything, on a fresh box, unattended

sudo ./install.sh --with-adguard --yes

Dashboard only, against an existing resolver

sudo ./install.sh --dashboard-only --agh-url http://192.168.1.10:3000

See what it would do

./install.sh --dry-run --with-adguard

Move to the newest release

sudo /opt/elele-dns/install.sh --update

Remove the dashboard, keep everything else

sudo ./install.sh --uninstall

Against your Pi-hole, unattended

sudo ./install.sh --pihole-url http://192.168.1.10 --yes

Pi-hole on a non-standard port

sudo ./install.sh --pihole-url http://192.168.1.10:8080

See what it would do

./install.sh --dry-run --pihole-url http://192.168.1.10

Move to the newest release

sudo /opt/elele-dns/install.sh --update

Remove the dashboard, keep everything else

sudo ./install.sh --uninstall

If it fails#

Every run writes a log to /tmp/elele-install-TIMESTAMP.log and the error trap prints the path and the failing line number. Most failures are one of four things, all covered in Troubleshooting: port 53 occupied, wrong AdGuard Home credentialsa Pi-hole still on v5, a password that authenticates but cannot read the log, all the session seats taken, Docker not running, or the image failing to pull on a slow connection.

See also