Files
order_site/deploy/docker/backend.Dockerfile
T
yml2213 56ca479c6b chore(deploy): 基础镜像源改为可配置 BASE_REGISTRY,并提前补齐 FROM 基础镜像
## 修的是什么

线上部署卡死过一次:daocloud 加速源返回 502 Bad Gateway,整轮构建在 load metadata
阶段就失败,而服务器 daemon.json 里另外两个 registry-mirrors 完全帮不上忙。

原因是**显式写死的 registry 会绕过 daemon.json 的 registry-mirrors**:
Dockerfile 里 `FROM docker.m.daocloud.io/library/node:...` 属于显式指定 registry,
镜像列表对它就失效了,于是这个源成了构建的单点故障。

## 修法

1. 四个 Dockerfile(backend / frontend / backend-dev / dev-caddy)的 `FROM` 改用
   `${BASE_REGISTRY}`(registry 前缀语义),默认值 docker.m.daocloud.io 保持不变;
2. docker-compose.yml / docker-compose.dev.yml 的 `build.args` 接上
   `${BASE_REGISTRY:-docker.m.daocloud.io}`,并把 postgres / minio / node / caddy
   这几处 `image:` 也改成同一变量,整套编排只有一个换源开关;
3. 部署脚本:新增 resolve_base_registry()(读 .env 的 BASE_REGISTRY,缺省同 compose),
   --dry-run 的基础镜像 digest 预检沿用同一变量;
   新增 ensure_dockerfile_base_images(),在 pull_base_images 阶段把 Dockerfile 里
   `FROM` 用到的基础镜像提前补齐 —— 这类镜像不归 `docker compose pull` 管,
   本地缺失要拖到构建阶段才报错,且报错信息晦涩,看不出来是"源挂了"还是"代码写错了";
   现在缺失时明确提示并给出换源/离线搬运两条排障路径;
4. .env.server.example 增加 BASE_REGISTRY 说明(推荐多源容灾时设 docker.io,
   走 daemon 的 registry-mirrors 列表自动故障转移)。

## 验证

- docker compose config:默认值下所有镜像引用与改动前逐字一致(不会触发重新下载);
  BASE_REGISTRY=docker.1panel.live / docker.io 时全部引用正确替换;
- docker buildx build --call=check -f deploy/docker/backend.Dockerfile:Check complete, no warnings;
- deploy/ubuntu-deploy.sh bash -n 通过;
- 生产实测:预拉三个基础镜像后,buildkit 解析基础镜像 1s 命中本地镜像、不再访问远端。
2026-10-12 16:33:45 +08:00

80 lines
3.3 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 快手轻量后端镜像
#
# 基础镜像源可整体替换(.env 的 BASE_REGISTRY)。为什么必须可配:
# 显式写死的 registry 会**绕过** daemon.json 的 registry-mirrors —— 加速源一抽风
# (daocloud 出现过 502 Bad Gateway),整轮构建在 load metadata 阶段就失败,
# 而 daemon 里其它可用镜像源完全帮不上忙,只能等它自己恢复。
# 默认值保持历史值,避免已有本地镜像被重新下载;多源容灾可改 BASE_REGISTRY=docker.io
# (那样会走 daemon.json 的 registry-mirrors 列表自动故障转移)。
ARG BASE_REGISTRY=docker.m.daocloud.io
FROM ${BASE_REGISTRY}/library/node:22-bookworm AS builder
# 阿里云公共源(全国可达);也可构建时覆盖:--build-arg DEBIAN_MIRROR=mirrors.cloud.aliyuncs.com
ARG DEBIAN_MIRROR=mirrors.aliyun.com
ARG NPM_REGISTRY=https://registry.npmmirror.com
ENV DEBIAN_FRONTEND=noninteractive
ENV NPM_CONFIG_REGISTRY=${NPM_REGISTRY}
WORKDIR /app
# bookworm 基础镜像可能尚无 ca-certificates;国内源常跳 HTTPS,需先跳过校验装证书
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
sed -i "s|http://deb.debian.org/debian|http://${DEBIAN_MIRROR}/debian|g" /etc/apt/sources.list.d/debian.sources \
&& sed -i "s|http://security.debian.org/debian-security|http://${DEBIAN_MIRROR}/debian-security|g" /etc/apt/sources.list.d/debian.sources \
&& apt-get -o Acquire::https::Verify-Peer=false -o Acquire::https::Verify-Host=false update \
&& apt-get -o Acquire::https::Verify-Peer=false -o Acquire::https::Verify-Host=false install -y --no-install-recommends \
ca-certificates \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
curl tzdata
COPY apps/backend/package.json apps/backend/package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY apps/backend/ ./
RUN npm run build \
&& npm prune --omit=dev
FROM ${BASE_REGISTRY}/library/node:22-bookworm-slim AS runtime
ARG DEBIAN_MIRROR=mirrors.aliyun.com
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
ENV NODE_ENV=production
WORKDIR /app
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
sed -i "s|http://deb.debian.org/debian|http://${DEBIAN_MIRROR}/debian|g" /etc/apt/sources.list.d/debian.sources \
&& sed -i "s|http://security.debian.org/debian-security|http://${DEBIAN_MIRROR}/debian-security|g" /etc/apt/sources.list.d/debian.sources \
&& apt-get -o Acquire::https::Verify-Peer=false -o Acquire::https::Verify-Host=false update \
&& apt-get -o Acquire::https::Verify-Peer=false -o Acquire::https::Verify-Host=false install -y --no-install-recommends \
ca-certificates \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
curl tzdata \
&& ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/dist ./dist
RUN groupadd -g 1001 appuser \
&& useradd -m -u 1001 -g appuser appuser \
&& mkdir -p /app/data \
&& chown -R appuser:appuser /app/data
USER appuser
EXPOSE 3000
CMD ["npm", "run", "start"]