Dokku Deploy from Container Registry with Github Action
Photo by Dominik Lückmann.
After years of working with Jenkins as a build system for your Docker images, VM images, RPM packages, jar files, and so on, Github Actions feels as a breeze of fresh air in desert land. Your free Github plan comes with 2,000 free minutes of execution time, so definitely give it a shot.
This specific post will focus on a particular matter on hand: build and push your application Docker image to Github Packages Container Registry and then deploying the same image to Dokku host.
Dokku is a lightweight, fast, and open source alternative to Heroku, bring your own hardware and have your PaaS ready for action.
All the necessary introductions have been made, so let’s jump to business.
Prerequisites
This post assumes that you’ve done your homework and you have your Dockerfile with your application ready. You can docker build
on your machine as well as on the cloud (or somebody else’s machine).
I also assume that you have your Dokku host provisioned, you have root access over ssh to the host machine or you can sudo
without a password.
The rest of the guide will cover from there.
Prepare the Github Action Secrets
In your Github repository, you will need to add your credentials to Dokku host. After the image is built and published to the Container Registry, Github Action will ssh to your Dokku host and deploy the newly built image.
In this case add the following secrets:
DOKKU_HOST
- the hostname of your Dokku hostDOKKU_USER
- the username to login to your Dokku hostDOKKU_PRIVATE_KEY
- the private key to acess your Dokku host. Don’t forget to add the public key to your~/.ssh/authorized_keys
file on Dokku host.
Authorize Dokku to work with Container Registry
Your Dokku host needs access to the Github Container Registry to pull down the images on deployment. I rather recommend pre-authorizing Dokku host with the registry instead of doing the authorization every time you deploy. The latter option can leak your Personal Access Token (PAT) to the deployment logs, which would be unfortunate (Github Copilot auto suggests security risk
).
Get your Github Personal Access Token and make sure that the token has access to read private packages as shown on the image below:
As you’ve generated the PAT, copy it’s value to the clipboard and execute the following on Dokku host:
sudo -s -u dokku # Configure authentication for dokku user
export PAT=<your-access-token-here> # Space is the beginning of this command is on purpose
echo $PAT | docker login --username your-github-username --password-stdin ghcr.io
exit # Exit from dokku user
Once executed, you shall observe Login Succeeded
in the output.
Install Dokku plugin for Deployment from Registry
Dokku has a plugin for deploying your application from container registry. This essentially helps us eliminate the need to build the application image on Dokku host. Deploy-from-registry Dokku Plugin github repository. These are the short instructions on setup:
dokku plugin:install https://github.com/yurihs/dokku-deploy-from-registry.git deploy-from-registry
dokku deploy-from-registry:set-remote-image-repo testapp ghcr.io/${{ github.repository_owner }}/${{ github.repository }}
Github Action
Github Action definition is another flavor of yaml file. You have to put it in your repository under .github/workflows/
directory. Example file path is .github/workflows/delivery.yml
, but get creative and name it whatever you prefer.
name: Deployment
on:
push:
branches: [ main ]
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64
push: true
tags: ghcr.io/${{ github.repository_owner }}/${{ github.repository }}:latest,ghcr.io/${{ github.repository_owner }}/${{ github.repository }}:${{ github.sha }}
deploy:
needs: docker
runs-on: ubuntu-latest
environment: staging
steps:
- name: Deploy application
uses: D3rHase/ssh-command-action@v0.2.1
with:
HOST: ${{ secrets.DOKKU_HOST }}
USER: ${{ secrets.DOKKU_USER }}
PRIVATE_SSH_KEY: ${{ secrets.DOKKU_PRIVATE_KEY }}
COMMAND: |
dokku deploy-from-registry testapp ${{ github.sha }}
docker tag dokku/testapp:${{ github.sha }} dokku/testapp:latest
In case you access your dokku host with unprivileged user, add sudo
to the beginning of the last three lines of the COMMAND
section.
Now, your application will be deployed to your Dokku host every time you push to main
branch of your repository.
Thanks for reading, stay active, close your rings, and see you next time.