Installing Firefly

2 minute read

Firefly

“Firefly III” is a self-hosted financial manager. It can help you keep track of expenses, income, budgets and everything in between. It supports credit cards, shared household accounts and savings accounts. It’s pretty fancy. You should use it to save and organise money.

You can find its website here

Setup

Organizing files

First off we create a directory Firefly on our system.

mkdir Firefly

Inside this directory we create a file named docker-compose.yml

touch docker-compose.yml

Organizing mounts

Firefly will need three main folders :

  • export : to store Firefly exports
  • upload : to store Firefly uploads
  • data : to store the database data
  • db_backup : to store the database backups

Setting up the IP address

I chose to reserve the IP address 10.0.6.2 for Firefly. To do so, I went into my router DHCP dashboard and set a static DHCP address. The rule maps the MAC address 02:42:0A:00:06:02 to the IP address 10.0.6.2 and also sets the hostname to Firefly.

Firefly’s db will be at 10.0.6.3.

Firefly environment file

We create a file firefly_app_env containing the environment variables for Firefly.

# Database configuration
FF_DB_CONNECTION=mysql
FF_DB_HOST=firefly_db
FF_DB_NAME=fireflydb
FF_DB_USER=firefly
FF_DB_PASSWORD=secret_db_password
FF_APP_KEY=base64:ae31489cf678d324e3f=
FF_DB_PORT=3306

# Other configurations
FF_APP_ENV=local
TZ=Europe/Amsterdam
APP_LOG_LEVEL=debug
SITE_OWNER=your@email.com
APP_URL=http://10.0.6.2
LOG_CHANNEL=daily

# Mail configuration
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_FROM=changeme@example.com
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

Database environment file

We create a file firefly_db_env containing the environment variables for Firefly’s database.

MYSQL_ROOT_PASSWORD=secret_root_password
MYSQL_DATABASE=fireflydb
MYSQL_USER=firefly
MYSQL_PASSWORD=secret_db_password

Docker-compose

Here is the content of the docker-compose file

version: "2.2"
services: 
  firefly_iii_app: 
    container_name: "firefly_app"
    image: "jc5x/firefly-iii:release-4.7.9"
    hostname: "firefly"
    restart: "unless-stopped"
    env_file: firefly_app_env
    networks:
      host-macvlan-net:
        ipv4_address: 10.0.6.2
    ports: 
      - "80:80"
    volumes: 
      - "/home/braincoke/Firefly/export:/var/www/firefly-iii/storage/export"
      - "/home/braincoke/Firefly/upload:/var/www/firefly-iii/storage/upload"
    depends_on:
      - firefly_iii_db
  firefly_iii_db: 
    container_name: "firefly_db"
    image: "mysql:5"
    hostname: "firefly_db"
    restart: "unless-stopped"
    env_file: firefly_db_env
    networks:
      host-macvlan-net:
        ipv4_address: 10.0.6.3
    volumes: 
      - "/home/braincoke/Firefly/data:/var/lib/mysql"
      - "/home/braincoke/Firefly/db_backup:/backup/db"
networks:
  host-macvlan-net:
    external:
      name: host-macvlan-net

Start the container with docker-compose up -d

Database initialization

We need to initialize the database. To do so, we run the following commands :

docker-compose exec firefly_iii_app php artisan migrate --seed
docker-compose exec firefly_iii_app php artisan firefly:upgrade-database
docker-compose exec firefly_iii_app php artisan firefly:verify
docker-compose exec firefly_iii_app php artisan passport:install
docker-compose exec firefly_iii_app php artisan cache:clear

Backup script

#!/bin/zsh
#
#This script backs up the Firefly III data
#It must be executed by the root user to work properly
#
UPLOADS_DIR=/home/braincoke/Firefly/upload
EXPORTS_DIR=/home/braincoke/Firefly/export
DATA_DIR=/home/braincoke/Firefly/data
DB_BACKUP_DIR=/home/braincoke/Firefly/db_backup
SHARED_BACKUP_DIR=/home/braincoke/backup/Firefly
echo -n "Getting Firefly version : "
FIREFLY_VERSION=$(echo -n $(docker exec -it firefly_app sh -c "cat /var/www/firefly-iii/config/firefly.php | grep -E \"^\s+'version'\" | cut -d '>' -f2 | sed -r \"s/[',\n\r\ ]//g\"") | tr -d $"\r")

echo "$FIREFLY_VERSION"
NEW_BACKUP_NAME=$(echo -n "$(date +%s)_$(date -I | tr - _)_$FIREFLY_VERSION")
NEW_BACKUP_DIR="$SHARED_BACKUP_DIR/$NEW_BACKUP_NAME"


# Create a new directory on the shared folder
echo "Creating new directory $NEW_BACKUP_DIR"
mkdir -p $NEW_BACKUP_DIR
# Backup the upload dir
echo "Backing up Firefly uploads..."
cp -r $UPLOADS_DIR $NEW_BACKUP_DIR
# Backup the export dir
echo "Backing up Firefly exports..."
cp -r $EXPORTS_DIR $NEW_BACKUP_DIR
# Backup the data dir
echo "Backing up Firefly data..."
cp -r $DATA_DIR $NEW_BACKUP_DIR
# Backup the db
echo "Backing up Firefly database..."
find $DB_BACKUP_DIR -type f -exec mv -t $NEW_BACKUP_DIR {} \+

# Create tar from backed up directories
echo "Creating tar file"
tar -cvzf "$NEW_BACKUP_DIR.tar" -C "$NEW_BACKUP_DIR" .

rm -r "$NEW_BACKUP_DIR"

echo "Firefly backup finished"