From 0f174ae967aded8cb87c9db8b37e9a2f02a91cb6 Mon Sep 17 00:00:00 2001 From: fkrebs Date: Thu, 28 May 2026 10:01:56 +0200 Subject: [PATCH] auto: sync 2026-05-28 --- act-runner/compose.yaml | 17 ++++++ ai/docker-compose.yml | 90 ++++++++++++++++++++++++++++ alloy/docker-compose.yml | 20 +++++++ coder/compose.yaml | 24 ++++++++ dozzle/docker-compose.yml | 43 +++++++++++++ gitea-pages-proxy/docker-compose.yml | 19 ++++++ gitea/compose.yaml | 53 ++++++++++++++++ miniflux/docker-compose.yml | 30 ++++++++++ ops-agents/docker-compose.yml | 16 +++++ paperless_ai/docker-compose.yml | 21 +++++++ proton-bridge/docker-compose.yml | 18 ++++++ qdrant/docker-compose.yml | 26 ++++++++ socket-proxy/docker-compose.yml | 25 ++++++++ vpn/docker-compose.yml | 46 ++++++++++++++ 14 files changed, 448 insertions(+) create mode 100644 act-runner/compose.yaml create mode 100644 ai/docker-compose.yml create mode 100644 alloy/docker-compose.yml create mode 100644 coder/compose.yaml create mode 100644 dozzle/docker-compose.yml create mode 100644 gitea-pages-proxy/docker-compose.yml create mode 100644 gitea/compose.yaml create mode 100644 miniflux/docker-compose.yml create mode 100644 ops-agents/docker-compose.yml create mode 100644 paperless_ai/docker-compose.yml create mode 100644 proton-bridge/docker-compose.yml create mode 100644 qdrant/docker-compose.yml create mode 100644 socket-proxy/docker-compose.yml create mode 100644 vpn/docker-compose.yml diff --git a/act-runner/compose.yaml b/act-runner/compose.yaml new file mode 100644 index 0000000..e6b6aa6 --- /dev/null +++ b/act-runner/compose.yaml @@ -0,0 +1,17 @@ +name: act-runner + +services: + act-runner: + image: gitea/act_runner:latest + container_name: act-runner + restart: unless-stopped + environment: + GITEA_INSTANCE_URL: "https://git.nuclide.systems" + GITEA_RUNNER_REGISTRATION_TOKEN: "${ACT_TOKEN}" + GITEA_RUNNER_NAME: "ct104-runner" + GITEA_RUNNER_LABELS: "docker,ubuntu-latest:docker://node:20-bookworm,debian:docker://debian:bookworm" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./data:/data + group_add: + - "996" diff --git a/ai/docker-compose.yml b/ai/docker-compose.yml new file mode 100644 index 0000000..42bf999 --- /dev/null +++ b/ai/docker-compose.yml @@ -0,0 +1,90 @@ +name: nuc-ai-core + +include: + # - path: ./lobehub.yml # decommissioned 2026-05-26 + - path: ./open-terminal.yml + - path: ./qdrant.yml + - path: ./tei.yml + - path: ./nomic.yml + - path: ./searxng.yaml + #- path: ./mcp-tools.yaml # All your MCP servers (Nextcloud, etc.) + # SAIA image/STT/edit now handled natively by LiteLLM (saia-* models in + # litellm-config/config.yaml); Docling moved to the docling-mcp stack. + +services: + # --- LiteLLM Gateway --- + # --- LiteLLM (DECOMMISSIONED 2026-05-26 — stopped; Bifrost replaced it) --- + # litellm: + # image: ghcr.io/berriai/litellm:main-latest + # container_name: litellm + # volumes: + # - ./litellm-config:/app/config + # env_file: .env + # ports: + # - "14000:4000" + # networks: + # - ai-internal + # - shared_backend + # command: ["--config", "/app/config/config.yaml"] + # labels: + # - "homepage.group=ai" + # - "homepage.name=LiteLLM" + # - "homepage.icon=sh-litellm" + # - "homepage.href=https://ai.nuclide.systems" + # - "homepage.instance.internal.href=http://192.168.1.40:14000" + # - "homepage.instance.public.href=https://ai.nuclide.systems" + # healthcheck: + # test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:4000/health/liveliness')"] + # interval: 10s + # timeout: 5s + # retries: 10 + # start_period: 30s + + # syncstack: + # build: + # context: . + # dockerfile: Dockerfile.syncstack + # env_file: .env + # volumes: + # - ./.env:/app/.env + # - .:/project + # - /var/run/docker.sock:/var/run/docker.sock + # networks: + # - ai-internal + # depends_on: + # litellm: + # condition: service_healthy + # lobe: + # condition: service_healthy + # restart: "no" +# + claude-max-bridge: + build: + context: /opt/stacks/ai/claude-max-bridge + dockerfile: Dockerfile + container_name: claude-max-bridge + restart: unless-stopped + environment: + CLAUDE_BIN: /usr/local/bin/claude + CLAUDE_HOME: /root/.claude + LOG_LEVEL: INFO + REQUEST_TIMEOUT_S: "120" + volumes: + - /usr/local/bin/claude:/usr/local/bin/claude:ro + - /root/.claude:/root/.claude:rw + - /root/.claude.json:/root/.claude.json:rw + networks: + - ai-internal + healthcheck: + test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s + +networks: + ai-internal: + external: true + shared_backend: + external: true + diff --git a/alloy/docker-compose.yml b/alloy/docker-compose.yml new file mode 100644 index 0000000..0ffe841 --- /dev/null +++ b/alloy/docker-compose.yml @@ -0,0 +1,20 @@ +services: + alloy: + image: grafana/alloy:latest + container_name: alloy + restart: unless-stopped + ports: + - "12345:12345" + volumes: + - /opt/stacks/alloy/config.alloy:/etc/alloy/config.alloy:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + - /var/log/journal:/var/log/journal:ro + - /run/log/journal:/run/log/journal:ro + - /etc/machine-id:/etc/machine-id:ro + group_add: + - "999" + command: + - run + - /etc/alloy/config.alloy + - --server.http.listen-addr=0.0.0.0:12345 + - --stability.level=generally-available diff --git a/coder/compose.yaml b/coder/compose.yaml new file mode 100644 index 0000000..bfba748 --- /dev/null +++ b/coder/compose.yaml @@ -0,0 +1,24 @@ +services: + coder: + image: ghcr.io/coder/coder:latest + container_name: coder + restart: unless-stopped + ports: + - "7080:7080" + environment: + CODER_HTTP_ADDRESS: "0.0.0.0:7080" + CODER_ACCESS_URL: "https://dev.nuclide.systems" + CODER_WILDCARD_ACCESS_URL: "*.dev.nuclide.systems" + CODER_PG_CONNECTION_URL: "postgresql://coder:${CODER_DB_PASSWORD}@192.168.1.6:5432/coder?sslmode=disable" + CODER_OIDC_ISSUER_URL: "https://id.nuclide.systems" + CODER_OIDC_CLIENT_ID: "${CODER_OIDC_CLIENT_ID}" + CODER_OIDC_CLIENT_SECRET: "${CODER_OIDC_CLIENT_SECRET}" + CODER_OIDC_ALLOW_SIGNUPS: "true" + CODER_OIDC_EMAIL_DOMAIN: "nucli.de" + CODER_DISABLE_PASSWORD_AUTH: "true" + CODER_OAUTH2_GITHUB_DEFAULT_PROVIDER_ENABLE: "false" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /mnt/pve/unas/services/coder:/home/coder + group_add: + - "996" diff --git a/dozzle/docker-compose.yml b/dozzle/docker-compose.yml new file mode 100644 index 0000000..2481858 --- /dev/null +++ b/dozzle/docker-compose.yml @@ -0,0 +1,43 @@ +# Run with docker compose up -d +services: + dozzle: + image: amir20/dozzle:latest + container_name: dozzle + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./dozzle_data:/data + ports: + - 10001:8080 + restart: unless-stopped + deploy: + resources: + limits: + cpus: "0.5" + memory: 256M + reservations: + cpus: "0.25" + memory: 128M + environment: + # Uncomment to enable container actions (stop, start, restart). See https://dozzle.dev/guide/actions + - DOZZLE_ENABLE_ACTIONS=true + # + # Uncomment to allow access to container shells. See https://dozzle.dev/guide/shell + # - DOZZLE_ENABLE_SHELL=true + # + # Uncomment to enable authentication. See https://dozzle.dev/guide/authentication + # - DOZZLE_AUTH_PROVIDER=simple + # + # Label this Dozzle instance (shown in the header and multi-host menu). See https://dozzle.dev/guide/hostname + - DOZZLE_HOSTNAME=nuc + # + # Connect to one or more remote agents to monitor other Docker hosts. See https://dozzle.dev/guide/agent + # - DOZZLE_REMOTE_AGENT=192.168.1.10:7007,192.168.1.11:7007 + # + # Only show containers matching a filter. See https://dozzle.dev/guide/filters + # - DOZZLE_FILTER=label=com.example.app + healthcheck: + disable: true +networks: + default: + external: true + name: shared_backend diff --git a/gitea-pages-proxy/docker-compose.yml b/gitea-pages-proxy/docker-compose.yml new file mode 100644 index 0000000..b0a184d --- /dev/null +++ b/gitea-pages-proxy/docker-compose.yml @@ -0,0 +1,19 @@ +name: gitea-pages-proxy + +# Thin nginx proxy so *.pages.nuclide.systems:80 reaches Gitea:3000 +# without the port suffix in the Host header that breaks Pages routing. +# Remove once a Zoraxy route is added for pages.nuclide.systems. +services: + pages-proxy: + image: nginx:alpine + container_name: gitea-pages-proxy + restart: unless-stopped + ports: + - "80:80" + volumes: + - /opt/stacks/gitea-pages-proxy/nginx.conf:/etc/nginx/nginx.conf:ro + labels: + - "homepage.group=infra" + - "homepage.name=Gitea Pages proxy" + +networks: {} diff --git a/gitea/compose.yaml b/gitea/compose.yaml new file mode 100644 index 0000000..90345b2 --- /dev/null +++ b/gitea/compose.yaml @@ -0,0 +1,53 @@ +services: + gitea-redis: + image: redis:7-alpine + container_name: gitea-redis + restart: unless-stopped + command: redis-server --requirepass ${GITEA_REDIS_PASS} + volumes: + - gitea_redis:/data + + gitea: + image: gitea/gitea:latest + container_name: gitea + restart: unless-stopped + depends_on: + - gitea-redis + ports: + - "3000:3000" + - "222:22" + environment: + USER_UID: "1000" + USER_GID: "1000" + GITEA__database__DB_TYPE: postgres + GITEA__database__HOST: 192.168.1.6:5432 + GITEA__database__NAME: gitea + GITEA__database__USER: gitea + GITEA__database__PASSWD: "${GITEA_DB_PASSWORD}" + GITEA__server__DOMAIN: git.nuclide.systems + GITEA__server__ROOT_URL: "https://git.nuclide.systems" + GITEA__server__SSH_DOMAIN: git.nuclide.systems + GITEA__server__SSH_PORT: "222" + GITEA__queue__TYPE: redis + GITEA__queue__CONN_STR: "redis://:${GITEA_REDIS_PASS}@gitea-redis:6379/0" + GITEA__cache__ADAPTER: redis + GITEA__cache__HOST: "redis://:${GITEA_REDIS_PASS}@gitea-redis:6379/1" + GITEA__session__PROVIDER: redis + GITEA__session__PROVIDER_CONFIG: "redis://:${GITEA_REDIS_PASS}@gitea-redis:6379/2" + GITEA__oauth2__ENABLED: "true" + GITEA__openid__ENABLE_OPENID_SIGNIN: "false" + GITEA__openid__ENABLE_OPENID_SIGNUP: "false" + GITEA__service__ENABLE_PASSWORD_SIGNIN_FORM: "false" + GITEA__oauth2_client__ENABLE_AUTO_REGISTRATION: "true" + GITEA__oauth2_client__ACCOUNT_LINKING: "auto" + GITEA__oauth2_client__USERNAME: "preferred_username" + GITEA__oauth2_client__UPDATE_AVATAR: "true" + GITEA__pages__ENABLED: "true" + GITEA__pages__DOMAIN: "pages.nuclide.systems" + GITEA__server__REVERSE_PROXY_LIMIT: "1" + GITEA__server__REVERSE_PROXY_TRUSTED_PROXIES: "10.0.12.2,172.16.0.0/12,192.168.0.0/16" + volumes: + - /mnt/pve/unas/services/gitea:/data + +volumes: + gitea_redis: diff --git a/miniflux/docker-compose.yml b/miniflux/docker-compose.yml new file mode 100644 index 0000000..6f3b422 --- /dev/null +++ b/miniflux/docker-compose.yml @@ -0,0 +1,30 @@ +name: miniflux + +services: + miniflux: + image: miniflux/miniflux:latest + container_name: miniflux + restart: unless-stopped + ports: + - "17002:8080" + environment: + DATABASE_URL: "postgresql://miniflux:${MINIFLUX_DB_PASSWORD}@192.168.1.6:5432/miniflux?sslmode=disable" + RUN_MIGRATIONS: "1" + BASE_URL: "https://flux.nuclide.systems" + OAUTH2_PROVIDER: "oidc" + OAUTH2_CLIENT_ID: "${MINIFLUX_OIDC_CLIENT_ID}" + OAUTH2_CLIENT_SECRET: "${MINIFLUX_OIDC_CLIENT_SECRET}" + OAUTH2_REDIRECT_URL: "https://flux.nuclide.systems/oauth2/oidc/callback" + OAUTH2_OIDC_DISCOVERY_ENDPOINT: "https://id.nuclide.systems" + OAUTH2_USER_CREATION: "1" + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:8080/healthcheck"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + labels: + - "homepage.group=Notes & Bookmarks" + - "homepage.name=Miniflux" + - "homepage.href=https://flux.nuclide.systems" + - "homepage.icon=miniflux" diff --git a/ops-agents/docker-compose.yml b/ops-agents/docker-compose.yml new file mode 100644 index 0000000..935bcb6 --- /dev/null +++ b/ops-agents/docker-compose.yml @@ -0,0 +1,16 @@ +name: ops-agents +services: + dozzle-agent: + image: amir20/dozzle:latest + container_name: dozzle-agent + command: agent + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock + ports: + - "7007:7007" + deploy: + resources: + limits: + cpus: "0.25" + memory: 64M diff --git a/paperless_ai/docker-compose.yml b/paperless_ai/docker-compose.yml new file mode 100644 index 0000000..44913e9 --- /dev/null +++ b/paperless_ai/docker-compose.yml @@ -0,0 +1,21 @@ +services: + paperless-ai: + image: clusterzx/paperless-ai + container_name: paperless-ai + network_mode: bridge + restart: unless-stopped + cap_drop: + - ALL + security_opt: + - no-new-privileges=true + environment: + - PUID=997 + - PGID=988 + - PAPERLESS_AI_PORT=${PAPERLESS_AI_PORT:-3000} + #- RAG_SERVICE_URL=http://localhost:8000 + - RAG_SERVICE_ENABLED=true + ports: + - 15002:${PAPERLESS_AI_PORT:-3000} + volumes: + - /mnt/pve/unas/services/paperless-ai:/app/data +networks: {} diff --git a/proton-bridge/docker-compose.yml b/proton-bridge/docker-compose.yml new file mode 100644 index 0000000..42547ee --- /dev/null +++ b/proton-bridge/docker-compose.yml @@ -0,0 +1,18 @@ +services: + proton-bridge: + image: shenxn/protonmail-bridge:latest + container_name: proton-bridge + restart: unless-stopped + ports: + - "1025:25/tcp" + - "1143:143/tcp" + volumes: + - proton_config:/root + deploy: + resources: + limits: + cpus: "0.25" + memory: 128M + +volumes: + proton_config: diff --git a/qdrant/docker-compose.yml b/qdrant/docker-compose.yml new file mode 100644 index 0000000..f519470 --- /dev/null +++ b/qdrant/docker-compose.yml @@ -0,0 +1,26 @@ +services: + qdrant: + image: qdrant/qdrant:latest + container_name: qdrant_scientific + ports: + - "14002:6333" # REST API & Dashboard + - "6334:6334" # gRPC (For high-speed ingestion) + volumes: + - /mnt/pve/unas/services/qdrant:/qdrant/storage + deploy: + resources: + limits: + cpus: "1.0" + memory: 2G + reservations: + cpus: "0.5" + memory: 1G + environment: + - QDRANT__SERVICE__ENABLE_CORS=true + healthcheck: + disable: true + restart: unless-stopped +networks: + default: + external: true + name: shared_backend diff --git a/socket-proxy/docker-compose.yml b/socket-proxy/docker-compose.yml new file mode 100644 index 0000000..9435516 --- /dev/null +++ b/socket-proxy/docker-compose.yml @@ -0,0 +1,25 @@ +name: socket-proxy +services: + socket-proxy: + image: tecnativa/docker-socket-proxy:latest + container_name: docker-socket-proxy + restart: unless-stopped + privileged: true + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + ports: + - "2375:2375" + environment: + CONTAINERS: 1 + SERVICES: 0 + TASKS: 0 + NETWORKS: 1 + IMAGES: 1 + INFO: 1 + VERSION: 1 + EVENTS: 1 + PING: 1 + POST: 0 + VOLUMES: 0 + EXEC: 0 + LOG_LEVEL: warning diff --git a/vpn/docker-compose.yml b/vpn/docker-compose.yml new file mode 100644 index 0000000..c22fdec --- /dev/null +++ b/vpn/docker-compose.yml @@ -0,0 +1,46 @@ +services: + gluetun: + image: qmcgaw/gluetun + container_name: vpn_gluetun + restart: unless-stopped + deploy: + resources: + limits: + cpus: "0.5" + memory: 256M + reservations: + cpus: "0.25" + memory: 128M + ports: + - 30000:8000 + - 13001:6500 + - 11470:11470 + - 11471:11471 + - 12470:12470 + - 12471:12471 + - 8099:8080 + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun:/dev/net/tun + volumes: + - /mnt/pve/unas/services/gluetun/data:/gluetun + environment: + - PUID=977 + - PGID=988 + - VPN_SERVICE_PROVIDER=nordvpn + - SERVER_COUNTRIES=Germany + - VPN_TYPE=wireguard + - WIREGUARD_MTU=1420 + - WIREGUARD_PERSISTENT_KEEPALIVE_INTERVAL=25s + - FIREWALL_OUTBOUND_SUBNETS=192.168.1.0/24 + - UPDATER_PERIOD=24h + - TZ=Europe/Berlin + - OPENVPN_USER=BNDz2XmPPbgWxoPe1XQcWT1v + - OPENVPN_PASSWORD=kqbaBsuvVP4gcvqfv3bC8BHe + - WIREGUARD_PRIVATE_KEY=70dYZGDAUkXDjeCEFVJJMMbbso/jGnuk10HoInKHF+w= + - HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE='{"auth":"none"}' + # No custom healthcheck: gluetun ships a built-in healthcheck (queries + # 127.0.0.1:9999 in healthcheck mode and verifies the VPN tunnel/DNS). + # Overriding it with wget against the :8000 control server gives false + # "unhealthy" (that endpoint 404s). Let the image's own healthcheck run.