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.
This commit is contained in:
2026-08-30 18:36:31 +03:00
parent 9d6d78b31f
commit 27efeb8b26
5 changed files with 108 additions and 3 deletions
+5 -1
View File
@@ -1,7 +1,11 @@
public
/public
node_modules
.git
manimations/*.*
/zola
/zola-v*.tar.gz
/artifacts
dist
.strapi
.tmp
build
+8 -2
View File
@@ -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
+33
View File
@@ -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"]
+30
View File
@@ -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"]
+32
View File
@@ -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: