Self-hosted personal finance manager
Table of Contents
Overview
This post is about self-hosting the personal finance manager app firefly-iii. The prerequisites are:
- a running server
- with a domain such as peterpf.dev
- installed docker and certbot.
Install firefly
Some of the following steps are an excerpt from the documentation available at docs.firefly-iii.org:
Set up env variables
Firefly is configurable via a .env
file.
Download the basic configuration from the official github repository and store it as firefly.env
in your server’s workspace folder (where you want to have all files for docker and firefly).
Create a docker-compose.yml
file
We will use docker-compose to manage all the services required by firefly. The tutorial from the firefly docs provides and example docker-compose.yml. Here is my modified version:
version: "3.3"
services:
firefly-app:
image: fireflyiii/core:latest
restart: always
volumes:
- firefly_iii_upload:/var/www/html/storage/upload
env_file: firefly.env
ports:
- 8080:8080
depends_on:
- fireflydb
firefly-db:
image: mariadb
hostname: fireflyiiidb
restart: always
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_USER=firefly
- MYSQL_PASSWORD=INSERT_YOUR_SECURE_PASSWORD_HERE
- MYSQL_DATABASE=firefly
volumes:
- firefly_iii_db:/var/lib/mysql
volumes:
firefly_iii_upload:
firefly_iii_db:
The values you need to adapt are:
- the
port
and - the
password
for the database.
Start up everything with
docker-compose up -d firefly-app firefly-db
Check the status of the containers with
docker ps
which should show a similar output to
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
582fa3bee42f fireflyiii/core:latest "/usr/local/bin/entr…" 4 hours ago Up 4 hours (healthy) 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp services_firefly-app_1
443e260b8aec mariadb "docker-entrypoint.s…" 18 hours ago Up 17 hours 3306/tcp services_firefly-db_1
You should be able to access the firefly web interface by visiting http://YOUR_SERVER_IP_ADDRESS:8080/
.
Configure nginx
The goal of this section is to set up nginx with an SSL certificate as a reverse-proxy to host the firefly app.
First, make sure to create a new A Record
for the subdomain you want to host the app on.
It should have the form of sub.yourdomain.com
and point to your server’s IP address.
Create a new server configuration to set up nginx as a reverse-proxy for firefly:
touch /etc/nginx/sites-available/firefly.conf
and populate the file with the following content:
Listing 1: nginx server block configuration.
server {
server_name sub.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
client_max_body_size 64M;
proxy_read_timeout 300s;
}
}
Enable the site by creating a symlink in the sites-enabled
folder:
ln -s /etc/nginx/sites-available/firefly.conf /etc/nginx/sites-enabled/
Create an SSL certificate
Execute
certbot --nginx
and follow the instructions to create a certificate for your server. This step touches the configuration file in Listing 1 and
- extends the old server block with certificate settings,
- and adds a new server block.
server {
server_name sub.yourdomain.com;
location / {
# ...
}
# SSL configuration
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = sub.yourdomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name sub.yourdomain.com;
listen 80;
return 404; # managed by Certbot
}
Restart nginx with new configuration
Check the nginx configuration by running
nginx -t
and, if everything is fine, restart it with
systemctl restart nginx
Firefly should now be available through a secure connection via your subdomain.