Ubuntu系统Docker安装配置全指南:从零到生产环境优化 1. 项目概述为什么要在Ubuntu上安装Docker如果你正在用Ubuntu无论是作为主力开发机还是服务器迟早会碰到Docker。这东西现在几乎是现代软件开发和部署的标配它把应用和它依赖的环境打包成一个“集装箱”让你在任何地方都能以相同的方式运行。想象一下你写了个Python应用在你自己电脑上跑得好好的结果放到同事的Mac或者公司的服务器上因为Python版本、系统库不一样直接报错。有了Docker你只需要把打包好的“集装箱”发过去对方就能一键运行环境问题彻底拜拜。在Ubuntu上装Docker尤其对新手来说可能是个小门槛。网上教程很多但要么太老跟不上Ubuntu新版本的节奏要么太简略关键步骤一笔带过你照着做十有八九会卡在某个报错上。我自己从Ubuntu 16.04一路用到现在的24.04Docker的安装方式也变了好几次踩过的坑不计其数。这篇教程的目的就是把我这些年最稳、最详细、最避坑的安装方法总结出来让你一次成功。文末我还会附上一个我自己整理的“运维实用干货大礼包”里面是一些能极大提升你使用Docker效率的脚本和配置算是彩蛋。简单说这篇教程适合谁所有需要在Ubuntu系统上使用Docker的人无论是刚接触Linux和容器的新手开发者还是需要为团队搭建标准化环境的运维工程师。我会从最基础的准备工作讲起一直讲到安装后的验证和基础使用确保每一步你都能看懂并且能自己动手复现。2. 安装前的核心准备工作安装软件最怕什么怕环境不对怕依赖缺失。在动手安装Docker之前花几分钟做好准备工作能避免90%的安装失败问题。这一步很多人会跳过直接复制粘贴安装命令结果遇到各种奇奇怪怪的错误回头还得重来更浪费时间。2.1 确认你的Ubuntu版本和系统架构首先你得知道你用的是什么版本的Ubuntu。Docker官方对不同版本的支持策略和仓库配置可能略有不同。打开终端输入以下命令lsb_release -a你会看到类似这样的输出No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy这里关键看Release和Codename。22.04是版本号jammy是代号。本教程主要覆盖Ubuntu 20.04 (Focal Fossa)、22.04 (Jammy Jellyfish) 和 24.04 (Noble Numbat)这些长期支持版LTS它们是目前最主流且稳定的选择。如果你的版本太老比如18.04以下强烈建议先升级系统。接着确认系统架构。虽然个人电脑大多是x86_64也叫amd64但如果你用的是树莓派或某些云服务器可能是arm64。运行uname -m输出x86_64或aarch64对应arm64都是支持的。这决定了我们后续从哪个仓库下载正确的安装包。2.2 彻底卸载旧版本或冲突软件这是至关重要的一步如果你的系统里曾经通过apt安装过老旧的docker、docker.io或docker-engine包或者安装过非官方的Docker Desktop for Linux它们会和新版Docker产生冲突导致安装失败或运行异常。在终端中执行以下命令进行彻底清理sudo apt-get remove docker docker-engine docker.io containerd runc这条命令会移除这些旧的软件包。但请注意它不会删除你主机上的镜像、容器、卷或自定义配置文件。这些数据通常存放在/var/lib/docker/和/var/lib/containerd/目录下。如果你是想全新安装不在乎旧数据可以手动删除这些目录sudo rm -rf /var/lib/docker /var/lib/containerd但操作前请务必确认注意docker.io是Ubuntu官方仓库里一个非常陈旧且功能不全的Docker版本千万不要用它。我们一定要安装Docker官方维护的版本。2.3 安装必备的工具和配置APT仓库Docker官方提供了APT软件源我们需要把这个源添加到系统的软件源列表里这样才能用apt命令安装到最新、最官方的版本。首先安装一些让apt能通过HTTPS使用仓库的必要工具sudo apt-get update sudo apt-get install ca-certificates curl gnupg这几条命令先更新本地软件包列表然后安装证书、curl下载工具和GPG密钥管理工具。接下来添加Docker官方的GPG密钥。这个密钥用于验证从Docker仓库下载的软件包的完整性确保它们没有被篡改。这是安全安装的关键一步。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这里我们创建了一个目录来存放密钥然后下载Docker的GPG公钥并用gpg --dearmor处理成APT能识别的格式最后设置正确的读取权限。最后将Docker的APT仓库源添加到系统。我们需要根据之前查到的系统代号比如jammy来构造正确的源地址。用下面的命令一键完成echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null这条命令看起来复杂其实它做了三件事arch$(dpkg --print-architecture)自动获取你的系统架构如amd64。signed-by/etc/apt/keyrings/docker.gpg指定我们刚才添加的GPG密钥路径。$(. /etc/os-release echo $VERSION_CODENAME)自动获取你系统的代号如jammy。这样添加的源就是为你当前系统量身定制的。完成后再次更新APT软件包列表让系统识别到这个新加的仓库sudo apt-get update如果这一步没有报错并且你在更新列表时能看到来自download.docker.com的链接说明仓库添加成功。3. Docker安装的详细步骤与核心组件解析准备工作全部就绪现在可以开始正式安装Docker了。Docker现在是一个包含多个组件的套件我们将安装其核心部分。3.1 安装Docker引擎及相关组件运行以下命令来安装最新的Docker版本sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin我来解释一下这几个包分别是干什么的理解了它们以后出问题你才知道该查哪里docker-ce: Docker社区版Community Edition的核心引擎。这是Docker的运行时负责创建和运行容器。docker-ce-cli: Docker的命令行接口Command Line Interface。你平时打的docker ps、docker run这些命令都是这个包提供的。containerd.io: 一个行业标准的容器运行时。Docker引擎实际上是在containerd之上构建的它负责管理容器的生命周期创建、启动、停止、删除等。它是Docker的核心依赖。docker-buildx-plugin: Docker的扩展构建工具。它支持多平台构建比如在AMD64电脑上构建ARM64的镜像、缓存优化等高级构建特性。虽然不是必须但强烈建议安装。docker-compose-plugin: Docker Compose的插件版。老版的docker-compose是一个独立的Python脚本现在官方推荐以插件形式安装命令变成了docker compose注意中间没有横杠。用于定义和运行多容器应用。安装过程可能会持续几分钟取决于你的网速。安装完成后Docker服务docker.service会自动启动并且设置为开机自启。你可以用下面命令验证服务状态sudo systemctl status docker你应该看到绿色的active (running)字样表示Docker守护进程已经在后台正常运行了。3.2 免sudo执行Docker命令的配置默认情况下执行docker命令需要sudo权限因为Docker守护进程是以root用户运行的。每次命令前都加sudo非常麻烦而且有些图形化工具比如VSCode的Docker扩展也可能因此无法正常工作。解决方法是将你的用户添加到docker用户组中。这个组的成员被允许直接与Docker守护进程通信。sudo usermod -aG docker $USER执行这条命令后你需要完全退出当前终端会话然后重新登录或者重启电脑这个组权限变更才会生效。这是很多人配置完发现没用的常见原因。重新登录后打开一个新终端直接运行docker version如果能够正常显示Client和Server的版本信息而不再需要sudo说明配置成功。这是安装后必做的一步能极大提升日常使用体验。3.3 验证安装与运行第一个容器理论说再多不如跑一个容器试试。我们来运行Docker的“Hello World”docker run hello-world这条命令会做以下几件事Docker客户端联系本地守护进程。守护进程发现本地没有hello-world这个镜像。它自动从默认的Docker Hub镜像仓库拉取pullhello-world:latest镜像。拉取成功后根据这个镜像创建一个新的容器并运行它。容器运行一个简单的程序在终端打印出一段欢迎信息和一些说明然后自动停止。如果你看到类似下面的输出那么恭喜你Docker已经成功安装并可以正常工作了Hello from Docker! This message shows that your installation appears to be working correctly. ...这个简单的测试验证了Docker引擎、网络、镜像拉取和容器运行整个链条都是通的。至此Docker的安装部分已经100%完成。4. 安装后的关键优化与配置安装成功只是第一步。默认配置可能不适合我们的网络环境和使用习惯需要进行一些优化让Docker用起来更顺手、更高效。4.1 配置国内镜像加速器直接从Docker Hub拉取镜像在国内速度可能很慢甚至经常超时失败。配置一个国内的镜像加速器是必选项。这相当于给Docker加了个“下载加速器”。我们需要修改Docker守护进程的配置文件/etc/docker/daemon.json。如果这个文件不存在就创建它。sudo nano /etc/docker/daemon.json在文件中输入以下内容以阿里云镜像加速器为例你需要去阿里云容器镜像服务控制台免费获取专属加速器地址{ registry-mirrors: [ https://your-id.mirror.aliyuncs.com, https://hub-mirror.c.163.com, https://mirror.baidubce.com ] }你可以配置多个镜像源Docker会按顺序尝试。your-id.mirror.aliyuncs.com需要替换成你自己的阿里云加速地址。网易和百度的镜像源可以作为备选。实操心得不要只依赖一个镜像源。有些偏门的镜像可能某个源没有配置多个可以互为备份。阿里云的速度和覆盖率通常比较均衡。保存并退出编辑器在nano中是CtrlX然后按Y确认再按Enter。然后重新加载配置并重启Docker服务使更改生效sudo systemctl daemon-reload sudo systemctl restart docker重启后可以运行docker info在输出结果里查找Registry Mirrors看看你配置的加速器是否已经生效。4.2 调整Docker数据存储路径可选但重要默认情况下Docker的所有数据镜像、容器、卷都存放在/var/lib/docker。如果你的系统根分区/空间不大随着镜像越拉越多很容易就把磁盘撑满。我们可以将数据目录迁移到更大的磁盘分区上。重要警告此操作会移动所有现有Docker数据请在操作前确保没有重要的容器在运行并做好备份。首先停止Docker服务sudo systemctl stop docker假设你想把数据迁移到/home/docker-data目录确保这个目录所在分区有足够空间sudo rsync -avxP /var/lib/docker/ /home/docker-data/这条命令会同步复制所有数据。备份原目录然后修改Docker配置指向新路径。编辑/etc/docker/daemon.json在之前配置的基础上增加>{ registry-mirrors: [...], data-root: /home/docker-data }启动Docker服务sudo systemctl start docker验证新路径是否生效并确认镜像和容器都在docker info | grep Docker Root Dir docker images docker ps -a如果一切正常你可以删除旧的/var/lib/docker目录以释放空间sudo rm -rf /var/lib/docker。这个操作在服务器部署或长期使用Docker的开发机上非常有用能从根本上避免“磁盘已满”的尴尬。4.3 安装并配置Docker Compose虽然我们已经安装了docker-compose-plugin但这里单独提一下因为它的用法和旧版略有不同。Docker Compose是用来管理“多容器应用”的神器。你用一个docker-compose.yml文件就能定义一整套服务比如一个Web应用数据库缓存然后一条命令启动所有。验证插件是否安装成功docker compose version应该输出版本号如Docker Compose version v2.24.0。基本使用示例假设你有一个简单的项目包含一个Python Flask应用和一个Redis。你可以创建一个docker-compose.yml文件version: 3.8 services: web: build: . ports: - 5000:5000 depends_on: - redis redis: image: redis:alpine在这个文件所在目录运行docker compose up -dCompose就会自动构建Web服务镜像拉取Redis镜像并启动两个容器同时建立它们之间的网络连接。-d表示后台运行。管理命令也很直观docker compose down停止并移除所有容器docker compose logs查看日志。5. 安装后常见问题与深度排查指南即使按照最详细的教程在实际操作中也可能遇到问题。下面是我总结的几个最常见的问题及其解决方法。5.1 安装失败依赖包冲突或版本锁定有时运行sudo apt-get install docker-ce会失败提示类似“无法安装因为xxx包需要yyy版本但zzz包提供了aaa版本”的错误。这通常是系统中已有软件包的版本与Docker所需版本冲突。解决方案先尝试全面更新系统sudo apt update sudo apt upgrade。有时更新后冲突就解决了。使用 aptitude 尝试智能解决安装aptitude工具sudo apt install aptitude然后运行sudo aptitude install docker-ce。aptitude会提供几个解决方案比如降级某些包你可以选择最合理的一个。最彻底的方法如果冲突无法解决可以考虑备份数据后使用一个更纯净的Ubuntu系统如新安装的或快照恢复的来安装Docker。5.2 运行报错Cannot connect to the Docker daemon执行docker version或docker ps时出现错误“Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?”排查步骤检查Docker服务状态sudo systemctl status docker。如果没运行启动它sudo systemctl start docker。检查用户组如果你已经执行了usermod -aG docker $USER并重新登录但还是需要sudo可以检查你的当前用户是否在docker组里groups $USER。如果不在可能是重新登录没生效可以尝试重启系统或者直接newgrp docker命令临时切换组只对当前shell有效。检查socket文件权限ls -l /var/run/docker.sock。这个文件的属组应该是docker。如果不是可以手动改一下sudo chown root:docker /var/run/docker.sock。查看详细日志sudo journalctl -u docker.service --since 5 minutes ago查看最近5分钟的Docker服务日志里面可能有更具体的错误信息。5.3 镜像拉取失败TLS handshake timeout 或 net/http: request canceled这几乎都是网络问题特别是连接Docker Hub超时。解决方案首要检查镜像加速器确认/etc/docker/daemon.json里的registry-mirrors配置正确且已重启Docker。这是最可能的原因。测试网络连通性ping download.docker.com看是否能通。如果不通可能是DNS问题尝试修改/etc/resolv.conf使用8.8.8.8或114.114.114.114等公共DNS。使用代理如果你在公司内网或特殊网络环境可能需要为Docker配置HTTP/HTTPS代理。编辑~/.docker/config.json文件没有就创建{ proxies: { default: { httpProxy: http://your-proxy:port, httpsProxy: http://your-proxy:port, noProxy: localhost,127.0.0.1,.internal } } }同时还需要为Docker服务本身配置代理sudo mkdir -p /etc/systemd/system/docker.service.d sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf添加[Service] EnvironmentHTTP_PROXYhttp://your-proxy:port EnvironmentHTTPS_PROXYhttp://your-proxy:port EnvironmentNO_PROXYlocalhost,127.0.0.1,.internal然后sudo systemctl daemon-reload和sudo systemctl restart docker。手动拉取镜像有时可以尝试先通过其他方式下载镜像文件再导入。但这比较麻烦优先解决网络问题。5.4 虚拟机环境报错Virtualization support not detected这个错误常见于在VMware、VirtualBox等虚拟机里安装Docker Desktop for Linux时。但对于我们通过APT安装的Docker Engine也就是本文的方法通常不会遇到此问题因为Docker Engine不依赖宿主机的虚拟化支持VT-x/AMD-V它利用的是Linux内核的cgroups和namespaces特性。如果你在物理机或某些云服务器上安装后运行容器时出现性能问题或奇怪错误可以检查内核是否支持并开启了必要的功能grep -E (vmx|svm) /proc/cpuinfo如果有输出说明CPU支持硬件虚拟化。对于Docker Engine这不是必须的但某些容器运行时如kata-containers需要。对于绝大多数在Ubuntu上使用Docker Engine的场景你完全不必担心虚拟化支持的问题。6. 运维实用干货大礼包脚本与配置好了Docker已经稳稳地跑在你的Ubuntu上了。作为承诺的彩蛋这里分享几个我日常开发和运维中高频使用的脚本和配置片段。你可以把它们保存为脚本文件如docker-clean.sh赋予执行权限chmod x docker-clean.sh然后随时调用能省下大量时间。6.1 一键清理脚本释放磁盘空间Docker用久了会产生很多停止的容器、无用的镜像none、悬空的卷和网络占用大量磁盘空间。这个脚本帮你一键清理。#!/bin/bash # 一键清理Docker无用资源 echo 开始清理Docker磁盘空间... echo 1. 删除所有已停止的容器... docker container prune -f echo 2. 删除所有未被任何容器使用的卷谨慎确保数据已备份... read -p 确认删除未使用的卷(y/N): confirm if [[ $confirm [yY] ]]; then docker volume prune -f else echo 跳过卷清理。 fi echo 3. 删除所有未被使用的镜像悬空镜像... docker image prune -f echo 4. 删除所有未被使用的网络自定义网络... docker network prune -f echo 5. 可选删除所有未被使用的构建缓存需要BuildKit... docker builder prune -f echo 清理完成 echo 当前磁盘使用情况 docker system df使用提示删除卷docker volume prune要特别小心因为卷是持久化数据存储的地方。确保你要删除的卷确实没有被需要的数据。建议先运行docker system df查看详情再决定是否清理。6.2 容器日志管理脚本防止日志撑爆磁盘默认情况下容器日志会无限制地增长可能很快占满磁盘。这个脚本可以定期清理旧日志或者配置日志轮转。方案一运行时限制日志大小推荐在运行容器时直接限制日志文件的最大大小和数量docker run -d \ --name my-app \ --log-driver json-file \ --log-opt max-size10m \ --log-opt max-file3 \ nginx:alpine这样每个容器的日志文件最大10MB最多保留3个文件如my-app-json.log,my-app-json.log.1,my-app-json.log.2。方案二全局配置日志驱动编辑/etc/docker/daemon.json添加日志配置{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }然后重启Docker。这会对所有新创建的容器生效。方案三手动清理脚本对于已经产生的巨大日志文件可以编写脚本查找并清空#!/bin/bash # 查找并清空大于100MB的容器日志文件 find /var/lib/docker/containers/ -name *-json.log -size 100M -exec truncate -s 0 {} \; echo 已清理大日志文件。注意直接删除rm日志文件可能导致Docker无法继续写入日志使用truncate -s 0清空内容更安全。执行此脚本需要sudo权限。6.3 常用Docker命令速查表把下面这个表格保存下来或者贴在便利贴上能覆盖你80%的日常操作场景。操作类别命令说明与常用参数镜像管理docker images列出本地镜像。-a显示所有包括中间层。docker pull nginx:alpine拉取镜像。指定标签如:alpine更小。docker rmi 镜像ID删除镜像。-f强制删除。docker build -t myapp:v1 .构建镜像。-t打标签.是构建上下文路径。容器生命周期docker run -d -p 80:80 --name web nginx运行容器。-d后台-p端口映射--name命名。docker ps查看运行中的容器。-a查看所有包括已停止。docker stop 容器名/ID停止容器。docker start 容器名/ID启动已停止的容器。docker restart 容器名/ID重启容器。docker rm 容器名/ID删除已停止的容器。-f强制删除运行中的。容器交互docker exec -it web /bin/bash进入运行中容器的终端。-it交互式终端。docker logs web查看容器日志。-f实时跟踪--tail 50看最后50行。docker cp file.txt web:/path/在宿主机和容器间复制文件。系统与信息docker system df查看Docker磁盘使用情况。docker stats实时查看容器资源CPU、内存使用情况。docker inspect web查看容器/镜像的详细信息JSON格式。Docker Composedocker compose up -d启动所有服务-d后台。docker compose down停止并移除所有容器、网络。-v同时删除卷。docker compose logs -f查看所有服务的日志。6.4 进阶配置守护进程参数调优对于生产环境或高性能需求场景可以调整Docker守护进程的启动参数。编辑/etc/docker/daemon.json以下是一些常用配置{ registry-mirrors: [https://your-mirror], data-root: /path/to/docker-data, log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 }, storage-driver: overlay2, live-restore: true, iptables: false, userland-proxy: false, experimental: false }storage-driver: 存储驱动。对于Ubuntuoverlay2是默认且最佳选择无需修改。live-restore: 设为true可以在Docker守护进程重启时保持运行的容器不受影响。这对维护很重要。iptables和userland-proxy: 如果你有更高级的网络需求或者宿主机上运行了其他防火墙如firewalld、ufw可能需要调整这些设置。设为false可以避免Docker自动修改iptables规则但需要你手动管理容器网络。experimental: 是否开启实验性功能。除非你需要用到某些预览特性否则保持false。每次修改/etc/docker/daemon.json后都要运行sudo systemctl restart docker使配置生效。修改前最好备份原文件。