refactor: move workshop backend app

This commit is contained in:
Thomas Camlong committed 2026-07-14 01:21:53 +02:00
1 parent 55ba12473c
commit 699134a576
14 files changed
+25 -22

No files matched your search

+10
View File
@@ -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
-6
View File
@@ -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
-4
View File
@@ -1,4 +0,0 @@
.env
.env.*
!.env.example
pb_data/
+1
View File
@@ -0,0 +1 @@
pb_data/
File renamed without changes.
@@ -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.
@@ -1,3 +1,5 @@
name: homarr-workshop
services:
workshop:
build:
File renamed without changes.
File renamed without changes.
@@ -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
+3 -3
View File
@@ -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 --"