Docker Deployment¶
Docker is the recommended way to self-host TradeTally.
This deployment path now matches the actual files in the main repository:
docker-compose.yaml.env.examplescripts/quick-deploy.sh
Quick Start¶
Fastest Path¶
The script:
- creates
.envfrom.env.exampleif needed - prompts for the important deployment values
- generates secrets when you leave them blank
- starts the containers with Docker Compose
By default, TradeTally starts at http://localhost:8080.
Manual Setup¶
If you want to configure things yourself instead of using the script:
Update the important values in .env:
APP_PORT=8080
DB_PASSWORD=change_this_database_password
JWT_SECRET=change_this_to_a_long_random_string
BROKER_ENCRYPTION_KEY=generate_with_openssl_rand_hex_32
INSTANCE_NAME=TradeTally
INSTANCE_URL=http://localhost:8080
FRONTEND_URL=http://localhost:8080
CORS_ORIGINS=http://localhost:8080
API_BASE_URL=http://localhost:8080/api
REGISTRATION_MODE=open
Then start the stack:
Prerequisites¶
- Docker Engine 20.10+
- Docker Compose v2
- 2 GB+ RAM available
- 10 GB+ free disk space
What the Official Compose File Includes¶
The shipped docker-compose.yaml starts:
postgreson PostgreSQL 16appusingpotentialmidas/tradetally:latest
The web UI is exposed on:
http://localhost:${APP_PORT}whereAPP_PORTdefaults to8080
The backend API is reached through the same web port under /api.
Required Settings¶
Always Set¶
DB_PASSWORDJWT_SECRETINSTANCE_URLFRONTEND_URLCORS_ORIGINS
Required for Broker Sync¶
BROKER_ENCRYPTION_KEY
Required for Schwab Sync¶
SCHWAB_CLIENT_IDSCHWAB_CLIENT_SECRETSCHWAB_REDIRECT_URI
The quick deploy script generates BROKER_ENCRYPTION_KEY automatically unless you provide one.
Common Commands¶
Start¶
Stop¶
View Logs¶
Restart¶
Update to the Latest Image¶
Data Persistence¶
The official compose file persists data with Docker volumes:
postgres_data- PostgreSQL dataapp_uploads- trade images, diary images, avatarsapp_data- backup JSON files and other runtime dataapp_logs- application logs
Because these volumes are already part of the official compose file, you do not need to add manual bind mounts just to preserve uploads.
Health Check¶
Expected response:
Reverse Proxy / HTTPS¶
If you are putting TradeTally behind Nginx, Caddy, or Traefik:
- Set
INSTANCE_URLandFRONTEND_URLto your publichttps://URL. - Set
CORS_ORIGINSto that same public URL. - Set
API_BASE_URLtohttps://your-domain.com/api. - Set
TRUST_PROXY=1.
The quick deploy script does this automatically when you enter an https:// public URL.
Troubleshooting¶
Port Already in Use¶
Change APP_PORT in .env, then restart:
Database Container Is Healthy but App Fails¶
Check application logs:
The most common causes are:
JWT_SECRETwas left at an unsafe placeholderDB_PASSWORDdoes not match the database containerFRONTEND_URL/CORS_ORIGINSdo not match the actual public URL
Broker Sync Fails Immediately¶
Make sure BROKER_ENCRYPTION_KEY is set. Broker sync will not work without it.