Nếu bạn chưa cảm thấy chán nản vì cứ phải lặp đi lặp lại những công việc tẻ nhạt như cập nhật máy chủ ứng dụng để đưa dự án của mình lên mạng, thì sớm muộn gì bạn cũng sẽ thấy như vậy. Niềm vui khi phát triển dự án thường bị vơi đi đáng kể khi phải đối mặt với những phần tẻ nhạt của việc quản trị hệ thống (như upload code, sửa cấu hình, chạy đi chạy lại cùng một loạt lệnh, v.v.).
Công cụ tự động hóa tác vụ Capistrano sẽ giúp bạn giải quyết vấn đề này. Trong bài viết này, chúng ta sẽ tạo một cấu hình server với phiên bản CentOS mới nhất để host các ứng dụng Ruby on Rails bằng Nginx và Passenger. Sau đó, ta sẽ tìm hiểu cách tự động hóa quy trình triển khai và cập nhật bằng Capistrano, một công cụ tự động hóa dựa trên Ruby.
Chuẩn bị server nơi deploy ứng dụng
Cập nhật hệ điều hành
Chạy lệnh sau để cập nhật phần mềm trên máy chủ chạy CentOS của bạn:
yum -y update
Cài đặt package phần mềm chứa các công cụ lập trình và phát triển bằng lệnh sau:
yum groupinstall -y 'development tools'
Một số package chúng ta cần cho hướng dẫn này (ví dụ: libyaml-devel, nginx, v.v.) không có trong repository chính thức của CentOS. Trước tiên, ta cần thêm repository EPEL:
sudo su -c 'rpm -Uvh <http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm>'
yum -y update
Sau đó chạy lệnh sau để cài các thư viện và công cụ bổ sung đó:
yum install -y curl-devel nano sqlite-devel libyaml-devel
Thiết lập môi trường Ruby và Rails
Chạy các lệnh sau để cài đặt RVM và tạo môi trường hệ thống cho Ruby:
curl -L get.rvm.io | bash -s stable
source /etc/profile.d/rvm.sh
rvm reload
rvm install 2.1.0
Vì Rails cần một trình thông dịch JavaScript, chúng ta cũng cần thiết lập Node.js. Chạy lệnh sau để tải và cài đặt nodejs bằng yum
:
yum install -y nodejs
Tải và cài đặt rails
bằng gem
của RubyGems:
gem install bundler rails
Cài đặt app & HTTP server
Nếu máy chủ của bạn có ít hơn 1 GB RAM, bạn sẽ cần chuẩn bị một không gian đĩa SWAP để dùng làm nơi lưu trữ dữ liệu tạm thời (thay thế cho RAM). Các dịch vụ hosting như DigitalOcean thường cung cấp máy chủ với đĩa SSD tốc độ cao, nên điều này không thực sự gây ra vấn đề trong quá trình cài đặt các ứng dụng server.
# Create a 1024 MB SWAP space
sudo dd if=/dev/zero of=/swap bs=1M count=1024
sudo mkswap /swap
sudo swapon /swap
Phusion Passenger
Trình quản lý package mặc định của Red Hat Linux (RPM) phân phối các ứng dụng dùng các file .rpm
. Trong trường hợp của Passenger, các phiên bản này khá lỗi thời. Do đó, chúng ta sẽ một lần nữa sử dụng RubyGem để tải và cài đặt phiên bản mới nhất (4) của Passenger.
Sử dụng lệnh dưới đây để tải và cài đặt passenger:
gem install passenger
Nginx
Lưu ý: Thông thường, để tải về và cài đặt Nginx, bạn có thể thêm repository EPEL (như chúng ta đã làm) và cài Nginx qua yum
. Tuy nhiên, để Nginx hoạt động được với Passenger, ta phải biên dịch từ nguồn của nó với các module cần thiết.
Chạy lệnh sau để bắt đầu biên dịch Nginx với module Passenger gốc:
passenger-install-nginx-module
Nhấn Enter và xác nhận lựa chọn ngôn ngữ của bạn (trong trường hợp này là Ruby). Bạn có thể dùng phím mũi tên và phím cách để chỉ chọn Ruby nếu muốn.
Use <space> to select.
If the menu doesn't display correctly, ensure that your terminal supports UTF-8.
‣ ⬢ Ruby
⬢ Python
⬢ Node.js
⬡ Meteor
Ở bước tiếp theo, chọn 1
:
1. Yes: download, compile and install Nginx for me. (recommended)
The easiest way to get started. A stock Nginx 1.4.4 with Passenger
support, but with no other additional third party modules, will be
installed for you to a directory of your choice.
Và nhấn Enter để tiếp tục. Bây giờ, source Nginx sẽ được tải về, biên dịch và cài đặt với sự hỗ trợ của Passenger. Lưu ý là tác vụ này có thể mất một chút thời gian.
Tạo script quản lý Nginx
Sau khi biên dịch Nginx, để dễ dàng điều khiển nó, chúng ta cần tạo một script quản lý đơn giản. Chạy các lệnh sau để tạo script này:
nano /etc/rc.d/init.d/nginx
Sao chép và dán nội dung dưới đây:
#!/bin/sh
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network
[ "$NETWORKING" = "no" ] && exit 0
nginx="/opt/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/opt/nginx/conf/nginx.conf"
lockfile=/var/lock/subsys/nginx
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
start
}
reload() {
configtest || return $?
echo -n $”Reloading $prog: ”
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
Nhấn CTRL+X và xác nhận bằng Y để lưu và thoát. Sau đó thiết lập quyền thực thi cho script quản lý này:
chmod +x /etc/rc.d/init.d/nginx
Cấu hình Nginx cho việc triển khai ứng dụng
Trong bước cuối cùng của việc cấu hình server, chúng ta cần tạo một block cho Nginx server, gần tương đương với virtual host (máy chủ ảo) của Apache.
Như bạn có thể đã thấy trong quá trình cài đặt Nginx của Passenger, quy trình này bao gồm việc thêm một đoạn code vào file cấu hình của Nginx nginx.conf
. Theo mặc định, file này nằm tại /opt/nginx/conf/nginx.conf
trừ khi bạn chỉ định nơi khác.
Dùng lệnh sau để mở file cấu hình này bằng trình soạn thảo văn bản nano:
nano /opt/nginx/conf/nginx.conf
Bước đầu tiên, tìm đến node http {
và thêm những dòng sau ngay sau các chỉ thị passenger_root
và passenger_ruby
:
# Only for development purposes.
# Remove this line when you upload an actual application.
# For * TESTING * purposes only.
passenger_app_env development;
Cuộn xuống và tìm server { ..
. Chú thích lại phần location mặc định:
# location / {
# root html;
# index index.html index.htm;
# }
Và định nghĩa application root mặc định của bạn:
# Set the folder where you will be deploying your application.
# We are using: /home/deployer/apps/my_app
root /home/deployer/apps/my_app/public;
passenger_enabled on;
Nhấn CTRL+X và xác nhận bằng Y để lưu và thoát. Chạy lệnh sau để tải lại Nginx với cấu hình ứng dụng mới:
# !! Remember to create an Nginx management script
# by following the main Rails deployment article for CentOS
# linked at the beginning of this section.
/etc/init.d/nginx restart
Để kiểm tra trạng thái của Nginx, bạn có thể sử dụng:
/etc/init.d/nginx status
Cài đặt Capistrano
Sau khi hệ thống đã sẵn sàng, việc tải và cài đặt phiên bản mới nhất của Capistrano trở nên cực kỳ đơn giản nhờ có RubyGems. Bạn chỉ cần sử dụng lệnh sau để cài Capistrano phiên bản 3:
gem install capistrano
Tạo một người dùng system cho việc triển khai
Trong bước này, chúng ta sẽ tạo một system user trên CentOS để thực hiện việc triển khai ứng dụng. Đây sẽ là user mà Capistrano sử dụng.
Để giữ mọi thứ đơn giản, chúng ta sẽ tạo một deployer
user với các đặc quyền cần thiết. Tạo system user mới với lệnh sau:
adduser deployer
Thiết lập mật khẩu cho deployer
:
passwd deployer
# Enter a password
# Confirm the password
Chỉnh sửa /etc/sudoers
bằng visudo
:
nano /etc/sudoers
Cuộn xuống và tìm nơi root
được định nghĩa:
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
Thêm dòng sau ngay sau root ALL=(ALL) ALL
:
deployer ALL=(ALL) ALL
Phần này của file /etc/sudoers
bây giờ sẽ trông như thế này:
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
deployer ALL=(ALL) ALL
Nhấn CTRL+X và xác nhận bằng Y để lưu và thoát.
Chuẩn bị ứng dụng Rails cho việc triển khai với Capistrano và Git
Sau khi hệ thống của chúng ta đã sẵn sàng, với tất cả các ứng dụng cần thiết đã được thiết lập và hoạt động chính xác, chúng ta có thể chuyển sang tạo một ứng dụng Rails mẫu để sử dụng.
Ở giai đoạn này, chúng ta sẽ tạo một Git repository (nơi lưu và quản lý code trong Git) và đẩy code lên một nơi trung tâm ở Github để Capistrano sử dụng cho việc triển khai.
Lưu ý: Ở đây, chúng ta đang tạo một ứng dụng mẫu. Đối với việc triển khai thực tế, bạn nên tự thực hiện các hành động này sau khi đã chắc chắn rằng mọi thứ đã được sao lưu kĩ càng. Ngoài ra, bạn sẽ cần chạy Capistrano từ một máy khác với server nơi ứng dụng cần được triển khai.
Tạo một ứng dụng Ruby-On-Rails Cơ bản
Các bước dưới đây dùng để tạo một ứng dụng Rails để thử nghiệm Capistrano. Sau khi cài đặt Ruby và Rails, chúng ta chỉ cần một lệnh duy nhất để bắt đầu.
Chạy lệnh sau để Rails tạo một ứng dụng mới có tên là my_app:
# Create a sample Rails application
rails new my_app
# Enter the application directory
cd my_app
# Create a sample resource
rails generate scaffold Task title:string note:text
# Create a sample database
RAILS_ENV=development rake db:migrate
Để kiểm tra xem ứng dụng của bạn đã được thiết lập đúng và mọi thứ hoạt động tốt chưa, hãy vào thư mục ứng dụng và chạy một server đơn giản với rails s
:
# Enter the application directory
cd my_app
# Run a simple server
rails s
# You should now be able to access it by
# visiting: http://[your droplet's IP]:3000
# In order to terminate the server process,
# Press CTRL+C
Tạo một Git repository
Lưu ý: Để thực hiện bước này, bạn sẽ cần một tài khoản Github. Ngoài ra, bạn cũng có thể tự thiết lập một máy chủ để host Git repository cho riêng mình. Nếu chọn cách này, hãy nhớ sử dụng URL tương ứng trong các file triển khai.
Chúng ta sẽ sử dụng các hướng dẫn mẫu do Github cung cấp để tạo một repository nguồn. Chạy các lệnh sau đây bên trong thư mục my_app
để khởi tạo một repository:
# !! These commands are to be executed on
# your development machine, from where you will
# deploy to your server.
# Instructions might vary slightly depending on
# your choice of operating system.
#
# Make sure to set correct paths for application
# Otherwise Nginx might not be able to locate it.
# Initiate the repository
git init
# Add all the files to the repository
git add .
# Commit the changes
git commit -m "first commit"
# Add your Github repository link
# Example: git remote add origin git@github.com:[user name]/[proj. name].git
git remote add origin git@github.com:user123/my_app.git
# Create an RSA/SSH key
# Follow the on-screen instructions
ssh-keygen -t rsa
# View the contents of the key and add it to your Github
# by copy-and-pasting from the current remote session by
# visiting: <https://github.com/settings/ssh>
# To learn more about the process,
# visit: <https://help.github.com/articles/generating-ssh-keys>
cat /root/.ssh/id_rsa.pub
# Set your Github information
# Username:
# Usage: git config --global user.name "[your username]"
git config --global user.name "user123"
# Email:
# Usage: git config --global user.email "[your email]"
git config --global user.email "user123@domain.tld"
# Push the project's source code to your Github account
Cấu hình Capistrano để tự động hóa việc triển khai
Cách để sử dụng thư viện này là cài đặt nó thẳng vào bên trong thư mục dự án của bạn. Trong phần này, chúng ta sẽ thực hiện điều đó và sau đó là tạo các file cần thiết để thiết lập server.
Cài đặt Capistrano bên trong thư mục dự án
Một bước đơn giản khác là cài đặt các file Capistrano. Lệnh dưới đây sẽ tạo ra một số thư mục và file để công cụ sử dụng cho việc triển khai.
Chạy lệnh sau để khởi tạo các file Capistrano:
cap install
# mkdir -p config/deploy
# create config/deploy.rb
# create config/deploy/staging.rb
# create config/deploy/production.rb
# mkdir -p lib/capistrano/tasks
# Capified
Cấu hình config/deploy.rb
File deploy.rb
chứa các tham số và thiết lập cho (các) server triển khai. Trong file này, ta sẽ khai báo cho Capistrano biết cần kết nối và triển khai lên server nào, cũng như cách thức thực hiện.
Lưu ý: Khi chỉnh sửa file (hoặc định nghĩa cấu hình), bạn có thể chú thích lại hoặc thêm các dòng mới. Nhưng nhớ không để thiết lập mẫu ghi đè lên những gì bạn đang thêm vào.
Chạy lệnh sau để chỉnh sửa file đó bằng nano
:
nano config/deploy.rb
Thêm đoạn dưới đây, sửa đổi nó cho phù hợp với thiết lập của riêng bạn:
# Define the name of the application
set :application, 'my_app'
# Define where can Capistrano access the source repository
# set :repo_url, '<https://github.com/>[user name]/[application name].git'
set :scm, :git
set :repo_url, '<https://github.com/user123/my_app.git>'
# Define where to put your application code
set :deploy_to, "/home/deployer/apps/my_app"
set :pty, true
set :format, :pretty
# Set the post-deployment instructions here.
# Once the deployment is complete, Capistrano
# will begin performing them as described.
# To learn more about creating tasks,
# check out:
# <http://capistranorb.com/>
# namespace: deploy do
# desc 'Restart application'
# task :restart do
# on roles(:app), in: :sequence, wait: 5 do
# # Your restart mechanism here, for example:
# execute :touch, release_path.join('tmp/restart.txt')
# end
# end
# after :publishing, :restart
# after :restart, :clear_cache do
# on roles(:web), in: :groups, limit: 3, wait: 10 do
# # Here we can do anything such as:
# # within release_path do
# # execute :rake, 'cache:clear'
# # end
# end
# end
# end
Nhấn CTRL+X và xác nhận bằng Y để lưu và thoát.
Cấu hình config/deploy/production.rb
Lưu ý: Tương tự như config/deploy.rb
, bạn sẽ cần thực hiện một số sửa đổi đối với file config/deploy/production.rb
. Tốt hơn là bạn nên sửa đổi đoạn cấu hình thay vì chỉ thêm đoạn dưới đây.
Chạy lệnh sau để chỉnh sửa file bằng nano
:
nano config/deploy/production.rb
Nhập các thiết lập của server của bạn tương tự như dưới đây:
# Define roles, user and IP address of deployment server
# role :name, %{[user]@[IP adde.]}
role :app, %w{deployer@162.243.74.190}
role :web, %w{deployer@162.243.74.190}
role :db, %w{deployer@162.243.74.190}
# Define server(s)
server '162.243.74.190', user: 'deployer', roles: %w{web}
# SSH Options
# See the example commented out section in the file
# for more options.
set :ssh_options, {
forward_agent: false,
auth_methods: %w(password),
password: 'user_deployers_password',
user: 'deployer',
}
Nhấn CTRL+X và xác nhận bằng Y để lưu và thoát.
Triển khai lên production server
Sau khi đã hoàn tất các thiết lập, đã đến lúc bạn thực hiện triển khai ứng dụng. Chạy lệnh sau ở nơi phát triển dự án để triển khai lên production server.
cap production deploy
Như đã định nghĩa trong các file trên, Capistrano sẽ:
- Kết nối đến server triển khai
- Tải code của ứng dụng
- Thực hiện các hành động triển khai (ví dụ: yêu cầu passenger khởi động lại ứng dụng)
Tổng kết
Tự động hóa việc triển khai ứng dụng Ruby on Rails với Capistrano không chỉ tiết kiệm công sức mà còn tạo được một nền tảng ổn định cho toàn bộ quá trình phát triển, tránh những sai sót do thao tác lặp lại. Để tìm hiểu thêm về Capistrano và những khả năng khác của nó, hãy tham khảo tài liệu chính thức của dự án.