- Extract shared SlowAPI limiter to app/limiter.py to break circular import between app.main and app.routers.auth - Seed default SystemConfig row (id=1) on first DB init so settings page works out of the box - Make all docker_service.compose_* functions async (run_in_executor) so long docker pulls/stops no longer block the async event loop - Propagate async to netbird_service stop/start/restart and await callers in deployments router - Move customer delete to BackgroundTasks so the HTTP response returns immediately and avoids frontend "Network error" on slow machines - docker-compose: add :z SELinux labels, mount docker.sock directly, add security_opt label:disable for socket access, extra_hosts for host.docker.internal, enable DELETE/VOLUMES on socket proxy - npm_service: auto-detect outbound host IP via UDP socket when HOST_IP env var is not set Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
77 lines
2.2 KiB
YAML
77 lines
2.2 KiB
YAML
services:
|
|
# ---------------------------------------------------------------------------
|
|
# Docker Socket Proxy — limits Docker API access to only what is needed.
|
|
# The main app container no longer has direct access to /var/run/docker.sock.
|
|
# ---------------------------------------------------------------------------
|
|
docker-socket-proxy:
|
|
image: tecnativa/docker-socket-proxy:latest
|
|
container_name: docker-socket-proxy
|
|
restart: unless-stopped
|
|
environment:
|
|
# Read-only endpoints
|
|
CONTAINERS: 1
|
|
IMAGES: 1
|
|
NETWORKS: 1
|
|
INFO: 1
|
|
# Write endpoints (needed for compose up/down/start/stop)
|
|
POST: 1
|
|
DELETE: 1
|
|
# Volumes needed for docker compose (creates/removes volumes per customer)
|
|
VOLUMES: 1
|
|
# Explicitly deny dangerous endpoints
|
|
AUTH: 0
|
|
SECRETS: 0
|
|
SWARM: 0
|
|
NODES: 0
|
|
SERVICES: 0
|
|
TASKS: 0
|
|
CONFIGS: 0
|
|
PLUGINS: 0
|
|
BUILD: 0
|
|
COMMIT: 0
|
|
DISTRIBUTION: 0
|
|
EXEC: 1
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro,z
|
|
networks:
|
|
- npm-network
|
|
# Only accessible from within the Docker network — never expose port externally
|
|
|
|
netbird-msp-appliance:
|
|
build: .
|
|
container_name: netbird-msp-appliance
|
|
restart: unless-stopped
|
|
security_opt:
|
|
- label:disable
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
depends_on:
|
|
- docker-socket-proxy
|
|
ports:
|
|
- "${WEB_UI_PORT:-8000}:8000"
|
|
volumes:
|
|
- ./data:/app/data:z
|
|
- ./logs:/app/logs:z
|
|
- ./backups:/app/backups:z
|
|
- /var/run/docker.sock:/var/run/docker.sock:z
|
|
- ${DATA_DIR:-/opt/netbird-instances}:${DATA_DIR:-/opt/netbird-instances}:z
|
|
environment:
|
|
- SECRET_KEY=${SECRET_KEY}
|
|
- DATABASE_PATH=/app/data/netbird_msp.db
|
|
- LOG_LEVEL=${LOG_LEVEL:-INFO}
|
|
- DATA_DIR=${DATA_DIR:-/opt/netbird-instances}
|
|
- DOCKER_NETWORK=${DOCKER_NETWORK:-npm-network}
|
|
- HOST_IP=${HOST_IP:-}
|
|
networks:
|
|
- npm-network
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 15s
|
|
|
|
networks:
|
|
npm-network:
|
|
external: true
|