This article is a sequel to the earlier one on deploying Django ‘on GCP, which was carried in the December 2019 issue of OSFY. It guides users on installing Nginx, enabling SSL and controlling the Django application using Supervisor to ease the process.
As you know, Nginx (http://nginx.org/) is an HTTP server which listens to Port 80 and can redirect to your application. We can also configure the SSL certificate and related configurations in Nginx.
sudo apt-get install nginx
You can check the status of Nginx by running the following command:
sudo systemctl status nginx.service
Creating an SSL certificate
We have different authorities providing SSL certificates — GoDaddy, Comodo, DigiCert, etc, but here, we are going to use Let’s Encrypt (https://letsencrypt.org/) — an organisation that provides free SSL certificates. (Let’s Encrypt is a free, automated, and open certificate authority brought to you by the non-profit Internet Security Research Group.)
I have used ZeroSSL (https://zerossl.com/) to access Let’s Encrypt, but have made the process simple to create, verify and download from the ZeroSSL online tool. Once the certificate is generated, you may scp the certificate to your GCP VM, where you have your Django application running.
Making changes in Django settings
For a production environment, you have to change debug= true to false, as follows:
debug=false
You may also add the security parameters given below to your Django settings:
SECURE_PROXY_SSL_HEADER = (‘HTTP_X_FORWARDED_PROTO’, ‘https’) SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
Installing and configuring Supervisor
Supervisor helps us to automate the starting and stopping of the Django process in production, as follows:
sudo apt-get install supervisor
Configure the Django app for Supervisor in the /etc/supervisor/config.d/<<your project name>> file sample content is shown 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
The above config file instructs Supervisor what to run and where to write logs. You have to run the commands given below to make Supervisor understand the configuration for your application:
sudo supervisorctl reread sudo supervisorctl update
The commands given below are for starting, stopping and restarting the 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, it is time to configure the HTTP server and redirect Port 80 requests to 8000 and also, configure SSL for our app. Make sure Nginx is running, by using the command given below:
sudo systemctl status nginx.service
You can configure your app for Nginx in the file given below:
/etc/nginx/sites-available/project_name_here
Here is a 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. The HTTP request will be forwarded to HTTPS, as per the Nginx configuration.