说实话,没接触过 Docker 之前,我在服务器上装环境着实折腾了不少时间——装完 Java 发现版本不对,装完 MySQL 发现和系统库冲突……
Docker 解决的就是这个问题。简单理解:把你的应用程序连同它需要的所有环境一起打包成一个"容器",搬到哪台机器上都能跑。再也不用担心"在我电脑上明明能跑"这种情况了。
本教程带你从零安装 Docker,把常用命令都过一遍,最后还能亲手跑起来一个真实的多容器项目。
很多新手听到容器会想,这不就是个轻量版虚拟机吗?其实差很多:
| 对比项 | Docker 容器 | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | 共享宿主机内核,很轻 | 要跑一个完整 OS,很重 |
| 性能 | 接近原生 | 有损耗 |
| 镜像大小 | 几十MB 到几百MB | 动辄几个 GB |
虚拟机是在你电脑里装了一台完整的新电脑,而 Docker 只是给你的应用划了个独立的"圈",内核还是共用宿主机的。所以 Docker 启动快、占用少。
一条命令搞定:
curl -fsSL https://get.docker.com | sudo sh
装完之后把当前用户加进 docker 用户组,以后跑 docker 命令就不用每次都 sudo 了:
sudo usermod -aG docker $USER
执行完需要重新登录才生效,直接断开 SSH 重连一下就行。
同样的安装脚本:
curl -fsSL https://get.docker.com | sudo sh
CentOS 如果报 podman 冲突,先把它卸了:
sudo yum remove -y podman buildah
然后再跑一遍安装命令。
如果你的服务器在国内,Docker Hub 下载镜像大概率会超时甚至直接失败。原因是 2024 年 6 月起,GFW 对 docker.com 及相关域名实施了 SNI 阻断——即便 DNS 解析没问题,建立 TLS 连接时也会被防火墙识别域名并直接断开。与此同时,阿里云、腾讯云等国内主流镜像加速站也陆续因"政策监管要求"关闭了对 Docker Hub 的代理。所以现在在国内服务器上不配镜像源,基本是拉不到镜像的:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
EOF
重启 Docker 让配置生效:
sudo systemctl daemon-reload
sudo systemctl restart docker
docker --version
输出类似 Docker version 28.x.x 就说明装好了。
再跑个测试容器确认 Docker 能正常拉镜像和跑容器:
docker run --rm hello-world
看到 Hello from Docker! 就完全没问题了 🎉
sudo systemctl enable docker
查看运行状态:
sudo systemctl status docker
显示 Active: active (running) 就正常。
用 Docker 之前只需要搞清楚三个词:
镜像(Image):可以理解为一个"安装包"。比如你想跑 Nginx,就去下载一个 Nginx 的镜像。镜像是只读的,不能修改。
容器(Container):镜像跑起来以后就变成了容器。一个镜像可以同时跑多个容器,每个容器之间互不影响。就像同一个安装包可以装在多台电脑上。
仓库(Registry):放镜像的地方,Docker Hub 是最大的公开仓库,主流软件基本都有官方镜像。
搜索镜像:
docker search nginx
拉取镜像(默认拉最新版):
docker pull nginx
指定版本:
docker pull nginx:1.27
查看本地已有的镜像:
docker images
删除镜像:
docker rmi nginx
如果镜像还有容器在用,强制删:
docker rmi -f nginx
docker run -d --name my-nginx -p 8080:80 nginx
参数解释:
-d:后台运行,不占终端--name my-nginx:给容器起名,后面管理方便-p 8080:80:把宿主机 8080 端口映射到容器的 80 端口nginx:镜像名跑起来之后访问 http://服务器IP:8080,能看到 Nginx 欢迎页就成了。
# 只看正在运行的
docker ps
# 看全部(包括已停止的)
docker ps -a
docker stop my-nginx # 停止
docker start my-nginx # 启动
docker restart my-nginx # 重启
docker exec -it my-nginx bash
进去之后就像在一个迷你 Linux 里,用 exit 出来。
docker logs my-nginx
# 实时跟踪
docker logs -f my-nginx
docker stop my-nginx
docker rm my-nginx
懒得分两步可以强制删:
docker rm -f my-nginx
容器默认是临时的,删掉就什么都没了。要保存数据,需要把宿主机目录挂进去:
docker run -d --name my-nginx \
-p 8080:80 \
-v /home/www:/usr/share/nginx/html \
nginx
-v /home/www:/usr/share/nginx/html 把宿主机的 /home/www 和容器内的网站目录双向同步。宿主机改了文件容器里立刻生效,反过来也一样。这样容器删了重建,数据还在宿主机上。
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 密码,换成你自己的强密码-e MYSQL_DATABASE=mydb:自动创建 mydb 数据库-v /data/mysql:/var/lib/mysql:数据持久化到宿主机等十几秒 MySQL 初始化完,进去测试一下:
docker exec -it my-mysql mysql -uroot -p
输密码后出现 mysql> 提示符就说明跑起来了,exit 退出。
项目一般不止一个容器,手动一个个 docker run 太繁琐。Docker Compose 用一个 YAML 文件描述所有容器,一条命令全部拉起来。
先确认 Compose 有没有装:
docker compose version
没有的话:
sudo apt install docker-compose-plugin -y
以 WordPress + MySQL 为例:
mkdir -p /home/myapp && cd /home/myapp
nano docker-compose.yml
内容:
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:
Ctrl+O 回车保存,Ctrl+X 退出。
docker compose up -d
两个容器自动创建好、自动配好网络。访问 http://服务器IP 就能看到 WordPress 安装界面。
常用命令:
docker compose ps # 查看状态
docker compose logs -f # 查看日志
docker compose down # 停止并删除容器(数据还在)
docker compose down -v # 停止并删除容器+数据(谨慎!)
端口被占用
sudo lsof -i :8080
看看是谁占了,换个端口映射或者停掉那个进程。
容器启动就退出
docker logs 容器名
看日志,一般是配置写错了、端口冲突或者权限问题。
磁盘占满了
Docker 用久了会堆积废弃镜像和缓存,清理一下:
docker system df # 先看看占了多少
docker system prune -af # 清理所有未使用的资源(注意:不可恢复)
docker run -d --name my-app --memory=512m --cpus=1 nginx
Docker 上手其实不难,核心就三步:拉镜像、跑容器、挂目录。Compose 只是把这些步骤写进文件里统一管理。
学完这篇之后下一步可以试试:
一旦养成习惯,以后部署什么东西一条命令解决,再也不用手动装环境了。
**,防止某个失控的容器把整台机器搞崩
docker run -d --name my-app --memory=512m --cpus=1 nginx
Docker 上手其实不难,核心就三步:拉镜像、跑容器、挂目录。Compose 只是把这些步骤写进文件里统一管理。
学完这篇之后下一步可以试试:
一旦熟练掌握,以后部署什么东西一条命令解决,再也不用手动装环境了。