Files
RSSHub/Dockerfile
T
Rongrong 3ede128c55 fix(route/picnob): bring back support for diygod/rsshub:chromium-bundled (#20504)
* ci(docker-release): enable ZRAM to reduce memory pressure

This should hopefully help reduce stuck build jobs. Note that this can't
completely eliminate stuck builds since this is usually caused by
synchronization issues in QEMU.

Signed-off-by: Rongrong <i@rong.moe>

* build(Dockerfile): Add support for puppeteer-real-browser

Sets CHROMIUM_EXECUTABLE_PATH on AMD64 and installs essential
dependencies.

Signed-off-by: Rongrong <i@rong.moe>

* fix(route/picnob): bring back support for diygod/rsshub:chromium-bundled

The support for puppeteer-real-browser on diygod/rsshub:chromium-bundled
was improperly implemented in 400fb1fa49 ("fix(route/picnob): use
puppeteer-real-browser to pass cf check (#20478)") and was then removed
in 2cb11d7c7e ("fix(route/picnob): support img not in slide").

With proper support for puppeteer-real-browser added to Dockerfile, this
patch brings back the support for diygod/rsshub:chromium-bundled.

This partially reverts commit 2cb11d7c7e ("fix(route/picnob): support
img not in slide").

Signed-off-by: Rongrong <i@rong.moe>

* chore(route/picnob): add myself as maintainer

This route explicitly consult CHROMIUM_EXECUTABLE_PATH from the docker
image variant `diygod/rsshub:chromium-bundled`. Since I am the author of
the image variant, add myself as one of route maintainers so that I am
mentioned when the route is broken.

Signed-off-by: Rongrong <i@rong.moe>

# Conflicts:
#	lib/routes/picnob/user.ts

---------

Signed-off-by: Rongrong <i@rong.moe>
2025-11-21 01:23:22 +08:00

206 lines
8.1 KiB
Docker

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 ./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 !!!