学习中心/工程实践/Docker/Docker 进阶:能发上线的镜像,不是只在本机跑

· Docker · 进阶

Docker 进阶:能发上线的镜像,不是只在本机跑

多阶段构建、钉版本、非 root、健康检查。密钥不要写进图层。

正在加载录音…

能跑不等于能发

本机 compose up 只证明你的笔记本行。要给别人、给服务器,镜像得小、得可重复、密钥不能在图层里、进程不要用 root。

  1. 瘦multi-stage
  2. 钉pin tag
  3. 人USER
  4. 活HEALTHCHECK

1. 多阶段:构建和运行分开

编译器、测试、包管理器只在 builder 里。最终镜像只拷产物。少几百兆是常态。

  • 写
    第一阶段:有编译工具FROM node:22-bookworm AS builder
  • 写
    第二阶段:更小的运行基础FROM node:22-bookworm-slim
  • 写
    只把产物拷过来,不要拷 node 的构建缓存COPY --from=builder /app/dist /app/dist

2. 钉住版本,不要 latest

latest 今天和明天可以不是同一个摘要。FROM 和 compose 里都写小版本。对外发,再钉 digest。

  • 标签用你能说清楚的版本,不要 latestdocker build -t ghcr.io/you/myapp:1.4.2 .
  • 看摘要。部署清单里可以写 image@sha256:…docker image inspect --format '{{.RepoDigests}}' ghcr.io/you/myapp:1.4.2

3. 容器里不要 root

默认 root。镜像被打穿,就是宿主机上的特权起点。建一个用户,USER 切过去。

  • 写
    系统用户,固定 uid,方便挂卷时权限稳定RUN useradd --system --uid 10001 app
  • 写
    这行之后的进程不再是 rootUSER app

4. 健康检查

进程在不等于能服务。Compose 和编排器靠 HEALTHCHECK 决定要不要摘掉这个实例。

  • 写
    容器自己报活。没有 wget 就换 curl 或你的二进制HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://127.0.0.1:8000/health || exit 1

5. 推到仓库

  • 先登录。账号和 token 不要写进 Dockerfiledocker login ghcr.io
  • 把这张标签送到仓库。服务器 pull 这一张,不要在服务器上 build 业务镜像docker push ghcr.io/you/myapp:1.4.2

6. 资源先写上

没限制的容器可以吃光那台机器。本机 compose 就可以先写 CPU 和内存,习惯带到后面的编排。

  • 先在本机用上限跑。撑不住现在就知道,不要等生产docker run --rm --cpus=1 --memory=512m myapp:1.4.2

7. Compose 是本地,不是集群

Compose 适合笔记本和单机。多机、滚动、服务发现,是 Kubernetes 或同类编排的事。先把镜像做对,再谈那一层。

瘦、钉、非 root、能探活、能推进仓库,这张镜像才叫能发。密钥仍然只在运行时出现。

同模块

工程实践 →