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
Chọn Ubuntu Server 24.04
Key pair dùng để SSH và server
Ở Security group, các bạn nhớ mở các cổng sau:
22
: SSH80
: HTTP-
443
: HTTPS
Thiết lập quyền SSH
Đầu tiên bạn cần copy public key từ local
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.
Tiếp theo là dán public key vừa copy từ local vào server trong file ~/.ssh/authorized_keys
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:
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
1
rails new kamaltest
Sau đó di chuyển vào thư mục project
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.
1
rails g scaffold article title content:text
Tạo database
1
rake db:migrate
Thiết lập trang chủ trong routes.rb
1
root "articles#index"
Cuối cùng là khởi động ứng dụng
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:
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.
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ự độnghost
: Chỉ ra domain của bạn, ở đây mình dùng subdomain.
registry
username
: Tên tài khoản Dockerpassword
: 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 secretKAMAL_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.
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:
1
export KAMAL_REGISTRY_PASSWORD='hogehoge'
Có thể kiểm tra giá trị thông qua câu lệnh sau.
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.
1
kamal setup
Câu lệnh này sẽ làm những việc sau:
- Kết nối với server qua SSH (xác thực bằng SSH key).
- 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.
- Đăng nhập vào registry cả cục bộ và từ xa.
- Xây dựng image sử dụng Dockerfile chuẩn tại thư mục gốc của ứng dụng.
- Đẩy image lên registry.
- Kéo image từ registry về server.
- Đảm bảo kamal-proxy chấp nhận lưu lượng tại các cổng 80 và 443.
- 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.
- 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.
- Dừng container cũ đang chạy phiên bản trước của ứng dụng.
- 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:
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:
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:
- SSH vào server:
- Chạy câu lệnh sau:
1
sudo usermod -aG docker $USER && newgrp docker
- Kiểm tra xem đã ổn chưa bằng câu lệnh sau:
1
docker ps
Nếu thấy kết quả hiện ra như sau thì đã thành công:
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.
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.
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ị.
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
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 consolekamal shell
: Truy cập vào container trên serverkamal logs
: Xem server logkamal dbc
: Truy cập vào database console
Deploy assets trong Kamal
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ý.
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:
1
2
3
group :development, :test do
gem 'dotenv'
end
Sau đó tạo file .env
để chứa biến môi trường.
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.
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.
1
TEST_ENV_SECRET=env_secret_prod
Bây giờ hãy xem qua file deploy.yml
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 filedeploy.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
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.production
có TEST_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.
1
kamal console
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.
1
gem 'mysql2'
Sau đó cấu hình file config/database.yml
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
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 secretMYSQL_ROOT_PASSWORD
clear
:DB_HOST
sẽ theo dạngTê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:
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
và .env.production
1
MYSQL_ROOT_PASSWORD=admin
1
MYSQL_ROOT_PASSWORD=admin
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
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
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.
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.
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:
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:
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.
1
sudo rm -rf kamaltest-mysql
Cấu hình Kamal để sử dụng Redis
Đầu tiên cần thêm gem redis
.
1
gem 'redis'
Sau đó thêm accessory như sau:
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:
1
REDIS_URL=redis://localhost:6379
1
REDIS_URL=redis://kamaltest-redis:6379
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
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
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:
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:
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.
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.
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.
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.
1
2
3
env:
clear:
DB_HOST: kamaltest-mysql # Dùng chung của ứng dụng Rails thứ nhất
1
2
3
4
production:
primary:
<<: *default
database: kamaltest_production # Dùng chung của ứng dụng Rails thứ nhất