[Docker] Nextcloud avec Docker Compose

Quand j'ai fini par laisser tomber Yunohost j'ai vite choisi Docker pour héberger mes services et surtout mon Nextcloud. J'ai galéré a trouver une configuration qui marche alors je me suis dit que j'allais la partager ici.

[Docker] Nextcloud avec Docker Compose
Photo by C Dustin / Unsplash

Quand j'ai fini par laisser tomber Yunohost parce que je voulais mettre plus les mains dans le cambouis j'ai vite choisi Docker pour héberger mes services. Le plus gros morceau pour moi était mon Nextcloud qui me sert beaucoup. J'ai galéré a trouver une configuration qui marche alors je me suis dit que j'allais la partager ici. On va donc voir en détail le fichier docker-compose qui fait tourner mon Nextcloud avec en bonus comment j'ai paramétré le reverse proxy Nginx.

Le fichier docker-compose:


version: '3'

services:
  db:
    image: mariadb:latest
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    restart: always
    volumes:
      - db:/var/lib/mysql
    env_file:
      - db.env

  redis:
    image: redis:alpine
    restart: always
    command: redis-server --requirepass password

  app:
    image: nextcloud:apache
    restart: always
    ports:
      - 8080:80
    volumes:
      - nextcloud:/var/www/html
      - /home/docker/nextcloud/config:/var/www/html/config  
      - /home/docker/nextcloud/data:/var/www/html/data
    environment:
      - MYSQL_HOST=db
      - REDIS_HOST=redis
      - REDIS_HOST_PASSWORD=password
      - NEXTCLOUD_TRUSTED_DOMAINS=domain.tld
      - TRUSTED_PROXIES=192.168.X.Y
      - APACHE_DISABLE_REWRITE_IP=1
      - OVERWRITEHOST=domain.tld
      - OVERWRITEPROTOCOL=https
      - OVERWRITEWEBROOT=/sousdossier
      - NEXTCLOUD_DATA_DIR=/chemin/vers/data/nextcloud
    env_file:
      - db.env
    depends_on:
      - db
      - redis

  cron:
    image: nextcloud:apache
    restart: always
    volumes:
      - nextcloud:/var/www/html
    entrypoint: /cron.sh
    depends_on:
      - db
      - redis
  
volumes:
  db:
  nextcloud:

Donc on est dans une configuration avec un Nextcloud classique sous Apache, une base de données MariaDB et on ajoute Redis pour le cache et un conteneur en plus pour gérer le cron. Je ne vais pas discuter de pourquoi ceci ou cela, c'est la solution la plus fonctionnelle et adaptée pour moi après pas mal de recherches.

Pour la base de données rien de compliqué si ce n'est que comme j'aime vivre dangereusement je mets sur la branche latest de mariadb. En vrai le faites pas et restez sur une branche stable. Si jamais il y'a un changement de version trop important il faudra toutefois mettre à jour le schéma pour que Nextcloud arrête de tousser:

docker exec -ti nextcloud_db_1 mysql_upgrade --user=root --password;

Ensuite tout se déclare dans le fichier .env (base, mots de passe, etc...)

Pour ce qui est de Redis j'ai eu des bugs si l'instance n'avait pas un mot de passe défini donc il faut penser à le déclarer et à le passer à la partie app.

Pour ce qui est de l'application justement, attention a bien définir l'emplacement des data et de la config ce sont les choses les plus importantes à sauvegarder pour moi. Dans les variables on reprends le mot de passe pour l'instance Redis et si vous avez un reverse proxy c'est mieux de le déclarer ici. Sinon les variables parlent d'elles mêmes.

Et oui cette partie mérite un coup de balai afin de tout regrouper dans le même fichier .env, je sais !

Pour ce qui est du cron je suis partagé, j'ai eu pas mal de soucis au début et j'avais fini par faire exécuter les tâches cron directement par le serveur hébergeant les conteneurs. Maintenant cela fonctionne donc je garde le conteneur dédié mais si jamais vous avez besoin de cette solution dans le crontab de l'hôte:

*/15 * * * * docker exec -u www-data nextcloud_app_1 php cron.php

Le reverse proxy

J'utilise un reverse proxy Nginx qui tourne dans un conteneur LXC dédié sur Proxmox. Pour des raisons qui me sont propre Nextcloud ne tourne pas sur son domaine dedié mais dans un sous répertoire de type  domain.tld/files

Voici la config de ce répertoire dans Nginx:

#Nextcloud
    location /repertoirenextcloud {
        include proxy_params;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://192.168.0.X:8080/;
        rewrite /nextcloud(.*) $1 break;
        client_max_body_size 100M;
         }

    location /.well-known {
        alias /var/www/html/.well-known;
        }

    location /.well-known/carddav {
        return 301 $scheme://$host/nextcloud/remote.php/dav;
    }

    location /.well-known/caldav {
        return 301 $scheme://$host/nextcloud/remote.php/dav;
    }

    location /.well-known/nodeinfo {
        return 301 $scheme://$host/public.php?service=nodeinfo;
    }

    location /.well-known/webfinger {
        return 301 $scheme://$host/public.php?service=webfinger;
    }

Bien sûr au niveau de proxy_pass il faut mettre l'IP du serveur qui héberge le conteneur Docker. Bien sûr en réalité tout est servi en HTTPS avec gestion automatique des certificats Let's Encrypt mais c'est une autre histoire.