Installer Nextcloud sur son propre serveur

Publié le 15 min de lecture

Du serveur vide à une vue d'ensemble sans avertissement : serveur web, modules PHP, base de données, droits sur le répertoire de données, trusted_domains, limites d'envoi et tâches de fond par cron.

Nextcloud se décompresse en quelques secondes. Ce qui prend du temps, c'est la suite : sur une installation fraîche, la page de synthèse sous Paramètres d'administration affiche presque toujours une liste d'avertissements jaunes et rouges, les envois de fichiers échouent à partir de 2 Mo, et l'accès par l'adresse IP se termine sur « You are accessing the site from an untrusted domain. ». Cet article parcourt le chemin complet et s'arrête précisément là où la plupart des tutoriels abandonnent.

Décider en amont : version de PHP, base de données, emplacement des données

Nextcloud dépend de la version de PHP bien plus que la plupart des autres logiciels serveur. Les séries actuelles 33 et 34 exigent au minimum PHP 8.2, la série 32 se contente encore de PHP 8.1. C'est donc la distribution qui détermine si vous pouvez vous en tenir aux paquets fournis :

SystèmePHP de la distributionBase de données de la distributionVerdict
Debian 13 (trixie)8.4MariaDB 11.8convient sans dépôt tiers
Debian 12 (bookworm)8.2MariaDB 10.11convient, mais tout juste
Ubuntu 24.04 LTS8.3MariaDB 10.11, MySQL 8.0convient sans dépôt tiers
Ubuntu 22.04 LTS8.1MariaDB 10.6, MySQL 8.0trop ancien pour Nextcloud 33 et 34
Debian 11 (bullseye)7.4MariaDB 10.5à exclure

Debian 11 est le cas le plus pénible, et il se remarque volontiers tard, parce que l'installation des paquets se déroule sans la moindre erreur. Le métapaquet php y tire PHP 7.4, et la version actuelle de Nextcloud s'arrête dès le premier appel dans le navigateur avec une erreur HTTP 500 et le message « This version of Nextcloud requires at least PHP 8.2 ». Debian 11 est de toute façon sorti du support régulier : ce n'est pas la bonne base pour une nouvelle installation. Si vous n'avez vraiment pas le choix, ajoutez d'abord le dépôt Sury et installez explicitement les paquets versionnés, donc php8.2-fpm, php8.2-cli, php8.2-mysql et ainsi de suite, plutôt que les métapaquets sans numéro de version.

Sur Ubuntu 22.04, vous vous heurtez tout aussi sûrement à un mur dès que vous déployez la version actuelle de Nextcloud. Soit vous restez délibérément sur la série 32, soit vous récupérez PHP depuis le PPA bien connu :

sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:ondrej/php
sudo apt-get update
sudo apt-get install -y php8.3-fpm php8.3-cli php8.3-mysql

Deux autres points se fixent au tout début et ne se changent ensuite qu'au prix d'efforts : Debian ne fournit tout simplement pas de paquet mysql-server, MariaDB y est la référence. Et le répertoire de données n'a rien à faire sous /var/www/nextcloud/data, il doit se trouver en dehors de la racine du serveur web, par exemple dans /var/nextcloud-data. Le chemin par défaut est dangereux pour une seule raison : une configuration de serveur web cassée livrerait alors l'intégralité des fichiers des utilisateurs. Nextcloud avertit dans ce cas avec « Your data directory and files are probably accessible from the internet », mais seulement une fois que le problème existe déjà.

Installer le serveur web, PHP et la base de données

Nous partons sur nginx avec PHP-FPM. Si vous préférez Apache avec mod_php, la marche à suivre est décrite dans Apache, PHP et MySQL sur Debian, les points liés à PHP plus bas restent valables tels quels. Pour une installation de base de nginx, voyez installer nginx.

sudo apt-get update
sudo apt-get install -y nginx mariadb-server
sudo apt-get install -y php-fpm php-cli php-mysql php-gd php-curl php-mbstring php-intl php-gmp php-bcmath php-xml php-zip php-imagick php-apcu

Cette liste est volontairement plus longue que le strict minimum. Nextcloud a besoin de bcmath et gmp pour la connexion sans mot de passe, de intl pour le tri correct des caractères accentués et spéciaux, de imagick pour les vignettes, de apcu pour le cache local. S'il manque un des modules obligatoires, l'assistant d'installation ne vous laisse même pas avancer : la page énumère alors nommément les modules absents.

Vérifiez ensuite ce qui est réellement chargé :

php -v
php -m

Deuxième piège fréquent : il existe deux configurations PHP distinctes, une pour la ligne de commande et une pour FPM. php --ini vous montre celle de la ligne de commande, celle du serveur web se trouve sous /etc/php/<version>/fpm/php.ini. Les modifications faites dans le mauvais fichier n'ont aucun effet, et c'est ce qui coûte le plus de temps en pratique.

Passons à la base de données. Sécurisez d'abord MariaDB, voyez sécuriser MariaDB et MySQL, puis :

sudo mariadb -e "CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
sudo mariadb -e "CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'UnLongMotDePasse';"
sudo mariadb -e "GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';"
sudo mariadb -e "FLUSH PRIVILEGES;"

Le utf8mb4 de la première commande n'est pas un détail. Si vous créez la base avec utf8, Nextcloud signalera plus tard « MySQL is used as database but does not support 4-byte characters », et la conversion en production est nettement plus pénible que le bon CREATE DATABASE dès le départ. Si la connexion de l'utilisateur de base de données échoue, consultez corriger Access denied for user.

Décompresser l'archive et poser les droits

sudo apt-get install -y wget unzip
wget https://download.nextcloud.com/server/releases/latest.zip
sudo unzip -q latest.zip -d /var/www
sudo mkdir -p /var/nextcloud-data
sudo chown -R www-data:www-data /var/www/nextcloud
sudo chown -R www-data:www-data /var/nextcloud-data
sudo chmod 750 /var/nextcloud-data

Les droits sont le point où l'on bâcle le plus souvent. Trois symptômes et leur cause :

  • « Cannot write into config directory » : /var/www/nextcloud/config n'appartient pas à l'utilisateur du serveur web. Sur Debian et Ubuntu, c'est www-data, sur AlmaLinux et Rocky en revanche apache ou nginx. Un chown www-data copié aveuglément ne produit rien du tout sur la famille Red Hat.
  • « Can't create or write into the data directory » : le chemin n'existe pas, ce n'est pas un chemin absolu, ou un répertoire parent n'est pas traversable par www-data.
  • « Your data directory is readable by other users » : droits trop larges. Un chmod 750 sur le répertoire de données suffit.

Résistez à la tentation de régler le problème à coups de chmod -R 777. Nextcloud vous renvoie exactement l'avertissement dont vous vouliez vous débarrasser, et vous avez au passage rendu chaque fichier lisible par n'importe quel utilisateur local.

La configuration nginx

Nextcloud a besoin de plus qu'un bloc PHP standard, entre autres de réécritures pour la découverte de services sous /.well-known/ et de blocages sur les répertoires internes. Ce qui suit est la version raccourcie du modèle officiel, et elle fonctionne telle quelle :

upstream php-handler {
    server unix:/run/php/php8.3-fpm.sock;
}

server {
    listen 80;
    server_name cloud.example.com;
    root /var/www/nextcloud;

    client_max_body_size 10G;
    client_body_timeout 300s;
    fastcgi_buffers 64 4K;

    add_header Referrer-Policy "no-referrer" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Permitted-Cross-Domain-Policies "none" always;
    add_header X-Robots-Tag "noindex, nofollow" always;

    index index.php index.html /index.php$request_uri;

    location ^~ /.well-known {
        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }
        location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
        return 301 /index.php$request_uri;
    }

    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)              { return 404; }

    location ~ \.php(?:$|/) {
        rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+) /index.php$request_uri;
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        set $path_info $fastcgi_path_info;
        try_files $fastcgi_script_name =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;
        fastcgi_request_buffering off;
        fastcgi_max_temp_file_size 0;
    }

    location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|map|woff2)$ {
        try_files $uri /index.php$request_uri;
        expires 6M;
        access_log off;
    }

    location / {
        try_files $uri $uri/ /index.php$request_uri;
    }
}

Vous devez adapter le chemin du socket FPM à votre version de PHP. Il s'appelle php8.4-fpm.sock sous Debian 13, php8.2-fpm.sock sous Debian 12, php8.3-fpm.sock sous Ubuntu 24.04 et php8.1-fpm.sock sous Ubuntu 22.04. Si le nom ne correspond pas, vous récoltez une erreur 502 Bad Gateway. Le nom réel s'affiche ainsi :

systemctl enable --now php8.4-fpm
ls /run/php/

La première ligne fait partie de la manœuvre, car le fichier socket n'apparaît qu'au démarrage du service. Avant cela, /run/php/ est soit vide, soit totalement inexistant, et ls répond No such file or directory. Sur un serveur ordinaire, le paquet démarre lui-même le service à l'installation, mais après une réinstallation ou dans un conteneur, ce n'est pas garanti. Adaptez le numéro de version dans le nom du service à votre installation. Ensuite nginx -t et rechargez.

Installation, HTTPS et trusted_domains

Vous pouvez dérouler l'installation dans le navigateur ou la faire directement en ligne de commande. La deuxième variante est reproductible et se met sans peine dans un script :

cd /var/www/nextcloud
sudo -u www-data php occ maintenance:install --database "mysql" --database-name "nextcloud" --database-user "nextcloud" --database-pass "UnLongMotDePasse" --admin-user "admin" --admin-pass "UnAutreLongMotDePasse" --data-dir "/var/nextcloud-data"

Deux pièges ici. Premièrement, la commande doit être lancée depuis le répertoire de Nextcloud, sinon PHP s'arrête sur une Fatal Error. Deuxièmement, occ ne doit jamais tourner en tant que root, sinon vous obtenez « Console has to be executed with the user that owns the file config/config.php », et dans le pire des cas les fichiers fraîchement créés appartiennent ensuite au mauvais utilisateur.

Passons à HTTPS. Sans certificat, les applications mobiles refusent de fonctionner et Nextcloud vous avertit dans la vue d'ensemble :

sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d cloud.example.com

Pour plusieurs sous-domaines, un certificat wildcard vaut le coup. Ajoutez ensuite dans le bloc serveur TLS l'en-tête Strict-Transport-Security "max-age=15552000; includeSubDomains" always;, sinon l'avertissement « The Strict-Transport-Security HTTP header is not configured to at least 15552000 seconds » reste affiché.

Le grand classique pour finir : vous appelez le site sous un autre nom que celui utilisé à l'installation et vous ne voyez plus que « You are accessing the site from an untrusted domain. » Nextcloud n'accepte que les hostnames inscrits dans trusted_domains. Pour en ajouter un sans éditer le fichier à la main :

sudo -u www-data php occ config:system:set trusted_domains 1 --value=cloud.example.com
sudo -u www-data php occ config:system:get trusted_domains

L'index commence à 0, et 0 est en général déjà pris. Si vous attribuez deux fois le même index, vous écrasez l'entrée existante et vous risquez de vous verrouiller vous-même dehors. Si cela arrive : config/config.php est un fichier PHP tout à fait ordinaire, l'entrée s'y corrige dans un éditeur. Définissez en plus overwrite.cli.url sur l'adresse HTTPS définitive, sinon les tâches de fond génèrent des liens avec un hostname erroné.

Taille des envois et limite de mémoire

Les valeurs par défaut de PHP sont trop justes pour Nextcloud. upload_max_filesize est typiquement à 2M, memory_limit à 128M. Nextcloud recommande au moins 512M de mémoire et avertit sinon avec « The PHP memory limit is below the recommended value of 512MB ».

Il y a trois endroits à traiter ici, et en modifier un seul ne suffit pas :

  1. La configuration FPM sous /etc/php/<version>/fpm/php.ini : memory_limit = 512M, upload_max_filesize = 10G, post_max_size = 10G, max_execution_time = 3600. Redémarrez ensuite FPM, un rechargement de nginx ne suffit pas.
  2. Le fichier .user.ini dans le répertoire de Nextcloud : Nextcloud livre ses propres valeurs, et comme .user.ini s'applique au niveau du répertoire, il l'emporte sur le php.ini global. C'est précisément là que le diagnostic échoue régulièrement. Ajustez donc les valeurs à cet endroit aussi. PHP met ce fichier en cache, cinq minutes par défaut, votre modification prend donc effet avec un décalage.
  3. La directive nginx client_max_body_size : si elle manque ou si elle est trop basse, l'envoi s'arrête sur « 413 Request Entity Too Large » avant même que PHP soit sollicité.

Pour vérifier ce qui s'applique au final, la page Paramètres d'administration est utile : la limite réellement effective y est indiquée. En ligne de commande :

grep -E '^(memory_limit|upload_max_filesize|post_max_size)' /etc/php/8.4/fpm/php.ini

Interrogez explicitement le fichier FPM et non la ligne de commande. Un php -r "echo ini_get('memory_limit');" lit la SAPI CLI, et celle-ci renvoie -1 sur toutes les distributions testées, donc illimité. Qui s'y fie croit la valeur suffisante et se heurte quand même plus tard à des erreurs de mémoire, parce que le fichier FPM contient toujours memory_limit = 128M. Ce qui arrive vraiment dans le navigateur, php-fpm8.4 -i le montre, ou bien un info.php déposé brièvement avec phpinfo(), que vous supprimez aussitôt après.

Si le noyau tue le processus pendant l'envoi de gros fichiers, c'est tout simplement qu'il manque de la mémoire. Mettre en place du swap sert alors de solution de secours, mais plus de RAM vaut mieux.

Basculer les tâches de fond sur cron

Après l'installation, Nextcloud fonctionne en mode AJAX : les tâches de fond ne s'exécutent que lorsque quelqu'un a l'interface ouverte. C'est la raison pour laquelle la recherche en texte intégral, les travaux de nettoyage et les notifications semblent ne jamais se produire sur les instances peu fréquentées. Basculez sur un vrai cron, Nextcloud attend une exécution toutes les cinq minutes. Les bases sont expliquées dans configurer un cronjob sous Linux.

sudo crontab -u www-data -e

Y saisir la ligne :

*/5 * * * * php -f /var/www/nextcloud/cron.php

Signalez ensuite le changement de mode à Nextcloud :

cd /var/www/nextcloud
sudo -u www-data php occ background:cron

Si vous préférez travailler sans démon cron, prenez un service systemd avec un timer. L'unité nextcloudcron.service appelle /usr/bin/php -f /var/www/nextcloud/cron.php sous l'utilisateur www-data, le timer associé définit OnBootSec=5min et OnUnitActiveSec=5min.

Si l'avertissement « Last background job execution ran X hours ago. Something seems wrong » persiste malgré tout, vérifiez dans cet ordre : la tâche tourne-t-elle sous le bon utilisateur ? Le chemin existe-t-il réellement ? Et surtout : cron.php est-il seulement exécutable avec la configuration PHP de la ligne de commande, ou bien y manque-t-il un module installé uniquement pour FPM ? Le test le plus honnête est l'appel à la main, vous y voyez chaque message d'erreur en clair :

sudo -u www-data php -f /var/www/nextcloud/cron.php

Traiter les avertissements de la vue d'ensemble

La liste sous Paramètres d'administration puis Vue d'ensemble n'est pas décorative, chaque ligne a une raison concrète. Voici les plus fréquentes et leur correction :

  • « No memory cache has been configured » : APCu est installé, mais pas déclaré. occ config:system:set memcache.local --value='\OC\Memcache\APCu'. Pour que occ et les exécutions cron en profitent également, ajoutez apc.enable_cli=1 dans /etc/php/<version>/mods-available/apcu.ini.
  • « Transactional file locking is disabled » : installez Redis (apt-get install -y redis-server php-redis) et positionnez memcache.locking sur \OC\Memcache\Redis. Facultatif sur une instance mono-utilisateur, mais plus du tout dès que plusieurs personnes synchronisent en même temps.
  • « Your web server is not properly set up to resolve /.well-known/caldav » : les réécritures du bloc location ^~ /.well-known manquent. Cela se teste directement avec curl -I https://cloud.example.com/.well-known/caldav, la réponse attendue est un 301 vers /remote.php/dav/.
  • « Your installation has no default phone region set » : occ config:system:set default_phone_region --value="AT", pour la France FR. La valeur est un code pays selon ISO 3166-1.
  • « Server has no maintenance window start time configured » : occ config:system:set maintenance_window_start --type=integer --value=1. La valeur est l'heure de début en UTC, les tâches quotidiennes coûteuses s'exécutent alors la nuit plutôt qu'en pleine activité.
  • « The database is missing some indexes » : occ db:add-missing-indices, et dans la foulée occ db:add-missing-columns et occ db:add-missing-primary-keys. Ces commandes sont lentes sur de grosses instances, mais sans danger.
  • « PHP does not seem to be setup properly to query system environment variables » : dans le fichier de pool FPM /etc/php/<version>/fpm/pool.d/www.conf, décommentez la ligne env[PATH] = /usr/local/bin:/usr/bin:/bin et redémarrez FPM.
  • « Module php-imagick in this instance has no SVG support » : ce n'est pas un défaut de Nextcloud, mais une bibliothèque delegate absente dans ImageMagick. Si vous n'avez pas besoin d'aperçus SVG, vous pouvez laisser cet avertissement tel quel.

Reconnaître que tout fonctionne vraiment

Quatre contrôles qui, pris ensemble, sont parlants :

cd /var/www/nextcloud
sudo -u www-data php occ status
sudo -u www-data php occ check
sudo -u www-data php occ config:app:get core lastcron

occ status doit indiquer installed: true et la version attendue, occ check ne doit produire aucune sortie. La troisième commande renvoie un horodatage Unix. Convertissez-le : il ne doit pas avoir plus de cinq minutes, c'est alors seulement que votre cron travaille réellement.

Depuis l'extérieur :

curl -s https://cloud.example.com/status.php

La réponse est un objet JSON contenant "installed":true, "maintenance":false et le numéro de version. Si du HTML revient ici, c'est qu'une de vos règles location est trop large. Si vous obtenez une redirection vers la page de connexion, tout va bien, mais vous vous êtes trompé d'URL.

Enfin le test terrain qu'aucune page de statut ne remplace : envoyer un fichier de plusieurs gigaoctets via l'interface web, puis le synchroniser avec le client desktop. C'est seulement là que l'on voit si client_max_body_size, post_max_size, les délais d'attente et l'espace disque libre s'accordent. Si tout se bloque soudainement, un coup d'œil du côté des disques pleins s'impose, car Nextcloud crée des aperçus et des versions qui grossissent sensiblement.

En cas de problème

Nextcloud écrit ses logs dans /var/nextcloud-data/nextcloud.log, donc dans votre répertoire de données, et non dans /var/log. C'est le premier fichier à consulter, pas le log de nginx. Pour une sortie lisible :

sudo -u www-data php occ log:watch

Si l'instance reste bloquée en mode maintenance après une mise à jour interrompue, occ maintenance:mode --off la récupère. Si l'interface n'est plus accessible du tout, positionnez 'maintenance' => false directement dans config/config.php.

Avant de toucher à la base de données ou à la configuration, sauvegardez les deux. Une sauvegarde du répertoire seule ne suffit pas, Nextcloud ne vaut rien sans la base de données correspondante :

sudo -u www-data php occ maintenance:mode --on
sudo mariadb-dump --single-transaction nextcloud > /root/nextcloud-db.sql
sudo -u www-data php occ maintenance:mode --off

Et un conseil de fond : terminez le serveur avant de le rendre accessible publiquement. Un pare-feu, un accès SSH sécurisé et les points de la checklist pour un nouveau serveur root viennent avant la première connexion, pas après. Une instance Nextcloud avec un mot de passe par défaut est trouvée en quelques heures.

Questions fréquentes

Quelle version de PHP faut-il pour Nextcloud ?
Nextcloud 33 et 34 exigent au minimum PHP 8.2 et sont pris en charge jusqu'à 8.5, Nextcloud 32 fonctionne à partir de PHP 8.1. Debian 13 (PHP 8.4), Debian 12 (PHP 8.2) et Ubuntu 24.04 (PHP 8.3) conviennent sans dépôt tiers. Ubuntu 22.04 ne fournit que PHP 8.1 et se révèle donc trop ancien pour les séries actuelles, il vous faut là le PPA ondrej/php. Debian 11 fournit PHP 7.4 : l'installation s'y déroule sans erreur, mais Nextcloud s'arrête au premier appel avec une erreur HTTP 500 et « This version of Nextcloud requires at least PHP 8.2 ».
Pourquoi ai-je le message « You are accessing the site from an untrusted domain » ?
Nextcloud n'accepte que les hostnames figurant dans le tableau trusted_domains de config/config.php. Ajoutez le nom avec sudo -u www-data php occ config:system:set trusted_domains 1 --value=cloud.example.com. L'index commence à 0, et un index déjà attribué est écrasé.
Pourquoi mes envois échouent-ils malgré un php.ini augmenté ?
Il existe trois limites. Outre upload_max_filesize et post_max_size dans le php.ini de FPM, Nextcloud embarque son propre .user.ini dans le répertoire d'installation, qui l'emporte parce qu'il s'applique au niveau du répertoire, et nginx limite en plus via client_max_body_size. Si cette dernière valeur est trop basse, vous obtenez 413 Request Entity Too Large avant même que PHP soit sollicité.
Pourquoi mes tâches de fond ne s'exécutent-elles pas ?
Les installations fraîches sont en mode AJAX, les tâches ne tournent alors que si l'interface est ouverte. Ajoutez */5 * * * * php -f /var/www/nextcloud/cron.php dans la crontab de www-data et basculez avec occ background:cron. Vous pouvez le vérifier avec occ config:app:get core lastcron, l'horodatage ne doit pas avoir plus de cinq minutes.
Quels droits faut-il sur le répertoire de données ?
Il appartient à l'utilisateur du serveur web (www-data sur Debian et Ubuntu, apache ou nginx dans la famille Red Hat) et devrait porter un chmod 750. Des droits trop larges déclenchent le message « Your data directory is readable by other users ». Créez le répertoire en dehors de la racine du serveur web, par exemple sous /var/nextcloud-data.
Comment faire disparaître l'avertissement sur le cache mémoire manquant ?
Installez php-apcu et définissez occ config:system:set memcache.local --value='\OC\Memcache\APCu'. Pour que occ et les exécutions cron utilisent le cache eux aussi, ajoutez apc.enable_cli=1 dans le fichier apcu.ini de la ligne de commande PHP.
Puis-je aussi faire tourner Nextcloud avec PostgreSQL ?
Oui, PostgreSQL est pris en charge par Nextcloud au même titre que MySQL, la documentation le met même en avant. Sur Debian, cela règle du même coup la question de MySQL, qui n'y est de toute façon pas disponible en paquet. Lors de l'installation, indiquez --database "pgsql" au lieu de "mysql".

Nextcloud Auto-hébergement PHP nginx MariaDB Debian Ubuntu Cloud Linux