Let’s create an EC2 instance where we’ll deploy the API with Docker.
- First, connect to your AWS account, go to the EC2 section and pick a distribution. I recommend Ubuntu 20.04 LTS for this tutorial.
- Pick an instance: we’re not gonna go crazy here. We’ll just pick a relatively small one: a
t2.medium
.
- Now launch the instance.
- Create an elastic IP address and associate it to the running instance. This way this IP won’t change every time we restart the instance.
- Add a new security group (I named it fastapi) to allow inbound traffic on port 8000.
- Then, add it to the instance security groups:
Now the instance is ready to accept requests on port 8000.
- SSH into it using your terminal.
- Install
docker
anddocker-compose
by following the official Docker documentation for ubuntu - Generate an ssh key and add it to your Github account so that it can perform git clones seamlessly (we’ll use this in the following section)
Create a deployment workflow on Github Actions
Github Actions is Github’s CI/CD service. It allows you to automate testing, building and deploying applications based on events such as git commits, merges or pull requests.
To learn more about Github Actions, have a look at this link.
To add a workflow in your repo, click on the Actions tab.
Then, click on setup a workflow yourself.
A YAML file will be automatically created inside a workflows
folder which will be itself created in a .github
folder at the root of the repo.
In our case, we will set the workflow to be triggered on push requests only on the main branch.
The job that will be triggered will be run on a remote server that Github Actions will connect to through the SSH Remote Commands. In other situations, this job may run on Github runners, i.e. instances provided by Github.
SSH Remote Commands is a custom Github Action that you can find from the marketplace. It’s free to use, you’ll just have to call it after the uses
section.
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [main]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
name: Build
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: executing ssh commands using ssh key
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST}}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
script: |
rm -rf anonymization-api
git clone git@github.com:ahmedbesbes/anonymization-api.git
cd anonymization-api
sudo docker-compose build
sudo docker-compose up -d
The SSH Remote Commands Github Action will be called with the following arguments
- host: the hostname of the server (i.e. its public IP)
- username: the ssh username
- key: the content of ssh private key
- script: the script that will be executed once the ssh connection is established
The script will list the commands that will be run on the server once the SSH connection is established: it’ll:
- clone the repo
- cd into it
- run the docker-compose build and up commands.
$ git clone git@github.com:ahmedbesbes/anonymization-api.git
$ cd anonymization-api
$ sudo docker-compose up --build -d
The previous arguments host
, username
and key
will not be hard-coded in the YAML file. They’ll never be. This information is sensitive.
They will rather be stored as Github Secrets and referenced with the $ sign, the same way you would call environment variables.
To create Github secrets, go to the settings of the repository and click on Secrets on the left tab. Github Secrets are always defined in the scope of a Github repo.
Then define your secrets by setting their name (in capital letters) and their value.
Here’s how you would set the USERNAME
secret for example.
Now you can commit, push and look out for the magic happening!
Once you push your code (after testing that everything works fine locally) you will notice, after clicking on the Actions tab that a new runis queued to start.
By clicking on it, you can see the different steps of the build.
Once the API is successfully deployed on your remote server, fire up Postman and execute some requests on the API endpoint to check if it’s working properly.
Yahoo! 🎊 Now the API is deployed, working, and ready to accept requests.