Wallos
Subscription tracker for keeping an eye on recurring bills, with stats, multiple currencies and reminders before things renew.
Finance
Personal finance manager for tracking what comes in and goes out, with budgets, subscriptions, recurring transactions, rules and reports. This one runs on Postgres.
It isn't in the main Portainer Templates list yet, so use this one. Portainer takes one URL at a time, so it swaps out whatever list you had before.
In Portainer, head to Settings --> App Templates, paste this in as the URL and save.
https://raw.githubusercontent.com/NotAFlightRisk/portainer-templates-extras/main/templates.json http://<your-server>:8092 in a browser.The same file Portainer deploys. It reads its settings from a .env next to it.
services:
firefly:
image: fireflyiii/core:version-6
restart: unless-stopped
ports:
- "${FIREFLY_PORT:-8092}:8080"
environment:
APP_KEY: ${FIREFLY_APP_KEY:?Set a 32 character app key}
STATIC_CRON_TOKEN: ${FIREFLY_CRON_TOKEN:?Set a 32 character cron token}
TZ: ${FIREFLY_TZ:-UTC}
TRUSTED_PROXIES: ${FIREFLY_TRUSTED_PROXIES:-}
DB_CONNECTION: pgsql
DB_HOST: postgres
DB_PORT: "5432"
DB_DATABASE: firefly
DB_USERNAME: firefly
DB_PASSWORD: ${FIREFLY_DB_PASSWORD:?Set a database password}
volumes:
- firefly-upload:/var/www/html/storage/upload
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_DB: firefly
POSTGRES_USER: firefly
POSTGRES_PASSWORD: ${FIREFLY_DB_PASSWORD:?Set a database password}
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U firefly -d firefly"]
interval: 10s
timeout: 5s
retries: 5
cron:
image: alpine:3
restart: unless-stopped
environment:
TZ: ${FIREFLY_TZ:-UTC}
STATIC_CRON_TOKEN: ${FIREFLY_CRON_TOKEN:?Set a 32 character cron token}
command: ["sh", "-c", "apk add tzdata && (ln -s /usr/share/zoneinfo/$$TZ /etc/localtime || true) && echo \"0 3 * * * wget -qO- http://firefly:8080/api/v1/cron/$$STATIC_CRON_TOKEN;echo\" | crontab - && crond -f -L /dev/stdout"]
depends_on:
- firefly
volumes:
firefly-upload:
postgres-data:
Fill in the blanks, as Firefly III won't start without them.
# App key (required) - Exactly 32 characters. Generate one with: openssl rand -hex 16. Keep it the same when you redeploy, or everyone's logged out and API tokens stop working.
FIREFLY_APP_KEY=
# Cron token (required) - Exactly 32 characters, and not the same as the app key. Generate one with: openssl rand -hex 16.
FIREFLY_CRON_TOKEN=
# Database password (required) - Generate one with: openssl rand -hex 32. Keep it the same when you redeploy, or Firefly III can't reach its database.
FIREFLY_DB_PASSWORD=
# Host port for the web UI
FIREFLY_PORT=8092
# Timezone - Like Europe/London. Transaction dates and the nightly cron use it.
FIREFLY_TZ=UTC
# Trusted proxies - Leave blank, unless it's behind a reverse proxy. Then set ** so Firefly III trusts the proxy's headers.
FIREFLY_TRUSTED_PROXIES= Grab the file and start it.
mkdir firefly-iii && cd firefly-iii
curl -fsSL -o compose.yml https://raw.githubusercontent.com/NotAFlightRisk/portainer-templates-extras/main/apps/firefly-iii/compose.yml
# save the .env tab here as .env first
docker compose up -d Fill in all three secrets before you deploy, since the stack won't start without them. The app key and cron token must be exactly 32 characters (openssl rand -hex 16 makes one), and keep all three the same when you redeploy. Then open http://<your-host>:8092 (or whichever port you picked) and register. The first account becomes the admin and sign-ups close after it, so do it straight away. A small cron container pings Firefly III at 03:00 every night, which is what creates recurring transactions and fires subscription reminders. Transactions live in Postgres, in the postgres-data volume, and attachments in firefly-upload. Docs: docs.firefly-iii.org
What the Portainer form asks for. With compose they go in the .env file instead.
| Variable | What it's for | Default |
|---|---|---|
FIREFLY_APP_KEY | App key (required) Exactly 32 characters. Generate one with: openssl rand -hex 16. Keep it the same when you redeploy, or everyone's logged out and API tokens stop working. | Needs filling in |
FIREFLY_CRON_TOKEN | Cron token (required) Exactly 32 characters, and not the same as the app key. Generate one with: openssl rand -hex 16. | Needs filling in |
FIREFLY_DB_PASSWORD | Database password (required) Generate one with: openssl rand -hex 32. Keep it the same when you redeploy, or Firefly III can't reach its database. | Needs filling in |
FIREFLY_PORT | Host port for the web UI | 8092 |
FIREFLY_TZ | Timezone Like Europe/London. Transaction dates and the nightly cron use it. | UTC |
FIREFLY_TRUSTED_PROXIES | Trusted proxies Leave blank, unless it's behind a reverse proxy. Then set ** so Firefly III trusts the proxy's headers. | Needs filling in |
The containers this stack runs, with ports as they come out of the box.
| Service | Image | Ports |
|---|---|---|
firefly | fireflyiii/core:version-6 | 8092:8080 |
postgres | postgres:17-alpine | Internal only |
cron | alpine:3 | Internal only |