# ============================================================ # opsx-loki - Development Docker Compose Configuration # ============================================================ # P0 Fixes: # - Non-root kubeconfig mount (/home/opsxloki/.kube) # - Healthcheck for orchestration visibility # - Resource limits to prevent noisy-neighbor # - security_opt: no-new-privileges # - Log rotation (json-file driver) # - Named volumes instead of bind mounts # P1 Fixes: # - Restart policy optimization # - Network isolation # ============================================================ services: opsxloki: build: context: . dockerfile: Dockerfile args: TARGETARCH: ${TARGETARCH:-amd64} image: lghost/lokistack:latest container_name: opsxloki hostname: opsxloki # ---- P0: Security options ---- security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: # Required for healthcheck (wget) and runtime operations - NET_BIND_SERVICE # Required for file operations in /app/data - CHOWN - SETGID - SETUID read_only: false # Dev mode needs writable /app/data ports: - "${SERVER_PORT:-8080}:8080" # ---- P0: Named volumes for data persistence ---- volumes: - opsxloki-data:/app/data # P0: Mount kubeconfig to non-root user directory - ${KUBECONFIG_PATH:-${HOME}/.kube}:/home/opsxloki/.kube:ro # SSH keys for host-based deployments - ${SSH_KEY_PATH:-${HOME}/.ssh}:/home/opsxloki/.ssh:ro # ---- P0: Environment variables (no default secrets) ---- environment: - SERVER_PORT=8080 - DATA_DIR=/app/data # P0: JWT_SECRET must be provided externally # Set via .env file or shell export before running docker compose up. # 注意:错误提示里不要内嵌 $(openssl ...),否则会在 compose 解析时被执行。 - "JWT_SECRET=${JWT_SECRET:?JWT_SECRET is required. Generate: openssl rand -hex 32, then: export JWT_SECRET=}" # P0: ENCRYPTION_KEY must be provided externally (AES-256, >=32 字符) - "ENCRYPTION_KEY=${ENCRYPTION_KEY:?ENCRYPTION_KEY is required. Generate: openssl rand -hex 32, then: export ENCRYPTION_KEY=}" # KUBECONFIG points to non-root user's .kube directory - KUBECONFIG=/home/opsxloki/.kube/config # ---- P0: Healthcheck ---- healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/index.html"] interval: 30s timeout: 5s retries: 3 start_period: 15s # ---- P0: Resource limits ---- deploy: resources: limits: cpus: '2.0' memory: 512M pids: 100 reservations: cpus: '0.25' memory: 64M # ---- P0: Log rotation ---- logging: driver: "json-file" options: max-size: "50m" max-file: "5" labels: "service,image" env: "SERVER_PORT,DATA_DIR" # ---- P1: Restart policy ---- restart: unless-stopped stop_grace_period: 15s networks: - opsxloki-net # ---- Named volumes ---- volumes: opsxloki-data: driver: local labels: - "com.opsxloki.description=opsx-loki data directory" # ---- Network isolation ---- networks: opsxloki-net: driver: bridge ipam: config: - subnet: 172.28.0.0/16 labels: - "com.opsxloki.description=opsx-loki internal network"