Manual Install
Install directly on Ubuntu 24.04 LTS or Debian 12+ with full control.
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
- Register an account at your server URL
- Verify your email
- Add your user ID to
ADMIN_USERSin.env(find your UUID in the admin panel or database):ADMIN_USERS=your-uuid-here - Restart:
docker compose up -d
Email Setup (Resend)
Email is required for MFA login codes, email verification, password resets, and account lockout notifications.
- Create an account at resend.com
- Add and verify your domain under Domains
- Create an API key under API Keys
- Add to
.envand 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.
- Create a project at Firebase Console
- Go to Project Settings > Service Accounts
- Select Node.js and click Generate new private key
- Add the full JSON string to
.env:FIREBASE_SERVICE_ACCOUNT='{"type":"service_account","project_id":"...","private_key":"...","client_email":"..."}' - Restart the service
CAPTCHA (Optional)
Add Cloudflare Turnstile to prevent automated signups:
- Go to the Turnstile dashboard and add your site
- Copy the Site Key and Secret Key
- Add both to
.env:TURNSTILE_SITE_KEY=0x4AAAAAAA... TURNSTILE_SECRET_KEY=0x4AAAAAAA... - Restart the service
Auto-Deploy (GitHub Actions)
Automatically deploy on push to main:
- Create a deploy user:
sudo useradd -m -s /bin/bash deploy sudo usermod -aG docker deploy - 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 - Add repository secrets in GitHub:
Secret Value DEPLOY_HOSTServer IP address DEPLOY_USERdeployDEPLOY_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
| Port | Protocol | Purpose |
|---|---|---|
| 22 | TCP | SSH |
| 80 / 443 | TCP | Caddy — HTTP / HTTPS |
| 40000-40100 | UDP | mediasoup 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