Skip to content

Latest commit

Β 

History

History
596 lines (418 loc) Β· 17.9 KB

File metadata and controls

596 lines (418 loc) Β· 17.9 KB

PrivyDrop Docker One-Click Deployment (Recommended)

This guide provides a one-click Docker deployment for PrivyDrop. It supports both private and public networks, automates config/build/start, and provisions HTTPS certificates.

πŸš€ Quick Start (Top)

# Private LAN (no domain/public IP)
bash ./deploy.sh --mode lan-http

# Private LAN + TURN (for complex NAT/LAN)
bash ./deploy.sh --mode lan-http --with-turn

# LAN HTTPS (self-signed; dev/managed env; explicitly enable 8443)
bash ./deploy.sh --mode lan-tls --enable-web-https --with-nginx

# Public IP without domain (with TURN; recommended with Nginx for same-origin)
bash ./deploy.sh --mode public --with-turn --with-nginx

# Public domain (HTTPS + Nginx + TURN + SNI 443, auto-issue/renew certs)
bash ./deploy.sh --mode full --domain your-domain.com --with-nginx --with-turn --le-email you@domain.com
  • Requires Docker Compose v2 (command docker compose).
  • In full mode, Let’s Encrypt (webroot) is auto-issued and auto-renewed (no downtime); SNI 443 multiplexing is enabled by default (turn.your-domain.com β†’ coturn:5349; others β†’ web:8443).

Modes Overview

  • lan-http: Intranet HTTP; fastest to start; no TLS
  • lan-tls: Intranet HTTPS (self-signed; dev/managed env); 8443 disabled by default; enable via --enable-web-https; HSTS disabled; turns:443 not guaranteed
  • public: Public HTTP + TURN; works without a domain (no HTTPS/turns:443)
  • full: Domain + HTTPS (Let’s Encrypt auto-issue/renew) + TURN; SNI 443 split enabled by default (use --no-sni443 to disable)

🎯 Deployment Advantages

Compared to traditional deployment methods, Docker deployment offers the following advantages:

Comparison Traditional Deployment Docker Deployment
Deploy Time 30-60 minutes 5 minutes
Technical Requirements Linux ops experience Basic Docker knowledge
Environment Requirements Public IP + Domain Works on private networks
Configuration Complexity 10+ manual steps One-click auto configuration
Success Rate ~70% >95%
Maintenance Difficulty Manual multi-service management Automatic container management

πŸ“‹ System Requirements

Minimum Configuration

  • CPU: 1 core
  • Memory: 512MB
  • Disk: 2GB available space
  • Network: Any network environment (private/public)

Recommended Configuration

  • CPU: 2+ cores
  • Memory: 1GB+
  • Disk: 5GB+ available space
  • Network: 100Mbps+

Low-Memory Server Notes (important for 1GB–2GB hosts)

  • The frontend Docker build runs next build, which can be killed by the kernel on very small hosts.
  • On fresh 1GB–2GB servers, add at least 1GB swap before the first production build if memory pressure is high.
  • Typical symptom: the frontend image build exits unexpectedly during next build or the host shows OOM messages in dmesg.

Recommended one-time swap setup on Ubuntu:

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -h

After swap is enabled, rerun the deploy command.

Software Dependencies

  • Docker 20.10+
  • Docker Compose 2.x (command docker compose)
  • curl (for health checks, optional)
  • openssl (cert tools; the script auto-installs certbot)

πŸš€ Quick Start

1. Get the Code

# Clone the project
git clone https://github.com/david-bai00/PrivyDrop.git
cd PrivyDrop

2. One-Click Deployment

# Always pass an explicit deployment mode
bash ./deploy.sh --mode lan-http

That's it! πŸŽ‰

πŸ“š Deployment Modes

LAN HTTP (lan-http)

Use Case: Private network file transfer, personal use, testing environment

bash ./deploy.sh --mode lan-http

Features:

  • βœ… HTTP access
  • βœ… Private network P2P transfer
  • βœ… Uses public STUN servers
  • βœ… Zero configuration startup

Public Mode

Use Case: Servers with public IP but no domain

bash ./deploy.sh --mode public --with-turn --with-nginx

Features:

  • βœ… HTTP access
  • βœ… Built-in TURN server
  • βœ… Supports complex network environments
  • βœ… Automatic NAT traversal configuration

Full Mode (full)

Use Case: Production environment, public servers with domain

bash ./deploy.sh --mode full --domain your-domain.com --with-nginx --with-turn --le-email you@domain.com

Features:

  • βœ… HTTPS secure access (Let’s Encrypt auto-issue/renew)
  • βœ… Nginx reverse proxy
  • βœ… Built-in TURN server (default port range 49152-49252/udp)
  • βœ… SNI 443 multiplexing (turn. β†’ coturn:5349; others β†’ web:8443)
  • βœ… Same-origin frontend/API gateway by default when --with-nginx is enabled (NEXT_PUBLIC_API_URL is generated as an empty string, so the browser uses /api and /socket.io/)
  • βœ… Production CORS generation covers the canonical domain and its www variant by default (for example https://example.com,https://www.example.com)
  • βœ… Complete production setup

Tip: The script no longer auto-detects the deployment mode; always pass --mode lan-http|lan-tls|public|full. If the detected LAN IP is not the one you expect, add --local-ip 192.168.x.x to override.

πŸ”§ Advanced Configuration

Custom Ports

# Modify .env file
FRONTEND_PORT=8080
BACKEND_PORT=8081
HTTP_PORT=8000

Build-Time Proxy (optional)

Set the following variables in .env (or export them before running deploy.sh) when the build needs to go through a proxy. The configuration generator now preserves these fields on subsequent runs.

HTTP_PROXY=http://your-proxy:7890
HTTPS_PROXY=http://your-proxy:7890
NO_PROXY=localhost,127.0.0.1,backend,frontend,redis,coturn

docker compose passes these values as build args; the Dockerfiles expose them as environment variables so npm/pnpm automatically reuse the proxy. Leave them blank if you don't need a proxy.

Common Flags

# Always include an explicit --mode (examples)
bash ./deploy.sh --mode lan-http --with-nginx
bash ./deploy.sh --mode lan-http --with-turn
bash ./deploy.sh --mode public --with-turn --with-nginx
bash ./deploy.sh --mode full --domain your-domain.com --with-nginx --with-turn --with-sni443 --le-email you@domain.com

# Adjust TURN port range (default 49152-49252/udp)
bash ./deploy.sh --mode full --domain your-domain.com --with-nginx --with-turn --le-email you@domain.com --turn-port-range 55000-55100

🌐 Access Methods

  • With Nginx (recommended, same-origin gateway)

    • lan-http/public: http://localhost (or http://<public IP>)
    • lan-tls (with --enable-web-https): https://localhost:8443 (or https://<LAN IP>:8443)
    • full (with domain): https://<your-domain> (443)
    • Health checks: curl -fsS http://localhost/api/health (lan-http/public), curl -kfsS https://localhost:8443/api/health (lan-tls+https), curl -fsS https://<domain>/api/health (full)
  • Without Nginx (direct ports, for debugging only)

    • Frontend: http://localhost:3002 (or http://<LAN IP>:3002)
    • API: http://localhost:3001 (or http://<LAN IP>:3001)
    • Note: direct ports may cause CORS or 404 in production/public setups and are not recommended for public access.

HTTPS Access (lan-tls/full)

  • lan-tls: with --enable-web-https, access via https://localhost:8443 (certs in docker/ssl/). Import docker/ssl/ca-cert.pem into your browser or trust store on first use.
  • full: after Let’s Encrypt issuance, access via https://<your-domain> (443). Certs auto-issue/renew; the deploy hook hot-reloads edge services on renewal, and the initial full-mode deploy also force-recreates nginx (and coturn when enabled) to guarantee the new HTTPS/SNI config is active.

πŸ” Management Commands

View Service Status

docker compose ps

View Service Logs

# View all service logs
docker compose logs -f

# View specific service logs
docker compose logs -f backend
docker compose logs -f frontend
docker compose logs -f redis

Restart Services

# Restart all services
docker compose restart

# Restart specific service
docker compose restart backend

Stop Services

# Stop services but keep data
docker compose stop

# Stop services and remove containers
docker compose down

Complete Cleanup

# Clean all containers, images and data
bash ./deploy.sh --clean

πŸ› οΈ Troubleshooting

Common Issues

1. Port Already in Use

Symptom: Deployment shows port occupation warning

⚠️  The following ports are already in use: 3002, 3001

Solution:

# First try cleaning previous containers
bash ./deploy.sh --clean   # or docker compose down

# If the port is still occupied, locate the process
sudo ss -tulpn | grep :3002
sudo kill -9 <PID>

# Finally, adjust the exposed ports in .env if necessary
vim .env   # Update FRONTEND_PORT / BACKEND_PORT

2. Insufficient Memory

Symptom: Containers fail to start or restart frequently

Solution:

# Check memory usage
free -h

# Add swap space (temporary solution)
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

3. Docker Permission Issues

Symptom: Permission denied errors

Solution:

# Add user to docker group
sudo usermod -aG docker $USER

# Re-login or refresh group permissions
newgrp docker

4. Service Inaccessible

Symptom: Browser cannot open pages

Solution:

# 1. Check service status
docker compose ps

# 2. Check health status
curl http://localhost:3001/health
curl http://localhost:3002/api/health

# 3. View detailed logs
docker compose logs -f

# 4. Check firewall
sudo ufw status

5. WebRTC Connection Failure

Symptom: Cannot establish P2P connections

Solution:

# Enable TURN server (re-run with an explicit --mode)
bash ./deploy.sh --mode lan-http --with-turn
# or (public IP, recommended same-origin via Nginx)
bash ./deploy.sh --mode public --with-turn --with-nginx

# Check network connectivity
curl -I http://localhost:3001/api/get_room

Health Checks

The project provides comprehensive health check functionality:

# Run health check tests
bash test-health-apis.sh

# Manual service checks
curl http://localhost:3001/health          # Backend basic check
curl http://localhost:3001/health/detailed # Backend detailed check
curl http://localhost:3002/api/health      # Frontend check

Performance Monitoring

# View container resource usage
docker stats

# View disk usage
docker system df

# Clean unused resources
docker system prune -f

πŸ“Š Performance Optimization

Production Environment Optimization

  1. Enable Nginx Caching:
# Example (public IP, same-origin via Nginx)
bash ./deploy.sh --mode public --with-turn --with-nginx
  1. Configure Resource Limits:
# Add to docker-compose.yml
services:
  backend:
    deploy:
      resources:
        limits:
          memory: 256M
        reservations:
          memory: 128M
  1. Enable Log Rotation:
# Configure log size limits
echo '{"log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"3"}}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker

Network Optimization

  1. Use Dedicated Network:
networks:
  privydrop-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
  1. Enable HTTP/2:
# Auto-enabled (requires HTTPS)
bash ./deploy.sh --mode full --domain your-domain.com --with-nginx --with-turn --le-email you@domain.com

πŸ”’ Security Configuration

LAN HTTPS (lan-tls, self-signed, dev/managed env)

  • 8443 is disabled by default; explicitly enable with:
bash ./deploy.sh --mode lan-tls --enable-web-https --with-nginx
  • For development or managed devices only (internal CA trusted fleet-wide); HSTS disabled; turns:443 not guaranteed. For restricted networks (443-only), use full (domain + trusted cert + SNI 443).

Usage (strongly recommended)

  1. Import the self-signed CA (required)
  • Location: docker/ssl/ca-cert.pem
  • Browser import:
    • Chrome/Edge: Settings β†’ Privacy & Security β†’ Security β†’ Manage certificates β†’ β€œTrusted Root Certification Authorities” β†’ Import ca-cert.pem
    • macOS: Keychain Access β†’ System β†’ Certificates β†’ Import ca-cert.pem β†’ set to β€œAlways Trust”
    • Linux (system-wide):
      • sudo cp docker/ssl/ca-cert.pem /usr/local/share/ca-certificates/privydrop-ca.crt
      • sudo update-ca-certificates
  • Without trusting the CA, browser HTTPS will show untrusted cert warnings and API requests will fail.
  1. Access endpoints (default ports and paths)
  • Nginx reverse proxy: http://localhost
  • HTTPS (Web): https://localhost:8443, https://<LAN IP>:8443
  • Frontend direct (optional): http://localhost:3002, http://<LAN IP>:3002
  • Note: In lan-tls, 443 is not open; HTTPS uses 8443.
  1. CORS
  • For convenience, common dev origins are allowed by default: https://<LAN IP>:8443, https://localhost:8443, http://localhost, http://<LAN IP>, http://localhost:3002, http://<LAN IP>:3002.
  • To minimize allowed origins, edit CORS_ORIGIN in .env and then docker compose restart backend.
  • In production, CORS_ORIGIN is a comma-separated list consumed by both Express and Socket.IO. Example: CORS_ORIGIN=https://example.com,https://www.example.com.
  1. Health checks
  • curl -kfsS https://localhost:8443/api/health β†’ 200
  • bash ./test-health-apis.sh β†’ all tests should pass (frontend container trusts the self-signed CA).
  1. Deployment hints
  • The script prints only reachable Nginx endpoints; in lan-tls it will show https://localhost:8443 (and https://<LAN IP>:8443 if available).

Public Domain Deployment (HTTPS + Nginx) β€” Quick Test

  1. Point your domain A record to the server IP (optional: also turn.<your-domain> to the same IP)

    Recommended DNS / CDN layout:

    • Web entry: choose one canonical hostname for --domain (for example example.com) and redirect alternate hostnames such as www.example.com at the CDN/DNS layer if desired.
    • TURN entry: keep turn.<your-domain> as DNS-only when using Cloudflare so TURN traffic does not go through the HTTP proxy.
    • Current certificate issuance covers --domain and turn.<your-domain> by default. If you need direct HTTPS on an additional hostname such as www.<your-domain>, add that certificate handling separately or make it redirect to the canonical host.
  2. Run:

./deploy.sh --mode full --domain <your-domain> --with-nginx --with-turn --le-email you@domain.com
  1. Open ports: 80, 443, 3478/udp, 5349/tcp, 5349/udp

  2. Verify: visit https://<your-domain>, /api/health returns 200; open chrome://webrtc-internals and check for relay candidates (TURN)

SSL/TLS Automation (Let’s Encrypt)

In full mode, certificates are auto-issued and auto-renewed:

  • Initial issuance: webroot (no downtime); system certs live under /etc/letsencrypt/live/<domain>/; copied to docker/ssl/ and 443 is enabled.
  • Initial issuance is followed by docker compose up -d --force-recreate nginx (and coturn when enabled) so the freshly generated HTTPS/SNI config is guaranteed to be mounted and active. Expect a brief reconnect window during this first cutover.
  • Renewal: certbot.timer or /etc/cron.d/certbot runs daily; the deploy-hook copies new certs to docker/ssl/, sends HUP to coturn when possible, and hot-reloads Nginx/Coturn (falling back to container restart if needed).
  • Lineage suffixes (-0001/-0002) are handled automatically.

Network Security

  1. Firewall Configuration:
# Ubuntu/Debian
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp  # TURN server
  1. Container Network Isolation:
    • All services run in isolated networks
    • Only necessary ports exposed
    • Internal services communicate using container names

πŸ“ˆ Monitoring and Logging

Log Management

All service logs are centrally stored in the logs/ directory:

logs/
β”œβ”€β”€ nginx/          # Nginx access and error logs
β”œβ”€β”€ backend/        # Backend application logs
β”œβ”€β”€ frontend/       # Frontend application logs
└── coturn/         # TURN server logs

πŸ”„ Updates and Maintenance

Update Application

# Pull latest code
git pull origin main

# Re-run the same deployment command you used initially (examples)
bash ./deploy.sh --mode lan-http
# or (public IP)
bash ./deploy.sh --mode public --with-turn --with-nginx
# or (full domain)
bash ./deploy.sh --mode full --domain your-domain.com --with-nginx --with-turn --le-email you@domain.com

Data Backup

# Backup Redis data
docker compose exec redis redis-cli BGSAVE

# Backup SSL certificates
tar -czf ssl-backup.tar.gz docker/ssl/

# Backup configuration files
cp .env .env.backup

Regular Maintenance

# Clean unused images and containers
docker system prune -f

# Update base images
docker compose pull
docker compose up -d

πŸ†˜ Getting Help

Command Line Help

bash ./deploy.sh --help

### Additional Notes

- In Docker environments, Next.js Image optimization is disabled by default (`NEXT_IMAGE_UNOPTIMIZED=true`) to avoid container loopback fetch failures on `/_next/image`. To enable it, set the variable to `false` and rebuild.
- With `--with-nginx`, the frontend is built to use same-origin API (`/api`, `/socket.io/`). Use the gateway URLs printed by the script; direct ports `:3002/:3001` are not recommended in production.

Online Resources

Community Support

  • GitHub Issues: Technical questions and bug reports