After struggling some time trying to deploy an Django App on Amazon Web Services EC2 here you can find how I solved it.
When you deploy a Django App there are some slight differences between the local development environment and the AWS environment and appear some new technologies.
I'm newbie with Django. I use it for my experiments and automate some boring tasks and to have more fun at work.
Starting with Django is quite easy in local environment, but when you want to share your app with the whole world, you need to know several tools, technologies, network, etc... And usually, a very small error makes all fail with out explanation or at less for me, difficult to find what's the problem.
Starting point
My company (Schibsted Spain) provides me a AWS account, so I won't explain you how to create an AWS account and related stuff.
Create a new instance (a machine) on the cloud
Preparatory steps:
- Login to your AWS account
- Access to the EC2 service
- Create a new instance following the next steps. As you'll see, in most of the steps I choose the default values, so quite easy, at least for now ;-)
1. Choose an Amazon Machine Image (AMI)
In my case I've choosen Ubuntu Server 16.04 LTS AMI. After choosing your prefered AMI click Next button.
I've done some tests with Amazon Linux and Ubuntu Linux, and there are some differences on the machines. If you choose an AMI different from what I've choosen maybe some further steps are not identical.
2. Choose instance type
At this moment, I'm trying to do a test, so with an small machine is more than enough.
Let the default value and click Next button
3. Configure instance
If you don't have a Virtual Private Cloud (a group of instances running together in a private network on Amazon, a Direct Connect - huge a private communication channel between your offices and AWS Data Center - ) you don't need to change anything.
Otherwise, if you have a big infrastructure with several machines on AWS, probably you'll need the help of your IT people to know which value you must choose on the Network field. Click Next button.
4. Add Storage
Nothing to consider (at this moment). Click Next button
5. Add Tags
At this moment, you only need to add the tag Name to identify later the instance. Pay attention to the capitalization of the tag. And click Next ;-)
- Tag: Name
- Value: My Personal Instance (or the value you want)
6. Configure Security Group
This is one of the first tricky points. In my case, I use an existing security group created by the Admins team in my company.
What's intented to do here is open the protocols and ports to enable the communication from outside with the instance.
At least you'll need to configure two things:
- Enable access from your local machine to the remote machine (instance) through SSH, but only you.
- Enable whoever (well depending on your preferences) to access your remote machine through HTTP to access to your django application.
SSH configuration (choosing the protocol most of the following fields are set automatically)
- Type: SSH
- Protocol: TCP
- Port: 22
- Source: My IP (In this case you'll use SSH to manage via Terminal the remote server, so I encourage you to set you local IP. Remember that if for any reason you change you local IP, you won't be able to access the remote server with SSH and you'll need to update this field).
HTTP configuration
- Type: HTTP
- Protocol: TCP
- Port: 80 (if your django application uses a diferent public port, remember to change it here)
- Source: Custom (In this case, if your django application is public for every body, set to 0.0.0.0/0, ::/0).
7. Review
Finally review your configuration and if all is ok, click on Launch button.
8. Access running instances dashboard
After launching your instance you'll be redirected to the instances page. There you'll find your instance. Select it and get this information to follow the next steps:
- Public DNS (IPv4)
- IPv4 Public IP
Setup your intance for the deployment
At this moment you have a raw instance running, without your Django Application nor the needed software to run it.
To access to your instance and configure it you'll use the SSH command line tool (Secure Shell). This tool requires a pem file stored on your computer. The pem file contains a key value pairs that identifies you when you access to a remote server.
In my case, an Administrator generated the pem file for me. So I can't help on how to create it. You'll find info at Amazon EC2 Key pairs.
- Store the pem file in your computer and remember the path. In my case I've stored it in a hidden folder called .amazon
- Open a Terminal (command line) window
- Type the following command:
ssh -i /Users/marc.pou/.amazon/di-devops.pem ubuntu@34.253.180.133
- ubuntu is the name of the user that this instance uses. This value changes depending of the AMI type you choose at the begining.
- and the number after the @ symbol is the IPv4 Public IP you collected in a previous step
If all goes well you'll be redirected to the command line of the remote server.
At this moment you need to update / upgrade the software installed on your instance. To do that you need to run the following commands:
sudo apt-get update
sudo apt-get upgrade
After that you need to install the tools necesary to run python on this instance and create the Virtual Environment in which to install the python packages to run you application.
sudo apt-get install python-pip
sudo pip install virtualenv
At this moment I'm not using git. This is not a good practice, but for a concept test, is enough. If you use git is easier to copy you files to the remote server. If you use git, install it.
sudo apt-get install git
To run you Django application on the remote server, you'll need a web server running on it. One common solution is to use Nginx. Install it with the following command.
sudo apt-get install nginx
Nginx is a service that needs to be started / stoped when necessary. Follow these commands to start / stop / restart the service
sudo service nginx start
sudo service nginx stop
sudo service nginx restart
After starting the web server Nginx, check if it runs properly. To do that, grap you Public DNS (IPv4) and paste it in a web browser and you should see the Nginx Welcome page. If you can't access to the Welcome page, review your security groups (steps before and check if the service is started).
Create a new folder to store your app:
pwd
# your path will be something like /home/ubuntu. Otherwise go there.
# create a new folder to store your Application
mkdir simpletest
Copy your Django Application files to your remote server
Before to copy the files, I want to show you the structure of my application. This is a proof of concept intended to check that the application runs on the remote server and check if the application can get the static content (images, javascript and css files).
Locally, my django application resolves the static content with this line in the settings.py file (nothing else). I point this because later you'll need to do some changes on the remote server.
STATIC_URL = '/static/'
Before to copy your local files to the remote server, you need to generate the requirements.txt file for your project. This file identifies which packages are necessary to run your application. These packages must be installed in the remote server to run your application.From the command line in your local computer run this command# move to the path where your App is stored
cd /Users/marc.pou/PycharmProjects/simpletest
# activate your virtual environment. Set the path to your virtual
# environment
source /Users/marc.pou/simpletest/bin/active
# after activating the virtual environment, freeze the requirements
# of your app
pip freeze > requirements.txt
At this moment, your app directory contains a new file called requirements.txt. Open it to view your packages dependencies. Could be that the gunicorn line don't appears. Add it manually and save the file.To copy the local files to the remote server I used the SCP command line (Secure Copy). Open a new terminal window on your local computer. And type the following sentece:To run you Django application on the remote server, you'll need a web server running on it. One common solution is to use Nginx. Install it with the following command.cd /Users/marc.pou/PycharmProjects/simpletest
scp -r -i /Users/marc.pou/.amazon/di-devops.pem . ubuntu@34.253.180.133:/home/ubuntu/simpletest/.
When the copy process has finished you can continue from the remote terminal window.Setup you application and configure the Nginx web server
First of all you need to create the virtual environment for your django app. In my case I've decided to create the virtual environment in a hidden folder named .virtualenvs and use the same name of the app for the virtual environment.# create the virtual environment
virtualenv /home/ubuntu/.virtualenvs/simpletest
# activate the virtual environment
source /home/ubuntu/.virtualenvs/simpletest/bin/activate
# point to your application folder
cd /home/ubuntu/simpletest
# install the requirements of your django app
pip install -r requirements.txt
At this moment you can check if your django app runs properly.
To do that, start gunicorn indicating the name of your app
You'll see something similar to that, but at this moment, you won't be able to access there from a browser.
To check it you can open a new terminal for the remote server and execute a wget command
This command will save the web page in a file. You can inspect the content. If you see that, the gunicorn server is running properly.
Click CTRL+C to stop gunicorn server.
More information about gunicorn and wsgi servers (new for me).
Now its time to configure your Nginx web server to handle request to your django app. There are two files: this is the first one. Don't change anything here, but you should know it.
And the second one:
Modify the server part of the file to match with the lines in the following picture. Pay attention to the blue part.
Add the Public DNS to the ALLOWED_HOSTS variable
Remove the following variable:
STATICFILES_DIR
Add a new variable for the static content. This path should match with the path on the Nginx configuration done before.
STATIC_ROOT = '/home/ubuntu/om/static'
To do that, start gunicorn indicating the name of your app
gunicorn simpletest.wsgi
To check it you can open a new terminal for the remote server and execute a wget command
wget 127.0.0.1:8000/simpletest
Click CTRL+C to stop gunicorn server.
More information about gunicorn and wsgi servers (new for me).
Now its time to configure your Nginx web server to handle request to your django app. There are two files: this is the first one. Don't change anything here, but you should know it.
sudo nano /etc/nginx/nginx.conf
sudo nano /etc/nginx/sites-enabled/default
- server_name is the Public DNS
- And pay attention to the static section !
Add the Public DNS to the ALLOWED_HOSTS variable
ALLOWED_HOSTS = [u'ec2-34-253-180-133.eu-west-1.compute.amazonaws.com']
STATICFILES_DIR
Add a new variable for the static content. This path should match with the path on the Nginx configuration done before.
STATIC_ROOT = '/home/ubuntu/om/static'
Finally you need to execute the following commands before making your app available for the whole world.
# collect static content in a new folder (that will create this process)
python manage.py collectstatic
# restart the nginx web server
sudo service nginx restart
# start your application
gunicorn simpletest.wsgi
And now you can go to a web browser and enjoy with your app!
Hope this helps! If you miss something or consider that something can be improved, please let me know.
Comentarios
Publicar un comentario