Backend: Cloudron container image packaging and Gitea registry workflow #56

Merged
an.di merged 2 commits from adilallo/Backend/ContainerRegistry into main 2026-05-23 19:52:39 +00:00
Owner

Summary

  • Package the app as a Cloudron app: CloudronManifest.json, production Dockerfile, scripts/start.sh (migrate + privilege drop), and scripts/docker-release.sh (buildx push to Gitea).
  • Document the closed registry decision (Gitea Container Registry on git.medlab.host) and the operator build/push/install workflow in docs/guides/ops-backend-deploy.md §9.
  • Drop legacy Storybook peer deps: remove @storybook/addon-interactions, import interaction helpers from storybook/test, and bump next-intl to v4 so npm ci stays clean inside the Docker build.

What changed

Cloudron packaging (CR-97)

  • CloudronManifest.json — declares httpPort 3000, healthCheckPath /api/health, 768 MiB memory limit, and postgresql + sendmail + localstorage addons; pins image ref git.medlab.host/communityrule/community-rule:0.1.0.
  • Dockerfile — production-oriented multi-stage build:
    • npm ci --ignore-scripts in deps stage (schema not present yet; prisma generate runs in builder).
    • Reuses base image node user (uid 1000) for Cloudron localstorage mount compatibility.
    • Copies Prisma CLI into the runner so start.sh can run prisma migrate deploy.
    • Symlinks .next/cache → /tmp/next-cache so ISR works on Cloudron's read-only rootfs.
  • scripts/start.sh — chowns /app/data and /tmp/next-cache, drops to node:node via gosu, runs migrations, execs Next.js standalone server.
  • scripts/docker-release.sh + npm run docker:release — cross-platform linux/amd64 buildx push to the Gitea registry.

Docs

  • docs/guides/ops-backend-deploy.md — registry decision closed (§6.3); new §9 build/push/install runbook; CR-97 status updated. Staging install (CR-98) remains blocked on CR-96 env bridging.

Storybook / deps cleanup

  • Remove @storybook/addon-interactions (merged into Storybook 8+ core); stories import from storybook/test.
  • Bump next-intl to ^4.0.0; refresh lockfile.

Test plan

  • npx tsc --noEmit
  • ./scripts/docker-release.sh — builds and pushes to git.medlab.host/communityrule/community-rule:<tag> (requires Gitea PAT + docker login)
  • docker logout git.medlab.host && docker pull git.medlab.host/communityrule/community-rule:<tag> — anonymous pull succeeds (Cloudron simulation)
  • Run container locally with CLOUDRON_POSTGRESQL_URL + SESSION_SECRET; confirm GET /api/health returns {"ok":true,"database":"connected"} after migrations
  • npm run storybook — interaction stories still run
  • npx vitest run — unit/component suite passes
## Summary - Package the app as a Cloudron app: `CloudronManifest.json`, production `Dockerfile`, `scripts/start.sh` (migrate + privilege drop), and `scripts/docker-release.sh` (buildx push to Gitea). - Document the closed registry decision (Gitea Container Registry on `git.medlab.host`) and the operator build/push/install workflow in `docs/guides/ops-backend-deploy.md` §9. - Drop legacy Storybook peer deps: remove `@storybook/addon-interactions`, import interaction helpers from `storybook/test`, and bump `next-intl` to v4 so `npm ci` stays clean inside the Docker build. ## What changed ### Cloudron packaging (CR-97) - **`CloudronManifest.json`** — declares `httpPort 3000`, `healthCheckPath /api/health`, 768 MiB memory limit, and `postgresql + sendmail + localstorage` addons; pins image ref `git.medlab.host/communityrule/community-rule:0.1.0`. - **`Dockerfile`** — production-oriented multi-stage build: - `npm ci --ignore-scripts` in deps stage (schema not present yet; `prisma generate` runs in builder). - Reuses base image `node` user (uid 1000) for Cloudron localstorage mount compatibility. - Copies Prisma CLI into the runner so `start.sh` can run `prisma migrate deploy`. - Symlinks `.next/cache → /tmp/next-cache` so ISR works on Cloudron's read-only rootfs. - **`scripts/start.sh`** — chowns `/app/data` and `/tmp/next-cache`, drops to `node:node` via `gosu`, runs migrations, execs Next.js standalone server. - **`scripts/docker-release.sh`** + **`npm run docker:release`** — cross-platform `linux/amd64` buildx push to the Gitea registry. ### Docs - **`docs/guides/ops-backend-deploy.md`** — registry decision closed (§6.3); new §9 build/push/install runbook; CR-97 status updated. Staging install (CR-98) remains blocked on CR-96 env bridging. ### Storybook / deps cleanup - Remove `@storybook/addon-interactions` (merged into Storybook 8+ core); stories import from `storybook/test`. - Bump `next-intl` to `^4.0.0`; refresh lockfile. ## Test plan - [x] `npx tsc --noEmit` - [x] `./scripts/docker-release.sh` — builds and pushes to `git.medlab.host/communityrule/community-rule:<tag>` (requires Gitea PAT + `docker login`) - [x] `docker logout git.medlab.host && docker pull git.medlab.host/communityrule/community-rule:<tag>` — anonymous pull succeeds (Cloudron simulation) - [x] Run container locally with `CLOUDRON_POSTGRESQL_URL` + `SESSION_SECRET`; confirm `GET /api/health` returns `{"ok":true,"database":"connected"}` after migrations - [x] `npm run storybook` — interaction stories still run - [x] `npx vitest run` — unit/component suite passes
an.di added 2 commits 2026-05-23 19:52:01 +00:00
an.di self-assigned this 2026-05-23 19:52:28 +00:00
an.di merged commit 062a9e4068 into main 2026-05-23 19:52:39 +00:00
an.di deleted branch adilallo/Backend/ContainerRegistry 2026-05-23 19:52:39 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: CommunityRule/community-rule#56