
Ubuntu上安装Docker与Docker Compose从零到能跑容器的完整实操记录这篇文章的起因很简单最近几个月被问得最多的一个问题就是Ubuntu上到底怎么干净利落地装好Docker和Docker Compose。说实话网上教程很多但大多要么太老、要么只讲一半——装完Docker发现Compose用不了或者装完Compose发现版本对不上又或者卡在权限、挂载、镜像拉不下来这些莫名其妙的问题上。我前前后后在 Ubuntu 18.04、20.04、22.04 甚至 24.04 上装过不下二十次也帮同事排查过各种千奇百怪的报错。这篇博文就把我实际踩过的坑、验证过的步骤、以及安装后的基础配置一并整理出来。它适用于想在 Ubuntu 上快速跑起 Docker 环境、然后用 Docker Compose 编排多个容器的开发者或运维人员。你不需要多深的Linux基础只要会复制粘贴命令、能看懂基本的终端输出照着做基本都能顺利装完。1. 安装前的准备先搞清楚系统状态省得后面到处救火1.1 查看系统版本和内核确认是否满足安装条件很多人上来就直接复制安装命令结果装到一半发现内核太老、apt源不对、甚至系统本身是精简版缺了一堆依赖。我建议所有人在动手之前先花一分钟确认两件事系统版本和内核版本。lsb_release -a uname -rlsb_release 的输出会告诉你当前Ubuntu的具体版本号比如 22.04.3 LTS。uname -r 输出的是当前内核版本比如 5.15.0-91-generic。为什么要看这两个因为Docker对内核有最低要求通常需要内核版本在 3.10 以上但这只是理论下限。在实际使用中我强烈建议至少是 Ubuntu 18.04 4.15 内核最好是 20.04 或 22.04 这种较新的LTS版本原因有二新内核自带的内核模块更全overlay2存储驱动Docker默认且推荐的存储驱动运行更稳定新版本的Docker引擎对老内核的兼容性测试覆盖越来越少很多奇怪的bug在老系统上根本没法复现和解决。如果你用的是 Ubuntu 16.04 或者更老的版本我建议直接升级系统而不是硬装Docker。这不是不能装而是后续维护成本会让你想砸键盘。1.2 检查是否装过旧版本先清理干净再开始这一步是我踩过最多坑的地方。很多机器上其实已经装过 docker 或 docker.io、docker-engine 之类的旧包要么是apt装的要么是之前手动从某处下载的二进制包。如果不清理直接装新的最常见的后果是装完之后 docker 命令能执行但 docker --version 和 docker compose version 分别指向两套完全不同的东西或者是 service docker start 起不来报各种各样的 socket 错误。所以不管你的机器看起来是不是干净的我都建议先跑一遍清理命令sudo apt remove docker docker-engine docker.io containerd runc sudo rm -rf /var/lib/docker /etc/dockerapt remove 会卸载旧版本的Docker相关包。rm -rf 那两步是删除Docker的数据目录和配置目录这一步很多人会忽略但如果不删旧配置可能残留影响新装的Docker。注意如果你之前有用Docker跑过数据库之类的容器数据都存放在 /var/lib/docker 里确认不需要了再删。我之前有一次清理一台测试机没多想就删了后来发现里面有个GitLab容器的数据没备份那叫一个酸爽。生产机器务必先备份再清理。2. 安装Docker引擎官方仓库方式为主顺便聊聊为什么不用别的2.1 用官方apt仓库安装步骤拆开讲Docker在Ubuntu上的安装方式我试过脚本安装curl -fsSL https://get.docker.com | sh、apt直接装docker.io包、以及官方apt仓库三种方式。综合体验下来官方apt仓库是首选原因后面细说。先看完整步骤# 1. 更新apt索引并安装依赖 sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release # 2. 创建keyring目录并添加Docker官方GPG密钥 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg # 3. 添加Docker apt仓库 echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 4. 再次更新索引并安装Docker引擎 sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin第3步里的$(lsb_release -cs)会自动获取你系统的代号比如 22.04 返回的是 jammy。这里有个坑如果你用的是 Linux Mint 或者基于Ubuntu的衍生发行版lsb_release -cs 可能返回的不是Ubuntu代号而是Mint自己的代号导致apt找不到对应的仓库目录。解决办法是手动把$(lsb_release -cs)替换成对应的Ubuntu代号比如 jammy、focal 等。第4步安装的包有几个我分别说下作用docker-ceDocker社区版引擎本体装完 docker 命令就能用docker-ce-cliDocker命令行客户端负责和Docker守护进程通信containerd.io容器运行时Docker引擎底层靠它来跑容器docker-buildx-plugin构建镜像的BuildKit插件现在 docker build 默认走的就是它docker-compose-pluginDocker Compose v2插件装完这个就能用docker compose命令。这里顺便回答一个我经常被问到的问题为什么不用apt install docker.io因为Ubuntu官方仓库里的 docker.io 包版本比Docker官方仓库的 docker-ce 旧得多而且更新不及时。我在 Ubuntu 22.04 上曾经见过 docker.io 还停留在 20.10.x 时代而官方仓库已经到 24.x 甚至 25.x 了。如果你需要用到新特性比如 Compose v2 的某些新参数、BuildKit 的增强功能老版本会非常难受。2.2 配置镜像加速解决拉取镜像慢的痛点Docker装好之后大部分人遇到的第一个实际问题就是docker pull ubuntu能成功但速度感人或者干脆超时。这不是你的网络问题而是默认镜像源在海外的原因。解决办法是配置registry mirror也就是镜像加速器。编辑或新建/etc/docker/daemon.jsonsudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [https://docker.m.daocloud.io] } EOF这里我写的加速器地址是一个公共的镜像加速服务。其他的还有不少但很多是第三方个人维护的稳定性参差不齐。我的建议是优先用云服务商提供的加速器如果你有云服务器的化其次是这种公开的聚合加速服务。不要同时配置太多镜像地址Docker会依次尝试如果第一个挂了会切到下一个但如果你的加速器列表里有一个不健康的地址反而会拖慢拉取速度。配置完之后重启Dockersudo systemctl daemon-reload sudo systemctl restart docker然后验证docker info | grep -A 5 Registry Mirrors如果看到你配置的地址出现在列表里说明生效了。这时候再docker pull ubuntu:22.04速度应该会有明显改善。注意镜像加速只对Docker Hub官方仓库的镜像有效。如果你的镜像是从其他私有仓库拉取的需要配置的是insecure-registries或者额外的认证信息跟registry-mirrors无关。3. 安装Docker Compose理清v1和v2的区别别再按老教程装了3.1 为什么建议直接用v2版本很多人在安装Docker Compose的时候会遇到一个大困惑网上的教程一半在讲怎么下载 docker-compose 二进制文件比如放到 /usr/local/bin/docker-compose另一半在讲apt install docker-compose或者直接用docker compose。这其实是因为Docker Compose经历了比较大的版本更迭v1docker-compose独立的Python程序需要通过pip安装或者直接下载二进制文件命令形式是docker-compose upv2docker compose用Go语言重写作为Docker CLI的插件存在命令形式是docker compose up注意中间是空格。现在Docker官方主推的就是v2版本你在前面安装 docker-compose-plugin 那个包的时候实际上已经把v2装好了。装上之后默认命令是docker compose但为了兼容旧习惯Docker Compose v2也提供了一个兼容模式可以通过docker-compose这个符号链接来调用。我的建议很简单如果你不是维护老项目不要再单独装v1了。直接使用docker compose命令即可。理由很实际v2是官方持续维护的版本bug修复和新功能都优先给v2;v2性能更好启动多个服务的并行度更高v1依赖Python环境容易出现Python版本兼容问题在Ubuntu 22.04上apt装v1还会自动带上一堆Python依赖包很烦。3.2 v2二进制方式安装备选方案虽然装 docker-compose-plugin 就能用docker compose但有些场景下你可能需要单独装一个独立的 docker-compose 二进制文件。比如你的机器上不想装Docker引擎只是纯客户端操作远程Docker或者你需要在CI/CD流水线里单独调用一个特定版本的Compose。这时候的步骤是# 1. 到GitHub Releases页面查最新版本号 # 2. 下载对应架构的二进制文件 sudo curl -L https://github.com/docker/compose/releases/download/v2.26.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose # 3. 赋可执行权限 sudo chmod x /usr/local/bin/docker-compose # 4. 验证 docker-compose version这一步有个非常常见的问题GitHub Releases的下载速度在国内很慢。我试过几次几MB的二进制文件能下载十几分钟中间还经常断。如果你遇到这种情况可以考虑用国内一些镜像站提供的下载加速比如把GitHub Releases的地址换成对应镜像站的地址或者直接用代理。另一个问题是版本选择。我经常看到有人随便下载一个版本就装上了结果发现 docker compose 文件里写的某些指令不支持。这里给个经验值当前2024年-2025年我推荐 v2.20 以上的版本因为向下兼容性做得好且对 Compose 文件规范比如 version 3.8 和较新的 version 2.x 规范支持比较完整。同样重要的是尽量保持 Docker 引擎版本和 Compose 插件版本不要差太多极端情况下会出现 API 版本不兼容的报错。4. 安装后的验证与基础配置让Docker真正好用起来4.1 验证Docker和Compose是否安装成功安装完成后别急着跑去拉镜像先做几个基础验证确认整个环境是健康的# 检查Docker引擎版本 docker --version # 检查Compose插件版本 docker compose version # 检查Docker环境信息 docker info # 验证Docker守护进程是否正常运行一个测试容器 docker run hello-world如果一切正常docker run hello-world会输出一段欢迎信息并提示你的安装似乎正确。如果这一步报错大概率是Docker守护进程没启动或者当前用户没有权限。我们看下一节怎么解决权限问题。docker info的输出信息量很大其中几个重点字段我建议你留意Server VersionDocker引擎的版本号Storage Driver存储驱动最好是 overlay2Cgroup Versioncgroup v2 或者 v1影响资源限制的行为Docker Root Dir镜像和容器数据的存放位置默认是 /var/lib/docker。4.2 将当前用户加入docker组免去每次sudo的烦恼这个问题几乎每个新用户都会遇到装完Docker执行docker ps或docker run终端提示permission denied while trying to connect to the Docker daemon socket。这不是Docker坏了而是因为Docker守护进程监听在 /var/run/docker.sock 这个socket上而这个socket文件默认属于 root 用户和 docker 组。普通用户不在docker组里自然没有权限访问。解决办法很简单把当前用户加入docker组sudo usermod -aG docker $USER然后注销重新登录或者执行newgrp docker让组变更立即生效。之后再执行docker ps应该就不会报错了。注意把用户加入docker组实际上等同于给该用户root级别的权限因为可以通过挂载宿主机目录的方式轻松获取宿主机的root权限。生产环境一定要想清楚再操作不要给普通开发机上所有用户都加组权限。5. 实操环节用Docker Compose跑一个MySQL验证全链路5.1 编写docker-compose.yml文件说完了安装和配置我们来一个实际场景验证一下。我在日常开发中最常用的验证方式就是通过Docker Compose跑一个MySQL实例因为MySQL涉及端口映射、数据卷挂载、环境变量配置、健康检查等多个常见的Compose特性。在你的工作目录下新建一个文件夹比如 ~/docker-test/mysql然后创建一个 docker-compose.yml 文件services: mysql8: image: mysql:8.0 container_name: mysql-test restart: unless-stopped ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: root123456 MYSQL_DATABASE: test_db TZ: Asia/Shanghai volumes: - ./data:/var/lib/mysql command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_unicode_ci在这个配置文件里几个关键点分别说一下services下面定义服务名这里我们叫 mysql8image指定镜像和版本mysql:8.0 会从Docker Hub拉取ports做端口映射宿主机3306映射到容器3306。注意宿主机3306端口如果已经被占用了这里会失败改成一个没用过的端口比如 3307:3306 即可volumes把宿主机的 ./data 目录挂载到容器的 /var/lib/mysql这样MySQL的数据文件就保存在宿主机上容器删了数据不丢。5.2 启动服务并验证在 docker-compose.yml 所在目录下执行# 启动服务后台运行 docker compose up -d # 查看服务状态 docker compose ps # 查看日志第一次启动会比较久因为要拉镜像 docker compose logs -f mysql8第一次启动时镜像可能比较大MySQL 8.0镜像大约550MB拉取需要一些时间取决于你配置的镜像加速器速度。等日志里出现ready for connections或者类似字样说明MySQL已经启动成功了。验证一下能否连接# 在宿主机上通过docker命令进入容器内部 docker exec -it mysql-test mysql -uroot -p输入密码 root123456如果能看到MySQL的欢迎界面说明整个Docker和Compose环境已经跑通了。如果连接不上或者容器一直重启排查的第一件事就是看日志docker compose logs mysql8大部分问题都能从日志里看出来密码策略报错、内存不足MySQL很吃内存512MB的小机器可能起不来、端口冲突等等。注意docker compose down会删除容器但不会删除数据卷只要你是用的volumes挂载的宿主机目录。这点设计得很合理容器删了可以重建数据不能丢。如果你确实想连数据一起清理用docker compose down -v。6. 常见问题与排查技巧实录6.1 无法连接Docker daemon类的报错这类报错的表现形式有很多常见的有Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?permission denied while trying to connect to the Docker daemon socket排查思路分两步第一步确认Docker守护进程是不是在运行sudo systemctl status docker如果显示 active (running)说明服务在运行。如果没在运行sudo systemctl start docker # 设置开机自启 sudo systemctl enable docker第二步确认当前用户是否有权限访问socket。按照前面说的办法把用户加入docker组然后重新登录。还有一种不太常见的情况是系统防火墙拦截了Docker的网络。Ubuntu默认的ufw防火墙如果开启的话需要放行Docker相关的端口sudo ufw allow 2375/tcp # 如果你用的是远程API端口的话 sudo ufw reload当然这种情况更多出现在你配置了DOCKER_HOST为远程TCP地址的机器上本地socket模式的很少受防火墙影响。6.2 apt安装时提示Unable to locate package docker-ce这个问题几乎必定和apt源有关。执行sudo apt update之后如果仍然找不到 docker-ce 包通常是你没有正确添加Docker官方apt仓库或者仓库里没有你的系统版本对应的目录。排查方法是查看 /etc/apt/sources.list.d/docker.list 文件内容是否正确。很多人在添加仓库这一步卡住因为$(lsb_release -cs)替换出来的系统代号可能不适用比如某些基于Ubuntu的衍生系统。解决办法是手动指定Ubuntu的代号。6.3 docker compose命令找不到或者提示Command not found如果你安装的是 docker-compose-plugin 插件那docker compose命令应该在安装完成之后就能直接用。但是有几种情况会导致命令找不到安装过程中断插件没有正确安装。重新执行sudo apt install -y docker-compose-plugin。Docker CLI版本太旧不支持插件机制。Ubuntu 20.04 上如果通过旧版apt源只装了 docker.io 而没装 docker-ce可能出现这个问题。升级Docker CLI到新版本即可。你单独下载的 docker-compose 二进制文件没有放到 PATH 目录下。检查一下 /usr/local/bin 是否存在以及文件是否有可执行权限。我遇到过一种比较隐蔽的情况一台机器上既有独立二进制 docker-composev1放到了 /usr/local/bin 下又装了 docker-compose-plugin 插件。结果docker compose和docker-compose分别是两种不同的机制导致同一个项目用两个命令执行效果不一致。这种情况建议彻底移除v1二进制文件只保留一种方式避免混乱。6.4 常见问题速查表问题现象可能原因解决办法apt找不到 docker-ce 包apt源未添加或仓库地址错误重新检查并添加官方Docker仓库拉取镜像超时未配置镜像加速器或加速器不可用配置 registry-mirrors 并重启Dockersocket权限报错用户不在docker组usermod -aG docker 后重新登录容器反复重启配置错误、端口冲突、内存不足查看 docker compose logsdocker compose 命令找不到插件未装或版本过旧重新安装 docker-compose-plugin下载 docker-compose 二进制太慢GitHub Releases访问慢使用镜像加速或代理7. 一些实用小技巧最后分享几个日常使用频率很高的技巧。技巧一通过别名简化命令。在 ~/.bashrc 或 ~/.zshrc 里添加alias dcdocker compose alias dpsdocker ps --format table {{.Names}}\t{{.Status}}\t{{.Ports}}然后source ~/.bashrc之后执行dc up -d、dc logs -f、dps就会非常顺手。技巧二及时清理无用资源。Docker用久了会积累很多悬空镜像、停止的容器、未使用的网络占磁盘空间。我习惯定期执行docker system prune -a这条命令会删除所有未使用的镜像和容器释放磁盘空间。加了 -a 会把所有没有被容器引用的镜像也删掉下次要用再拉取即可。执行之前还是确认一下因为有些镜像虽然当前没被使用但你可能之后会用到。技巧三用 docker inspect 定位问题。当容器行为不符合预期时除了看日志还可以用docker inspect 容器名输出是完整的JSON格式包含了容器的网络配置、挂载信息、环境变量、资源限制等所有细节。排查端口映射不生效、环境变量没传进去这类问题时特别好用。技巧四守护进程日志在journald里。如果Docker守护进程本身出了问题不是某个容器的问题去看系统日志journalctl -u docker.service比如网络相关的 iptables 报错、磁盘空间满导致的启动失败都会记录在这里比网上瞎猜有效得多。我个人的体会是Docker和Compose的安装其实只占整个使用链条里很小的一部分真正让你感到顺手的是对这套工具链的运行逻辑和常用排查手段的熟悉。装好了只是开始后面怎么用好、怎么在遇到问题时不慌不忙地定位才是拉开效率差距的地方。希望这篇记录能帮你少走一些弯路。