22b2583f0b
O.0 prep from OPERATOR-PLAN.md. Mechanical refactor before adding partner management and operator-specific endpoints. The service now owns more than just provisioning orchestration (it'll soon own partners, tenant lifecycle actions, multi-audience JWT validation), so the name 'platform-api' reflects its scope better. What changed: - Directory: services/provisioning/ -> services/platform-api/ - Package: @dezky/provisioning -> @dezky/platform-api - Docker: container_name dezky-provisioning -> dezky-platform-api; compose service key 'provisioning' -> 'platform-api'; volume provisioning_node_modules -> platform_api_node_modules - Portal: PROVISIONING_INTERNAL_URL env var -> PLATFORM_API_INTERNAL_URL, default URL http://provisioning:3001 -> http://platform-api:3001 in all three proxy routes (me.get.ts, tenants/index.post.ts, tenants/[slug]/ reconcile.post.ts), plus NUXT_API_BASE updated - Health endpoint service identifier and main.ts log lines updated to 'dezky-platform-api' - Docs swept: README, CLAUDE.md, SERVICES.md, AUTHENTIK-SETUP.md, NEXT-STEPS.md, TROUBLESHOOTING.md, OPERATOR-PLAN.md, traefik/dynamic.yml What deliberately stays: - Internal module names ProvisioningService / ProvisioningModule (those describe an orchestration sub-concern, not the service's purpose) - Tenant.provisioningStatus / provisioningErrors field names (state per integration, not service name) - File services/platform-api/src/tenants/provisioning.service.ts - 'Hetzner provisioning' references in production-prep docs (infrastructure provisioning, unrelated) Verified end-to-end after rename: /api/me returns 200 with profile + 2 tenants + subscription, /api/tenants/dezky/reconcile returns 200 with Authentik integration still ok. OPERATOR-PLAN.md O.0 checkboxes ticked.
306 lines
6.6 KiB
Markdown
306 lines
6.6 KiB
Markdown
# Troubleshooting
|
|
|
|
Common issues and fixes when running the Dezky local development stack.
|
|
|
|
## TLS / Certificate issues
|
|
|
|
### Browser shows "Not Secure" or certificate warning
|
|
|
|
mkcert root CA isn't trusted in your browser yet.
|
|
|
|
```bash
|
|
mkcert -install
|
|
```
|
|
|
|
Then **fully restart your browser** (quit, not just close window).
|
|
|
|
### Certificate not loading in Traefik
|
|
|
|
Verify the cert files exist:
|
|
```bash
|
|
ls -la infrastructure/docker-compose/certs/
|
|
# Should show:
|
|
# dezky.local.pem
|
|
# dezky.local-key.pem
|
|
```
|
|
|
|
If they're named differently (e.g. `_wildcard.dezky.local+1.pem`), rename them:
|
|
```bash
|
|
cd infrastructure/docker-compose/certs/
|
|
mv _wildcard.dezky.local+*.pem dezky.local.pem
|
|
mv _wildcard.dezky.local+*-key.pem dezky.local-key.pem
|
|
```
|
|
|
|
Then restart Traefik:
|
|
```bash
|
|
docker compose restart traefik
|
|
```
|
|
|
|
### Service-to-service TLS errors
|
|
|
|
Inside Docker, services talk via internal hostnames (e.g. `authentik-server:9000`), not `auth.dezky.local`. Internal traffic uses HTTP, not HTTPS. Only Traefik handles TLS termination.
|
|
|
|
If a service config has `https://authentik-server`, change it to `http://authentik-server`.
|
|
|
|
---
|
|
|
|
## Container startup issues
|
|
|
|
### Authentik fails to start
|
|
|
|
Most common cause: PostgreSQL not ready yet, or password mismatch.
|
|
|
|
```bash
|
|
# Check postgres is healthy
|
|
docker compose ps postgres
|
|
# Should show "healthy" in STATUS
|
|
|
|
# Check Authentik DB user exists
|
|
docker compose exec postgres psql -U postgres -c "\du"
|
|
# Should list "authentik" as a user
|
|
|
|
# Check Authentik logs
|
|
docker compose logs authentik-server | tail -50
|
|
```
|
|
|
|
If password is wrong, reset and re-bootstrap:
|
|
```bash
|
|
./scripts/reset.sh
|
|
./scripts/bootstrap.sh
|
|
```
|
|
|
|
### Port 25 conflict (Stalwart fails to bind)
|
|
|
|
macOS often has Postfix running by default:
|
|
```bash
|
|
sudo launchctl unload /System/Library/LaunchDaemons/org.postfix.master.plist 2>/dev/null || true
|
|
sudo launchctl stop org.postfix.master 2>/dev/null || true
|
|
```
|
|
|
|
Or just disable the SMTP port mapping in `docker-compose.yml` for local dev:
|
|
```yaml
|
|
stalwart:
|
|
# ports:
|
|
# - "25:25" # comment out if conflicting
|
|
```
|
|
|
|
### Port 80/443 conflict (Traefik fails to bind)
|
|
|
|
Another service is using those ports.
|
|
```bash
|
|
# Find what's using port 80
|
|
sudo lsof -nP -i:80 -sTCP:LISTEN
|
|
```
|
|
|
|
Common culprits: nginx, apache, Caddy, other Docker stacks. Stop them or change Traefik to use 8080/8443.
|
|
|
|
### OCIS crashes on first start
|
|
|
|
OCIS needs to initialize before running. The compose file does this via:
|
|
```yaml
|
|
command: ["-c", "ocis init --insecure true || true && ocis server"]
|
|
```
|
|
|
|
If init fails:
|
|
```bash
|
|
# Manually init
|
|
docker compose run --rm ocis ocis init --insecure true
|
|
|
|
# Then start
|
|
docker compose up -d ocis
|
|
```
|
|
|
|
---
|
|
|
|
## DNS / hostname issues
|
|
|
|
### `app.dezky.local` doesn't resolve
|
|
|
|
Check /etc/hosts:
|
|
```bash
|
|
grep dezky.local /etc/hosts
|
|
```
|
|
|
|
Should see entries pointing 127.0.0.1 to all hostnames. If missing, run:
|
|
```bash
|
|
./scripts/bootstrap.sh # Will offer to add them
|
|
```
|
|
|
|
Or manually:
|
|
```bash
|
|
echo "127.0.0.1 dezky.local app.dezky.local auth.dezky.local mail.dezky.local files.dezky.local office.dezky.local meet.dezky.local chat.dezky.local traefik.dezky.local" | sudo tee -a /etc/hosts
|
|
```
|
|
|
|
### Browser DNS cache holding old entry
|
|
|
|
Clear browser cache, or test from terminal:
|
|
```bash
|
|
ping app.dezky.local
|
|
# Should return 127.0.0.1
|
|
```
|
|
|
|
If terminal resolves but browser doesn't:
|
|
- Chrome: chrome://net-internals/#dns → Clear host cache
|
|
- Firefox: about:networking#dns → Clear DNS cache
|
|
|
|
---
|
|
|
|
## Authentik OIDC integration issues
|
|
|
|
### "Invalid issuer URL"
|
|
|
|
The `iss` claim in the JWT must match exactly what the consuming service expects.
|
|
|
|
```yaml
|
|
# In docker-compose.yml for OCIS:
|
|
OCIS_OIDC_ISSUER: https://auth.dezky.local/application/o/ocis/
|
|
```
|
|
|
|
The trailing slash matters. Authentik issues with trailing slash by default.
|
|
|
|
Verify the actual issuer:
|
|
```bash
|
|
curl -s https://auth.dezky.local/application/o/ocis/.well-known/openid-configuration | jq .issuer
|
|
```
|
|
|
|
### "redirect_uri not allowed"
|
|
|
|
The OAuth provider in Authentik must list every redirect URI the client might use.
|
|
|
|
For OCIS:
|
|
```
|
|
https://files.dezky.local/
|
|
https://files.dezky.local/oidc-callback
|
|
```
|
|
|
|
Add both. Patterns matter — exact match.
|
|
|
|
### Login loop (redirects forever)
|
|
|
|
Usually caused by:
|
|
1. **Time mismatch** between container and host. Check `docker compose exec ocis date` matches host clock.
|
|
2. **Cookie domain mismatch.** Cookies set for `.dezky.local` should work across subdomains.
|
|
|
|
---
|
|
|
|
## Hot reload not working
|
|
|
|
### Nuxt portal doesn't rebuild on file changes
|
|
|
|
The volume mount works on macOS but file watching needs explicit polling:
|
|
|
|
Add to `apps/portal/nuxt.config.ts`:
|
|
```ts
|
|
export default defineNuxtConfig({
|
|
vite: {
|
|
server: {
|
|
watch: {
|
|
usePolling: true,
|
|
interval: 1000,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
### NestJS platform-api doesn't restart
|
|
|
|
Same issue. The `start:dev` command uses nodemon under the hood. Make sure your `package.json` has:
|
|
```json
|
|
{
|
|
"scripts": {
|
|
"start:dev": "nest start --watch"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Data and reset issues
|
|
|
|
### Want to keep data but restart services
|
|
|
|
```bash
|
|
docker compose restart [service-name]
|
|
```
|
|
|
|
### Want to reset just one service
|
|
|
|
```bash
|
|
docker compose stop authentik-server authentik-worker
|
|
docker volume rm dezky_authentik_media dezky_authentik_certs
|
|
docker compose up -d authentik-server authentik-worker
|
|
```
|
|
|
|
### Full reset (nuclear option)
|
|
|
|
```bash
|
|
./scripts/reset.sh
|
|
./scripts/bootstrap.sh
|
|
```
|
|
|
|
---
|
|
|
|
## Performance issues
|
|
|
|
### Stack is using too much RAM
|
|
|
|
Check usage:
|
|
```bash
|
|
docker stats --no-stream
|
|
```
|
|
|
|
Top RAM consumers are usually:
|
|
- Zulip (4-6 GB) — disabled in main compose
|
|
- Jitsi (2-4 GB) — disabled in main compose
|
|
- Authentik server + worker (~1 GB each)
|
|
- OCIS (~1 GB)
|
|
- Collabora (1-2 GB if active document open)
|
|
|
|
For low-memory machines, disable services you're not using:
|
|
```bash
|
|
docker compose stop collabora # Save ~1 GB
|
|
docker compose stop ocis # Save ~1 GB if not testing files
|
|
```
|
|
|
|
### macOS Docker is slow
|
|
|
|
OrbStack is significantly faster than Docker Desktop on macOS:
|
|
```bash
|
|
brew install --cask orbstack
|
|
```
|
|
|
|
Or in Docker Desktop, enable VirtioFS for bind mount performance.
|
|
|
|
---
|
|
|
|
## Logs and debugging
|
|
|
|
### See logs from one service
|
|
```bash
|
|
docker compose logs -f authentik-server
|
|
```
|
|
|
|
### See logs from multiple services
|
|
```bash
|
|
docker compose logs -f authentik-server authentik-worker postgres
|
|
```
|
|
|
|
### Inspect a container
|
|
```bash
|
|
docker compose exec authentik-server sh
|
|
# or
|
|
docker compose exec postgres psql -U postgres
|
|
```
|
|
|
|
### See what's running
|
|
```bash
|
|
docker compose ps
|
|
```
|
|
|
|
### Network debugging — can services reach each other?
|
|
```bash
|
|
docker compose exec ocis ping -c 3 authentik-server
|
|
docker compose exec ocis curl -v http://authentik-server:9000/-/health/ready/
|
|
```
|