When install.sh doesn’t finish clean.
install.sh preflight-checks Docker, ports, and DNS before it touches your server, and it’s safe to re-run at any point. Almost every failure we see falls into one of the three buckets below.
This page covers the three most common install.sh failures — missing Docker/Compose, ports 80/443 already in use, and DNS that hasn’t propagated — with the exact commands to diagnose and fix each one, plus how to read the install log and re-run the installer safely without losing your secrets or license.
Docker or Docker Compose not installed
install.sh checks for both docker and the Compose plugin as its very first preflight step. If either is missing, it stops immediately with a clear message rather than partially provisioning anything — it will not attempt to install Docker for you.
API details (Tier 0 / self-hosters) · Check what's actually present▸
docker --version
docker compose versionIf either command errors out, install Docker Engine and the Compose plugin for your distribution first (Docker’s own convenience script, curl -fsSL https://get.docker.com | sh, covers most Ubuntu/Debian boxes), then re-run the WarmHawk install command.
Port 80 or 443 already bound
WarmHawk’s bundled nginx is the only container that publishes 80/443 — everything else stays on an internal-only Docker network. If another process (a previous nginx, Apache, or a different app) already owns those ports, the compose stack will fail to start. Check first:
API details (Tier 0 / self-hosters) · Find what's listening on 443 (Linux)▸
sudo lsof -i :443
sudo lsof -i :80API details (Tier 0 / self-hosters) · No lsof? use netstat or ss▸
sudo netstat -tulpn | grep -E ':80|:443'
sudo ss -tulpn | grep -E ':80|:443'Stop or reconfigure whatever’s bound to those ports (sudo systemctl stop nginx is the usual culprit on a box that had a prior web server), confirm both ports are free, then re-run install.sh. It’s idempotent, so it will pick up where it left off rather than starting over.
DNS hasn’t propagated yet
Certbot needs your domain to resolve to this server before it can issue a certificate. If you just pointed DNS at this box, propagation can take anywhere from a few minutes to a few hours depending on your registrar and TTL. Check whether it’s resolved yet:
API details (Tier 0 / self-hosters) · Check DNS resolution▸
dig +short app.yourcompany.comThat should print this server’s public IP. If it prints nothing, or a different IP, DNS isn’t ready yet. This is expected and install.sh handles it gracefully: nginx comes up HTTP-only, the certbot step degrades instead of crashing the stack, and your dashboard will be reachable over plain HTTP in the meantime. Once dig shows the right IP, recover TLS with:
API details (Tier 0 / self-hosters) · Retry TLS once DNS is ready▸
sudo ./install.sh --retry-tlsSee TLS & observability for what to do if --retry-tls itself fails.
Re-running install.sh safely
install.sh is built to be re-run. It won’t regenerate secrets that already exist in .env, won’t re-request a certificate that’s already valid, and won’t re-prompt for backups or an alert webhook if you already answered those prompts. Just run the same command again:
API details (Tier 0 / self-hosters) · Re-run install▸
curl -fsSL https://warmhawk.com/install | bash -s -- --domain app.yourcompany.comReading the install log
install.sh streams every preflight check, secret generation step, and container startup directly to your terminal. If you need to review it after the fact, redirect it to a file on your next run, or check the containers it already started:
API details (Tier 0 / self-hosters) · Tee the install output to a file▸
curl -fsSL https://warmhawk.com/install | bash -s -- --domain app.yourcompany.com 2>&1 | tee install.logAPI details (Tier 0 / self-hosters) · Check which containers actually started▸
docker compose ps
docker compose logs --tail=100 nginxQuestions
install.sh: questions worth answering up front
Is it safe to just run install.sh again after a failure?+
Yes. install.sh is idempotent — it checks what already exists (containers, secrets in .env, TLS certs) before touching anything, so re-running it after a failed step won’t duplicate secrets or double-provision a certificate.
Where do I actually see why install.sh failed?+
install.sh prints each preflight check and stage to your terminal as it runs. Scroll up to the first line containing "FAILED" or a non-zero exit — that’s almost always the root cause, not the last line printed.
What if DNS hasn’t propagated yet but I want to keep going?+
Let the install finish — a certbot failure degrades to HTTP-only mode rather than crashing the whole stack. Once DNS resolves, run install.sh --retry-tls to pick up TLS without re-running the entire install.
Do I need to re-enter my secrets on a re-run?+
No. install.sh detects an existing .env and reuses the secrets it already generated there instead of prompting again. (This is the free, self-hosted engine installer — it has no license concept at all. If you’re setting up the licensed operator dashboard separately, see that repo’s own install.sh, which does handle a license.)