Setting up an AWS ec2 instance for Nginx, Django, uWSGI, and MySQL
Getting an ubuntu server set up on AWS
Log into your AWS panel and navigate into the EC2 management console. Click “Launch Instance”. Select “Classic Wizard” and then click continue.
- Choose an AMI
- Choose “Ubuntu Server 12.04.1 LTS” AMI and click continue.
- Instance Details
- Make sure that the number of Instances is set to “1” and that instance Type is set to “T1 Micro” and click Continue.
- Under “Advanced Instance Options” leave all options defaulted and click Continue.
- Under “Storage Device Configuration” leave all options defaulted and click Continue.
- K/V Pairs
- Add a Key “Name” with a value describing the app/apps that will be living on this server.
- Add a Key “Stack” with a value that describes the application stack “django, MySQL, nginx”
- Click Continue
- Create Key Pair
- Under Create a new Key Pair, enter the same value as you used in your “Name” K/V in the last step.
- Click the “Create and Download Key Pair” link and note where this saves to on your computer (this is your .pem file referred to later).
- Then Click Continue
- Configure Firewall
- Create a new Security Group
- For “Group Name” enter “Developers”.
- For “Group Description” enter “Anyone Collaborating”.
- Create Rules for MySQL, SSH, and HTTP.
- Click Continue.
- look over everything and click Launch.
- Navigate to the EC2 management console.
- Under “NETWORK & SECURITY” click on “Elastic IPs”.
- At the top of the page click “Allocate New Address”.
- For “EIP used in” select “EC2” and click “Yes, Allocate”.
- Select the New EIP by clicking the checkbox next to it and click “Associate Address” at the top of the page.
- Select the EC2 instance you created in the step prior and click “Yes, Allocate”.
Do you have a domain you want to point to this IP? go to your DNS management console where the domain is registered and create an A record pointing the domain to the EIP
Now wait for the DNS to propagate
Configure your server
Run the following command
chmod 600 <your pem filename>.pem && ssh -i <your pem filename>.pem [email protected]<your EIP> to ssh into your server.
Set ubuntu user’s password
sudo passwd ubuntu and follow the steps to change the default user’s password.
Set up the directories to run your applications
mkdir ~/web/web is where the applications (vhosts) will live
mkdir ~/web/<vhost>/name the vhost appropriately (usually for me www.domain.com OR dev.domain.com)
mkdir ~/web/<vhost>/app/location where the project’s git will be initialized
mkdir ~/web/<vhost>/logs/location of logs
mkdir ~/web/<vhost>/static/location of static assets for collectstatic
mkdir ~/web/<vhost>/media/location of user uploaded media
Enabling ubuntu’s Multiverse
sudo cp /etc/apt/sources.list /etc/apt/sources.list.backupbackup sources list
sudo nano /etc/apt/sources.listand uncomment the multiverse lines that look like the following and then save.
deb http://us-east-1.ec2.archive.ubuntu.com/ubuntu/ precise multiverse
deb-src http://us-east-1.ec2.archive.ubuntu.com/ubuntu/ precise multiverse
deb http://us-east-1.ec2.archive.ubuntu.com/ubuntu/ precise-updates multiverse
deb-src http://us-east-1.ec2.archive.ubuntu.com/ubuntu/ precise-updates multiverse
sudo apt-get update
- install python headers
sudo aptitude install python2.7-dev
sudo aptitude install python-setuptools
sudo easy_install pip
sudo pip install virtualenv
cd /home/ubuntu/web/<vhost.com>/ && virtualenv --no-site-packages venv
Install & configure GIT
sudo apt-get install git
ssh-keygen -t rsa -C "[email protected]"
git config --global user.name "AWS Server"
git config --global user.email "[email protected]"
git config --global core.autocrlf input
- initialize your first vhost’s git repo:
cd /home/ubuntu/web/<vhost>/app && git init
Note: don’t forget to add your public key as a deploy key on github for the repo.
cat ~/.ssh/id_rsa.pub and then copy the output to your clipboard. On github.com, go to the
Settings > Deploy Keys page and paste the ssh public key into the Key field and name it appropriately.
Initialize your application.
- add a remote origin for this repo
cd /home/ubuntu/web/<vhost>/app && git remote add origin [email protected]:Y/X.git
- run the command
git pull origin masterto bring your remote project local
- activate the virtualenv
cd /home/ubuntu/web/<vhost>/app && pip install -r requirements.txt
Note: If your app uses mysql as a database backend, run sudo apt-get install libmysqlclient-dev BEFORE you pip install mysql-python. This is necessary regardless of where the MySQL server resides.
Note: If you use the Python Image Library(PIL) install it’s dependencies so that when PIL is installed support for jpeg, png etc is already there.
sudo apt-get build-dep python-imaging && sudo ln -s /usr/lib/`uname -i`-linux-gnu/libfreetype.so /usr/lib/ && sudo ln -s /usr/lib/`uname -i`-linux-gnu/libjpeg.so /usr/lib/ && sudo ln -s /usr/lib/`uname -i`-linux-gnu/libz.so /usr/lib/
I was using gunicorn for a my apps until I got a good look at some of the performance /benefits of uWSGI. Many thanks to this blogpost for the upstart script help.
First, install uwsgi globally:
sudo pip install uwsgi.
Next, create a wsgi.py file for this vhost
nano /home/ubuntu/web/<vhost>/wsgi.py Add the following:
Note: this is also where you would add the newrelic application wrapper
Lastly, create an init script to daemonize this vhost
sudo nano /etc/init/<vhostid>uwsgi.conf and add the following:
Note: what you name this file will effect how you refer to this application
sudo service <vhostid>uwsgi restart so maybe you want to name your process
Lets look at the options we called uwsgi with:
- home The home directory for uwsgi to use
- socket The path to a socket file. We’ll give this to Nginx later.
- chmod-socket Set the permissions on the socket so we can use it.
- module The wsgi configuration file’s name, without extension. So, myapp_wsgi, not myapp_wsgi.py
- pythonpath The directory in which the wsgi configuration file resides.
- H The path to the virtualenv to use with uwsgi
- Install nginx
sudo apt-get install nginx
- Test to make sure that nginx starts:
sudo service nginx startthen stop the service
sudo service nginx stop
- Make sure that nginx starts automatically
sudo update-rc.d nginx defaultsVirtual Hosts
Next, create the vhost’s configuration
sudo nano /etc/nginx/sites-available/<vhost.com>. (sample below)
- Enable this vhost:
sudo ln -s /etc/nginx/sites-available/<vhost.com> /etc/nginx/sites-enabled/<vhost.com>
- Restart Nginx for changes to take effect
sudo service nginx restart
This step guides you through setting up a locally hosted mysql database server if you aren’t using a dedicated database solution such as Amazon’s RDS.
- install mysql server:
sudo apt-get install mysql-server libmysqlclient-devand set password for the root user
- restart the mysql process:
sudo service mysql restart