Tutorial Nextcloud

Introducción

Hoy en día todos tenemos un teléfono móvil en el bolsillo. Este teléfono está sincronizado con la llamada "nube" gracias a lo cual tus datos son convenientemente compartidos con todos los dispositivos conectados a la misma cuenta. Esto nos da mucha comodidad al poder ver cada cambio reflejado en todas nuestras pantallas al mismo tiempo y poder acceder a nuestros datos desde cualquier parte.

Pero desafortunadamente, sabemos que esta "nube" no es otra cosa que "el ordenador de otro".

¿Por qué deberíamos confiar nuestras agendas, contactos, fotos y documentos personales a alguien que no somos nosotros mismos, que ni siquiera tiene nuestros intereses en mente y para los que incluso somos un producto más? Estás en lo cierto, no deberíamos.

¿Qué pensarías si te dijese que existe hoy en día una solución que permite gestionar nuestra información personal del mismo modo que lo haríamos a través de la "nube"?

Tenemos la gran suerte de contar con un producto que cuenta con todas las características que necesitamos, con un largo track record y además es software libre y gratis. Os presento Nextcloud.

Nextcloud logo

Qué necesitamos

Siendo todo el software que usaremos libre, nos centraremos primero en el hardware.

¿Dónde lo quieres instalar? ¿Qué uso le vas a dar? ¿Cuántos usuarios? ¿Qué tiempo de respuesta necesitas? ¿Cuánta tolerancia a fallos por disponibilidad? Estas serán algunas de las preguntas que deberías plantearte antes de decidir dónde vas a instalar tu instancia de Nextcloud. Te pongo unos ejemplos para que te sirvan como guía en tu decisión:

  1. Me interesa una instalación con la que trastear. No quiero dedicar más hardware que un raspberry que tengo por casa. Usaré Nextcloud para compartir documentos importantes y fotos con la familia, dentro de casa.

  2. Quiero usarlo continuamente con mi familia, amigos, o empleados de mi pequeña empresa. Tendremos calendarios compartidos y contactos sincronizados continuamente. Haremos uso de la compartición de archivos, fotos e incluso colaboraremos en línea en la creación de documentos.

Si ya sabes con cuál de las situaciones te identificas, ya sabes más o menos a qué atenerte en cuanto a hardware.

En el caso de tenerlo en casa usaremos una Raspberry PI u ordenador que podamos dejar encendido y en caso de querer tenerlo fuera de casa por razones de conectividad o recursos, podremos usar cualquiera de los servicios de hosting que existen en el mercado. Podría recomendar host4coins, Digital Ocean o Linode.

Instalación

Preparación del sistema

Nextcloud no requiere muchos recursos, pero al menos 1GB de RAM sería recomendable. Puesto que uno de sus usos será el almacenar archivos y fotos, necesitaremos además algo de capacidad de disco duro.

Si vamos a darle uso y no se trata únicamente de cacharrear, convendría además registrar un nombre de dominio que apunte a nuestra IP. En el caso de querer instalarlo en casa no disponder de IP fija, existen en internet una gran variedad de empresas que ofrecen DNS dinámico. En nuestro caso, seleccionamos jaimescloud.xyz

Para empezar, nos conectaremos a nuestro servidor por ssh:

ssh jaime@jaimescloud.xyz

Nextcloud es una aplicación web escrita en PHP. Necesitaremos por lo tanto un servidor web y una base de datos.

La instalación oficial pasa por instalar el conocido servidor web Apache. Sin embargo, tratándose de una instalación que quizá tengamos que usar en máquinas con pocos recursos, me he decantado por adaptarlo para nginx, que es un servidor mucho más ligero.

Usaremos configuraciones creadas por la comunidad Nextcloud, adaptadas a las oficiales de Apache. Me he tomado la libertad de adaptar a su vez estas configuraciones para simplificar y actualizarlas a las versiones actuales de los distintos paquetes de software que usaremos.

Para la base de datos optaré por MariaDB.

Con el software ya elegido, procedemos a la instalación de los distintos requerimientos.

Actualizamos primero nuestro sistema. Supondremos que estamos trabajando con Ubuntu 20.04 LTS:

sudo apt update
sudo apt upgrade

Instalamos los paquetes necesarios servidor web, base de datos y php:

sudo apt install nginx mariadb-server 
sudo apt install php7.4-gd php7.4-mysql php7.4-curl php7.4-mbstring php7.4-intl php7.4-gmp php7.4-bcmath php-imagick php7.4-xml php7.4-zip php7.4-bz2 php7.4-fpm 

Nos conectamos a mysql/MariaDB y creamos nuestra base de datos que albergará la información de nuestra instalación Nextcloud, sustituyendo username and password por las credenciales que elijamos. Anotamos usuario y contraseña que necesitaremos posteriormente:

sudo mysql -uroot -p 

CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES ON nextcloud.* TO 'username'@'localhost';
FLUSH PRIVILEGES;
quit;

Descarga e instalación de Nextcloud

Descargamos Nextcloud desde su página: https://nextcloud.com/install -> Server -> Download for server -> Download Nextcloud -> Details and download options

Vamos a nuestro terminal y lo descargamos, junto con el archivo sha256 y asc para su verificación, sustituyendo x.y.z por la versión actual:

wget https://download.nextcloud.com/server/releases/nextcloud-x.y.z.tar.bz2
wget https://download.nextcloud.com/server/releases/nextcloud-x.y.z.tar.bz2.sha256
wget https://download.nextcloud.com/server/releases/nextcloud-x.y.z.tar.bz2.asc
wget https://nextcloud.com/nextcloud.asc

Verificamos el paquete:

gpg --import nextcloud.asc
gpg --recv-keys 28806A878AE423A28372792ED75899B9A724937A
gpg --verify nextcloud-x.y.z.tar.bz2.asc nextcloud-x.y.z.tar.bz2
sha256sum -c nextcloud-x.y.z.tar.bz2.sha256 < nextcloud-x.y.z.tar.bz2
> OK

Una vez verificado, lo extraemos y copiamos a la carpeta donde residirá a partir de ahora:

tar -xjvf nextcloud-x.y.z.tar.bz2
cp -r nextcloud /var/www

Hacemos que nginx sea el propietario del nuevo directorio creado:

sudo chown -R www-data:www-data /var/www/nextcloud

Configuración de Nginx:

Necesitamos crear el fichero de configuración principal. Se trata de la lista de instrucciones que damos a nginx para que sepa cómo comportarse al ejecutar nuestra instancia Nextcloud.

Creamos pues el archivo /etc/nginx/sites-available/nextcloud.conf que contendrá las siguiente líneas:

upstream php-handler {
    server unix:/var/run/php/php7.4-fpm.sock;
}

server {
    listen 80;
    listen [::]:80;
    server_name jaimescloud.xyz;


    # set max upload size and increase upload timeout:
    client_max_body_size 512M;
    client_body_timeout 300s;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    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 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;

    # Pagespeed is not supported by Nextcloud, so if your server is built
    # with the `ngx_pagespeed` module, uncomment this line to disable it.
    #pagespeed off;

    # HTTP response headers borrowed from Nextcloud `.htaccess`
    add_header Strict-Transport-Security "max-age=31536000" always;
    add_header Referrer-Policy                      "no-referrer"   always;
    add_header X-Content-Type-Options               "nosniff"       always;
    add_header X-Download-Options                   "noopen"        always;
    add_header X-Frame-Options                      "SAMEORIGIN"    always;
    add_header X-Permitted-Cross-Domain-Policies    "none"          always;
    add_header X-Robots-Tag                         "none"          always;
    add_header X-XSS-Protection                     "1; mode=block" always;

    # Remove X-Powered-By, which is an information leak
    fastcgi_hide_header X-Powered-By;

    # Path to the root of your installation
    root /var/www/nextcloud;

    # Specify how to handle directories -- specifying `/index.php$request_uri`
    # here as the fallback means that Nginx always exhibits the desired behaviour
    # when a client requests a path that corresponds to a directory that exists
    # on the server. In particular, if that directory contains an index.php file,
    # that file is correctly served; if it doesn't, then the request is passed to
    # the front-end controller. This consistent behaviour means that we don't need
    # to specify custom rules for certain paths (e.g. images and other assets,
    # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
    # `try_files $uri $uri/ /index.php$request_uri`
    # always provides the desired behaviour.
    index index.php index.html /index.php$request_uri;

    # Rule borrowed from `.htaccess` to handle Microsoft DAV clients
    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;
    }

    # Make a regex exception for `/.well-known` so that clients can still
    # access it despite the existence of the regex rule
    # `location ~ /(\.|autotest|...)` which would otherwise handle requests
    # for `/.well-known`.
    location ^~ /.well-known {
        # The rules in this block are an adaptation of the rules
        # in `.htaccess` that concern `/.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; }

        # Let Nextcloud's API for `/.well-known` URIs handle all other
        # requests by passing them to the front-end controller.
        return 301 /index.php$request_uri;
    }

    # Rules borrowed from `.htaccess` to hide certain paths from clients
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

    # Ensure this block, which passes PHP files to the PHP process, is above the blocks
    # which handle static assets (as seen below). If this block is not declared first,
    # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
    # to the URI, resulting in a HTTP 500 error response.
    location ~ \.php(?:$|/) {
        # Required for legacy support
        rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/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;         # Avoid sending the security headers twice
        fastcgi_param front_controller_active true;     # Enable pretty urls
        fastcgi_pass php-handler;

        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;

        fastcgi_max_temp_file_size 0;
    }

    location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite)$ {
        try_files $uri /index.php$request_uri;
        expires 6M;         # Cache-Control policy borrowed from `.htaccess`
        access_log off;     # Optional: Don't log access to assets

        location ~ \.wasm$ {
            default_type application/wasm;
        }
    }

    location ~ \.woff2?$ {
        try_files $uri /index.php$request_uri;
        expires 7d;         # Cache-Control policy borrowed from `.htaccess`
        access_log off;     # Optional: Don't log access to assets
    }

    # Rule borrowed from `.htaccess`
    location /remote {
        return 301 /remote.php$request_uri;
    }

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


Lo activamos creando un link en el directorio sites-enabled:

sudo ln -s /etc/nginx/sites-available/nextcloud.conf /etc/nginx/sites-enabled/

A continuación modificaremos un par de configuraciones PHP para que Nextcloud se comporte correctamente y tenga suficiente memoria para poder tratar con la sincronización de archivos más grandes.

En el archivo /etc/php/7.4/fpm/pool.d/www.conf descomentamos las lineas:

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

Cambiamos dos variables en el fichero /etc/php/7.4/fpm/php.ini

# Default is 128M
memory_limit = 512M 

# Default is 2M
upload_max_filesize = 100M

Reiniciamos php y nginx:

sudo systemctl reload php7.4-fpm.service
sudo systemctl restart nginx

Conexión segura SSL: letsencrypt!

Si vamos a usar esta instalación de modo más "oficial", es aconsejable el conectarse a ella mediante SSL. Para ello necesitaremos generar nuestros certificados. Usaremos certbot para tal propósito:

sudo apt-get install python3-certbot-nginx

sudo certbot --nginx

Responderemos a las preguntas de certbot. Elegiremos "redirect to SSL" para obligar al usuario a conectarse de forma segura.

Volvemos a reiniciar nginx para que cargue el fichero de configuración modificado, con las directivas para conectar por SSL.

sudo systemctl restart nginx

Conectamos por primera vez con nuestra instalación. En nuestro caso, https://jaimescloud.xyz.

Siendo la primera vez, nos pedirá crear usuario y contraseña y otros datos como nuestra base de datos y su password de acceso.

Primera configuración

En cuanto se haya configurado todo, nos lleva automáticamente a nuestro dashboard.

Uso

En la esquina superior derecha, si hacemos click en nuestro usuario, podremos crear más usuarios e instalar aplicaciones

Menú

Estas son sólo algunas de las aplicaciones recomendadas. Invito al lector a descubrir más de tantas joyas incluídas en el enorme directorio:

  • Contacts. Directorio de contactos que permite acceso a teléfonos y programas de email mediante CardDAV
  • Calendar. La misma idea pero para calendarios. Nos permitirá conectar a través de CalDAV
  • Photos. Almacenaje, categorización y visualización de fotos y vídeos al estilo de Google Photos. Los distintos programas y apps nos permitirán sincronizarlas en los dispositivos que queramos
  • Files. La misma idea pero para archivos de todo tipo.
  • News - RSS feed manager. Podemos crear canales RSS personalizados de forma que el estado de los artículos que vayamos leyendo, quede sincronizado en todos nuestros dispositivos
  • Bookmarks. Lo mismo, pero para los links favoritos de todos nuestros navegadores
  • PhoneTrack. ¿Y si quisieras que tu familia te pudiera seguir la pista de forma privada sin compartir tu localización con "la nube"? Este AddOn lo hace posible si se empareja con Apps para móvil creadas para este propósito.
  • Notes. Nuestro block de notas en el servidor, sincronizado con las distintas apps.

Como decíamos, hay muchas más que podrás descubrir navegando por estas listas. Dejo como ejercicio al lector instalar y probar algunas aplicaciones más.

Sincronización al teléfono y al ordenador: apps Nextcloud y DAVx5

Todas estas funcionalidades ya descritas, no servirían de mucho si se quedasen únicamente en nuestro servidor. Lo interesante es la sincronización y posibilidad de colaboración entre equipos que este sistema ofrece.

En esta página nos podremos descargar la aplicación Nextcloud para cualquiera de nuestras plataformas ya sea ordenador o teléfono móvil.

Si además nos intalamos DAVx5 en Android, podremos sincronizar tanto contactos como calendarios con nuestra nueva instalación Nextcloud.

Recursos

Gran parte de los ficheros de configuración han sido tomados de las excelentes páginas de documentación del proyecto Nextcloud, ordenados, simplificados y organizados como me ha parecido tratándo de hacer el proceso menos árido al lector.

https://docs.nextcloud.com