20 KiB
Privydrop Backend Deployment Guide
This guide provides comprehensive instructions for deploying the Privydrop backend application, including setting up necessary services like Redis, TURN, and Nginx (for production).
1. Introduction
This document will walk you through the steps to prepare your server environment, configure dependencies, and deploy the Privydrop backend. Whether you are setting up a development/testing environment or a full production instance, this guide aims to cover the essential aspects.
2. Prerequisites
Before you begin, ensure your server environment meets the following requirements:
- Operating System: A Linux distribution (e.g., Ubuntu 20.04 LTS or later is recommended).
- Node.js: v18.x or later.
- npm (or yarn): Package manager for Node.js.
- Git: For cloning the repository.
- Curl, GnuPG, etc.: For installing Nginx or other dependencies.
- Root or Sudo Access: Required for installing packages and configuring services.
3. Dependent Services Installation and Configuration
The Privydrop backend relies on several external services.
3.1. Redis Server
Redis is used for room management, session information, and caching.
Installation (Ubuntu Example):
sudo apt update
sudo apt install redis-server
Configuration:
- By default, Redis listens on
127.0.0.1:6379and requires no password. - If your Redis instance is on a different host, port, or requires a password, you will need to update the backend application's environment variables accordingly (see section 4.3).
- Ensure Redis is running:
sudo systemctl status redis-server # Or for older systems # /etc/init.d/redis-server status - To start Redis if it's not running:
sudo systemctl start redis-server # Or # sudo /etc/init.d/redis-server start
3.2. TURN/STUN Server (Coturn)
A TURN server is crucial for WebRTC to traverse NATs and firewalls, ensuring reliable peer-to-peer connections. Coturn is a popular open-source TURN server implementation.
Installation (Ubuntu Example):
sudo apt update
sudo apt install coturn
Configuration:
-
Enable Coturn Service: Edit
/etc/default/coturnand uncomment the line:TURNSERVER_ENABLED=1 -
Coturn Configuration File (
/etc/turnserver.conf): This is the main configuration file. Below is a comprehensive example. Adapt it to your needs.-
For Testing/Development (using IP, no TLS):
# Listening IP address(es) for STUN/TURN. Use your server's private/local IP if behind NAT, # and ensure your TURN_EXTERNAL_IP environment variable for the backend uses the public IP. # If your server has a public IP directly, you can use that. listening-ip=YOUR_SERVER_PRIVATE_OR_PUBLIC_IP # External IP address of the server. # This is the IP that clients will use to connect to the TURN server from the internet. # It MUST be set if the server is behind NAT. external-ip=YOUR_SERVER_PUBLIC_IP # Realm for the TURN server realm=YOUR_SERVER_PUBLIC_IP # Or your domain for production # User for TURN authentication user=YourTurnUsername:YourTurnPassword # Listening port for STUN/TURN (UDP and TCP) listening-port=3478 # Further listening ports for STUN/TURN (UDP and TCP) # alt-listening-port=3479 # Optional # Log file log-file=/var/log/turnserver.log verbose # Deny TLS/DTLS for non-secure connections if you don't have SSL certs for testing no-tls no-dtls # Other recommended settings lt-cred-mech # Use long-term credential mechanism fingerprint # Use fingerprint for STUN messages -
For Production (using Domain, with TLS for TURNS):
# Listening IP address(es) listening-ip=YOUR_SERVER_PRIVATE_OR_PUBLIC_IP # External IP address of the server if behind NAT external-ip=YOUR_SERVER_PUBLIC_IP # Must be the public IP # Realm for the TURN server - MUST match your domain used for SSL cert realm=turn.yourdomain.com # User for TURN authentication user=YourTurnUsername:YourTurnPassword # Listening port for STUN/TURN (UDP and TCP) - standard non-TLS listening-port=3478 # Listening port for TURNS (TLS-TCP) tls-listening-port=5349 # SSL Certificate and Key for TURNS cert=/etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem pkey=/etc/letsencrypt/live/turn.yourdomain.com/privkey.pem # Log file log-file=/var/log/turnserver.log verbose # Other recommended settings lt-cred-mech fingerprint # Specify a cipher list if needed, e.g., for older clients, but modern defaults are usually fine. # cipher-list="DEFAULT"
-
-
Firewall Configuration: Open the necessary ports on your server's firewall (e.g., using
ufw):- TCP & UDP
3478: For STUN and TURN. - TCP & UDP
5349: For TURNS (TURN over TLS/DTLS) - Production. - UDP
49152-65533: Default relay port range for Coturn (configurable withmin-portandmax-portinturnserver.conf).
sudo ufw allow 3478 sudo ufw allow 5349 # For production sudo ufw allow 49152:65535/udp sudo ufw enable sudo ufw status - TCP & UDP
-
SSL Certificate for Production (TURNS): If deploying for production and using
TURNS(TURN over TLS), you need an SSL certificate for your TURN domain (e.g.,turn.yourdomain.com).- Ensure you have a DNS 'A' record pointing
turn.yourdomain.comto your server's public IP. - Use Certbot to obtain a certificate:
The certificate and private key will typically be stored in
sudo apt install certbot sudo certbot certonly --standalone -d turn.yourdomain.com/etc/letsencrypt/live/turn.yourdomain.com/.
- Ensure you have a DNS 'A' record pointing
-
Permissions for SSL Certificates (Production): The Coturn process (usually runs as user
turnserver) needs permission to read the SSL certificate and key.- Check current permissions:
sudo ls -lh /etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem sudo ls -ld /etc/letsencrypt/archive/ - If Coturn logs show permission errors:
Create a group (e.g.,
ssl-cert), addturnserverto it, and adjust permissions:Verify the new permissions onsudo groupadd -f ssl-cert # Find the user coturn runs as, usually 'turnserver' or 'coturn' # ps aux | grep turnserver sudo usermod -a -G ssl-cert turnserver # Replace 'turnserver' if it's different sudo chown -R root:ssl-cert /etc/letsencrypt/ sudo chmod -R 750 /etc/letsencrypt//etc/letsencrypt/archive/and/etc/letsencrypt/live/.
- Check current permissions:
-
Start/Restart and Test Coturn:
sudo systemctl restart coturn sudo systemctl status coturnCheck
/var/log/turnserver.logfor any errors.Testing your TURN server: Use an online tool like Metered TURN Server Tester (https://www.metered.ca/turn-server-testing):
- For testing (non-TLS):
- TURN URL:
turn:YOUR_SERVER_PUBLIC_IP:3478 - Username:
YourTurnUsername - Password:
YourTurnPassword
- TURN URL:
- For production (TURNS):
- TURNS URL:
turns:turn.yourdomain.com:5349 - Username:
YourTurnUsername - Password:
YourTurnPasswordLook for "Success" or "Reachable" messages.
- TURNS URL:
- For testing (non-TLS):
3.3. Nginx (Reverse Proxy - Production Environment)
Nginx is recommended for production environments to act as a reverse proxy, handle SSL termination, serve static files (if applicable), and enable HTTP/3.
Installation (with HTTP/3 support, Ubuntu Example): Ref: https://nginx.org/en/linux_packages.html#Ubuntu
- Install prerequisites:
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring - Import Nginx signing key:
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null - Verify the key:
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg # Expected fingerprint: 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 - Set up apt repository for stable Nginx packages:
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \ | sudo tee /etc/apt/sources.list.d/nginx.list - Set up repository pinning:
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \ | sudo tee /etc/apt/preferences.d/99nginx - Install Nginx:
sudo apt update sudo apt install nginx
Configuration:
-
Firewall Configuration:
- TCP
80(for HTTP, redirects to HTTPS) - TCP
443(for HTTPS) - UDP
443(for HTTP/3 QUIC)
sudo ufw allow 'Nginx Full' # Allows HTTP and HTTPS sudo ufw allow 443/udp # For HTTP/3 sudo ufw status - TCP
-
SSL Certificate for Your Main Domain: Obtain an SSL certificate for your main application domain (e.g.,
yourdomain.comandwww.yourdomain.com).# Ensure certbot is installed and configured to work with Nginx sudo apt install python3-certbot-nginx sudo certbot --nginx -d yourdomain.com -d www.yourdomain.comFollow the prompts. This will also attempt to configure Nginx for SSL.
-
Nginx Configuration (
/etc/nginx/nginx.confand server blocks in/etc/nginx/conf.d/): You'll need to configure Nginx to:- Listen on port 80 and redirect to HTTPS.
- Listen on port 443 (TCP and UDP for HTTP/3).
- Use your SSL certificates.
- Proxy pass requests to your backend Node.js application (running on e.g.,
localhost:3001). - Handle WebSocket connections for Socket.IO.
- (Optionally) Serve your frontend static files if they are on the same server.
A basic example server block for your application (
/etc/nginx/conf.d/privydrop.conf):map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name yourdomain.com www.yourdomain.com; # Redirect all HTTP requests to HTTPS return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; # For HTTP/3 (QUIC) listen 443 quic reuseport; listen [::]:443 quic reuseport; server_name yourdomain.com www.yourdomain.com; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; # Recommended SSL settings from Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Recommended SSL settings from Certbot # HTTP/3 specific headers # Tell the browser that HTTP/3 is available add_header Alt-Svc 'h3=":443"; ma=86400'; # For 0-RTT # add_header Alt-Svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'; # If supporting older h3 drafts # ssl_early_data on; # Nginx 1.15.4+ # (Optional) If serving frontend from Nginx # root /path/to/your/frontend/build; # index index.html index.htm; location / { # If serving frontend: # try_files $uri $uri/ /index.html; # If only backend, or for API calls when frontend is separate: proxy_pass http://localhost:3001; # Assuming backend runs on port 3001 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; proxy_read_timeout 86400s; # For potentially long file transfers proxy_send_timeout 86400s; } # Socket.IO specific location (ensure path matches your Socket.IO path) location /socket.io/ { proxy_pass http://localhost:3001; # Assuming backend runs on port 3001 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; } # Add other security headers, logging, etc. as needed }- Important: The
nginx.confmain file should have anhttpblock that enables QUIC:Ensure your Nginx version supports QUIC and# In /etc/nginx/nginx.conf, inside the http {} block: http { # ... other settings ... quic_retry on; # Nginx 1.25.0+ # ... other settings ... }quic_retry. The official Nginx packages usually do.
-
Test Nginx Configuration and Restart:
sudo nginx -t sudo systemctl restart nginx
4. Backend Application Deployment
4.1. Get the Code
Clone your repository to your server:
git clone <your-repository-url> privydrop
cd privydrop/backend
4.2. Install Dependencies
npm install
4.3. Environment Variables
Create a .env.production.local file in the backend/ directory. This file contains sensitive information and configurations.
# Server Configuration
PORT=3001 # The port your Node.js app will listen on (Nginx will proxy to this)
NODE_ENV=production
CORS_ORIGIN=https://yourdomain.com # URL of your frontend application
# Redis Configuration
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
# REDIS_PASSWORD=your_redis_password # If applicable
# TURN Server Configuration
# These are used by the backend to inform clients about the TURN server.
# For Testing (if using non-TLS TURN)
# TURN_EXTERNAL_IP=YOUR_SERVER_PUBLIC_IP
# TURN_REALM=YOUR_SERVER_PUBLIC_IP
# TURN_USERNAME=YourTurnUsername
# TURN_PASSWORD=YourTurnPassword
# For Production (if using TURNS)
TURN_EXTERNAL_IP=YOUR_SERVER_PUBLIC_IP # The public IP of your TURN server
TURN_REALM=turn.yourdomain.com # The realm, usually your TURN domain
TURN_USERNAME=YourTurnUsername
TURN_PASSWORD=YourTurnPassword
TURN_CERT_PATH=/etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem # Path to TURN SSL cert
TURN_KEY_PATH=/etc/letsencrypt/live/turn.yourdomain.com/privkey.pem # Path to TURN SSL key
# Note: The backend itself doesn't directly use TURN_CERT_PATH/TURN_KEY_PATH
# for its own operations but might pass this info or use it for internal validation
# if you extend its functionality. The primary user of these paths is Coturn itself.
# The backend primarily needs to know the correct TURN URL (derived from these settings)
# to send to clients.
# Nginx Related (Used by helper scripts if any, or for reference)
# NGINX_SERVER_NAME=yourdomain.com
# NGINX_SSL_CERT=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
# NGINX_SSL_KEY=/etc/letsencrypt/live/yourdomain.com/privkey.pem
# NGINX_FRONTEND_ROOT=/path/to/your/frontend/build # If Nginx serves frontend
Important:
- Ensure
CORS_ORIGINis correctly set to your frontend's domain for production. - The
TURN_*variables are critical for the backend to correctly inform clients how to connect to your TURN server.
4.4. Process Management with PM2
PM2 is a production process manager for Node.js applications.
- Install PM2 globally:
sudo npm install -g pm2 - Start the application using the
ecosystem.config.jsfile: Theecosystem.config.jsfile (usually in your project root) defines how PM2 should run your application.If you have a previous instance running with the same name (e.g.,# Navigate to your backend directory if not already there # cd /path/to/privydrop/backend sudo pm2 start ecosystem.config.jssignaling-serveras defined inecosystem.config.js):sudo pm2 stop signaling-server && sudo pm2 delete signaling-server sudo pm2 start ecosystem.config.js - Check application status and logs:
sudo pm2 list sudo pm2 logs signaling-server # Or the name defined in your ecosystem file sudo pm2 monit - Enable PM2 to start on system boot:
sudo pm2 startup # Follow the instructions provided by the command (usually involves running another command it outputs) sudo pm2 save # Save current process list
4.5. Firewall for Backend Application
If your backend application's port (3001 by default) is not proxied by Nginx for all access (e.g., health checks directly to the app), ensure it's open in the firewall. However, for typical production setups with Nginx, only Nginx ports (80, 443) need to be publicly accessible.
# Only if direct access to Node.js app is needed and not through Nginx
# sudo ufw allow 3001/tcp
5. Dockerized Deployment (Advanced/Optional)
While this guide focuses on a traditional deployment, you can also containerize the Privydrop backend. Refer to the Dockerfile in the backend/docker/ directory and the Docker deployment section in README.md for basic Docker build and run commands.
For a production Docker setup, consider using docker-compose to orchestrate the backend application, Nginx (as a reverse proxy within Docker or on the host), Redis, and potentially Coturn (though Coturn often runs better directly on the host for network access). Managing SSL certificates and network configurations requires careful planning in a Dockerized environment.
6. Security and Maintenance
- Regular Updates: Keep your server's OS, Nginx, Node.js, PM2, and all other software packages updated.
- SSL Certificate Renewal: Certbot usually sets up automatic renewal. You can test it with
sudo certbot renew --dry-run. Ensure the renewal process has permissions to restart Nginx if needed. - Log Management: Regularly monitor logs for Nginx (
/var/log/nginx/), Coturn (/var/log/turnserver.log), and your application (via PM2). Set up log rotation. - Firewall: Keep your firewall rules strict, only allowing necessary ports.
- Application Dependencies: Regularly update Node.js dependencies (
npm update) and test thoroughly.
7. Troubleshooting
- Connection Issues: Check firewall rules, Nginx proxy settings,
CORS_ORIGINin your backend .env file, and ensure all services (Redis, Coturn, Node.js app) are running. - WebRTC Failures: Use
chrome://webrtc-internals(or Firefox equivalent) for debugging. Test your TURN server independently. EnsureTURN_EXTERNAL_IPandTURN_REALMare correctly set. - Nginx Errors:
sudo nginx -twill check configuration syntax. Examine Nginx error logs. - PM2 Issues: Use
pm2 logs <app_name>to see application errors. - Certificate Permissions: If Coturn or Nginx can't read SSL certificates, double-check file permissions and group memberships.
This is a draft and can be expanded with more details, specific configurations for different Linux distributions, or more advanced topics.