写在前面
Docker 是目前最主流的容器引擎:把应用和它的运行环境打包成一个「镜像」,在任何装了 Docker 的机器上都能以「容器」的形式原样跑起来,彻底告别「我这儿能跑、服务器上跑不起来」的经典难题。
Docker Compose 则是它的编排搭档:用一个 docker-compose.yml 文件把多个容器(比如网站 + 数据库 + 缓存)的配置一次性写清楚,一条命令全部拉起、一条命令全部停掉,不用再手敲一长串 docker run 参数。
这篇文章以 Debian 为主线(Ubuntu 步骤基本一致,文末附 RHEL 系的差异),把从安装、配置、实战到卸载的完整流程走一遍。所有命令都可以直接复制执行,代码块右上角有复制按钮。
准备条件
开始之前,先确认你的机器满足下面几个条件:
- 64 位 Linux 系统:Debian 11/12/13、Ubuntu 20.04/22.04/24.04,或 CentOS/Rocky/AlmaLinux 9 等
- 内核版本 3.10 以上(用
uname -r查看,现代发行版都满足) - 有
root权限,或当前账号可以用sudo - 服务器能正常访问外网(要从官方仓库下载软件包)
查看自己的系统版本:
cat /etc/os-releaseuname -r先卸载旧版本(装过才需要)
如果这台机器以前用系统自带源装过老版本的 Docker,先卸干净,避免和新版本冲突。没装过可以直接跳到下一节。
Debian / Ubuntu:
sudo apt-get remove -y docker docker-engine docker.io containerd runc注意:这一步只删程序本体,/var/lib/docker 里的镜像和容器数据不会被删。全新安装的机器执行它只会提示「未安装」,无副作用,放心执行。
方式一:官方仓库安装(推荐)
这是官方推荐、也是生产环境最稳妥的装法:把 Docker 官方软件源加进系统,以后升级直接跟着 apt update 一起走。
第 1 步:安装依赖并导入官方 GPG 密钥
sudo apt-get updatesudo apt-get install -y ca-certificates curlsudo install -m 0755 -d /etc/apt/keyringssudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.ascsudo chmod a+r /etc/apt/keyrings/docker.asc说明一下每一步在干什么:
ca-certificates和curl是下载 HTTPS 文件的基础工具/etc/apt/keyrings是现在 Debian/Ubuntu 存放第三方仓库签名密钥的标准目录- 下载下来的
docker.asc是 Docker 官方的签名公钥,系统靠它验证软件包是不是官方发布的、有没有被篡改
如果你的系统是 Ubuntu,把上面地址里的
debian换成ubuntu即可,下同。
第 2 步:添加 Docker 官方软件源
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullsudo apt-get update这条命令做了两件事:自动识别你的 CPU 架构(amd64 / arm64)和系统版本代号(如 bookworm、trixie),拼出一条仓库配置写进 /etc/apt/sources.list.d/docker.list;然后刷新软件包列表。刷新时能看到多出来一个 download.docker.com 的源,就说明添加成功了。
第 3 步:安装 Docker Engine 与 Compose 插件
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这五个包分别是:
| 软件包 | 作用 |
|---|---|
docker-ce | Docker 引擎本体(守护进程 dockerd) |
docker-ce-cli | docker 命令行客户端 |
containerd.io | 底层容器运行时,负责真正管理容器生命周期 |
docker-buildx-plugin | 新一代镜像构建工具 |
docker-compose-plugin | Compose 的插件版,装完就能用 docker compose 命令 |
也就是说,用这种方式安装,Compose 已经一起装好了,不需要再单独装一遍。后文还会介绍独立版 Compose 的装法,适合只想单独升级 Compose 的场景。
第 4 步:启动服务并设置开机自启
sudo systemctl start dockersudo systemctl enable docker验证服务状态(显示 active (running) 即正常):
sudo systemctl status docker第 5 步:验证安装
sudo docker versionsudo docker run hello-worlddocker run hello-world 会自动拉取一个官方测试镜像并运行。看到 Hello from Docker! 就说明引擎、网络、镜像拉取整条链路都通了。
方式二:一键脚本安装(快速体验)
Docker 官方还提供了一个便捷安装脚本,一行命令自动完成上面所有步骤:
curl -fsSL https://get.docker.com -o get-docker.shsudo sh get-docker.sh国内服务器下载慢的话,可以给脚本指定阿里云镜像:
sudo sh get-docker.sh --mirror Aliyun需要提醒的是:一键脚本适合测试机和快速体验,生产环境更建议用方式一的仓库安装——脚本装了什么版本不完全受你控制,而仓库安装的版本管理、升级和回滚都更清晰。
RHEL 系(CentOS / Rocky / AlmaLinux)差异
RHEL 系用 dnf 代替 apt,其余思路完全一样。简要流程如下:
# 卸载旧版本sudo dnf remove -y docker docker-client docker-client-latest docker-common \ docker-latest docker-latest-logrotate docker-logrotate docker-engine
# 添加官方仓库sudo dnf -y install dnf-plugins-coresudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装并启动sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginsudo systemctl enable --now dockersudo docker run hello-world让普通用户免 sudo 用 Docker
默认情况下只有 root 和 docker 用户组的成员能操作 Docker。每次敲命令都加 sudo 很烦,可以把当前用户加进 docker 组:
sudo usermod -aG docker $USER执行后注销重新登录(或重启服务器)才会生效,之后直接 docker ps 就能用了。
安全提醒:
docker组的权限实际上等同于 root——组内用户可以把宿主机任意目录挂进容器读写。所以只把可信账号加进这个组,公网服务器尤其要注意。
装完必做:daemon.json 基础配置
Docker 的全局配置放在 /etc/docker/daemon.json,没有就新建。下面这份是我自己所有服务器都在用的配置,解决了三个最常见的问题:拉镜像慢、日志撑爆磁盘、改配置没头绪。
sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-'EOF'{ "registry-mirrors": [ "https://docker.1ms.run", "https://docker.m.daocloud.io" ], "log-driver": "json-file", "log-opts": { "max-size": "20m", "max-file": "3" }, "live-restore": true}EOF逐项说明:
registry-mirrors:镜像加速器。国内服务器直连 Docker Hub 经常超时,配上加速地址后拉镜像走国内节点。公共加速器时有失效,如果某个拉不动了,换一个可用的即可,这一行为空也可以删掉log-driver+log-opts:限制单个容器的日志文件大小。这里设的是每个日志文件最大 20 MB、最多保留 3 个,也就是单个容器最多占约 60 MB 日志。不设这个的话,话痨容器能把系统盘写满,这是新手最容易踩的坑live-restore:dockerd 升级或重启时,正在运行的容器保持不中断,老版本升级时很有用
改完配置后重启 Docker 生效,并检查配置是否被正确加载:
sudo systemctl daemon-reloadsudo systemctl restart dockerdocker info | grep -A3 "Registry Mirrors"docker info 里能看到加速器地址、日志驱动等信息,就说明配置生效了。
安装 Docker Compose(独立版)
前面仓库安装已经自带了 Compose 插件(命令是 docker compose,中间空格)。下面介绍的是独立二进制版(命令是 docker-compose,中间连字符),两种装法任选其一即可,区别在文末有对比。
第 1 步:查询并下载最新版
先用 GitHub 官方接口查一下最新版本号,避免写死版本号很快过期:
COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep '"tag_name"' | cut -d'"' -f4)echo $COMPOSE_VERSION下载对应平台的二进制文件(命令会自动识别系统和架构):
sudo curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose国内服务器从 GitHub 下载慢的话,可以多重试几次,或者先在本地下载再传到服务器上,文件本身只有几十 MB。
第 2 步:添加执行权限并验证
sudo chmod +x /usr/local/bin/docker-composedocker-compose version能输出类似 Docker Compose version v2.x.x 就装好了。
插件版 vs 独立版,怎么选
| 对比项 | 插件版 | 独立版 |
|---|---|---|
| 命令形式 | docker compose(空格) | docker-compose(连字符) |
| 安装方式 | 跟着 Engine 仓库一起装 | 单独下载二进制 |
| 升级方式 | 随 Docker 一起升级 | 手动替换二进制 |
| 适合场景 | 大多数情况,省心 | 只想单独升级 Compose 时 |
功能上两者完全一致,新装机器直接用插件版就行。另外提醒一句:老教程里的 docker-compose 1.x 是 Python 写的版本,已经在 2023 年停止维护,不要再装了,现在全是 Go 写的 2.x。
Compose 快速上手实战
光装好不算会用,下面用一个真实的小例子走一遍完整流程:部署一个 Nginx 网站,并配一个 Redis 做缓存,两个服务一条命令一起拉起。
第 1 步:准备项目目录
mkdir -p ~/demo-app/htmlcd ~/demo-appecho '<h1>Hello from Docker Compose</h1>' > html/index.html第 2 步:编写 docker-compose.yml
在 ~/demo-app 目录下新建 docker-compose.yml,内容如下:
services: web: image: nginx:alpine container_name: demo-web ports: - "8080:80" volumes: - ./html:/usr/share/nginx/html:ro depends_on: - cache restart: unless-stopped
cache: image: redis:alpine container_name: demo-redis volumes: - redis-data:/data restart: unless-stopped
volumes: redis-data:字段逐个拆解:
services:下面定义的每一个顶格名字就是一个服务(容器)image:用哪个镜像,nginx:alpine表示官方 Nginx 的 Alpine 精简版,体积小container_name:给容器起个固定名字,不写的话 Compose 会自动生成ports:端口映射,"8080:80"表示把宿主机的 8080 转发到容器的 80,格式是「宿主机:容器」volumes:目录挂载。./html:/usr/share/nginx/html:ro把当前目录的 html 文件夹只读挂进 Nginx 的网页目录,改网页不用重启容器;redis-data:/data则用命名卷保存 Redis 数据,容器删了数据还在depends_on:启动顺序,web 依赖 cache,会先启动 cache 再启动 web(注意它只保证启动先后,不保证服务就绪,生产项目里一般靠应用自己重试连接)restart: unless-stopped:容器异常退出时自动重启,除非你手动停了它- 顶层的
volumes:声明上面用到的命名卷
第 3 步:启动并验证
# 在 docker-compose.yml 所在目录执行,-d 表示后台运行docker compose up -d
# 查看两个服务的状态docker compose ps
# 访问测试curl http://localhost:8080curl 返回刚才写的 Hello from Docker Compose,实战就通关了。注意独立版 Compose 的命令是 docker-compose up -d,其余参数完全一样。
第 4 步:日常操作
docker compose logs -f web # 实时追踪 web 服务的日志docker compose restart web # 只重启 web 这一个服务docker compose pull # 拉取 compose 文件里所有服务的新镜像docker compose down # 停止并删除容器和网络(命名卷数据保留)docker compose down -v # 连命名卷一起删(数据会没,慎用)Docker 常用命令速查
镜像相关
docker images # 列出本地镜像docker pull nginx:alpine # 拉取镜像docker rmi nginx:alpine # 删除镜像docker build -t myapp:v1 . # 用当前目录的 Dockerfile 构建镜像docker history nginx # 查看镜像的层级构建历史容器相关
docker ps # 正在运行的容器docker ps -a # 所有容器(含已停止的)docker logs -f <容器名> # 实时查看日志docker exec -it <容器名> sh # 进入容器内部(alpine 镜像用 sh,普通镜像可用 bash)docker stop <容器名> # 停止容器docker start <容器名> # 启动已停止的容器docker rm <容器名> # 删除容器(要先停止,或加 -f 强制)docker stats # 实时查看所有容器的 CPU / 内存占用Compose 常用命令速查
| 命令 | 作用 |
|---|---|
docker compose up -d | 按 compose 文件后台启动全部服务 |
docker compose down | 停止并删除容器与网络 |
docker compose ps | 查看本项目服务状态 |
docker compose logs -f | 追踪全部服务日志 |
docker compose exec <服务> sh | 进入某个服务的容器 |
docker compose pull | 拉取全部服务的新镜像 |
docker compose up -d --build | 重新构建镜像并启动 |
docker compose config | 校验并打印最终生效的配置 |
磁盘清理(务必谨慎)
Docker 用久了,废弃镜像和停止的容器会悄悄占满磁盘。官方提供了一组 prune 清理命令,但它们都是「宁可错杀」的设计,执行前一定看清楚范围:
docker system df # 先看 Docker 到底占了多少磁盘docker container prune # 只删已停止的容器(相对安全)docker image prune # 只删没有标签的悬空镜像(相对安全)下面这两条范围很大,不要随手执行,尤其是 -a 和 --volumes:
# docker system prune -a # 删除所有未被容器使用的镜像# docker system prune -a --volumes # 连未使用的卷一起删,数据库数据可能陪葬我个人的习惯是:只定期清停止的容器和悬空镜像,正式镜像和卷一律手动确认后再删。服务器上真实出过事的,往往不是病毒,是手滑的一条清理命令。
常见问题排查
报错 Cannot connect to the Docker daemon
意思是客户端连不上守护进程,按顺序查:
systemctl status docker # 服务是不是没启动sudo systemctl start docker # 没启动就拉起来如果是普通用户执行时报这个错,多半是没加进 docker 组或加了组还没重新登录,回到前面「免 sudo」那节处理。
报错 permission denied(docker.sock)
同上,本质是当前用户没有访问 /var/run/docker.sock 的权限,usermod -aG docker $USER 后重新登录即可,不要图省事去 chmod 666 这个文件,那等于把 root 权限对所有人敞开。
拉取镜像超时或特别慢
先确认 daemon.json 里的镜像加速器已配置且 Docker 已重启;再用 docker info 确认加速器真的加载进去了。都正常还慢,就是当前加速器节点的问题,换一个可用的地址,或者给服务器挂代理后再拉。
容器起来了但访问不了
docker compose ps # 容器是不是 Up 状态,有没有反复重启docker compose logs <服务名> # 看容器内部报什么错ss -tlnp | grep 8080 # 宿主机端口到底有没有在监听、被谁占用端口映射写错和端口被其他程序占用,是这两个问题里最常见的。
查看 Docker 服务本身的日志
容器日志解决不了问题时,看守护进程自己的日志:
sudo journalctl -u docker -f升级与卸载
仓库安装的升级很简单,跟着系统一起升:
sudo apt-get updatesudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin彻底卸载(先停服务,再卸软件包):
sudo systemctl stop docker docker.socket containerdsudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginsudo apt-get autoremove -y独立版 Compose 的卸载就是删文件:
sudo rm /usr/local/bin/docker-compose注意:卸载软件包不会自动删除 /var/lib/docker(镜像、容器、卷都在这里)和 /etc/docker/daemon.json。重装时它们会被继续沿用;确认数据都不要了,才手动删目录:
# 危险操作:执行后所有镜像、容器、数据卷全部消失,不可恢复sudo rm -rf /var/lib/docker /var/lib/containerd总结
回顾一下整条路线:用官方仓库装好 Engine 和 Compose 插件 → 启动服务并验证 hello-world → 普通用户加组免 sudo → 写好 daemon.json(加速器 + 日志限制)→ 用一个双服务的小项目把 Compose 的核心字段和日常命令练一遍。有了这套底子,后面不管是部署网站、数据库还是各种自托管服务,都只是往 Compose 文件里加服务而已。
参考资料:Docker 官方文档(docs.docker.com)中 Engine 与 Compose 的安装章节,建议收藏,版本更新时以官方文档为准。