Coolify
Deploy Wealthfolio on Coolify, the self-hosted PaaS that handles HTTPS, env vars, persistent storage, and rolling updates with one click.
Coolify is a self-hosted PaaS, think Heroku you run on your own VPS. It handles HTTPS, env vars, persistent storage, and rolling updates, so deploying Wealthfolio is mostly clicks plus a few values to paste in.
Prerequisites
- A Coolify instance (v4 or newer) with a configured server and destination
- A domain pointed at your Coolify server (for HTTPS)
opensslandargon2on any machine for generating secrets
Deploy
Step 1: Create a new resource
In Coolify: + New Resource → Docker Image.
| Field | Value |
|---|---|
| Image | afadil/wealthfolio:latest |
| Port (exposed) | 8088 |
Pin to a specific tag (e.g. afadil/wealthfolio:3.3.0) for production.
Step 2: Set the domain
Under Domains, add the FQDN you want (e.g.
wealthfolio.example.com). Coolify provisions a Let’s Encrypt
certificate automatically through its built-in proxy (Traefik or Caddy).
Step 3: Generate your secrets
On any machine:
# 32-byte secret key. Back this up!
openssl rand -base64 32
# Argon2id password hash for your login
printf 'your-password' | argon2 yoursalt16chars! -id -eStep 4: Set environment variables
Under Environment Variables, add:
| Name | Value | Notes |
|---|---|---|
WF_LISTEN_ADDR | 0.0.0.0:8088 | Required for container networking |
WF_DB_PATH | /data/wealthfolio.db | SQLite database location |
WF_SECRET_KEY | (paste your 32-byte key) | Toggle Is Secret, Coolify masks the value |
WF_AUTH_PASSWORD_HASH | (paste the full $argon2id$... string) | Toggle Is Secret, Coolify handles $ safely |
WF_CORS_ALLOW_ORIGINS | https://wealthfolio.example.com | Must match your domain exactly |
WF_AUTH_TOKEN_TTL_MINUTES | 480 | Optional (8 hours) |
Coolify’s env var UI escapes $ characters correctly when stored as
secrets. Paste the raw Argon2 hash without doubling or quoting.
Step 5: Add persistent storage
Under Storage (or Persistent Volumes), add a mount:
| Field | Value |
|---|---|
| Mount path | /data |
| Type | Volume Mount |
| Volume name | wealthfolio-data |
This holds your SQLite database and encrypted secrets. Without it, all data is lost on container restart.
Step 6: Deploy
Click Deploy. Coolify pulls the image, mounts the volume, sets the env, and starts the container behind its proxy. After ~30 seconds, your domain serves Wealthfolio over HTTPS.
Updating
Coolify auto-fetches new images if you’ve enabled Watchtower /
auto-update; otherwise click Redeploy to pull :latest (or change
the tag). For zero-downtime, enable Rolling Updates in the resource
settings.
Health checks
Wealthfolio exposes a health endpoint at /api/v1/healthz. Configure
Coolify’s healthcheck:
| Field | Value |
|---|---|
| Path | /api/v1/healthz |
| Port | 8088 |
| Interval | 30s |
| Start period | 15s |
Letting Coolify handle authentication
If you use Coolify’s basic auth or front it with Authentik / Authelia, you can disable Wealthfolio’s built-in login:
| Variable | Value |
|---|---|
WF_AUTH_REQUIRED | false |
WF_AUTH_PASSWORD_HASH | (empty) |
Wealthfolio will trust whatever Coolify’s proxy lets through.
Backups
Coolify’s S3 backup integration handles the volume. Point it at your
wealthfolio-data volume and your storage backend.
Back up WF_SECRET_KEY separately from the volume. The encrypted
secrets in /data/secrets.json are useless without the key.
Troubleshooting
| Symptom | Fix |
|---|---|
Container restarts: WF_SECRET_KEY missing | Variable wasn’t saved as a secret. Re-add it under Environment Variables. |
| Login rejects the right password | Hash captured a trailing newline. Regenerate with printf (not echo -n). |
502 Bad Gateway from Coolify proxy | Check WF_LISTEN_ADDR=0.0.0.0:8088 and that the resource port matches. |
| CORS errors in browser console | WF_CORS_ALLOW_ORIGINS must match the domain in your address bar exactly. |
Configuration reference
Every variable Wealthfolio reads is documented in Configuration.