This guide details the steps needed to install Firefly-iii (a popular open-source and self-hosted personal finance manager) in a FreeNAS jail (FreeBSD). As a bonus it also details how to extend the base install with the CSV importer tool which allows you to import CSV based data which you exported from your bank account.
The exact versions used for this guide are:
- FreeNAS-11.3-U5
- Firefly-iii v5.4.6
- Firefly CSV importer v2.2.3
Setting up the LEMP stack
First, we’ll be setting up a LEMP (Linux, Nginx, MariaDB, PHP) stack which will serve the Firefly-iii web application.
PHP setup
Execute the following commands to install the necessary PHP modules (first command contains all modules needed by firefly:
pkg install -y php74 php74-bcmath php74-intl php74-curl php74-zip php74-gd php74-xml php74-xml php74-mbstring php74-ldap php74-mysqli php74-pear-MDB2 php74-pear-MDB2_Driver_mysqli php74-fileinfo php74-pdo php74-pdo_mysql php74-session php74-simplexml php74-xmlwriter php74-tok enizer php74-iconv php74-dom php74-json php74-phar php74-filter php74-openssl php74-zlib echo 'php_fpm_enable="YES"' >> /etc/rc.conf service php-fpm start
NGINX install
Install the NGINX web server.
pkg install -y nginx echo 'nginx_enable="YES"' >> /etc/rc.conf service nginx start
This will create the webserver root under ‘/usr/local/www’, which should be owned by www:www. If this is not the case
Database setup
First install the package and add it to the list of startup services so that it automatically runs. Finally start the database.
(Optionally run “service mysql-server start” to improve the security of your database if your using this in a production environment.)
pkg install -y mariadb105-server echo 'mysql_enable="YES"' >> /etc/rc.conf service mysql-server start
Now we can create the database and user (replace #password# with your own selected password)
mysql create database firefly; grant all on firefly.* to firefly@localhost identified by '#password#'; flush privileges; quit
Remember this password as you’ll need to enter it into the configuration file of Firefly-iii.
Installing Firefly III
Composer
We need to install some packages before we can jump into the composer based install of Firefly III.
pkg install -y curl sudo
Note: All steps from here on out are also documented in the official documentation. Some paths have been adjusted to match the FreeBSD folder structure.
Now install composer and verify that the installation is successful by calling the command.
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer composer -v
Change directory to the web root and run the install (replace ‘latest’ with an actual release tag. This guide was created using ‘5.4.6’.).
composer create-project grumpydictator/firefly-iii --no-dev --prefer-dist firefly-iii <latest>
Make sure the permissions are set correctly
sudo chown -R www-data:www-data firefly-iii sudo chmod -R 775 firefly-iii/storage
And then adjust the ‘.env’ file in the ‘firefly-iii’ directory. Make sure to change the following settings:
- SITE_OWNER, set to your email address
- DEFAULT_LANGUAGE, if you want to switch the language used.
- TZ, to set the correct timezone.
- DB_HOST, set to ‘127.0.0.1’
- DB_PASSWORD, set to the password you entered for the ‘firefly’ user while setting up the database before.
- APP_URL, set to the IP or associated DNS name of the jail.
Now we can initialize the database
sudo -u www php artisan migrate:refresh --seed sudo -u www php artisan firefly-iii:upgrade-database sudo -u www php artisan passport:install
Connect NGINX and PHP-FPM
In ‘/usr/local/etc/php-fpm.d/www.conf’. Make sure the following values are set (and are uncommented!)
listen = /var/run/php-fpm.sock; listen.owner = www listen.group = www listen.mode = 0660
In ‘/usr/local/etc/nginx/nginx.conf’ put the following content:
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; gzip on; server { listen 80; server_name localhost; root /usr/local/www/firefly-iii/public; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; index index.php; } # pass the PHP scripts to FastCGI server listening on a UNIX file socket location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } }
Final steps
Run the following commands to make sure all configuration changes have been picked up:
service php-fpm restart service nginx restart
You should now be able to browse to the website, where you will be prompted to create a user account!
Optional: Setup CSV importer
We’ll be using the same jail and LEMP stack to setup the CSV importer. This assumes you have an internal DNS resolving a local domainname to the jail. We’ll be configuring NGINX so that it serves the two tools on separate subdomains:
- firefly-iii on ‘firefly-iii.home’
- csv-importer on ‘csv.firefly-iii.home’
You can of course select a different domain name, but then you need to make sure to adjust the csv-importer .env file NGINX configuration file accordingly (see below).
By separating the tool on another subdomain, we know that the two apps will never conflict.
Start in the ‘/usr/local/www’ folder and use compose to install the CSV importer (again replace <latest> with a release tag. This guide was created using ‘2.2.3’.).
composer create-project firefly-iii/csv-importer --no-dev --prefer-dist csv-importer 2.2.3
Make sure the permissions are set correctly
chown -R www:www csv-importer chmod -R 775 csv-importer/storage/
And then adjust the ‘.env’ file in the ‘csv-importer’ directory. Make sure to change the following settings:
- FIREFLY_III_URI, set to ‘firefly-iii.home’
- Check the docs and determine if you want to hardcode a FIREFLY_III_ACESS_TOKEN or FIREFLY_III_CLIENT_ID.
- TZ, to set the correct timezone.
In ‘/usr/local/etc/nginx/nginx.conf’ put the following content:
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; gzip on; server { # csv-importer on csv.firefly-iii.home subdomain listen 80; server_name csv.*; root /usr/local/www/csv-importer/public; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; index index.php; } # pass the PHP scripts to FastCGI server listening on a UNIX file socket # location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } server { # All other domains (i.e. the main firefly app at firefly-iii.home) listen 80 default_server; server_name _; # Will match all other domains root /usr/local/www/firefly-iii/public; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; index index.php; } # pass the PHP scripts to FastCGI server listening on a UNIX file socket # location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } }
Make sure to adjust the <mylocaldomain.home> to your own domainname.
Go to ‘http://csv.firefly-iii.home’ and you should now be able to access the CSV importer app. After authenticating (if you didn’t set the keys in the configuration file) you should be able to start importing CSV files.
Note: if you get a HTTP 502 Internal server error. Check the latest additions to ‘/var/log/nginx/error.log’ If this states
”80 upstream sent too big header while reading response header from upstream, client: xxx.xxx.xxx.xxx server: csv., request: “GET /callback?code=[…]”
Add the following lines to your nginx.conf file to increase the buffer size:
fastcgi_buffers 16 16k; fastcgi_buffer_size 32k;