Looking for good programming challenges?

Use the search below to find our solutions for selected questions!

Setup Jenkins On AWS EC2 For Your Python (Django) Application – Part 2

Sharing is caring!

This article assumes you know how to setup an EC2 instance with a running Apache web server and SSL. If you don’t know how to setup an EC2 instance with an Apache web server and a Let’s Encrypt SSL certificate please refer to this link: Migrating WordPress site from a legacy hosting provider to AWS

In Part 1 of this tutorial we covered the following:
• Setup Jenkins in you EC2 Instance
• Setup an Apache VirtualHost to run Jenkins over SSL

In this tutorial we will cover how to run our Django REST service behind an Apache web server on our EC2 instance.

Step 1: Install Python 3
Login to your AWS EC2 instance and run the following:

$ sudo su
$ yum -y update

Then, run the following command to see what is available to install:

$ sudo yum list | grep python3

To install Python run:

$ sudo yum install python36
$ sudo yum install -y python36-setuptools
$ sudo easy_install-3.6 pip

To use pip3 add the following symbolic link ln -s /usr/bin/pip-3.6 /usr/bin/pip3.

Step 2: Start you Django REST application

$ cd rest-service

# Create/Activate virtualenv
$ virtualenv venv
$ source  venv/bin/activate

# Install Requirements
$ pip3 install -r requirements.txt

$ python3 manage.py runserver

Normally you would be able to access your Django application locally at

Step 3: Update the existing Apache VirtualHost to forward traffic to your Django application
Edit your /etc/httpd/conf.d/ssl.conf using $ nano /etc/httpd/conf.d/ssl.conf and make sure you add the following to the end of the file (or update the existing one):

Listen 443

  ErrorLog logs/ssl_error_log
  TransferLog logs/ssl_access_log
  LogLevel warn

  SSLEngine on
  SSLProtocol all -SSLv3
  SSLProxyProtocol all -SSLv3
  SSLHonorCipherOrder on
  SSLCertificateFile /etc/letsencrypt/live/fizzbuzzer.com/cert.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/fizzbuzzer.com/privkey.pem
  SSLCertificateChainFile /etc/letsencrypt/live/fizzbuzzer.com/chain.pem

  ProxyRequests     Off
  AllowEncodedSlashes NoDecode
  ProxyPass         /api
  ProxyPassReverse  /api
  ProxyPassReverse  /  https://fizzbuzzer.com/

Now you will be able to access your Django application at https://fizzbuzzer.com/api/.

Note: The ProxyPassReverse / http://fizzbuzzer.com/ is required for the following reasons:
The ProxyPassReverse is used to change the headers sent by the app to Apache, before Apache sends it the browser. For example, if the app sits at, and it tries to redirect the browser to, say, /new_location/, then it will respond with a redirect and location header of, and Apache will take this and send it off to the browser. Problem is, the browser (assuming it’s somewhere else) then tries to send a request to, and gets an error.

What ProxyPassReverse does is intercepts those headers, and rewrites them so that they match what the Apache server that’s doing the proxying looks like. So if my apache server is hosting http://fizzbuzzer.com/ and I have a ProxyPass that points /api to, if the application sitting at returns a redirect to, I’ll need to use ProxyPassReverse so that it gets rewritten to http://fizzbuzzer.com/new_location/ by Apache before sending the request back to the browser.

If you aren’t issuing redirects, it’s not going to be an issue, but it doesn’t hurt to have it there in case a 301/302 redirect is returned. As far as mod_rewrite, the RewriteRule applies to the request going to the App, and not the response coming from the App. So they are mutually exclusive events.

Step 4: Restart Apache

$ service httpd restart