Skip to content

Server Context

This guide documents the server environment for agents working on this system. Understanding this context is essential before making changes.

SoftwareVersion
n8n2.12.3
PostgreSQL15.15
Node (docs)22
Astro6.0.6
Starlight0.38.1
Traefiklatest

Last updated: 19.mar.2026

ServiceContainerImagePurpose
traefiktraefiktraefik:latestReverse proxy, SSL termination
docsdocsdocs-starlightDocumentation site (Starlight)
n8nn8nn8nio/n8n:latestWorkflow automation
postgres-mainpostgres-mainpostgres:15-alpinePostgreSQL database
bucko-web-prodbucko-web-prodbucko-bucko-webStatic website (Astro)
admineradmineradminerDatabase admin UI
promtailpromtailgrafana/promtail:latestLog shipping
PathPurpose
/opt/docker/All Docker projects root
/opt/docker/bucko/Bucko website (Astro)
/opt/docker/docs/Documentation site (Starlight)
/opt/docker/n8n/n8n workflow automation
/opt/docker/postgres/PostgreSQL configuration
/opt/docker/traefik/Traefik reverse proxy
/home/<username>/User home, backup storage
┌─────────────────┐
│ Traefik │
│ (reverse proxy)│
│ :80, :443 │
└────────┬────────┘
┌────────┴────────┐
│ proxy network │
│ (external) │
└────────┬────────┘
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ docs │ │ n8n │ │bucko-web │
│ :4322 │ │ :5678 │ │ :4321 │
└───────────┘ └─────┬─────┘ └───────────┘
┌───────────┐
│ postgres │
│ :5432 │
└───────────┘

All web services connect to the proxy Docker network. Traefik routes traffic based on Host headers.

DomainServiceContainer
bucko.example.comBucko websitebucko-web-prod
n8n.example.comn8n workflowsn8n
docs.example.comDocumentationdocs
adm.example.comTraefik dashboardtraefik
ServiceLocationNotes
PostgreSQL/opt/docker/postgres/compose.yamlPOSTGRES_PASSWORD
n8n database/opt/docker/n8n/compose.yamlDB_POSTGRESDB_PASSWORD
n8n encryption/opt/docker/n8n/compose.yamlN8N_ENCRYPTION_KEY - also in volume
Traefik/opt/docker/traefik/compose.yamlACME email for Let’s Encrypt

To expose a service through Traefik, add these labels to compose.yaml:

labels:
- "traefik.enable=true"
- "traefik.http.routers.<name>.rule=Host(`<domain>`)"
- "traefik.http.routers.<name>.entrypoints=websecure"
- "traefik.http.routers.<name>.tls.certresolver=letsencrypt"
- "traefik.http.services.<name>.loadbalancer.server.port=<internal_port>"
Terminal window
# List all running containers
docker ps
# View container logs
docker logs <container_name>
# Follow logs in real-time
docker logs -f <container_name>
# Restart a service
cd /opt/docker/<service> && docker compose restart
# Rebuild and restart
cd /opt/docker/<service> && docker compose build && docker compose up -d
Terminal window
# List databases
docker exec postgres-main psql -U postgres -c "\l"
# Backup a database
docker exec postgres-main pg_dump -U <user> <database> > backup.sql
# Restore a database
cat backup.sql | docker exec -i postgres-main psql -U <user> -d <database>
Terminal window
# Check Traefik logs for errors
docker logs traefik | grep -i error
# Verify container labels
docker inspect <container_name> --format '{{json .Config.Labels}}' | jq
# Check proxy network
docker network inspect proxy

For services that require building (docs, bucko), create a build.sh script.

Download: build.sh

Or create /opt/docker/<service>/build.sh:

#!/bin/sh
docker run --rm \
-v "$(dirname "$0")":/app \
-w /app \
node:22-alpine \
sh -c "npm install && npm run build"

Make it executable:

Terminal window
chmod +x /opt/docker/<service>/build.sh

Every time you add or modify .md files:

Terminal window
cd /opt/docker/<service>
./build.sh # Generate dist/
docker compose build --no-cache && docker compose up -d # Rebuild + restart

Compare running container image IDs with local latest images:

Terminal window
# Get running container image ID
docker inspect <container_name> --format '{{.Image}}'
# Pull latest image
docker pull <image>:latest
# Compare with local images
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}" | grep <image>
  1. Pull the latest image:

    Terminal window
    docker pull <image>:latest
  2. Recreate the container:

    Terminal window
    cd /opt/docker/<service>
    docker compose up -d
  3. Verify update:

    Terminal window
    docker inspect <container_name> --format '{{.Image}}'
    docker images --format "{{.ID}}" <image>:latest

Both IDs should match after update.

ContainerImageUpdate Command
traefiktraefik:latestcd /opt/docker/traefik && docker compose up -d
n8nn8nio/n8n:latestcd /opt/docker/n8n && docker compose up -d
postgres-mainpostgres:15-alpinecd /opt/docker/postgres && docker compose up -d
admineradminercd /opt/docker/adminer && docker compose up -d
promtailgrafana/promtail:latestcd /opt/docker/promtail && docker compose up -d
LocationContents
/home/<username>/Local backup copies (persistent)
/opt/docker/docs/public/downloads/Downloadable backups via docs site
Terminal window
docker logs <container_name>

Check for port conflicts, missing volumes, or configuration errors.

  1. Verify container has correct labels
  2. Verify container is on proxy network
  3. Check Traefik logs: docker logs traefik
Terminal window
docker inspect <container_name> | grep -A 20 Labels
docker network inspect proxy
  1. Check postgres is running: docker ps | grep postgres
  2. Verify credentials in compose.yaml match
  3. Test connection: docker exec postgres-main psql -U postgres -c "\l"

Files created by Docker may be owned by root. Use Docker to modify:

Terminal window
docker run --rm -v /opt/docker/<service>:/app -w /app node:22-alpine sh -c "rm -rf node_modules"