Deploy your apps on a Raspberry Pi using Kamal
()Back to homeSetting up the Raspberry Pi
Use Raspberry Pi imager to flash the latest Raspberry Pi OS to a microSD card. Use the Lite version of the OS if you only intend to use the Pi as a server.
Don't forget to enable SSH in the "Services" tab and adding your computer's public key.
Once the OS is flashed and the Pi is booted, SSH into the Pi using the following command with the hostname and username you defined in Raspberry Pi Imager:
ssh <USERNAME>@<HOSTNAME>
The next steps will require you to be able to SSH into the Pi with the root user. To do so, copy your public key to the root user's authorized_keys
file:
sudo cp ~/.ssh/authorized_keys /root/.ssh/
The raspberry Pi should now be ready, as Kamal will handle the rest of the setup.
Installing Kamal
On a Mac, install ruby.
brew install ruby
brew link --overwrite ruby --force
The second version allows to link brew to the latest version of ruby (cf this thread)
Add ruby to your PATH in your .bashrc
or .zshrc
:
export PATH=$(brew --prefix ruby)/bin:$PATH
export PATH=$(gem environment gemdir)/bin:$PATH
Setting up the Github container registry
On Github, create a personal access token with the read:packages
and write:packages
permissions. Kamal will use this token to push the Docker image to the Github container registry.
Set it as an environment variable:
export KAMAL_REGISTRY_PASSWORD=<YOUR-TOKEN>
You can now follow Kamal's setup instructions and get your site up and running!
Github actions
On the page of the Github package Kamal created, link the package to its related repository. You should also got to Package settings > Manage Actions access
and allow the repository to write the package.
Then, add the following Github action to your repository:
name: Deploy
on:
push:
branches:
- main
jobs:
Deploy:
runs-on: ubuntu-latest
env:
DOCKER_BUILDKIT: 1
KAMAL_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2.2
bundler-cache: true
- name: Install dependencies
run: gem install kamal
- uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- run: kamal version
- run: kamal registry login --verbose
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Deploying two builds could cause locking issues when the first is cancelled.
- run: kamal lock release --verbose
- run: kamal redeploy --verbose
Using the gh
cli, you can use the following command to generate an SSH key pair and set the private key as a secret in your repository:
REPO=$(gh repo view --json nameWithOwner --jq .nameWithOwner | sed 's/\//\-/g')
DATE=$(date '+%Y-%m-%d %H:%M:%S')
KEY=$TMPDIR$REPO
PUB_KEY=$KEY.pub
ssh-keygen -t rsa -b 4096 -f $KEY -P "" -C "$REPO $DATE"
ssh-copy-id -i $PUB_KEY root@<HOSTNAME>
gh secret set SSH_PRIVATE_KEY --body "$(cat -p $KEY)"