From fdf3e80a0c448beac9203e93126f03d021732bb9 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 1 Mar 2026 17:38:57 -0600 Subject: [PATCH] feat: custom base image to pre-bake apt updates --- .woodpecker/base-image.yml | 18 ++++++++++++++++++ apps/api/Dockerfile | 21 ++++++++------------- apps/orchestrator/Dockerfile | 11 +++++------ apps/web/Dockerfile | 11 +++++------ docker/base.Dockerfile | 16 ++++++++++++++++ 5 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 .woodpecker/base-image.yml create mode 100644 docker/base.Dockerfile diff --git a/.woodpecker/base-image.yml b/.woodpecker/base-image.yml new file mode 100644 index 0000000..8fa1f29 --- /dev/null +++ b/.woodpecker/base-image.yml @@ -0,0 +1,18 @@ +when: + - event: manual + - event: cron + cron: weekly-base-image + +steps: + build-base: + image: woodpeckerci/plugin-docker-buildx:latest + privileged: true + settings: + registry: git.mosaicstack.dev + repo: git.mosaicstack.dev/mosaic/node-base + tags: 24-slim + dockerfile: docker/base.Dockerfile + username: + from_secret: gitea_user + password: + from_secret: gitea_token diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index f05c802..7a9d27b 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -1,7 +1,7 @@ # Base image for all stages # Uses Debian slim (glibc) instead of Alpine (musl) because native Node.js addons # (matrix-sdk-crypto-nodejs, Prisma engines) require glibc-compatible binaries. -FROM node:24-slim AS base +FROM git.mosaicstack.dev/mosaic/node-base:24-slim AS base # Install pnpm globally RUN corepack enable && corepack prepare pnpm@10.27.0 --activate @@ -19,9 +19,9 @@ COPY turbo.json ./ FROM base AS deps # Install build tools for native addons (node-pty requires node-gyp compilation) -# and OpenSSL for Prisma engine detection +# Note: openssl and ca-certificates pre-installed in base image RUN apt-get update && apt-get install -y --no-install-recommends \ - python3 make g++ openssl \ + python3 make g++ \ && rm -rf /var/lib/apt/lists/* # Copy all package.json files for workspace resolution @@ -61,19 +61,14 @@ RUN pnpm turbo build --filter=@mosaic/api --force # ====================== # Production stage # ====================== -FROM node:24-slim AS production +FROM git.mosaicstack.dev/mosaic/node-base:24-slim AS production -# Install dumb-init for proper signal handling (static binary from GitHub, -# avoids apt-get which fails under Kaniko with bookworm GPG signature errors) -ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64 /usr/local/bin/dumb-init +# dumb-init, openssl, ca-certificates pre-installed in base image # Single RUN to minimize Kaniko filesystem snapshots (each RUN = full snapshot) -# - openssl: Prisma engine detection requires libssl -# - No build tools needed here — native addons are compiled in the deps stage -RUN apt-get update && apt-get install -y --no-install-recommends openssl \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx \ - && chmod 755 /usr/local/bin/dumb-init \ +# - Remove npm/npx to reduce image size (not used in production) +# - Create non-root user +RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx \ && groupadd -g 1001 nodejs && useradd -m -u 1001 -g nodejs nestjs WORKDIR /app diff --git a/apps/orchestrator/Dockerfile b/apps/orchestrator/Dockerfile index 4d0a979..d3fc408 100644 --- a/apps/orchestrator/Dockerfile +++ b/apps/orchestrator/Dockerfile @@ -1,6 +1,6 @@ # Base image for all stages # Uses Debian slim (glibc) instead of Alpine (musl) for native addon compatibility. -FROM node:24-slim AS base +FROM git.mosaicstack.dev/mosaic/node-base:24-slim AS base # Install pnpm globally RUN corepack enable && corepack prepare pnpm@10.27.0 --activate @@ -54,7 +54,7 @@ RUN find ./apps/orchestrator/dist \( -name '*.spec.js' -o -name '*.spec.js.map' # ====================== # Production stage # ====================== -FROM node:24-slim AS production +FROM git.mosaicstack.dev/mosaic/node-base:24-slim AS production # Add metadata labels LABEL maintainer="mosaic-team@mosaicstack.dev" @@ -65,13 +65,12 @@ LABEL org.opencontainers.image.vendor="Mosaic Stack" LABEL org.opencontainers.image.title="Mosaic Orchestrator" LABEL org.opencontainers.image.description="Agent orchestration service for Mosaic Stack" -# Install dumb-init for proper signal handling (static binary from GitHub, -# avoids apt-get which fails under Kaniko with bookworm GPG signature errors) -ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64 /usr/local/bin/dumb-init +# dumb-init, ca-certificates pre-installed in base image # Single RUN to minimize Kaniko filesystem snapshots (each RUN = full snapshot) +# - Remove npm/npx to reduce image size (not used in production) +# - Create non-root user RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx \ - && chmod 755 /usr/local/bin/dumb-init \ && groupadd -g 1001 nodejs && useradd -m -u 1001 -g nodejs nestjs WORKDIR /app diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 740edd6..ab37503 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -1,7 +1,7 @@ # Base image for all stages # Uses Debian slim (glibc) for consistency with API/orchestrator and to prevent # future native addon compatibility issues with Alpine's musl libc. -FROM node:24-slim AS base +FROM git.mosaicstack.dev/mosaic/node-base:24-slim AS base # Install pnpm globally RUN corepack enable && corepack prepare pnpm@10.27.0 --activate @@ -87,15 +87,14 @@ RUN mkdir -p ./apps/web/public # ====================== # Production stage # ====================== -FROM node:24-slim AS production +FROM git.mosaicstack.dev/mosaic/node-base:24-slim AS production -# Install dumb-init for proper signal handling (static binary from GitHub, -# avoids apt-get which fails under Kaniko with bookworm GPG signature errors) -ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64 /usr/local/bin/dumb-init +# dumb-init, ca-certificates pre-installed in base image # Single RUN to minimize Kaniko filesystem snapshots (each RUN = full snapshot) +# - Remove npm/npx to reduce image size (not used in production) +# - Create non-root user RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx \ - && chmod 755 /usr/local/bin/dumb-init \ && groupadd -g 1001 nodejs && useradd -m -u 1001 -g nodejs nextjs WORKDIR /app diff --git a/docker/base.Dockerfile b/docker/base.Dockerfile new file mode 100644 index 0000000..3ad6a41 --- /dev/null +++ b/docker/base.Dockerfile @@ -0,0 +1,16 @@ +FROM node:24-slim AS base + +# Pre-bake OS updates and common packages shared across all apps. +# Rebuild this image weekly or when base packages change. +# Push to: git.mosaicstack.dev/mosaic/node-base:24-slim +RUN apt-get update && apt-get upgrade -y --no-install-recommends \ + && apt-get install -y --no-install-recommends \ + openssl \ + ca-certificates \ + curl \ + dumb-init \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Enable corepack for pnpm +RUN corepack enable -- 2.49.1