Prerequisites

  • Ubuntu 24.04 LTS or Debian 12+ (x86_64)
  • Root or sudo access
  • A domain name pointed to your server

What's Included

The Docker Compose setup includes everything you need:

  • Caddy — Reverse proxy with automatic HTTPS (Let's Encrypt)
  • Docker — Application container with all dependencies built in
  • SQLite — Zero-config database
  • mediasoup — WebRTC voice/video SFU

What the Setup Script Does

The included deploy/setup.sh configures a fresh server with:

  • System updates + 1GB swap + automatic security updates
  • Docker and Docker Compose
  • UFW firewall (SSH, HTTP, HTTPS, WebRTC UDP ports)
  • SSH hardening (password auth disabled, key-only root login)
  • fail2ban for brute-force protection

Installation

1. Run the Setup Script

On a fresh server, this installs Docker and configures the UFW firewall:

curl -fsSL https://raw.githubusercontent.com/sellserv/voice-server/main/deploy/setup.sh | sudo bash

2. Clone and Configure

git clone https://github.com/sellserv/voice-server.git /opt/voip-server
cd /opt/voip-server/deploy/self-hosted
cp .env.example .env
nano .env

Required:

# Secret key for authentication tokens
JWT_SECRET=your-generated-secret

# Your server's public IP — required for WebRTC voice
MEDIASOUP_ANNOUNCED_IP=203.0.113.50

# Your domain — used by Caddy for automatic HTTPS
DOMAIN=your-domain.com

Recommended:

# Email (required for MFA login codes)
RESEND_API_KEY=re_xxxxxxxxxxxx
EMAIL_FROM=noreply@your-domain.com

# GIF picker
GIPHY_API_KEY=your-giphy-api-key

3. Start the Server

docker compose up -d

Admin Setup

  1. Register an account at your server URL
  2. Verify your email
  3. Add your user ID to ADMIN_USERS in .env (find your UUID in the admin panel or database):
    ADMIN_USERS=your-uuid-here
  4. Restart: docker compose up -d

Email Setup (Resend)

Email is required for MFA login codes, email verification, password resets, and account lockout notifications.

  1. Create an account at resend.com
  2. Add and verify your domain under Domains
  3. Create an API key under API Keys
  4. Add to .env and restart

Mobile Push Notifications (Optional)

Required for sending push notifications to the Android mobile app. Without this, the app works normally but won't receive background notifications.

  1. Create a project at Firebase Console
  2. Go to Project Settings > Service Accounts
  3. Select Node.js and click Generate new private key
  4. Add the full JSON string to .env:
    FIREBASE_SERVICE_ACCOUNT='{"type":"service_account","project_id":"...","private_key":"...","client_email":"..."}'
  5. Restart the service

CAPTCHA (Optional)

Add Cloudflare Turnstile to prevent automated signups:

  1. Go to the Turnstile dashboard and add your site
  2. Copy the Site Key and Secret Key
  3. Add both to .env:
    TURNSTILE_SITE_KEY=0x4AAAAAAA...
    TURNSTILE_SECRET_KEY=0x4AAAAAAA...
  4. Restart the service

Auto-Deploy (GitHub Actions)

Automatically deploy on push to main:

  1. Create a deploy user:
    sudo useradd -m -s /bin/bash deploy
    sudo usermod -aG docker deploy
  2. Generate and copy an SSH key:
    ssh-keygen -t ed25519 -f ~/.ssh/voip-deploy -N ""
    ssh-copy-id -i ~/.ssh/voip-deploy.pub deploy@your-server-ip
  3. Add repository secrets in GitHub:
    SecretValue
    DEPLOY_HOSTServer IP address
    DEPLOY_USERdeploy
    DEPLOY_SSH_KEYPrivate key contents

Updating

cd /opt/voip-server/deploy/self-hosted
docker compose pull
docker compose up -d

Data and uploads persist across updates via Docker volumes. Database migrations run automatically on startup.

Firewall Ports

PortProtocolPurpose
22TCPSSH
80 / 443TCPCaddy — HTTP / HTTPS
40000-40100UDPmediasoup RTP (voice/video)

Backups

Back up these two directories to save your entire instance:

  • /opt/voip-server/data/ — SQLite database
  • /opt/voip-server/uploads/ — User-uploaded files