DEV Community

Cover image for If your dokku push doesn't trigger a build
cerico
cerico

Posted on

If your dokku push doesn't trigger a build

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 } 
Enter fullscreen mode Exit fullscreen mode

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 } 
Enter fullscreen mode Exit fullscreen mode

You'll need to add the letsencrypt dokku plugin

dokku plugin:install letsencrypt 
Enter fullscreen mode Exit fullscreen mode

and you can add a remote

g remote add dokku dokku@ol14.cc:kiseljak 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 }} 
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)