Installazione Nextcloud su Docker

Stasera ho tentato di aggiornare la mia installazione di Nextcloud e ho combinato un big casino, morale della favola ho dovuto reinstallare e reimportare i files.. Quindi quale occasione migliore di questa per raccontare il procedimento?

Per cominciare, Nextcloud è una applicazione di produttività web based. Può fare un sacco di cose (calendario, contatti, email, ecc..) ma io la uso sostanzialmente solo per archiviare files sul cloud e sincronizzarli tra i miei dispositivi.. sostanzialmente è una versione personale di Dropbox, ma senza i quotidiani popup per dirmi che ho usato il 70% del mio spazio e quindi dovrei pagare per l'account premium.

L'installazione è sulla mia VPS, in Docker. Richiede una installazione di MariaDB per lo storage, anche questa naturalmente su Docker. Il mio docker-compose.yaml è fatto così:

version: '2'

services:
  db:
    image: mariadb
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
    restart: always
    volumes:
      - $ENV_DB_ROOT:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=$ENV_MYSQL_ROOT_PASSWORD
      - MYSQL_PASSWORD=$ENV_MYSQL_PASSWORD
      - MYSQL_DATABASE=$ENV_APP_DATABASE
      - MYSQL_USER=$ENV_MYSQL_USER

  app:
    image: nextcloud
    ports:
      - 50020:80
    links:
      - db
    volumes:
      - $ENV_APP_HTML:/var/www/html
    restart: always
    environment:
      - MYSQL_PASSWORD=$ENV_MYSQL_PASSWORD
      - MYSQL_DATABASE=$ENV_APP_DATABASE
      - MYSQL_USER=$ENV_MYSQL_USER
      - MYSQL_HOST=db

Le uniche peculiarità sono una serie di opzioni per l'avvio di MariaDB (per compatibilità con l'ultima versione di Nextcloud). Le variabili che iniziano con $ sono variabili locali, recuperate da un file chiamato ".env" nella cartella corrente (un modo per non dover scrivere le password nel docker-compose).

Al primo avvio MariaDB crea un database e un utente con i parametri passati nel docker-compose mediante variabili di ambiente. Allo stesso modo, al primo avvio Nextcloud configura la connessione al db. Anche per questo è comodo usare un file ".env" esterno, così indico ad entrambe le applicazioni le stesse variabili anzichè doverle riscrivere. Il mio file è fatto così:

ENV_MYSQL_ROOT_PASSWORD=**********
ENV_MYSQL_PASSWORD=************
ENV_APP_HTML=./app/html
ENV_APP_DATABASE=**********
ENV_MYSQL_USER=********
ENV_DB_ROOT=./db
Nota importante: il processo di creazione del primo utente in MariaDB avviene, naturalmente, solo al primo avvio. Dopodichè salva (nella cartella locale db/) il suo database, e al successivo avvio ovviamente non crea nessun utente. Quindi, se si sbaglia utente e si vuole ricreare da zero, è necessario eliminare la cartella /db (perdendo naturalmente tutti i dati) e riavviare. So che sembra ovvio ma ci ho perso mezz'ora e se ci penso mi viene ancora da picchiare la testa contro la tastiera.

Come si vede nel docker-compose, ho esposto la porta 80 (default) di NextCloud sulla porta 50020 locale (scelta allegramente a caso). Voglio che questa porta in realtà sia esposta semplicemente come sottopercorso dell'indirizzo web della mia VPS (https://miosito.it/mynextcloud), quindi devo modificare la configurazione del mio proxy nginx con questo blocco:

location /mynextcloud/ {
  rewrite ^/mynextcloud(.*) $1 break;
  proxy_pass http://localhost:50020/;
  
  proxy_http_version 1.1;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $remote_addr;
  proxy_read_timeout 1d;
  proxy_set_header HTTP_X-Forwarded-For $proxy_add_x_forwarded_for;
  
  # set max upload size
  client_max_body_size 10G;
  fastcgi_buffers 64 4K;
}

A questo punto sono pronto per il primo avvio dello stack. Lo avviamo in modalità interattiva (senza opzione -d) così mantiene impegnato il terminale e mostra i log di avvio. In questo modo possiamo verificare che stia funzionando nel modo giusto.

docker-compose up

Possiamo andare al nostro sito "https://miosito.it/blog" e vedere la prima pagina, ma questa farà schifo (non c'è lo sfondo, i caratteri sono fuori posto eccetera). Possiamo fermarci subito e stoppare tutto (se avevamo avviato in modalità interattiva basta premere Ctrl+C nel terminale). Durante il primo avvio Nextcloud si è creato i suoi file di configurazione nella cartella "app/html/config", e noi dobbiamo andare a modificarne uno, "config.php", per aggiungere un paio di elementi che servono a far funzionare il cloud su questo particolare sottoindirizzo (mioindirizzo/mynextcloud).

Nel suddetto config.html dobbiamo aggiungere queste righe, nell'array principale (sotto la riga contenente la chiave "instanceid"):

  'overwrite.cli.url' => 'https://www.miosito.it/mynextcloud',
  'overwritehost' => 'www.miosito.it',
  'overwritewebroot' => '/mynextcloud',
  'overwriteprotocol' => 'https',

A questo punto possiamo avviare il docker-compose, stavolta in modalità batch:

docker-compose up -d

Se tutto va per il verso giusto dovremmo poter accedere alla pagina web all'indirizzo pubblico e vedere la schermata iniziale:

In questa schermata impostiamo il nostro utente (che sarà amministratore) e relativa password. Fatto!


Nota: reimportare i files manualmente

Nella mia vecchia installazione avevo un sacco di files, e li ho dovuti ricopiare tutti in quella nuova. I files sono archiviati nel percorso locale "app/html/data/<utente>/files". Invece di ricaricarli a mano attraverso l'interfaccia web è possibile copiarli direttamente dentro la cartella, ma a quel punto non saranno immediatamente visibili a Nextcloud. Bisogna entrare nella macchina Docker manualmente e lanciare un comando apposta, che forzerà l'indicizzazione dei files:

# Per entrare nella macchina docker
# nota: -u 33 serve a entrare con l'utente corretto
docker exec -ti -u 33 nextcloud_app_1 /bin/bash

# Per lanciare l'indicizzazione
./occ files:scan --all

Altra nota: bruteforce protection

Nextcloud integra una funzione di protezione contro gli attacchi bruteforce, ovvero gli attacchi informatici che tentano di accedere a un portale provando milioni di password. La protezione funziona in questo modo: viene registrato l'indirizzo IP di tutti i recenti login falliti, e quando ce ne sono un numero sufficiente viene mostrata una schermata di errore e impedito l'accesso per qualche ora. Si tratta di un ottimo sistema di sicurezza che però può ritorcersi contro quando abbiamo nella nostra rete una applicazione legittima che non riesce a connettersi (se per esempio è cambiata la password dell'utente). In questi casi è possibile resettare il log dei tentativi di accesso, nella maniera più grezza possibile: accedendo alla macchina Docker che contiene il db e cancellando i record da una tabella.

# Per entrare nella macchina Docker
docker exec -ti nextcloud_db_1 /bin/bash

# Per avviare il client mysql
# (quando richiesta, la password è la mysql_root_password nel nostro .env)
mysql -u root -p

# Per lavorare sul database 
# (il nome del db è l'env_app_database nel nostro .env)
use <nomedb>;

# Per cancellare il contenuto della tabella
delete from oc_bruteforce_attempts;

Un venerdì sera ben speso a risolvere casini, ma almeno ho trovato qualcosa da scrivere sul blog.

Alla prossima!