Self-Host Firefly III: Your Own Private Budget App
Many hosted budgeting services ask you to place detailed financial records on infrastructure controlled by another company. Firefly III is a free, open-source, double-entry personal finance manager that can run on hardware you control. Self-hosting gives you direct control over the application database, uploaded files, backups, updates, and optional integrations. This guide covers a Docker Compose installation, safe reverse-proxy settings, and remote access through a Localtonet HTTP tunnel without inbound router port forwarding.
Why Self-Host Financial Software?
A hosted budgeting application can be convenient, particularly when it includes automatic bank synchronization. It also means that account names, balances, transaction descriptions, categories, and spending history are stored on infrastructure governed by the provider's pricing, retention, and security policies.
With Firefly III, the primary application database and uploaded files remain on the server you operate. You decide when to update the software, where to store backups, whether to enable optional integrations, and how the service can be reached. That control comes with responsibility: you must install security updates, protect credentials, monitor storage, and verify that backups can actually be restored.
Self-hosting improves control, but it is not an automatic guarantee of privacy or security. Review Firefly III's current telemetry settings and any optional data import, exchange-rate, email, or other external integrations before assuming the server makes no outbound requests.
What Is Firefly III?
Firefly III is a free, open-source personal finance manager maintained by James Cole and contributors under the GNU Affero General Public License version 3. Its accounting model represents transactions as movements between source and destination accounts. This supports consistent balance calculations and more detailed financial reports than a simple list of expenses.
Confirm that every selected container image publishes a build for your device's exact architecture. ARM64 and older 32-bit ARM systems do not have identical image availability. PostgreSQL is used in this example, but compatibility still depends on the tags and hardware architecture you select.
Install Firefly III With Docker Compose
This example binds Firefly III to the Docker host's loopback interface. That keeps port 8080 from being exposed directly on every LAN or public interface while still allowing a Localtonet client running on the same host to reach it. Replace all placeholder credentials, restrict access to the environment file, and compare the example with the current Firefly III Docker documentation before deployment.
Create a working directory and generate an APP_KEY
Firefly III requires an application encryption key. Generate a random 32-character value and keep it secret. Changing this value after deployment can invalidate encrypted application data.
mkdir firefly-iii && cd firefly-iii
head /dev/urandom | LC_ALL=C tr -dc A-Za-z0-9 | head -c 32; echo
Create a protected environment file
Insert the generated key and a separate random database password. Start with a local APP_URL for local testing. After Localtonet assigns the public HTTPS address, update APP_URL to that exact address and recreate the application container.
APP_KEY=replace_with_generated_32_character_key
DB_PASSWORD=replace_with_a_long_random_database_password
APP_URL=http://localhost:8080
chmod 600 .env
Create docker-compose.yml
services:
app:
image: fireflyiii/core:latest
restart: unless-stopped
depends_on:
- db
environment:
APP_KEY: ${APP_KEY}
DB_CONNECTION: pgsql
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: firefly
DB_USERNAME: firefly
DB_PASSWORD: ${DB_PASSWORD}
APP_URL: ${APP_URL}
TRUSTED_PROXIES: "**"
volumes:
- firefly_upload:/var/www/html/storage/upload
ports:
- "127.0.0.1:8080:8080"
db:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: firefly
POSTGRES_USER: firefly
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- firefly_db:/var/lib/postgresql/data
volumes:
firefly_upload:
firefly_db:
For a production deployment, consider pinning both images to versions you have tested rather than following a moving latest tag. Review release notes and create a backup before upgrading.
Start the stack and inspect its status
docker compose up -d
docker compose ps
docker compose logs --tail=100 app
Do not continue until the application and database are running without repeated startup errors.
Open Firefly III locally
On the Docker host, visit http://localhost:8080, create the initial user account, and configure your first asset, expense, revenue, or cash accounts as appropriate.
TRUSTED_PROXIES=** tells Firefly III to trust forwarded headers from any proxy. This can be appropriate when the application is reachable only through a controlled proxy path, but it is unsafe to combine with an unrestricted direct application port. The loopback-only port binding above reduces that risk. If the Localtonet client runs on another device, use a restricted private address and firewall rules rather than exposing port 8080 to the public internet.
Remote Access With Localtonet
Localtonet exposes a service through an outbound connection from its client to a relay server. This avoids inbound router port forwarding, firewall changes, VPN setup, and the need for a public IP address. The tunnel works only while the selected Localtonet client is connected and the tunnel is running.
Install and run the Localtonet client
Install the current Localtonet client on the Docker host, or on another device that can securely reach the Firefly III host. Follow the current dashboard or documentation for operating-system-specific installation instructions.
Select the correct device token
In the Localtonet dashboard, select the device-specific AuthToken associated with the client that can reach Firefly III. Treat this token as a secret and never place it in an article, screenshot, public repository, or shared command history.
Select an available relay server
Choose a currently available relay server or region from the dashboard. Availability can vary, so do not copy a hardcoded server code from an old tutorial.
Create an HTTP tunnel to Firefly III
Set the local target to 127.0.0.1 and port 8080 when the Localtonet client runs on the Docker host. If it runs elsewhere, use a private address that is reachable from that client and protected by host or network firewall rules.
Choose the public address type
Select Random Sub Domain, Custom Sub Domain, or Custom Domain according to the options currently available to your account. All three process types serve the HTTP tunnel at a public HTTPS address. Check the current Localtonet documentation before making custom-domain DNS changes.
Start the tunnel and update APP_URL
Creating a tunnel does not start it. Press Start, copy the assigned public HTTPS address, place that exact address in APP_URL, and recreate the application container.
docker compose up -d --force-recreate app
Firefly III uses APP_URL when generating URLs and handling requests. A mismatch between the configured address and the real public HTTPS address can cause incorrect links, redirects, cookies, or form behavior. Trusting proxy headers is also security-sensitive. Keep the direct application port private, use the exact public URL, and consult the current Firefly III reverse-proxy documentation if the deployment includes additional proxy layers.
๐ Securing Your Financial Data
๐ Keep Firefly III authentication enabled
Do not expose an account without a strong, unique password. If the current Localtonet dashboard or your own access gateway provides additional authentication, IP restrictions, or access-control options, apply them using least privilege. Verify compatibility with the Firefly III API and Data Importer before placing an extra interactive login screen in front of the application.
๐ Enable multi-factor authentication
Firefly III supports multi-factor authentication. Enable it for each user account and store recovery material securely. An extra factor reduces the impact of a compromised password, but it does not replace software updates or secure host configuration.
๐งฑ Keep the origin private
The example publishes port 8080 only on 127.0.0.1. This prevents a remote user from bypassing the tunnel and reaching Firefly III directly through the Docker host's network interface. If a separate Localtonet device must connect over a LAN, permit only that private source where practical.
๐ Patch intentionally
Monitor Firefly III, PostgreSQL, Docker, and host operating-system security updates. Back up first, read release notes, and test upgrades. A self-hosted application does not receive maintenance unless you perform it.
๐พ Back up the database and uploaded files
Transaction records and application configuration are stored in PostgreSQL, while uploaded attachments are stored in the upload volume. Back up both firefly_db and firefly_upload, encrypt off-host copies, and perform periodic restore tests. A backup that has never been restored is not yet a verified recovery plan.
Importing Your Bank Data
Firefly III's separate Data Importer can import supported file formats, including CSV and CAMT.053, and can work with supported third-party financial-data providers when explicitly configured. Provider names, regional availability, authentication requirements, and capabilities can change, so consult the current Data Importer documentation before choosing an automated connection.
Using a third-party provider means relevant financial or authentication data is processed outside your Firefly III server under that provider's terms. Manual file import provides a different privacy and convenience trade-off. In either case, review an import configuration with a small sample before processing years of records, and use duplicate-detection options supported by the importer.
Keep the Deployment Recoverable
The Compose services use restart: unless-stopped, which asks Docker to restart them after a daemon or machine restart unless an administrator intentionally stopped them. Docker itself must also be configured to start with the operating system. This setting does not guarantee application availability if the database is corrupt, the disk is full, or an upgrade fails.
Localtonet tunnels are available only while the selected client is connected and the tunnel is running. Use the current Localtonet client documentation for background-service installation on your operating system. Do not copy undocumented service commands or expose an AuthToken in shell history. After every reboot, verify both the Firefly III application and the public tunnel rather than assuming they recovered.
Firefly III vs. Hosted Budgeting Apps
| Feature | Hosted budgeting service | Self-hosted Firefly III |
|---|---|---|
| Software cost | May be free, subscription-based, or bundled with another service | Open-source software under AGPLv3; hosting and maintenance still have costs |
| Primary data location | Provider-controlled infrastructure | Your database and upload storage, subject to any integrations you enable |
| Accounting model | Varies by product | Double-entry transaction model |
| Bank connections | Often integrated into the service | Separate Data Importer using supported files or configured providers |
| Operations | Handled primarily by the provider | You handle updates, backups, access control, monitoring, and recovery |
The trade-off is straightforward. A hosted service may provide easier onboarding and integrated bank synchronization. Firefly III gives you greater control over storage, accounting workflows, retention, and integrations, but requires ongoing system administration. Neither model is automatically appropriate for every user.
๐ Tips for Getting the Most Out of Firefly III
Troubleshooting Common Issues
| Symptom | Likely cause | Fix |
|---|---|---|
| No application encryption key has been specified | APP_KEY is missing or not being loaded | Check the protected .env file, generate a valid key, and recreate the application container |
| Redirects or forms behave incorrectly through the tunnel | APP_URL does not match the public HTTPS address, or proxy headers are not handled correctly | Set the exact public URL, keep the origin private, and review the current reverse-proxy documentation |
| Database connection fails on startup | Credentials differ between services, PostgreSQL is not ready, or the database volume has a problem | Compare the environment values, inspect both service logs, and do not delete the database volume as a first troubleshooting step |
| The container image does not start on an ARM device | The selected image tag may not support that architecture | Check the image manifest and use a supported tag or a supported operating-system architecture |
| The local site works but the public URL does not | The Localtonet client is disconnected, the tunnel is stopped, or the local target is wrong | Confirm the selected device is connected, press Start for the tunnel, and test the target from the client device |
| Attachments are missing after a restore | Only PostgreSQL was backed up | Restore the Firefly III upload volume together with the matching database backup |
Frequently Asked Questions
Does Firefly III connect to my bank automatically?
Not through the core application alone. The separate Firefly III Data Importer handles supported files and optional financial-data providers. Automated provider access must be explicitly configured and may have regional or provider-specific requirements.
Is Firefly III free?
Firefly III is open-source software licensed under AGPLv3. You may still incur costs for hardware, electricity, storage, domain registration, backups, or optional third-party services.
Can I access it from my phone?
Yes. Once the HTTP tunnel is running, you can open its public HTTPS address in a phone browser. Keep Firefly III authentication and multi-factor authentication enabled, and stop the tunnel when remote access is not required.
Why does Firefly III need trusted-proxy configuration?
A proxy or tunnel can communicate the original scheme, host, and client details through forwarded headers. Firefly III must handle those headers correctly to generate HTTPS links and secure cookies. Trusting every sender is risky, so the direct application port should remain private.
Does self-hosting mean no data ever leaves my server?
No. Your primary database and uploaded files can remain on your server, but telemetry settings and optional imports, email, exchange-rate services, maps, or other integrations may involve outbound communication. Review the current configuration and privacy implications of every enabled integration.
Can multiple people use one Firefly III instance?
Firefly III supports multiple users and financial administrations. Review the current administration and access model before using one installation for people who should not be able to see one another's financial records.
What must I back up?
Back up PostgreSQL and the Firefly III upload volume. Also retain the deployment configuration securely, but do not place secrets in an unencrypted public repository. Test a complete restore on an isolated system.
Does creating a Localtonet tunnel make it immediately available?
No. Select the correct connected device, configure the local target, and press Start. The tunnel is available only while that client is connected and the tunnel remains running.
Ready to Control Your Financial Server?
Deploy Firefly III, keep its origin private, protect every account with strong authentication, and use a Localtonet HTTP tunnel when you need remote HTTPS access.
Get Started Free โ