EC2 - Nginx - Git [step-by-step]

Setting up an Amazon EC2 instance + Nginx + git (and more)

This week we faced an issue in one of our live websites. We were using Heroku and Amazon RDS and we decided to move all these stuff from Heroku to Amazon EC2.

I really like the easy step-by-step way of learning. See an example, get the main idea and adapt it to your particular case - Jose

If you have to do it an you're feeling missed then, (I hope) this will help you.

Step 1: Create your Amazon EC2 instance.

Not much brains at this point. Obviously you'll need an AWS Amazon Console account, probably you are currently using S3 or some other
Amazon service ... anyway Sign in or Sign up in Amazon AWS.

Go to EC2 menu option and follow the instance creation wizard, just 2 tips:

  • You can choose any "box" there, but I am using Ubuntu 14.04

  • Ensure the security profile you choose suits your needs. In my case I chose "open to any IP".

Before you finish and launch that instance you'll need to provide a .pem file or generate a pair there and save it locally.

Once your instance is ready select the public DNS and store it locally in order to ssh the server later or update some of your DNS records.

Step 2: SSH

Well, you're a command line fan boy, a security guru and you decrypt the matrix code at a glance. Go to Step 3. I like command line, I don't love it and I am not a guru, though. I can decrypt matrix code, you loser!

Ok, there we go. You should be able to ssh your EC2 server in order to install some stuff. You can use that that .pem file you stored previously to achieve it.

ssh -i my-key-pair.pem

Remember, you can use scp to copy local <--> EC2

scp -i my-key.pem ./{my_local_file} ubuntu@{ec2_dns}:/route/to/{remote_file}

As you can see, we are using '-i some-file.pem' option in ssh/scp, a good tip for you now:

First create a text file locally named "authorized_keys" copy any public key from you and/or your team mates and scp this file to :~/.ssh/

Finally I recomend you to edit your local ~/.ssh/config and add a section like that:

Host myec2server


   User ubuntu

   IdentityFile ~/.ssh/id_rsa

At this point you should be able to access you server easily just typing:

ssh myec2server

Step 3: Packages & More

Obviously, it depends a lot on the software you need in you server, we are talking about ngnix and git but also will add some php stuff I need. Cool, ssh your server and...

   sudo apt-get update && apt-get upgrade

   sudo apt-get install nginx

   sudo apt-get install php5-cli

   sudo apt-get install php5-fpm

   sudo apt-get install php-apc

   sudo apt-get install php5-gd

   sudo apt-get install php5-curl

   sudo apt-get install php5-mysql

   sudo apt-get install git

Almost 2015 and PHP, what's next? If you don't know go to Composer website right now!. Install composer in your EC2 server

cd ~

   sudo curl -sS | sudo php

   sudo mv composer.phar /usr/local/bin/composer

   sudo ln -s /usr/local/bin/composer /usr/bin/composer

Step 4: Nginx set up

Well, that's pretty straight-forward. First, create a directory to store your website sources

   sudo mkdir -p /var/www/{site1}

   sudo mkdir -p /var/www/{site2}

   sudo mkdir -p /var/www/{site3}

   sudo chown -R ubuntu:www-data www

Second (sudo) edit /etc/nginx/sites-enable/default

Your nginx config will depend on your needs, maybe your using virtual hosts or not...
you know it is not the point now but just as an example this is a "server" block for 1 of my virtual hosts, this works with slim and will/should work with Laravel as well.

server {

   listen 80;

   root /var/www/{mysite1}/public;

   index index.php;


   access_log /var/log/nginx/mysite1.access.log;

   error_log /var/log/nginx/mysite1.error.log;

   location / {

      try_files $uri $uri/ /index.php?$args;


   error_page 404 /404.html;

   error_page 500 502 503 504 /50x.html;

   location ~ \.php$ {

      try_files $uri =404;

      fastcgi_split_path_info ^(.+\.php)(/.+)$;

      fastcgi_pass unix:/var/run/php5-fpm.sock;

      fastcgi_index index.php;

      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

      include fastcgi_params;



As I said this is just an example, do any further action you need in regards Nginx config. And by the way remember to reload config

sudo service ngnix reload

Step 5: Git Deploy

We are almost done. First we need a git repository in the sources directory in ec2. So:

cd /var/www/{site}

git init

git config receive.denyCurrentBranch ignore

Last command is Soooo important don't forget it.

Finally you'll need to edit the git hooks to probably run composer or the like after push. I have a very cool post-receive script (sorry for not sharing it but it depends on OUR build). From local I do:

scp git/hooks/post-receive ubuntu@{myec2server}:/var/www/{site1}/.git/hooks

This .git/hooks must be executable so ensure chmod +x {hook_files}

That's the very final stuff. In your local repo you need to add a git remote. Edit your .git/config and add

[remote "ec2-remote"]

url = ubuntu@{ec2_dns}:/var/www/{site1}
fetch = +refs/heads/*:refs/remotes/ec2-remote/*
pushurl = ubuntu@{ec2_dns}:/var/www/{site1}

Git deploy it!

git push ec2-remote master


[Edited] To avoid problems regarding json_encode() over results from DB I recommend you to installmysql native driver in your EC2 server

sudo apt-get install php5-mysqlnd