How to Deploy to DigitalOcean Kubernetes with GitHub Actions
In this post, I will document how I automate deploying my docker images to Digital Ocean Kubernetes using GitHub actions.
Create Digital Ocean API Token
We need to have a Digital Ocean personal token to give the Github action access to the Kubernetes cluster. It can be created from here. The expiration needs to be set to “No expiry” for this automation to keep working in the future.
After the token is generated, we need to use it in the Github action script, but to avoid having the token in plain text in the Github script, we store it in the Github repository’s secret, and you can do that from:
https://github.com/{username}/{repo-name}/settings/secrets/actions/new
The name will be used in the GitHub action script.
Install Digital Ocean Commandline (doctl)
This can be done easily using this step code.
- name: Install doctl
uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
Saving Kubernetes Cluster
- name: Save DigitalOcean kubeconfig
run: doctl kubernetes cluster kubeconfig save the-cluster-id
Rolling out the deployment
# Kubernetes rollout the latest image
- name: Kubernetes rollout the latest image
run: kubectl -n {namespace} rollout restart deployment {deployment-name}
Those were the minimum steps that are needed to get the auto-deploying working, but in my production setup, I do more steps including building the image with the right tag and deploying it to the staging/production cluster depending on the branch name.
Full example of microservice Github action yml file.
# This is a basic workflow to help you get started with Actions
name: docker push and build
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [master, develop]
tags:
- "v*"
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Docker meta
id: meta
uses: docker/metadata-action@v3
with:
# list of Docker images to use as base name for tags
images: |
docker-id/image-name
# generate Docker tags based on the following events/attributes
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v2
with:
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Install doctl
uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
# Save the right kuberenetes context depending on the branch name
- name: Save DigitalOcean kubeconfig Staging
if: github.ref == 'refs/heads/develop'
run: doctl kubernetes cluster kubeconfig save qikfgax1-qikfgax1-aszz-qweqw-bb53721318
# Save the right kuberenetes context depending on the branch name
- name: Save DigitalOcean kubeconfig Production
if: github.ref == 'refs/heads/master'
run: doctl kubernetes cluster kubeconfig save qikfgax1-3ddc-12312-5561-12341321
# Kubernetes rollout the latest image
- name: Kubernetes rollout the latest image
run: kubectl -n karma-stats rollout restart deployment karma-stats