Scroll to top
Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

ByYuto 04/12/2024 21:19
30min read

Bạn đang tìm cách deploy ứng dụng Ruby on Rails nhanh chóng lên server? Hãy thử Kamal! Bài viết này sẽ hướng dẫn bạn từng bước, từ cài đặt đến triển khai, để việc deploy trở nên đơn giản và hiệu quả hơn bao giờ hết.

Ruby on Rails 8 mới ra mắt có tích hợp với Kamal, một công cụ deploy nhanh chóng và tiện lợi có thể thay thế hoàn toàn Capistrano. Từ trước đến nay mình đều dùng Capistrano cho việc deploy các ứng dụng Ruby on Rails, tuy nhiên từ sau khi sử dụng Rails 8 và deploy thử với Kamal thì mình bị cuốn hút bởi sự tiện lợi và dễ dàng của công cụ này.

Bài viết này sẽ hướng dẫn chi tiết cho các bạn các bước để deploy một ứng dụng Ruby on Rails lên server AWS EC2 bằng Kamal.

Bài viết bao gồm:

  • Khái quát về Kamal
  • Chuẩn bị server cho project Ruby on Rails
  • Cách deploy bằng Kamal
  • Biến môi trường trong Kamal
  • Cấu hình Kamal để sử dụng MySQL
  • Cấu hình Kamal để sử dụng Redis
  • Xử lý bất đồng bộ trong Rails 8
  • Cài đặt Cron trong Rails 8
  • Deploy nhiều ứng dụng trên cùng một server
  • Nhiều ứng dụng dùng chung database

Kamal là gì?

Kamal là một công cụ triển khai mới được phát triển bởi đội ngũ của 37Signals. Công cụ này cho phép bạn định nghĩa quy trình triển khai chỉ trong một file duy nhất, giúp đơn giản hóa nhiều khía cạnh phức tạp mà hầu hết các ứng dụng không cần phải bận tâm. Kamal hoạt động bằng cách kết hợp các phần mềm như Docker containers và Traefik. Ngay từ khi thiết lập, công cụ này mang đến một giải pháp trọn gói, hỗ trợ bạn triển khai ứng dụng Rails sẵn sàng cho môi trường production trong thời gian ngắn nhất.

Kamal hoạt động như thế nào?

Kamal chạy ứng dụng web của bạn trong Docker container trên server, kết hợp với Traefik để xử lý lưu lượng mạng. Khi triển khai phiên bản mới, Kamal sẽ:

  • Xây dựng Docker image mới.
  • Khởi chạy container từ image mới.
  • Kiểm tra container mới có hoạt động tốt không.
  • Cập nhật Traefik để chuyển hướng lưu lượng đến container mới.
  • Dừng container cũ.

Điểm nổi bật là khả năng triển khai không downtime và hỗ trợ blue/green deploy.

Chuẩn bị server cho ứng dụng Ruby on Rails

Mình sẽ chuẩn bị nhanh một server trên AWS EC2.

Tạo một EC2 instance

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Chọn Ubuntu Server 24.04

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Key pair dùng để SSH và server

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Ở Security group, các bạn nhớ mở các cổng sau:

  • 22: SSH
  • 80: HTTP
  • 443: HTTPS

Thiết lập quyền SSH

Đầu tiên bạn cần copy public key từ local

zsh
Copy
1
cat ~/.ssh/id_rsa.pub

Sau khi khởi động instance, bạn dùng key pair vừa tạo để SSH vào server với user là ubuntu, địa chỉ IP là của instance mới tạo.

zsh
Copy
1
ssh [email protected] -i /path/to/key.pem

Tiếp theo là dán public key vừa copy từ local vào server trong file ~/.ssh/authorized_keys

~/.ssh/authorized_keys
Copy
1
ssh-rsa AAAABEAAAADAQABAAABgQ...AAAAB3Nzac2EAAAADAQABA Yuto MacBook Pro

Như vậy là đã chuẩn bị xong phần server, từ bây giờ bạn có thể SSH vào server với dòng lệnh:

zsh
Copy

Tạo một ứng dụng Ruby on Rails 8

Đầu tiên cần tạo một ứng dụng Ruby on Rails 8 với câu lệnh quen thuộc, mình sẽ đặt tên project mới là kamaltest

zsh
Copy
1
rails new kamaltest

Sau đó di chuyển vào thư mục project

zsh
Copy
1
cd kamaltest

Ứng dụng này sẽ là một blog đơn giản với tiêu đề và nội dung, do đó ta sẽ tạo nhanh một scaffold.

zsh
Copy
1
rails g scaffold article title content:text

Tạo database

zsh
Copy
1
rake db:migrate

Thiết lập trang chủ trong routes.rb

config/routes.rb
Copy
1
  root "articles#index"

Cuối cùng là khởi động ứng dụng

zsh
Copy
1
bin/dev

Sau đó bạn truy cập vào đường dẫn http://localhost:3000 là có thể thấy ứng dụng đã được khởi động.

Cấu hình Kamal thông qua file deploy.yml

Đối với Ruby on Rails 8 thì Kamal đã được tích hợp sẵn. Đối với những project trước đó, nếu bạn muốn thêm Kamal thì hãy thêm gem kamal vào Gemfile, sau đó dùng câu lệnh sau:

zsh
Copy
1
kamal init

Câu lệnh trên sẽ tạo ra file config/deploy.yml chứa mọi thiết lập của Kamal để deploy ứng dụng.

Cấu hình cơ bản của Kamal

Để deploy thì cần những thiết lập như file bên dưới.

config/deploy.yml
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
image: yutoyasunaga/kamaltest

servers:
  web:
    - 18.182.197.19 # server IP

proxy:
  ssl: true
  host: kamaltest.sampleapp.net

registry:
  username: yutoyasunaga
  password:
    - KAMAL_REGISTRY_PASSWORD

ssh:
  user: ubuntu
  • image: Đây là nơi Docker image sẽ được lưu trên https://hub.docker.com với tài khoản Docker của bạn.
  • servers
    • web: Địa chỉ IPv4 của server
  • proxy
    • ssl: Để là true, SSL sẽ được thiết lập tự động
    • host: Chỉ ra domain của bạn, ở đây mình dùng subdomain.
  • registry
    • username: Tên tài khoản Docker
    • password: Password để login vào tài khoản Docker, tuy nhiên vì là thông tin nhạy cảm nên sẽ được truy xuất thông qua secret KAMAL_REGISTRY_PASSWORD
  • ssh
    • user: Thông tin user để SSH vào server

Kamal secret

Các thông tin nhạy cảm sẽ được đặt trong file .kamal/secrets, ví dụ như bên dưới.

.kamal/secrets
Copy
1
2
# Grab the registry password from ENV
KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD

Secret sẽ được lấy từ biến môi trường, ví dụ password Docker của mình là hogehoge thì mình sẽ thiết lập password của Docker như sau:

zsh
Copy
1
export KAMAL_REGISTRY_PASSWORD='hogehoge'

Có thể kiểm tra giá trị thông qua câu lệnh sau.

zsh
Copy
1
echo $KAMAL_REGISTRY_PASSWORD

Bắt đầu deploy bằng Kamal

Sau khi đã cấu hình xong trong file config/deploy.yml, dùng câu lệnh sau để bắt đầu deploy lần đầu tiên.

zsh
Copy
1
kamal setup

Câu lệnh này sẽ làm những việc sau:

  1. Kết nối với server qua SSH (xác thực bằng SSH key).
  2. Cài đặt Docker trên server chưa có Docker (sử dụng get.docker.com): việc này yêu cầu quyền truy cập root qua SSH.
  3. Đăng nhập vào registry cả cục bộ và từ xa.
  4. Xây dựng image sử dụng Dockerfile chuẩn tại thư mục gốc của ứng dụng.
  5. Đẩy image lên registry.
  6. Kéo image từ registry về server.
  7. Đảm bảo kamal-proxy chấp nhận lưu lượng tại các cổng 80 và 443.
  8. Khởi động container mới với phiên bản ứng dụng khớp với hash của phiên bản Git hiện tại.
  9. Khi container mới trả về trạng thái 200 OK cho yêu cầu GET /up, chỉ định kamal-proxy định tuyến lưu lượng tới container mới.
  10. Dừng container cũ đang chạy phiên bản trước của ứng dụng.
  11. Xóa các image không sử dụng và container đã dừng để tránh làm đầy server.

Nếu deploy thành công thì sẽ có kết quả như sau:

zsh
Copy
1
Finished all in 70.0 seconds

Với lần đầu tiên deploy thì dùng câu lệnh kamal setup, tuy nhiên với những lần deploy sau này thì là câu lệnh kamal deploy

Giải quyết lỗi permission denied

Nếu lần deploy đầu tiên xuất hiện lỗi không có quyền truy cập liên quan đến Docker như sau:

zsh
Copy
1
2
3
4
5
Releasing the deploy lock...
  Finished all in 47.9 seconds
  ERROR (SSHKit::Command::Failed): Exception while executing on host 54.250.243.158: docker exit status: 1
docker stdout: Nothing written
docker stderr: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.47/images/create?fromImage=yutoyasunaga%2Fkamaltest&tag=4985d03bae739286203ce1185efdd4b2c71f90a9": dial unix /var/run/docker.sock: connect: permission denied

Cách giải quyết như sau:

  1. SSH vào server:
zsh
Copy
  1. Chạy câu lệnh sau:
zsh
Copy
1
sudo usermod -aG docker $USER && newgrp docker
  1. Kiểm tra xem đã ổn chưa bằng câu lệnh sau:
zsh
Copy
1
docker ps

Nếu thấy kết quả hiện ra như sau thì đã thành công:

zsh
Copy
1
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Kiểm tra kết quả sau khi deploy

Đầu tiên bạn vào https://hub.docker.com của bạn để kiểm tra thì sẽ thấy image đã được push lên.

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Nếu bạn dùng Route53 để quản lý domain thì phải tạo một record trong host zone như sau để domain trỏ về IP của server.

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Trong ví dụ của mình, khi mình truy cập https://kamaltest.sampleapp.net thì sẽ thấy màn hình của ứng dụng hiển thị.

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Như vậy là chỉ trong vòng hơn 1 phút, mình đã deploy xong một ứng dụng Ruby on Rails lên server và thiết lập xong domain kèm SSL. Thật là tuyệt vời phải không nào!

Những câu lệnh Kamal thường dùng

config/deploy.yml
Copy
1
2
3
4
5
aliases:
  console: app exec --interactive --reuse "bin/rails console"
  shell: app exec --interactive --reuse "bash"
  logs: app logs -f
  dbc: app exec --interactive --reuse "bin/rails dbconsole"

Trong file deploy.yml mặc định đã định nghĩa 4 câu lệnh thường dùng như sau:

  • kamal console: Truy cập vào Rails console
  • kamal shell: Truy cập vào container trên server
  • kamal logs: Xem server log
  • kamal dbc: Truy cập vào database console

Deploy assets trong Kamal

Dockerfile
Copy
1
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile

Ở Dockerfile đã định nghĩa sẵn câu lệnh precompile assets, do đó khi deploy thì assets cũng sẽ được xử lý.

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Biến môi trường (environment variable) trong Kamal

Biến môi trường Kamal trong môi trường development

Mình sử dụng gem dotenv https://github.com/bkeepers/dotenv

Thêm gem dotenv vào Gemfile:

Gemfile
Copy
1
2
3
group :development, :test do
  gem 'dotenv'
end

Sau đó tạo file .env để chứa biến môi trường.

.env
Copy
1
2
TEST_ENV_CLEAR=env_clear_local
TEST_ENV_SECRET=env_secret_local

Bạn có thể kiểm tra bằng cách truy cập vào Rails console.

ruby
Copy
1
2
ENV.select { |key, _| key.start_with?("TEST_ENV") }
=> {"TEST_ENV_CLEAR"=>"env_clear_local", "TEST_ENV_SECRET"=>"env_secret_local"}

Biến môi trường Kamal trong môi trường production

Mình chưa tìm được cách khác tốt hơn nên tạm thời mình dùng như thế này

Tạo file .env.production để chứa biến môi trường cho production.

.env.production
Copy
1
TEST_ENV_SECRET=env_secret_prod

Bây giờ hãy xem qua file deploy.yml

config/deploy.yml
Copy
1
2
3
4
5
env:
  secret:
    - TEST_ENV_SECRET
  clear:
    TEST_ENV_CLEAR: env_clear_prod

Trong file deploy.yml, biến môi trường được chia làm 2 loại:

  • clear: Định nghĩa trực tiếp trong file deploy.yml
  • secret: Thông tin nhạy cảm, được đọc từ file .kamal/secrets

Cấu hình file .kamal/secrets để lấy biến môi trường

.kamal/secrets
Copy
1
TEST_ENV_SECRET=$(cat .env.production | grep TEST_ENV_SECRET | cut -d '=' -f 2)

Cách viết trên nghĩa là lấy phần thông tin trong file .env.production. Ví dụ khi trong .env.productionTEST_ENV_SECRET=env_secret_prod thì dòng cut -d '=' -f 2 sẽ lấy ra phần env_secret_prod.

Để kiểm tra biến môi trường của production thì sau khi deploy xong, bạn có thể vào Rails console để xem.

zsh
Copy
1
kamal console
ruby
Copy
1
2
ENV.select { |key, _| key.start_with?("TEST_ENV") }
=> {"TEST_ENV_SECRET"=>"env_secret_prod", "TEST_ENV_CLEAR"=>"env_clear_prod"}

Cấu hình Kamal để sử dụng MySQL

Để sử dụng MySQL làm cơ sở dữ liệu, đầu tiên thêm gem mysql2 vào Gemfile.

Gemfile
Copy
1
gem 'mysql2'

Sau đó cấu hình file config/database.yml

config/database.yml
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: <%= ENV.fetch("DB_HOST") { "127.0.0.1" } %>
  timeout: 5000
  username: root
  password: <%= ENV["MYSQL_ROOT_PASSWORD"] %>

development:
  <<: *default
  database: kamaltest_development

test:
  <<: *default
  database: kamaltest_test

production:
  primary:
    <<: *default
    database: kamaltest_production

Cấu hình file config/deploy.yml

config/deploy.yml
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
env:
  secret:
    - MYSQL_ROOT_PASSWORD
  clear:
    DB_HOST: kamaltest-mysql

accessories:
  mysql:
    image: mysql:9.1
    host: 18.182.197.19
    port: 3306:3306
    env:
      clear:
        MYSQL_ROOT_HOST: '%'
        MYSQL_DATABASE: kamaltest_production
      secret:
        - MYSQL_ROOT_PASSWORD
    files:
      - config/mysql/production.cnf:/etc/mysql/my.cnf
    directories:
      - data:/var/lib/mysql

Giải thích:

  • env
    • secret: Ở đây ta thêm secret MYSQL_ROOT_PASSWORD
    • clear: DB_HOST sẽ theo dạng Tên service-Tên accessory, ở đây là kamaltest-mysql
  • accessories: Là nơi để ta cấu hình những cái như MySQL, Redis...v.v.. host sẽ cùng IP server với web.

Bạn có thể thêm file config/mysql/production.cnf chứa những thiết lập cho MySQL như sau:

config/mysql/production.cnf
Copy
1
2
3
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

Và đừng quên thêm biến môi trường MYSQL_ROOT_PASSWORD vào .env.env.production

.env
Copy
1
MYSQL_ROOT_PASSWORD=admin
.env.production
Copy
1
MYSQL_ROOT_PASSWORD=admin
.kamal/secrets
Copy
1
MYSQL_ROOT_PASSWORD=$(cat .env.production | grep MYSQL_ROOT_PASSWORD | cut -d '=' -f 2)

Sau khi cấu hình xong, bạn dùng câu lệnh sau để tích hợp MySQL vào

zsh
Copy
1
kamal accessory boot mysql

Lúc này, bạn có thể sử dụng những phần mềm như Sequel ACE để thử kết nối vào DB

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Kiểm tra trạng thái của container MySQL trên server

Bạn có thể SSH vào server và dùng lệnh docker ps để kiểm tra container MySQL có hoạt động hay chưa.

zsh
Copy
1
2
3
CONTAINER ID   IMAGE                         COMMAND                  CREATED         STATUS          PORTS                                                                      NAMES
814f73c42aba   mysql:9.1                     "docker-entrypoint.s…"   7 minutes ago   Up 7 minutes    0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                       kamaltest-mysql
d380868591df   basecamp/kamal-proxy:v0.8.2   "kamal-proxy run"        30 hours ago    Up 19 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   kamal-proxy

Dùng câu lệnh docker logs kamaltest-mysql để kiểm tra log của container MySQL.

zsh
Copy
1
2
3
4
5
6
7
8
2024-11-10T11:24:36.569937Z 0 [System] [MY-015015] [Server] MySQL Server - start.
2024-11-10T11:24:36.898839Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 9.1.0) starting as process 1
2024-11-10T11:24:36.908602Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2024-11-10T11:24:36.976394Z 1 [ERROR] [MY-012592] [InnoDB] Operating system error number 2 in a file operation.
2024-11-10T11:24:36.976451Z 1 [ERROR] [MY-012593] [InnoDB] The error means the system cannot find the path specified.
2024-11-10T11:24:36.976463Z 1 [ERROR] [MY-012594] [InnoDB] If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them.
2024-11-10T11:24:36.976476Z 1 [ERROR] [MY-012646] [InnoDB] File ./ibdata1: 'open' returned OS error 71. Cannot continue operation
2024-11-10T11:24:36.976486Z 1 [ERROR] [MY-012981] [InnoDB] Cannot continue operation.

Xóa accessory MySQL

Trường hợp bạn muốn xóa accessory MySQL thì cũng đơn giản. Đầu tiên ở local, bạn chạy câu lệnh sau:

zsh
Copy
1
kamal accessory remove mysql

Tiếp theo bạn SSH vào server, khi liệt kê file bằng lệnh ll thì bạn sẽ thấy kết quả như sau:

zsh
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ubuntu@ip-172-31-38-201:~$ ll
total 60
drwxr-x--- 8 ubuntu ubuntu 4096 Nov 10 11:32 ./
drwxr-xr-x 3 root   root   4096 Nov  9 05:00 ../
-rw------- 1 ubuntu ubuntu 5092 Nov 10 11:31 .bash_history
-rw-r--r-- 1 ubuntu ubuntu  220 Mar 31  2024 .bash_logout
-rw-r--r-- 1 ubuntu ubuntu 3771 Mar 31  2024 .bashrc
drwx------ 2 ubuntu ubuntu 4096 Nov  9 05:06 .cache/
drwx------ 3 ubuntu ubuntu 4096 Nov  9 05:46 .config/
drwx------ 2 ubuntu ubuntu 4096 Nov 10 11:32 .docker/
drwxrwxr-x 3 ubuntu ubuntu 4096 Nov 10 11:32 .kamal/
-rw------- 1 ubuntu ubuntu   20 Nov 10 09:47 .lesshst
-rw-r--r-- 1 ubuntu ubuntu  807 Mar 31  2024 .profile
drwx------ 2 ubuntu ubuntu 4096 Nov  9 05:07 .ssh/
-rw-r--r-- 1 ubuntu ubuntu    0 Nov  9 05:15 .sudo_as_admin_successful
-rw------- 1 ubuntu ubuntu  928 Nov  9 05:07 .viminfo
drwxrwxr-x 4 ubuntu ubuntu 4096 Nov 10 11:32 kamaltest-mysql

Bạn cần phải xóa cả thư mục kamaltest-mysql nữa.

zsh
Copy
1
sudo rm -rf kamaltest-mysql

Cấu hình Kamal để sử dụng Redis

Đầu tiên cần thêm gem redis.

Gemfile
Copy
1
gem 'redis'

Sau đó thêm accessory như sau:

config/deploy.yml
Copy
1
2
3
4
5
6
7
8
9
10
11
env:
  secret:
    - REDIS_URL

accessories:
  redis:
    image: redis:7.4.1
    host: 18.182.197.19
    port: 6379:6379
    directories:
      - data:/data

Biến môi trường REDIS_URL ở môi trường development và produciton sẽ như sau:

.env
Copy
1
REDIS_URL=redis://localhost:6379
.env.production
Copy
1
REDIS_URL=redis://kamaltest-redis:6379
.kamal/secrets
Copy
1
REDIS_URL=$(cat .env.production | grep REDIS_URL | cut -d '=' -f 2)

Cũng tương tự như accessory MySQL, REDIS_URL cũng chứa dạng Tên service-Tên accessory.

Sau khi cấu hình xong, bạn dùng câu lệnh sau để tích hợp Redis vào

zsh
Copy
1
kamal accessory boot redis

Lúc này, bạn có thể sử dụng những phần mềm như TablePlus để thử kết nối vào Redis

Deploy nhanh ứng dụng Ruby on Rails lên server bằng Kamal

Xóa accessory Redis

Tương tự như các accessory khác, nếu bạn muốn xóa accessory Redis thì ở local, bạn chạy câu lệnh sau:

zsh
Copy
1
kamal accessory remove redis

Tiếp theo bạn SSH vào server, khi liệt kê file bằng lệnh ll thì bạn sẽ thấy kết quả như sau:

zsh
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ubuntu@ip-172-31-38-201:~$ ll
total 60
drwxr-x--- 8 ubuntu ubuntu 4096 Nov 10 11:32 ./
drwxr-xr-x 3 root   root   4096 Nov  9 05:00 ../
-rw------- 1 ubuntu ubuntu 5092 Nov 10 11:31 .bash_history
-rw-r--r-- 1 ubuntu ubuntu  220 Mar 31  2024 .bash_logout
-rw-r--r-- 1 ubuntu ubuntu 3771 Mar 31  2024 .bashrc
drwx------ 2 ubuntu ubuntu 4096 Nov  9 05:06 .cache/
drwx------ 3 ubuntu ubuntu 4096 Nov  9 05:46 .config/
drwx------ 2 ubuntu ubuntu 4096 Nov 10 11:32 .docker/
drwxrwxr-x 3 ubuntu ubuntu 4096 Nov 10 11:32 .kamal/
-rw------- 1 ubuntu ubuntu   20 Nov 10 09:47 .lesshst
-rw-r--r-- 1 ubuntu ubuntu  807 Mar 31  2024 .profile
drwx------ 2 ubuntu ubuntu 4096 Nov  9 05:07 .ssh/
-rw-r--r-- 1 ubuntu ubuntu    0 Nov  9 05:15 .sudo_as_admin_successful
-rw------- 1 ubuntu ubuntu  928 Nov  9 05:07 .viminfo
drwxrwxr-x 4 ubuntu ubuntu 4096 Nov 10 11:32 kamaltest-redis

Bạn cũng cần phải xóa cả thư mục kamaltest-redis nữa.

zsh
Copy
1
sudo rm -rf kamaltest-redis

Cấu hình Kamal để sử dụng Cron

Trước Ruby on Rails 8 thì mình deploy bằng Capistrano và sử dụng gem whenever để quản lý các tác vụ Cron. Tuy nhiên Ruby on Rails 8 nay đã có Solid Queue. Solid Queue hỗ trợ định nghĩa các tác vụ được thực thi định kỳ vào một thời điểm cụ thể trong tương lai, giống như cron job.

Việc thiết lập Cron job cho Rails 8 rất đơn giản, ví dụ như bên dưới.

config/recurring.yml
Copy
1
2
3
4
5
6
7
8
9
10
# production:
#   periodic_cleanup:
#     class: CleanSoftDeletedRecordsJob
#     queue: background
#     args: [ 1000, { batch_size: 500 } ]
#     schedule: every hour
#   periodic_command:
#     command: "SoftDeletedRecord.due.delete_all"
#     priority: 2
#     schedule: at 5am every day

Bạn có thể tìm hiểu thêm về Solid Queue tại đây: https://github.com/rails/solid_queue?tab=readme-ov-file#recurring-tasks

Ở phần thiết lập schedule, bạn có thể tham khảo theo định dạng của Fugit: https://github.com/floraison/fugit?tab=readme-ov-file#fugitcron

Xử lý bất đồng bộ, background job trong Kamal

Trước Ruby on Rails 8 thì mình dùng sidekiq cho việc xử lý bất đồng bộ. Từ Rails 8 thì đã rất tiện lợi rồi, Solid Queue sẽ đảm nhận việc xử lý bất đồng bộ, background job cho ứng dụng Rails.
Để tìm hiểu thêm về Solid Queue thì bạn có thể xem tại GitHub: https://github.com/rails/solid_queue

Dùng Kamal để deploy nhiều ứng dụng Rails trên cùng một server

Giả sử mình có một server và đã deploy ứng dụng Rails thứ nhất thành công, và bây giờ mình muốn deploy ứng dụng Rails thứ hai trên cùng một server và sử dụng MySQL, Redis riêng biệt. Rất đơn giản, ứng dụng Rails thứ hai bạn cũng cấu hình file config/deploy.yml tương tự như ứng dụng Rails thứ nhất, chỉ khác tên service.

Ví dụ file config/deploy.yml của ứng dụng Rails thứ hai.

config/deploy.yml
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
service: kamaltest2

image: yutoyasunaga/kamaltest2

proxy:
  ssl: true
  host: kamaltest2.sampleapp.net

env:
  clear:
    DB_HOST: kamaltest2-mysql

volumes:
  - "kamaltest2_storage:/rails/storage"

accessories:
  mysql:
    image: mysql:9.1
    host: 18.182.197.19
    port: 3307:3306
    env:
      clear:
        MYSQL_ROOT_HOST: '%'
        MYSQL_DATABASE: kamaltest2_production
      secret:
        - MYSQL_ROOT_PASSWORD
                - REDIS_URL
    files:
      - config/mysql/production.cnf:/etc/mysql/my.cnf
    directories:
      - data:/var/lib/mysql
  redis:
    image: redis:7.4.1
    host: 18.182.197.19
    port: 6380:6379
    directories:
      - data:/data

Lưu ý là bạn phải thay đổi port cho MySQL và Redis cho khác với của ứng dụng Rails thứ nhất. Ở đây mình đặt port của MySQL là 3307 và của Redis là 6380.

Ở biến môi trường và secrets cũng thay đổi tên service cho khớp với ứng dụng Rails thứ hai.

Chia sẻ accessory trong Kamal, nhiều ứng dụng dùng chung database

Giả sử mình có một server và đã deploy ứng dụng Rails thứ nhất thành công, và bây giờ mình muốn deploy ứng dụng Rails thứ hai trên cùng một server và sử dụng chung database với ứng dụng Rails thứ nhất. Lúc này bạn chỉ cần chỉ định DB_HOST là DB của ứng dụng Rails thứ nhất là xong.

Ví dụ về cấu hình của ứng dụng Rails thứ hai.

config/deploy.yml
Copy
1
2
3
env:
  clear:
    DB_HOST: kamaltest-mysql # Dùng chung của ứng dụng Rails thứ nhất
config/database.yml
Copy
1
2
3
4
production:
  primary:
    <<: *default
    database: kamaltest_production # Dùng chung của ứng dụng Rails thứ nhất
Đánh giá bài viết: 5/5 (47 đánh giá)
Bạn chưa đánh giá

Bình luận

Author
hoclaptrinh.io author
Tác giả:Yuto Yasunaga

Mình là một full stack developer, tốt nghiệp và làm việc tại Nhật Bản. Trang web này là nơi mình tổng hợp, đúc kết và lưu trữ lại những kiến thức trong quá trình học và làm việc liên quan đến IT.
Hy vọng những bài viết ở website này sẽ có ích cho bạn.