Deploying a modern, privately controlled proxy on a VPS provides flexibility, performance, and security for developers, site operators, and businesses. This guide walks through a robust V2Ray setup on a DigitalOcean droplet, combining VLESS over WebSocket with TLS via Nginx as a reverse proxy. It includes concrete commands, configuration snippets, and operational best practices so you can complete a secure, production-ready deployment in minutes.
Why choose V2Ray on a DigitalOcean droplet?
V2Ray is a versatile, actively maintained proxy platform supporting multiple protocols (VMess, VLESS, Trojan, SOCKS, etc.), routing, obfuscation, and plugin integration. Hosting on a DigitalOcean droplet gives you:
- Full control of networking and firewall rules
- Dedicated public IP and predictable performance
- Fast provisioning and snapshots for backups
Recommended use cases: secure remote access for teams, bypassing throttling for API services, or providing dedicated outbound IPs for webhooks and integrations.
Prerequisites
- A DigitalOcean account and a created droplet (Ubuntu 22.04 LTS recommended, 1GB RAM minimum for basic usage).
- A domain name with DNS control (A record pointing to the droplet’s public IP).
- Basic Linux admin skills (SSH, systemctl, ufw/iptables).
Step 1 — Provision and harden the droplet
Create an Ubuntu droplet on DigitalOcean with at least 1 vCPU and 1GB RAM. After it’s created, SSH in as root (or initial user) and perform initial hardening:
Update and create a non-root sudo user:
sudo apt update && sudo apt upgrade -y
adduser deployuser
usermod -aG sudo deployuser
Enable OpenSSH security features (on Ubuntu 22.04, default is already secure):
Edit /etc/ssh/sshd_config and disable root login and optionally password auth:
PermitRootLogin no
PasswordAuthentication no
Then restart SSH: sudo systemctl restart sshd. Make sure you have key-based login working before disabling password auth.
Step 2 — Configure firewall and basic networking
Use UFW (Uncomplicated Firewall) to expose only the ports you need. We’ll allow SSH, HTTP, and HTTPS; V2Ray will be proxied through Nginx on standard web ports.
sudo apt install -y ufw
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Note: If you’re using cloud provider networking features, ensure DigitalOcean VPC or floating IP settings don’t block traffic.
Step 3 — Install Nginx and obtain TLS certificates
We use Nginx as a reverse proxy for TLS termination and WebSocket upgrade handling. Install Nginx and Certbot (Let’s Encrypt) to get a free certificate.
sudo apt install -y nginx certbot python3-certbot-nginx
Create a minimal server block for your domain (replace example.com):
sudo nano /etc/nginx/sites-available/example.com
Paste a simple HTTP-to-HTTPS redirect and proxy pass (we’ll configure the secure proxy next):
server {
listen 80;
server_name example.com;# replace
location / {
return 301 https://$host$request_uri;
}
}
Enable the site and reload Nginx:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Obtain a certificate:
sudo certbot --nginx -d example.com --email your@email.com --agree-tos --noninteractive
Certbot will edit the Nginx config and add secure listeners for 443.
Step 4 — Install V2Ray (v2ray-core)
Use the official v2ray-core packages or a verified installation script. Here we detail a conservative install using the project binary releases.
Install prerequisites:
sudo apt install -y curl unzip
Download the latest release (example uses a release name; check https://github.com/v2fly/v2ray-core/releases):
VERSION=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases/latest | jq -r .tag_name)
wget https://github.com/v2fly/v2ray-core/releases/download/$VERSION/v2ray-linux-64.zip
unzip v2ray-linux-64.zip -d v2ray
sudo cp v2ray/* /usr/local/bin/
Place service files and default config (systemd unit):
Create /etc/systemd/system/v2ray.service with content:
[Unit]
Description=V2Ray Service
After=network.target
User=nobody
ExecStart=/usr/local/bin/v2ray -config /etc/v2ray/config.json
Restart=on-failure [Install] WantedBy=multi-user.target
Enable and start the service (it will fail until we create config.json):
sudo systemctl daemon-reload
sudo systemctl enable v2ray
Step 5 — V2Ray configuration: VLESS over WebSocket
We will configure VLESS protocol with WebSocket (ws) transport and no TLS at the V2Ray layer because TLS is handled by Nginx. This improves compatibility and allows us to use standard port 443 for both HTTP/S and proxy traffic.
Create /etc/v2ray/config.json with a secure template (replace UUID with a generated one):
sudo apt install -y uuid-runtime
UUID=$(uuidgen)
sudo tee /etc/v2ray/config.json <<'EOF'
{
"inbounds": [
{
"port": 10000,
"listen": "127.0.0.1",
"protocol": "vless",
"settings": {
"clients": [
{ "id": "REPLACE_UUID", "level": 0, "email": "admin@example.com" }
],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"wsSettings": { "path": "/ray" }
}
}
],
"outbounds": [
{ "protocol": "freedom", "settings": {} },
{ "protocol": "blackhole", "tag": "blocked", "settings": {} }
],
"routing": { "rules": [] }
}
EOF
Replace REPLACE_UUID with the value from $UUID. Example: sudo sed -i "s/REPLACE_UUID/$UUID/" /etc/v2ray/config.json
Start V2Ray:
sudo systemctl start v2ray
sudo systemctl status v2ray
If V2Ray started successfully, it will listen on 127.0.0.1:10000 for WebSocket connections.
Step 6 — Configure Nginx to proxy WebSocket to V2Ray
Edit your HTTPS server block (the one certbot created) to route the WebSocket path to V2Ray and proxy other paths to your web app if needed. Example server block snippet:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location /ray {
proxy_redirect off;
proxy_pass http://127.0.0.1:10000;
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;
}
# Optional: serve a normal website on other paths
location / {
try_files $uri $uri/ =404;
}
}
Reload Nginx: sudo nginx -t && sudo systemctl reload nginx.
Step 7 — Client configuration example
Provide the following information to your client (V2RayN, V2RayNG, or other clients supporting VLESS):
- Address: example.com
- Port: 443
- Protocol: VLESS
- UUID: (the generated UUID)
- Flow: none
- Transport: WebSocket
- Path: /ray
- TLS: enabled
Because TLS terminates at Nginx, the client must use TLS. This preserves privacy and integrates with standard HTTPS inspection behavior.
Operational considerations and hardening
Rotate UUIDs and keys periodically. Treat UUIDs like credentials and rotate them if you suspect leakage.
Restrict V2Ray listener scope. V2Ray listens on 127.0.0.1 in this guide. That prevents accidental external binding; Nginx handles external traffic.
Limit user accounts and follow least privilege. Run V2Ray under a non-privileged user if possible, and avoid running processes as root.
Enable logging and monitoring: set V2Ray logs to a controlled file and use logrotate. Monitor CPU, memory, and traffic with Prometheus + node_exporter or simpler tools like netdata.
Backups and recovery
Use DigitalOcean snapshots for full-droplet backups and track /etc/v2ray/config.json, Nginx configs, and certificate renewal hooks in a secure Git repository (private). Periodically export and store the UUIDs and configuration in an encrypted secrets store.
Performance tuning
- Use HTTP/2 or HTTP/3 (QUIC) on Nginx for improved multiplexing if your clients support it.
- Scale droplet size if CPU usage spikes; encryption is CPU-bound. Consider dedicated CPU or more cores for heavy traffic.
- Use a location-aware CDN cautiously — it may interfere with WebSocket upgrades unless configured properly.
Troubleshooting checklist
- If Nginx returns 400 or 502 for WebSocket upgrades, check proxy_set_header Upgrade and Connection values, and ensure V2Ray is listening on the proxied address and port.
- If clients fail TLS validation, confirm the certificate covers the domain and that the client trusts Let’s Encrypt certificates or SNI is correct.
- Use tcpdump or ss/netstat to verify listening sockets:
sudo ss -tulpen | grep :10000 - Inspect V2Ray logs:
sudo journalctl -u v2ray -for the file configured in the V2Ray JSON.
Alternatives and extensions
Depending on requirements, consider these variants:
- VLESS + XTLS (requires client support) for slightly better performance and smaller handshake overhead.
- Running V2Ray directly with TLS enabled (no Nginx) if you prefer fewer moving parts, but certificate management must be handled by V2Ray or ACME client.
- Using Docker containers for deployment isolation; map a local bridge network and run Nginx in front of the V2Ray container.
Following this approach yields a secure, maintainable deployment with standard HTTPS ports, certificate-backed TLS, and the flexibility of V2Ray’s routing features. Keep configs minimal and document changes in your operations runbook to facilitate audits and onboarding.
For more server and VPN operational guides, visit Dedicated-IP-VPN: https://dedicated-ip-vpn.com/