diff --git a/nextcloud/README.md b/nextcloud/README.md index acd16c2..701446a 100644 --- a/nextcloud/README.md +++ b/nextcloud/README.md @@ -1,55 +1,109 @@ # nextcloud -Docker Hub: https://hub.docker.com/_/nextcloud -Proxy Port: 80 - ## Overview -Self-hosted file sync, sharing, and collaboration platform. +Self-hosted file sync, sharing, and collaboration platform. This stack runs Nextcloud (Apache) with MariaDB, Redis for caching and file locking, and a cron container for background jobs. ## Project Details -- **Container Image:** [mariadb:latest](https://hub.docker.com/_/mariadb) -- **Reverse Proxy Port:** `n/a` +- **Project Repository:** [GitHub](https://github.com/nextcloud/docker) +- **Container Image:** [nextcloud](https://hub.docker.com/_/nextcloud), [mariadb](https://hub.docker.com/_/mariadb), [redis](https://hub.docker.com/_/redis) +- **Documentation:** [Admin Manual](https://docs.nextcloud.com/server/latest/admin_manual/) +- **Reverse Proxy Port:** `80` ## Getting Started -1. Start the container: `docker compose up -d` -2. Open http://localhost:PORT in your browser -3. Follow the initial setup wizard to configure the application +1. Set `NEXTCLOUD_DOMAIN` and change every `ChangeThisPassword` in `sample.env` +2. Start the stack: `docker compose up -d` +3. In NPM, add a proxy host for `NEXTCLOUD_DOMAIN` → `http://nextcloud:80` with SSL enabled +4. Open https://NEXTCLOUD_DOMAIN and create the admin account (the database fields are pre-filled from the environment) ## Environment Variable Notes + NEXTCLOUD_IMAGE – default: nextcloud:35 (pin the major version, see Gotchas) + MARIADB_IMAGE – default: mariadb:11.8 (the version Nextcloud recommends) + REDIS_IMAGE – default: redis:alpine NEXTCLOUD_DB – default: nextcloud - MARIADB_ROOT_PASSWORD – default: ChangeThisPassword NEXTCLOUD_DB_USER – default: nextcloud NEXTCLOUD_DB_PASSWORD – default: ChangeThisPassword NEXTCLOUD_DB_HOST – default: nextcloud-db + MARIADB_ROOT_PASSWORD – default: ChangeThisPassword + NEXTCLOUD_REDIS_HOST – default: nextcloud-redis + NEXTCLOUD_DOMAIN – public hostname without a scheme; sets trusted_domains (first install only) and overwrite.cli.url + NEXTCLOUD_TRUSTED_PROXIES – default: 172.16.0.0/12 (Docker bridge range, covers NPM) + NEXTCLOUD_OVERWRITEPROTOCOL – default: https; generates https links behind NPM's TLS termination + VOL_CACHE – default: /var/cache; base path for regenerable data (exclude from backups) + NEXTCLOUD_PREVIEW_DIR – default: /mnt/nextcloud-preview (unused placeholder); after install, set to /var/www/html/data/appdata_/preview ## Volume Notes - /var/lib/mysql – host path /data/nextcloud/db - /var/www/html – host path /data/nextcloud/data + /var/lib/mysql – host path /data/nextcloud/db (MariaDB data) + /data – host path /data/nextcloud/redis (Redis cache, safe to lose) + /var/www/html – host path /data/nextcloud/data (Nextcloud app, config and user files; shared by nextcloud and nextcloud-cron) + + /var/www/html/data/appdata_/preview – host path /var/cache/nextcloud/preview (generated thumbnails; only once NEXTCLOUD_PREVIEW_DIR is set) + +Back up `/data/nextcloud/data` and `/data/nextcloud/db` together. Leave out `/var/cache`: previews are regenerated on demand. + +### Moving previews to VOL_CACHE + +Previews are usually the largest regenerable data, often several GB. They live in a folder named after the instance ID, which Nextcloud only creates during install. That's why the preview mount points at a placeholder until you set `NEXTCLOUD_PREVIEW_DIR`. + +1. Get the instance ID: `docker compose exec -u www-data nextcloud php occ config:system:get instanceid` +2. Stop the stack: `docker compose down` +3. Move existing previews and give them to www-data (UID 33): + ```bash + sudo mkdir -p /var/cache/nextcloud + sudo mv /data/nextcloud/data/data/appdata_/preview /var/cache/nextcloud/preview + sudo mkdir /data/nextcloud/data/data/appdata_/preview + sudo chown -R 33:33 /var/cache/nextcloud/preview /data/nextcloud/data/data/appdata_/preview + ``` +4. Set `NEXTCLOUD_PREVIEW_DIR=/var/www/html/data/appdata_/preview` and start the stack + +If you lose `/var/cache`, don't start with an empty folder: Nextcloud's file cache still lists the old previews. Recreate the folder (owned by 33:33), start the stack, then run `docker compose exec -u www-data nextcloud php occ files:scan-app-data preview`. ## Network Notes -Requires proxy network +Requires proxy network. `nextcloud` joins `proxy` and `internal`; `nextcloud-db`, `nextcloud-redis` and `nextcloud-cron` join `internal` only. ## Docker Run +Nextcloud needs the database container to run, so use compose. The app container alone looks like this: + ```bash docker run -d \ --name nextcloud \ - -v /data/nextcloud/db:/var/lib/mysql \ + --network proxy \ + -e MYSQL_HOST=nextcloud-db \ + -e MYSQL_DATABASE=nextcloud \ + -e MYSQL_USER=nextcloud \ + -e MYSQL_PASSWORD=ChangeThisPassword \ -v /data/nextcloud/data:/var/www/html \ - mariadb:latest + nextcloud:35 ``` -See compose.yaml for the full set of environment variables. +See compose.yaml for the full set of services and environment variables. ## Additional Notes / Gotchas -See `compose-aio.yaml` in this directory for the Nextcloud All-in-One variant. +- **Upgrade one major version at a time.** Nextcloud can't skip majors (for example 33 → 35 fails). Bump `NEXTCLOUD_IMAGE` step by step and let each version finish its upgrade before moving on. +- **MariaDB can't be downgraded.** If an existing install has already run a newer `mariadb:latest`, keep `MARIADB_IMAGE` at that version. Data files from a newer MariaDB won't start on 11.8. `MARIADB_AUTO_UPGRADE=1` handles upgrades. +- **Env vars that only apply on first install:** `NEXTCLOUD_TRUSTED_DOMAINS` and the database settings. For an existing install, set the domain with occ: + `docker compose exec -u www-data nextcloud php occ config:system:set trusted_domains 1 --value=cloud.example.com` +- **Background jobs:** after install, go to Administration settings → Basic settings and select **Cron**. The `nextcloud-cron` container runs `cron.php` every 5 minutes. +- **NPM:** increase the upload limit in the proxy host's Advanced tab (for example `client_max_body_size 10G;`) or large uploads will fail. +- **Nextcloud All-in-One:** `compose-aio.yaml` is an alternative to this stack, not an add-on. The master container spawns and manages its own containers, so container and volume names are fixed. It doesn't join the `proxy` network. Open the AIO admin UI at https://HOST:8080, then point NPM at `http://HOST_IP:11000` (the `APACHE_PORT`). User data goes to `/data/nextcloud-aio`. + +### Useful commands + +```bash +docker compose exec -u www-data nextcloud php occ status +docker compose exec -u www-data nextcloud php occ app:list +docker compose exec -u www-data nextcloud php occ app:disable +docker compose exec -u www-data nextcloud php occ maintenance:mode --on +docker compose exec -u www-data nextcloud php occ trashbin:cleanup --all-users +docker compose exec -u www-data nextcloud php occ db:add-missing-indices +``` ## Dockhand Stack, Deploy from Git @@ -61,14 +115,3 @@ Additional env file (optional): nextcloud/sample.env Then "Load" nextcloud/sample.env into the Environmental variables in dockhand Create the Stack - -## Useful commands - -```bash -sudo -u www-data php occ app:list -sudo -u www-data php occ app:disable -sudo -u www-data php occ maintenance:mode --on -php occ trashbin:cleanup --all-users - -docker-compose exec --user www-data nextcloud php occ -``` diff --git a/nextcloud/compose.yaml b/nextcloud/compose.yaml index a941448..d37fdf1 100644 --- a/nextcloud/compose.yaml +++ b/nextcloud/compose.yaml @@ -1,6 +1,6 @@ services: nextcloud-db: - image: ${MARIADB_IMAGE:-mariadb:latest} + image: ${MARIADB_IMAGE:-mariadb:11.8} restart: ${MARIADB_RESTART:-unless-stopped} volumes: - ${VOL_PATH:-/data}/nextcloud/db:/var/lib/mysql @@ -9,27 +9,55 @@ services: - MARIADB_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD:-ChangeThisPassword} - MARIADB_USER=${NEXTCLOUD_DB_USER:-nextcloud} - MARIADB_PASSWORD=${NEXTCLOUD_DB_PASSWORD:-ChangeThisPassword} + - MARIADB_AUTO_UPGRADE=1 + networks: + - internal + command: --transaction-isolation=READ-COMMITTED + + nextcloud-redis: + image: ${REDIS_IMAGE:-redis:alpine} + restart: ${REDIS_RESTART:-unless-stopped} + volumes: + - ${VOL_PATH:-/data}/nextcloud/redis:/data networks: - internal - command: > - --transaction-isolation=READ-COMMITTED - --binlog-format=ROW - --innodb-file-per-table=1 - --skip-innodb-read-only-compressed nextcloud: - image: ${NEXTCLOUD_IMAGE:-nextcloud:latest} + image: ${NEXTCLOUD_IMAGE:-nextcloud:35} restart: ${NEXTCLOUD_RESTART:-unless-stopped} volumes: - ${VOL_PATH:-/data}/nextcloud/data:/var/www/html + - ${VOL_CACHE:-/var/cache}/nextcloud/preview:${NEXTCLOUD_PREVIEW_DIR:-/mnt/nextcloud-preview} environment: - MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD:-ChangeThisPassword} - MYSQL_DATABASE=${NEXTCLOUD_DB:-nextcloud} - MYSQL_USER=${NEXTCLOUD_DB_USER:-nextcloud} - MYSQL_HOST=${NEXTCLOUD_DB_HOST:-nextcloud-db} + - REDIS_HOST=${NEXTCLOUD_REDIS_HOST:-nextcloud-redis} + - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_DOMAIN:-cloud.example.com} + - TRUSTED_PROXIES=${NEXTCLOUD_TRUSTED_PROXIES:-172.16.0.0/12} + - OVERWRITEPROTOCOL=${NEXTCLOUD_OVERWRITEPROTOCOL:-https} + - OVERWRITECLIURL=https://${NEXTCLOUD_DOMAIN:-cloud.example.com} networks: - proxy - internal + depends_on: + - nextcloud-db + - nextcloud-redis + + # Runs background jobs every 5 minutes — volumes and image must match the nextcloud service + nextcloud-cron: + image: ${NEXTCLOUD_IMAGE:-nextcloud:35} + restart: ${NEXTCLOUD_RESTART:-unless-stopped} + volumes: + - ${VOL_PATH:-/data}/nextcloud/data:/var/www/html + - ${VOL_CACHE:-/var/cache}/nextcloud/preview:${NEXTCLOUD_PREVIEW_DIR:-/mnt/nextcloud-preview} + networks: + - internal + depends_on: + - nextcloud-db + - nextcloud-redis + entrypoint: /cron.sh networks: proxy: diff --git a/nextcloud/sample.env b/nextcloud/sample.env index d04bb17..9069855 100644 --- a/nextcloud/sample.env +++ b/nextcloud/sample.env @@ -1,13 +1,28 @@ # Compose VOL_PATH=/data -NEXTCLOUD_IMAGE=nextcloud:latest +# Regenerable data (previews) — exclude from backups +VOL_CACHE=/var/cache +NEXTCLOUD_IMAGE=nextcloud:35 NEXTCLOUD_RESTART=unless-stopped -MARIADB_IMAGE=mariadb:latest +MARIADB_IMAGE=mariadb:11.8 MARIADB_RESTART=unless-stopped -MARIADB_ROOT_PASSWORD=ChangeThisPassword +REDIS_IMAGE=redis:alpine +REDIS_RESTART=unless-stopped -# Nextcloud +# Database NEXTCLOUD_DB=nextcloud NEXTCLOUD_DB_USER=nextcloud NEXTCLOUD_DB_PASSWORD=ChangeThisPassword NEXTCLOUD_DB_HOST=nextcloud-db +MARIADB_ROOT_PASSWORD=ChangeThisPassword + +# Nextcloud +NEXTCLOUD_REDIS_HOST=nextcloud-redis +# Public hostname served by NPM (no scheme) +NEXTCLOUD_DOMAIN=cloud.example.com +# Docker's default bridge range — covers NPM on the proxy network +NEXTCLOUD_TRUSTED_PROXIES=172.16.0.0/12 +NEXTCLOUD_OVERWRITEPROTOCOL=https +# Leave as-is for a fresh install. After install, set to +# /var/www/html/data/appdata_/preview (see README → Volume Notes) +NEXTCLOUD_PREVIEW_DIR=/mnt/nextcloud-preview