Self-Hosting
Step-by-step instructions to run Harmony on your own infrastructure
Self-Hosting / Deployment Guide
Who is this for? Teams and individuals who want full control over their data or need to deploy Harmony in air-gapped, compliance-sensitive, or cost-optimized environments.
Prerequisites
- Node.js 20+ and pnpm 9+
- PostgreSQL 15+ with a dedicated database & user
- A Spotify Developer App (Client ID & Secret)
- (Optional) Docker & Docker Compose if you prefer containerized deployments
- A domain name (e.g.,
harmony.example.com
) and HTTPS certificate (we recommend Caddy or Let's Encrypt)
Clone & Configure
# SSH into your server
ssh user@your-server
# Install pnpm (if not already)
corepack enable
corepack prepare pnpm@latest --activate
# Clone the repository
mkdir -p ~/apps && cd ~/apps
git clone https://github.com/your-org/harmony.git
cd harmony
# Install dependencies (root of monorepo)
pnpm install
Environment Variables
Create a .env
file in the project root:
DATABASE_URL="postgresql://harmony:supersecret@127.0.0.1:5432/harmony"
AUTH_SECRET="$(openssl rand -hex 32)"
AUTH_SPOTIFY_ID="your-spotify-client-id"
AUTH_SPOTIFY_SECRET="your-spotify-client-secret"
APP_MAINTENANCE=false
# Optional - Use in demo mode
DEMO_ID="your-demo-id"
# Optional - used to upload your Spotify data package
UPLOADTHING_TOKEN="your-uploadthing-token"
# Optional - used in local development
AUTH_URL="http://localhost:3000"
Tip: Never commit
.env
to version control. Use a secrets manager (Vault, AWS SSM, etc.) in production.
Running with Docker Compose (Database Only)
The provided docker-compose.yml
focuses solely on PostgreSQL to keep things lightweight. Your application will run on the host (or a separate process manager) and connect to this containerised database.
Compose excerpt:
version: "3.8"
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Start the database:
# From repo root
docker compose up -d postgres
Check logs with:
docker compose logs -f postgres
Note: Feel free to extend the compose file with
web
orapi
services if you prefer a fully containerised setup.
Run Database Migrations
Use Drizzle migration tooling.
# Generate & apply migrations
cd packages/database
pnpm db:generate # Generates SQL
pnpm db:push # Applies migrations to the DB
Run the app
Production Build
# From repo root
pnpm build
Production Run
# From repo root
pnpm start
Development
# From repo root
pnpm dev
Deploying to Vercel (Cloud Option)
- Push your fork to GitHub.
- Import the repo in Vercel → configure the
web
app as Framework: Next.js. - Add env vars inside Project Settings → Environment Variables.
- Disable Vercel’s automatic Postgres add-on (we bring our own).
- (Optional) Add a second Vercel project for
apps/api
if you need the REST layer.
Common Issues
Symptom | Fix |
---|---|
ECONNREFUSED connecting Postgres | Check firewall, database_url , and ensure Postgres is running. |
OAuth callback fails | Verify NEXTAUTH_URL and Spotify redirect URI match. |
404 on /api/upload | Make sure apps/api is deployed and env var UPLOADTHING_SECRET is set. |
Next Steps
- Set up CI/CD with GitHub Actions using the included workflow templates.
- Configure Caddy / Nginx reverse proxy for HTTPS and to forward
web
→ port 3000. - Read the FAQ for more troubleshooting tips.