VPS Deployment with Docker Compose
This guide walks you through deploying Fystack on a VPS (e.g., DigitalOcean, Linode, Hetzner, AWS EC2) using Docker Compose.
Overview
A VPS deployment differs from local development in several key ways:
| Aspect | Local | VPS |
|---|---|---|
| Access | localhost | Public domain name |
| HTTPS | Not needed | Required for cookies |
| Reverse Proxy | Not needed | Required (nginx) |
| API_BASE_URL | http://localhost:8150 | https://api.yourdomain.com |
| CORS | http://localhost:8015 | https://app.yourdomain.com |
| Ports | Bound to 127.0.0.1 | Behind reverse proxy, NOT exposed |
Prerequisites
- A VPS with at least 4 vCPU and 4 GB RAM
- A domain name with DNS configured (e.g.,
app.yourdomain.comandapi.yourdomain.com) - SSH access to the VPS
- Docker and Docker Compose installed on the VPS
- All general prerequisites met
Step 1: DNS Setup
Create two DNS A records pointing to your VPS IP address:
| Type | Name | Value |
|---|---|---|
| A | app.yourdomain.com | YOUR_VPS_IP |
| A | api.yourdomain.com | YOUR_VPS_IP |
Wait for DNS propagation (usually a few minutes).
Step 2: Clone and Configure
SSH into your VPS and follow the initial setup:
ssh user@YOUR_VPS_IP
# Clone the repository
git clone git@github.com:fystack/fystack-selfhost-scripts.git
cd fystack-selfhost-scripts
# Docker login
docker login -u fystacklabs
# Copy config templates
cp ./dev/config.yaml.template ./dev/config.yaml
cp ./dev/config.rescanner.yaml.template ./dev/config.rescanner.yaml
cp ./dev/config.indexer.yaml.template ./dev/config.indexer.yaml
Step 3: Configure for VPS
Edit ./dev/config.yaml with the following changes:
Set CoinMarketCap API Key (mandatory)
price_providers:
coinmarketcap:
api_key: "your-coinmarketcap-api-key"
Update App URLs
app:
root_url: https://app.yourdomain.com
sign_in_url: https://app.yourdomain.com/auth
sign_up_url: https://app.yourdomain.com/auth/sign-up
workspace_url: https://app.yourdomain.com/auth/workspace
checkout_url: https://app.yourdomain.com/checkout
reset_url: https://app.yourdomain.com/auth/reset-password
email_verification_url: https://app.yourdomain.com/auth/verify-email
cli_auth_url: https://app.yourdomain.com/auth/cli
Update CORS
cors:
allow_origins: https://app.yourdomain.com
The allow_origins value must exactly match the URL where your Fystack UI is accessible, including the protocol (https://). A mismatch causes CSRF cookie errors.
Update Cookie Settings
For most setups (same domain or subdomains like app.yourdomain.com + api.yourdomain.com), keep the default:
cookie:
same_site: strict
Only change to none if your frontend and API are on completely different root domains (e.g., myapp.com and api.otherdomain.com):
cookie:
same_site: none # Requires HTTPS on both frontend and API
Update OAuth Callback (if using Google OAuth)
oauth2:
google:
callback_url: "https://api.yourdomain.com/api/v1/authentication/google/callback"
Step 4: Set API_BASE_URL
The Fystack UI needs to know where the API is. Set this before running the start script:
Option 1: Environment variable
export API_BASE_URL=https://api.yourdomain.com
Option 2: .env file
echo "API_BASE_URL=https://api.yourdomain.com" > dev/.env
Step 5: Start Fystack
chmod +x ./fystack-ignite.sh
./fystack-ignite.sh
Step 6: Set Up Reverse Proxy
At this point, Fystack is running but only accessible from localhost on the VPS. You need a reverse proxy to expose it securely.
See the Reverse Proxy guide for complete nginx + SSL setup.
Step 7: Verify
After setting up the reverse proxy:
- Open
https://app.yourdomain.comin your browser - Create an account and sign in
- Create a wallet to verify MPC key generation
Updating the API URL Later
If you need to change the API URL after initial setup:
export API_BASE_URL=https://new-api-domain.com
docker compose -f ./dev/docker-compose.yaml up -d --force-recreate fystack-ui-community
This recreates only the UI container. No other services are affected.
Updating Docker Images
To update a specific component to a new version:
cd dev
docker compose pull apex
docker compose up -d --no-deps --force-recreate apex
Replace apex with the service you want to update (e.g., multichain-indexer, rescanner, fystack-ui-community).
Security Considerations
- Never expose database ports (5433, 6380, 27018) to the public internet. The default Docker Compose binds them to
127.0.0.1, which is correct. - Change default passwords in
config.yamlfor production (PostgreSQL, Redis, MongoDB). - Back up your encryption key — it's used to encrypt sensitive data. If lost, that data is unrecoverable.
- Back up MPC node data — the BadgerDB volumes contain key shares. See the backup section.
- Use HTTPS — required for secure cookie handling and to prevent credential interception.
Next Steps
- Reverse Proxy Setup — nginx + SSL configuration (required)
- Troubleshooting — Common VPS deployment issues