From 699134a57606c4c5229c79d13587c205293c5175 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Mon, 13 Jul 2026 20:02:42 +0200 Subject: [PATCH] refactor: move workshop backend app --- .env.example | 10 ++++++++++ apps/store/.env.example | 6 ------ apps/store/.gitignore | 4 ---- apps/workshop/.gitignore | 1 + apps/{store => workshop}/Dockerfile | 0 apps/{store => workshop}/README.md | 10 +++++----- apps/{store => workshop}/docker-compose.yml | 2 ++ apps/{store => workshop}/entrypoint.sh | 0 apps/{store => workshop}/pb_hooks/workshop-utils.js | 0 apps/{store => workshop}/pb_hooks/workshop.pb.js | 0 .../pb_migrations/1783900000_workshop_v2.js | 0 apps/{store => workshop}/tests/run-integration.sh | 8 ++++---- .../{store => workshop}/tests/workshop.integration.mjs | 0 package.json | 6 +++--- 14 files changed, 25 insertions(+), 22 deletions(-) delete mode 100644 apps/store/.env.example delete mode 100644 apps/store/.gitignore create mode 100644 apps/workshop/.gitignore rename apps/{store => workshop}/Dockerfile (100%) rename apps/{store => workshop}/README.md (80%) rename apps/{store => workshop}/docker-compose.yml (97%) rename apps/{store => workshop}/entrypoint.sh (100%) rename apps/{store => workshop}/pb_hooks/workshop-utils.js (100%) rename apps/{store => workshop}/pb_hooks/workshop.pb.js (100%) rename apps/{store => workshop}/pb_migrations/1783900000_workshop_v2.js (100%) rename apps/{store => workshop}/tests/run-integration.sh (52%) rename apps/{store => workshop}/tests/workshop.integration.mjs (100%) diff --git a/.env.example b/.env.example index 9c7bc8292..5efbdf549 100644 --- a/.env.example +++ b/.env.example @@ -69,3 +69,13 @@ UNSAFE_ENABLE_MOCK_INTEGRATION=true # DEMO_READ_ONLY=false # Central Homarr Workshop API. Override only when developing the Workshop locally. # NEXT_PUBLIC_WORKSHOP_API_URL=http://localhost:8090 +# WORKSHOP_API_URL=http://localhost:8090 + +# Workshop development backend and GitHub OAuth. +# The GitHub OAuth callback URL is http://localhost:8090/api/oauth2-redirect. +GITHUB_CLIENT_ID= +GITHUB_CLIENT_SECRET= +PB_SUPERUSER_EMAIL= +PB_SUPERUSER_PASSWORD= +PB_EXPOSE_PORT=8090 +PB_ALLOWED_ORIGINS=http://localhost:3003,http://127.0.0.1:3003 diff --git a/apps/store/.env.example b/apps/store/.env.example deleted file mode 100644 index 6d409e25b..000000000 --- a/apps/store/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -GITHUB_CLIENT_ID= -GITHUB_CLIENT_SECRET= -PB_SUPERUSER_EMAIL= -PB_SUPERUSER_PASSWORD= -PB_EXPOSE_PORT=8090 -PB_ALLOWED_ORIGINS=http://localhost:3003,http://127.0.0.1:3003 diff --git a/apps/store/.gitignore b/apps/store/.gitignore deleted file mode 100644 index b566e12c9..000000000 --- a/apps/store/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.env -.env.* -!.env.example -pb_data/ diff --git a/apps/workshop/.gitignore b/apps/workshop/.gitignore new file mode 100644 index 000000000..5a1dc89f6 --- /dev/null +++ b/apps/workshop/.gitignore @@ -0,0 +1 @@ +pb_data/ diff --git a/apps/store/Dockerfile b/apps/workshop/Dockerfile similarity index 100% rename from apps/store/Dockerfile rename to apps/workshop/Dockerfile diff --git a/apps/store/README.md b/apps/workshop/README.md similarity index 80% rename from apps/store/README.md rename to apps/workshop/README.md index abaeb505c..0d3eb6ceb 100644 --- a/apps/store/README.md +++ b/apps/workshop/README.md @@ -4,14 +4,14 @@ PocketBase provides the central Workshop API at `workshop.homarr.dev`. It is not ## Local startup -1. Copy `.env.example` to `.env` and create a GitHub OAuth app. +1. Copy the repository-root `.env.example` to `.env` and create a GitHub OAuth app. 2. Set its callback URL to `http://localhost:8090/api/oauth2-redirect`. 3. Set `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`, `PB_SUPERUSER_EMAIL`, and `PB_SUPERUSER_PASSWORD`. 4. Run `pnpm dev:workshop` from the repository root. It starts PocketBase and the Docusaurus Workshop together and removes obsolete Compose containers. Open the Workshop at `http://localhost:3003/workshop`. The API is at `http://localhost:8090`; the emergency PocketBase dashboard is at `http://localhost:8090/_/`. `0.0.0.0` in PocketBase's server log is its container bind address, not a browser URL. Day-to-day moderation belongs in `/workshop/admin`, not the PocketBase dashboard. -Use `pnpm dev:workshop:backend` when only the API is needed. If port 8090 is unavailable, set `PB_EXPOSE_PORT` in `apps/store/.env` and run the website separately with a matching `NEXT_PUBLIC_WORKSHOP_API_URL`. +Use `pnpm dev:workshop:backend` when only the API is needed. All Workshop configuration is read from the repository-root `.env`; there is no app-specific environment file. If port 8090 is unavailable, set `PB_EXPOSE_PORT` there. The website derives its local API URL from that port unless `WORKSHOP_API_URL` is explicitly set. The image downloads the official PocketBase `0.39.6` release and verifies it against that release's `checksums.txt`. Migrations and hooks are mounted read-only. @@ -32,9 +32,9 @@ Bootstrap the first admin through the PocketBase dashboard by changing a GitHub- PocketBase stores records and uploads in `/pb_data`. Stop writes or stop the container, then archive the named volume: ```sh -docker compose stop workshop -docker run --rm -v store_workshop_data:/data -v "$PWD":/backup alpine tar czf /backup/workshop-backup.tgz -C /data . -docker compose start workshop +docker compose --env-file .env --file apps/workshop/docker-compose.yml stop workshop +docker run --rm -v homarr-workshop_workshop_data:/data -v "$PWD":/backup alpine tar czf /backup/workshop-backup.tgz -C /data . +docker compose --env-file .env --file apps/workshop/docker-compose.yml start workshop ``` Restore only into the same PocketBase version after preserving the current volume. Extract the archive into an empty `workshop_data` volume, start the service, and verify `/api/health`, collection migrations, a listing request, and an authenticated write. diff --git a/apps/store/docker-compose.yml b/apps/workshop/docker-compose.yml similarity index 97% rename from apps/store/docker-compose.yml rename to apps/workshop/docker-compose.yml index 21d1d6f6f..1c6fc6c14 100644 --- a/apps/store/docker-compose.yml +++ b/apps/workshop/docker-compose.yml @@ -1,3 +1,5 @@ +name: homarr-workshop + services: workshop: build: diff --git a/apps/store/entrypoint.sh b/apps/workshop/entrypoint.sh similarity index 100% rename from apps/store/entrypoint.sh rename to apps/workshop/entrypoint.sh diff --git a/apps/store/pb_hooks/workshop-utils.js b/apps/workshop/pb_hooks/workshop-utils.js similarity index 100% rename from apps/store/pb_hooks/workshop-utils.js rename to apps/workshop/pb_hooks/workshop-utils.js diff --git a/apps/store/pb_hooks/workshop.pb.js b/apps/workshop/pb_hooks/workshop.pb.js similarity index 100% rename from apps/store/pb_hooks/workshop.pb.js rename to apps/workshop/pb_hooks/workshop.pb.js diff --git a/apps/store/pb_migrations/1783900000_workshop_v2.js b/apps/workshop/pb_migrations/1783900000_workshop_v2.js similarity index 100% rename from apps/store/pb_migrations/1783900000_workshop_v2.js rename to apps/workshop/pb_migrations/1783900000_workshop_v2.js diff --git a/apps/store/tests/run-integration.sh b/apps/workshop/tests/run-integration.sh similarity index 52% rename from apps/store/tests/run-integration.sh rename to apps/workshop/tests/run-integration.sh index f13af1bcc..fb92075e8 100755 --- a/apps/store/tests/run-integration.sh +++ b/apps/workshop/tests/run-integration.sh @@ -7,7 +7,7 @@ email="integration@homarr.test" password="WorkshopIntegrationPassword123!" cleanup() { - PB_EXPOSE_PORT="$port" docker compose --file apps/store/docker-compose.yml --project-name "$project" down --volumes >/dev/null 2>&1 || true + PB_EXPOSE_PORT="$port" docker compose --env-file .env.example --file apps/workshop/docker-compose.yml --project-name "$project" down --volumes >/dev/null 2>&1 || true } trap cleanup EXIT INT TERM cleanup @@ -17,12 +17,12 @@ PB_SUPERUSER_EMAIL="$email" \ PB_SUPERUSER_PASSWORD="$password" \ GITHUB_CLIENT_ID="integration-client" \ GITHUB_CLIENT_SECRET="integration-secret" \ -docker compose --file apps/store/docker-compose.yml --project-name "$project" up --detach --build --wait +docker compose --env-file .env.example --file apps/workshop/docker-compose.yml --project-name "$project" up --detach --build --wait if ! WORKSHOP_TEST_URL="http://127.0.0.1:$port" \ WORKSHOP_TEST_SUPERUSER_EMAIL="$email" \ WORKSHOP_TEST_SUPERUSER_PASSWORD="$password" \ - node apps/store/tests/workshop.integration.mjs; then - docker compose --file apps/store/docker-compose.yml --project-name "$project" logs --no-color workshop + node apps/workshop/tests/workshop.integration.mjs; then + docker compose --env-file .env.example --file apps/workshop/docker-compose.yml --project-name "$project" logs --no-color workshop exit 1 fi diff --git a/apps/store/tests/workshop.integration.mjs b/apps/workshop/tests/workshop.integration.mjs similarity index 100% rename from apps/store/tests/workshop.integration.mjs rename to apps/workshop/tests/workshop.integration.mjs diff --git a/package.json b/package.json index 2cf612019..f3a9485f6 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "dev": "pnpm -F nextjs dev", "dev:docs": "pnpm -F @homarr/docs dev", "dev:workshop": "concurrently --kill-others --names workshop-api,workshop-web \"pnpm dev:workshop:backend\" \"pnpm dev:workshop:website\"", - "dev:workshop:backend": "docker compose -f apps/store/docker-compose.yml up --build --remove-orphans", - "dev:workshop:website": "pnpm -F @homarr/workshop build && pnpm -F @homarr/docs clear && cross-env WORKSHOP_API_URL=http://localhost:8090 NEXT_PUBLIC_WORKSHOP_API_URL=http://localhost:8090 pnpm -F @homarr/docs dev", + "dev:workshop:backend": "docker compose --env-file .env -f apps/workshop/docker-compose.yml up --build --remove-orphans", + "dev:workshop:website": "pnpm -F @homarr/workshop build && pnpm -F @homarr/docs clear && pnpm with-env sh -c 'WORKSHOP_API_URL=${WORKSHOP_API_URL:-http://localhost:${PB_EXPOSE_PORT:-8090}} pnpm -F @homarr/docs dev'", "docker:dev": "docker compose -f ./development/development.docker-compose.yml up", "format": "turbo format --continue -- --check", "format:fix": "turbo format --continue", @@ -36,7 +36,7 @@ "start": "concurrently \"pnpm with-env node apps/tasks/tasks.cjs\" \"pnpm with-env node apps/websocket/wssServer.cjs\" \"pnpm -F nextjs start\"", "test": "cross-env NODE_ENV=development CI=true vitest run --exclude e2e --coverage.enabled ", "test:e2e": "cross-env NODE_ENV=development CI=true vitest e2e", - "test:workshop-backend": "bash apps/store/tests/run-integration.sh", + "test:workshop-backend": "bash apps/workshop/tests/run-integration.sh", "test:ui": "cross-env NODE_ENV=development CI=true vitest --exclude e2e --ui --coverage.enabled", "typecheck": "turbo typecheck", "with-env": "dotenv -e .env --"