Poți rula Firefly III pe propriul VPS în mai puțin de 20 de minute, cu Docker Compose. Obții un manager de finanțe personale complet privat, cu datele tranzacțiilor stocate în propriul container MariaDB, accesibil prin HTTPS în spatele unui proxy Nginx, gata să importe extrase CSV din orice bancă. Ghidul acesta acoperă configurarea completă, inclusiv containerul Data Importer, și se oprește explicit la singura greșeală de configurare care îți deteriorează datele criptate fără niciun avertisment la fiecare actualizare de versiune.
Ce face Firefly III de fapt
Firefly III este un manager de finanțe personale open-source construit pentru cei care vor un registru real de tranzacții cu dublă înregistrare, nu imaginea prelucrată pe care o oferă aplicația băncii. Îți definești conturile (curent, economii, card de credit, numerar, investiții), înregistrezi tranzacțiile manual sau le imporți din CSV ori conexiuni bancare directe, și construiești pe baza lor bugete, categorii și rapoarte. Totul rulează pe propria ta infrastructură. Niciun serviciu terț nu îți atinge istoricul financiar.
Scenariul obișnuit pe un VPS arată astfel: exporți un CSV din portalul băncii o dată pe săptămână, îl procesezi prin containerul Data Importer, iar Firefly III categorizează și stochează tranzacțiile. În timp obții un istoric curat al cheltuielilor, suport multi-valută, tranzacții recurente automatizate și rapoarte financiare care altfel ar presupune un abonament lunar la o aplicație cloud ce stochează datele pe serverele altcuiva. Pe un plan ct.Steady (4 nuclee, 4 GB RAM, 50 GB SSD), Firefly III rulează confortabil alături de alte servicii, fără să pună presiune vizibilă pe resurse.
Ce îți trebuie înainte de a începe
Ai nevoie de un VPS cu Debian 12 sau Ubuntu 22.04/24.04, cu Docker și plugin-ul Compose instalate. Cerința minimă oficială este de 512 MB RAM, dar cu MariaDB și containerul cron pornite în paralel, 1 GB devine insuficient în condiții normale de operare. Planifică pentru cel puțin 2 GB ca să eviți situațiile limită. Ai nevoie și de un domeniu sau subdomeniu îndreptat spre IP-ul serverului înainte de a configura proxy-ul Nginx. Blocul implicit de SMTP de pe instanțele VPS noi nu afectează funcționarea Firefly III, deoarece email-ul este opțional.
Dacă Docker nu este încă instalat, rulează:
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
Verifică că plugin-ul Compose este disponibil:
docker compose version
Dacă obții un număr de versiune v2.x, ești pregătit. Dacă comanda nu este recunoscută, instalează plugin-ul manual:
apt install docker-compose-plugin -y
Structura directorului și descărcarea fișierelor
Creează un director dedicat pentru implementare și intră în el:
mkdir -p /opt/firefly-iii && cd /opt/firefly-iii
Descarcă cele trei fișiere de configurare direct din repository-urile oficiale Firefly III:
curl -O https://raw.githubusercontent.com/firefly-iii/docker/main/docker-compose.yml
curl -o .env https://raw.githubusercontent.com/firefly-iii/firefly-iii/main/.env.example
curl -o .db.env https://raw.githubusercontent.com/firefly-iii/docker/main/database.env
Numele fișierelor contează. Fișierul compose le referențiază literal: env_file: .env și env_file: .db.env. Dacă le redenumești, trebuie să actualizezi și fișierul compose în consecință. Descarcă fișierele brute cu curl în loc să copiezi din browser, pentru că YAML este sensibil la spații albe, iar paginile redate pot introduce formatări invizibile.
Fișierul Docker Compose
Fișierul compose implicit din repository-ul Docker al Firefly III pornește trei servicii: aplicația principală (app), baza de date (db cu MariaDB LTS) și un container Alpine cron care declanșează noaptea procesarea tranzacțiilor recurente. Un fișier compose minimal configurat pentru producție arată astfel:
services:
app:
image: fireflyiii/core:latest
hostname: app
container_name: firefly_iii_core
restart: always
volumes:
- firefly_iii_upload:/var/www/html/storage/upload
env_file: .env
networks:
- firefly_iii
ports:
- "127.0.0.1:8080:8080"
depends_on:
- db
db:
image: mariadb:lts
hostname: db
container_name: firefly_iii_db
restart: always
env_file: .db.env
networks:
- firefly_iii
volumes:
- firefly_iii_db:/var/lib/mysql
cron:
image: alpine
container_name: firefly_iii_cron
restart: always
command: >
sh -c "echo '0 3 * * * wget -qO- http://app:8080/api/v1/cron/REPLACE_WITH_CRON_TOKEN' | crontab - && crond -f -L /dev/stdout"
networks:
- firefly_iii
volumes:
firefly_iii_upload:
firefly_iii_db:
networks:
firefly_iii:
driver: bridge
Portul este legat la 127.0.0.1:8080:8080, nu la 0.0.0.0:8080:8080. Accesul direct la container rămâne restricționat la interfața loopback a serverului, iar singura cale de acces din exterior trece prin proxy-ul Nginx configurat mai jos. Legarea la 0.0.0.0 este una dintre greșelile frecvente pe VPS-urile noi și ocolește complet regulile de firewall definite pentru portul 8080.
Configurarea .env și de ce APP_KEY este cea mai importantă variabilă din fișier
Deschide .env și setează cel puțin aceste valori înainte de prima pornire a containerelor. Parola bazei de date trebuie să fie identică în .env și .db.env:
# .env
APP_KEY= # Generează această valoare PRIMUL - vezi mai jos
APP_URL=https://finance.domeniultau.ro
SITE_OWNER=tu@domeniultau.ro
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=firefly
DB_USERNAME=firefly
DB_PASSWORD=o_parola_puternica_aici
STATIC_CRON_TOKEN=un_sir_aleatoriu_de32caractere00
TZ=Europe/Bucharest
# .db.env
MYSQL_RANDOM_ROOT_PASSWORD=yes
MYSQL_USER=firefly
MYSQL_PASSWORD=o_parola_puternica_aici
MYSQL_DATABASE=firefly
Setează parola în ambele fișiere înainte de primul docker compose up. MariaDB își inițializează directorul de date la prima pornire și stochează credențialele în volum. Dacă pornești stack-ul cu o parolă și o schimbi ulterior în fișierele env, volumul rămâne cu credențialele inițiale. Vei obține erori de autentificare la fiecare repornire ulterioară, remediabile numai prin ștergerea volumului firefly_iii_db și reinițializarea bazei de date.
Cum generezi APP_KEY corect
APP_KEY este cheia de criptare Laravel pe care Firefly III o folosește pentru toți tokenii OAuth, cheile API și câmpurile sensibile din baza de date. Trebuie să aibă exact 32 de caractere. Generează-o înainte de prima pornire:
head /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32 && echo
Ia rezultatul și pune-l în .env:
APP_KEY=sirul_generat_de_tine_de32caractere
Salvează această valoare imediat într-un manager de parole. O vei folosi la fiecare actualizare de container, la orice reconstruire a stack-ului și la orice migrare pe alt server. Cheia este permanent legată de datele criptate din volumul MariaDB. Nu se schimbă.
Greșeala care distruge instalarea la actualizări
Acesta este tiparul pe care îl întâlnim cel mai des în gestionarea implementărilor Docker cu Firefly III: utilizatorul vrea să actualizeze la o versiune nouă, descarcă din nou .env.example din repository pentru configurări curate, lasă APP_KEY necompletat sau generează unul nou și pornește containerul actualizat pe același volum de bază de date. Noua cheie nu poate decripta nimic scris cu cea veche. Aplicația aruncă Illuminate\Contracts\Encryption\DecryptException în log, iar toți clienții OAuth, tokenii API și câmpurile criptate create anterior devin inutilizabile.
Inspectează logul aplicației din interiorul containerului:
docker exec -it firefly_iii_core tail -n 50 /var/www/html/storage/logs/laravel.log
Dacă găsești intrări DecryptException, cauza este aproape sigur o nepotrivire de APP_KEY. Recuperarea este simplă: restaurezi cheia originală în .env și repornești stack-ul. Nu există utilitar automat de recriptare. Odată schimbată cheia după ce datele au fost scrise, fără cheia originală accesul la tot ce era criptat este pierdut definitiv.
Valoarea STATIC_CRON_TOKEN merge atât în comanda containerului cron, cât și în .env. Generează-o în același mod ca APP_KEY și las-o neschimbată la actualizări din același motiv.
Pornirea stack-ului și verificarea stării
Pornește toate containerele:
docker compose up -d --pull=always
Urmărește logurile aplicației până la finalizarea inițializării:
docker compose logs -f app
La prima rulare, Firefly III execută automat migrațiile bazei de date. Pe un plan vm.Entry sau ct.Ready, procesul se termină de obicei în 60-90 de secunde. Linia Thank you for installing Firefly III din log confirmă că aplicația este gata. Verifică APP_KEY-ul și conexiunea la baza de date cu:
docker exec firefly_iii_core php artisan firefly-iii:decrypt-all
Dacă această comandă se termină fără erori, stack-ul funcționează corect.
Proxy-ul invers Nginx
Instalează Nginx pe gazdă dacă nu rulează deja:
apt install nginx -y
Creează un bloc de server la /etc/nginx/sites-available/firefly:
server {
listen 80;
server_name finance.domeniultau.ro;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name finance.domeniultau.ro;
ssl_certificate /etc/letsencrypt/live/finance.domeniultau.ro/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/finance.domeniultau.ro/privkey.pem;
client_max_body_size 64M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Activează site-ul și obține un certificat Let's Encrypt:
ln -s /etc/nginx/sites-available/firefly /etc/nginx/sites-enabled/
apt install certbot python3-certbot-nginx -y
certbot --nginx -d finance.domeniultau.ro
nginx -t && systemctl reload nginx
Directiva client_max_body_size 64M este obligatorie dacă imporți fișiere CSV mari. Fără ea, Nginx respinge orice fișier care depășește limita implicită de 1 MB cu o eroare 413. Firefly III nu afișează niciun mesaj explicit în interfață când se întâmplă asta — cererea eșuează silențios și importul nu pornește niciodată. Dacă pe același server rulează un stack DirectAdmin sau cPanel cu Nginx ca front-end, adaugă configurarea proxy la virtual host-ul relevant, nu crea o instanță Nginx separată.
Adăugarea Data Importer
Data Importer este un container separat, întreținut de proiectul Firefly III. Citește fișiere CSV sau se conectează la API-uri bancare compatibile prin GoCardless și trimite tranzacțiile procesate în Firefly III prin REST API. Cel mai simplu pe un singur VPS este să-l adaugi ca serviciu suplimentar în același fișier compose.
Adaugă blocul importer în docker-compose.yml:
importer:
image: fireflyiii/data-importer:latest
hostname: importer
container_name: firefly_iii_importer
restart: always
networks:
- firefly_iii
ports:
- "127.0.0.1:8081:8080"
env_file: .importer.env
depends_on:
- app
Creează .importer.env cu cele două variabile obligatorii:
# .importer.env
FIREFLY_III_URL=http://app:8080
VANITY_URL=https://finance.domeniultau.ro
TZ=Europe/Bucharest
FIREFLY_III_URL trebuie să fie adresa internă din rețeaua bridge Docker, nu domeniul tău public. Importerul comunică cu containerul Firefly III direct, pe rețeaua partajată firefly_iii, folosind hostname-ul intern app și portul 8080. Dacă pui aici domeniul public, importerul va eșua la rezolvarea DNS din interiorul rețelei. VANITY_URL este adresa publică pe care importerul o folosește în propria interfață pentru a genera linkuri de redirecționare corecte.
Crearea clientului OAuth
Repornește stack-ul cu docker compose up -d, deschide Firefly III în browser și intră în pagina de profil. Mergi la secțiunea OAuth și creează un client nou:
- Nume: Data Importer (sau orice altă denumire descriptivă)
- URL de redirect:
https://finance.domeniultau.ro/callback - Debifează „Confidential"
Notează ID-ul generat, un număr întreg mic, de obicei 1 sau 2. Îl vei introduce prima dată când accesezi interfața importerului. Adaugă un bloc proxy Nginx pentru importer, fie pe un subdomeniu separat, fie ca locație pe același server cu Firefly III:
server {
listen 443 ssl;
server_name importer.domeniultau.ro;
ssl_certificate /etc/letsencrypt/live/importer.domeniultau.ro/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/importer.domeniultau.ro/privkey.pem;
client_max_body_size 64M;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Primul import CSV din bancă
Aproape toate băncile oferă export CSV din secțiunea de istoric al tranzacțiilor din portalul online. Structura coloanelor diferă de la o instituție la alta, dar Data Importer gestionează asta printr-un pas de mapare la primul import. Asociezi coloanele CSV cu câmpurile Firefly III (dată, sumă, descriere, IBAN), salvezi configurarea ca fișier JSON, și de atunci orice import din aceeași bancă reutilizează acel JSON. Procesul devine: selectezi CSV-ul, selectezi configurarea salvată, apeși import.
Importerul îți arată o previzualizare a tranzacțiilor procesate înainte de a le trimite în baza de date. Verifică acolo că datele sunt parsate corect și că direcția debit/credit este gestionată cum trebuie pentru formatul băncii tale. Unele bănci exportă sumele cu o coloană separată debit/credit în loc de valori cu semn, iar mapper-ul gestionează ambele variante.
Pentru echipele care urmăresc cheltuielile de afaceri pe un VPS administrat, REST API-ul Firefly III acceptă și tranzacții trimise direct. Poți construi fluxuri de import automatizate cu n8n sau un script cron care postează datele la endpoint-ul API, eliminând complet pasul manual CSV pentru conturile care suportă export programatic. Dacă ai nevoie de ajutor la configurarea containerelor Docker sau a proxy-ului invers pe un server nou, serviciul de administrare Linux al ServerSpan acoperă exact acest tip de implementare.
Rularea Firefly III alături de alte servicii self-hosted pe același VPS necesită o alocare atentă a memoriei și o gestionare corectă a rețelelor Docker. Dacă preferi să te ocupi de aplicație și să lași infrastructura pe mâini bune, hosting-ul VPS administrat al ServerSpan vine cu Docker pre-configurat, acces SSH root, stocare NVMe SSD și suport tehnic pentru implementări. Consultă planurile disponibile și locațiile din Germania, Canada și SUA.
Pentru un ghid practic despre gestionarea containerelor și limitele de resurse Docker pe un VPS, consultă articolul nostru despre cele mai bune practici pentru containere Docker pe VPS. Dacă dimensionezi un VPS nou pentru mai multe aplicații self-hosted, ghidul nostru despre swap Linux vs. RAM pentru gestionarea memoriei pe VPS explică cum să configurezi swap-ul drept plasă de siguranță pentru sarcinile cu consum variabil de memorie.
Sursă și Atribuire
Aceast articol se bazează pe date originale ale serverspan.com. Pentru metodologia completă și pentru a asigura integritatea datelor, articolul original trebuie citat. Sursa canonică este disponibilă la: Firefly III pe un VPS: fii stăpân pe datele tale financiare înainte ca banca să fie stăpână pe tine.