Prerequisites and Initial Setup
Before setting up nginx virtual hosts ssl on your Ubuntu VPS, you'll need a few things ready. Your server should have Nginx installed and running, plus root access and at least one domain pointing to your server's IP.
Check that Nginx is running:
sudo systemctl status nginx
If Nginx isn't installed yet:
sudo apt update
sudo apt install nginx -y
Open your firewall for HTTP and HTTPS traffic:
sudo ufw allow 'Nginx Full'
sudo ufw status
Your domains should already point to your server. Verify DNS propagation with dig yourdomain.com or any online DNS checker.
Creating the Directory Structure
Set up directories for each domain you want to host:
sudo mkdir -p /var/www/example.com/html
sudo mkdir -p /var/www/testsite.com/html
Fix ownership and permissions:
sudo chown -R $USER:$USER /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/testsite.com/html
sudo chmod -R 755 /var/www
Add simple test pages:
echo '<h1>Welcome to example.com</h1>' | sudo tee /var/www/example.com/html/index.html
echo '<h1>Welcome to testsite.com</h1>' | sudo tee /var/www/testsite.com/html/index.html
These test pages help you verify everything works before adding SSL certificates.
Configuring Basic Virtual Host Blocks
Create server block files for each domain. Start with your first domain:
sudo nano /etc/nginx/sites-available/example.com
Add this configuration:
server {
listen 80;
listen [::]:80;
root /var/www/example.com/html;
index index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ =404;
}
}
Create your second virtual host:
sudo nano /etc/nginx/sites-available/testsite.com
server {
listen 80;
listen [::]:80;
root /var/www/testsite.com/html;
index index.html index.htm index.nginx-debian.html;
server_name testsite.com www.testsite.com;
location / {
try_files $uri $uri/ =404;
}
}
Enable both sites with symbolic links:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/testsite.com /etc/nginx/sites-enabled/
Installing Let's Encrypt SSL Certificates
Let's Encrypt gives you free SSL certificates that work great with Hostperl VPS hosting. Install Certbot and its Nginx plugin:
sudo apt install certbot python3-certbot-nginx -y
Test your Nginx configuration first:
sudo nginx -t
If the test passes, reload Nginx:
sudo systemctl reload nginx
Get SSL certificates for your domains. Run these commands separately:
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot --nginx -d testsite.com -d www.testsite.com
Certbot automatically updates your Nginx configuration files with SSL settings and redirects. The process takes about a minute per domain.
You'll need to provide an email address and agree to the terms of service. You can choose whether to share your email with the Electronic Frontier Foundation.
Verifying SSL Configuration
Check your updated configuration files after Certbot finishes:
sudo cat /etc/nginx/sites-available/example.com
You'll see new server blocks for port 443 with SSL directives. The configuration now includes:
- SSL certificate paths
- SSL protocols and ciphers
- HTTP to HTTPS redirects
- Security headers
Test your SSL setup by visiting both domains in a browser. Look for the lock icon showing secure connections.
Verify with command line tools:
curl -I https://example.com
curl -I https://testsite.com
Both should return HTTP 200 responses with proper SSL headers.
Adding Security Headers
Boost your SSL setup with extra security headers. Edit each virtual host configuration:
sudo nano /etc/nginx/sites-available/example.com
Add these headers inside the port 443 server block:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
Apply the same headers to all virtual hosts. These protect against common web attacks and improve your site's security.
For sensitive data sites, use stricter Content Security Policy rules. The example above works well for most hosting scenarios.
SSL Certificate Auto-Renewal
Let's Encrypt certificates expire every 90 days. Certbot sets up automatic renewal, but verify it works:
sudo certbot renew --dry-run
This simulates renewal without replacing actual certificates. Success means auto-renewal is configured properly.
Check the renewal timer:
sudo systemctl status certbot.timer
The timer should be active and enabled. If not, enable it:
sudo systemctl enable --now certbot.timer
Check renewal logs:
sudo journalctl -u certbot.timer
Most people set up SSL once and forget about it. Automatic renewal prevents certificate expiration that could take your sites offline.
Performance Optimization
SSL connections use more CPU than plain HTTP. Add these performance settings to your virtual host configurations:
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_buffer_size 8k;
Enable HTTP/2 for better performance:
listen 443 ssl http2;
listen [::]:443 ssl http2;
Enable Gzip compression in the main Nginx configuration:
sudo nano /etc/nginx/nginx.conf
Uncomment and configure these Gzip settings:
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
Troubleshooting Common Issues
Several issues commonly affect nginx virtual hosts ssl setups. Here's how to fix them:
Certificate Not Found Errors: Check that certificate paths in your configuration match actual files:
sudo ls -la /etc/letsencrypt/live/example.com/
Mixed Content Warnings: Update internal links to use HTTPS or relative URLs. Make sure all site resources load over secure connections.
Port 443 Connection Refused: Confirm Nginx listens on port 443 and your firewall allows HTTPS traffic:
sudo ss -tlnp | grep :443
sudo ufw status numbered
Wrong Certificate Served: Verify server_name directives match your domain names exactly. Nginx picks virtual hosts based on these values.
Always test configuration changes before reloading:
sudo nginx -t && sudo systemctl reload nginx
This prevents breaking working configurations with syntax errors.
Setting up Nginx virtual hosts with SSL requires careful certificate management and security configuration. Our managed VPS hosting includes pre-configured Nginx with SSL support, plus our support team can help with complex virtual host setups and certificate troubleshooting.
Frequently Asked Questions
Can I use one SSL certificate for multiple subdomains?
Yes, you can use wildcard certificates (*.example.com) or Subject Alternative Name (SAN) certificates. Let's Encrypt supports both. For wildcard certificates, use sudo certbot --nginx -d example.com -d *.example.com but this requires DNS validation.
How many virtual hosts can I run on one VPS?
The limit depends on your VPS resources and traffic patterns. A typical 2GB VPS handles 50-100 low-traffic sites. Monitor memory usage and CPU load as you add domains. Each SSL certificate uses minimal additional resources.
What happens if I don't renew my SSL certificate?
Expired certificates trigger browser security warnings and may block users from accessing your sites. Let's Encrypt certificates expire after 90 days. With proper auto-renewal setup, this shouldn't happen, but monitor renewal logs periodically.
Can I mix SSL and non-SSL virtual hosts on the same server?
Yes, but it's not recommended for security and SEO reasons. Modern browsers and search engines prefer HTTPS. If you must serve some content over HTTP, make sure it doesn't include sensitive data or user interactions.
How do I backup my SSL certificates?
Let's Encrypt certificates live in /etc/letsencrypt/. Include this directory in your regular backups. You can export certificates manually, but since Let's Encrypt certificates are free and easily renewable, backing up your configurations matters more.

