Back to blog
November 24, 2024·Blog

How I Set Up Nginx with SSL and Port Redirection on the website

In this step-by-step guide, learn how to set up your own VPS (Virtual Private Server) with Nginx, configure it to redirect traffic from port 80 to a Docker app running on port 3000, and secure your website with SSL certificates. This beginner-friendly tutorial covers everything from installing Nginx to configuring SSL for HTTPS, ensuring your site is fast, secure, and ready for the web. Perfect for developers and site owners looking to take control of their hosting environment!

Hey there! I recently got my very own VPS (Virtual Private Server) to host the site you're reading this on. It was exciting but also a bit intimidating at first. I had heard about Nginx, an awesome web server, and decided to give it a try. Along the way, I learned how to:

  • Install Nginx on my VPS
  • Redirect traffic from port 80 (HTTP) to 3000 (the port used for my Docker container)
  • Secure my website with SSL certificates

Let’s see how you, too, can implement it!


Step 1: Install Nginx on the VPS

First, I logged into my VPS using SSH. If you haven’t done this before, it’s usually as simple as:

ssh your_username@your_vps_ip

Once I was in, I updated the package list to make sure I got the latest version of everything:

sudo apt update

Then, I installed Nginx using:

sudo apt install nginx

After the installation, I checked to see if Nginx was running:

sudo systemctl status nginx

If it’s running, you’ll see something like “active (running).” ✅


Step 2: Redirect Port 80 to Port 3000

My app was running on port 3000, but I wanted users to access it just by typing my domain name (on port 80). To do that, I needed to configure Nginx.

Create a Configuration File

First, I navigated to the Nginx configuration directory:

cd /etc/nginx/sites-available

I created a configuration file for my site. You can name it anything, but I called mine blogfolio:

sudo nano blogfolio

Inside this file, I added the following configuration:

server {
    listen 80;

    server_name thomasbechu.me www.thomasbechu.me;

    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_cache_bypass $http_upgrade;
    }
}

Here’s what each part does:

  • listen 80; tells Nginx to handle HTTP requests on port 80.
  • server_name specifies the domain names this configuration applies to.
  • Inside location /, the proxy_pass directive tells Nginx to forward requests to http://localhost:3000, where my app is running.

Enable and Test the Configuration

Next, I enabled my configuration by creating a symbolic link:

sudo ln -s /etc/nginx/sites-available/blogfolio /etc/nginx/sites-enabled/

I tested the Nginx configuration for syntax errors:

sudo nginx -t

If everything looked good, I reloaded Nginx to apply the changes:

sudo systemctl reload nginx

At this point, when I typed my domain into a browser, it successfully showed my app running on port 3000!


Step 3: Add SSL for a Secure Connection

Having HTTPS is super important to keep your website secure. For that, I used a free SSL certificate provided by IONOS, my domain host.

Send the Certificate Files to the VPS

Once I had my certificate ready and downloaded, I sent it to the VPS using scp:

scp certificate.cer root@your-server-ip:/etc/ssl/thomasbechu.me

This command copies the certificate file to the /etc/ssl/thomasbechu.me directory on the VPS. You also need to send the intermediate certificate and the private key!

If your certificate has a .crt extension, don’t worry—it works the same way.

Set File Permissions

Next, I set appropriate permissions for the certificate files to ensure Nginx could access them:

sudo chmod 644 /etc/ssl/thomasbechu.me/*.crt
sudo chmod 600 /etc/ssl/thomasbechu.me/*.key

Update the Nginx Configuration for SSL

I edited my Nginx configuration file to include the SSL certificate settings:

server {
    listen 80;
    listen 443 ssl;
    server_name thomasbechu.me www.thomasbechu.me;

    ssl_certificate /etc/ssl/thomasbechu.me/certificate.cer;
    ssl_certificate_key /etc/ssl/thomasbechu.me/private_key.key;
    ssl_trusted_certificate /etc/ssl/thomasbechu.me/intermediate.cer;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Redirect HTTP to HTTPS
    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }

    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_cache_bypass $http_upgrade;
    }
}

Here’s a breakdown of the SSL-related directives:

  • listen 443 ssl; enables SSL on port 443.
  • ssl_certificate, ssl_certificate_key, and ssl_trusted_certificate point to the certificate and key files.
  • ssl_protocols and ssl_ciphers set modern, secure encryption standards.
  • The if ($scheme = http) block redirects all HTTP traffic to HTTPS.

Test and Restart Nginx

Finally, I tested the configuration and restarted Nginx:

sudo nginx -t
sudo systemctl restart nginx

I also verified the certificate using OpenSSL:

openssl x509 -in /etc/ssl/thomasbechu.me/certificate.cer -text -noout

And that’s it! My site was now live and secured with HTTPS.


Wrapping Up

Congratulations! You’ve set up a VPS with:

  • Nginx for web serving
  • Port redirection from 80 to your app on 3000
  • SSL certificates for HTTPS security

The configuration might vary slightly depending on your setup, but this should give you a solid foundation. Happy hosting! 🎉