From 6318f4b4add6d485877201f062090e3843f8ea19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20St=C3=B6ckle?= Date: Sat, 24 Jan 2026 22:21:19 +0100 Subject: [PATCH] Improve container images (#749) * :lock: chore(security): improve container image security * :ok_hand: chore(review): add cron job to Dockerfile for periodic tasks --- .github/workflows/release.yaml | 8 ---- db/.dockerignore | 9 +++++ db/Dockerfile | 55 ++++++++++++++++++++----- web/.dockerignore | 9 +++++ web/Dockerfile | 74 ++++++++++++++++++++++++++-------- 5 files changed, 122 insertions(+), 33 deletions(-) create mode 100644 db/.dockerignore create mode 100644 web/.dockerignore diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 4936e1be..5b8baa7d 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -79,17 +79,9 @@ jobs: VERSION: ${{ needs.versioning.outputs.version }} run: | # Build db image - cd db - env GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o pocketbase_arm64 - env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o pocketbase_amd64 - cd .. docker buildx build db/ --no-cache -t flomp/wanderer-db:$VERSION -t flomp/wanderer-db:latest --platform=linux/amd64,linux/arm64 --push # Build web image - export PUBLIC_VALHALLA_URL=https://valhalla1.openstreetmap.de - cd web - npm ci && npm run build - cd .. docker buildx build web/ --no-cache -t flomp/wanderer-web:$VERSION -t flomp/wanderer-web:latest --platform=linux/amd64,linux/arm64 --push # Build docs image diff --git a/db/.dockerignore b/db/.dockerignore new file mode 100644 index 00000000..357e70b1 --- /dev/null +++ b/db/.dockerignore @@ -0,0 +1,9 @@ +* +!commands +!federation +!go.* +!integrations +!main.go +!migrations +!templates +!util diff --git a/db/Dockerfile b/db/Dockerfile index 8a42a650..f795a2c6 100644 --- a/db/Dockerfile +++ b/db/Dockerfile @@ -1,18 +1,55 @@ -FROM alpine:3.19 +FROM curlimages/curl:8.18.0 AS download-env + +# renovate: datasource=github-releases depName=stunnel/static-curl packageName=stunnel/static-curl +ENV CURL_VERSION=8.18.0 + +RUN set -eux ; \ + ARCHITECTURE="$(uname -m)" ; \ + case $ARCHITECTURE in \ + x86_64) ARCHITECTURE="x86_64" ;; \ + aarch64 | armv8* | arm64) ARCHITECTURE="aarch64" ;; \ + *) \ + echo "(!) Architecture $ARCHITECTURE unsupported" ; \ + exit 1 \ + ;; \ + esac ; \ + curl \ + --connect-timeout 10 \ + --fail \ + --location \ + --max-time 300 \ + --output /tmp/curl.tar.xz \ + --proto '=https' \ + --show-error \ + --silent \ + --tlsv1.2 \ + "https://github.com/stunnel/static-curl/releases/download/${CURL_VERSION}/curl-linux-${ARCHITECTURE}-glibc-${CURL_VERSION}.tar.xz" \ + ; \ + tar -xJf /tmp/curl.tar.xz -C /tmp ; \ + chmod +x /tmp/curl ; + +FROM golang:1.24.0@sha256:3f7444391c51a11a039bf0359ee81cc64e663c17d787ad0e637a4de1a3f62a71 AS build + +WORKDIR /app + +COPY . . + +RUN go mod download +RUN CGO_ENABLED=0 go build -o /app/pocketbase + +FROM scratch WORKDIR / +COPY --from=build /app/pocketbase /pocketbase +COPY --from=download-env /tmp/curl /curl COPY migrations ./migrations COPY templates ./templates -ARG TARGETARCH -RUN echo ${TARGETARCH} -COPY ./pocketbase_${TARGETARCH} /pocketbase -RUN chmod +x /pocketbase - -ENV MEILI_URL=http://localhost:7700 -ENV MEILI_MASTER_KEY= +ENV MEILI_URL=http://localhost:7700 \ + MEILI_MASTER_KEY= \ + POCKETBASE_ENCRYPTION_KEY= EXPOSE 8090 -ENTRYPOINT ["/pocketbase", "serve", "--http=0.0.0.0:8090", "--dir=/pb_data"] \ No newline at end of file +ENTRYPOINT ["/pocketbase", "serve", "--http=0.0.0.0:8090", "--dir=/pb_data"] diff --git a/web/.dockerignore b/web/.dockerignore new file mode 100644 index 00000000..c8747a50 --- /dev/null +++ b/web/.dockerignore @@ -0,0 +1,9 @@ +* +!*.js +!*.ts +!package-lock.json* +!package.json +!src +!static +!tsconfig.json +!cron.sh diff --git a/web/Dockerfile b/web/Dockerfile index 150cc116..eaa67423 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -1,21 +1,63 @@ -FROM node:22-alpine -WORKDIR /app -COPY ./build build/ -COPY package*.json . -RUN npm ci --omit=dev -EXPOSE 3000 -ENV NODE_ENV=production +FROM curlimages/curl:8.18.0 AS download-env +# renovate: datasource=github-releases depName=stunnel/static-curl packageName=stunnel/static-curl +ENV CURL_VERSION=8.18.0 + +RUN set -eux ; \ + ARCHITECTURE="$(uname -m)" ; \ + case $ARCHITECTURE in \ + x86_64) ARCHITECTURE="x86_64" ;; \ + aarch64 | armv8* | arm64) ARCHITECTURE="aarch64" ;; \ + *) \ + echo "(!) Architecture $ARCHITECTURE unsupported" ; \ + exit 1 \ + ;; \ + esac ; \ + curl \ + --connect-timeout 10 \ + --fail \ + --location \ + --max-time 300 \ + --output /tmp/curl.tar.xz \ + --proto '=https' \ + --show-error \ + --silent \ + --tlsv1.2 \ + "https://github.com/stunnel/static-curl/releases/download/${CURL_VERSION}/curl-linux-${ARCHITECTURE}-glibc-${CURL_VERSION}.tar.xz" \ + ; \ + tar -xJf /tmp/curl.tar.xz -C /tmp ; \ + chmod +x /tmp/curl ; + +FROM node:22-alpine AS build-env + +WORKDIR /app + +COPY ["package.json", "package-lock.json*", "./"] + +RUN npm ci + +COPY . . + +RUN npm run build + +FROM node:22-alpine + +WORKDIR /app/uploads +WORKDIR /app + +COPY --from=download-env /tmp/curl /curl +COPY --from=build-env /app /app COPY ./cron.sh /etc/periodic/15min/cron RUN chmod +x /etc/periodic/15min/cron -RUN mkdir /app/uploads -RUN apk add curl -ENV PUBLIC_POCKETBASE_URL=http://127.0.0.1:8090 -ENV MEILI_URL=http://127.0.0.1:7700 -ENV PUBLIC_DISABLE_SIGNUP=false -ENV UPLOAD_USER= -ENV UPLOAD_PASSWORD= -ENV PUBLIC_OVERPASS_API_URL= +CMD crond && node build -CMD crond && node build \ No newline at end of file +EXPOSE 3000 + +ENV \ + MEILI_URL=http://127.0.0.1:7700 \ + PUBLIC_DISABLE_SIGNUP=false \ + PUBLIC_OVERPASS_API_URL= \ + PUBLIC_POCKETBASE_URL=http://127.0.0.1:8090 \ + UPLOAD_PASSWORD= \ + UPLOAD_USER=