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
Github has a notion of deploy keys, designed for this very purpose.
On the machine you want to deploy to, run:
ssh-keygen -t ed25519 -f ~/.ssh/my_project_deploy_key -C "firstname.lastname@example.org"
-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.
In the target repository, go to Settings -> Deploy keys.
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).
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
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
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 email@example.com_string_identifying_our_service:shiny_deploys_inc/deploy_alpha.git
git pull should work as usual to update the project.
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.