# Firefly III

Personal finance manager for tracking income, expenses and budgets.

- Replaces: [Mint](https://openlogs.fyi/alternatives/mint)
- Summary: Paid budgeting services, such as Mint.
- Stack: PHP (language), MariaDB (database)
- Deployment: docker_compose
- License: AGPL-3.0 (osi) [source](https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/LICENSE)
- Business model: unknown. The README at the pinned commit does not state a business model, so it stays unknown. ([source](https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/readme.md), read 2026-10-22)
- Difficulty: medium. 3 services (1 database or broker: mariadb), 2 volume mounts, 1 env value to set, no elevated host access. Heuristic score 4 of 11: medium.
- Requirements: not stated
- Repository: [firefly-iii/firefly-iii](https://github.com/firefly-iii/firefly-iii)

## Install

1. Docker with the Compose plugin ([source](https://github.com/firefly-iii/docs/blob/7c54c4bd43f9dd5297899ceb9584d8bb047788ef/docs/docs/how-to/firefly-iii/installation/docker.md))

   ```text
   A host with Docker and the Docker Compose plugin. This entry runs from a compose file.
   ```

2. Save the compose file as docker-compose.yml ([source](https://github.com/firefly-iii/docker/blob/841e328345ce10ca8eaebbda4d3a42c628bc0dc2/docker-compose.yml))

   ```yaml
   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:
         - 80: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:
       #
       # To make this work, set STATIC_CRON_TOKEN in your .env file or as an environment variable
       # The STATIC_CRON_TOKEN must be *exactly* 32 characters long
       # Use this URL for inspiration: https://www.random.org/strings/?num=1&len=32&digits=on&upperalpha=on&loweralpha=on&unique=on&format=html&rnd=new
       #
       image: alpine
       restart: always
       container_name: firefly_iii_cron
       env_file: .env
       command: ["sh", "-c", "apk add tzdata && \
         (ln -s /usr/share/zoneinfo/$$TZ /etc/localtime || true) && \
         echo \"0 3 * * * wget -qO- http://app:8080/api/v1/cron/$$STATIC_CRON_TOKEN;echo\" \
         | crontab - && \
         crond -f -L /dev/stdout"]
       networks:
         - firefly_iii
       depends_on:
         - app
   
   volumes:
      firefly_iii_upload:
      firefly_iii_db:
   
   networks:
     firefly_iii:
       driver: bridge
   ```

3. Save as .env next to the compose file ([source](https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/.env.example))

   ```dotenv
   # You can leave this on "local". If you change it to production most console commands will ask for extra confirmation.
   # Never set it to "testing".
   APP_ENV=production
   
   # Set to true if you want to see debug information in error screens.
   APP_DEBUG=false
   
   # This should be your email address.
   # If you use Docker or similar, you can set this variable from a file by using SITE_OWNER_FILE
   # The variable is used in some errors shown to users who aren't admin.
   SITE_OWNER=mail@example.com
   
   # The encryption key for your sessions. Keep this very secure.
   # Change it to a string of exactly 32 chars or use something like `php artisan key:generate` to generate it.
   # If you use Docker or similar, you can set this variable from a file by using APP_KEY_FILE
   #
   # Try to avoid special characters like #, < and > in your app key. This string does not need full entropy
   # When in doubt, follow the link below and pick one.
   #
   # https://www.random.org/strings/?num=5&len=32&digits=on&upperalpha=on&loweralpha=on&unique=on&format=html&rnd=new
   #
   # If you are a fancy linux nerd like me, use this command:
   #
   # head /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32 && echo
   #
   #
   APP_KEY=SomeRandomStringOf32CharsExactly
   
   # Firefly III will launch using this language (for new users and unauthenticated visitors)
   # For a list of available languages: https://github.com/firefly-iii/firefly-iii/blob/main/config/firefly.php#L123
   #
   # If text is still in English, remember that not everything may have been translated.
   DEFAULT_LANGUAGE=en_US
   
   # The locale defines how numbers are formatted.
   # by default this value is the same as whatever the language is.
   DEFAULT_LOCALE=equal
   
   # Change this value to your preferred time zone.
   # Example: Europe/Amsterdam
   # For a list of supported time zones, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
   TZ=Europe/Amsterdam
   
   # TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
   # Set it to ** and reverse proxies work just fine.
   TRUSTED_PROXIES=
   
   # The log channel defines where your log entries go to.
   # Several other options exist. You can use 'single' for one big fat error log (not recommended).
   # Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
   # A rotating log option is 'daily', creates 5 files that (surprise) rotate.
   # A cool option is 'papertrail' for cloud logging
   # Default setting 'stack' will log to 'daily' and to 'stdout' at the same time.
   LOG_CHANNEL=stack
   
   # Log level. You can set this from least severe to most severe:
   # debug, info, notice, warning, error, critical, alert, emergency
   # If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
   # nothing will get logged, ever.
   APP_LOG_LEVEL=notice
   
   # Audit log level.
   # The audit log is used to log notable Firefly III events on a separate channel.
   # These log entries may contain sensitive financial information.
   # The audit log is disabled by default.
   #
   # To enable it, set AUDIT_LOG_LEVEL to "info"
   # To disable it, set AUDIT_LOG_LEVEL to "emergency"
   AUDIT_LOG_LEVEL=emergency
   
   #
   # If you want, you can redirect the audit logs to another channel.
   # Set 'audit_stdout', 'audit_syslog', 'audit_errorlog' to log to the system itself.
   # Use audit_daily to log to a rotating file.
   # Use audit_papertrail to log to papertrail.
   #
   # If you do this, the audit logs may be mixed with normal logs because the settings for these channels
   # are often the same as the settings for the normal logs.
   AUDIT_LOG_CHANNEL=
   
   #
   # Used when logging to papertrail:
   # Also used when audit logs log to papertrail:
   #
   PAPERTRAIL_HOST=
   PAPERTRAIL_PORT=
   
   # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
   # For other database types, please see the FAQ: https://docs.firefly-iii.org/references/faq/install/#i-want-to-use-sqlite
   # If you use Docker or similar, you can set these variables from a file by appending them with _FILE
   # Use "pgsql" for PostgreSQL
   # Use "mysql" for MySQL and MariaDB.
   # Use "sqlite" for SQLite.
   DB_CONNECTION=mysql
   DB_HOST=db
   DB_PORT=3306
   DB_DATABASE=firefly
   DB_USERNAME=firefly
   DB_PASSWORD=secret_firefly_password
   # leave empty or omit when not using a socket connection
   DB_SOCKET=
   
   # MySQL supports SSL. You can configure it here.
   # If you use Docker or similar, you can set these variables from a file by appending them with _FILE
   MYSQL_USE_SSL=false
   MYSQL_SSL_VERIFY_SERVER_CERT=true
   # You need to set at least of these options
   MYSQL_SSL_CAPATH=/etc/ssl/certs/
   MYSQL_SSL_CA=
   MYSQL_SSL_CERT=
   MYSQL_SSL_KEY=
   MYSQL_SSL_CIPHER=
   
   # PostgreSQL supports SSL. You can configure it here.
   # If you use Docker or similar, you can set these variables from a file by appending them with _FILE
   PGSQL_SSL_MODE=prefer
   PGSQL_SSL_ROOT_CERT=null
   PGSQL_SSL_CERT=null
   PGSQL_SSL_KEY=null
   PGSQL_SSL_CRL_FILE=null
   
   # For postgresql 15 and up, setting this to public will no longer work as expected, becasuse the
   # 'public' schema is without grants. This can be worked around by having a super user grant those
   # necessary privileges, but in security conscious setups that's not viable.
   # You will need to set this to the schema you want to use.
   PGSQL_SCHEMA=public
   
   # If you're looking for performance improvements, you could install memcached or redis
   CACHE_STORE=file
   SESSION_DRIVER=file
   
   # If you set either of the options above to 'redis', you might want to update these settings too
   # If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
   # REDIS_PORT_FILE to set the value from a file instead of from an environment variable
   
   # can be tcp or unix. http is not supported
   REDIS_SCHEME=tcp
   
   # use only when using 'unix' for REDIS_SCHEME. Leave empty otherwise.
   REDIS_PATH=
   
   # use only when using 'tcp' or 'http' for REDIS_SCHEME. Leave empty otherwise.
   REDIS_HOST=127.0.0.1
   REDIS_PORT=6379
   
   # Use only with Redis 6+ with proper ACL set. Leave empty otherwise.
   REDIS_USERNAME=
   REDIS_PASSWORD=
   
   # always use quotes and make sure redis db "0" and "1" exists. Otherwise change accordingly.
   REDIS_DB="0"
   REDIS_CACHE_DB="1"
   
   # Cookie settings. Should not be necessary to change these.
   # If you use Docker or similar, you can set COOKIE_DOMAIN_FILE to set
   # the value from a file instead of from an environment variable
   # Setting samesite to "strict" may give you trouble logging in.
   COOKIE_PATH="/"
   COOKIE_DOMAIN=
   COOKIE_SECURE=false
   COOKIE_SAMESITE=lax
   
   # If you want Firefly III to email you, update these settings
   # For instructions, see: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/notifications/#email
   # If you use Docker or similar, you can set these variables from a file by appending them with _FILE
   MAIL_MAILER=log
   MAIL_HOST=null
   MAIL_PORT=2525
   MAIL_FROM=changeme@example.com
   MAIL_USERNAME=null
   MAIL_PASSWORD=null
   MAIL_ENCRYPTION=null
   MAIL_SENDMAIL_COMMAND=
   
   #
   # If you use self-signed certificates for your SMTP server, you can use the following settings.
   #
   MAIL_ALLOW_SELF_SIGNED=false
   MAIL_VERIFY_PEER=true
   MAIL_VERIFY_PEER_NAME=true
   
   # Other mail drivers:
   # If you use Docker or similar, you can set these variables from a file by appending them with _FILE
   MAILGUN_DOMAIN=
   MAILGUN_SECRET=
   
   # If you are on EU region in mailgun, use api.eu.mailgun.net, otherwise use api.mailgun.net
   # If you use Docker or similar, you can set this variable from a file by appending it with _FILE
   MAILGUN_ENDPOINT=api.mailgun.net
   
   # If you use Docker or similar, you can set these variables from a file by appending them with _FILE
   MANDRILL_SECRET=
   SPARKPOST_SECRET=
   MAILERSEND_API_KEY=
   
   # Firefly III can send you the following messages.
   SEND_ERROR_MESSAGE=true
   
   # The map will default to this location:
   MAP_DEFAULT_LAT=51.983333
   MAP_DEFAULT_LONG=5.916667
   MAP_DEFAULT_ZOOM=6
   
   #
   # Firefly III authentication settings
   #
   
   #
   # Firefly III supports a few authentication methods:
   # - 'web' (default, uses built in DB)
   # - 'remote_user_guard' for Authelia etc
   # Read more about these settings in the documentation.
   # https://docs.firefly-iii.org/how-to/firefly-iii/advanced/authentication/
   #
   # LDAP is no longer supported :(
   #
   AUTHENTICATION_GUARD=web
   
   #
   # Remote user guard settings
   #
   AUTHENTICATION_GUARD_HEADER=REMOTE_USER
   AUTHENTICATION_GUARD_EMAIL=
   
   #
   # Firefly III generates a basic keypair for your OAuth tokens.
   # If you want, you can overrule the key with your own (secure) value.
   # It's also possible to set PASSPORT_PUBLIC_KEY_FILE or PASSPORT_PRIVATE_KEY_FILE
   # if you're using Docker secrets or similar solutions for secret management
   #
   PASSPORT_PRIVATE_KEY=
   PASSPORT_PUBLIC_KEY=
   
   #
   # Extra authentication settings
   #
   CUSTOM_LOGOUT_URL=
   
   # You can disable the X-Frame-Options header if it interferes with tools like
   # Organizr. This is at your own risk. Applications running in frames run the risk
   # of leaking information to their parent frame.
   DISABLE_FRAME_HEADER=false
   
   # You can disable the Content Security Policy header when you're using an ancient browser
   # or any version of Microsoft Edge / Internet Explorer (which amounts to the same thing really)
   # This leaves you with the risk of not being able to stop XSS bugs should they ever surface.
   # This is at your own risk.
   DISABLE_CSP_HEADER=false
   
   # If you wish to track your own behavior over Firefly III, set valid analytics tracker information here.
   # Nobody uses this except for me on the demo site. But hey, feel free to use this if you want to.
   # Do not prepend the TRACKER_URL with http:// or https://
   # The only tracker supported is Matomo.
   # You can set the following variables from a file by appending them with _FILE:
   TRACKER_SITE_ID=
   TRACKER_URL=
   
   #
   # The static cron job token can be useful when you use Docker and wish to manage cron jobs.
   # 1. Set this token to any 32-character value (this is important!).
   # 2. Use this token in the cron URL instead of a user's command line token that you can find in /profile
   #
   # For more info: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/cron/
   #
   # You can set this variable from a file by appending it with _FILE
   #
   STATIC_CRON_TOKEN=PLEASE_REPLACE_WITH_32_CHAR_CODE
   
   # You can fine tune the start-up of a Docker container by editing these environment variables.
   # Use this at your own risk. Disabling certain checks and features may result in lots of inconsistent data.
   # However if you know what you're doing you can significantly speed up container start times.
   # Set each value to true to enable, or false to disable.
   
   # Check if the SQLite database exists. Can be skipped if you're not using SQLite.
   # Won't significantly speed up things.
   DKR_CHECK_SQLITE=true
   
   # Leave the following configuration vars as is.
   # Unless you like to tinker and know what you're doing.
   APP_NAME=FireflyIII
   BROADCAST_DRIVER=log
   QUEUE_DRIVER=sync
   CACHE_PREFIX=firefly
   PUSHER_KEY=
   PUSHER_SECRET=
   PUSHER_ID=
   DEMO_USERNAME=
   DEMO_PASSWORD=
   
   #
   # Please make sure this URL matches the external URL of your Firefly III installation.
   # It is used to validate specific requests and to generate URLs in emails.
   #
   APP_URL=http://localhost
   ```

4. Save as .db.env next to the compose file ([source](https://github.com/firefly-iii/docker/blob/841e328345ce10ca8eaebbda4d3a42c628bc0dc2/database.env))

   ```dotenv
   MYSQL_RANDOM_ROOT_PASSWORD=yes
   MYSQL_USER=firefly
   MYSQL_PASSWORD=secret_firefly_password
   MYSQL_DATABASE=firefly
   
   #
   # Remove the environment variables above, and replace them with the following if your using PostgreSQL
   #
   # 
   # POSTGRES_USER=firefly
   # POSTGRES_DB=firefly
   # POSTGRES_PASSWORD=secret_firefly_password
   # POSTGRES_PASSWORD=secret_firefly_password
   ```

5. What the compose file check ran with ([source](https://github.com/firefly-iii/docs/blob/7c54c4bd43f9dd5297899ceb9584d8bb047788ef/docs/docs/how-to/firefly-iii/installation/docker.md))

   ```text
   The compose file check ran together with database.env (saved as .db.env) from the same commit and .env.example from firefly-iii/firefly-iii at commit b9c3100 (saved as .env). The folder held only these files. The installation guide tells the reader to download docker-compose.yml, the Firefly III variables file as .env and database.env as .db.env into one folder, set the passwords and run docker compose up -d.
   ```

6. Start it ([source](https://github.com/firefly-iii/docs/blob/7c54c4bd43f9dd5297899ceb9584d8bb047788ef/docs/docs/how-to/firefly-iii/installation/docker.md))

   ```bash
   docker compose up -d
   ```

7. Open the app ([source](https://github.com/firefly-iii/docker/blob/841e328345ce10ca8eaebbda4d3a42c628bc0dc2/docker-compose.yml))

   ```text
   Open http://localhost:80. The compose file publishes host port 80 for the app service.
   ```

Compose file check: config_ok on 2026-10-22.

## Gotchas and maintenance

### Gotchas

- Some images use the latest tag or no tag: Images without a pinned version: app: fireflyiii/core:latest, cron: alpine (no tag). A later pull can get a different version. ([source](https://github.com/firefly-iii/docker/blob/841e328345ce10ca8eaebbda4d3a42c628bc0dc2/docker-compose.yml), checked 2026-10-22)
- The compose file publishes host ports: Host ports: 80 (app). A port without a host address listens on all host network interfaces. ([source](https://github.com/firefly-iii/docker/blob/841e328345ce10ca8eaebbda4d3a42c628bc0dc2/docker-compose.yml), checked 2026-10-22)
- The example env file .env.example has placeholder values: The example env file sets placeholder text for: MAIL_FROM. Replace them before you rely on the install. ([source](https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/.env.example), checked 2026-10-22)

### Signals

Computed from a GitHub snapshot taken 2026-10-22.

- Open issues and pull requests: 166
- Stars: 24968, forks: 2347
- Last push: 2026-10-21 (1 days ago)
- Latest release: v6.7.9 on 2026-10-11 (11 days ago)

## Sources

- [Repository: https://github.com/firefly-iii/firefly-iii](https://github.com/firefly-iii/firefly-iii)
- [License: https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/LICENSE](https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/LICENSE)
- [Business model: https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/readme.md](https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/readme.md)
- [Compose file: https://github.com/firefly-iii/docker/blob/841e328345ce10ca8eaebbda4d3a42c628bc0dc2/docker-compose.yml](https://github.com/firefly-iii/docker/blob/841e328345ce10ca8eaebbda4d3a42c628bc0dc2/docker-compose.yml)
- [Install step: https://github.com/firefly-iii/docs/blob/7c54c4bd43f9dd5297899ceb9584d8bb047788ef/docs/docs/how-to/firefly-iii/installation/docker.md](https://github.com/firefly-iii/docs/blob/7c54c4bd43f9dd5297899ceb9584d8bb047788ef/docs/docs/how-to/firefly-iii/installation/docker.md)
- [Install step: https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/.env.example](https://github.com/firefly-iii/firefly-iii/blob/b9c31006e8d3008df3d12e23de86b66088c9480e/.env.example)
- [Install step: https://github.com/firefly-iii/docker/blob/841e328345ce10ca8eaebbda4d3a42c628bc0dc2/database.env](https://github.com/firefly-iii/docker/blob/841e328345ce10ca8eaebbda4d3a42c628bc0dc2/database.env)

---
Canonical: https://openlogs.fyi/tools/firefly-iii  
Last updated: 2026-10-22
