Nowadays, CI/CD became an essential part when developing software. It can save tons of money, time and reduce risks… In this article, I will show you how did I set up CI/CD for my personal blog with free services.
If you are not familiar with any services, check their definitions:
- GitHub Action: A CI/CD platform of GitHub. https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions
- DigitalOcean Container Registry: A place to store and manage private Docker images, have a free plan for 1 repository.
- DigitalOcean Droplets: A virtual machine provider. Cheap, stable, and easy to set up.
Firstly, have a look at this workflow.
- Every time we push a new commit to GitHub, it will start processing GitHub Actions workflow.
- GitHub Actions will build a Docker image in its runner and push that image to Container Registry.
- GitHub Actions then will connect to Droplets and deploy the image from Container Registry to that Droplets.
Let’s see how to set up this workflow.
There are some secret variables that you need to use in the GitHub Action
workflow.yml file, so it should be better if they are encrypted by storing them in Github Secrets.
You can go to repository
Settings → Secrets → Actions, then click
New repository secret.
There are some variables we need:
- DIGITALOCEAN_ACCESS_TOKEN: A token that you have generated to access the DigitalOcean API.
DigitalOcean dashboard → API → Token/keys → Generate New Token(Remember to check both Read and Write permission)
- HOST: your ssh host (Droplets ipv4)
- PASSPHRASE: to encrypt the private key, generated when you create ssh keys for Droplets.
- SSHKEY: the content of ssh private key. ex raw content of ~/.ssh/id_rsa
- USERNAME: ssh username, default:
Now we have enough secret variables to use in our CI/CD workflow file.
- Create a directory called
.github/workflowsin the repository directory.
- In that directory, create a new file called
build-and-deploy.ymland add the following code:
- Controlling when the workflow will run: In this case, every time we have a push in the master branch.
- Define some environment variables that don’t need to be encrypted.
- IMAGE_NAME: your Docker image name
- REGISTRY: your DigitalOcean Registry Container URL
- We have 2 jobs here: run
build_and_pushthen after it finishes, run
Some things need to be noted in the YAML files:
- Because DigitalOcean Container Registry only has 500MB for the free plan, so we should remove all old images after we build and push the new image.
- When deploying, it is better to stop running the container, remove it then run the new image (will pull it from DigitalOcean Container Registry).