Files
LokiStack/docker-compose.yml
T
opsx b65dcc9677 refactor: 镜像名 lghost/opsxloki → lghost/lokistack(跟随项目更名)
只改镜像引用(8 处),K8s 资源名一律不动 —— 改了会丢数据/断服务:

改:
  kubernetes/deployment.yaml        image
  docker-compose.yml                image
  docker-compose.prod.yml           image ×2
  kubernetes/README.md              文档 ×2
  docs/deployment/kubernetes.md     文档 ×2

不改(重要):
  opsxloki-secrets    K8s Secret —— 改名会导致 JWT_SECRET/ENCRYPTION_KEY 重置,
                      历史加密的实例密码无法解密
  opsxloki-data       PVC —— 改名 = 新建空卷,数据全丢
  container_name      docker 容器名 —— 改名会让 docker exec/logs 命令失效
  app: opsx-loki      Pod label —— 改名要同步改 Service selector
  deployment 名称 opsx-loki —— 改名要重建 Deployment

⚠️ 部署顺序(本提交只改代码,尚未 apply 到 K8s):
  1) 推镜像 lghost/lokistack:latest 到 Docker Hub
  2) kubectl apply -f kubernetes/deployment.yaml
  3) 等 Pod 1/1 就绪
  4) 才能删除 lghost/opsxloki
  顺序颠倒会因 imagePullPolicy: Always 拉到不存在的镜像导致服务中断
2026-10-26 17:09:47 +00:00

116 lines
3.4 KiB
YAML

# ============================================================
# 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=<value>}"
# 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=<value>}"
# 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"