To be honest, before I encountered Docker, I spent a considerable amount of time struggling with environment setup on servers—installing Java only to find the version was wrong, installing MySQL only to discover conflicts with system libraries...
Docker solves this problem. Simply put: it packages your application along with all its required environment into a "container," which can run on any machine. You'll never have to worry about the "it works on my machine" scenario again.
This tutorial will guide you from installing Docker from scratch, covering all the essential commands, to finally running a real multi-container project yourself.
Many beginners hear about containers and think, isn't this just a lightweight virtual machine? Actually, they are quite different:
| Comparison Point | Docker Container | Virtual Machine |
|---|---|---|
| Startup Speed | Seconds | Minutes |
| Resource Usage | Shares host kernel, very light | Runs a full OS, very heavy |
| Performance | Near-native | Has overhead |
| Image Size | Tens to hundreds of MB | Often several GB |
A virtual machine installs a complete new computer inside your computer, while Docker just creates an isolated "sandbox" for your application, sharing the host's kernel. That's why Docker starts faster and uses fewer resources.
One command does it all:
curl -fsSL https://get.docker.com | sudo sh
After installation, add the current user to the docker group so you don't need sudo for every docker command:
sudo usermod -aG docker $USER
You need to log out and back in for this to take effect; simply disconnect and reconnect your SSH session.
Same installation script:
curl -fsSL https://get.docker.com | sudo sh
If CentOS reports a podman conflict, remove it first:
sudo yum remove -y podman buildah
Then run the installation command again.
If your server is in China, downloading images from Docker Hub will likely time out or fail completely. The reason is that since June 2024, the GFW has implemented SNI blocking on docker.com and related domains—even if DNS resolution works, the TLS connection is identified by the firewall and disconnected. At the same time, major domestic mirror acceleration services like Alibaba Cloud and Tencent Cloud have also gradually shut down their Docker Hub proxies due to "policy and regulatory requirements." So now, without configuring a mirror source, it's basically impossible to pull images on servers in China:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
EOF
Restart Docker for the configuration to take effect:
sudo systemctl daemon-reload
sudo systemctl restart docker
docker --version
Output similar to Docker version 28.x.x means it's installed correctly.
Run a test container to confirm Docker can pull images and run containers normally:
docker run --rm hello-world
If you see Hello from Docker!, everything is working perfectly 🎉
sudo systemctl enable docker
Check the running status:
sudo systemctl status docker
It's normal if it shows Active: active (running).
Before using Docker, you just need to understand three terms:
Image: Think of it as an "installation package." For example, if you want to run Nginx, you download an Nginx image. Images are read-only and cannot be modified.
Container: When an image is run, it becomes a container. One image can run multiple containers simultaneously, each independent of the others. It's like installing the same software package on multiple computers.
Registry: A place where images are stored. Docker Hub is the largest public registry, hosting official images for most mainstream software.
Search for an image:
docker search nginx
Pull an image (defaults to the latest version):
docker pull nginx
Specify a version:
docker pull nginx:1.27
List locally available images:
docker images
Delete an image:
docker rmi nginx
If the image is still being used by a container, force delete it:
docker rmi -f nginx
docker run -d --name my-nginx -p 8080:80 nginx
Parameter explanation:
-d: Run in the background, freeing up the terminal.--name my-nginx: Give the container a name for easier management later.-p 8080:80: Map the host's port 8080 to the container's port 80.nginx: Image name.After running, visit http://server-ip:8080. If you see the Nginx welcome page, you're good.
# Only see running containers
docker ps
# See all (including stopped ones)
docker ps -a
docker stop my-nginx # Stop
docker start my-nginx # Start
docker restart my-nginx # Restart
docker exec -it my-nginx bash
Once inside, it's like being in a mini Linux system. Use exit to leave.
docker logs my-nginx
# Real-time tailing
docker logs -f my-nginx
docker stop my-nginx
docker rm my-nginx
If you're too lazy for two steps, force delete:
docker rm -f my-nginx
Containers are temporary by default; deleting them erases everything. To save data, you need to mount a host directory into the container:
docker run -d --name my-nginx \
-p 8080:80 \
-v /home/www:/usr/share/nginx/html \
nginx
-v /home/www:/usr/share/nginx/html synchronizes the host's /home/www directory with the container's web directory bidirectionally. Changes on the host take effect immediately in the container, and vice versa. This way, even if the container is deleted and recreated, the data remains on the host.
docker run -d --name my-mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=YourStrongPassword123 \
-e MYSQL_DATABASE=mydb \
-v /data/mysql:/var/lib/mysql \
mysql:8.0
-e MYSQL_ROOT_PASSWORD: Root password. Replace with your own strong password.-e MYSQL_DATABASE=mydb: Automatically creates the mydb database.-v /data/mysql:/var/lib/mysql: Persists data to the host machine.Wait a dozen seconds for MySQL to initialize, then test it:
docker exec -it my-mysql mysql -uroot -p
After entering the password, if you see the mysql> prompt, it's running. Type exit to leave.
Projects usually involve more than one container, and manually running docker run for each is tedious. Docker Compose uses a YAML file to describe all containers and can start them all with a single command.
First, check if Compose is installed:
docker compose version
If not:
sudo apt install docker-compose-plugin -y
Take WordPress + MySQL as an example:
mkdir -p /home/myapp && cd /home/myapp
nano docker-compose.yml
Content:
services:
wordpress:
image: wordpress:latest
ports:
- "80:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: wp_password
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
depends_on:
- db
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wp_user
MYSQL_PASSWORD: wp_password
volumes:
- db_data:/var/lib/mysql
volumes:
wp_data:
db_data:
Press Ctrl+O then Enter to save, and Ctrl+X to exit.
docker compose up -d
Both containers are automatically created and configured with networking. Visit http://server-ip to see the WordPress installation page.
Common commands:
docker compose ps # Check status
docker compose logs -f # View logs
docker compose down # Stop and remove containers (data remains)
docker compose down -v # Stop and remove containers + data (Use with caution!)
Port Already in Use
sudo lsof -i :8080
See what's using it, then either change the mapped port or stop that process.
Container Exits Immediately After Starting
docker logs container_name
Check the logs. It's usually due to incorrect configuration, port conflicts, or permission issues.
Disk Full
Docker accumulates unused images and cache over time. Clean it up:
docker system df # First, see how much is used
docker system prune -af # Clean all unused resources (Warning: Irreversible)
docker run -d --name my-app --memory=512m --cpus=1 nginx
docker-compose.yml files to environment variables.Getting started with Docker isn't actually difficult. The core process is just three steps: pull an image, run a container, mount a directory. Compose simply writes these steps into a file for unified management.
After finishing this tutorial, your next steps could be:
Once you get into the habit, you can deploy almost anything with a single command, never having to manually set up environments again.
**,防止某个失控的容器把整台机器搞崩
docker run -d --name my-app --memory=512m --cpus=1 nginx
Getting started with Docker isn't actually difficult. The core process is just three steps: pull an image, run a container, mount a directory. Compose simply writes these steps into a file for unified management.
After finishing this tutorial, your next steps could be:
Once mastered, you can deploy almost anything with a single command, never having to manually set up environments again.