From 27efeb8b2663b6638c554a52461df854b791a7fc Mon Sep 17 00:00:00 2001 From: andwati Date: Sun, 30 Aug 2026 18:36:31 +0300 Subject: [PATCH] Add Docker setup for running Strapi locally apps/cms/Dockerfile.dev + root docker-compose.yml give a one-command way to run the CMS in a container for testing (docker compose up cms), with the shared content/ directory mounted so it matches the host dev setup. apps/cms/Dockerfile is a production multi-stage build for later Dokploy deployment. Uses node:24-bookworm-slim to match the local Node version and get glibc prebuilt binaries for better-sqlite3 without needing a native build toolchain in the final image. Verified: both images build, the dev container boots Strapi successfully, admin panel and API routes are reachable, and the mounted content/ volume resolves at the same relative path the future sync provider will expect. --- .dockerignore | 6 +++++- TODO.md | 10 ++++++++-- apps/cms/Dockerfile | 33 +++++++++++++++++++++++++++++++++ apps/cms/Dockerfile.dev | 30 ++++++++++++++++++++++++++++++ docker-compose.yml | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 apps/cms/Dockerfile create mode 100644 apps/cms/Dockerfile.dev create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore index 48767d1..fce65b8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,7 +1,11 @@ -public +/public node_modules .git manimations/*.* /zola /zola-v*.tar.gz /artifacts +dist +.strapi +.tmp +build diff --git a/TODO.md b/TODO.md index 84b7279..42c09ee 100644 --- a/TODO.md +++ b/TODO.md @@ -16,11 +16,17 @@ approved plan for full rationale on each decision referenced below. end-to-end in-browser (`pnpm --filter site dev`) - [x] CLAUDE.md updated: no agent self-attribution in commits/PRs, commit regularly after each working step +- [x] Strapi content-type definitions matching the `content/` schema exactly + (writings, portfolio, bookshelf, blogs) — verified boots and registers + all four REST routes +- [x] `apps/cms/Dockerfile.dev` + root `docker-compose.yml` for running + Strapi locally in a container (node:24-bookworm-slim, matches local + Node version); `apps/cms/Dockerfile` production multi-stage build for + later Dokploy deployment. Verified: builds, boots, admin panel and API + reachable, shared `content/` volume mounted at the right relative path ## Content pipeline -- [ ] Strapi content-type definitions matching the `content/` schema exactly - (writings, portfolio, bookshelf, blogs) - [ ] Strapi custom provider/lifecycle hooks that read + write the same Markdown files in `content/` (Strapi's DB stays a disposable cache) - [ ] Verify round-trip: edit in Strapi admin → file on disk updates, and diff --git a/apps/cms/Dockerfile b/apps/cms/Dockerfile new file mode 100644 index 0000000..cb65b78 --- /dev/null +++ b/apps/cms/Dockerfile @@ -0,0 +1,33 @@ +# Production image for the Strapi CMS. Multi-stage: install deps, build the +# admin panel, then copy only the built output + prod node_modules into the +# runtime layer. +# +# Build context must be the repo root (pnpm workspace root), e.g.: +# docker build -f apps/cms/Dockerfile -t andwati-cms . + +FROM node:24-bookworm-slim AS base +RUN corepack enable +WORKDIR /app + +FROM base AS deps +# better-sqlite3 needs to compile if no prebuilt binary matches the platform. +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 make g++ \ + && rm -rf /var/lib/apt/lists/* +COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./ +COPY apps/site/package.json apps/site/package.json +COPY apps/cms/package.json apps/cms/package.json +RUN pnpm install --frozen-lockfile --filter cms + +FROM deps AS build +ENV NODE_ENV=production +COPY apps/cms apps/cms +RUN pnpm --filter cms build + +FROM base AS runtime +ENV NODE_ENV=production +COPY --from=build /app/node_modules /app/node_modules +COPY --from=build /app/apps/cms /app/apps/cms +WORKDIR /app/apps/cms +EXPOSE 1337 +CMD ["pnpm", "start"] diff --git a/apps/cms/Dockerfile.dev b/apps/cms/Dockerfile.dev new file mode 100644 index 0000000..a131b8f --- /dev/null +++ b/apps/cms/Dockerfile.dev @@ -0,0 +1,30 @@ +# Local testing image for the Strapi CMS — runs `strapi develop` with the +# workspace's own lockfile, so it matches what `pnpm --filter cms develop` +# does on the host. Not for production (see Dockerfile for that). +# +# Build context must be the repo root (pnpm workspace root), e.g.: +# docker build -f apps/cms/Dockerfile.dev -t andwati-cms-dev . +# or simply: docker compose up cms + +FROM node:24-bookworm-slim + +# better-sqlite3 needs to compile if no prebuilt binary matches the platform. +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 make g++ \ + && rm -rf /var/lib/apt/lists/* + +RUN corepack enable +WORKDIR /app + +# Copy just the manifests first so `pnpm install` is cached across rebuilds +# unless a package.json actually changes. +COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./ +COPY apps/site/package.json apps/site/package.json +COPY apps/cms/package.json apps/cms/package.json +RUN pnpm install --frozen-lockfile --filter cms + +COPY apps/cms apps/cms + +WORKDIR /app/apps/cms +EXPOSE 1337 +CMD ["pnpm", "develop"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8b5340c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +# Local-only convenience for running Strapi in a container while developing. +# Not a production deployment manifest. Usage: docker compose up cms +# +# The dev credentials below are throwaway values for a local SQLite instance +# only — never reuse them anywhere real. +services: + cms: + build: + context: . + dockerfile: apps/cms/Dockerfile.dev + ports: + - "1337:1337" + environment: + HOST: 0.0.0.0 + PORT: "1337" + NODE_ENV: development + APP_KEYS: devkey1,devkey2,devkey3,devkey4 + API_TOKEN_SALT: dev-api-token-salt + ADMIN_JWT_SECRET: dev-admin-jwt-secret + TRANSFER_TOKEN_SALT: dev-transfer-token-salt + JWT_SECRET: dev-jwt-secret + ENCRYPTION_KEY: dev-encryption-key + volumes: + - ./apps/cms/src:/app/apps/cms/src + - ./apps/cms/config:/app/apps/cms/config + - ./apps/cms/public:/app/apps/cms/public + - ./apps/cms/database:/app/apps/cms/database + - ./content:/app/content + - cms_data:/app/apps/cms/.tmp + +volumes: + cms_data: