Skip to main content

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:

AspectLocalVPS
AccesslocalhostPublic domain name
HTTPSNot neededRequired for cookies
Reverse ProxyNot neededRequired (nginx)
API_BASE_URLhttp://localhost:8150https://api.yourdomain.com
CORShttp://localhost:8015https://app.yourdomain.com
PortsBound to 127.0.0.1Behind 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.com and api.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:

TypeNameValue
Aapp.yourdomain.comYOUR_VPS_IP
Aapi.yourdomain.comYOUR_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
CORS Must Match

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.

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:

  1. Open https://app.yourdomain.com in your browser
  2. Create an account and sign in
  3. 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.yaml for 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