Ubuntu 22.04 / 24.04 / 26.04 中安装 Docker 和 Docker Compose
以下步骤适用于 Ubuntu 22.04 / 24.04 / 26.04 LTS,命令需要 sudo 权限。
Ubuntu 20.04(Focal)已在 2025 年 5 月结束标准支持,之后进入需要 Ubuntu Pro 的 ESM 阶段;Docker 官方安装文档现在也只列 26.04、24.04、22.04 三个 LTS。新机器直接用 24.04 或 26.04。
什么是Docker?
Docker是一款开源的容器化平台,通过将应用程序与其运行环境打包成轻量级容器,实现跨平台一致性运行。其核心特点包括:
- 轻量高效:共享宿主机内核,无需完整操作系统虚拟化
- 环境一致性:容器镜像可在开发、测试、生产环境无缝运行
- 快速部署:秒级启动时间,支持弹性扩缩容
- 资源隔离:每个容器拥有独立的文件系统、网络和进程空间
核心概念解析
| 术语 | 说明 |
|---|---|
| 镜像(Image) | 静态模板文件,包含应用程序及其运行环境(类似软件安装包) |
| 容器(Container) | 镜像的运行实例,提供隔离的运行时环境 |
| 仓库(Registry) | 镜像存储和分发平台(如Docker Hub) |
系统要求
- 64 位 Ubuntu:26.04 LTS (Resolute)、24.04 LTS (Noble)、22.04 LTS (Jammy)
- 兼容架构:x86_64/amd64、armhf、arm64、s390x、ppc64le
- 衍生发行版(如 Linux Mint)不在官方支持范围内
装之前先看两件事,它们会决定你后面会不会踩坑:
- 用 ufw 或 firewalld 的话,容器发布的端口会绕过你的防火墙规则。这是 Docker 直接改写 iptables 的结果,不是配置错误。需要在
DOCKER-USER链里自己加规则,见官方文档 Packet filtering and firewalls。 - 默认(iptables 后端)下 Docker 只兼容
iptables-nft与iptables-legacy,用nft原生命令写的规则集不被支持,防火墙规则要用iptables/ip6tables写。Docker Engine 29.0 起另有实验性的 nftables 后端(daemon.json里"firewall-backend": "nftables"),启用后 Docker 自己写 nft 规则、没有DOCKER-USER链,自定义规则改在自己新建的 nft 表里按相同 base chain 与 priority 书写。
卸载旧版本 (全新机器跳过这一步)
在安装 Docker Engine 之前,先卸载所有有冲突的软件包。
发行版可能自带非官方的 Docker 软件包,它们与 Docker 官方包冲突;装 Docker Engine 正式版之前要先卸载这些包。
要卸载的非官方软件包包括:
- docker.io
- docker-compose
- docker-compose-v2
- docker-doc
- podman-docker
此外,Docker Engine 依赖于containerd和runc。Docker Engine 将这些依赖项捆绑为一个包:containerd.io。如果你之前安装了containerd或runc,请卸载它们以避免与 Docker Engine 捆绑的版本发生冲突。
- 运行以下命令来卸载所有冲突的包:
1 | sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1) |
apt 会告诉你其中哪些包本来就没装,这不是错误。
- 清理残留配置
1 | sudo apt-get autoremove -y |
- 彻底卸载 Docker Engine(连数据一起清掉,官方三步)
1 | sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras |
注意 /var/lib/containerd 这一条:漏掉它常常会留下几个 GB 的数据。只要清旧包、想保留镜像和卷的话,执行到 apt purge 为止即可。
使用apt存储库安装
在新的主机上首次安装 Docker Engine 之前,你需要设置 Docker apt存储库。之后,你可以从存储库安装和更新 Docker。
- 设置 Docker 的apt存储库。
1 | # Add Docker's official GPG key: |
- 安装 Docker 包。
1 | sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin |
- 确认服务在跑
1 | sudo systemctl status docker |
不是 running 就手动起一次:sudo systemctl start docker。
- 测试 Docker
1 | sudo docker run hello-world |
上述命令会下载一个 Docker 测试镜像,并在容器内执行一个 “hello_world” 样例程序。
输出里有 Hello from Docker! 就是装好了。
1 | $ docker run --rm hello-world |
镜像摘要与第 2 步括号里的架构会随版本和机器变化(arm64 服务器上会显示 (arm64)),不必与自己机器的输出逐字一致。
- 确认 Compose 插件可用
1 | docker compose version |
输出形如 Docker Compose version v5.x.y。注意命令是 docker compose(v2 插件),不是已停止维护的独立二进制 docker-compose;docker-compose-plugin 这个包提供的正是前者。
配置非Root用户权限(可选)
非root用户执行docker命令的时候, 如 docker ps -a 可能会报错
1 | Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json?all=1": dial unix /var/run/docker.sock: connect: permission denied |
解决方法:
1 | sudo groupadd docker # 组通常已由安装包创建,重复执行只会提示已存在 |
加入 docker 组等于给了这个用户 root 级权限(组成员可以直接挂载宿主机目录、以 root 跑容器),官方文档把这一点写在 Docker Daemon Attack Surface 里。单人服务器上这是常见的取舍;多人共用的机器上更稳妥的做法是 rootless 模式。
如果你在加组之前用 sudo docker 跑过命令,可能会看到这条报错:
1 | WARNING: Error loading config file: /home/user/.docker/config.json - |
原因是 ~/.docker/ 目录被 root 创建过。按官方文档修:
1 | sudo chown "$USER":"$USER" ~/.docker -R |
生产环境还要做的六件事
下面六件事按「先止损、再安全、最后收敛权限」排列,前两件建议装完就做。
1. 给日志设上限
json-file 是默认的日志驱动,它默认不限制大小:容器一直往 stdout 写,/var/lib/docker/containers/*/ 下的日志文件就一直涨,最后撑爆磁盘。这是服务器磁盘被 Docker 吃满最常见的原因。
写一个 /etc/docker/daemon.json:
1 | { |
1 | sudo systemctl restart docker |
这个配置只对之后新建的容器生效,已经在跑的容器要重建才会用上新值。不想管这些参数的话,官方提供了 local 驱动,它默认就带轮转:
1 | { |
参考:Configure default logging driver、json-file 驱动。
2. 把数据目录挪到别的盘(可选)
默认数据目录是 /var/lib/docker,但 Docker Engine 29 起全新安装默认启用 containerd image store:镜像与容器快照实际存在 /var/lib/containerd,"data-root" 搬不走它们。系统盘小的时候要迁两处:
1 | # 必须连 socket 一起停:docker.service 声明了 Requires=docker.socket, |
然后在 /etc/docker/daemon.json 里加一行:
1 | { |
再让 containerd 也换根,编辑 /etc/containerd/config.toml:
1 | version = 2 |
1 | sudo systemctl start containerd |
确认新目录工作正常之后再删旧目录。rsync 的 -aHAX 三个参数负责保留权限、硬链接与扩展属性,少了它们容器层会出各种权限错误。
只有从 28 及更早版本升级上来、仍用 overlay2 的机器可以只迁
data-root;29 的全新安装必须两处都迁,否则镜像照样把系统盘写满(官方说明:data-root不影响 containerd image store 里的镜像与容器数据)。
3. 磁盘回收
服务器磁盘被 Docker 吃满,多数时候是停掉的容器、构建缓存和匿名卷在堆积。先看占用,再动手:
1 | docker system df # 分类看:镜像 / 容器 / 卷 / 构建缓存 |
1 | docker system prune # 停掉的容器 + 未使用网络 + 悬空镜像 + 未用构建缓存 |
边界要说清楚:默认不删卷(官方原话:By default, volumes aren’t removed),匿名卷只有带 --volumes 才清;-a 删的是「没有被任何容器引用」的镜像,正在跑的服务用到的镜像不会被碰。想保守一点可以加时间过滤:
1 | docker system prune -a --filter "until=168h" # 只清一周前创建的 |
4. 卷的备份与恢复
迁移数据目录不等于备份:卷被误删、机器坏掉时数据一起没。官方给的标准做法是「借一个临时容器把卷打成 tar」:
1 | # 备份:把 myvol 卷的内容打包到当前目录的 backup.tar |
对数据库这类有写入的服务,备份前先停容器(docker stop)或让它自己做一致性快照,热备份拿到的 tar 可能是半写状态。官方文档在 Back up, restore, or migrate data volumes 里给了基于 --volumes-from 的等价写法。
5. rootless 模式(多人机器或对外服务值得上)
docker 组等价于 root,这一点在前面提过。rootless 模式让守护进程和容器都在普通用户名下运行,解决了这个问题:
1 | # 前置:内核允许普通用户分配子 UID/GID |
它带来两个差别,写在这里免得踩:
- 控制命令从
sudo systemctl变成systemctl --user,代理 drop-in 的路径也跟着变:~/.config/systemd/user/docker.service.d/proxy.conf。 - 容器不能直接绑 1024 以下的端口,除非把
net.ipv4.ip_unprivileged_port_start调低(sudo sysctl net.ipv4.ip_unprivileged_port_start=80)。
如果机器上已经有系统级守护进程在跑,先按官方文档把它停掉再开 rootless(或加 --force):sudo systemctl disable --now docker.service docker.socket。
6. 资源与权限收敛
自建服务暴露在公网上时,最坏情况是被人拿来挖矿或打内存。给容器套几道限制,代价几乎为零:
1 | docker run -d --name ytdlp --memory 512m --memory-swap 512m --cpus 1 --pids-limit 256 --read-only --tmpfs /tmp --security-opt no-new-privileges -p 127.0.0.1:8000:8000 -v "$PWD/data:/data" ytdlp-service |
--memory+--memory-swap相等表示禁用 swap,内存超了直接 OOM 而不是拖垮整机--pids-limit防 fork bomb--read-only把根文件系统挂成只读,需要写的地方单独用--tmpfs或卷挂出来no-new-privileges阻止容器内进程通过 setuid 提权- 已经在运行的容器可以用
docker update --memory 512m --cpus 1 ytdlp补内存与 CPU 限制(--read-only这类要重建容器)
总结
本篇覆盖:
- Docker 核心概念与系统要求(含防火墙与 iptables 兼容性提醒)
- 冲突包的清理与官方 apt 源(deb822 格式)的配置
- Docker Engine 与 Compose 插件的安装和验证(
docker run hello-world、docker compose version) - 免 sudo 的组权限配置与
~/.docker权限修复 - 日志轮转与数据目录迁移
- 磁盘回收的边界(默认不删卷)、卷的备份与恢复、rootless 落地、容器的资源与权限限制
拉取镜像慢或超时,通常是出口网络的问题,给 Docker 守护进程配代理的做法见 Ubuntu 24.04 配置 Sing-box 代理服务器完整指南。
参考资料
- Docker官方文档
- Docker Compose教程
- Docker Hub镜像仓库
- 在 Ubuntu 上安装 Docker 引擎
- Linux 安装后步骤(组权限、日志驱动)
- 守护进程配置参考(data-root、log-opts)
- 容器包过滤与防火墙
- 卷的备份与恢复
- rootless 模式
- 容器资源限制
系列索引:网络与自建服务





