Guide to deploy Django application with SSL and Nginx in GCP (google cloud platform) Ubuntu VM

Somanath Balakrishnan
Nov 7 · 4 min read

Hope you read my other article to deploy Django in GCP, here is the LINK if you have missed. In this new article, I am trying to explain the steps to install nginx, enable ssl and control the Django application using supervisor to ease the process.

Install NGINX

As you know nginx (http://nginx.org/) is a HTTP server which will be listening to port 80 and can redirect to your application. We can also configure SSL certificate and related configurations in nginx.

sudo apt-get install nginx

you can check the status of nginx by running below command,

sudo systemctl status nginx.service

Create SSL certificate

We have different authorities who providing SSL certificates — godaddy, comodo, digicert etc, but here, we are going to use let’s encrypt (https://letsencrypt.org/) — an org who providing free SSL certificate. (Let’s Encrypt is a free, automated, and open certificate authority brought to you by the non-profit Internet Security Research Group (ISRG). source: https://letsencrypt.org/)

I have used zerossl (https://zerossl.com/) which intern using let’s encrypt, but made process simple and we can create, verify and download from zerossl online tool. Once certificate generated, you may scp the certificate to your GCP VM where you have your Django application running.

Changes in Django settings

For production environment, you have to change “debug= true” to false

debug=false

You may also add below security parameters in django settings,

SECURE_PROXY_SSL_HEADER = (‘HTTP_X_FORWARDED_PROTO’, ‘https’)

SECURE_SSL_REDIRECT = True

SESSION_COOKIE_SECURE = True

CSRF_COOKIE_SECURE = True

Install and configure Supervisor

As I said in the intro section, supervisor (https://pypi.org/project/supervisor/) helps us to automate the start and stop the django process in production.

sudo apt-get install supervisor

configure django app for supervisor in /etc/supervisor/config.d/<<your project name>> file,

sample content below,

[program:your_project_name]

command = /usr/bin/python3 /path/to/project/manage.py runserver 0.0.0.0:8000 ; Command to start app

user = vm_user_name ; User to run as

stdout_logfile = /path/log_file_name ; Where to write log messages

redirect_stderr = true ; Save stderr in the same log

environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8 ; Set UTF-8 as default encoding

Above config file tells supervisor what to run and where to write logs etc.

You have to run below commands to make supervisor understand the configuration for our application,

sudo supervisorctl reread

sudo supervisorctl update

Below commands for start, stop and restart application,

sudo supervisorctl start project_name

sudo supervisorctl stop project_name

sudo supervisorctl restart project_name

sudo supervisorctl status # to check status and make sure app is running

Nginx configurations

We have our application running in port 8000 which we triggered from supervisor, now, its time to configure http server and redirect port 80 requests to 8000 and also, configure SSL for our app. Make your nginx is running by checking below command,

sudo systemctl status nginx.service

You can configure your app for nginx in below file,

/etc/nginx/sites-available/project_name_here

Here is the sample configuration:

upstream app_server {

# fail_timeout=0 means we always retry an upstream even if it failed

# to return a good HTTP response

# for UNIX domain socket setups

# server unix:/tmp/gunicorn.sock fail_timeout=0;

# for a TCP configuration

server VM_IP:8000 fail_timeout=0;

# above statement will forward request to django application which running on port 8000

}

# below section is to forward default request (to http port 80) to SSL port 443

server {

listen 80;

server_name host_name_or_IP_or_domain_name www.host_name_or_IP_or_domain_name;

return 301 https://$server_name$request_uri;

}

server {

# use ‘listen 80 deferred;’ for Linux

# use ‘listen 80 accept_filter=httpready;’ for FreeBSD

listen 443 ssl; # <-

ssl on; # <-

ssl_certificate /path/to/ssl/certificate; # <-

ssl_certificate_key /path/to/ssl/certificate_key; # <-

client_max_body_size 4G;

# set the correct host(s) for your site

server_name host_name_or_IP_or_domain_name www.host_name_or_IP_or_domain_name;

keepalive_timeout 5;

# path for static files

root /path/to/static/files;

location /static/ {

alias /path/to/static/files;

}

location /media/ {

alias /path/to/static/media/files/;

}

location / {

# checks for static file, if not found proxy to app

try_files $uri @proxy_to_app;

}

location @proxy_to_app {

}

location @proxy_to_app {

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-Proto https;

proxy_set_header Host $http_host;

# we don’t want nginx trying to do something clever with

# redirects, we set the Host: header above already.

proxy_redirect off;

proxy_pass http://app_server;

}

error_page 500 502 503 504 /500.html;

location = /500.html {

root /path/to/app/current/public;

}

}

Link the site to site enabled list,

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

sudo service nginx restart

sudo systemctl status nginx.service

Now, you can access the application by its https url and also, the http request will be forwarding to https per nginx configuration.

Somanath Balakrishnan

Written by

Technical Consultant @ Digitalcore Technologies, Kochi, India

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade