Instalacion (docker)
NEXTCLOUD
Instalación de nextcloud mediante docker
INICIO
Instalación
La instalación consta de 4 servicios:
- db: Base de datos mariadb
- redis: Base de datos de memoria caché redis
- app: Aplicativo nextcloud
- web: Servidor web nginx, se encarga de redireccionar las peticiones hacia el aplicativo (app)
El primer paso es generar nuestro docker-compose:
db:
image: mariadb:10.11
container_name: nextcloud-db
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- database:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: Ko5b0sq977j1saaCQ3SD55
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: Ko5b0sq977j1saaCQ3SD55
redis:
image: redis:alpine
container_name: nextcloud-redis
restart: unless-stopped
volumes:
- redis:/data
app:
image: nextcloud:fpm
container_name: nextcloud-app
restart: unless-stopped
ports:
- 9000:9000
depends_on:
- db
- redis
volumes:
- data:/var/www/html
- user:/var/nextcloud/data
- /datos/dFa:/mnt
environment:
MYSQL_HOST: db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: Ko5b0sq977j1saaCQ3SD55
REDIS_HOST: redis
PHP_UPLOAD_LIMIT: 0
NEXTCLOUD_DATA_DIR: /var/nextcloud/data
command: >
sh -c "chown -R www-data:www-data /var/nextcloud &&
chmod -R 770 /var/nextcloud &&
exec /entrypoint.sh php-fpm"
web:
image: nginx
container_name: nextcloud-web
restart: always
ports:
- 8080:80
depends_on:
- app
volumes:
- nginx_conf:/etc/nginx
- data:/var/www/html
volumes_from:
- app
volumes:
data:
driver: local
database:
driver: local
redis:
driver: local
nginx_conf:
driver: local
user:
driver: local
Los volúmenes se han configurado por las siguientes razones:
- database: Ficheros de la base de datos mysql
- redis: Ficheros de la base de datos de memoria caché
- data: Ficheros del aplicativo nextcloud (es necesario que lo usen tanto el contenedor app como el contenedor web)
- user: Ficheros de los perfiles de usuarios creados para nextcloud
- nginx_conf: Fichero nginx.conf
Además, en este caso, se ha realizado un bind de nuestro disco /datos para que sea utilizado como punto de montaje en nextcloud. Dado que es un contenedor, es necesario mapearlo para que la interfaz web tenga acceso al recurso de alguna manera.
También se añade la adición de permisos al directorio /var/nextcloud durante la generación del contenedor, dado que el directorio se crea durante la creación del volumen "user".
sh -c "chown -R www-data:www-data /var/nextcloud &&
chmod -R 770 /var/nextcloud &&
exec /entrypoint.sh php-fpm"
Desplegamos los contenedores:
Y vemos que se han creado los volumenes correctamente:
Configuración
Con los volumenes creados, todavía nextcloud no es accesible, dado que debemos configurar tanto el config.php como como el nginx.conf.
nginx.conf
El fichero nginx.conf se encuentra en el volumen nextcloud_nginx_conf. Realizamos previamente un backup y reemplazamos por el siguiente:
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
types {
text/javascript mjs;
application/wasm wasm;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# Define asset_immutable variable properly
map $arg_v $asset_immutable {
default "";
"" ", immutable";
}
upstream php-handler {
server app:9000;
}
server {
listen 80;
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
client_body_buffer_size 512k;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
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;
add_header X-XSS-Protection "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
root /var/www/html;
index index.php index.html /index.php$request_uri;
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
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; }
location /.well-known/pki-validation { 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\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /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 HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_max_temp_file_size 0;
}
location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463$asset_immutable";
access_log off;
}
location ~ \.wasm$ {
default_type application/wasm;
}
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}
}
Reiniciamos los contenedores para que apliquen todos los cambios y comprobamos si funciona correctamente accediendo a través del puerto expuesto, en este caso el 8080:
Indicamos un usuario y contraseña y comenzará la instalación.
config.php
Una vez realizada la instalación, nos redireccionará mediante https lo cual dará el siguiente error:
Procedemos a modificar el fichero config.php que se encuentra en el volumen app dentro del directorio config con la siguiente configuración, teniendo en cuenta de no reemplazar los siguiente valores:
'secret' => 'eFMG77LAdbjw6oPSJM7hL/IDPBnP3qDxE7xlX6/uPMOvQ/kG'
'dbpassword' => 'Ko5b0sq977j1saaCQ3SD55'
config.php:
$CONFIG = array (
'memcache.local' => '\\OC\\Memcache\\APCu',
'apps_paths' =>
array (
0 =>
array (
'path' => '/var/www/html/apps',
'url' => '/apps',
'writable' => false,
),
1 =>
array (
'path' => '/var/www/html/custom_apps',
'url' => '/custom_apps',
'writable' => true,
),
),
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' =>
array (
'host' => 'redis',
'password' => '',
'port' => 6379,
),
'upgrade.disable-web' => true,
'instanceid' => 'ocxuwrcpcats',
'passwordsalt' => 'bFuPjx3NMpliQCtY729Uob2SRp19xe',
'secret' => 'eFMG77LAdbjw6oPSJM7hL/IDPBnP3qDxE7xlX6/uPMOvQ/kG',
'trusted_domains' =>
array (
0 => '10.100.200.35:8080',
1 => 'dfacloud.ddns.net',
),
'datadirectory' => '/var/nextcloud/data',
'dbtype' => 'mysql',
'version' => '30.0.6.2',
'overwrite.cli.url' => 'https://dfacloud.ddns.net',
'overwritehost' => '10.100.200.35:8080',
'overwriteprotocol' => 'http',
'dbname' => 'nextcloud',
'dbhost' => 'db',
'dbport' => '',
'dbtableprefix' => 'oc_',
'mysql.utf8mb4' => true,
'dbuser' => 'nextcloud',
'dbpassword' => 'Ko5b0sq977j1saaCQ3SD55',
'installed' => true,
);
En este fichero php tendremos que tener en cuenta modificar los valores nuestra dirección ip:puerto y nuestra dns en consecuencia.
Tambien debemos tener en cuenta la directiva:
- 'datadirectory' => '/var/nextcloud/data',
Dado que indica el directorio de datos dentro del contenedor.
Así como la directivas:
- overwrite.cli.url' => 'https://dfacloud.ddns.net'
- 'overwritehost' => '10.100.200.35:8080'
- 'overwriteprotocol' => 'http'
Estas directivas garantizarán que podremos acceder mediante http de manera local y mediante https de manera externa.
Tras esto ya podremos acceder a nextcloud correctamente.
Permisos
Es importante tener en cuenta los permisos de los directorios, sobre todo los directorios de datos y perfiles de usuarios.
En nuestro caso hemos montado el perfil de usuario en un directorio distinto dado que es una recomendación de seguridad de nextcloud, y además hemos expuesto nuestro disco /datos montando en el host anfitrión al contenedor, por lo que es posible que tengamos que revisar los permisos.
El usuario y grupo desde el host anfitrión en nuestro caso son:
- user: 33 (www-data)
- group: tape (www-data)
Y deben contener permisos 770
Hemos ajustado el compose para que se adapten estos permisos de forma automática, no obstante es importante revisarles si nextcloud indica algún problema de permisos.
OTROS
Compartir recurso que se usa en docker por smb
Si vamos a compartir un directorio de datos usado por docker tambien a través de smb, es importante tener en cuenta los permisos.
Para ello añadiremos nuestro usuario de smb al grupo tape e indicaremos en el recurso smb como usuario valido dicho grupo.
Para añadir el usuario al grupo tape:
Para configurar el grupo en smb:
path = /datos/dFa
browsable = yes
writable = yes
valid users = @tape
#valid users = dFa
read only = no
force create mode = 0777
force directory mode = 0777
guest ok = no
De esta manera tanto docker como el usuario de smb que hemos añadido al grupo tape tendrá permisos sobre el recurso.
También para evitar problemas, es importante asignar ACL's para que el recurso siempre tenga los mismos permisos cuando se añade un nuevo fichero y además aseguramos que el contenido ya existente se encuentra en un estado correcto en cuanto a los mismos:
setfacl -R -d -m g:tape:rwx /datos/