Nextcloud en Debian 13 + Nginx + PHP-FPM 8.4
Documento antialzheimer técnico.
Si estás leyendo esto es porque ya sufriste.
Este cookbook está limpiado (sin retales contradictorios) y orientado a:
- Debian 13
- PHP-FPM 8.4.x
- Nginx (no Apache)
- MariaDB
- Redis (caching + file locking)
0) Variables que ustedes definen una vez
Ajusta esto a tu caso y mantégalo consistente:
# Dominio público
NC_DOMAIN="files.example.com"
# Rutas
NC_WEBROOT="/var/www/nextcloud" # código
NC_DATA="/srv/nextcloud-data" # datos (recomendado fuera de webroot)
# Base de datos
NC_DB="nextcloud"
NC_DB_USER="nextclouduser"
NC_DB_PASS="CAMBIAR_ESTO"
# Redis
REDIS_PASS="CAMBIAR_ESTO"
1) Base del sistema
sudo apt update
sudo apt -y full-upgrade
sudo apt -y install ca-certificates curl unzip gnupg lsb-release bzip2 vim-tiny
2) MariaDB
sudo apt -y install mariadb-server mariadb-client
sudo systemctl enable --now mariadb
sudo mysql_secure_installation
Crear DB y usuario (utf8mb4):
sudo mysql -u root -p <<SQL
CREATE DATABASE ${NC_DB} CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER '${NC_DB_USER}'@'localhost' IDENTIFIED BY '${NC_DB_PASS}';
GRANT ALL PRIVILEGES ON ${NC_DB}.* TO '${NC_DB_USER}'@'localhost';
FLUSH PRIVILEGES;
SQL
3) PHP 8.4 + PHP-FPM
3.1 Paquetes
sudo apt -y install php8.4-fpm php8.4-cli php8.4-common \
php8.4-gd php8.4-curl php8.4-zip php8.4-xml php8.4-mbstring \
php8.4-intl php8.4-bz2 php8.4-bcmath php8.4-gmp \
php8.4-imagick php8.4-mysql \
php8.4-redis
Si en su mirror no existe
php8.4-*, entonces su Debian no trae esa versión en ese momento y tocará repos alternativo o bajar a la versión disponible. No inventen compatibilidad: miren la matriz PHP/Nextcloud de su release.
3.2 Ajustes PHP-FPM
Recomendación práctica: no toquen php.ini a mano para todo. Creen un override propio.
Crear /etc/php/8.4/fpm/conf.d/99-nextcloud.ini:
; === Nextcloud sane defaults ===
memory_limit = 512M
upload_max_filesize = 2G
post_max_size = 2G
max_execution_time = 360
max_input_time = 360
output_buffering = Off
expose_php = Off
; Ajusten a su zona
date.timezone = Atlantic/Canary
; OPcache (básico)
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.memory_consumption=256
opcache.save_comments=1
opcache.revalidate_freq=60
Reiniciar y habilitar:
sudo systemctl enable --now php8.4-fpm
sudo systemctl restart php8.4-fpm
4) Redis (caché + file locking)
sudo apt -y install redis-server
sudo systemctl enable --now redis-server
Endurecer mínimo (local only + contraseña):
Editar /etc/redis/redis.conf:
bind 127.0.0.1 ::1
protected-mode yes
requirepass CAMBIAR_ESTO
Reiniciar:
sudo systemctl restart redis-server
5) Nginx + TLS (Let’s Encrypt)
5.1 Instalar Nginx y Certbot
sudo apt -y install nginx
sudo systemctl enable --now nginx
sudo apt -y install certbot python3-certbot-nginx
5.2 Certificado
sudo certbot --nginx -d "${NC_DOMAIN}"
6) Descargar Nextcloud (fuente oficial)
sudo install -d -m 0755 /var/www
cd /var/www
curl -L -o nextcloud.tar.bz2 https://download.nextcloud.com/server/releases/latest.tar.bz2
sudo tar -xjf nextcloud.tar.bz2
sudo chown -R www-data:www-data nextcloud
sudo chmod -R 0750 nextcloud
Data directory fuera del webroot:
sudo install -d -o www-data -g www-data -m 0770 "${NC_DATA}"
7) Nginx vhost base (genérico)
Crear /etc/nginx/sites-available/nextcloud.conf:
upstream php-handler {
server unix:/run/php/php8.4-fpm.sock;
}
server {
listen 80;
listen [::]:80;
server_name files.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name files.example.com;
root /var/www/nextcloud;
ssl_certificate /etc/letsencrypt/live/files.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/files.example.com/privkey.pem;
# Ajusten tamaño según su realidad
client_max_body_size 2G;
fastcgi_buffers 64 4K;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
index index.php index.html /index.php$request_uri;
access_log /var/log/nginx/nextcloud.access.log;
error_log /var/log/nginx/nextcloud.error.log;
location = /robots.txt { allow all; log_not_found off; access_log off; }
location = /.well-known/carddav { return 301 $scheme://$host/remote.php/dav; }
location = /.well-known/caldav { return 301 $scheme://$host/remote.php/dav; }
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ { deny all; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { deny all; }
location ~ \.php(?:$|/) {
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(/.*)$ /index.php$request_uri;
include fastcgi_params;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ \.(?:css|js|woff2?|svg|gif|map|png|jpg|jpeg|ico)$ {
try_files $uri /index.php$request_uri;
expires 6M;
access_log off;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}
Activar:
sudo ln -sf /etc/nginx/sites-available/nextcloud.conf /etc/nginx/sites-enabled/nextcloud.conf
sudo nginx -t
sudo systemctl reload nginx
8) Instalación de Nextcloud por CLI (repetible)
sudo -u www-data php -d memory_limit=512M /var/www/nextcloud/occ maintenance:install \
--database "mysql" \
--database-name "${NC_DB}" \
--database-user "${NC_DB_USER}" \
--database-pass "${NC_DB_PASS}" \
--database-host "localhost" \
--admin-user "admin" \
--admin-pass "CAMBIAR_ESTO" \
--data-dir "${NC_DATA}"
Dominio y URL:
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 0 --value="${NC_DOMAIN}"
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value="https://${NC_DOMAIN}"
9) Cron (lo correcto)
sudo -u www-data crontab -e
Añadan:
*/5 * * * * php -f /var/www/nextcloud/cron.php
10) Redis en config.php (sin APCu)
Editar /var/www/nextcloud/config/config.php y meter esto dentro del array:
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'password' => 'CAMBIAR_ESTO',
'timeout' => 1.5,
],
Quitar APCu es una decisión válida si ustedes quieren simplificar. El precio es que pierden el “caché local” rápido. Redis sigue resolviendo lo importante: locking y cache distribuida.
11) Permisos
Código:
sudo chown -R www-data:www-data /var/www/nextcloud
sudo find /var/www/nextcloud/ -type d -exec chmod 750 {} \;
sudo find /var/www/nextcloud/ -type f -exec chmod 640 {} \;
Data dir:
sudo chown -R www-data:www-data "${NC_DATA}"
sudo chmod -R 770 "${NC_DATA}"
12) Checklist post-instalación
sudo -u www-data php /var/www/nextcloud/occ status
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
sudo -u www-data php /var/www/nextcloud/occ maintenance:repair