My container exits immediately after start: how to find out why in thirty secondsSolved

Help & QuestionsNico3 replies

Jump to the accepted answer

NicoMember#1

A container of mine exits right after it starts. docker ps shows nothing, docker logs shows one line, and the service is simply not there.

I am fairly sure the image is fine — it is a project I have run before on another machine. Here is what I have and have not tried.

docker compose up -d
docker compose logs

The log line is the whole story, and it is not helpful: exited with code 1. No stack trace, no message about the port, nothing about the database.

What I have not done: look at the container that actually ran, since up -d removes nothing but logs only shows the last container. I am guessing the issue is the environment: a variable the README tells you to set that I did not set, and the app exits rather than starting with a default.

Is there a better way to find out than guessing?

3 replies

JimmyMember#2

Accepted answer

Four commands, in this order, and you will know within the minute.

1. Get the exit code and the error message. docker inspect on the container gives you both the exit code and, in State.Error, the reason it died:

docker compose ps -a
docker inspect --format '{{.State.ExitCode}} {{.State.Error}}' <container>

Exit code 1 is "the program failed", which tells you nothing. Exit code 2 is usually a shell or a bad argument. Exit code 127 is "command not found", which means the image's entrypoint is not what you think.

2. Run the image with the command you meant. The single most useful habit here: override the entrypoint and start a shell instead.

docker run --rm -it --entrypoint /bin/sh <image> -c 'ls -la /app; cat /app/.env 2>/dev/null'

Now you can see the working directory, whether the files are where the Dockerfile thinks they are, and whether the environment file is baked into the image.

3. Read the logs of the container that ran, not the current one. docker compose logs --no-log-prefix reads the service, but if the container was recreated the old one is gone. docker compose up in the foreground, without -d, shows the output as it happens and stops when the container dies.

4. Check the environment. docker compose config prints the fully resolved configuration — every variable, every volume, every port — after the substitution rules are applied. If a variable is missing, it shows up as empty, which is usually the whole problem.

Your guess is likely right. An app that exits rather than starting with a default is almost always refusing to start without a variable that has no fallback, and docker compose config will show it as empty in one screen.

EdwardMember#3

In reply to Jimmy (#2)

Two more things worth having in the habit.

docker compose up --wait waits for the healthcheck instead of returning immediately, which turns "it exited" into a message naming the failing service. And if the image has a healthcheck, docker inspect --format '{{json .State.Health}}' prints the last three healthcheck outputs, which is often where the real error is — the app logged the reason at startup and the healthcheck captured it.

NicoAuthorMember#4

In reply to Edward (#3)

docker compose config was the answer. It printed DATABASE_URL: empty, exactly as suspected, and the README's own example had it set in a .env file that I had not created in that directory.

For future me, the order is: compose config first, then --entrypoint /bin/sh if the config looks right. Accepting this one, thank you.