1. 为什么要在树莓派5上折腾Docker树莓派5这块板子出来之后我第一时间把手头那台跑了三年多的树莓派4换了下来。原因很简单树莓派4的USB 3.0和千兆网卡共享带宽跑几个容器之后IO就顶不住了而树莓派5把PCIe通道单独拉出来USB和网络不再互相抢资源这对容器化部署来说是个质变。但很多人拿到树莓派5之后第一反应是我直接apt install docker.io不就行了。这个做法在树莓派4上勉强能用在树莓派5上却会踩到几个坑系统自带的Docker版本太老不支持新版Compose的某些特性ARM64架构下部分镜像的拉取策略和x86不一样再加上树莓派5默认的Debian Bookworm系统用的是cgroup v2一些老教程里的配置直接照搬会出问题。所以这篇内容我打算把树莓派5上Docker的安装、配置、日常管理、常见故障排查完整讲一遍。适合三类人看一是刚拿到树莓派5想跑容器的新手二是从树莓派4迁移过来发现配置不兼容的老玩家三是想把树莓派5当轻量级家庭服务器用、需要长期稳定运行容器的朋友。我会把每一步为什么这么做讲清楚而不是只丢一堆命令让你复制。先说一个核心结论树莓派5上装Docker不要用系统源里的docker.io要用Docker官方维护的APT仓库。原因后面会详细展开但你可以先记住这个原则。2. 系统准备装Docker之前必须先做的几件事2.1 确认系统版本和架构树莓派5目前主流跑的是Raspberry Pi OS Bookworm基于Debian 12也有部分人刷Ubuntu Server 24.04。这两个系统的包管理逻辑有差异装Docker的步骤也不完全一样。先确认你手上是什么cat /etc/os-release uname -muname -m的输出应该是aarch64。如果是armv7l说明你刷的是32位系统这时候装Docker会遇到一堆镜像架构不匹配的问题。我的建议是树莓派5直接上64位系统别犹豫。树莓派5的BCM2712是四核Cortex-A7664位系统才能发挥它的全部性能而且现在绝大多数官方镜像都有arm64版本32位反而成了累赘。2.2 更新系统并安装基础依赖这一步看起来是例行公事但树莓派5刚发布那段时间官方源的固件包更新比较频繁不更新的话可能会遇到网卡驱动或者PCIe相关的兼容问题。sudo apt update sudo apt full-upgrade -y sudo apt install -y ca-certificates curl gnupg lsb-releaseca-certificates和curl是用来添加Docker官方GPG密钥的gnupg负责密钥管理lsb-release帮我们自动识别系统代号。这几个包在最小化安装的Raspberry Pi OS上可能没有预装所以显式装一遍。注意full-upgrade和upgrade的区别在于前者会处理依赖关系变化可能卸载一些包。树莓派5的内核更新比较频繁用full-upgrade更稳妥。如果你有正在运行的服务升级前先备份。2.3 关于cgroup的坑这是树莓派5上最容易翻车的地方。Debian Bookworm默认启用cgroup v2而Docker从20.10版本开始才完整支持cgroup v2。如果你用的是系统源里的老版本Docker可能会出现容器启动后资源限制不生效、docker stats显示异常等问题。检查当前cgroup版本stat -fc %T /sys/fs/cgroup/如果输出cgroup2fs说明是v2输出tmpfs说明是v1。树莓派5的Bookworm系统基本都是v2。这个信息你记一下后面配置Docker的时候会用到。另外树莓派5默认可能没有启用memory cgroup需要手动在/boot/firmware/cmdline.txt里加参数。不过实测下来只要你装的是Docker官方最新版这一步通常不需要手动做Docker会自动处理。但如果你发现容器内存限制不生效就要回来检查这里。3. 安装Docker官方仓库方案与系统源方案的取舍3.1 为什么不用apt install docker.io系统源里的docker.io包在Debian Bookworm上大概是20.10左右的版本。这个版本有几个问题第一Docker Compose是独立的Python版本docker-compose不是现在的Compose V2插件语法和功能都有差距第二对cgroup v2的支持不完整第三更新滞后遇到安全漏洞修复不及时。Docker官方仓库的方案装出来的是docker-ce社区版版本新、更新快、对ARM64支持好。代价是多几步配置但这是一次性的工作值得。3.2 添加Docker官方GPG密钥和仓库sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg这里用/etc/apt/keyrings而不是老教程里的/etc/apt/trusted.gpg.d是因为后者会把密钥全局信任安全性差一些。--dearmor是把ASCII格式的密钥转成二进制格式APT需要这种格式。然后添加仓库echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null注意这里用的是debian的仓库而不是raspbian。因为Raspberry Pi OS Bookworm本质上是Debian的arm64移植用Debian的arm64仓库完全兼容。如果你刷的是Ubuntu把debian换成ubuntu即可。3.3 安装Docker引擎和Compose插件sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这几个包的分工docker-ce是引擎本体docker-ce-cli是命令行工具containerd.io是底层容器运行时docker-buildx-plugin支持多架构构建docker-compose-plugin就是Compose V2用docker compose命令调用注意中间是空格不是横杠。装完之后验证sudo docker run hello-world如果看到Hello from Docker!就说明装好了。第一次运行会拉取镜像树莓派5的网络性能比4代好不少但国内拉取Docker Hub镜像可能还是慢这个后面讲镜像加速的时候再说。3.4 把当前用户加入docker组默认情况下只有root能跑Docker命令每次都要sudo很烦。把当前用户加到docker组sudo usermod -aG docker $USER然后必须重新登录才生效。你可以退出SSH再连或者直接newgrp docker临时切换。验证docker ps不报权限错误就对了。注意docker组的权限等同于root因为容器可以挂载宿主机任意目录。这是Docker的设计决定不是bug。如果你的树莓派5是多用户共用慎重考虑是否加这个组。4. 树莓派5特有的配置调优4.1 配置daemon.jsonDocker的配置文件在/etc/docker/daemon.json默认可能不存在手动创建sudo nano /etc/docker/daemon.json写入以下内容{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 }, storage-driver: overlay2, exec-opts: [native.cgroupdriversystemd] }逐项解释log-driver和log-opts是限制容器日志大小不加的话日志会无限增长树莓派的存储卡很快就被写满这是新手最容易忽略的问题。storage-driver指定overlay2这是目前性能最好的存储驱动。exec-opts指定cgroup驱动为systemd和Bookworm的init系统保持一致避免资源管理混乱。改完重启Dockersudo systemctl restart docker4.2 镜像加速与拉取策略国内直接拉Docker Hub的镜像速度不稳定。可以配置镜像加速器在daemon.json里加{ registry-mirrors: [https://your-mirror.example.com] }具体用哪个加速地址这里不展开因为可用的地址经常变你可以自行搜索当前可用的。但我要提醒一点加速器只对Docker Hub的官方镜像生效对ghcr.io、quay.io这些第三方registry无效。如果你要拉树莓派相关的镜像比如balena系列、linuxserver系列很多时候是从ghcr或者lscr.io拉的加速器帮不上忙只能靠网络本身。另一个技巧是拉取时指定平台。树莓派5是arm64但有些镜像的latest标签可能指向amd64拉下来跑不了。显式指定docker pull --platform linux/arm64 nginx:alpine4.3 存储位置迁移到外接SSD树莓派5支持PCIe可以接NVMe SSD。如果你打算长期跑容器强烈建议把Docker的数据目录从SD卡迁到SSD。SD卡的随机读写性能和寿命都不适合跑数据库类容器。迁移步骤sudo systemctl stop docker sudo mkdir -p /mnt/ssd/docker sudo rsync -aP /var/lib/docker/ /mnt/ssd/docker/然后在daemon.json里加{ data-root: /mnt/ssd/docker }重启Docker确认数据目录变了sudo systemctl start docker docker info | grep Docker Root Dir注意rsync的时候源目录末尾的斜杠不能少/var/lib/docker/和/var/lib/docker含义不同前者是复制目录内容后者是复制目录本身。这个细节搞错会导致数据路径不对。5. 日常管理容器、镜像、Compose的实操5.1 容器生命周期管理最常用的几条命令我按使用频率排docker ps # 查看运行中的容器 docker ps -a # 查看所有容器包括已停止的 docker logs -f 容器名 # 实时查看日志 docker exec -it 容器名 bash # 进入容器内部 docker stats # 实时查看资源占用docker stats在树莓派5上特别有用因为它的内存只有4GB或8GB跑几个容器之后要盯着内存别爆了。我一般会开一个终端专门跑docker stats观察一段时间。停止和删除docker stop 容器名 docker rm 容器名 docker rm -f 容器名 # 强制删除运行中的容器清理无用资源这个要定期做docker system prune -a # 清理所有未使用的镜像、容器、网络 docker volume prune # 清理未使用的数据卷system prune -a会删掉所有没有被容器使用的镜像包括你手动pull下来还没用的。执行前想清楚。5.2 用Compose管理多容器应用树莓派5上跑单容器的情况其实不多更多是几个容器配合比如一个Web服务加一个数据库。这时候用Compose比手敲docker run命令清晰得多。一个典型的docker-compose.ymlservices: web: image: nginx:alpine ports: - 8080:80 volumes: - ./html:/usr/share/nginx/html restart: unless-stopped depends_on: - db db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: yourpassword volumes: - db_data:/var/lib/mysql restart: unless-stopped volumes: db_data:几个关键点restart: unless-stopped让容器在树莓派重启后自动拉起除非你手动停过它。depends_on只保证启动顺序不保证db真正ready了web才启动这个坑后面讲。数据卷用命名卷db_data而不是绑定挂载性能更好管理也更方便。启动docker compose up -d docker compose logs -f docker compose down注意Compose V2的命令是docker compose空格不是docker-compose横杠。后者是V1的写法已经停止维护了。5.3 树莓派5上的资源限制树莓派5内存有限给容器加限制是必须的。在Compose里services: web: image: nginx:alpine deploy: resources: limits: cpus: 1.0 memory: 512Mcpus: 1.0表示最多用一个核心memory: 512M表示内存上限。注意在非Swarm模式下deploy.resources.limits在Compose V2里是生效的但如果你用的是老版本Compose可能要用mem_limit和cpus这两个顶层字段。实测树莓派5上Compose V2的deploy写法没问题。6. 踩坑实录树莓派5上Docker的典型故障6.1 容器启动报cgroup相关错误现象容器启动失败日志里出现failed to create cgroup或者cannot set memory limit。排查链路先确认cgroup版本前面讲过如果是v2检查daemon.json里的exec-opts是否配了native.cgroupdriversystemd。然后确认内核命令行有没有启用cgroupcat /proc/cmdline | grep cgroup如果没有cgroup_enablememory需要在/boot/firmware/cmdline.txt末尾加上注意是同一行不能换行cgroup_enablememory cgroup_memory1改完重启树莓派。这个坑在树莓派4时代很常见树莓派5的Bookworm系统默认配置好一些但如果你刷的是精简版系统可能还是要手动加。6.2 镜像拉取失败或架构不匹配现象docker pull报no matching manifest for linux/arm64。原因这个镜像没有arm64版本。解决办法有两个一是找替代镜像很多官方镜像都有arm64版本比如nginx、redis、mysql都有二是用--platform参数强制拉amd64版本然后靠QEMU模拟运行但性能会差很多树莓派5上不推荐。排查时先看镜像支持哪些架构docker manifest inspect nginx:alpine | grep architecture6.3 网络不通容器访问不了外网现象容器内ping不通外网或者DNS解析失败。排查步骤先在宿主机上确认网络正常然后进容器测试docker run --rm -it alpine ping -c 3 8.8.8.8如果IP能通但域名不通是DNS问题。检查/etc/docker/daemon.json里有没有配dns或者宿主机的/etc/resolv.conf是否正常。树莓派5上如果用了某些网络管理工具可能会覆盖resolv.conf。如果IP都不通检查iptables规则sudo iptables -L -n -t natDocker会在这里插入NAT规则。如果规则缺失重启Docker服务通常会重新生成。6.4 存储卡写满导致Docker异常这是树莓派上最隐蔽的坑。SD卡写满之后Docker可能表现为容器启动失败、镜像拉取中断、甚至docker ps都卡住。排查df -h du -sh /var/lib/docker/*如果/var/lib/docker/overlay2特别大说明镜像和容器层占了很多空间。清理docker system df # 查看Docker占用概览 docker system prune -a --volumes--volumes会连数据卷一起清理慎用。日常维护建议每周跑一次docker system df看看趋势别等到写满了才处理。7. 长期运行的经验与建议树莓派5跑Docker稳定性比树莓派4好很多但有几个习惯我建议你养成。第一所有容器都配日志轮转。前面daemon.json里的log-opts是全局配置但如果你有某个容器日志特别多可以在Compose里单独给它配logging选项。我见过一个nginx容器因为没配轮转三天写了20GB日志直接把SD卡干满。第二用watchtower之类的工具自动更新镜像要谨慎。自动更新听起来省事但树莓派上镜像更新后可能出现兼容问题尤其是数据库类容器大版本升级可能破坏数据格式。我的做法是手动更新更新前先docker compose pull看有哪些变化确认没问题再up -d。第三定期备份数据卷。Docker的数据卷在/var/lib/docker/volumes/下直接复制这个目录可以备份但更稳妥的方式是用一个临时容器挂载卷然后打包docker run --rm -v db_data:/data -v $(pwd):/backup alpine tar czf /backup/db_data.tar.gz -C /data .这个命令把db_data卷的内容打包到当前目录。恢复的时候反过来操作。第四监控温度。树莓派5跑满负载的时候发热不小如果容器持续高负载建议加散热片或者风扇。查看温度vcgencmd measure_temp超过80度就要考虑降负载或者加强散热了长期高温会影响SD卡和板子寿命。最后说一个我自己的体会树莓派5上跑Docker最大的瓶颈不是CPU也不是内存而是存储IO。如果你认真想把它当服务器用一块NVMe SSD是必须的投资比换更大的内存条管用得多。我现在的配置是8GB版本加256GB NVMe跑十几个容器毫无压力docker stats里CPU常年个位数内存用了不到一半。这套配置的性价比比买一台低功耗x86小主机高不少。