Reference
Troubleshooting
The problems people hit most often, each with the likely cause and the fix. Skim the headings to
find yours. When in doubt, the logs (docker compose logs and an app's Logs tab) almost
always say what's wrong.
Deploy blocked: "missing required variables"
Cause: Your app declares one or more required environment variables in its
app.json, and at least one isn't set yet. Astrodock blocks the deploy on purpose so an
app never starts half-configured.
Fix: Set the missing values, then deploy again. From the CLI:
astrodock set-secret <APP_SLUG> SOME_VAR=value
# repeat for each missing variable, then:
astrodock deploy <APP_SLUG>
Or set them in the dashboard under the app's Env vars tab. The error message lists exactly which names are missing. More on this in Secrets & env vars.
App returns 502 / won't load
Cause: The deploy succeeded but the app's server isn't actually listening where
the platform expects. The most common reason: the server didn't bind the port the platform handed
it. Astrodock injects ASTRODOCK_PORT and your server must listen on it.
Fix: Make sure your server reads that variable rather than hard-coding a port:
const port = process.env.ASTRODOCK_PORT || 3000;
app.listen(port);
Then check the app's Logs tab for a crash or a startup error. A 502 almost always means "nothing is answering behind this subdomain" — a crashed process or the wrong port.
Check the process
The app detail view shows process status. If it's stopped or crash-looping, the logs will say why (a missing dependency, a thrown error on boot, a bad env var).
/api/... returns 404
Cause: For node apps with a frontend, Astrodock serves your static files and routes
only /api/* to your server. If your server's routes aren't under /api,
requests to them never reach it.
Fix: Mount your server routes under /api. For example
/api/login, /api/notes, and so on — not /login at the root.
See the app shapes in App structure & app.json.
Login fails with 403
Cause: The email and password are correct, but the user hasn't been
granted access to that app. The platform's /verify check requires both a valid
password and per-app access; a missing grant returns a 403 ("does not have access to this app").
Fix: In the dashboard, open Users, click the user, and grant them access to the app (by its slug). Then try again. Full walkthrough: Manage users & access.
401 vs 403
A 401 means the credentials were wrong (bad password, unknown or inactive user, or a bad app secret). A 403 means the credentials were fine but access isn't granted. That tells you which thing to fix.
HTTPS / certificate errors
Cause: With ASTRODOCK_TLS_MODE=auto, Caddy tries to get real Let's
Encrypt certificates — which only works if the public internet can reach your server by name. It
usually fails for one of these reasons:
- DNS isn't pointed at your server (no wildcard
*.<base-domain>record yet). - Ports
80and443aren't open to the internet (firewall / security group). - You're on a laptop or LAN with no public domain at all.
Fix: For a real server, point a wildcard DNS record and open ports 80 and 443 — see Custom domains & DNS. For local or LAN use, switch off public certs:
ASTRODOCK_TLS_MODE=internal # Caddy's own CA — browser warns once
# or
ASTRODOCK_TLS_MODE=off # plain HTTP, simplest for local
With internal, the first-visit browser warning is expected — you can accept it. After
changing the mode, restart: docker compose up -d.
Services won't start
Cause: A container failed to come up — often a missing required value (e.g. an
empty ASTRODOCK_PG_PASSWORD, which the compose file refuses to start without) or a port
conflict on 80/443.
Fix: Check what's running and read the logs:
docker compose ps # which services are up / restarting
docker compose logs -f api # the control plane
docker compose logs -f caddy # routing / TLS
docker compose logs -f runner # builds & running apps
Confirm every required value in .env is filled in
(Configuration reference). If something else is already using ports
80 or 443, free it or stop the conflicting service, then docker compose up -d.
Can't reach admin.localhost
Cause: Either the stack isn't up, or you're using a non-localhost base domain
locally. Browsers route any *.localhost name to your own machine automatically — but
only if you actually set ASTRODOCK_BASE_DOMAIN=localhost.
Fix: Confirm the services are up (docker compose ps), that
.env has ASTRODOCK_BASE_DOMAIN=localhost and a local-friendly
ASTRODOCK_TLS_MODE (off is simplest), then open
http://admin.localhost. If you used a different base domain, visit
admin.<that-domain> instead.
"Runner unreachable"
Cause: The control plane (the api service) can't talk to the
runner service — the part that builds and runs your apps. Usually the runner didn't
start, or the shared token doesn't match between the two.
Fix: Check the runner is up and read its log:
docker compose ps
docker compose logs -f runner
Make sure ASTRODOCK_RUNNER_TOKEN is set in .env (both services read the
same value). If you only just set or changed it, restart the stack so both pick it up:
docker compose up -d.
FAQ
I changed .env — why didn't anything happen?
Re-run docker compose up -d. Containers read .env at start, so config
changes need a restart.
How do I rotate the admin password?
Either change it in-app after logging in, or update ASTRODOCK_ADMIN_PASSWORD in
.env and restart.
A user keeps getting bounced even though the password is right.
Check they're active and have been granted access to that app on
the Users page. See Manage users & access.
Do "public" apps use the Users page?
No. Only apps with auth.mode: platform use platform login and the access list. Public
apps handle their own (or no) auth.
Where do I see what's been deployed and who's logged in?
The Activity page combines recent deploys and auth logs. See
Admin UI.
My app worked locally but 502s after deploy.
Almost always the port — bind process.env.ASTRODOCK_PORT, not a fixed number (see above).
Related
- Every config value: Configuration (.env)
- Find your way around the dashboard: Admin UI
- Get the platform running: Install & run