Vai al contenuto

๐Ÿณ Guida Avanzata a Docker

Questa guida fornisce un approfondimento sulla configurazione Docker per LibreFolio, destinata agli utenti che desiderano personalizzare la propria installazione.

โš ๏ธ Prerequisiti

Docker group (Linux)

Su Linux, il tuo utente deve appartenere al gruppo docker per eseguire i comandi Docker senza sudo:

sudo usermod -aG docker $USER

Successivamente, effettua il logout e accedi nuovamente, oppure esegui newgrp docker per attivare il gruppo nella sessione corrente. Senza questo passaggio, tutti i comandi docker e docker compose falliranno con un errore di permessi.

.env file required

LibreFolio richiede un file .env nella root del progetto. Se manca, ./dev.py docker build si rifiuterร  di procedere.

cp .env.example .env
$EDITOR .env          # review and customize parameters

๐Ÿ—๏ธ Architettura

LibreFolio utilizza un'immagine Docker solo per il runtime. Il frontend (SvelteKit) e la documentazione (MkDocs) vengono compilati sull'host e poi copiati nell'immagine. Il comando ./dev.py docker build gestisce questo processo automaticamente.

Host (build)                    Docker Image (runtime)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ frontend/src โ”‚โ”€โ”€npm buildโ”€โ”€โ–ถ  โ”‚ frontend/build/      โ”‚
โ”‚ mkdocs_src/  โ”‚โ”€โ”€mkdocs โ”€โ”€โ”€โ–ถ   โ”‚ mkdocs_src/site/     โ”‚
โ”‚ backend/     โ”‚โ”€โ”€copyโ”€โ”€โ”€โ”€โ”€โ”€โ–ถ   โ”‚ backend/             โ”‚
โ”‚ Pipfile*     โ”‚โ”€โ”€pipenv โ”€โ”€โ”€โ–ถ   โ”‚ Python packages      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“„ docker-compose.yml

Il file docker-compose.yml definisce il servizio e la directory dei dati persistenti.

๐Ÿ” Ordine di Prioritร  delle Variabili

Quando risolve le variabili di configurazione, LibreFolio rispetta il seguente ordine di precedenza (dalla prioritร  piรน bassa alla piรน alta):

graph LR
    CodeDefaults[1. Default del Codice] --> EnvFile[2. File .env]
    HostShell[3. Variabili d'Ambiente Host]
    DockerCompose[4. Blocco 'environment' in docker-compose.yml]

    EnvFile --> HostShell
    HostShell --> DockerCompose

๐Ÿ”ง Servizio: librefolio

  • ๐Ÿ—๏ธ build: .: Compila a partire dal Dockerfile nella root del progetto.
  • ๐Ÿ”Œ ports: Mappa la porta dell'host (${PORT:-6040}) alla porta 6040 del container, e ${TEST_PORT:-6041} alla porta 6041 per la modalitร  test.
  • ๐Ÿ“‚ volumes: Un bind mount ./LibreFolio-data โ†’ /app/backend/data/prod-docker rende persistenti database, upload, report dei broker e log nella stessa directory di docker-compose.yml.
  • ๐Ÿ“ env_file: .env: Carica tutta la configurazione dal file .env (copiato da .env.example).
  • ๐ŸŒ environment: Sovrascrive solo i valori specifici di Docker: LIBREFOLIO_DATA_DIR (percorso nel container) e HOST=0.0.0.0.
  • ๐Ÿฉบ healthcheck: Interroga GET /api/v1/system/health ogni 30 secondi.

๐Ÿ’พ Directory dei dati: LibreFolio-data/

Una directory in bind mount creata accanto a docker-compose.yml. Contiene il database SQLite, gli upload personalizzati, i report dei broker e i file di log. I dati sopravvivono all'arresto/riavvio/rimozione del container. รˆ possibile eseguire il backup direttamente dal file system dell'host.

๐Ÿ‘ค Utente e Permessi

Il container di LibreFolio viene eseguito come utente non root per motivi di sicurezza. L'UID/GID predefinito รจ 1000:1000. I file creati dall'applicazione in LibreFolio-data/ apparterranno a questo UID/GID sull'host.

Scegliere l'UID e il GID corretti

Imposta UID e GID nel tuo file .env per farli corrispondere all'utente dell'host (o a un utente dedicato) che deve possedere i file dei dati:

UID=1000
GID=1000

Come ls -l mostra la proprietร  dei file

Sull'host, ls -l LibreFolio-data/ mostra il nome dell'utente/gruppo scelto (risolto dall'UID/GID tramite /etc/passwd).

All'interno del container, gli stessi file appaiono come librefolio:librefolio โ€” รจ lo stesso UID/GID numerico, semplicemente risolto rispetto al file /etc/passwd del container.

Linux cheatsheet: utenti, gruppi e ID

Scoprire l'UID e il GID correnti:

id -u              # your user ID (e.g. 1000)
id -g              # your primary group ID (e.g. 1000)
id                 # full info: uid, gid, groups

Trovare l'UID/GID di qualsiasi utente:

id -u username     # UID of 'username'
id -g username     # primary GID of 'username'

Creare un nuovo gruppo:

sudo groupadd librefolio          # create group (auto-assigns GID)
sudo groupadd -g 1500 librefolio  # create group with specific GID

Creare un nuovo utente:

# System user (no home, no login โ€” ideal for services)
sudo useradd --system --no-create-home --gid librefolio --shell /usr/sbin/nologin librefolio

# Regular user with home directory
sudo useradd -m -g librefolio librefolio

Verificare gli ID assegnati:

id librefolio
# โ†’ uid=998(librefolio) gid=998(librefolio) groups=998(librefolio)

Aggiungere l'utente esistente a un gruppo:

sudo usermod -aG librefolio $USER
newgrp librefolio    # activate in current session (or log out/in)

Verificare l'appartenenza al gruppo:

groups $USER         # list all groups for your user

Impostare la proprietร  della directory dei dati:

sudo chown -R librefolio:librefolio ./LibreFolio-data

Successivamente, imposta l'UID/GID corrispondente in .env.

๐Ÿ› ๏ธ Comandi CLI

Tutte le operazioni Docker sono disponibili tramite dev.py:

./dev.py docker build          # Build image (auto-builds frontend + docs)
./dev.py docker build --no-cache  # Full rebuild without Docker cache
./dev.py docker rebuild        # Build โ†’ stop โ†’ restart (one-step deploy)
./dev.py docker up             # Start containers
./dev.py docker down           # Stop containers
./dev.py docker logs -f        # Follow container logs
./dev.py docker status         # Show container status
./dev.py docker exec <cmd>     # Run a dev.py command inside the container

Documentazione con screenshot

Se stai compilando la documentazione e desideri gli screenshot completi nella galleria, esegui:

./dev.py mkdocs --gallery

Questo richiede un ambiente completamente installato (con pipenv) e un server in esecuzione con dati di test popolati. Sii paziente: la generazione della galleria richiede alcuni minuti.

๐Ÿ“ก docker exec โ€” Esecuzione di comandi all'interno del container

Il sottocomando docker exec inoltra qualsiasi comando dev.py nel container in esecuzione:

./dev.py docker exec user create admin admin@example.com Pass123!
./dev.py docker exec user list
./dev.py docker exec db upgrade
./dev.py docker exec server --test

Questo equivale a eseguire docker compose exec librefolio python dev.py <cmd>.

๐Ÿงช Modalitร  Test

La configurazione Docker Compose espone due porte:

Porta Scopo Database
6040 Server di produzione (avviato dal CMD del container) prod-docker/sqlite/app.db (volume persistente)
6041 Server di test (avviato manualmente via docker exec) test/sqlite/app.db (effimero)

Avvio del server di test

  1. Avvia il container (il server di produzione parte automaticamente su :6040):

    docker compose up -d
    
  2. Popola il database di test con dati simulati:

    ./dev.py docker exec test db populate --force --with-static
    
  3. Avvia il server di test sulla porta 6041:

    ./dev.py docker exec server --test
    
  4. Accedi all'indirizzo http://localhost:6041

    Credenziali di test:

    Username Password
    e2e_test_user E2eTestPass123!
    e2e_test_admin E2eAdminPass123!

I dati di test sono effimeri

Il database di test risiede nello strato scrivibile del container, non su un bind mount persistente. Ciรฒ significa che:

  • โœ… I dati sopravvivono a docker compose stop / docker compose start (il container รจ in pausa, non rimosso).
  • โŒ I dati vanno persi con docker compose down (il container viene rimosso e ricreato).

Se hai bisogno di dati di test persistenti, aggiungi un bind mount dedicato in docker-compose.yml:

volumes:
  - ./LibreFolio-data:/app/backend/data/prod-docker
  - ./LibreFolio-test-data:/app/backend/data/test    # โ† add this

๐Ÿญ Considerazioni per la Produzione

๐ŸŽฎ 1. Personalizzazione di docker-compose.yml

Il repository include un file docker-compose.yml pronto all'uso. Ecco il file completo con annotazioni che mostrano cosa puoi personalizzare:

services:
  librefolio:
    image: librefolio:latest           # Built by ./dev.py docker build
    build:
      context: .
      args:
        UID: ${UID:-1000}              # (1) Match host user UID
        GID: ${GID:-1000}              # (1) Match host user GID
    container_name: librefolio
    # No 'user:' directive โ€” entrypoint starts as root, fixes permissions,
    # then drops to 'librefolio' user via gosu (same pattern as postgres/redis).
    restart: unless-stopped
    ports:
      - "${PORT:-6040}:6040"           # (2) Production port โ€” change via PORT in .env
      - "${TEST_PORT:-6041}:6041"      # (3) Test server port (optional)
    volumes:
      - ./LibreFolio-data:/app/backend/data/prod-docker  # (4) Persistent data (bind mount)
    env_file: .env                     # (5) All config from .env file
    environment:
      - LIBREFOLIO_DATA_DIR=/app/backend/data/prod-docker  # Docker-specific override
      - HOST=0.0.0.0
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:6040/api/v1/system/health')"]
      interval: 30s
      timeout: 10s
      start_period: 15s
      retries: 3

Personalizzazioni comuni:

# Cosa Come
(1) Allineare UID/GID all'host Imposta UID=1001 e GID=1001 in .env, poi ricompila
(2) Cambiare porta produzione Imposta PORT=3000 in .env
(3) Disabilitare porta test Rimuovi la riga TEST_PORT da ports:
(4) Percorso dati personalizzato Cambia il bind mount: ./my-data:/app/backend/data/prod-docker
(5) Tutta la configurazione Modifica il file .env (copiato da .env.example)

Primo utente

La prima volta che accederai a LibreFolio nel browser, vedrai una pagina di registrazione. Crea il tuo account direttamente โ€” il primo utente diventa automaticamente l'amministratore. Non รจ necessario l'uso della CLI.

๐Ÿ”’ 2. Reverse Proxy

รˆ vivamente consigliato eseguire LibreFolio dietro un reverse proxy come Nginx o Traefik. Questo ti permette di:

  • ๐Ÿ” Gestire facilmente i certificati SSL/TLS per HTTPS.
  • ๐Ÿ–ฅ๏ธ Servire piรน applicazioni sullo stesso server.
  • ๐Ÿ›ก๏ธ Aggiungere header di sicurezza e rate limiting.

๐Ÿ’พ 3. Backup del Database

Il database รจ memorizzato nella directory LibreFolio-data/ accanto a docker-compose.yml. Eseguine il backup direttamente dal file system dell'host:

#!/bin/bash
cp ./LibreFolio-data/sqlite/app.db /path/to/backups/app.db-$(date +%F)

Non รจ necessario docker cp โ€” la directory dei dati รจ un bind mount accessibile dall'host.

๐Ÿ”‘ 4. Variabili d'Ambiente

Tutta la configurazione รจ gestita nel file .env (copiato da .env.example). Le sovrascritture specifiche per Docker nel blocco environment: non devono essere modificate:

Variabile Default Descrizione Dove
PORT 6040 Porta host per il server di produzione .env
TEST_PORT 6041 Porta host per il server di test .env
UID 1000 UID utente container (deve corrispondere al proprietario della directory dati) .env
GID 1000 GID utente container (deve corrispondere al proprietario della directory dati) .env
LOG_LEVEL INFO Verbositร  dei log โ€” vedi Riferimento Livelli Log โ†’ .env
PORTFOLIO_BASE_CURRENCY EUR Valuta base per i calcoli del portafoglio .env
PREVIEW_CACHE_MAX_MB 50 Cache massima in memoria per l'anteprima immagini (MB) .env
LIBREFOLIO_DATA_DIR /app/backend/data/prod-docker Percorso dati nel container (non modificare) docker-compose.yml
HOST 0.0.0.0 Indirizzo di bind del container (non modificare) docker-compose.yml