If your dokku push doesn’t trigger a build

RMAG news

If your dokku push doesn’t trigger a build

Dokku is a great cost-effective way to host your Rails apps, and is well documented elsewhere. I followed the instructions at https://marketplace.digitalocean.com/apps/dokku to create my dokku droplet. But there are a couple of caveats. The first is you’ll need to increase swap size on your VM for dokku to work. I created a zsh/bash function to do that

Increase Swap Size

bump () {
sudo install -o root -g root -m 0600 /dev/null /swapfile
sudo dd if=/dev/zero of=/swapfile bs=1k count=2048k
sudo mkswap /swapfile
sudo swapon /swapfile
echo “/swapfile swap swap auto 0 0” | sudo tee -a /etc/fstab
sudo sysctl -w vm.swappiness=10
echo vm.swappiness = 10 | sudo tee -a /etc/sysctl.conf
}

Create Application

You also need to create your application before you can deploy it. There are a number of things to do here, so i also combined them into one function

newapp () {
local email=“cityguessr@skiff.com”
local domain=“ol14.cc”
dokku apps:create $1
dokku postgres:create $1db
dokku postgres:link $1db $1
dokku domains:set $1 $1.$domain
dokku letsencrypt:set $1 email $email
dokku letsencrypt:enable $1
dokku letsencrypt:auto-renew
}

You’ll need to add the letsencrypt dokku plugin

dokku plugin:install letsencrypt

and you can add a remote

g remote add dokku dokku@ol14.cc:kiseljak

and it will push your app and build it

But will it? (Push doesn’t trigger a build)

I couldn’t get this to work consistently, and I couldn’t find much helpful on the web at all. But I was able to trigger a build from the dokku server itself with the following

dokku ps:rebuild kiseljak

So I knew the app was fine, but doing a git push wasn’t triggering a rebuild. The feedback from the git push isn’t that helpful as it reports a successful push but no build is triggered

The solution

The solution that worked best for me was to create a global post-receive hook that will trigger the build automatically

☁ dokku@ol14:~ ➜ cat ~/.config/git/hooks/post-receive
REPO_NAME=$(basename $(pwd))

if command -v dokku &> /dev/null
then
DOKKU_ROOT=“/home/dokku” dokku git-hook $REPO_NAME
fi

Your hooksPath may be different, you can check or set it in your gitconfig

☁ dokku@ol14:~ ➜ cat ~/.gitconfig | grep core -A2
[core]
editor = vi
hooksPath = ~/.config/git/hooks

If we return to the pre-recieve hook, this sets a git-hook of the repository name, which gets set on app creation (so will work for all newly created applications on the dokku server). On git push, the post-recieve hook is activated and the build process starts

Github Action

Naturally, you’ll want this to work on a github action rather than pushing directly to dokku. Here is an example of a working action

☁ brew@kelso:kiseljak cat .github/workflows/dokku.yml
name: dokku”

env:
url: kiseljak

on:
push:
branches:
main

jobs:
deploy:
runs-on: ubuntu-22.04
steps:
name: Cloning repo
uses: actions/checkout@v4
with:
fetch-depth: 0

name: Push to dokku
uses: dokku/github-action@master
with:
branch: main”
git_remote_url: ssh://dokku@64.23.226.251:22/~/kiseljak”
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}

The git_remote_url line is the most important to get right here. I could not get this to work via domain, only via ip. I’m not sure if this is someting to do with ipv6 or not, but to get working via domain may need extra work. If you’re using dokku it means you’re using your own vps, so you will have a static ip to use here

Dockerfile caveat

One other thing whih sometimes seems to get in the way of dokku is the Dockerfile that Rails provides by default. In some applications this seemed to be a problem and in others it wasn’t. If you don’t nee the Dockerfile, just rename to Dockerfile.orig