You run docker run myimage or docker compose up and the container vanishes instantly. docker ps shows nothing. docker ps -a shows the container with status Exited (0) or Exited (1) seconds ago.

Here’s how to figure out what’s happening and fix it.

Step 1: Check the logs first

Before anything else:

1
docker logs <container_id_or_name>

If the container is already gone, use the container ID from docker ps -a:

1
2
3
docker ps -a
# Copy the container ID, then:
docker logs abc123def456

This will usually tell you exactly what went wrong.

Cause 1: No foreground process (Exit 0)

The most common cause — especially with custom images. Docker containers exit when their main process exits. If your CMD or ENTRYPOINT runs a script that completes immediately, the container exits cleanly with code 0.

Classic example: You wrote a Dockerfile that runs a setup script but forgot to start the actual service:

1
2
3
4
# Broken
FROM ubuntu:22.04
COPY setup.sh /setup.sh
CMD ["/setup.sh"]

The setup script runs, finishes, container exits.

Fix: Make sure your CMD starts a long-running foreground process:

1
2
3
4
# Fixed
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y nginx
CMD ["nginx", "-g", "daemon off;"]

The key is daemon off; — without it, nginx forks to the background and the foreground process exits immediately.

Same issue with other services:

1
2
3
4
5
# Wrong — starts in background, main process exits
CMD ["service", "postgresql", "start"]

# Right — runs in foreground
CMD ["postgres", "-D", "/var/lib/postgresql/data"]

Cause 2: The process crashes on startup (Exit 1 or other non-zero)

If the logs show an error, you have a crashing process. Common culprits:

Missing environment variables:

Error:DATABASE_URLisrequiredbutnotset

Fix: pass the variable with -e or in your compose file:

1
docker run -e DATABASE_URL=postgres://... myimage

Port already in use:

Error:listenEADDRINUSE:::3000

Fix: stop whatever is using the port, or map to a different host port:

1
docker run -p 3001:3000 myimage

File or volume not found:

Error:Cannotfindconfigfile/app/config.yaml

Fix: make sure the file exists in the image or mount it correctly:

1
docker run -v $(pwd)/config.yaml:/app/config.yaml myimage

Cause 3: Shell vs exec form in CMD

There’s a subtle difference between these two CMD forms:

1
2
3
4
5
# Shell form — runs via /bin/sh -c
CMD "npm start"

# Exec form — runs directly
CMD ["npm", "start"]

The shell form can cause issues with signal handling — Docker can’t send SIGTERM to the actual process because it goes to the shell wrapper instead. In some cases this causes unexpected exits.

Always prefer exec form:

1
CMD ["node", "server.js"]

Cause 4: Script exits on error

If your entrypoint is a shell script, set -e at the top causes it to exit on any command that returns non-zero — including things like grep finding no matches, or a curl that fails.

1
2
3
4
5
6
7
#!/bin/bash
set -e  # Any failure = script exits = container exits

# This grep might return 1 if pattern not found
grep "something" /etc/config.txt

exec "$@"

Fix: Either remove set -e or handle the specific commands:

1
2
3
4
5
6
7
#!/bin/bash
set -e

# Safe — won't exit if grep finds nothing
grep "something" /etc/config.txt || true

exec "$@"

Cause 5: Wrong architecture

If you pulled an image built for a different architecture (e.g., arm64 image on amd64 host), it may exit immediately with a cryptic error:

exec/usr/local/bin/docker-entrypoint.sh:execformaterror

Fix: specify the platform when pulling or building:

1
2
3
docker pull --platform linux/amd64 myimage
# or
docker build --platform linux/amd64 -t myimage .

Debugging trick: override the entrypoint

If the container exits before you can see what’s happening, override the entrypoint to drop into a shell:

1
2
3
docker run -it --entrypoint /bin/bash myimage
# or if bash isn't available:
docker run -it --entrypoint /bin/sh myimage

Now you’re inside the container and can run commands manually to see what fails.

If even that exits immediately, the base image probably doesn’t have a shell — use a debug sidecar:

1
docker run -it --entrypoint "" myimage sh

Quick diagnosis checklist

  1. docker logs <id> — read the actual error
  2. Exit code 0 → no foreground process, check your CMD
  3. Exit code 1+ → process crashed, check logs for the specific error
  4. Override entrypoint with bash to debug interactively
  5. Check environment variables, volume mounts, port conflicts
  6. Verify architecture matches your host

The logs almost always have the answer. Start there.