Objective
Diagnose a Docker Engine container that repeatedly exits on a Linux host, preserve its data and evidence, then correct the cause before restoring automatic restarts. Compose and orchestrated services require their own deployment controls.
- Keep persistent volumes and the original deployment configuration.
- Do not use repeated restarts as the only diagnostic action.
- Separate observation commands from service-changing commands, and retain the previous restart policy.
Prerequisites
- Exact container identity, incident time and Docker Engine access on the affected Linux host.
- Original Compose or deployment configuration and knowledge of persistent mounts and dependencies.
- Permission for the service interruption and a known recovery option for the workload.
- Protected storage for diagnostic exports; getent, nc and kernel-log access depend on the host.
Step-by-step procedure
Establish the baseline and scope
Record the affected container, image, incident time and recent deployment changes. Save its current state and restart policy before stopping it. Compare with a known working deployment where available.
- The identity or workload, timing and intended result are recorded.
Capture state and deployment configuration
Identify the exact container and the deployment source before changing it. Capture state, image reference, restart count, restart policy and mounted-data locations; compare them with the intended Compose or deployment configuration. Environment inspection may reveal credentials, so restrict saved output and redact values before sharing it. Keep persistent volumes while investigating.
- The failing container, deployment source and persistent-data locations are known; configuration evidence is retained safely.
Read the first relevant failure
Use timestamps and a bounded log window around the first observed failure. Follow the earliest application error rather than only the final restart message. If the application writes to a mounted file or another logging destination, collect the relevant output there as well; empty docker logs output does not prove that startup was healthy.
- The first useful error and its timestamp are captured, or the missing logging path is identified.
Interpret the exit state
Inspect ExitCode, Error, StartedAt and FinishedAt with the application logs and deployment events. Exit code 137 indicates a SIGKILL result and is not proof of an out-of-memory event on its own; correlate it with OOMKilled and host evidence. Check the entrypoint, command, permissions and required configuration when the application exits immediately.
- The exit status is linked to supporting evidence instead of being treated as a complete diagnosis.
Correlate memory and storage evidence
Check OOMKilled, host kernel messages and the configured memory limit at the incident time. Also verify free space for application data and logs. A memory limit increase should follow an assessment of workload and host capacity; it may only postpone a leak. An empty or inaccessible kernel log leaves the memory cause unconfirmed.
- Memory or storage pressure is supported by incident-time evidence, or explicitly remains unconfirmed.
Test the required dependency path
Check the configured DNS name, destination port, certificate and application credentials for dependencies such as a database or API. A successful host-side DNS or TCP check does not establish that the container’s network and application authentication work. Repeat the relevant test from the intended network context where possible without modifying persistent data.
- The evidence distinguishes name resolution, connectivity and application-level access to the dependency.
Pause the loop deliberately
Record the existing policy and arrange the allowed interruption before stopping the affected container. A temporary no-restart policy can help observe one attempt; it does not fix the application fault. For Compose or an orchestrator, use its deployment source and lifecycle controls rather than relying on a manual change that the next deployment will replace.
- The loop is controlled for investigation, and the previous policy and persistent data remain available.
Apply the fix and validate one restart
Correct the demonstrated cause in the versioned deployment configuration, image or secret source. Start only the intended workload and observe its first attempt and logs. Once the application test succeeds, restore the approved restart policy and monitor status and RestartCount over the agreed observation period. A running process alone does not establish that the service works.
- The application works, restart count is stable and the correction survives the next intended deployment.
Validate the complete service
Complete the validation checklist below and retain the observed results. Record unresolved checks instead of treating a command success as a complete service recovery.
- The outcome is checked against the service-specific criteria below.
Command examples and their effects
These examples target Docker Engine on Linux, not a Swarm service. Replace the quoted CONTAINER_NAME, DEPENDENCY_NAME and PORT_NUMBER tokens with the intended values. Run observations first; policy updates, stop and start change the service. Preserve the previous policy and use the deployment source for Compose-managed workloads. Do not share raw environment exports containing secrets.
List container status
docker ps -a --no-trunc
Observe the selected container state
docker inspect 'CONTAINER_NAME' --format '{{json .State}}'
Record the current restart policy
docker inspect 'CONTAINER_NAME' --format '{{json .HostConfig.RestartPolicy}}'
Read timestamped recent logs
docker logs --timestamps --tail 200 'CONTAINER_NAME'
Read the incident log window
docker logs --since 30m 'CONTAINER_NAME'
Service-changing action: temporarily disable automatic restarts
docker update --restart=no 'CONTAINER_NAME'
Service-changing action: stop the affected container
docker stop 'CONTAINER_NAME'
Observe OOM, exit code and error fields
docker inspect 'CONTAINER_NAME' --format 'OOM={{.State.OOMKilled}} Exit={{.State.ExitCode}} Error={{.State.Error}}'
Read relevant Linux kernel messages where permitted
dmesg -T | grep -i -E 'oom|killed process' | tail -30
Check filesystem capacity
df -h
Observe persistent mounts
docker inspect 'CONTAINER_NAME' --format '{{json .Mounts}}'
Sensitive output: inspect environment locally and redact secrets
docker inspect 'CONTAINER_NAME' --format '{{json .Config.Env}}'
Check dependency name resolution from the host
getent hosts 'DEPENDENCY_NAME'
Check dependency TCP reachability from the host
nc -vz 'DEPENDENCY_NAME' 'PORT_NUMBER'
Service-changing action: start one attempt after the targeted fix
docker start 'CONTAINER_NAME'
Follow output; use Ctrl+C to stop following logs
docker logs -f 'CONTAINER_NAME'
Service-changing example only: use unless-stopped only if it is the approved policy
docker update --restart=unless-stopped 'CONTAINER_NAME'
Observe restart count and status
docker inspect 'CONTAINER_NAME' --format 'Restarts={{.RestartCount}} Status={{.State.Status}}'
Validation
The procedure is validated when:
- The intended application workflow succeeds and RestartCount stays stable during the observation period.
- The initial fault and the corrective change have supporting evidence.
- The fix is present in the deployment source, with required data, dependencies and resources available.
Rollback
- Return to the last known working image or deployment configuration when the targeted fix fails.
- Keep the persistent volumes; do not prune or delete them to recreate the container.
- Restore the recorded restart policy only when doing so will not recreate an uncontrolled loop; otherwise keep the affected workload stopped pending recovery.
Troubleshooting / common errors
- Exit 137 without matching OOM evidence: check for other SIGKILL causes and deployment actions.
- No container logs: inspect the logging configuration, entrypoint and application log location.
- Host checks succeed but the container fails: compare network context, mounts and deployment environment.
- RestartCount still rises: verify that the changed container and deployed configuration are the ones serving the workload.
Official references
Keep the selected scope, evidence and outcome with the procedure record. Use the official references for the installed product and version.