Clojure Stack TemplatesClojure Stack Templates

Kamal

Deploy your Clojure application with Kamal

We use Kamal for deployment. It's a CLI tool that simplifies deployment with Docker on your own server.

Install Kamal locally

Add ruby = "3.3.0" to your project's .mise.toml or to the global ~/.mise.toml file.

Install Ruby and Kamal:

brew install libyaml  # or for Ubuntu: `sudo apt-get install libyaml-dev`
mise install ruby
gem install kamal -v 2.5.3

Deploy from local machine using Kamal

At the root directory of your project, please create a .env file with appropriate variables for your project:

SERVER_IP=192.168.0.1
REGISTRY_USERNAME=your-github-username
REGISTRY_PASSWORD=personal-github-token
APP_DOMAIN=app.domain.com
SESSION_SECRET_KEY=secret-key
  • SERVER_IP is the IP address of your server.
  • REGISTRY_USERNAME is your GitHub username, that we will use to push the Docker image to the GitHub registry.
  • REGISTRY_PASSWORD is your personal access token with write:packages and read:packages scopes. You can create it in your GitHub account settings.
  • APP_DOMAIN is your application domain name. It will be used to generate the SSL certificate for your application and make routing at reverse proxy.
  • SESSION_SECRET_KEY can be any random string. It will be used to sign the session cookies.

Important

.env must not be included to the system control version of your repository.

SSH access to the server from CI

SSH_PRIVATE_KEY - an SSH private key without password that you should create and add the public part of it to the server's ~/.ssh/authorized_keys to authorize from the CI worker.

To generate SSH keys, run:

ssh-keygen -t ed25519 -C "your_email@example.com"

As a result you will be able to deploy from GitHub Actions.

Create GitHub Token

To create a personal access token, go to your GitHub account settings, navigate to "Developer settings" > "Personal access tokens" > "Tokens (classic)" and click on "Generate new token". Make sure to select the write:packages and read:packages scopes.

GitHub Token

This token you will put to REGISTRY_USERNAME env var only locally. In CI we will be using secrets.GITHUB_TOKEN which is automatically created by GitHub Actions for each workflow run.

First deploy to a fresh server

Important

Before first deployment, please:

  • update repository url in LABEL of your Dockerimage
  • create your repository on GitHub (it can be empty)

This is important for correct attribution of the image and ability to push image to GitHub registry from GitHub Actions using built-in GitHub Access Token from secrets.GITHUB_TOKEN in the CI workflow file.

bb kamal setup

This first run will take some time to install Docker and other dependencies on the server. If everything ok you should see the similar output at the end:

...
  INFO [9b741bb6] Finished in 0.187 seconds with exit status 0 (successful).
  Finished all in 210.2 seconds
Releasing the deploy lock...
  Finished all in 237.7 seconds

And the application should be available at your application domain you set in APP_DOMAIN env var.

If you already have a server with Kamal installed, you can skip this step.

Info

We run Kamal via Babashka task as we changed the default location for deployment config to .kamal/deploy.yml to keep Kamal files in single place.

GitHub Packages Registry

If LABEL in Dockerimage was set up correctly, after first deployment you will see your image in the GitHub Packages on the repository page:

GitHub Token

Regular deployment

bb kamal deploy

Deploy from GitHub Actions

Setup secrets for Actions at your repository settings Settings > Secrets and variables > Actions > New repository secret:

SERVER_IP=192.168.0.1
APP_DOMAIN=app.domain.com
SSH_PRIVATE_KEY=secret-ssh-key
SESSION_SECRET_KEY=secret-key

GitHub Token

Tip

We use .env and GitHub Secrets for convenience and simplicity in the tutorial. The recommended approach is to fetch secrets from systems that are designed to store sensitive data. Read more at Kamal documentation.

Then you can just push to master branch, or merge PR to master and GitHub Actions will automatically deploy your application to the server.

Full cycle of regular deployment from GitHub Actions should take between 2 and 3 minutes.

On this page