Post

Deploy Rails apps to Ubuntu servers with Kamal

Kamal เป็นเครื่องมือที่ใช้สำหรับ deploy web app ด้วย Docker ในที่นี้เราจะลองใช้เครื่องมือนี้ deploy ลอง server ของเราเอง

Preparing Server

เริ่มจากที่เราติดตั้ง ubuntu server หลังจากติดตั้งเสร็จให้ทำการตั้งค่า firewall1 ให้เรียบร้อยเสียก่อน

จากนั้นตรวจดูว่าเราสามารถ ssh เข้าไปได้:

1
2
ssh ubuntu@SERVER_ADDRESS
exit

แล้วก็ทำการอนุญาตให้ login ได้โดยไม่ต้องใช้ password:

1
2
ssh-copy-id ubuntu@SERVER_ADDRESS
ssh ubuntu@SERVER_ADDRESS

อัพเดทและอัพเกรด server ให้เรียบร้อย:

1
2
sudo apt update
sudo apt upgrade -y

Install Docker2

  • ตั้งค่า Docker’s apt repository:
1
2
3
4
5
6
7
8
9
10
11
12
13
# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
  • ติดตั้ง Docker packages ตัวล่าสุด:
1
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  • อนุญาตให้รัน docker ได้โดยไม่ต้องใช้ sudo:
1
2
3
sudo usermod -a -G docker ubuntu
sudo apt install -y curl git
exit

ตรวจว่า docker รันอยู่มั้ยโดยการ login เข้าอีกครั้ง:

1
2
3
$ ssh ubuntu@SERVER_ADDRESS
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

ใน rails application ที่เราจะสร้าง เราจะใช้ SQLite ในการทดลองนี้ เพราะฉะนั้นเราจะต้องสร้าง directory เพื่อให้ docker มา mounted ไฟล์ไว้ที่นี่:

1
2
3
mkdir hello-storage
sudo chmod 777 hello-storage
exit

Preparing Rails

Prerequisites

สำหรับเครื่อง local ที่ต้องเตรียมสำหรับสร้าง rails application มีดังต่อไปนี้:

  • Ruby 3.3.4
  • Rails 7.2.0.rc1
  • Kamal 1.8.1
  • Docker Desktop

Create new rails application

1
2
3
4
5
rails new hello
cd hello
bundle lock --add-platform aarch64-linux
bin/rails g scaffold Post body:text
bin/setup

แก้ไข routes.rb:

1
2
3
4
Rails.application.routes.draw do
  resources :posts
  root "posts#index"
end

แก้ไขยังไม่ force ssl ก่อน:

1
config.force_ssl = false

เสร็จแล้วลองรันดู:

1
2
bin/rails s
open http://127.0.0.1:3000/

Install Kamal

1
2
gem install kamal
kamal init --bundle

ต่อไปก็แก้ไฟล์ deploy.yml ดังตัวอย่างนี้:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
service: hello
image: phuwanart/hello
servers:
  - SERVER_ADDRESS
registry:
  username: phuwanart
  password:
    - KAMAL_REGISTRY_PASSWORD
env:
  secret:
    - RAILS_MASTER_KEY
ssh:
  user: ubuntu
volumes:
  - "./hello-storage:/rails/storage"

ในที่นี้เราจะใช้ registry ที่ docker hub

จากนั้นไปดูไฟล์ .env:

1
2
KAMAL_REGISTRY_PASSWORD=change-this
RAILS_MASTER_KEY=another-env

เราจะต้องสร้าง access token เพื่อเอามากำหนดใน KAMAL_REGISTRY_PASSWORD

สำหรับ permissions จะให้เป็น Read & Write:

เมื่อ Generate แล้วจะได้ access token มาแล้วก็ copy ไปใส่ .env ได้เลย:

อีกค่าที่ต้องกำหนด RAILS_MASTER_KEY ให้ copy แล้วเอาไปใช้ได้ดังนี้:

1
cat config/master.key | pbcopy

ต้องไม่ลืมแก้ไข database.yml เสียก่อน:

1
2
3
production:
  <<: *default
  database: storage/production.sqlite3

เสร็จแล้วก็ให้ git add และ git commit เสียก่อน

ต่อไปให้รัน Docker Desktop จากนั้นรันคำสั่งนี้:

1
kamal setup

รอจนเสร็จ แล้วตรวจดูผล:

1
2
open http://SERVER_ADDRESS/up
open http://SERVER_ADDRESS/posts

เสร็จ!!!

Conclusion

ยังต้องมีอะไรต้องทำอีกเยอะหลังจากนี้ ไม่ว่าจะเป็นการทำ ssl, เปลี่ยน database ไปใช้ตัวอื่น, ใช้ nginx อะไรเหล่านี้ และที่ต้องหาเพิ่มคือจะใช้ registry ที่ไหนได้บ้างนอกจาก docker hub เพราะว่ามันได้แค่ 1 private repository เท่านั้นเอง

Reference

  • https://note.com/usutani/n/n890c38e68eb7
This post is licensed under CC BY 4.0 by the author.