Kamal
Table of Contents
Deploy Rails applications
I recently deployed a Rails application to Hetzner and AWS China1. Deploying on Hetzner is simple, requiring just two steps: launching a server and deploying. In contrast, deploying on AWS China involves extra steps because Docker Hub is not accessible from servers located in China.
The steps are:
- Launch an Amazon EC2 instance
- Create Amazon ECR repositories to store Docker Hub images
- Create an IAM user and assign only the “AmazonEC2ContainerRegistryFullAccess” permission
- Push Docker Hub images to Amazon ECR on local machine
- Pull images from Amazon ECR on Amazon EC2
- Deploy
Push Docker Hub images to Amazon ECR on local machine
-
Login ECR
aws configure aws ecr get-login-password | docker login --username AWS --password-stdin <aws-ecr-domain> -
Push
basecamp/kamal-proxyimagedocker pull basecamp/kamal-proxy:v0.9.0 --platform linux/amd64 docker tag basecamp/kamal-proxy:v0.9.0 <aws-ecr-domain>/basecamp/kamal-proxy:v0.9.0 docker push <aws-ecr-domain>/basecamp/kamal-proxy:v0.9.0 -
Push
pgvector/pgvectorimagedocker pull pgvector/pgvector:pg17 --platform linux/amd64 docker tag pgvector/pgvector:pg17 <aws-ecr-domain>/pgvector/pgvector:pg17 docker push <aws-ecr-domain>/pgvector/pgvector:pg17
Pull images from Amazon ECR on Amazon EC2
-
Install Docker
sudo apt update sudo apt install -y docker.io sudo usermod -aG docker $USER -
Install AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" sudo apt install -y unzip unzip awscliv2.zip sudo ./aws/install -
Login ECR
aws configure aws ecr get-login-password | docker login --username AWS --password-stdin <aws-ecr-domain> -
Pull
basecamp/kamal-proxyimagedocker pull <aws-ecr-domain>/basecamp/kamal-proxy:v0.9.0 docker tag <aws-ecr-domain>/basecamp/kamal-proxy:v0.9.0 basecamp/kamal-proxy:v0.9.0 -
Pull
pgvector/pgvectorimagedocker pull <aws-ecr-domain>/pgvector/pgvector:pg17
Deploy
- Run
kamal setupthe first time to setup everything. - Run
kamal deployfor subsequent deployments.
Deploy public images
I use Atuin2 for shell history. It supports syncing shell history through a sync server, which can be self-hosted using Docker. Kamal accessories are good at deploying such Docker images. The idea is to transform its Docker Compose example to Kamal accessories:
service: atuin
image: atuin
accessories:
db:
image: postgres:14
host: &host hetzner
env:
clear:
POSTGRES_DB: atuin
POSTGRES_USER: atuin
secret:
- POSTGRES_PASSWORD
directories:
- ./data:/var/lib/postgresql/data/
server:
image: ghcr.io/atuinsh/atuin:v18.10.0
host: *host
cmd: server start
env:
clear:
ATUIN_HOST: 0.0.0.0
ATUIN_OPEN_REGISTRATION: false
RUST_LOG: info,atuin_server=debug
secret:
- ATUIN_DB_URI
proxy:
host: atuin.yejun.dev
app_port: 8888
ssl: true
healthcheck:
interval: 1
timeout: 1
path: "/"
See https://github.com/goofansu/kamal-services for details.
Written on and updated on