Deploy Rails 8 với Kamal 2
Chào các bạn! Rails 8 ra mắt mang theo triết lý "No-PaaS" mạnh mẽ. Với sự kết hợp của SQLite (Solid Stack) và Kamal 2, bạn có thể tự vận hành một hệ thống chuyên nghiệp, Zero-downtime trên máy ảo cá nhân mà không cần đến các dịch vụ Cloud đắt đỏ.
Bước 1: Khởi tạo dự án Rails 8 (Local)
- Tạo dự án mới:
rails new rails_deploy
cd rails_deploy
- Tạo trang chủ: Để tránh lỗi 404 khi truy cập IP, hãy tạo một Controller đơn giản.
bin/rails generate controller Home index
Mở config/routes.rb và thêm: root "home#index".
Bước 2: Chuẩn bị Server Multipass
Chúng ta dùng Multipass để giả lập một server Ubuntu ngay tại máy local, vì mình không có IP của cloud như AWS, Heroku,... nên setup tạm ở local cho tiện sử dụng, vì mục đích bài này chỉ là việc setup deploy với kamal nhé.
- Tạo máy ảo (Cấp 20GB ổ đĩa để Docker thoải mái build):
multipass launch --name rails-server --disk 20G --memory 2G
- Lấy IP máy ảo:
multipass list
👉 Ghi lại IPv4 (Ví dụ: 10.106.158.38).
Bước 3: Thiết lập Server (Docker & SSH)
3.1 Cài đặt Docker & Phân quyền
multipass exec rails-server -- curl -fsSL https://get.docker.com | sh
multipass exec rails-server -- sudo usermod -aG docker ubuntu
multipass restart rails-server
3.2 Cấu hình SSH Passwordless
Để Kamal tự động đăng nhập, bạn cần gửi Public Key vào máy ảo. Thay 'id_ed25519.pub' bằng tên file key của bạn (ví dụ id_rsa.pub)
- Trên macOS hoặc Linux (Bash/Zsh/Fish):
cat ~/.ssh/id_rsa.pub | multipass exec rails-server -- bash -c "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Bước 4: Chuẩn bị Docker Hub (Chi tiết Username & Repo)
Đây là bước quan trọng nhất để Kamal có chỗ cất giữ "gói hàng" (Image) của bạn.
4.1 Xác định Username và Tạo Repo
- Lấy Username: Truy cập Docker Hub. Tên đăng nhập của bạn (ID) chính là
your_username.
- Ví dụ: Nếu URL trang cá nhân là
hub.docker.com/u/travv07thì username là travv07.
- Tạo Repo: Vào mục Repositories > Create Repository.
- Đặt tên là
rails_deploy. - Lúc này, địa chỉ Image đầy đủ của bạn sẽ là:
travv07/rails_deploy.
- Tạo Access Token: Vào Settings > Security > Personal Access Tokens -> Tạo Token mới (Quyền: Read & Write). Lưu mã này lại làm biến
KAMAL_REGISTRY_PASSWORD.
4.2 Kiểm tra Image thủ công
Đừng bỏ qua bước này để chắc chắn quyền Push đã thông suốt:
# Đăng nhập bằng Token (Thay 'travv07' bằng username thật của bạn)
docker login -u travv07
# Build và Push thử bản 'latest'
docker build -t travv07/rails_deploy .
docker push travv07/rails_deploy
Bước 5: Cấu hình mã nguồn (Production Ready)
5.1 Cấu hình Database SQLite chuẩn Rails 8
Mở config/database.yml, đảm bảo phần production sử dụng thư mục storage/ để dữ liệu không bị mất khi container khởi động lại:
production:
primary:
adapter: sqlite3
database: storage/production.sqlite3
cache:
adapter: sqlite3
database: storage/cache.sqlite3
migrations_paths: db/cache_migrate
queue:
adapter: sqlite3
database: storage/queue.sqlite3
migrations_paths: db/queue_migrate
cable:
adapter: sqlite3
database: storage/cable.sqlite3
migrations_paths: db/cable_migrate
5.2 Mở khóa bảo mật
Mở config/environments/production.rb và chỉnh sửa:
config.hosts.clear # Cho phép Kamal Proxy truy cập để Healthcheck
config.assume_ssl = false # Tạm tắt nếu chưa có HTTPS/SSL
config.force_ssl = false
Bước 6: Soạn thảo Manifest config/deploy.yml
Thay your_username và IP thật của bạn vào đây:
Lưu ý phần volumes và builder là cực kỳ quan trọng.
service: rails-deploy
image: your_username/rails_deploy
servers:
web:
- 10.106.158.38 # IP từ Multipass list
ssh:
user: ubuntu # User mặc định của máy ảo Multipass
registry:
server: index.docker.io
username: your_username
password:
- KAMAL_REGISTRY_PASSWORD
env:
secret:
- RAILS_MASTER_KEY
proxy:
ssl: false
host: 10.106.158.38
app_port: 3000
# QUAN TRỌNG: Lưu giữ dữ liệu SQLite khi deploy lại
volumes:
- "/var/lib/rails-deploy/storage:/rails/storage"
# Dành cho máy Mac chip M1/M2/M3 build cho máy ảo Linux AMD64
builder:
arch: amd64
Bước 7: Kích hoạt Deploy tự động với Kamal
7.1 Commit code
git add . && git commit -m "Final deploy config"
7.2 Thiết lập biến môi trường (Environment Variables)
Chọn lệnh tương ứng với Shell bạn đang dùng:
- Nếu dùng Bash hoặc Zsh (Mặc định Ubuntu/macOS):
export KAMAL_REGISTRY_PASSWORD="your_docker_token"
export RAILS_MASTER_KEY=$(cat config/master.key)
- Nếu dùng Fish Shell:
set -x KAMAL_REGISTRY_PASSWORD "your_docker_token"
set -x RAILS_MASTER_KEY (cat config/master.key)
7.3 Chạy Setup
kamal setup
7.4 Chạy Deploy (Từ lần thứ hai hoặc khi sửa code)
Dùng lệnh này khi bạn thay đổi code, cập nhật tính năng. Kamal sẽ build bản mới và thay thế bản cũ (Zero-downtime).
kamal deploy
Bước 8: Bảng tổng hợp lỗi & Giải pháp
| Lỗi gặp phải | Nguyên nhân | Cách xử lý |
|---|---|---|
| Auth Failed (SSH) | Sai user SSH | Kiểm tra user: ubuntu trong deploy.yml. |
| Permission Denied Docker | User chưa vào group docker | Chạy lệnh usermod ở Bước 3 và restart VM. |
| denied: access forbidden | Sai Token/Username | Kiểm tra lại Bước 4 và docker login lại. |
| Unhealthy (30s timeout) | Rails chặn Proxy Host | Thêm config.hosts.clear vào production.rb. |
| No space left on device | Ổ đĩa máy ảo đầy | Chạy docker system prune -f hoặc tạo VM 20GB. |
Bước 9: Kiểm tra thành quả
- Trạng thái:
kamal details - Xem Log:
kamal app logs -f - Truy cập: Mở trình duyệt tại
http://<IP_MÁY_ẢO>.
Lời kết:
Chúc mừng bạn đã làm chủ quy trình deploy Rails 8! Việc kết hợp SQLite và Kamal mang lại sự đơn giản tối đa nhưng vẫn đảm bảo tính chuyên nghiệp cao.
All Rights Reserved