From 9fd34731472c41437ac8b050d47a3894ca04dbcb Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Wed, 18 Mar 2026 17:26:41 +0100 Subject: [PATCH] Fix sandbox Docker root issue and replace make dev with systemd services Fixes docker permissions by enabling Docker daemon during provisioning. Replaces make dev with three managed systemd services: probo-stack (auto-starting Docker Compose infra), probod (API server with gow for hot-reload), and probo-console (frontend dev server). The stack now starts automatically on VM boot; probod and console are started manually after build. Signed-off-by: Bryan Frimin --- AGENTS.md | 1 - GNUmakefile | 4 --- contrib/claude/sandbox.md | 50 +++++++++++++++++++++++-------- contrib/lima/README.md | 12 ++++---- contrib/lima/provision.sh | 62 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 24 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5f9c294b6..4b5c878dd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,7 +11,6 @@ | `make test-verbose` | Tests with verbose output | | `make lint` | Vet + Go lint + npm lint | | `make fmt` | Format Go code | -| `make dev` | Start dev server (Go + console hot-reload) | | `make test-e2e` | Run console end-to-end tests (requires `bin/probod`) | | `make deadcode` | Detect dead code — run after removing or renaming exported functions | | `make stack-up` / `make stack-down` | Start / stop Docker compose infra | diff --git a/GNUmakefile b/GNUmakefile index ee0f3392f..5bee34e14 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -244,10 +244,6 @@ pkg/server/api/mcp/v1/types/types.go: pkg/server/api/mcp/v1/specification.yaml p help: ## Show this help @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' -.PHONY:dev -dev: ## Start the development server - parallel -j 2 --line-buffer ::: "gow -r=false run cmd/probod/main.go" "cd apps/console && npm run dev" - .PHONY: fmt fmt: fmt-go ## Format Go code diff --git a/contrib/claude/sandbox.md b/contrib/claude/sandbox.md index 725268e82..d51715aab 100644 --- a/contrib/claude/sandbox.md +++ b/contrib/claude/sandbox.md @@ -3,8 +3,8 @@ ## When to use Use a sandbox when you need to: -- Run `make stack-up` (Docker services: Postgres, SeaweedFS, etc.) -- Test changes end-to-end with `make dev` or `make test-e2e` +- Run the full service stack (Docker services, probod, console) +- Test changes end-to-end with `make test-e2e` - Build the full binary with `make build` - Run any command that requires Docker or the full service stack @@ -17,11 +17,9 @@ Use a sandbox when you need to: # Start an existing sandbox ./contrib/lima/sandbox.sh start -# Run commands inside the sandbox -./contrib/lima/sandbox.sh exec -- make stack-up +# Build and start the app (probo-stack starts automatically on boot) ./contrib/lima/sandbox.sh exec -- make build -./contrib/lima/sandbox.sh exec -- make dev -./contrib/lima/sandbox.sh exec -- make test +./contrib/lima/sandbox.sh exec -- sudo systemctl start probod probo-console # Get the VM IP and service URLs ./contrib/lima/sandbox.sh status @@ -56,27 +54,53 @@ During provisioning, the sandbox automatically generates: - **`/etc/probod/config.yml`** — probod config with the VM IP as cookie domain, `secure: false`, and correct CORS origins - **`apps/console/.env`** and **`apps/trust/.env`** — `VITE_API_URL` pointing to the VM IP -Use `-cfg-file /etc/probod/config.yml` when running probod in the sandbox. +Probod config is at `/etc/probod/config.yml`. + +## Systemd services + +The sandbox provisions three systemd services: + +| Service | Description | Starts on boot | +|---|---|---| +| `probo-stack` | Docker Compose stack (Postgres, SeaweedFS, Keycloak, etc.) | Yes | +| `probod` | Probo API server (depends on `probo-stack`) | No | +| `probo-console` | Console frontend dev server | No | + +`probo-stack` starts automatically when the VM boots. `probod` and `probo-console` must be started manually after building. + +Manage them with `systemctl`: +```bash +./contrib/lima/sandbox.sh exec -- sudo systemctl start probod probo-console +./contrib/lima/sandbox.sh exec -- sudo systemctl stop probod +./contrib/lima/sandbox.sh exec -- sudo systemctl restart probod +./contrib/lima/sandbox.sh exec -- sudo systemctl status probod +./contrib/lima/sandbox.sh exec -- sudo journalctl -u probod -f +``` ## Common workflows -**Build and test:** +**Start the app:** +```bash +./contrib/lima/sandbox.sh exec -- make build +./contrib/lima/sandbox.sh exec -- sudo systemctl start probod probo-console +``` + +**Run tests:** ```bash -./contrib/lima/sandbox.sh exec -- make stack-up ./contrib/lima/sandbox.sh exec -- make build ./contrib/lima/sandbox.sh exec -- make test ``` **Run e2e tests:** ```bash -./contrib/lima/sandbox.sh exec -- make stack-up ./contrib/lima/sandbox.sh exec -- make test-e2e ``` **Restart after code changes:** -Code changes are reflected immediately (virtiofs mount). Just re-run the -relevant make target — no need to restart the VM. +Code changes are reflected immediately (virtiofs mount). Just rebuild and +restart probod — no need to restart the VM. ```bash -./contrib/lima/sandbox.sh exec -- make dev +./contrib/lima/sandbox.sh exec -- make build +./contrib/lima/sandbox.sh exec -- sudo systemctl restart probod ``` diff --git a/contrib/lima/README.md b/contrib/lima/README.md index 06ddd678f..5217f67d0 100644 --- a/contrib/lima/README.md +++ b/contrib/lima/README.md @@ -19,15 +19,15 @@ brew install lima jq # Check status and get the VM IP ./contrib/lima/sandbox.sh status -# Start the Docker stack inside the VM -./contrib/lima/sandbox.sh exec -- make stack-up - -# Build and run the dev server +# Build the backend binary (probo-stack starts automatically on boot) ./contrib/lima/sandbox.sh exec -- make build -./contrib/lima/sandbox.sh exec -- make dev + +# Start probod and the console dev server +./contrib/lima/sandbox.sh exec -- sudo systemctl start probod probo-console # Access services from your host browser using the VM IP -# e.g. http://192.168.105.2:5173 +# e.g. http://192.168.105.2:5173 (console) +# e.g. http://192.168.105.2:8080 (API) ``` ## Commands diff --git a/contrib/lima/provision.sh b/contrib/lima/provision.sh index 76d05a055..cdec9abe2 100755 --- a/contrib/lima/provision.sh +++ b/contrib/lima/provision.sh @@ -45,6 +45,8 @@ if ! command -v docker &>/dev/null; then containerd.io \ docker-buildx-plugin \ docker-compose-plugin + + systemctl enable --now docker fi usermod -aG docker "${LIMA_CIDATA_USER:-lima}" 2>/dev/null || true @@ -107,3 +109,63 @@ AWS_USE_PATH_STYLE=true \ echo "VITE_API_URL=http://${VM_IP}:8080" > /workspace/apps/console/.env echo "VITE_API_URL=http://${VM_IP}:8080" > /workspace/apps/trust/.env + +# Install systemd services for the sandbox +cat > /etc/systemd/system/probo-stack.service << 'EOF' +[Unit] +Description=Probo Docker Compose Stack +Requires=docker.service +After=docker.service + +[Service] +Type=simple +User=root +WorkingDirectory=/workspace +ExecStart=/usr/bin/docker compose -f compose.yaml up +ExecStop=/usr/bin/docker compose -f compose.yaml down +Restart=on-failure +RestartSec=5s + +[Install] +WantedBy=multi-user.target +EOF + +cat > /etc/systemd/system/probod.service << EOF +[Unit] +Description=Probo API Server +Requires=probo-stack.service +After=probo-stack.service + +[Service] +Type=simple +User=${LIMA_USER} +WorkingDirectory=/workspace +ExecStart=/usr/local/bin/gow -r=false run ./cmd/probod -cfg-file /etc/probod/config.yml +Restart=on-failure +RestartSec=3s +Environment=PATH=/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin + +[Install] +WantedBy=multi-user.target +EOF + +cat > /etc/systemd/system/probo-console.service << EOF +[Unit] +Description=Probo Console Dev Server +After=probod.service + +[Service] +Type=simple +User=${LIMA_USER} +WorkingDirectory=/workspace +ExecStart=/usr/bin/npm --workspace @probo/console run dev -- --host 0.0.0.0 +Restart=on-failure +RestartSec=3s + +[Install] +WantedBy=multi-user.target +EOF + +systemctl daemon-reload +systemctl enable --now probo-stack.service +systemctl enable probod.service probo-console.service