Docker Operations Manual
On this page
Identify the daemon and Compose project first, then distinguish containers, images, volumes, and ports. Examples use myapp. Commands run on the client, but bind-mount paths belong to the daemon host.
| Task | Start here |
|---|---|
| Exit or restart loop | State and logs |
| Publish ports and retain data | Create and map paths |
| Update Compose services | Configuration to runtime |
| Disk use is high | Clean by object |
Identify the daemon, then inspect state
Identify the target daemon
# Read the selected context
Compare the endpoint with docker context ls. CLI --context and DOCKER_HOST / DOCKER_CONTEXT can affect the target; docker info verifies the connection and daemon identity. On failure, check the endpoint, service, and permissions.
Identify the container and exit cause
# List names, state, and ports, including stopped containers
-a includes stopped instances. Replace myapp below with the name found here. Exited means the process ended; Restarting means retries are occurring. Neither identifies the cause.
# Read exit status, OOM flag, and health state
Read ExitCode, OOMKilled, Error, and start/finish timestamps. If Health exists, inspect its Log probe output; use the evidence table below.
# Read up to 100 recent log lines
--tail limits lines and --since limits time. Add --follow for streaming; Ctrl-C ends the viewer. These are stdout/stderr logs via the logging driver, not necessarily application log files.
Check resource use and processes separately
# Take one CPU, memory, and I/O sample
Compare memory usage with its limit. Watch continuously for peaks; a low sample does not rule out an earlier OOM.
# List current processes to check application startup
Process presence does not replace log or application checks.
| Evidence | Interpretation and next step |
|---|---|
| ExitCode / Error | Read application exit logs; nonzero does not imply a Docker bug |
| OOMKilled=true | Check limits, host memory and kernel logs; 137 alone is not proof of OOM |
| unhealthy | Inspect Health.Log; the container may still be running |
| Restarting | Find the exit cause, then RestartPolicy |
Make port and data locations explicit
Prepare a network and persistent volume
This example creates new objects; use unused names or inspect existing objects before reuse. Resolve creation failures before starting the container.
# Create a user-defined application network
Success prints a network ID; containers on this network can communicate by name.
# Create a volume whose lifetime is independent of the container
Success prints its name. This creates storage, not application persistence settings.
Run a container on a loopback-bound port
# Create an instance using the prepared network and volume
-d detaches, --name names the instance, --memory limits memory, and unless-stopped selects restart behavior. A returned ID proves creation, not health; check ps/logs and the port/mount checks below.
This demonstrates creation syntax: nginx does not automatically write application data to /app/data. Configure the real application to use its mounted path. Do not put comments after continuation backslashes. Pin production images to the version or digest required by the project.
Stopping preserves the writable layer. Container removal loses that layer but retains a named volume. Compose down -v also removes this project’s non-external named volume, not its image.
| Object | Meaning |
|---|---|
| 127.0.0.1:8080:80 | Daemon-host loopback 8080 → container 80; peers use service-name:80 on a user-defined network |
| --mount type=bind | Host path mapping; hides existing image content at the mountpoint |
| --mount type=volume | Docker-managed data object with a separate lifetime |
| EXPOSE | Image metadata; does not publish a host port |
Verify port and storage paths
# Check the actual published host address and port
Expect 80/tcp mapped to 127.0.0.1:8080. If absent, inspect creation options.
# Inspect volume identity, destination, and write access
Check Type, Name, Destination, and RW, then confirm the application writes there. Correct mounts do not protect data written elsewhere in the container layer.
# Check network membership, addresses, and aliases
For container-to-container access, check shared networks and the listening address. Inspect DNS configuration separately with docker exec myapp cat /etc/resolv.conf.
# Request the published HTTP port on the daemon host
Inspect connection address, HTTP status, and response body. For a remote context, run this on the daemon host, not the client loopback.
Inspect running files or enter the container
# Copy the running configuration to the client for review
Source is in the container; destination is in the client current directory. Use a new or backed-up destination. Copying does not reload configuration. For interactive diagnosis use docker exec -it myapp sh; leaving that shell does not stop the main process.
Run the HTTP verification curl on the daemon host; with a remote context, local localhost is a different machine. A shell-less image may reject exec sh; use inspect, logs, cp, or suitable debugging tools.
Restart does not apply new configuration
Verify the Compose project
Run in the intended compose.yaml directory. Obtain service name app from config output; it is not necessarily container name myapp. Different directories, -f, or -p may target different objects.
# Validate parsing without printing expanded configuration
Success is normally silent. Fix configuration or environment errors before publishing.
# List services included in this configuration
Compare with existing instances in docker compose ps -a and confirm app is the intended service.
Pull, apply, then verify
# Fetch the configured image without recreating the container
Resolve registry, network, or reference failures before up. For source-built services use docker compose build app instead; pull and build are not mandatory consecutive steps.
# Create or update app and required dependencies from configuration
This may recreate containers and interrupt connections. Restarting existing processes does not apply changes such as container environment settings.
# Check the updated instance and health status
Follow with docker compose logs --tail 100 app and a real request. On failure retain logs, restore the recorded previous image/configuration, and run up again. Image rollback does not undo data migrations.
Run in the intended Compose directory, or specify -f and -p. restart reuses existing containers and does not apply edited environment variables; up -d recreates when necessary. Add --build for locally built code. Full config output may contain expanded credentials.
| Command | Effect |
|---|---|
| docker stop -t 30 myapp | Requests stop using the configured signal, then kills after timeout |
| docker compose down | Removes project containers/networks; named volumes stay by default |
| docker compose down -v | Also removes managed named and attached anonymous volumes; external volumes are excluded |
Locate usage before deleting objects
Choose objects from the usage inventory
# Inspect image, container, volume, and cache usage
Reclaimable is a reference-based estimate, not permission to delete business data. Shared layers prevent simple addition of sizes.
# List stopped containers for individual retention review
Inspect logs, metadata, mounts, and needed writable-layer files before deletion. Being stopped does not make the data disposable.
# Remove a reviewed, no-longer-needed stopped container
This removes the writable layer while named volumes remain. If running, stop and verify first instead of forcing removal. Confirm absence with docker ps -a.
# Identify the volume, labels, and mount location
Also inspect references with docker ps -a --filter volume=app-data and test the backup. Run docker volume rm app-data only when data destruction is intended; unreferenced does not mean worthless.
Separate image cleanup from transfer
# Locate the image reference and size
Use docker image history nginx:stable to inspect layers. Remove a reviewed image with docker image rm IMAGE, selecting IMAGE from the list rather than clearing everything.
# Export the image and layers to a client archive
Choose a path that does not overwrite an existing backup. Transfer the archive before running the next step on the destination client.
# Import the archive into the destination daemon
Check loaded tags and the image ID with docker image inspect nginx:stable. Save/load excludes volumes, runtime settings, and current container writable layers.
Confirm backups and retention needs before targeted rm/rmi/volume rm. Prune determines eligibility from references, not business value; avoid using system prune -a --volumes as a routine fix. Image save/load and container commit do not back up mounted volumes.
Access to docker.sock generally grants powerful host control; do not fix permissions with chmod 666. Inspect the daemon firewall backend and networks; setting "iptables": false does not select the nftables backend.