Installazione Redmine su Docker
Altro mese, altro esperimento. Stavolta con Redmine, un'applicativo di project management open source.
Perchè c'è un numero di task che posso gestire in un progetto prima di iniziare a maledire GSheet (e il corrispettivo su Teams). Quel numero è indicativamente compreso tra 9 e 11. Ed è arrivato. Ed è passato oltre. Ampiamente.
Redmine ha un sacco di funzionalità molto interessanti con cui sto sperimentando ultimamente, tra cui diversi tracker personalizzabili, gantt, news, wiki, forum, campi custom di diverse tipologie e per tutte le esigenze, una matrice di permessi ESTREMAMENTE flessibile, ottimo sistema di filtraggio/ricerca con query custom salvabili, notifiche via email e mille altre ancora, compresa una comoda api per caricamento/update delle issues a partire dai suddetti maledetti excel di cui si parlava poco fa.
Usando Docker (e docker-compose) è possibile tirare su una installazione di Redmine (e PostgreSQL) in un attimo, usando l'immagine ufficiale.
Un esempio di docker-compose.yml è più o meno così:
version: '3.3'
services:
postgres:
image: postgres:10
volumes:
- ./storage/postgresql-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: "my_postgres_password"
POSTGRES_DB: "redmine"
PGDATA: "/var/lib/postgresql/data"
restart: always
redmine:
image: redmine:5
ports:
- 2000:3000
volumes:
- ./storage/docker_redmine-plugins:/usr/src/redmine/plugins
- ./storage/docker_redmine-themes:/usr/src/redmine/public/themes
- ./storage/docker_redmine-data:/usr/src/redmine/files
- type: bind
source: ./storage/configuration.yml
target: /usr/src/redmine/config/configuration.yml
environment:
REDMINE_DB_POSTGRES: "postgres"
REDMINE_DB_USERNAME: "postgres"
REDMINE_DB_PASSWORD: "my_postgres_password"
REDMINE_DB_DATABASE: "redmine"
REDMINE_SECRET_KEY_BASE: "secret_key_base"
restart: always
La prima parte descrive il database postgres. Al primo avvio viene inizializzato con la password amministrativa e con il nome db specificati. La seconda parte è il server Redmine vero e proprio, corredato delle informazioni necessarie a collegarsi al database di cui sopra.
Come si vede sono stati esposti nel filesystem host una serie di volumi, tutti contenuti nella directory "storage". A parte quelli relativi ai dati (sia di redmine che di postgres) ho esposto anche le cartelle "plugins" e "themes" di Redmine, in cui posso copiare temi e plugin che saranno visibili dal prossimo riavvio.
A questo punto basta un:
docker-compose up -d
..e sulla porta 2000 abbiamo già la nostra installazione pronta per fare esperimenti.
HTTPS con Nginx
Già che ci siamo, possiamo usare il proxy Nginx per esporre il sito in https dal nostro server. Basta avere a disposizione la coppia di chiavi ssl valide per il proprio dominio (facili da ottenere e gratuite con LetsEncrypt), e aggiungere questa configurazione:
server{
listen 6666 ssl;
server_name my_beautiful_site.it
ssl_certificate /cert_path/fullchain.pem;
ssl_certificate_key /cert_path/privkey.pem;
location / {
proxy_pass http://localhost:2000/;
}
}
In questa configurazione stiamo esponendo la porta 2000 (quella che abbiamo aperto sul nostro container Redmine) sulla porta 6666 del nostro server, attraverso la connessione https con certificato. In questo caso naturalmente vogliamo anche assicurarci che la porta 9090 sia esposta mentre la 2000 no, ad esempio usando UFW (Uncomplicated FireWall). Per esporre la 6666 basta usare questi comandi:
ufw allow 6666
ufw reload
Bloccare la 2000 è meno immediato. In teoria UFW di default blocca qualunque porta che non sia esplicitamente esposta, ma Docker all'avvio di un container modifica per conto suo iptables (il firewall a basso livello di Linux), vanificando la protezione. La soluzione è esplicitare a Docker che la porta 2000 è accessibile solo dalla macchina locale, modificando la riga del docker-compose:
ports:
- 2000:3000
...così:
ports:
- 127.0.0.1:2000:3000
Adesso la porta 2000 non è più accessibile dall'esterno.
Configurazione email
Redmine supporta l'invio di email di notifica configurabili attraverso un server smtp. Configurare un server smtp proprio è divertente ma verrà subito bloccato per sospetto spam da qualunque altro server del pianeta, quindi conviene affidarsi a qualche servizio più professionale.
Nel mio caso ho voluto sperimentare con MailerSend, che offre un free-tier da 3000 email al mese che sono più che sufficienti per i miei esperimenti. Per accedere a questo servizio è necessario essere titolari di un dominio web, di cui si dovrà dimostrare il possesso modificando alcuni parametri DNS (accessibili dal pannello di controllo del servizio su cui si è registrato il suddetto dominio). La configurazione iniziale dell'account è un tantino macchinosa e non è un argomento particolarmente universale, quindi passerei oltre. Una volta superato l'ostacolo abbiamo a disposizione le credenziali per inviare mail dal nostro dominio attraverso il loro server SMTP.
Per configurare Redmine, dobbiamo predisporre dentro il container un file di configurazione denominato "config.yml", nel percorso /usr/src/redmine/config/.
Per assicurarci che il file persista ai riavvii del container, lo creiamo nel nostro host, ad esempio dentro la cartella "storage" che abbiamo predisposto in precedenza.
production:
delivery_method: :smtp
smtp_settings:
address: [smtp server url]
port: [smtp server port]
domain: [miodominio.it]
authentication: :login
user_name: [smtp username]
password: [smtp password]
..e poi creiamo il collegamento tra il file esterno e il percorso all'interno del container aggiungendo queste righe al nostro docker-compose, sotto la sezione "volumes":
- type: bind
source: ./storage/configuration.yml
target: /usr/src/redmine/config/configuration.yml
A questo punto possiamo stoppare il nostro container e riavviarlo (prima di riavviarlo usiamo il comando "rm" per fare pulizia, non sarebbe necessario dopo il "down" ma male non fa, così siamo certi di partire da un nuovo container pulito).
docker-compose down
docker-compose rm -v
docker-compose up -d
Per assicurarci che la configurazione sia stata accettata da Redmine possiamo andare sotto il menù Administration->Settings->Email notifications, se NON vediamo un messaggio di errore vuol dire che finora tutto è andato per il verso giusto.
Si configura un indirizzo (qualunque, anche inesistente) di provenienza per le email seguendo le regole del servizio SMTP; nel caso di MailerSend è obbligatorio che l'indirizzo sia nel dominio con cui è stato configurato l'account. E si preme il pulsante "Send a test email" in basso a destra. Salvo sorprese dovremmo essere arrivati a destinazione.
Successo!