# Managed by Ansible — do not edit manually services: nextcloud-db: image: postgres:{{ nextcloud_db_version }} container_name: nextcloud-db restart: unless-stopped environment: POSTGRES_USER: nextcloud POSTGRES_PASSWORD: "{{ nextcloud_db_password }}" POSTGRES_DB: nextcloud volumes: - {{ nextcloud_data_dir }}/db:/var/lib/postgresql/data networks: - nextcloud_internal healthcheck: test: ["CMD-SHELL", "pg_isready -U nextcloud"] interval: 10s timeout: 5s retries: 5 nextcloud-redis: image: redis:7-alpine container_name: nextcloud-redis restart: unless-stopped command: --save 60 1 --loglevel warning volumes: - {{ nextcloud_data_dir }}/redis:/data networks: - nextcloud_internal healthcheck: test: ["CMD-SHELL", "redis-cli ping | grep PONG"] interval: 10s timeout: 5s retries: 5 nextcloud: image: nextcloud:{{ nextcloud_version }} container_name: nextcloud restart: unless-stopped environment: # Database POSTGRES_HOST: nextcloud-db POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud POSTGRES_PASSWORD: "{{ nextcloud_db_password }}" # Redis — used for file locking and memcache REDIS_HOST: nextcloud-redis # Admin bootstrap (only used on first start) NEXTCLOUD_ADMIN_USER: "{{ nextcloud_admin_user }}" NEXTCLOUD_ADMIN_PASSWORD: "{{ nextcloud_admin_password }}" # URLs — must match external domain; tells Nextcloud it's behind an HTTPS proxy NEXTCLOUD_TRUSTED_DOMAINS: "{{ domain_nextcloud }}" OVERWRITEPROTOCOL: https OVERWRITECLIURL: "https://{{ domain_nextcloud }}" OVERWRITEHOST: "{{ domain_nextcloud }}" # PHP limits for large file uploads PHP_MEMORY_LIMIT: 512M PHP_UPLOAD_LIMIT: 512M volumes: - {{ nextcloud_data_dir }}/html:/var/www/html networks: - traefik_public - nextcloud_internal labels: - "traefik.enable=true" - "traefik.http.routers.nextcloud.rule=Host(`{{ domain_nextcloud }}`)" - "traefik.http.routers.nextcloud.entrypoints=websecure" - "traefik.http.routers.nextcloud.tls.certresolver=letsencrypt" - "traefik.http.services.nextcloud.loadbalancer.server.port=80" - "traefik.http.routers.nextcloud.middlewares=nextcloud-wellknown,nextcloud-headers" # Redirect .well-known CalDAV/CardDAV to the proper Nextcloud endpoint - "traefik.http.middlewares.nextcloud-wellknown.redirectregex.regex=^https://([^/]*)/.well-known/(card|cal)dav" - "traefik.http.middlewares.nextcloud-wellknown.redirectregex.replacement=https://$$1/remote.php/dav/" - "traefik.http.middlewares.nextcloud-wellknown.redirectregex.permanent=true" # Security headers recommended by Nextcloud - "traefik.http.middlewares.nextcloud-headers.headers.stsSeconds=15552000" - "traefik.http.middlewares.nextcloud-headers.headers.stsIncludeSubdomains=true" - "traefik.http.middlewares.nextcloud-headers.headers.stsPreload=true" depends_on: nextcloud-db: condition: service_healthy nextcloud-redis: condition: service_healthy # Runs Nextcloud background jobs on a 5-minute schedule (replaces webcron/ajax cron) nextcloud-cron: image: nextcloud:{{ nextcloud_version }} container_name: nextcloud-cron restart: unless-stopped entrypoint: /cron.sh volumes: - {{ nextcloud_data_dir }}/html:/var/www/html networks: - nextcloud_internal depends_on: - nextcloud networks: traefik_public: external: true nextcloud_internal: internal: true