File size: 8,351 Bytes
bf48b89 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | FROM node:24-bookworm AS dep-builder
# Here we use the non-slim image to provide build-time deps (compilers and python), thus no need to install later.
# This effectively speeds up qemu-based cross-build.
WORKDIR /app
# place ARG statement before RUN statement which need it to avoid cache miss
ARG USE_CHINA_NPM_REGISTRY=0
RUN \
set -ex && \
corepack enable pnpm && \
if [ "$USE_CHINA_NPM_REGISTRY" = 1 ]; then \
echo 'use npm mirror' && \
npm config set registry https://registry.npmmirror.com && \
yarn config set registry https://registry.npmmirror.com && \
pnpm config set registry https://registry.npmmirror.com ; \
fi;
COPY ./tsconfig.json /app/
COPY ./patches /app/patches
COPY ./pnpm-lock.yaml /app/
COPY ./package.json /app/
# lazy install Chromium to avoid cache miss, only install production dependencies to minimize the image size
RUN \
set -ex && \
export PUPPETEER_SKIP_DOWNLOAD=true && \
pnpm install --frozen-lockfile && \
pnpm rb
# ---------------------------------------------------------------------------------------------------------------------
FROM debian:bookworm-slim AS dep-version-parser
# This stage is necessary to limit the cache miss scope.
# With this stage, any modification to package.json won't break the build cache of the next two stages as long as the
# version unchanged.
# node:24-bookworm-slim is based on debian:bookworm-slim so this stage would not cause any additional download.
WORKDIR /ver
COPY ./package.json /app/
RUN \
set -ex && \
grep -Po '(?<="rebrowser-puppeteer": ")[^\s"]*(?=")' /app/package.json | tee /ver/.puppeteer_version && \
grep -Po '(?<="@vercel/nft": ")[^\s"]*(?=")' /app/package.json | tee /ver/.nft_version && \
grep -Po '(?<="fs-extra": ")[^\s"]*(?=")' /app/package.json | tee /ver/.fs_extra_version
# ---------------------------------------------------------------------------------------------------------------------
FROM node:24-bookworm-slim AS docker-minifier
# The stage is used to further reduce the image size by removing unused files.
WORKDIR /minifier
COPY --from=dep-version-parser /ver/* /minifier/
ARG USE_CHINA_NPM_REGISTRY=0
RUN \
set -ex && \
if [ "$USE_CHINA_NPM_REGISTRY" = 1 ]; then \
npm config set registry https://registry.npmmirror.com && \
yarn config set registry https://registry.npmmirror.com && \
pnpm config set registry https://registry.npmmirror.com ; \
fi; \
npm install -g corepack@latest && \
corepack enable pnpm && \
pnpm add @vercel/nft@$(cat .nft_version) fs-extra@$(cat .fs_extra_version) --save-prod
COPY . /app
COPY --from=dep-builder /app /app
WORKDIR /app
RUN \
set -ex && \
pnpm build && \
rm -rf /app/lib && \
cp /app/scripts/docker/minify-docker.js /minifier/ && \
export PROJECT_ROOT=/app && \
node /minifier/minify-docker.js && \
rm -rf /app/node_modules /app/scripts && \
mv /app/app-minimal/node_modules /app/ && \
rm -rf /app/app-minimal && \
ls -la /app && \
du -hd1 /app
# ---------------------------------------------------------------------------------------------------------------------
FROM node:24-bookworm-slim AS chromium-downloader
# This stage is necessary to improve build concurrency and minimize the image size.
# Yeah, downloading Chromium never needs those dependencies below.
WORKDIR /app
COPY ./.puppeteerrc.cjs /app/
COPY --from=dep-version-parser /ver/.puppeteer_version /app/.puppeteer_version
ARG TARGETPLATFORM
ARG USE_CHINA_NPM_REGISTRY=0
ARG PUPPETEER_SKIP_DOWNLOAD=1
# The official recommended way to use Puppeteer on x86(_64) is to use the bundled Chromium from Puppeteer:
# https://pptr.dev/faq#q-why-doesnt-puppeteer-vxxx-workwith-chromium-vyyy
RUN \
set -ex ; \
if [ "$PUPPETEER_SKIP_DOWNLOAD" = 0 ] && [ "$TARGETPLATFORM" = 'linux/amd64' ]; then \
if [ "$USE_CHINA_NPM_REGISTRY" = 1 ]; then \
npm config set registry https://registry.npmmirror.com && \
yarn config set registry https://registry.npmmirror.com && \
pnpm config set registry https://registry.npmmirror.com ; \
fi; \
echo 'Downloading Chromium...' && \
unset PUPPETEER_SKIP_DOWNLOAD && \
corepack enable pnpm && \
pnpm --allow-build=rebrowser-puppeteer add rebrowser-puppeteer@$(cat /app/.puppeteer_version) --save-prod && \
pnpm rb && \
pnpx rebrowser-puppeteer browsers install chrome ; \
else \
mkdir -p /app/node_modules/.cache/puppeteer ; \
fi;
# ---------------------------------------------------------------------------------------------------------------------
FROM node:24-bookworm-slim AS app
LABEL org.opencontainers.image.authors="https://github.com/DIYgod/RSSHub"
ENV NODE_ENV=production
ENV TZ=Asia/Shanghai
WORKDIR /app
# install deps first to avoid cache miss or disturbing buildkit to build concurrently
ARG TARGETPLATFORM
ARG PUPPETEER_SKIP_DOWNLOAD=1
# https://pptr.dev/troubleshooting#chrome-headless-doesnt-launch-on-unix
# https://github.com/puppeteer/puppeteer/issues/7822
# https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.en.html#noteworthy-obsolete-packages
# The official recommended way to use Puppeteer on arm/arm64 is to install Chromium from the distribution repositories:
# https://github.com/puppeteer/puppeteer/blob/07391bbf5feaf85c191e1aa8aa78138dce84008d/packages/puppeteer-core/src/node/BrowserFetcher.ts#L128-L131
# Dependencies of puppeteer-real-browser: xvfb, procps
RUN \
set -ex && \
apt-get update && \
apt-get install -yq --no-install-recommends \
dumb-init git curl \
; \
if [ "$PUPPETEER_SKIP_DOWNLOAD" = 0 ]; then \
if [ "$TARGETPLATFORM" = 'linux/amd64' ]; then \
apt-get install -yq --no-install-recommends \
ca-certificates fonts-liberation wget xdg-utils \
libasound2 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 libcairo2 libcups2 libdbus-1-3 libdrm2 \
libexpat1 libgbm1 libglib2.0-0 libnspr4 libnss3 libpango-1.0-0 libx11-6 libxcb1 libxcomposite1 \
libxdamage1 libxext6 libxfixes3 libxkbcommon0 libxrandr2 \
; \
else \
apt-get install -yq --no-install-recommends \
chromium \
&& \
echo "CHROMIUM_EXECUTABLE_PATH=$(which chromium)" | tee /app/.env ; \
fi; \
apt-get install -yq --no-install-recommends \
xvfb procps \
; \
fi; \
rm -rf /var/lib/apt/lists/*
COPY --from=chromium-downloader /app/node_modules/.cache/puppeteer /app/node_modules/.cache/puppeteer
RUN \
set -ex && \
if [ "$PUPPETEER_SKIP_DOWNLOAD" = 0 ] && [ "$TARGETPLATFORM" = 'linux/amd64' ]; then \
echo 'Verifying Chromium installation...' && \
_chrome_path=$(find /app/node_modules/.cache/puppeteer/chrome/ -name chrome -xtype f -executable | head -n1) && \
echo "CHROMIUM_EXECUTABLE_PATH=$_chrome_path" | tee /app/.env && \
if ldd "$_chrome_path" | grep "not found"; then \
echo "!!! Chromium has unmet shared libs !!!" && \
exit 1 ; \
else \
echo "Awesome! All shared libs are met!" ; \
fi; \
fi;
COPY --from=docker-minifier /app /app
EXPOSE 1200
ENTRYPOINT ["dumb-init", "--"]
CMD ["npm", "run", "start"]
# ---------------------------------------------------------------------------------------------------------------------
# In case Chromium has unmet shared libs, here is some magic to find and install the packages they belong to:
# In most case you can just stop at `grep ^lib` and add those packages to the above stage.
#
# set -ex && \
# apt-get update && \
# apt install -yq --no-install-recommends \
# apt-file \
# && \
# apt-file update && \
# ldd $(find /app/node_modules/.cache/puppeteer/ -name chrome -type f) | grep -Po "\S+(?= => not found)" | \
# sed 's/\./\\./g' | awk '{print $1"$"}' | apt-file search -xlf - | grep ^lib | \
# xargs -d '\n' -- \
# apt-get install -yq --no-install-recommends \
# && \
# apt purge -yq --auto-remove \
# apt-file \
# rm -rf /tmp/.chromium_path /var/lib/apt/lists/*
# !!! If you manually build Docker image but with buildx/BuildKit disabled, set TARGETPLATFORM yourself !!!
|