Ctrl K
ComunidadGuías…

compose.nextcloud.yaml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Nextcloud on top of the Media Hub storage network. Overlay on compose.yaml; production
# enables it with `COMPOSE_FILE=compose.yaml:compose.nextcloud.yaml` in .env, so plain
# `docker compose ...` (and scripts/backup.sh etc.) include it. Test stack:
#   docker compose -p mediahub-e2e --env-file <env> -f compose.yaml -f compose.nextcloud.yaml up -d --wait
#
# Nextcloud is unmodified: its primary storage is the S3 gateway (app/s3gw.py), which stores
# every object as a Media Hub blob (local copy + encrypted replicas on storage nodes).
# Only Caddy publishes a port (HTTPS ${NC_HTTPS_PORT}); s3gw, Nextcloud, its DB and Redis stay
# on the compose network. Object storage is chosen at install time: point a FRESH Nextcloud
# at it, never switch an existing one.
#
# Required in the env file: MEDIAHUB_S3_ACCESS_KEY, MEDIAHUB_S3_SECRET_KEY, NEXTCLOUD_DB_PASSWORD,
# NEXTCLOUD_ADMIN_PASSWORD, NEXTCLOUD_REDIS_PASSWORD, NC_DOMAIN (LAN IP or name).

x-nextcloud-env: &nextcloud-env
  POSTGRES_HOST: nextcloud-db
  POSTGRES_DB: nextcloud
  POSTGRES_USER: nextcloud
  POSTGRES_PASSWORD: ${NEXTCLOUD_DB_PASSWORD:?set NEXTCLOUD_DB_PASSWORD}
  NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER:-admin}
  NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD:?set NEXTCLOUD_ADMIN_PASSWORD}
  NEXTCLOUD_TRUSTED_DOMAINS: ${NC_DOMAIN:?set NC_DOMAIN} localhost
  # Behind Caddy (TLS terminated there): generate https URLs with the public host:port and
  # trust X-Forwarded-For only from the compose network (brute-force protection sees real IPs).
  OVERWRITEPROTOCOL: https
  OVERWRITEHOST: ${NC_DOMAIN}:${NC_HTTPS_PORT:-9443}
  OVERWRITECLIURL: https://${NC_DOMAIN}:${NC_HTTPS_PORT:-9443}
  TRUSTED_PROXIES: ${NC_TRUSTED_PROXIES:-172.16.0.0/12}
  REDIS_HOST: nextcloud-redis
  REDIS_HOST_PASSWORD: ${NEXTCLOUD_REDIS_PASSWORD:?set NEXTCLOUD_REDIS_PASSWORD}
  PHP_UPLOAD_LIMIT: 20G
  PHP_MEMORY_LIMIT: 1G
  # The image caps request bodies at 1 GiB; single-request WebDAV uploads above that fail
  # (the official clients chunk, but curl/rclone PUTs don't).
  APACHE_BODY_LIMIT: "0"
  OBJECTSTORE_S3_BUCKET: nextcloud
  OBJECTSTORE_S3_HOST: s3gw
  OBJECTSTORE_S3_PORT: "9000"
  OBJECTSTORE_S3_SSL: "false"
  OBJECTSTORE_S3_USEPATH_STYLE: "true"
  OBJECTSTORE_S3_REGION: us-east-1
  OBJECTSTORE_S3_AUTOCREATE: "true"
  OBJECTSTORE_S3_KEY: ${MEDIAHUB_S3_ACCESS_KEY:?set MEDIAHUB_S3_ACCESS_KEY}
  OBJECTSTORE_S3_SECRET: ${MEDIAHUB_S3_SECRET_KEY:?set MEDIAHUB_S3_SECRET_KEY}
  TZ: ${MEDIAHUB_TIMEZONE:-Asia/Taipei}

x-logging: &logging
  driver: json-file
  options:
    max-size: "10m"
    max-file: "5"

services:
  s3gw:
    extends:
      file: compose.yaml
      service: worker
    command: ["uvicorn", "app.s3gw:app", "--host", "0.0.0.0", "--port", "9000", "--workers", "2", "--timeout-keep-alive", "30"]
    environment:
      MEDIAHUB_S3_ACCESS_KEY: ${MEDIAHUB_S3_ACCESS_KEY}
      MEDIAHUB_S3_SECRET_KEY: ${MEDIAHUB_S3_SECRET_KEY}
    cpus: 4
    mem_limit: 1g
    stop_grace_period: 10s
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:9000/_health', timeout=4)"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 10s

  nextcloud-db:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: ${NEXTCLOUD_DB_PASSWORD}
      POSTGRES_DB: nextcloud
    volumes:
      - nc_pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U nextcloud -d nextcloud"]
      interval: 5s
      timeout: 5s
      retries: 20
    logging: *logging

  # Distributed cache + file locking. Also required for chunked upload v2 (chunks written
  # straight into an S3 multipart upload instead of being stored twice).
  nextcloud-redis:
    image: redis:8-alpine
    restart: unless-stopped
    command: ["redis-server", "--requirepass", "${NEXTCLOUD_REDIS_PASSWORD}", "--save", "", "--appendonly", "no"]
    environment:
      REDISCLI_AUTH: ${NEXTCLOUD_REDIS_PASSWORD}
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *logging

  nextcloud:
    image: nextcloud:34-apache
    restart: unless-stopped
    environment: *nextcloud-env
    volumes:
      # Code, config.php (instance secrets!), apps. File contents go to the S3 gateway.
      - nc_html:/var/www/html
      - ./deploy/nextcloud/hooks/before-starting:/docker-entrypoint-hooks.d/before-starting:ro
      - ./deploy/nextcloud/hooks/post-upgrade:/docker-entrypoint-hooks.d/post-upgrade:ro
      - ./deploy/nextcloud/hooks/post-upgrade:/docker-entrypoint-hooks.d/post-installation:ro
    depends_on:
      nextcloud-db:
        condition: service_healthy
      nextcloud-redis:
        condition: service_healthy
      s3gw:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "curl -fsS -H 'Host: localhost' http://127.0.0.1/status.php | grep -q '\"installed\":true'"]
      interval: 15s
      timeout: 10s
      retries: 20
      start_period: 5m
    mem_limit: 2g
    logging: *logging

  # Background jobs (file scans, previews, trash/version expiry) every 5 minutes.
  nextcloud-cron:
    image: nextcloud:34-apache
    restart: unless-stopped
    entrypoint: /cron.sh
    environment: *nextcloud-env
    volumes:
      - nc_html:/var/www/html
    depends_on:
      nextcloud:
        condition: service_healthy
    mem_limit: 1g
    logging: *logging

  caddy:
    environment:
      NC_SITES: https://${NC_DOMAIN}:${NC_HTTPS_PORT:-9443}
    ports:
      - "${HUB_BIND:-127.0.0.1}:${NC_HTTPS_PORT:-9443}:${NC_HTTPS_PORT:-9443}"
    volumes:
      - ./deploy/caddy/nextcloud.caddy:/etc/caddy/sites/nextcloud.caddy:ro

volumes:
  nc_pgdata:
  nc_html: