Self-Host Ghostfolio: Investment Portfolio Tracker 2026
TL;DR
Ghostfolio (AGPL 3.0, ~4K GitHub stars, TypeScript/Angular) is a privacy-first investment portfolio tracker. Track stocks, ETFs, crypto, and other assets across multiple accounts and currencies — all on your own server. Personal Capital (now Empower) requires linking your brokerage accounts to their cloud; Ghostfolio keeps everything local. Multi-currency support, dividend tracking, benchmark comparison, and a clean UI for understanding your net worth.
Key Takeaways
- Ghostfolio: AGPL 3.0, ~4K stars, TypeScript — investment portfolio tracker
- Multi-currency: Track assets in any currency with automatic conversion
- Data providers: Yahoo Finance, Alpha Vantage, and more for real-time quotes
- Benchmarking: Compare portfolio performance against S&P 500, custom indices
- Dividend tracking: Track dividend income, yield, and reinvestment
- Privacy-first: No brokerage account linking — manual or CSV import only
Part 1: Docker Setup
# docker-compose.yml
services:
ghostfolio:
image: ghostfolio/ghostfolio:latest
container_name: ghostfolio
restart: unless-stopped
ports:
- "3333:3333"
environment:
NODE_ENV: production
HOST: "0.0.0.0"
PORT: 3333
# Database:
DATABASE_URL: "postgresql://ghostfolio:${DB_PASSWORD}@db:5432/ghostfolio"
# Redis:
REDIS_HOST: redis
REDIS_PORT: 6379
# Security:
ACCESS_TOKEN_SALT: "${ACCESS_TOKEN_SALT}" # openssl rand -hex 32
JWT_SECRET_KEY: "${JWT_SECRET}" # openssl rand -hex 32
# Data providers (at least one required):
# Yahoo Finance (free, default):
# No additional config needed
# Alpha Vantage (free tier: 25 req/day):
# ALPHA_VANTAGE_API_KEY: "your-key"
depends_on:
- db
- redis
db:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- ghostfolio_db:/var/lib/postgresql/data
environment:
POSTGRES_USER: ghostfolio
POSTGRES_PASSWORD: "${DB_PASSWORD}"
POSTGRES_DB: ghostfolio
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- ghostfolio_redis:/data
volumes:
ghostfolio_db:
ghostfolio_redis:
echo "DB_PASSWORD=$(openssl rand -base64 24)" >> .env
echo "ACCESS_TOKEN_SALT=$(openssl rand -hex 32)" >> .env
echo "JWT_SECRET=$(openssl rand -hex 32)" >> .env
docker compose up -d
Visit http://your-server:3333 → create your account.
Part 2: HTTPS with Caddy
portfolio.yourdomain.com {
reverse_proxy localhost:3333
}
Part 3: Adding Accounts and Holdings
Create accounts
Accounts represent your brokerage, bank, or crypto accounts:
- Accounts → + Add Account
- Name:
Fidelity,Vanguard,Coinbase,401k - Platform: select or create
- Currency: USD, EUR, GBP, etc.
Add holdings
- Portfolio → + Add Activity
- Activity type: Buy / Sell / Dividend
- Search for asset:
AAPL,VTI,BTC - Fill in:
- Date: purchase date
- Quantity: number of shares/units
- Unit price: price per share at purchase
- Fee: transaction fee
- Account: which account
- Save
Supported asset types
| Type | Examples |
|---|---|
| Stocks | AAPL, MSFT, GOOGL |
| ETFs | VTI, VOO, QQQ, VT |
| Crypto | BTC, ETH, SOL |
| Mutual Funds | VTSAX, FXAIX |
| Bonds | Treasury, Corporate |
| Precious Metals | Gold, Silver |
| Cash | Savings accounts, CDs |
Part 4: Portfolio Dashboard
Overview
The dashboard shows:
- Total net worth: Sum of all accounts
- Performance: Absolute and percentage returns
- Allocation: By asset class, region, sector, account
- Holdings table: Each position with current value, gain/loss, weight
Performance chart
- Time-weighted return vs money-weighted return
- Compare against benchmarks (S&P 500, total market)
- Filter by: 1M, 3M, 6M, YTD, 1Y, 5Y, Max
Allocation view
- By asset class: Stocks vs bonds vs crypto vs cash
- By region: US, Europe, Emerging Markets
- By sector: Technology, Healthcare, Finance, etc.
- By account: Distribution across brokerages
- By currency: USD, EUR, etc.
Part 5: Import Transactions
CSV import
Date,Type,Symbol,Quantity,Price,Fee,Currency,Account
2025-01-15,BUY,VTI,50,245.30,0,USD,Vanguard
2025-02-01,BUY,AAPL,10,180.50,4.95,USD,Fidelity
2025-03-01,DIVIDEND,VTI,,125.00,0,USD,Vanguard
2025-06-15,SELL,AAPL,5,195.20,4.95,USD,Fidelity
Portfolio → Import → CSV → upload file → map columns → import.
Manual entry tips
- Enter transactions in chronological order
- Include dividends for accurate total return
- Record fees for true cost basis
- Use the correct currency for each transaction
Part 6: Benchmarking
Compare your portfolio performance against indices:
- Settings → Benchmarks
- Add:
SPY(S&P 500),VT(Total World), custom index - Dashboard → toggle benchmark overlay on performance chart
Example insights
Your portfolio: +12.3% YTD
S&P 500 (SPY): +15.1% YTD
Difference: -2.8% (underperforming)
Part 7: Dividend Tracking
Log dividends
- + Add Activity → Dividend
- Symbol:
VTI - Amount: total dividend received
- Date: ex-dividend date
- Account: receiving account
Dividend dashboard
Shows:
- Dividend income by month/year: bar chart of passive income
- Dividend yield: weighted yield across portfolio
- Top dividend payers: which holdings contribute most
Part 8: Multi-User and Security
Additional users
Admin → User Management → Invite:
Email: partner@example.com
Role: User
Each user has their own private portfolio — no data shared between users.
Security practices
- No brokerage linking: Ghostfolio never has access to your actual accounts
- Self-hosted: Data stays on your server
- Manual entry: You control exactly what data is stored
- Encryption: Use HTTPS and encrypted database backups
Maintenance
# Update:
docker compose pull
docker compose up -d
# Backup database:
docker exec ghostfolio-db-1 pg_dump -U ghostfolio ghostfolio \
| gzip > ghostfolio-db-$(date +%Y%m%d).sql.gz
# Logs:
docker compose logs -f ghostfolio
See also: Actual Budget — for budgeting and expense tracking
See all open source finance tools at OSSAlt.com/categories/finance.