Troubleshooting
Most deployment problems come down to a handful of causes: a build command that doesn’t match the project, an app listening on the wrong port, a missing environment variable, or a database URL pointing at the wrong host. This page lists the symptoms you’ll see in the dashboard and how to fix each one.
Build fails
Section titled “Build fails”The build log stops with an error and the deployment never reaches your running service. The previous version keeps serving traffic, so your site stays up while you fix it.
Wrong build command. The most common cause. Check the exact command under Settings → Build & Deploy and run it locally in a clean checkout — if it fails on your machine, it fails on Runsite too. A missing lockfile, an uncommitted dependency or a script that only exists in your local shell all show up here.
No Dockerfile and the stack wasn’t detected. Auto-detection covers Node, Python, Go and Java. Anything else needs a Dockerfile. If your project is one of those four and still isn’t detected, the project layout is probably non-standard (for example, the app lives in a subdirectory) — add a Dockerfile to make the build explicit.
Python build breaks on a version that used to work. If an unpinned Python build suddenly fails to resolve the interpreter, pin the exact version in your project (for example a .python-version file or runtime.txt) instead of tracking latest. Fresh CPython releases occasionally aren’t available in the build toolchain for a few days after they ship.
Service builds but won’t start
Section titled “Service builds but won’t start”The build succeeds, but the deployment fails with “did not start in time” or the container restarts in a loop. This is almost always one of three things.
The app isn’t listening on the right port. Runsite routes traffic to port 8080 by default, and your app must bind to 0.0.0.0 — not 127.0.0.1 or localhost. An app bound only to localhost is invisible to the platform. Either listen on 0.0.0.0:8080, or change the port under Settings → Build & Deploy to match what your app actually uses.
A required environment variable is missing. If your app reads config from the environment and crashes when a variable is absent, it dies on boot and the container loops. Open the container logs (not the build logs) — the stack trace names the missing variable. Add it under Settings → Environment, then restart.
The health check is failing. If you configured an HTTP health check path (for example /health) and that route returns a non-2xx response, the platform treats the container as unhealthy and never routes traffic to it. Test the path against your app directly. If your health route depends on the database, a database problem will surface here as a start failure.
App can’t connect to its database
Section titled “App can’t connect to its database”The service starts, then errors with connection refused, timeouts or authentication failures against PostgreSQL or Redis.
The app is trying to reach localhost. A managed database is a separate service, not a process inside your container. localhost inside your app points at the app’s own container, where nothing is listening. Set your DATABASE_URL (or Redis URL) to the connection URL shown on the database’s dashboard.
Wrong connection URL for the context. Each managed database exposes two URLs:
| URL | Use it from |
|---|---|
| Internal | Other Runsite services in the same project. Faster, not exposed to the internet. |
| External | Anywhere else — your laptop, CI, a third-party tool. TLS-encrypted. |
From one Runsite service to another, use the internal URL. Using the external URL from inside works but adds latency and routes over the public endpoint.
The database is stopped. A stopped database releases its compute; connections are refused until you start it again. Check its status on the dashboard and click Start.
Data disappears after a restart or redeploy
Section titled “Data disappears after a restart or redeploy”Files you wrote are gone after the service restarts, redeploys or scales.
The container filesystem is ephemeral — anything written to local disk is discarded when the container is replaced, which happens on every restart, redeploy and scale event. This is expected behaviour, not a bug.
Persist state somewhere durable instead:
- Database rows → managed PostgreSQL or Redis.
- Uploaded files and assets → Object Storage.
- State that has to be a local file → attach a persistent disk to the service.
Never rely on a local SQLite file or on-disk uploads without a persistent disk — they won’t survive the next deploy.
Custom domain won’t verify or get a certificate
Section titled “Custom domain won’t verify or get a certificate”You added a custom domain but it’s stuck at pending, or it verified but TLS never went active.
DNS hasn’t propagated or the record is wrong. The dashboard shows the exact record to add — copy the target from there rather than typing it, to avoid typos. Use a CNAME for a subdomain (app.example.com) and an A record for a root/apex domain (example.com). After adding the record, wait for propagation before triggering verification; DNS changes can take anywhere from minutes to a few hours depending on your registrar.
Verification fails with a mismatch. The dashboard shows the expected value and the value it actually resolved. A mismatch usually means an old record is still cached or you edited the wrong DNS zone. Fix the record to match exactly, then retry verification.
Once the records verify, TLS is issued automatically — no extra step on your side. If a domain sits at verified without becoming active for an extended period, the certificate authority is still working through validation; give it time before removing and re-adding the domain.
A deployment is stuck
Section titled “A deployment is stuck”A deployment sits in pending or building and never progresses.
Give it a minute — provisioning and image pulls take a little time. If it’s still stuck well beyond that, trigger a Redeploy from the service header; a fresh deploy almost always clears a one-off hiccup. If redeploys consistently stall for the same service, capture the deployment ID and reach out through support so it can be traced.
Still stuck?
Section titled “Still stuck?”- Read the container logs for a running-but-broken service, and the build logs for a failed build — they name the actual error more often than not.
- Check the service status and its database’s status on the dashboard before assuming a platform fault; a stopped dependency looks like an outage from inside your app.
- If the behaviour still doesn’t match anything here, reach out through support with your service name and the relevant log output.