Skip to content

Commit 39b6656

Browse files
committed
chore(docker): unify Bun base to 1-slim, fix Debian user creation, add deploy context check
- Docker: use oven/bun:1-slim everywhere (webapp, admin, hocuspocus); drop alpine - Webapp/admin: apt instead of apk; groupadd/useradd for non-root (Debian has no addgroup/adduser) - CI deploy: verify packages/email-templates and Dockerfile COPY before build - .cursor/rules/bun-monorepo.mdc: document single base image and node_modules pitfall Made-with: Cursor
1 parent 2f41049 commit 39b6656

File tree

5 files changed

+46
-20
lines changed

5 files changed

+46
-20
lines changed

.cursor/rules/bun-monorepo.mdc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ bun run --filter '*' build
3737
- Node >= 24.11.0
3838
- Bun >= 1.3.7
3939

40+
## Docker base image (single source of truth)
41+
42+
- All Dockerfiles use **one tag**: `oven/bun:1-slim` (latest Bun 1.x, floating; no hardcoded patch version).
43+
- Same tag everywhere: do not mix `1-alpine` / `1-slim` or add a patch (e.g. `1.3.9-slim`); use `1-slim` so rebuilds get the latest 1.x automatically.
44+
4045
## Docker (multi-stage builds)
4146

4247
- **Do not copy `node_modules` between stages.** Bun uses symlinks into a virtual store; copied `node_modules` in another stage break (e.g. `require('next-pwa/cache')` → MODULE_NOT_FOUND). Any stage that runs `next build`, extension builds, or loads config that requires() deps must run `bun install --frozen-lockfile` in that stage and copy only `package.json`, `bun.lock`, and workspace tree.

.github/workflows/prod.docs.plus.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,18 @@ jobs:
243243
echo "DEPLOY_TAG=${{ env.DEPLOY_TAG }}" >> "${{ env.ENV_FILE }}"
244244
echo "✅ Environment ready"
245245
246+
- name: 📂 Verify build context (monorepo root)
247+
run: |
248+
if [ ! -d packages/email-templates ]; then
249+
echo "::error::packages/email-templates missing. Build context must be repo root (context: .). Check checkout and that this commit includes the workspace."
250+
exit 1
251+
fi
252+
grep -q 'email-templates' packages/hocuspocus.server/docker/Dockerfile.bun && grep -q 'email-templates' packages/webapp/docker/Dockerfile.bun || {
253+
echo "::error::Dockerfiles must COPY packages/email-templates. Merge the commit that adds @docs.plus/email-templates to prod Dockerfiles."
254+
exit 1
255+
}
256+
echo "✅ Build context OK (repo root, email-templates present)"
257+
246258
- name: 🏗️ Build Docker Images
247259
env:
248260
DOCKER_BUILDKIT: 1
@@ -254,7 +266,7 @@ jobs:
254266
source ${{ env.ENV_FILE }}
255267
set +a
256268
257-
# Build with parallel execution
269+
# Build with parallel execution (must run from repo root so context: . includes packages/)
258270
docker compose -f ${{ env.COMPOSE_FILE }} \
259271
--env-file ${{ env.ENV_FILE }} \
260272
build --parallel

packages/admin-dashboard/docker/Dockerfile.bun

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
# -----------------------------------------------------------------------------
1414
# Stage 1: Dependencies
1515
# -----------------------------------------------------------------------------
16-
FROM oven/bun:1-alpine AS deps
16+
# Use latest Bun 1.x (floating tag); same tag across all Dockerfiles for cohesion
17+
FROM oven/bun:1-slim AS deps
1718

18-
RUN apk add --no-cache libc6-compat
19+
RUN rm -rf /var/lib/apt/lists/* && \
20+
apt-get update && apt-get install -y --no-install-recommends ca-certificates && \
21+
rm -rf /var/lib/apt/lists/*
1922

2023
WORKDIR /app
2124

@@ -28,9 +31,11 @@ RUN bun install --frozen-lockfile
2831
# -----------------------------------------------------------------------------
2932
# Stage 2: Build
3033
# -----------------------------------------------------------------------------
31-
FROM oven/bun:1-alpine AS builder
34+
FROM oven/bun:1-slim AS builder
3235

33-
RUN apk add --no-cache libc6-compat nodejs
36+
RUN rm -rf /var/lib/apt/lists/* && \
37+
apt-get update && apt-get install -y --no-install-recommends ca-certificates nodejs && \
38+
rm -rf /var/lib/apt/lists/*
3439

3540
WORKDIR /app
3641

@@ -59,9 +64,11 @@ RUN bun run build:ci
5964
# -----------------------------------------------------------------------------
6065
# Stage 3: Runner (Production)
6166
# -----------------------------------------------------------------------------
62-
FROM oven/bun:1-alpine AS runner
67+
FROM oven/bun:1-slim AS runner
6368

64-
RUN apk add --no-cache libc6-compat
69+
RUN rm -rf /var/lib/apt/lists/* && \
70+
apt-get update && apt-get install -y --no-install-recommends ca-certificates && \
71+
rm -rf /var/lib/apt/lists/*
6572

6673
WORKDIR /app
6774

@@ -70,9 +77,9 @@ ENV NODE_ENV=production \
7077
PORT=3100 \
7178
HOSTNAME="0.0.0.0"
7279

73-
# Create non-root user for security
74-
RUN addgroup --system --gid 1001 nodejs && \
75-
adduser --system --uid 1001 nextjs
80+
# Create non-root user for security (Debian slim: groupadd/useradd)
81+
RUN groupadd -r -g 1001 nodejs && \
82+
useradd -r -u 1001 -g nodejs nextjs
7683

7784
# Copy standalone build output
7885
# Next.js standalone creates: .next/standalone/app/server.js (monorepo structure)

packages/hocuspocus.server/docker/Dockerfile.bun

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# -----------------------------------------------------------------------------
77
# Stage 1: Base - Install dependencies (monorepo layout)
88
# -----------------------------------------------------------------------------
9+
# Use latest Bun 1.x (floating tag); same tag across all Dockerfiles for cohesion
910
FROM oven/bun:1-slim AS base
1011
WORKDIR /app
1112

packages/webapp/docker/Dockerfile.bun

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@
1313
# ============================================================================
1414
# Stage 1: Base - Common setup
1515
# ============================================================================
16-
FROM oven/bun:1-alpine AS base
16+
# Use latest Bun 1.x (floating tag); same tag across all Dockerfiles for cohesion
17+
FROM oven/bun:1-slim AS base
1718

18-
# Install system dependencies
19-
# Note: Build tools (python3, make, g++) kept for potential native dependencies
20-
# Most dependencies are pure JS, but some packages may have optional native modules
21-
RUN apk add --no-cache \
22-
libc6-compat \
19+
# Install system dependencies (Debian slim; build tools for potential native deps)
20+
RUN rm -rf /var/lib/apt/lists/* && \
21+
apt-get update && apt-get install -y --no-install-recommends \
22+
ca-certificates \
2323
python3 \
2424
make \
2525
g++ \
26-
nodejs
26+
nodejs \
27+
&& rm -rf /var/lib/apt/lists/*
2728

2829
WORKDIR /app
2930

@@ -156,9 +157,9 @@ ENV NODE_ENV=production \
156157
PORT=3000 \
157158
HOSTNAME="0.0.0.0"
158159

159-
# Create non-root user
160-
RUN addgroup --system --gid 1001 nodejs && \
161-
adduser --system --uid 1001 nextjs
160+
# Create non-root user (Debian slim: groupadd/useradd)
161+
RUN groupadd -r -g 1001 nodejs && \
162+
useradd -r -u 1001 -g nodejs nextjs
162163

163164
# Copy standalone build output to root (Next.js standalone expects to run from its own root)
164165
# Standalone already includes server.js, node_modules, and minimal dependencies

0 commit comments

Comments
 (0)