Skip to content

Instantly share code, notes, and snippets.

@acidtib
Created August 28, 2023 17:56
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save acidtib/df6fcdacfcf6063d2ec3d399e5ae8f5c to your computer and use it in GitHub Desktop.
Save acidtib/df6fcdacfcf6063d2ec3d399e5ae8f5c to your computer and use it in GitHub Desktop.
kamal + github actions

Example of Kamal deployment from Github Actions.

Add your applications .env variables to the Github repo as a repository secret, you can find this under the repo settings => secrets and variables => actions

https://github.com/username/repo_name/settings/secrets/actions

you are going to need an ssh private key that your deployment server is aware of (add public key to servers .ssh/authorized_keys) and add the ssh private key as a repo secret

create action workflows

.github/workflows/deploy.yml

heroku style, push code trigger kamal deploy you can extend the workflow to include testing and deploy based on test results

name: CD

on:
  push:
    branches:
      - main

jobs:
  Deploy:
    if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
    runs-on: ubuntu-latest

    env:
      DOCKER_BUILDKIT: 1
      RAILS_ENV: production
      RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
      KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }}
      KAMAL_REGISTRY_USERNAME: ${{ secrets.KAMAL_REGISTRY_USERNAME }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.2.2
          bundler-cache: true

      - name: Install dependencies
        run: |
          gem install specific_install
          gem specific_install https://github.com/basecamp/kamal.git 

      - uses: webfactory/ssh-agent@v0.7.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@v2
    
      - name: Run deploy command
        run: kamal deploy

optional kamal workflow

this this workflow you can run kamal arbitrary commands from the github actions panel, when running the workflow manually it will ask for a command input thats executed inside the action.

.github/workflows/kamal.yml

name: KAMAL Command

on:
  workflow_dispatch:
    inputs:
      command:
        description: "KAMAL command to run"
        default: "kamal app details"

jobs:
  Command:
    runs-on: ubuntu-latest

    env:
      RAILS_ENV: production
      RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
      KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }}
      KAMAL_REGISTRY_USERNAME: ${{ secrets.KAMAL_REGISTRY_USERNAME }}

    steps:
      - name: Checkout
        uses: actions/checkout@v3
      
      - uses: webfactory/ssh-agent@v0.7.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.2.2
      
      - name: Install dependencies
        run: |
          gem install specific_install
          gem specific_install https://github.com/basecamp/kamal.git main

      - name: Run KAMAL command
        run: ${{ github.event.inputs.command }}
@nogara
Copy link

nogara commented Sep 12, 2023

Thank you very much for this contribution! It worked perfectly!

The only thing I thought could be a little dangerous is that by using gem specific_install https://github.com/basecamp/kamal.git main you may have differences in the behavior of deploys. I just got bitten by a change in the PR basecamp/kamal#438 , because I wasn't pushing the env files before deploy...

@acidtib
Copy link
Author

acidtib commented Sep 12, 2023

@nogara yea that PR also slapped me on the face :), i get around it by defining the git sha to install gem specific_install -l https://github.com/basecamp/kamal.git -r 2962f545b990d5855d4ee5d85f7d8927cee36834

@luckylu
Copy link

luckylu commented Oct 7, 2023

I just install kamal with speific version
gem install kamal -v 0.16.1

@ahoy196
Copy link

ahoy196 commented Feb 13, 2024

This configuration worked fine for me for a while. However, it wasn't long before I started getting lock file errors from Kamal during the build. I think it was triggered by two simultaneous builds where I manually cancelled the older one.

I did two things to get it working from that point. First, limit concurrency to 1 for the GitHub action. Second, in every build, release the lock before trying to acquire it as part of kamal deploy. More below to help.

concurrency:
   group: production
   cancel-in-progress: true

Insert this into your steps

name: Release Kamal lock
   run: kamal lock release

@dorianmariecom
Copy link

dorianmariecom commented Feb 20, 2024

Here is the final workflow I ended up with:

name: Deploy
concurrency:
  group: production
  cancel-in-progress: true
on:
  push:
    branches:
      - main
jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      DOCKER_BUILDKIT: 1
      RAILS_ENV: production
      RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
      KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }}
      KAMAL_REGISTRY_USERNAME: ${{ secrets.KAMAL_REGISTRY_USERNAME }}
    steps:
      - uses: actions/checkout@v4
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.3.0
          bundler-cache: true
      - run: gem install kamal
      - uses: webfactory/ssh-agent@v0.9.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
      - uses: docker/setup-buildx-action@v3
      - run: kamal lock release
      - run: kamal redeploy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment