I'm kind of new to both EC2 and Git, and I have just set up my first instance of EC2, using a clean Amazon Linux AMI. I also installed MySQL, Apache and PHP and opened some ports to make it work as a normal web server, responding to an elastic IP as well.
Now, my code is on a private repo on GitHub, and I would like to perform simple deployments by doing git pull
or something like that. Git is also installed on the server already. I know I could set up my git repo on the server using my personal ssh key, but it seems odd. I guess another solution would be to create a new GitHub user and use it on the server, but it doesn't seem right either.
How do I achieve this in an elegant, safe way?
To avoid having to keep an SSH private key on your EC2 instance, people often use a workflow that involves pushing to that remote server in order to deploy. Essentially, you set up a bare git repository there with a pre-receive
hook that deploys to another directory. There is a simple example of doing this in this tutorial. Then you only need to have your SSH public key in ~/.ssh/authorized_keys
on the server. However, with this workflow, you couldn't deploy directly from your GitHub repository - you would need to pull it locally and then push to the EC2 machine.
An alternative is to use GitHub's deploy keys mechanism. This would involve creating a new SSH key-pair on your EC2 instance, and adding the public key as a deploy key into your private repository on GitHub. Then you can pull directly from your private GitHub repository to your EC2 instance.
I just solved such situation by following the tutorial that Mark Longair pointed before. The only problem I got was in the creation of the bare git repository. So let me resume how I solved it.
- I already have my github private repository.
- I created the EC2 Linux AMI (Ubuntu for practical procedures)
- I've installed git, mysql, php, apache and ssh at the EC2 instance, and added my public ssh key to the
/home/ubuntu/.ssh/authorized_keys
file.
- Once at the EC2 instance I created two folders, the first one to hold the repository (I just named it as I've named my github repository), and the second one to hold the site(s):
mkdir sitesrepo.git websites
.
- Then I went to the folder that was going to hold the repository and initialized the bare repository:
cd sitesrepo.git && git init --bare
I created the hook file via vim with the following content in a file named post-receive
and then I made it executable via chmod +x post-receive
(just as the tutorial stated). That file must be placed at /home/ubuntu/sitesrepo.git/hooks
#!/bin/sh
GIT_WORK_TREE=/home/ubuntu/websites git checkout -f
Here's where my steps differ from the tutorial mentioned before: A bare git repository has a conflict where it can't hold the worktree being a bare repository (It doesn't make sense since it's a bare repository. Non-bare repositories are intended to have a working space, i.e. a worktree). Fortunately you can manually set up the repository config
file. So by editing the file /home/ubuntu/sitesrepo.git/config
you must guarantee to have something like this:
[core]
repositoryformatversion = 0
filemode = true
bare = false
worktree = /home/ubuntu/websites
[receive]
denycurrentbranch = ignore
Now, at your own machine, at your git local repository working folder, the idea is to add a new remote repository. Currently you have configured by default origin
which tells your repository to push your content into github's repository. The tutorial calls such remote repository web
. So you have to run once: git remote add web ssh://mysite.com/home/ubuntu/sitesrepo.git && git push web +master:refs/heads/master
. The subsequent pushes can be done via a simple git push web
Depending on how many sites you are planning to hold, you must configure your apache sites-enabled
hosts. Also, since you're using apache, don't forget to change the web folder to point to /home/ubuntu/websites
, because by default it points to /var/www
But you're ready to go, just don't forget to restart the apache service after defining the new web folder.
Hope this helps with your question.