How to Fix "docker container exits immediately after running"
Quick answer
The issue where a "docker container exits immediately after running" happens when the container's primary process (PID 1) completes its task or terminates. A...
The issue where a "docker container exits immediately after running" happens when the container's primary process (PID 1) completes its task or terminates. A Docker container remains running only as long as its main process defined in CMD or ENTRYPOINT stays active in the foreground. If the command runs in the background, finishes immediately, or crashes due to missing configuration, Docker automatically shuts down the container with exit code 0 or an error code.
The Problem
When executing docker run -d my-container or docker-compose up -d, the container appears to start, but immediately stops when checking status via docker ps:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 my-app:v1 "/bin/sh -c 'nginx'" 5 seconds ago Exited (0) 4 seconds ago my-app-container
If the container crashed due to an execution failure, the status shows a non-zero exit code:
Exited (1) 3 seconds ago
Exited (137) 2 seconds ago
Why It Happens
Docker tracks the process specified in ENTRYPOINT or CMD as process ID 1 (PID 1). Common causes for immediate container exit include:
- Backgrounding Daemons: Commands that daemonize automatically (e.g.,
nginxorapachectl start) fork a background process and exit the main shell process immediately. - Interactive Shells Without TTY: Starting container base images (like
ubuntu,alpine, orbash) without allocated interactive pseudo-TTY terminals. - Application Runtime Exceptions: Uncaught syntax errors, unhandled exceptions, missing environment variables, or bad file permissions inside web apps.
- Out Of Memory (OOM) Kills: Exit code 137 indicates the OS Linux kernel OOM Killer terminated the container process due to memory limits.
The Fix
To fix this, keep your main application process executing in the foreground or allocate interactive terminal flags.
Step 1: Check container logs to identify crash causes
Inspect stdout and stderr logs from the exited container to rule out application errors:
docker logs
Step 2: Run services in the foreground
If your service defaults to running as a background daemon (like Nginx), update your CMD in the Dockerfile or docker-compose.yml to run explicitly in the foreground:
# Incorrect: Nginx defaults to running in background
# CMD ["nginx"]
# Correct: Force Nginx to run in foreground
CMD ["nginx", "-g", "daemon off;"]
For custom shell scripts, ensure the script ends with a long-running foreground process (or use exec):
#!/bin/sh
# Start background services
service cron start
# Keep container alive by executing primary service in foreground
exec node server.js
Step 3: Add interactive TTY flags for base images
If you are spinning up utility containers (like ubuntu or alpine) to debug or run commands interactively, include -i (interactive) and -t (TTY) flags:
docker run -it -d ubuntu bash
In docker-compose.yml, simulate interactive TTY mode using tty: true and stdin_open: true:
version: '3.8'
services:
debug-box:
image: alpine:latest
tty: true
stdin_open: true
Still Not Working?
If your container continues to exit immediately with Exited (137), it was killed by the kernel host OOM killer due to memory exhaustion, or received a SIGKILL signal.
Check system kernel logs on the Linux host to verify if OOM occurred:
sudo dmesg -T | grep -i oom
If OOM killing occurred, increase container memory limits in your docker-compose.yml file:
version: '3.8'
services:
app:
image: my-heavy-app
deploy:
resources:
limits:
memory: 2G