The main process was never going to stay running
CommonThe command completed and returned, so the container had nothing left to do. Classic versions: a base image whose default command is a shell that immediately reaches end-of-input, a script that ends, or a server launched with a trailing & so the foreground shell exits while the server is still starting.
Confirm
docker inspect <container> --format '{{.State.ExitCode}} {{json .Config.Cmd}} {{json .Config.Entrypoint}}'Exit code 0 alongside a command that is not a long-running server. If Entrypoint is null and Cmd is something like ["bash"], that is the whole answer.
Fix
- Run the actual server in the foreground as the container's main process. A container does not need a process manager; the application is the process.
- If you genuinely need the container to stay up for debugging, run it interactively with
-itso the shell has a terminal to read from. - Remove any trailing
&from the start command. Backgrounding the server means the foreground command finishes, which ends the container.
# Foreground, in exec form CMD ["node", "server.js"] # Or, to keep a shell alive for poking around: docker run -it --entrypoint sh myimage
Exec form also matters for signal handling — see ENTRYPOINT vs CMD.