ARM64 云服务器跑 Docker:从镜像选型到 systemd 常驻的五个细节
前阵子把手上一台 ARM64 架构的云主机(Neoverse 平台)从“SSH 上去手动跑脚本”改成了 Docker 托管 + systemd 常驻。过程不算复杂,但有几个细节如果没提前想到,排查起来会绕很远。这篇把踩过的坑按顺序记一下,给同样在 ARM 云主机上跑容器的同学省点时间。
一、镜像架构要显式确认,不要想当然
在 x86 上写好的 Dockerfile,直接搬到 ARM 主机上构建通常没问题,问题出在“拉现成镜像”这一步:很多第三方镜像只发布了 amd64 一个架构,拉下来启动就报 exec format error,很容易被误判成程序本身有问题。
docker manifest inspect nginx:stable | grep -A2 architecture
docker image inspect nginx:stable -f '{{.Architecture}}'
# 期望输出:arm64
官方镜像基本都是多架构 manifest,选型时优先用官方镜像或者带 arm64v8 前缀的镜像,能省掉大量试错。
二、Dockerfile 里不要写死架构相关的二进制
镜像本身是多架构的,但 Dockerfile 里 ADD 下载的 release 包往往是单一架构。比如某个工具同时提供 linux-amd64 和 linux-arm64 两个包,写死前者,镜像能构建成功,运行时才崩。
稳妥的写法是用 TARGETARCH 做分支,构建时让 BuildKit 自动注入:
ARG TARGETARCH
RUN curl -fsSL -o /tmp/tool.tgz \
https://example.com/tool-linux-${TARGETARCH}.tar.gz \
&& tar -xzf /tmp/tool.tgz -C /usr/local/bin
三、挂载目录的 UID 要和容器内用户对齐
宿主机上以普通用户创建的目录,挂进容器后容器内进程如果不是同一个 UID,就会出现“目录存在但写不进去”,日志里只报 Permission denied,看不出是谁的问题。
两种处理方式:一是容器启动时用 --user $(id -u):$(id -g) 对齐身份;二是在宿主机上把目录 chown 给容器内运行用户的 UID。后者更省事,但迁移主机时要记得一起迁。
四、日志一定要设上限
默认的 json-file 日志驱动没有大小限制。一个每秒写几行的服务,跑上几个月就能把系统盘写满,然后整台机器上的容器一起挂。这个坑不常遇到,遇到一次就很难受。
{
"log-driver": "json-file",
"log-opts": { "max-size": "50m", "max-file": "3" }
}
写进 /etc/docker/daemon.json 后重启 Docker 生效,只影响新创建的容器,老容器要重建。
五、常驻交给 systemd,不要靠 --restart 硬扛
--restart always 能解决进程崩溃自启,但解决不了“Docker 服务本身没起来”“需要按顺序依赖网络”这类情况。用 systemd 托管 Compose 项目更清晰:
[Unit]
Description=myapp
Requires=docker.service
After=docker.service network-online.target
[Service]
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
这样开机顺序、失败重试、日志归集都交给系统,systemctl status myapp 一眼能看到当前状态,比翻 docker ps 可靠得多。
小结
ARM 云主机跑容器本身没有额外门槛,真正花时间的是“架构不匹配”和“权限不对”这两类静默失败。把镜像架构、挂载权限、日志上限、常驻方式这四件事在部署前定好,后面基本就不用再动了。
- 点赞
- 收藏
- 关注作者
评论(0)