{"id":4094,"date":"2024-02-10T16:25:14","date_gmt":"2024-02-10T16:25:14","guid":{"rendered":"https:\/\/blog.ssdnodes.com\/blog\/?p=4094"},"modified":"2025-05-18T13:16:59","modified_gmt":"2025-05-18T13:16:59","slug":"how-to-use-nginx-as-a-reverse-proxy-with-ssl-tutorial","status":"publish","type":"post","link":"https:\/\/www.ssdnodes.com\/blog\/how-to-use-nginx-as-a-reverse-proxy-with-ssl-tutorial\/","title":{"rendered":"How To Use Nginx As A Reverse Proxy With SSL"},"content":{"rendered":"<p>Are you looking for a simple tutorial for how to use Nginx as a reverse proxy with SSL? This guide will walk you through exactly that!<\/p>\n<p><a href=\"http:\/\/nginx.org\/\" target=\"_blank\" rel=\"noopener\">Nginx<\/a> is a powerful tool. It allows you to serve multiple apps, websites, load-balance applications and much more. All that flexibility is powered by a relatively simple configuration system that uses nearly-human-readable configuration files.<\/p>\n<h2>How To Use Nginx as a Reverse Proxy With SSL?<\/h2>\n<p>To use Nginx as a reverse proxy with SSL, configure Nginx to listen on the appropriate ports, set up SSL certificates, define <code>proxy_pass<\/code> directives to forward requests to backend servers, and adjust firewall settings as necessary.<\/p>\n<h2>Why Use Nginx as a Reverse Proxy With SSL?<\/h2>\n<p>It may not be directly obvious why you might need an Nginx <a href=\"https:\/\/www.imperva.com\/learn\/performance\/reverse-proxy\/\" target=\"_blank\" rel=\"noopener\">reverse proxy<\/a> with SSL, but Nginx is a great option for serving your web apps-- take, for example, a NodeJS app.<\/p>\n<p>By default, it runs locally on a machine and listens on a custom-defined port. Usually, this is port 3000 by default and is accessed by typing something like <a title=\"http:\/\/YOUR-DOMAIN:3000\" href=\"https:\/\/www.ssdnodes.com\">http:\/\/YOUR-DOMAIN:3000<\/a><\/p>\n<p>But Nginx lets you serve your app that is running on a non-standard port <em>without<\/em> needing to attach the port number to the URL. It even lets you run different apps on each subdomain, or even in different sub-folders!<\/p>\n<p>Cool, right?<\/p>\n<p>This guide will demonstrate how to utilize Nginx to serve a web app, such as a NodeJS App, using SSL Encryption.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-8785\" src=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2019\/08\/nginx_1-1024x712.png\" alt=\" nginx reverse proxy ssl \" width=\"600\" height=\"417\" srcset=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2019\/08\/nginx_1-1024x712.png 1024w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2019\/08\/nginx_1-300x209.png 300w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2019\/08\/nginx_1-768x534.png 768w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2019\/08\/nginx_1.png 1200w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<h2>Nginx as a Reverse Proxy With SSL - Prerequisites<\/h2>\n<p>This guide will assume a general understanding of using a Linux-based system via command line, and will further assume the following prerequisites:<\/p>\n<ul>\n<li>Ubuntu 22.04<\/li>\n<li>Non-Root User<\/li>\n<li>App Running on Custom Port (this guide assumes port 3000)<\/li>\n<li>DNS A Name Record for Domain Used<\/li>\n<li>SSL Certificate For the Domain<\/li>\n<\/ul>\n<h2>Nginx Configuration<\/h2>\n<p>To get the default configuration for Nginx on Ubuntu 22.04, when installed using the Nginx-full package option, look for available sites at the following location:<\/p>\n<p><code>\/etc\/nginx\/sites<span style=\"font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;\">-<\/span>available\/<\/code><\/p>\n<p>This location will have a <em>default<\/em> file with an example Nginx virtual host configuration. Instead, we will be creating a new site using an empty file that we can utilize. Once logged in as your non-root user, run the following command to create the new configuration file:<\/p>\n<pre><code>sudo touch \/etc\/nginx\/sites-available\/YOUR-DOMAIN\r\n<\/code><\/pre>\n<p>Be sure to replace <em>YOUR-DOMAIN<\/em> with your domain you plan to associate with your app.<\/p>\n<p>Next, we will modify the file so that it does what we need it to. I will be using <a href=\"https:\/\/www.vim.org\/\" target=\"_blank\" rel=\"noopener\"><strong>vim<\/strong><\/a> in this guide, but feel free to use whatever text editor you're most comfortable with:<\/p>\n<pre><code>sudo vim \/etc\/nginx\/sites-available\/YOUR-DOMAIN\r\n<\/code><\/pre>\n<p>The next few steps include adjusting the <em>sites-available\/YOUR-DOMAIN<\/em> file you created just before, so be sure to adjust where indicated so that it functions as desired:<\/p>\n<p>This Section tells Nginx to listen on port 80 for your domain and rewrites the request to HTTPS for us<\/p>\n<pre><code>server {\r\nlisten 80;\r\nserver_name YOUR-DOMAIN www.YOUR-DOMAIN; # Edit this to your domain name\r\nrewrite ^ https:\/\/$host$request_uri permanent;\r\n}\r\n<\/code><\/pre>\n<p>This is all the configuration declarations that help SSL Function.<\/p>\n<pre><code>server {\r\nlisten 443 ssl;\r\n\r\nserver_name YOUR-DOMAIN;                                               \r\n# Edit the above _YOUR-DOMAIN_ to your domain name\r\n\r\nssl_certificate \/etc\/letsencrypt\/live\/YOUR-DOMAIN\/fullchain.pem;       \r\n# If you use Lets Encrypt, you should just need to change the domain. \r\n# Otherwise, change this to the path to full path to your domains public certificate file.\r\n\r\nssl_certificate_key \/etc\/letsencrypt\/live\/YOUR-DOMAIN\/privkey.pem;     \r\n# If you use Let's Encrypt, you should just need to change the domain.\r\n# Otherwise, change this to the direct path to your domains private key certificate file.\r\n\r\nssl_session_cache builtin:1000 shared:SSL:10m;                        \r\n# Defining option to share SSL Connection with Passed Proxy\r\n\r\nssl_protocols TLSv1 TLSv1.1 TLSv1.2;                                  \r\n# Defining used protocol versions. \r\n\r\nssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; \r\n# Defining ciphers to use. \r\n\r\nssl_prefer_server_ciphers on;                                         \r\n# Enabling ciphers\r\n\r\naccess_log \/var\/log\/nginx\/access.log;                                 \r\n# Log Location. the Nginx User must have R\/W permissions. Usually by ownership.\r\n<\/code><\/pre>\n<p>This is the juicy part of the config file, handing off relevant data to our back-end app running on port 3000<\/p>\n<p>Nothing should need to be changed here unless port 3000 is not the port you're using.<\/p>\n<p>Furthermore, if you're using a socket to serve your app (PHP comes to mind), you can define a UNIX:.sock location here as well<\/p>\n<pre><code>location \/ {\r\nproxy_set_header Host $host;\r\nproxy_set_header X-Real-IP $remote_addr;\r\nproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\r\nproxy_set_header X-Forwarded-Proto $scheme;\r\nproxy_pass http:\/\/localhost:3000;\r\n#proxy_pass unix:\/path\/to\/php7.3.sock # This is an example of how to define a unix socket.\r\nproxy_read_timeout 90;\r\n}\r\n\r\n} # Don't leave this out! It \"closes\" the server block we started this file with. \r\n<\/code><\/pre>\n<p>Save and exit the <em>YOUR-DOMAIN<\/em> file. If you're using vim, hit <strong>Esc<\/strong> to exit INSERT mode, then type <code>:wq<\/code> and hit enter to save and exit the file.<\/p>\n<p>To make the file active, we will need to link the file in the <em>sites-available<\/em> folder to a location within the <em>sites-enabled<\/em> folder. Again, change <em>YOUR-DOMAIN<\/em> here with the actual name of the file you created earlier.<\/p>\n<pre><code>ln -s \/etc\/nginx\/sites-avaialable\/YOUR-DOMAIN \/etc\/nginx\/sites-enabled\/YOUR-DOMAIN.conf\r\n<\/code><\/pre>\n<p>Let's now test the configuration file.<\/p>\n<pre><code>sudo nginx -t\r\n<\/code><\/pre>\n<p>If the test is successful, you'll see this output:<\/p>\n<pre><code>nginx: the configuration file \/etc\/nginx\/nginx.conf syntax is ok\r\nnginx: configuration file \/etc\/nginx\/nginx.conf test is successful\r\n<\/code><\/pre>\n<p>Now that we know it's going to work as expected, issue the command to restart the Nginx service<\/p>\n<pre><code>sudo systemctl restart nginx\r\n\r\n# OR #\r\n\r\nsudo service nginx restart\r\n<\/code><\/pre>\n<p>Both commands perform the same task, simply preference decides your method here. I can safely say I use both and in no specific priority.<\/p>\n<p>You should now be able to launch your app (if it wasn't running already) and visit <strong>YOUR-DOMAIN<\/strong> in a browser, assuming the DNS is correct.<\/p>\n<p>Congratulations-- you've now set up a reverse proxy using Nginx. And your app will now be showing to the world with HTTPS enabled!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Are you looking for a simple tutorial for how to use Nginx as a reverse proxy with SSL? This guide will walk you through exactly that! Nginx is a powerful tool. It allows you to serve multiple apps, websites, load-balance applications and much more. All that flexibility is powered by a relatively simple configuration system  &#8230;<\/p>\n","protected":false},"author":20,"featured_media":8835,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[18,30],"tags":[202,211,212],"class_list":["post-4094","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-tutorials","tag-ca-ssl","tag-nginx","tag-proxy"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts\/4094","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/comments?post=4094"}],"version-history":[{"count":8,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts\/4094\/revisions"}],"predecessor-version":[{"id":13018,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts\/4094\/revisions\/13018"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/media\/8835"}],"wp:attachment":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/media?parent=4094"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/categories?post=4094"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/tags?post=4094"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}