在树莓派4B的Ubuntu上部署Docker:一份面向ARM开发者的深度实践指南

如果你和我一样,喜欢在树莓派这类小巧但潜力无限的ARM设备上“折腾”,那么容器化技术绝对是你绕不开的一环。想象一下,在巴掌大的板子上,轻松地部署、隔离和管理多个应用服务,无论是搭建个人网盘、智能家居中枢,还是作为轻量级的CI/CD构建节点,Docker都能让这一切变得优雅而高效。然而,在ARM架构上,特别是资源相对受限的树莓派4B上,安装和配置Docker的过程与x86平台有些许不同,尤其是在软件源和镜像加速方面,一个正确的配置能为你省下大量时间和带宽。

这篇文章,就是为你——一位在ARM边缘进行探索的开发者或爱好者——准备的实战手册。我们将不满足于简单的命令罗列,而是深入每一步背后的逻辑,探讨在Ubuntu系统上为ARM64架构量身定制Docker环境的完整流程,并重点解决国内网络环境下的镜像拉取难题。你会发现,从系统准备到第一个容器成功运行,整个过程充满了对细节的掌控感。

1. 环境审视与前期准备:为Docker铺平道路

在动手安装任何软件之前,花几分钟了解你的“战场”是至关重要的。对于树莓派4B,我们首先需要确认两件事:操作系统的具体版本和CPU的架构。这直接决定了后续软件源的配置是否正确。

打开终端,执行以下命令来获取系统信息:

lsb_release -a
uname -m

第一条命令会输出类似“Ubuntu 22.04.3 LTS”的信息,其中的代号(如“jammy”)是我们配置软件源的关键。第二条命令则确认架构,对于树莓派4B,你应该看到 aarch64arm64,两者在Linux语境下通常指代同一架构。

注意:虽然树莓派官方推荐使用Raspberry Pi OS,但许多开发者偏爱Ubuntu Server for ARM,因为它拥有更广泛的软件生态和更熟悉的包管理体验。本文基于Ubuntu,但核心思路同样适用于其他基于Debian的发行版。

接下来,我们需要清理可能存在的旧版本Docker,以避免冲突。Docker的旧称或社区版本有时会残留,使用apt的remove命令进行清理是稳妥的第一步:

sudo apt remove docker docker-engine docker.io containerd runc -y

这个命令移除了可能与新版本冲突的软件包。-y参数用于自动确认,但在生产环境或关键系统中,我建议你先不加-y,看一眼将要移除的包列表再确认。

安装核心依赖:为了让apt包管理器能够通过HTTPS协议安全地获取软件,我们需要安装几个基础工具。这不仅仅是“照着做”,理解它们的作用能让你在遇到网络问题时自行排查:

  • apt-transport-https:允许apt通过HTTPS源下载软件包。在现代网络环境下,这几乎是标配。
  • ca-certificates:提供权威机构颁发的SSL证书,用于验证HTTPS连接的安全性,防止中间人攻击。
  • curl:一个强大的命令行数据传输工具,我们用它来下载GPG密钥。
  • software-properties-common:它提供了add-apt-repository这个神器,能让我们以更优雅的方式添加PPA或第三方软件源。

使用一条命令完成安装和系统更新:

sudo apt update && sudo apt install -y apt-transport-https ca-certificates curl software-properties-common

这里的&&操作符表示前一条命令成功执行后,才执行后一条。先update更新本地软件包索引,再install安装,是一个好习惯。

2. 添加Docker官方与国内镜像源:速度与稳定的抉择

这是整个安装过程中最具技巧性的一步。Docker官方为不同的Linux发行版和架构维护着软件仓库。对于树莓派上的ARM64 Ubuntu,我们必须指定正确的架构和系统代号。

首先,需要添加Docker的GPG公钥。GPG密钥用于验证从软件源下载的软件包是否来自可信的发布者,没有被篡改。我们可以从官方获取,但考虑到网络连通性,同时添加国内镜像源的密钥是更保险的做法。

添加阿里云镜像源的GPG密钥

curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

让我拆解一下这个命令:

  • curl -fsSL-f 表示在服务器错误时静默失败,-s 静默模式(不显示进度条),-S 在静默模式下如果出错则显示错误,-L 自动跟随重定向。组合起来就是为了在脚本中可靠地下载内容。
  • |:管道符,将curl下载的内容传递给后面的命令。
  • sudo apt-key add -apt-key add用于将密钥添加到APT的可信密钥列表中,末尾的-表示从标准输入(即管道传过来的内容)读取密钥。

添加Docker官方GPG密钥(备用)

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

两个密钥都添加可以增加冗余。完成后,可以用sudo apt-key fingerprint 0EBFCD88来验证指纹(指纹ID可能随版本变化,可通过Docker文档查询)。

接下来,添加软件源本身。这里必须特别注意[arch=arm64]这个参数,它明确告诉系统,我们要添加的是适用于ARM64架构的仓库,而不是默认的amd64。

添加阿里云Docker CE镜像源

sudo add-apt-repository "deb [arch=arm64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

添加Docker官方源(备用)

sudo add-apt-repository "deb [arch=arm64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

命令中的$(lsb_release -cs)会自动获取你当前系统的发行版代号(例如jammy),确保源与系统版本匹配。stable代表稳定版频道,如果你需要体验前沿功能,可以替换为testnightly,但这在树莓派的生产环境中不推荐。

添加完成后,务必再次更新软件包列表,让系统识别新加的源:

sudo apt update

此时,你可以用apt-cache policy docker-ce命令查看可安装的Docker版本,它会列出所有可用版本及其对应的软件源,帮助你确认源是否添加成功。

3. 安装Docker CE与基础验证

当源配置无误后,安装Docker社区版(CE)就变得非常简单:

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

这里我们一次性安装了核心组件:

  • docker-ce:Docker守护进程和客户端。
  • docker-ce-cli:命令行接口。
  • containerd.io:行业标准的容器运行时,Docker在其之上构建。
  • docker-buildx-plugin:支持多平台构建的扩展。
  • docker-compose-plugin:将docker-compose功能集成到Docker CLI中。

安装完成后,Docker服务会自动启动。我们可以通过以下命令来验证服务状态和安装是否成功:

sudo systemctl status docker --no-pager -l

这个命令会显示Docker服务的详细状态。--no-pager确保输出全部内容而不进入分页器,-l显示完整的日志。你应该看到“active (running)”的状态。

更直接的验证是运行一个经典的“Hello World”容器:

sudo docker run --rm hello-world

如果一切顺利,你将在终端看到来自Docker的欢迎信息,报告你的安装看起来工作正常。这个--rm参数非常有用,它会在容器退出后自动清理其文件系统,避免留下无用的停止状态容器。

4. 配置镜像加速与用户权限优化

成功运行hello-world只是第一步。在实际使用中,从Docker Hub拉取镜像的速度可能不尽人意,尤其是较大的镜像。为此,配置一个国内的镜像加速器是必选项。国内多家云服务商提供了免费的Docker镜像加速服务。

配置镜像加速器:Docker守护进程的配置通常位于/etc/docker/daemon.json。如果文件不存在,我们创建它;如果存在,请谨慎编辑,避免破坏原有配置。

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://<你的镜像加速器地址>.mirror.aliyuncs.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://registry.docker-cn.com"
  ],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

提示:上述配置中包含了阿里云、中科大和Docker中国官方镜像地址。你需要将<你的镜像加速器地址>替换为你在阿里云容器镜像服务控制台获取的专属加速地址(通常需要登录阿里云账号免费开通)。同时配置多个镜像源,Docker会按顺序尝试,增加拉取成功率。

配置文件中其他参数也值得关注:

  • "exec-opts": ["native.cgroupdriver=systemd"]:让Docker使用systemd作为cgroup驱动,与Ubuntu系统更好地集成。
  • log-driverlog-opts:限制容器日志大小,防止日志文件占满树莓派有限的存储空间。
  • storage-driver:指定存储驱动,overlay2是当前推荐且高性能的驱动。

应用配置并重启Docker服务:

sudo systemctl daemon-reload
sudo systemctl restart docker

解决权限问题:默认情况下,只有root用户和docker用户组的成员才能执行Docker命令。为了避免每次都要输入sudo,将你的普通用户加入docker组是标准做法:

sudo usermod -aG docker $USER

执行此命令后,你必须完全退出当前终端会话并重新登录,或者启动一个新的终端窗口,用户组变更才会生效。之后,你就可以直接使用docker ps等命令,而无需sudo了。

验证配置是否生效,可以运行:

docker info

在输出信息中,寻找Registry Mirrors部分,确认你配置的镜像加速地址已经列在其中。

5. 实战演练:在ARM64上拉取与运行常用镜像

理论配置完成,让我们进行一些实战操作,感受一下在树莓派上使用Docker的便利,并理解ARM架构的特别之处。

拉取一个ARM兼容的镜像:并非所有Docker Hub上的镜像都提供了ARM64版本。在拉取时,我们可以显式指定标签,或者使用--platform参数。例如,拉取官方的ARM64版Nginx:

docker pull nginx:alpine

alpine标签的镜像基于Alpine Linux,体积非常小,非常适合树莓派。你可以使用docker images查看拉取的镜像,注意其ARCHITECTURE列。

运行一个简单的Web服务

docker run -d --name my-nginx -p 8080:80 nginx:alpine
  • -d:后台运行。
  • --name:给容器起个名字,便于管理。
  • -p 8080:80:将宿主机的8080端口映射到容器的80端口。

现在,用浏览器访问树莓派的IP地址的8080端口(如http://<树莓派IP>:8080),你应该能看到Nginx的欢迎页面。

使用Docker Compose部署多服务应用:由于我们安装了docker-compose-plugin,可以直接使用docker compose命令(注意是空格,不是横杠)。创建一个docker-compose.yml文件来定义和运行一个更复杂的应用栈,例如包含Web应用和数据库:

version: '3.8'
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
  db:
    image: arm64v8/mysql:oraclelinux8 # 专门为ARM64构建的MySQL镜像
    environment:
      MYSQL_ROOT_PASSWORD: example_password
    volumes:
      - db_data:/var/lib/mysql
volumes:
  db_data:

在包含该文件的目录下,运行docker compose up -d即可启动所有定义的服务。这种声明式的方式极大地简化了多容器应用的管理。

6. 性能调优、存储管理与故障排查

在资源有限的树莓派上,让Docker高效稳定地运行需要一些额外的技巧。

资源限制与监控:默认情况下,容器可以使用宿主机的所有资源。为了避免某个容器耗尽树莓派的CPU或内存,可以在运行容器时施加限制:

docker run -d --name limited-nginx --memory="512m" --cpus="1.5" nginx:alpine

这限制了容器最多使用512MB内存和1.5个CPU核心。使用docker stats命令可以实时查看所有运行容器的资源使用情况。

存储管理策略:树莓派的SD卡或SSD存储空间和IO性能有限。Docker的镜像、容器和卷会占用大量空间。定期清理无用资源至关重要:

# 删除所有已停止的容器
docker container prune -f
# 删除所有未被任何容器引用的镜像(悬空镜像)
docker image prune -f
# 删除所有未被使用的卷(谨慎操作,确保数据已备份)
docker volume prune -f
# 一键清理所有无用对象
docker system prune -f

考虑将Docker的数据根目录迁移到外接USB 3.0 SSD硬盘上,可以显著提升IO性能并节省SD卡寿命。这需要修改Docker的启动配置,编辑/etc/docker/daemon.json,添加"data-root": "/path/to/your/external/drive/docker"字段,然后迁移数据并重启Docker。

常见故障排查

  1. “Permission denied”错误:确保当前用户已加入docker组,并且已重新登录终端。
  2. 镜像拉取失败:首先检查docker info中的镜像加速器配置是否正确。尝试使用docker pull --platform linux/arm64 <镜像名>明确指定平台。对于非官方镜像,可能需要寻找专门为ARM构建的版本(标签常包含arm64v8aarch64linux/arm64)。
  3. 容器启动失败:使用docker logs <容器名>查看容器的日志输出,这是最直接的排查手段。
  4. 端口冲突:使用sudo netstat -tulpn | grep :<端口号>检查端口是否已被其他进程占用。

在树莓派这类设备上玩转Docker,最大的乐趣在于用极低的成本和能耗,构建出稳定可靠的服务。我自己的树莓派4B,8GB内存版本,常年运行着十多个容器,包括家庭媒体服务器、自动化工具和开发环境,从未让我失望。关键在于理解其特性,做好资源规划和监控,这小小的板子能发挥的能量远超你的想象。

更多推荐