How to Configure a Nginx Reverse Proxy With Let's Encrypt

Let’s say one of your micro services is running on http://localhost:3000
If you already have a nginx service running on the server, create a server block like this:

1vim /etc/nginx/sites-available/domain.com.conf

Grab this content to paste in:

 1server {
 2
 3  server_name domain.com;
 4
 5  root /var/www/html;
 6  index index.html;
 7
 8  location / {
 9    proxy_pass http://localhost:3000;
10    proxy_http_version 1.1;
11    proxy_set_header Upgrade $http_upgrade;
12    proxy_set_header Connection 'upgrade';
13    proxy_set_header Host $host;
14    proxy_cache_bypass $http_upgrade;
15  }
16
17}

For more advanced(production ready) configuration, use below instead:

 1server {
 2
 3  server_name domain.com;
 4
 5  root /var/www/html;
 6  index index.html;
 7
 8  location / {
 9    proxy_pass http://localhost:3000;
10
11    proxy_http_version 1.1;
12    proxy_set_header Upgrade $http_upgrade;
13    proxy_set_header Connection 'upgrade';
14    proxy_set_header Host $host;
15    proxy_cache_bypass $http_upgrade;
16
17    if ($request_uri ~* ".(ico|css|js|gif|jpe?g|png)$") {
18      expires 30d;
19      access_log off;
20      add_header Pragma public;
21      add_header Cache-Control "public";
22      break;
23    }
24  }
25
26  client_max_body_size 50M;
27  keepalive_timeout    65s;
28  keepalive_requests   1000;
29  sendfile             on;
30  tcp_nopush           on;
31  tcp_nodelay          on;
32  error_log            off;
33  access_log           off;
34
35  gzip on;
36  gzip_vary on;
37  gzip_comp_level 4;
38  gzip_min_length 256;
39  gzip_proxied any;
40  gzip_types
41    text/plain
42    text/css
43    text/xml
44    text/javascript
45    application/json
46    application/javascript
47    application/x-javascript
48    application/xml
49    application/xml+rss
50    application/vnd.ms-fontobject
51    font/eot
52    font/opentype
53    font/otf
54    application/font-woff
55    application/font-otf
56    application/font-ttf
57    application/x-font-opentype
58    application/x-font-truetype
59    application/x-font-woff
60    application/x-font-otf
61    application/x-font-ttf
62    image/svg+xml
63    image/x-icon
64    image/vnd.microsoft.icon;
65
66}

Make a link of the config file:

1sudo ln -s /etc/nginx/sites-available/domain.com.conf /etc/nginx/sites-enabled/

Or in nginx v14+, just create the .conf file inside the conf.d directory then you are good to go. Check the validity of your config file with this command

1sudo nginx -t

Now that it went fine, you will be able to see your public domain will be showing your landing page or something like that.
It’s time to secure your service with Let’s Encrypt (Let's just assume that the server is running Ubuntu 18.04 Bionic for simplicity):

1apt-get update
2apt-get install software-properties-common
3add-apt-repository universe
4add-apt-repository ppa:certbot/certbot
5apt-get update
6apt-get install certbot python-certbot-nginx
7certbot --nginx

Now, you will have to configure a cron job for auto-renewing the received certificates.

1certbot renew --dry-run
2crontab -e

Grab this code followed by an empty line

10 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew
2

It seems you did an awesome job! 😉
A Bonus Tip: Nginx Purging - Right Way

1apt purge nginx nginx-common nginx-full

On CentOS 7/8, you need to configure SELinux as well like so:

1setsebool -P httpd_can_network_connect on

Happy coding! 😎

comments powered by Disqus