Production Deployment

Deploy Nexo Share safely for production use.

HTTPS Setup (Required)

Never run Nexo Share without HTTPS in production. Passwords and files are transmitted, requiring encryption.

Option 1: Nginx Reverse Proxy

Install Nginx:

sudo apt update
sudo apt install nginx certbot python3-certbot-nginx

Create /etc/nginx/sites-available/Nexoshare:

server {
    listen 80;
    server_name share.company.com;
    
    # Redirect to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name share.company.com;
    
    # SSL certificates (Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/share.company.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/share.company.com/privkey.pem;
    
    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    
    # Increase upload limits
    client_max_body_size 0;  # Unlimited (handled by Nexo Share)
    proxy_read_timeout 300s;
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header 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_cache_bypass $http_upgrade;
    }
}

Enable and get certificate:

sudo ln -s /etc/nginx/sites-available/Nexo Share /etc/nginx/sites-enabled/
sudo certbot --nginx -d share.company.com
sudo nginx -t
sudo systemctl restart nginx

Option 2: Traefik (Docker)

Add to docker-compose.yml:

services:
  traefik:
    image: traefik:v2.10
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/acme.json:/acme.json
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "[email protected]"
      - "--certificatesresolvers.myresolver.acme.storage=/acme.json"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"

  Nexo Share:
    # ... existing config ...
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.Nexoshare.rule=Host(`share.company.com`)"
      - "traefik.http.routers.Nexoshare.entrypoints=websecure"
      - "traefik.http.routers.Nexoshare.tls.certresolver=myresolver"
      - "traefik.http.services.Nexoshare.loadbalancer.server.port=3000"

Create ACME file:

touch traefik/acme.json
chmod 600 traefik/acme.json

Environment Configuration

Update docker-compose.yml for production:

environment:
  - ALLOWED_ORIGINS=https://share.company.com
  - RP_ID=share.company.com
  - ORIGIN=https://share.company.com
  - NODE_ENV=production
  - TZ=Europe/Amsterdam

Enable Secure Cookies

After HTTPS is working:

  1. Log in as admin
  2. Go to Settings → General
  3. Enable Secure Cookies
  4. Click Save

This ensures cookies are only sent over HTTPS.

Firewall Configuration

Allow only necessary ports:

sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP (redirects to HTTPS)
sudo ufw allow 443/tcp   # HTTPS
sudo ufw enable

Block Nexo Share’s port directly:

sudo ufw deny 3000/tcp

Security Hardening

1. Strong Credentials

Generate new secrets:

# JWT Secret (64 characters)
openssl rand -hex 32

# Database Password (32 characters)
openssl rand -base64 32

2. Restrict Database Access

Add to PostgreSQL service in docker-compose.yml:

postgres:
  environment:
    - POSTGRES_HOST_AUTH_METHOD=scram-sha-256

3. Enable All Security Features

In web interface:

  • ✅ Require 2FA for all users
  • ✅ Enforce Virus Scan (fail-closed)
  • ✅ Secure Cookies
  • ✅ Strong session duration (7 days max)

4. Disable Unnecessary Features

If not using:

  • Disable Allow Password Reset (if no SMTP or SSO-only)
  • Disable Allow Passkeys (if not needed)

5. Regular Updates

Keep Docker images updated:

docker compose pull
docker compose up -d

Monitoring

Check Application Health

# View logs
docker compose logs -f Nexo Share

# Check container status
docker compose ps

# Monitor resource usage
docker stats

Key Metrics to Watch

  • CPU: Should stay under 50% normally
  • RAM: ~2GB for Nexo Share + 2GB for ClamAV
  • Disk: Monitor upload folder growth
  • Network: Check for unusual traffic spikes

ClamAV Updates

Check virus definition age:

docker compose exec clamav sigtool --info /var/lib/clamav/daily.cvd

Should update automatically daily. If not:

docker compose restart clamav

Backup Strategy

What to Backup

  1. Database: Contains all users, shares, metadata
  2. Upload folder: Contains all files
  3. Docker Compose file: Your configuration

Automated Backup Script

Create backup.sh:

#!/bin/bash
BACKUP_DIR="/backup/Nexoshare"
DATE=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p "$BACKUP_DIR"

# Backup database
docker compose exec -T postgres pg_dump -U nexoshare nexoshare | gzip > "$BACKUP_DIR/db_$DATE.sql.gz"

# Backup uploads (rsync is faster than tar for large folders)
rsync -a ./uploads/ "$BACKUP_DIR/uploads_$DATE/"

# Backup config
cp docker-compose.yml "$BACKUP_DIR/docker-compose_$DATE.yml"

# Keep only last 7 days
find "$BACKUP_DIR" -type f -mtime +7 -delete

echo "Backup completed: $DATE"

Make executable and add to cron:

chmod +x backup.sh
crontab -e
# Add: 0 2 * * * /path/to/backup.sh

Restore from Backup

# Stop services
docker compose down

# Restore database
zcat db_YYYYMMDD_HHMMSS.sql.gz | docker compose exec -T postgres psql -U nexoshare nexoshare

# Restore files
rsync -a uploads_YYYYMMDD_HHMMSS/ ./uploads/

# Restart
docker compose up -d

Performance Tuning

For High Upload Volumes

Increase chunk size in Settings → System:

Chunk Size: 100 MB (max for Cloudflare)

For Many Concurrent Users

Increase PostgreSQL connections in docker-compose.yml:

postgres:
  command: postgres -c max_connections=200

For Large Files

Increase Docker timeout:

Nexoshare:
  stop_grace_period: 60s  # Allow time for large uploads to complete

Troubleshooting Production Issues

Users Can’t Login After HTTPS

Problem: Cookies not working after enabling HTTPS.

Solution: Enable Secure Cookies in settings after HTTPS is active.

Uploads Fail at 100MB

Problem: Reverse proxy limit.

Solution: Set client_max_body_size 0; in Nginx config.

ClamAV Using Too Much RAM

Problem: System has < 4GB RAM.

Solution: Disable Enforce Virus Scan in settings (not recommended) or upgrade server.

Emails Not Sending

Problem: SMTP blocked by ISP/firewall.

Solutions:

  1. Check SMTP credentials in test connection
  2. Verify firewall allows outbound port 587/465
  3. Check logs: docker compose logs nexoshare | grep SMTP
  4. Enable Allow Local IPs if SMTP is on same network

Database Connection Lost

Problem: PostgreSQL crashed or is overloaded.

Solution:

docker compose restart postgres
docker compose logs postgres

Cloudflare Integration

If using Cloudflare proxy:

  1. Orange Cloud OFF for large files (>100MB)

  2. Or increase chunk size to max 100MB

  3. Set Trusted Proxy headers in reverse proxy:

    proxy_set_header CF-Connecting-IP $http_cf_connecting_ip;
  4. Enable Trust Proxy if needed (future Nexo Share feature)

Disaster Recovery

Keep these safe for emergencies:

  1. Database backup (most critical)
  2. JWT secret (can’t decode sessions without it)
  3. Docker compose file (configuration)

Store backups off-site (different server/cloud) for full protection.

Production Checklist

Before going live:

  • HTTPS working with valid certificate
  • Secure cookies enabled
  • Strong JWT secret set
  • Strong database password set
  • Firewall configured
  • 2FA enforced for all users
  • Virus scanning enabled
  • SMTP tested and working
  • Automated backups running
  • Monitoring in place
  • Admin password is strong and unique
  • Test upload and download from external network
  • Documentation saved for team

Your Nexo Share is now production-ready! 🎉