diff --git a/infra/apps/nextcloud/.env.example b/infra/apps/nextcloud/.env.example new file mode 100644 index 0000000..818f57b --- /dev/null +++ b/infra/apps/nextcloud/.env.example @@ -0,0 +1,14 @@ +# Nextcloud stack configuration + +NEXTCLOUD_DOMAIN=cloud.example.com + +# Database +NEXTCLOUD_DB_NAME=nextcloud +NEXTCLOUD_DB_USER=nextcloud +NEXTCLOUD_DB_PASSWORD=changeMe +NEXTCLOUD_DB_ROOT_PASSWORD=changeMeRoot + +# PHP tuning +NEXTCLOUD_PHP_MEMORY_LIMIT=512M +NEXTCLOUD_PHP_UPLOAD_LIMIT=1024M + diff --git a/infra/apps/nextcloud/README.md b/infra/apps/nextcloud/README.md new file mode 100644 index 0000000..ffc507f --- /dev/null +++ b/infra/apps/nextcloud/README.md @@ -0,0 +1,13 @@ +Nextcloud Stack + +Env vars required (copy .env.example to .env and adjust): + +- NEXTCLOUD_DOMAIN: public domain for Nextcloud +- NEXTCLOUD_DB_NAME, NEXTCLOUD_DB_USER, NEXTCLOUD_DB_PASSWORD, NEXTCLOUD_DB_ROOT_PASSWORD +- Optional: NEXTCLOUD_PHP_MEMORY_LIMIT, NEXTCLOUD_PHP_UPLOAD_LIMIT + +Usage + +- Ensure the Traefik proxy stack is up and the external `${TRAEFIK_NETWORK}` network exists. +- Run: `docker compose --env-file ../../env/${ENV}/common.env --env-file ./.env -f docker-compose.yml up -d` + diff --git a/infra/apps/nextcloud/docker-compose.yml b/infra/apps/nextcloud/docker-compose.yml new file mode 100644 index 0000000..96353b8 --- /dev/null +++ b/infra/apps/nextcloud/docker-compose.yml @@ -0,0 +1,70 @@ +services: + nextcloud: + image: nextcloud:28-apache + container_name: ${INFRASTRUCTURE_LABEL:-stack}-nextcloud + restart: unless-stopped + depends_on: + - db + - redis + environment: + - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_DOMAIN} + - OVERWRITEHOST=${NEXTCLOUD_DOMAIN} + - OVERWRITEPROTOCOL=https + - OVERWRITECLIURL=https://${NEXTCLOUD_DOMAIN} + - REDIS_HOST=redis + - MYSQL_HOST=db + - MYSQL_DATABASE=${NEXTCLOUD_DB_NAME:-nextcloud} + - MYSQL_USER=${NEXTCLOUD_DB_USER:-nextcloud} + - MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD} + - PHP_MEMORY_LIMIT=${NEXTCLOUD_PHP_MEMORY_LIMIT:-512M} + - PHP_UPLOAD_LIMIT=${NEXTCLOUD_PHP_UPLOAD_LIMIT:-1024M} + volumes: + - nextcloud_data:/var/www/html + networks: + - nextcloud + - proxy + labels: + - traefik.enable=true + - traefik.http.routers.nextcloud.rule=Host(`${NEXTCLOUD_DOMAIN}`) + - traefik.http.routers.nextcloud.entrypoints=websecure + - traefik.http.routers.nextcloud.tls=true + - traefik.http.routers.nextcloud.tls.certresolver=letsencrypt + - traefik.http.services.nextcloud.loadbalancer.server.port=80 + - traefik.http.routers.nextcloud.middlewares=security-headers@file + - traefik.docker.network=${TRAEFIK_NETWORK:-proxy} + + db: + image: mariadb:11 + container_name: ${INFRASTRUCTURE_LABEL:-stack}-nextcloud-db + restart: unless-stopped + environment: + - MYSQL_ROOT_PASSWORD=${NEXTCLOUD_DB_ROOT_PASSWORD} + - MYSQL_DATABASE=${NEXTCLOUD_DB_NAME:-nextcloud} + - MYSQL_USER=${NEXTCLOUD_DB_USER:-nextcloud} + - MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD} + volumes: + - db_data:/var/lib/mysql + networks: + - nextcloud + + redis: + image: redis:7-alpine + container_name: ${INFRASTRUCTURE_LABEL:-stack}-nextcloud-redis + restart: unless-stopped + command: redis-server --appendonly yes + volumes: + - redis_data:/data + networks: + - nextcloud + +volumes: + nextcloud_data: + db_data: + redis_data: + +networks: + proxy: + external: true + nextcloud: + name: ${INFRASTRUCTURE_LABEL:-stack}-nextcloud +