The silent page awaits the waking dawn.
docker pull only downloads images; running containers must be recreated to use them. The guide emphasizes that containers are ephemeral; important data should be stored in volumes or host directories, not within containers. It warns against exposing all ports to the public, explains how to manage Docker log files to prevent disk space issues, and provides a safe update workflow. The text highlights potentially destructive commands like docker system prune -a --volumes and advises caution before executing them.
Docker commands aren't really that many — the real pain is keeping them straight.
Like pulling a new image, only to find your website is still running the old version. Or deleting a container and recreating it, only to realize your database is gone too. Or waking up to a full server disk, only to trace it back to Docker log files.
None of these issues are complicated, but they crop up every now and then. And when they do, you end up digging through the docs and rechecking parameters you've looked up before.
So I've put together a collection of the Docker commands I actually reach for when deploying and maintaining servers.
This isn't a complete Docker reference. I haven't included every parameter you'll use once a year. Just the most common day-to-day operations, plus a few commands that can cost you your data.
Dockerfile 用来构建镜像,镜像用来创建容器。容器负责运行程序,但容器本身不适合保存重要数据,需要长期保留的内容应该放在数据卷或宿主机目录中。多个容器之间,则通过 Docker 网络互相通信。
Before we start, let's sort out the key Docker concepts
Docker commands are easy to mix up, mainly because images, containers, volumes, and networks all show up at once.
Here's roughly how they relate to each other:
1. First, check what Docker's doing right now
When something's off with Docker, I don't restart services right away — I check the container status first.
This command only shows running containers.
To also see stopped containers, add -a.
The key fields in the output are:
Some containers exit right after starting. In that case, running docker ps alone won't show them — you need:
To check how much disk space Docker is using:
For a more detailed breakdown of images, containers, and volumes:
These two commands are especially useful when a server disk suddenly fills up.
If you see /var/lib/docker is huge, don't just dive in and delete files. Docker manages this directory itself, and manually removing stuff inside it can easily break your whole Docker setup.
2. Checking container logs
When a container fails to start, the first thing to do isn't to enter the container — it's to check the logs.
For example:
If the log is too long, just look at the last 100 lines.
Follow new logs in real time:
Here's the combo I use most often:
It shows the last 200 lines first, then continues streaming new log output.
View logs from the last 30 minutes:
If a container keeps restarting, open two terminals at the same time.
First terminal — watch the status:
Second terminal — follow the logs:
Generally speaking, missing environment variables, config file errors, insufficient directory permissions, and database connection failures — they all leave clues in the logs.
3. Starting, stopping, and restarting containers
Start an existing container:
Stop a container:
Restart a container:
For example:
docker stop first tells the program inside the container to shut down gracefully.
For services that write data, like PostgreSQL, MySQL, and Redis, you should use docker stop first — give the program time to save its data and close files.
Only reach for this if the container is completely unresponsive:
docker kill terminates the container process directly — it's more forceful than docker stop.
It can fix a hung container, but it shouldn't be your everyday restart method.
4. Getting inside a container
To enter a container, use:
For example:
But not every image has Bash installed.
Lightweight images like Alpine usually only have sh:
To enter as root:
You can also run a single command without entering an interactive shell.
If the command includes cd, pipes, or multiple operations, wrap it with sh -c.
This usually won't work:
Because cd isn't a standalone executable — it's a shell built-in.
Going inside a container is good for troubleshooting, but not for making permanent changes.
For instance, you edit /etc/nginx/nginx.conf from inside a container — the next time that container is recreated, those changes will likely be gone.
Config that needs to stick around should go in the Dockerfile or be mounted from the host.
5. Basic image operations
List local images:
You can also write:
Pull an image:
Specify a version:
In production, always pin a specific version instead of just using:
latest is just a label — it doesn't always point to the same version.
The latest you pull today and the latest you pull months from now could be completely different. It makes updates convenient, but rolling back becomes a problem.
Delete an image:
For example:
If an image is still being used by a container, Docker will refuse to delete it.
Even if that container is stopped, it may still reference the image. Check first with:
6. Why the app is still on the old version after pulling a new image
This is a common point of confusion with Docker.
Running:
only downloads the new image to the server.
Running containers won't automatically switch to the new image — because the image used when the container was created is already set.
For Docker Compose projects, you typically need to run:
The first command pulls the image, the second recreates containers using the new image.
Just running:
usually doesn't help.
restart only restarts the original container — it doesn't swap the image or apply any new port mappings, volume mounts, or environment variables.
So after modifying compose.yaml, run:
If you suspect the container wasn't recreated properly, use:
But in most cases, a simple docker compose up -d is sufficient.
7. Common Docker Compose commands
Newer Docker versions generally use:
instead of the older:
Start the project:
-d runs it in the background.
Check the project status:
View logs:
Follow logs in real time:
View logs for a specific service:
Stop containers in the project without deleting them:
Restart:
Stop and delete project containers:
Rebuild images and start:
Pull remote images:
Check the Compose file for format errors:
To just validate without outputting the full config:
I usually run this before updating a project:
If there's no output, it usually means the config syntax is fine.
8. A safer update workflow
Say your project is at:
First, enter the project directory:
Check the config:
Check the current running status:
Pull the new image:
Recreate the containers:
Check the updated status:
Finally, check the logs:
If everything's running normally, then consider cleaning up old images.
Don't put cleanup at the start of your update workflow.
Make sure the new version is running properly first, then delete old images. That way, if something goes wrong, you can still fall back to the old version.
9. Where is your data actually stored?
Docker containers themselves aren't a great place for important data.
When a container is deleted, its writable layer is deleted too.
Data that needs to stick around is usually kept in one of two places:
List volumes:
Inspect a specific volume:
For example:
A typical volume setup in Compose:
This way, even if the container is deleted, the postgres-data volume usually stays around.
If you're using a host directory, you'd write:
Left side is the host directory:
Right side is the container directory:
The most common issue here is getting the path wrong.
Say a container originally ships with config files in /app/config, but you mount an empty directory:
Then the container's original /app/config gets overridden by the empty host directory.
When the app starts, it'll act as if the config files suddenly disappeared.
So before mounting anything, make sure the host directory exists and contains the right files.
10. How containers connect to each other
Services in the same Compose project can reach each other using their service names.
For example:
When your app connects to the database, the address should be:
Don't hardcode the container IP as:
A container's IP can change when it's recreated, but the service name usually won't.
List Docker networks:
Inspect a network's details:
Create a custom network:
Add an existing container to a network:
If two containers can't reach each other, first check that they're on the same Docker network.
11. Don't expose every port to the public internet
This config:
Typically maps port 8080 on the host to port 80 in the container.
By default, it may listen on all network interfaces:
That means any external device can reach that port if the server's firewall allows it.
If the service only needs to be accessed by Nginx or OpenResty on the same host, bind it to localhost:
Now the external network can't reach it directly — only local connections on the host can.
Databases and Redis generally don't need direct public exposure either.
Apps in the same Compose network can access them directly:
You don't need to configure ports for every internal service.
12. Checking resource usage
View real-time CPU and memory usage for all containers:
Output just once:
Inspect a specific container:
View processes inside a container:
If a container exits abruptly, check whether it was killed for running out of memory.
If you see:
it means the container experienced an OOM Kill — terminated by the kernel due to insufficient memory.
You can also check the exit code:
Check the restart count:
These details are really helpful when troubleshooting a container that keeps restarting.
13. Why Docker logs fill up your disk
Docker may use json-file by default to store container logs.
Without log rotation configured, log files keep growing indefinitely.
Modify:
Add:
This means:
After making the change, restart Docker:
Note that the new log config usually only applies to containers created afterward.
Existing containers may need to be recreated.
You can also configure this per service in Compose:
If your server disk keeps mysteriously shrinking, besides checking databases and uploads, take a look at Docker logs too.
14. Cleaning up Docker space
Remove stopped containers:
Remove dangling images:
Remove unused networks:
Remove unused volumes:
Comprehensive cleanup:
All these commands will ask for confirmation.
But don't assume 'unused' means it has no value.
For example, after a database container is deleted, its volume might not be attached to any container. Docker tags it as unused — but the database files are still in there.
Be extra careful before running these commands:
Especially:
The plain version:
usually only removes containers and networks.
Adding -v also deletes the project's volumes. If PostgreSQL, MySQL, or uploaded files live in those volumes, they'll be gone too.
At least check before cleaning:
Don't treat docker system prune -a --volumes like a routine cleanup command.
It's more of an 'I've confirmed none of this is needed' command.
15. What to do about directory permission errors
After mounting a host directory into a container, your app might complain:
First, check the host directory permissions:
Check the file's UID and GID:
Then check what user the app inside the container runs as:
If the container uses UID 1000, GID 1000, adjust the host directory owner accordingly:
A lot of people, when faced with permission issues, just run:
This might temporarily fix things, but it's usually not the right approach.
777 grants read, write, and execute permissions to everyone, and it masks the real UID, GID, and ownership issues.
It's safer to first find out what user the container runs as, then set the right permissions.
16. A few easily confused points
docker pull doesn't update running containers
It only downloads the image.
To update a Compose project, you also need:
docker restart doesn't apply new configuration
It just restarts the existing container.
After editing the Compose file, use:
Deleting a container doesn't always delete its volume
The plain version:
usually doesn't delete named volumes.
But:
may delete anonymous volumes used by the container.
Manually editing files inside a container is unreliable
Changes can vanish when the container is recreated.
Config that needs to persist should go in the Dockerfile, Compose file, or a host-mounted directory.
Don't rely on container IPs
Use container names or Compose service names to connect.
Don't map every port to the public internet
Internal services should stay within the Docker network whenever possible.
17. My everyday go-to commands
List containers:
View logs:
Enter a container:
Check resources:
Check disk usage:
Validate Compose config:
Update a Compose project:
Check the updated status:
These commands cover most of the daily deployment, update, and troubleshooting needs.
Final thoughts
The thing that trips people up most about Docker is that a container looks a lot like a small server.
But a container isn't a virtual machine.
It's more like a runtime environment that can be deleted, recreated, and replaced at any time. The stuff that really matters shouldn't live only inside a container.
Put your app in the image, write config into the Compose file or a mounted directory, and store data in volumes or independent storage. If something goes wrong with the container, just recreate it.
Once you get that, a lot of Docker commands stop feeling like they need to be memorized.
One last reminder — when you see these parameters, pause before running them:
They're not necessarily dangerous, but they usually mean deleting data, forcing an operation, or expanding container permissions.
Especially this one:
Don't run it until you've confirmed your data is backed up.