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:
- Log in as admin
- Go to Settings → General
- Enable Secure Cookies
- 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
- Database: Contains all users, shares, metadata
- Upload folder: Contains all files
- 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:
- Check SMTP credentials in test connection
- Verify firewall allows outbound port 587/465
- Check logs:
docker compose logs nexoshare | grep SMTP - 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:
-
Orange Cloud OFF for large files (>100MB)
-
Or increase chunk size to max 100MB
-
Set Trusted Proxy headers in reverse proxy:
proxy_set_header CF-Connecting-IP $http_cf_connecting_ip; -
Enable Trust Proxy if needed (future Nexo Share feature)
Disaster Recovery
Keep these safe for emergencies:
- Database backup (most critical)
- JWT secret (can’t decode sessions without it)
- 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! 🎉