version: '3.9' networks: traefik-public: external: true productivity-backend: driver: overlay volumes: nextcloud_data: nextcloud_db: nextcloud_redis: services: nextcloud-db: image: postgres:15-alpine volumes: - /mnt/database/nextcloud:/var/lib/postgresql/data environment: - POSTGRES_DB=nextcloud - POSTGRES_USER=nextcloud - POSTGRES_PASSWORD=nextcloud # Replace with a secure password in production networks: - productivity-backend deploy: placement: constraints: - node.labels.leader == true restart_policy: condition: on-failure nextcloud-redis: image: redis:7-alpine volumes: - nextcloud_redis:/data networks: - productivity-backend deploy: placement: constraints: - node.labels.leader == true restart_policy: condition: on-failure nextcloud: image: nextcloud:latest volumes: - /mnt/nextcloud_apps:/var/www/html/custom_apps - /mnt/nextcloud_config:/var/www/html/config - /mnt/nextcloud_data:/var/www/html/data environment: - POSTGRES_HOST=nextcloud-db - POSTGRES_DB=nextcloud - POSTGRES_USER=nextcloud - POSTGRES_PASSWORD=nextcloud # Replace with a secure password in production - REDIS_HOST=nextcloud-redis - NEXTCLOUD_ADMIN_USER=admin # Replace with your desired admin username - NEXTCLOUD_ADMIN_PASSWORD=password # Replace with a secure password - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.sj98.duckdns.org - OVERWRITEPROTOCOL=https - OVERWRITEHOST=nextcloud.sj98.duckdns.org - TRUSTED_PROXIES=172.16.0.0/12 depends_on: - nextcloud-db - nextcloud-redis networks: - traefik-public - productivity-backend deploy: placement: constraints: - node.labels.leader == true resources: limits: memory: 2G reservations: memory: 512M restart_policy: condition: on-failure labels: - "traefik.enable=true" - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.sj98.duckdns.org`)" - "traefik.http.routers.nextcloud.entrypoints=websecure" - "traefik.http.routers.nextcloud.tls.certresolver=leresolver" - "traefik.http.services.nextcloud.loadbalancer.server.port=80" - "traefik.docker.network=traefik-public" # Nextcloud-specific middlewares - "traefik.http.routers.nextcloud.middlewares=nextcloud-chain" - "traefik.http.middlewares.nextcloud-chain.chain.middlewares=nextcloud-caldav,nextcloud-headers" # CalDAV/CardDAV redirect - "traefik.http.middlewares.nextcloud-caldav.redirectregex.regex=^https://(.*)/.well-known/(card|cal)dav" - "traefik.http.middlewares.nextcloud-caldav.redirectregex.replacement=https://$$1/remote.php/dav/" - "traefik.http.middlewares.nextcloud-caldav.redirectregex.permanent=true" # Security headers - "traefik.http.middlewares.nextcloud-headers.headers.stsSeconds=31536000" - "traefik.http.middlewares.nextcloud-headers.headers.stsIncludeSubdomains=true" - "traefik.http.middlewares.nextcloud-headers.headers.stsPreload=true" - "traefik.http.middlewares.nextcloud-headers.headers.forceSTSHeader=true" - "traefik.http.middlewares.nextcloud-headers.headers.customFrameOptionsValue=SAMEORIGIN" - "traefik.http.middlewares.nextcloud-headers.headers.customResponseHeaders.X-Robots-Tag=noindex,nofollow"