Nextcloud, utilizando Docker y proxy inverso con Nginx

Aprendemos a instalar nuestra propia nube privada con Nextcloud, pero esta vez utilizando la tecnología de contenedores con Docker. De ambos productos ya he hablado largo y tendido en la web de Colaboratorio.net, donde colaboro.

La idea de esta entrada es crear una nube privada, que me sirva para tener sincronizado el contenido gestionado por la herramienta Joplin. De esta forma podré tener siempre al día la información, tanto en el portátil o laptop como en mi dispositivo móvil con sistema operativo Android.

También aprovecho para añadir un poco más de «chicha» al VPS que tengo en Clouding.io, al que ya le he instalado Icecast 2 para la emisión de una radio en directo, Jenkins para la integración continua (por si lo necesito para mi inclusión en el mundo del DevOps), el producto de monitoreo Cacti; todo ello condimentado con un servidor web con Nginx, que utilizo como proxy inverso para todos los productos. Además, un servidor de Minecraft que monté en su día, con la colaboración de mi hermano, para que los compañeros de la clase de mis hijos pudiesen entretenerse.

Despliegue de Nextcloud utilizando Docker

Así que vayamos allá. Para esta entrada he creado un fichero de configuración para Docker Compose. En este he especificado los contenedores que voy a utilizar. El primero es el motor de base de datos MariaDB y el otro el de la propia aplicación.

Nextcloud trabaja por defecto con SQlite, aunque no es lo recomendado para entornos en producción. Por lo que me he decido por MariaDB, la otra opción es PostgreSQL.

Respecto a la base de datos, antes del despliegue debemos definir los datos necesarios para su correcto funcionamiento, esto es, la contraseña de root y de la base de datos, su nombre y el del usuario que la va a administrar.

También he definido una serie de volúmenes, para que la información quede almacenada de forma persistente, aunque se reinicie o apague el contenedor. Estos volúmenes son el de la propia aplicación (/var/www/html), el de la información almacenada (/var/www/html/data) y el de la base de datos (/var/lib/mysql)

Por último, he definido la exposición del puerto 80, por un puerto que tenía disponible en el host.

Aquí os dejo la plantilla:

  1. version: '2'
  2.  
  3. volumes:
  4.   nextcloud:
  5.   db:
  6.   data:
  7.  
  8. services:
  9.   db:
  10.     image: mariadb
  11.     command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
  12.     restart: always
  13.     volumes:
  14.       - db:/var/lib/mysql
  15.     environment:
  16.       - MYSQL_ROOT_PASSWORD=contrasea
  17.       - MYSQL_PASSWORD=contrasea
  18.       - MYSQL_DATABASE=nextcloud
  19.       - MYSQL_USER=nextcloud
  20.  
  21.   app:
  22.     image: nextcloud
  23.     ports:
  24.       - 8684:80
  25.     links:
  26.       - db
  27.     volumes:
  28.       - nextcloud:/var/www/html
  29.       - data:/var/www/html/data
  30.     restart: always

Esta la plantilla la podemos modificar a nuestro gusto.

Una vez guardado el documento «Docker-compose.yml«, ya podemos generar el entorno, en el mismo directorio donde tengamos el fichero YML

  1. docker-compose up -d

Con un resultado similar al siguiente:

  1. [root@servubuntu nextcloud]# docker-compose up -d
  2. Creating volume "nextcloud_data" with default driver
  3. Creating volume "nextcloud_nextcloud" with default driver
  4. Creating nextcloud_db_1  ... done
  5. Creating nextcloud_db_1  ...
  6. Creating nextcloud_app_1 ... done

Podemos ver que efectivamente se han creado ambos contenedores y están funcionando:

  1. [root@servubuntu nextcloud]# docker ps
  2. CONTAINER ID        IMAGE                       COMMAND                  CREATED              \
  3. STATUS              PORTS                                         NAMES
  4. c59e4a045e9d        nextcloud                   "/entrypoint.sh ap..."   About a minute ago   \
  5. Up About a minute   0.0.0.0:8684->80/tcp   nextcloud_app_1
  6. acba20c1699g        mariadb                     "docker-entrypoint..."   About a minute ago   \
  7. Up About a minute   3306/tcp

Pero antes de continuar, para no tener que acceder por un puerto, vamos a configurar el proxy inverso con Nginx. Para ello vamos a generar un fichero de configuración, tal y como hemos en otras ocasiones.

  1. sudo vi /etc/nginx/sites-available/nextcloud.bitsandlinux.com

Con el siguiente contenido:

  1. server {
  2.     listen 80;
  3.     listen [::]:80;    
  4.     server_name nextcloud.bitsandlinux.com;   
  5.     location / {
  6.         proxy_pass http://localhost:8684;
  7.         proxy_http_version 1.1;
  8.         proxy_set_header Upgrade $http_upgrade;
  9.         proxy_set_header Connection 'upgrade';
  10.         proxy_set_header Host $host;
  11.         proxy_cache_bypass $http_upgrade;
  12.     }
  13. }

Una vez hecho esto, guardamos y creamos el correspondiente enlace simbólico:

  1. ln -s /etc/nginx/sites-available/nextcloud.bitsandlinux.com /etc/nginx/sites-enabled/

Reiniciamos el servidor web Nginx para que se apliquen los cambios:

  1. sudo systemctl restart nginx

Ahora nos falta una parte fundamental, que es habilitar el acceso HTTPS por el puerto 443, para ello utilizaremos las herramientas y certificados que nos ofrece la iniciativa Let’s Encrypt.

Habilitar HTTPS con Lets Encrypt

Para poder habilitar la conexión HTTPS, debemos instalar la herramienta Certbot:

  1. sudo apt-get install python-certbot-nginx

De esta manera ya podemos utilizar la herramienta:

  1. sudo certbot --nginx

Nos hará una serie de preguntas y al final listará los proyectos web que ha detectado y debemos seleccionar cuál de ellos será al que se le añadirán los certificados. Todo bastante fácil la verdad.

Los paquetes de Certbot vienen con un trabajo cron o un temporizador systemd que renovará los certificados automáticamente antes de que caduquen. No necesitaremos ejecutar Certbot nuevamente, a menos que cambiemos su configuración. Puede probar la renovación automática de los certificados ejecutando este comando:

  1. sudo certbot renew --dry-run

La herramienta añadira la tarea programada en algún de los siguientes lugares:

  1. /etc/crontab/
  2. /etc/cron.*/*
  3. systemctl list-timers

Podemos comprobar el certificado desde la siguiente URL: https://www.ssllabs.com/ssltest/

Instalación web de Nextcloud

Una vez hemos hecho todos estos pasos, toca la instalación vía web. En esta debemos definir el usuario administrador y su contraseña, además de los datos de conexión para la base de datos.

En la parte superior debemos indicar el usuario administrador y su contraseña:

Añadir las credenciales del usuario administrador

A continuación indicamos donde vamos a guardar los datos (en nuestro caso dejamos la configuración por defecto) y que motor de base de datos vamos a utilizar:

Añadimos las credenciales de la base de datos

Aquí es muy importante la última casilla, donde indicamos la ubicación de la base de datos y el puerto a utilizar. Recordar que esto ya lo habíamos definido en fichero de configuración del Docker Compose.

De esta manera ya podemos acceder a la aplicación sin problemas:

Vista de Nextcloud recién instalado

Y esto es todo. ¿Ya habéis instalado Nextcloud de esta manera? ¿Vuestra configuración es diferente? Me gustaría saber vuestra opinión. Nos vamos leyendo.