fix(docker): publish verified multi-platform images

- Build linux/amd64 and linux/arm64 on native GitHub runners
- Assemble version manifests from platform digests and promote latest only after verification
- Add release/tag validation, manual republishing, timeouts, and health smoke tests
- Make Docker build mirrors configurable via build args and remove unnecessary runtime apk upgrades
- Update DOCKER.md documentation
This commit is contained in:
DaDecky
2026-09-21 20:28:45 +07:00
parent c7df895bbb
commit f67d5a0c93
3 changed files with 496 additions and 43 deletions
+32 -11
View File
@@ -1,29 +1,49 @@
# syntax=docker/dockerfile:1.7
ARG NODE_IMAGE=node:22-alpine
ARG ALPINE_MIRROR=dl-cdn.alpinelinux.org
ARG NPM_REGISTRY=https://registry.npmjs.org/
ARG APP_VERSION=unknown
FROM ${NODE_IMAGE} AS base
ARG ALPINE_MIRROR
WORKDIR /app
# CN mirror for apk (used by builder and runner stages)
RUN sed -i 's|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g' /etc/apk/repositories
# Use the official Alpine mirror by default. A repository variable/build arg can
# override it for environments that require a regional mirror.
RUN if [ "$ALPINE_MIRROR" != "dl-cdn.alpinelinux.org" ]; then \
sed -i "s|dl-cdn.alpinelinux.org|${ALPINE_MIRROR}|g" /etc/apk/repositories; \
fi
FROM base AS builder
ARG NPM_REGISTRY
RUN apk --no-cache upgrade && apk --no-cache add python3 make g++ linux-headers
RUN apk add --no-cache python3 make g++ linux-headers
COPY package.json ./
RUN npm install --registry=https://registry.npmmirror.com
RUN --mount=type=cache,target=/root/.npm \
npm install \
--registry="${NPM_REGISTRY}" \
--fetch-retries=5 \
--fetch-retry-factor=2 \
--fetch-retry-mintimeout=10000 \
--fetch-retry-maxtimeout=120000 \
--fetch-timeout=300000
COPY . ./
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
FROM ${NODE_IMAGE} AS runner
ARG ALPINE_MIRROR
ARG APP_VERSION
WORKDIR /app
# The base stage's mirror swap does not reach here: runner starts from
# ${NODE_IMAGE} directly, so the apk upgrade below would go to
# dl-cdn.alpinelinux.org and hang forever on networks that cannot reach it.
RUN sed -i 's|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g' /etc/apk/repositories
LABEL org.opencontainers.image.title="9router"
RUN if [ "$ALPINE_MIRROR" != "dl-cdn.alpinelinux.org" ]; then \
sed -i "s|dl-cdn.alpinelinux.org|${ALPINE_MIRROR}|g" /etc/apk/repositories; \
fi
LABEL org.opencontainers.image.title="9router" \
org.opencontainers.image.version="${APP_VERSION}"
ENV NODE_ENV=production
ENV PORT=20128
@@ -52,8 +72,9 @@ RUN mkdir -p /app/data && chown -R node:node /app && \
mkdir -p /app/data-home && chown node:node /app/data-home && \
ln -sf /app/data-home /root/.9router 2>/dev/null || true
# Fix permissions at runtime (handles mounted volumes)
RUN apk --no-cache upgrade && apk --no-cache add su-exec && \
# Avoid a full distribution upgrade in the runtime image. It makes builds less
# reproducible and is unrelated to installing the runtime entrypoint helper.
RUN apk add --no-cache su-exec && \
printf '#!/bin/sh\nchown -R node:node /app/data /app/data-home 2>/dev/null\nexec su-exec node "$@"\n' > /entrypoint.sh && \
chmod +x /entrypoint.sh