3 min read

Using Kamal to deploy Shipyrd and also update Shipyrd

Shipyrd is Rails app that’s packaged as a Docker container and published on Docker Hub and GitHub container registry. It’s a simple deploy tracking and coordination product that shows you the relevant deploy information for an application as well as claiming an environment when working with a team.

The hosted web version is essentially a clone of the open-source version with a few additional features added in. Since I’m just working on Shipyrd as a small side project I wanted to ensure that I keep the setup and deployment as simple and straightforward as possible. And why not deploy Shipyrd with the deployment tool that it’s built to monitor deploys for? Kamal.

Here’s how I have everything setup to make this easy within the existing open source application. This flow can be used for any container-based application where you want to keep the deploy flow separate from the primary source code.

To start with, you’ll want to add a deploy directory within your application, once you’ve added that, you’ll also want to ignore that from the application’s git via .gitignore.

cd ossapp
mkdir deploy
cd deploy

Create the deploy directory

/deploy

.gitignore

Go ahead and cd into your new deploy/ directory within your application’s directory and we’ll set up Kamal with Bundler and run init. This assumes that you have a recent version of Ruby installed, you can also use the Docker container version if that’s preferred.

source "https://rubygems.org"

gem "kamal"

Gemfile

bundle install
kamal init

Initialize Kamal

You should now have your base deploy recipe(config/deploy.yml), some sample hooks(.kamal/hooks), and a secrets(.kamal/secrets) file to work with.

I’m not going to go through the full application build, deploy, and setup but just the relevant items for deploying the container-based application with Kamal.

You’ll want to set the service to the name of the application, in our case, shipyrd.

service: shipyrd

config/deploy.yml

Next, the organization/user and container name for the registry:

image: shipyrd/hosted

config/deploy.yml

And lastly, configure your builder to just build the container with the parent directory as your build context.

builder:
  arch: amd64
  dockerfile: "../Dockerfile"
  context: "../"

config/deploy.yml

After that, you’ll configure your role to run with the necessary env, a host to put it on, and maybe some resource limitations. Depending on what you need for env you’ll probably need to add some secrets to .kamal/secrets as well so that they’re loaded properly within Kamal.

Altogether, that should look something like this:

service: shipyrd

image: shipyrd/hosted

builder:
  arch: amd64
  dockerfile: "../Dockerfile"
  context: "../"

servers:
  web:
    host: 123.456.78.9
    env:
      secret:
        - SHIPYRD_HOST
        - SHIPYRD_HOOKS_HOST
        - SHIPYRD_SECRET_KEY_BASE
        - SHIPYRD_ENCRYPTION_DETERMINISTIC_KEY
        - SHIPYRD_ENCRYPTION_PRIMARY_KEY
        - SHIPYRD_ENCRYPTION_KEY_DERIVATION_SALT
        - SHIPYRD_DATABASE_URL
        - SHIPYRD_QUEUE_DATABASE_URL
        - SHIPYRD_CABLE_DATABASE_URL

config/deploy.yml

But maybe this is for your fork of Discord or Chatwoot instead. Kamal makes it dead simple to deploy an existing application you need to customize that’s already ready to run in a container.

There’s also a PR that was just merged in that makes hosting an accessory-only Kamal setup even easier. If you don’t need to customize anything with the hosted application then this is an even easier approach to get your open-source application up and running.

Allow accessory only configurations by djmb · Pull Request #1501 · basecamp/kamal
If there are accessories defined in the configuration, we'll not require servers to be defined as well. This allows for accessory-only configurations which allows you to run external images wit…