Ce que cela construit
Deux machines. Une instance Ryzen exécute Nextcloud, PHP-FPM, Postgres et Redis, le tout sur du NVMe Gen4 local, là où vit le travail sensible à la latence. Le nœud de stockage à côté contient le contenu réel des fichiers dans un bucket d'objets, là où vivent les téraoctets bon marché. Entre eux se trouve un tunnel WireGuard, donc rien dans cet agencement n'est exposé à autre chose.
Cette répartition importe parce que Nextcloud avec un stockage d'objets principal cesse complètement d'écrire les données utilisateur sur le disque local. Votre NVMe contient la base de données et le code ; le bucket contient chaque octet que quelqu'un téléverse. Passer de deux cents gigaoctets à vingt téraoctets devient alors une mise à niveau du nœud de stockage plutôt qu'une migration.
Avant de commencer
- Un R-8 pour l'application et un S-50 pour le bucket, idéalement dans la même ville afin que l'aller-retour du tunnel soit inférieur à une milliseconde.
- Un tunnel entre eux. Le guide WireGuard construit exactement cela ; utilisez
10.9.0.1pour l'application et10.9.0.2pour le nœud de stockage. - Un nom d'hôte pointant vers l'instance de l'application,
cloud.example.comci-dessous.
1. Stockage d'objets sur le nœud de stockage
MinIO est un binaire unique et n'a besoin de rien d'autre. Téléchargez-le, vérifiez-le, installez-le :
cd /usr/local/bin
wget https://dl.min.io/server/minio/release/linux-amd64/minio
wget https://dl.min.io/server/minio/release/linux-amd64/minio.sha256sum
sha256sum -c minio.sha256sum
chmod +x minio
useradd -r -s /sbin/nologin minio
install -d -o minio -g minio /srv/objectsLe niveau de capacité sur un nœud de stockage est monté séparément du NVMe. Placez le bucket sur le niveau de capacité et laissez le NVMe pour le cache d'écriture, c'est à cela qu'il sert. Ensuite, l'unité, à /etc/systemd/system/minio.service :
[Unit]
Description=MinIO
After=network-online.target [email protected]
Wants=network-online.target
[Service]
User=minio
Group=minio
Environment=MINIO_ROOT_USER=nextcloud
Environment=MINIO_ROOT_PASSWORD=<forty random characters>
ExecStart=/usr/local/bin/minio server /srv/objects --address 10.9.0.2:9000
Restart=always
LimitNOFILE=65535
NoNewPrivileges=yes
ProtectSystem=strict
ReadWritePaths=/srv/objects
[Install]
WantedBy=multi-user.targetSe lier à l'adresse du tunnel plutôt qu'à tout est la ligne importante. Le stockage d'objets n'a aucune raison de répondre sur l'interface publique, et de cette façon une erreur de pare-feu ne peut pas l'exposer.
systemctl daemon-reload && systemctl enable --now minio
ss -ltn | grep 90002. Hôte de l'application : paquets
Sur l'instance Ryzen :
apt update && apt install -y nginx postgresql redis-server unzip \
php8.4-fpm php8.4-pgsql php8.4-gd php8.4-curl php8.4-zip php8.4-xml \
php8.4-mbstring php8.4-intl php8.4-bcmath php8.4-gmp php8.4-imagick \
php8.4-redis php8.4-apcu3. Base de données
sudo -u postgres psql -c "CREATE USER nextcloud WITH PASSWORD '<a long password>';"
sudo -u postgres psql -c "CREATE DATABASE nextcloud OWNER nextcloud TEMPLATE template0 ENCODING UTF8;"Les paramètres par défaut de Postgres conviennent à cette échelle. Si ce Nextcloud finit par servir quelques centaines de personnes, le guide de réglage de Postgres s'applique et les chiffres qu'il contient valent une heure.
4. Nextcloud, configuré avant l'installation
cd /var/www
wget https://download.nextcloud.com/server/releases/latest.zip
unzip -q latest.zip && rm latest.zip
chown -R www-data:www-data /var/www/nextcloudMaintenant la partie qui doit se faire avant que l'installateur s'exécute, car un stockage d'objets principal ne peut pas être ajouté à une instance existante sans déplacer chaque fichier à la main. Créez /var/www/nextcloud/config/config.php :
<?php
$CONFIG = array(
"objectstore" => array(
"class" => "\\OC\\Files\\ObjectStore\\S3",
"arguments" => array(
"bucket" => "nextcloud",
"autocreate" => true,
"key" => "nextcloud",
"secret" => "<the same forty characters>",
"hostname" => "10.9.0.2",
"port" => 9000,
"use_ssl" => false,
"use_path_style" => true,
"region" => "local",
),
),
);use_ssl est faux délibérément. Le trafic traverse un tunnel WireGuard déjà authentifié et chiffré, et terminer TLS une seconde fois sur le nœud de stockage n'achète rien d'autre que des cycles CPU et un certificat à oublier de renouveler. Si les deux machines devaient un jour être dans des villes différentes, activez-le.
chown www-data:www-data /var/www/nextcloud/config/config.php
chmod 640 /var/www/nextcloud/config/config.php
cd /var/www/nextcloud
sudo -u www-data php occ maintenance:install --database pgsql \
--database-name nextcloud --database-user nextcloud \
--database-pass "<a long password>" \
--admin-user admin --admin-pass "<another long password>"5. Cache, cron et les derniers paramètres
sudo -u www-data php occ config:system:set memcache.local --value "\\OC\\Memcache\\APCu"
sudo -u www-data php occ config:system:set memcache.distributed --value "\\OC\\Memcache\\Redis"
sudo -u www-data php occ config:system:set memcache.locking --value "\\OC\\Memcache\\Redis"
sudo -u www-data php occ config:system:set redis host --value /run/redis/redis-server.sock
sudo -u www-data php occ config:system:set redis port --value 0
sudo -u www-data php occ config:system:set trusted_domains 0 --value cloud.example.com
sudo -u www-data php occ config:system:set overwrite.cli.url --value https://cloud.example.com
sudo -u www-data php occ background:cronRedis via une socket Unix plutôt que TCP économise un aller-retour d'appel système à chaque opération de verrouillage, et Nextcloud prend beaucoup de verrous. Ajoutez www-data au groupe redis pour qu'il puisse atteindre la socket, puis branchez le travail d'arrière-plan sur une minuterie :
usermod -aG redis www-data
systemctl restart php8.4-fpm redis-server
echo "*/5 * * * * php -f /var/www/nextcloud/cron.php" | crontab -u www-data -Les défauts de PHP-FPM supposent une machine partagée. La vôtre n'est pas partagée, donc dans /etc/php/8.4/fpm/pool.d/www.conf définissez pm = dynamic, pm.max_children = 60, pm.start_servers = 12, pm.min_spare_servers = 8 et pm.max_spare_servers = 20, et augmentez memory_limit à 1G dans /etc/php/8.4/fpm/php.ini. Les téléversements veulent upload_max_filesize et post_max_size à 16G à moins que vous n'aimiez expliquer pourquoi une vidéo a échoué à quatre-vingt-dix pour cent.
Vérifier
Le but de cette construction est que les fichiers utilisateur ne soient pas sur le serveur d'application. Prouvez-le, en trois commandes.
sudo -u www-data php occ status
du -sh /var/www/nextcloud/dataLe statut doit indiquer installé et non en mode maintenance. Le répertoire de données doit faire quelques mégaoctets et le rester pour toujours ; il contient des journaux et rien d'autre une fois le stockage d'objets principal.
Maintenant, téléversez quelque chose et regardez où cela atterrit :
head -c 50M /dev/urandom > /tmp/test.bin
curl -u admin -T /tmp/test.bin https://cloud.example.com/remote.php/dav/files/admin/test.bin
du -sh /var/www/nextcloud/dataLe téléversement réussit, et le répertoire de données n'a pas grandi de cinquante mégaoctets. Sur le nœud de stockage, l'objet est visible directement :
ls -R /srv/objects/nextcloud | tail -5
du -sh /srv/objects/nextcloudLes objets sont nommés urn:oid: suivi de l'identifiant du fichier, c'est pourquoi le bucket n'est pas une copie parcourable des dossiers de l'utilisateur et pourquoi vous sauvegardez la base de données et le bucket ensemble ou pas du tout.
Ensuite
Prenez le module de sauvegarde hors nœud pour le dump Postgres et le bucket, ou exécutez le vôtre vers un troisième site. Un bucket sans sa base de données est un tas de blobs numérotés, et une base de données sans son bucket est un index de fichiers qui n'existent plus. Perdre l'un, c'est perdre les deux.