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 <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-03-18 17:26:41 +01:00
parent a5743729f7
commit 9fd3473147
5 changed files with 105 additions and 24 deletions

View File

@@ -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 |

View File

@@ -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

View File

@@ -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
```

View File

@@ -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

View File

@@ -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