1. 项目概述:为什么要在Ubuntu上安装Docker?
如果你是一名开发者、运维工程师,或者正在学习云原生技术,那么Docker几乎是你绕不开的工具。它通过容器化技术,将应用及其所有依赖打包成一个标准化的单元,实现了“一次构建,处处运行”的梦想。而Ubuntu,作为最流行、社区支持最完善的Linux发行版之一,是运行Docker的绝佳平台。无论是个人开发机、测试服务器还是生产环境,Ubuntu + Docker的组合都极为常见。
这篇教程的目的,就是带你从零开始,在Ubuntu系统上完成Docker引擎的完整安装与基础配置。这不仅仅是敲几条命令,我会详细解释每一步背后的逻辑,分享我多年在Ubuntu服务器上部署Docker踩过的坑和总结的技巧。无论你是刚接触Linux的新手,还是想系统梳理安装流程的老手,都能从这里获得可以直接“抄作业”的可靠方案。我们将覆盖从系统准备、官方源安装、到权限配置、镜像加速以及验证测试的全过程,确保你安装的Docker既稳定又好用。
2. 安装前的核心准备与系统检查
在动手安装之前,充分的准备工作能避免至少80%的后续问题。很多人安装失败,问题往往出在这一步。
2.1 系统版本与内核确认
首先,你需要确认你的Ubuntu版本。Docker对系统版本有要求,通常需要64位的Ubuntu Jammy 22.04 (LTS)、Focal 20.04 (LTS) 或 Bionic 18.04 (LTS)。打开终端,执行以下命令:
lsb_release -a你会看到类似Description: Ubuntu 22.04.3 LTS的输出。确保是上述支持的LTS版本。非LTS版本虽然也可能运行,但长期支持版本在稳定性和社区支持上更有保障。
接下来,检查内核版本。Docker需要较新的内核来支持其核心功能(如cgroups、命名空间)。运行:
uname -r我建议内核版本至少在4.x以上,对于Ubuntu 20.04/22.04,默认内核都满足要求。这一步主要是为了排除一些极度老旧或自定义裁剪过的系统。
2.2 卸载可能的旧版本
如果你的系统上曾经安装过旧版本的Docker(可能叫docker、docker.io或docker-engine),必须先彻底清理,否则会导致冲突。执行以下命令组:
sudo apt-get remove docker docker-engine docker.io containerd runc注意,apt-get remove不会删除镜像、容器、卷等数据文件,它们通常存放在/var/lib/docker/。如果你需要全新开始,可以手动删除这个目录(sudo rm -rf /var/lib/docker),但务必谨慎,这会导致所有Docker数据丢失。
2.3 安装必备工具与配置APT源
为了让安装过程更顺畅,我们先安装一些用于HTTPS传输和软件源管理的工具:
sudo apt-get update sudo apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release关键一步:添加Docker官方GPG密钥和APT软件源。这是为了确保我们从官方渠道获取可信的软件包,并享受自动更新。不要使用某些过时教程里第三方源,那可能导致版本滞后或安全隐患。
添加Docker官方的GPG密钥:
sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg这条命令创建了密钥环目录,并下载、导入Docker的官方签名密钥。
设置稳定版(stable)仓库。以下命令适用于
amd64/x86_64架构的Ubuntu。如果你用的是ARM架构(如树莓派、苹果M芯片),需要将命令中的$(dpkg --print-architecture)部分替换为arm64。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这个命令会根据你的系统版本(如
jammy)自动生成正确的源地址。
注意:网络环境可能导致
curl下载密钥或访问软件源缓慢或失败。如果遇到问题,可以尝试重试,或检查网络连接。这是第一个常见的坑点。
3. Docker引擎的安装与核心配置
完成准备工作后,就可以开始安装Docker引擎本身了。
3.1 执行安装命令
首先,更新APT包索引,使其包含我们新添加的Docker仓库:
sudo apt-get update然后,安装Docker引擎、命令行工具、容器运行时Containerd以及插件组件:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin这里解释一下各个包的作用:
docker-ce: Docker社区版引擎,核心。docker-ce-cli: Docker命令行接口,让你能用docker命令与引擎交互。containerd.io: 行业标准的容器运行时,Docker底层依赖它来管理容器生命周期。docker-compose-plugin: 这是新的Docker Compose V2,作为插件安装,通过docker compose命令使用。比独立的Python版Compose更集成、高效。
安装过程中,APT会解析依赖并提示你确认安装。按下Y并回车继续。
3.2 管理Docker服务与开机自启
安装完成后,Docker服务(docker.service)不会自动启动。我们需要启动它,并设置为开机自启,这对于服务器环境尤为重要。
# 启动Docker服务 sudo systemctl start docker # 设置Docker服务开机自启 sudo systemctl enable docker # 检查Docker服务状态,确认其处于活跃(active)运行状态 sudo systemctl status docker执行status命令后,你应该看到绿色的active (running)字样。如果看到失败(failed)状态,通常需要查看日志排查:sudo journalctl -xu docker.service。
3.3 非root用户权限配置(至关重要)
默认情况下,执行docker命令需要sudo权限。每次命令前都加sudo非常麻烦,而且某些图形化工具或IDE集成也会因此失败。安全的做法是将你的用户加入docker用户组。
# 将当前登录用户加入docker组 sudo usermod -aG docker $USER重要提示:执行此命令后,权限变更不会立即生效。你需要完全退出当前终端会话,并重新登录,或者新开一个终端窗口。之后,你就可以直接运行docker命令,而不需要sudo了。
验证是否成功:
docker version如果能正常显示Client和Server版本信息,说明安装和权限配置都成功了。
实操心得:很多人配置完用户组后忘记注销重登录,然后疑惑为什么还要
sudo。这是一个高频“坑点”。另外,在生产服务器上,请谨慎添加用户到docker组,因为这意味着该用户拥有了等同于root的权限(docker守护进程以root运行)。
4. 验证安装与基础操作测试
安装完成并配置好权限后,我们必须进行测试,确保Docker能正常工作。
4.1 运行经典测试容器
最经典的测试是运行一个简单的hello-world容器:
docker run hello-world这条命令会执行以下动作:
- Docker客户端联系守护进程。
- 守护进程发现本地没有
hello-world镜像。 - 守护进程从默认的Docker Hub仓库拉取(pull)该镜像。
- 拉取成功后,守护进程根据该镜像创建一个新的容器并运行。
- 容器内的程序执行,输出一段欢迎信息(如 “Hello from Docker!”)后退出。
如果你能看到完整的欢迎信息,恭喜你,Docker安装成功!
4.2 运行一个实用的交互式容器
为了进一步测试,我们可以运行一个更实用的容器,比如Ubuntu容器,并与之交互:
docker run -it --rm ubuntu:22.04 bash参数解释:
-it:-i保持标准输入打开,-t分配一个伪终端,合起来让我们可以交互式操作容器。--rm: 容器退出后自动删除其文件系统,避免留下无用的停止的容器。ubuntu:22.04: 指定要运行的镜像及其标签。bash: 容器启动后要执行的命令。
执行后,你会进入容器内部的bash shell。可以尝试运行cat /etc/os-release查看系统信息,或者ls /查看根目录。输入exit或按Ctrl+D退出容器。由于使用了--rm参数,这个容器实例会被自动清理。
5. 配置优化与镜像加速
默认安装的Docker可以工作,但针对国内网络环境和个人使用习惯,进行一些优化配置能极大提升体验。
5.1 配置国内镜像加速器
从Docker Hub拉取镜像在境内可能非常缓慢。我们可以配置镜像加速器,将拉取请求代理到国内的镜像站点。这里以阿里云镜像加速器为例(需要注册阿里云账号获取专属地址),其他服务商(如腾讯云、网易云镜像中心)同理。
- 登录阿里云容器镜像服务控制台,在“镜像工具”->“镜像加速器”中,找到你的专属加速器地址,形如
https://xxxx.mirror.aliyuncs.com。 - 编辑Docker守护进程配置文件
/etc/docker/daemon.json(如果不存在则创建):sudo nano /etc/docker/daemon.json - 输入以下内容(将
your-mirror-address替换为你的实际地址):
你可以配置多个镜像源,用逗号分隔。{ "registry-mirrors": ["https://your-mirror-address.mirror.aliyuncs.com"] } - 保存并退出编辑器(在nano中按
Ctrl+X,然后Y,再回车)。 - 重新加载配置并重启Docker服务:
sudo systemctl daemon-reload sudo systemctl restart docker - 验证加速器是否生效:
在输出信息中查找docker infoRegistry Mirrors部分,应该能看到你配置的镜像地址。
5.2 数据目录与日志配置(可选)
默认情况下,Docker的所有镜像、容器、卷数据都存放在/var/lib/docker,日志可能比较庞大。如果你的系统根目录空间不大,可以考虑在安装初期就将数据目录迁移到更大的磁盘分区。这通常在初始化安装时规划,后期迁移较复杂。此外,可以在daemon.json中配置日志驱动和大小限制,防止日志撑爆磁盘:
{ "registry-mirrors": ["..."], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }这样配置后,每个容器的日志文件最大为10MB,最多保留3个文件,旧的会被自动删除。
6. 安装Docker Compose(独立版本)
虽然我们已经安装了docker-compose-plugin(使用docker compose命令),但有些老项目或脚本可能仍依赖旧的、独立的Python版Docker Compose(使用docker-compose命令)。为了兼容,可以额外安装它。
从Docker Compose的GitHub Release页面下载指定版本二进制文件到系统路径是最推荐的方式:
# 下载最新稳定版(请查看GitHub Release页面获取最新版本号) sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 授予二进制文件可执行权限 sudo chmod +x /usr/local/bin/docker-compose # 验证安装 docker-compose --version注意事项:现在有了
docker compose(插件版)和docker-compose(独立版)两个命令。它们功能几乎相同,但插件版与Docker CLI集成更好,无需单独管理。建议新项目优先使用docker compose。
7. 常见问题与故障排查实录
即使按照教程操作,你也可能遇到一些问题。这里记录了我遇到过的典型问题及其解决方案。
7.1 安装时依赖包冲突或报错
问题描述:执行sudo apt-get install docker-ce ...时,报错提示某些包无法安装或存在依赖冲突。
排查思路:
- 确保源正确:再次检查
/etc/apt/sources.list.d/docker.list文件内容是否正确,特别是Ubuntu版本代号。 - 彻底清理旧版本:确认之前是否用
snap或其他方式安装过Docker?运行snap list | grep docker和which docker查看。如果有,用sudo snap remove docker移除。 - 更新并修复依赖:
sudo apt-get update sudo apt-get install -f # 尝试修复依赖 sudo apt-get autoremove # 移除无用包 - 尝试指定版本:如果最新版有兼容问题,可以列出可用版本并安装一个稍旧的稳定版:
apt-cache madison docker-ce # 列出可用版本 sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
7.2 Docker服务启动失败
问题描述:sudo systemctl status docker显示状态为failed。
排查步骤:
- 查看详细日志:这是最重要的步骤。
日志通常会明确指出问题,例如:sudo journalctl -xu docker.service --no-pager -n 50- 权限问题:
/var/run/docker.sock权限不对。 - 存储驱动问题:
overlay2驱动所需的内核模块未加载或文件系统不支持。 - cgroup问题:与systemd的cgroup管理器不兼容。
- 权限问题:
- 检查存储驱动:Ubuntu通常使用
overlay2。确保你的内核版本支持,并且/var/lib/docker所在文件系统是支持的(如ext4, xfs)。可以尝试在/etc/docker/daemon.json中明确指定:{ "storage-driver": "overlay2" } - 检查防火墙:如果使用了UFW等防火墙,确保没有阻止Docker的网络流量。Docker会操作iptables规则,有时与UFW冲突。可以考虑在UFW中为Docker放行,或调整Docker的iptables策略。
7.3 用户加入docker组后仍无权限
问题描述:执行usermod命令并重新登录后,运行docker ps仍报错Got permission denied。
排查步骤:
- 确认用户是否在组中:
查看输出是否包含groups $USERdocker。 - 重启Docker服务(有时需要):
sudo systemctl restart docker - 检查
/var/run/docker.sock的权限:
通常应该是ls -l /var/run/docker.socksrw-rw---- 1 root docker ...。如果你的用户不在docker组,或者该文件权限异常,就会出错。可以尝试手动更改组:sudo chown root:docker /var/run/docker.sock - 终极方案:如果以上都不行,尝试完全注销图形界面或SSH会话,然后重新登录,而不仅仅是新开一个终端标签页。
7.4 拉取镜像速度极慢或超时
问题描述:docker pull速度很慢,甚至卡住不动最终超时。
解决方案:
- 确认镜像加速器配置正确:严格按照5.1节步骤操作,并确保
docker info中显示了你的镜像地址。 - 尝试其他镜像源:在
daemon.json的registry-mirrors数组中添加多个国内源,Docker会依次尝试。 - 检查DNS:Docker拉取镜像需要域名解析。可以尝试修改Docker的DNS设置,在
daemon.json中加入:
然后重启Docker服务。{ "dns": ["8.8.8.8", "114.114.114.114"] } - 直接使用国内镜像仓库:对于一些常用镜像(如
ubuntu,nginx,redis),可以直接从阿里云、腾讯云的公开镜像仓库拉取,例如:docker pull registry.cn-hangzhou.aliyuncs.com/library/ubuntu:22.04
7.5 运行容器时端口冲突或无法访问
问题描述:使用-p 80:80映射端口时,报错port is already allocated,或者映射后从宿主机无法访问容器服务。
排查思路:
- 检查端口占用:
查看是哪个进程占用了宿主机的80端口。sudo ss -tulpn | grep :80 - 检查防火墙:宿主机防火墙(如UFW)可能阻止了对外部访问的放行。需要允许该端口:
sudo ufw allow 80/tcp - 理解网络模式:默认的
bridge网络下,-p参数会将容器端口映射到宿主机所有接口(0.0.0.0)。如果你只想映射到本地回环,可以指定-p 127.0.0.1:80:80。
8. 进阶配置与日常使用建议
完成基础安装和排错后,这里有一些进阶配置和使用习惯的建议,能让你的Docker体验更上一层楼。
8.1 配置日志轮转与资源限制
Docker默认的日志如果不加管理,会无限增长。除了在daemon.json中全局配置,也可以在运行容器时单独指定日志选项:
docker run --log-opt max-size=10m --log-opt max-file=3 your-image对于资源限制,避免某个容器耗尽所有资源影响宿主机:
# 限制容器最多使用1个CPU核心和512MB内存 docker run -it --cpus="1.0" --memory="512m" ubuntu:22.04 bash8.2 使用别名简化常用命令
你可以将一些常用的、冗长的Docker命令设置为Shell别名,添加到~/.bashrc或~/.zshrc中:
# 查看所有容器(包括已停止的) alias dps='docker ps -a' # 查看所有镜像 alias dimg='docker images' # 停止所有运行中的容器 alias dstop='docker stop $(docker ps -q)' # 删除所有已停止的容器 alias drm='docker rm $(docker ps -aq)' # 删除所有悬空镜像(未被任何容器引用的中间层镜像) alias dprune='docker image prune -f'8.3 数据持久化与卷管理的最佳实践
容器本身是无状态的,删除容器后,其内部产生的数据也会丢失。持久化数据有几种方式:
- 绑定挂载(Bind Mount):将宿主机目录直接挂载到容器。适合开发环境,修改即时同步。
docker run -v /path/on/host:/path/in/container your-image - 命名卷(Named Volume):由Docker管理的存储卷,与宿主机路径解耦,是生产环境更推荐的方式。
卷可以通过docker run -v my-data-volume:/path/in/container your-imagedocker volume create创建和管理。 - Dockerfile中的VOLUME指令:在镜像构建时声明匿名卷,提醒运行时应挂载外部存储。
核心建议:对于数据库(如MySQL)、配置文件、应用日志等需要持久化的数据,务必使用-v参数进行挂载,切勿依赖容器内部存储。
8.4 镜像构建与Dockerfile基础
学会使用Docker后,下一步就是构建自己的镜像。Dockerfile是构建镜像的蓝图。一个简单的Python应用Dockerfile示例如下:
# 使用官方Python轻量级镜像作为基础 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 将当前目录的依赖文件复制到容器工作目录 COPY requirements.txt . # 安装依赖 RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY . . # 声明容器运行时监听的端口 EXPOSE 8080 # 定义容器启动时执行的命令 CMD ["python", "app.py"]构建镜像:docker build -t my-python-app .运行容器:docker run -p 8080:8080 my-python-app
掌握Dockerfile的编写,你才能真正发挥Docker的威力,实现应用环境的标准化封装。