DEV Community

loading...

Quick manual deploy to EC2 with github

Alexey
Web++
Updated on ・3 min read

It's not cheap to have a great automated build/deploy process. I've found that for prototyping services, it's very helpful to be up and running with a deploy process ASAP. This article is about my preferred way to bootstrap a deploy process (with AWS/EC2), allowing for future automation and improvements if the prototype is successful.

The setup I use is - spinning up an on-demand instance in EC2, SSH'ing into it, and doing git pull via deploy keys. I often run the server in a screen launched through SSH. I pair this with an nginx/SSL configuration with free SSL certificates via certbot: https://dev.to/alexeydc/modern-https-configuration-2h86

Deploy keys

Github has a notion of deploy keys, designed for this very purpose.

Step 1: Generate keys

On the machine you want to deploy to, run:

ssh-keygen -t ed25519 -f ~/.ssh/my_project_deploy_key -C "your_email@example.com"
Enter fullscreen mode Exit fullscreen mode

Note the -t ed25519 - an upgrade from RSA to elliptic curve cryptography. More info: https://medium.com/risan/upgrade-your-ssh-key-to-ed25519-c6e8d60d3c54.

In this case, we're only going to use the key to pull the repo on a deploy - so you don't really need the -C flag. But e.g. if you develop on a remote machine and plan to commit with the key - it's helpful to tie it to your github email.

Step 2: Add the public key to github

In the target repository, go to Settings -> Deploy keys.

Click Add Deploy Key.

Give it a descriptive title, like "Production MyProject EC2". Copy-paste the contents of ~/.ssh/my_project_deploy_key.pub into the key field, don't tick Allow write access (or do - but for deploys you shouldn't want to).

Step 3: Configure git to use the key

Actually, if we had named the key id_rsa, git would already have access to it (just make sure to clone via the git: URL, not https:).

However, then you are limited to just one repository for this machine, and... are forced to use the default key name.

Instead of being handcuffed by defaults, let's set up the config ( https://snipe.net/2013/04/11/multiple-github-deploy-keys-single-server/ ):

vim ~/.ssh/config

# Then add this type of config to the file
Host github.com-any_string_identifying_our_service
HostName github.com
IdentityFile /home/ubuntu/.ssh/my_project_deploy_key
User git

# You can have entries for multiple repos
Host github.com-another_string_for_another_project
HostName github.com
IdentityFile /home/ubuntu/.ssh/other_deploy_key
User git

Enter fullscreen mode Exit fullscreen mode

Then you need a special clone command, using the host defined above. Let's say our github organization name is shiny_deploys_inc, and the repository name is deploy_alpha. The web URL for the repo would be https://github.com/shiny_deploys_inc/deploy_alpha. Here is the clone command, given the example config above:

git clone git@github.com-any_string_identifying_our_service:shiny_deploys_inc/deploy_alpha.git
Enter fullscreen mode Exit fullscreen mode

After that, git pull should work as usual to update the project.

What next?

This barebones setup can work quite well to get started, but it's far from being complete.

Each deploy will involve a bit of downtime. One way to get around that is with pm2 ( https://futurestud.io/tutorials/pm2-cluster-mode-and-zero-downtime-restarts ).

Eventually (e.g. as more people start to work on the project), it becomes a bad idea to SSH into an instance to deploy, and deploys can grow more complex. A first step could be to simply send a message to the server so it can pull the new version and start it. It's possible to set up github webhooks, but it's also possible to configure the server to be another remote, push directly to the server, and have it perform a relaunch on deploy https://gist.github.com/noelboss/3fe13927025b89757f8fb12e9066f2fa

I'll write more about these configurations in an upcoming post.

Discussion (0)