12/08/2018, 15:54

Zero downtime deployment for Rails with Capistrano and Unicorn

Trên Viblo cũng có khá nhiều bài viết về việc auto deploy một ứng dụng Ruby on Rails với Capistrano. Nhưng mình cũng vẫn chia sẻ bài viết này với mục đích hướng dẫn mọi người chi tiết hơn trong việc cài đặt một server từ chưa có gì cho tới khi ứng dụng của chúng ta được chạy và có khả năng deploy ...

Trên Viblo cũng có khá nhiều bài viết về việc auto deploy một ứng dụng Ruby on Rails với Capistrano. Nhưng mình cũng vẫn chia sẻ bài viết này với mục đích hướng dẫn mọi người chi tiết hơn trong việc cài đặt một server từ chưa có gì cho tới khi ứng dụng của chúng ta được chạy và có khả năng deploy hoàn chỉnh. Nằm ngoài mục đích đó là mình cũng muốn note lại và tổng kết những gì mình đã tìm hiểu, học được từ việc cài đặt và sử dụng Capistrano. Chúng ta cùng vừa đọc vừa thực hành luôn nhé. Việc khó khăn nhất là chúng ta cần phải có một server để thực hiện, nhưng may mắn thay, chúng ta có thể sử dụng Docker để giả lập một server. Về việc cài đặt và sử dụng Docker như thế nào thì mình không bàn tới trong bài viết này nhé. Mặc định là mọi người đã cài và có thể sử dụng Docker căn bản. Chúng ta cùng đi từng bước một nhé. Phần đầu là chúng ta thực hiện cài đặt một server có thể SSH vào được từ host (giống với môi trường server thật).

Cài đặt server

Việc sử dụng image nào là tùy mọi người. Mình sử dụng image Ubuntu 14.04 nhé. Pull image (nếu chưa có):

sudo docker pull ubuntu:14.04

Sau khi pull image xong. Bạn có thể kiểm tra danh sách các images bằng lệnh:

sudo docker images

Khi đã có image của Ubuntu, chúng ta khởi tạo một Docker container bằng lệnh:

sudo docker run --name virtual_server -it ubuntu:14.04 /bin/bash

Sau khi khởi tạo xong, bạn đã ở trong container, mặc định chúng ta đang ở quyền cao nhất rồi (root) nên các câu lệnh không cần prefix là sudo nữa nhé (nhưng ở môi trường thật nếu chúng ta chưa ở root thì vẫn cần phải có prefix này để thực hiện các câu lệnh liên quan đến hệ thống yêu cầu quyền super user).

Tiếp theo, chúng ta sẽ cài đặt một package giúp chúng ta có thể SSH vào container là OpenSSH server. Đầu tiên, update lại APT cache bằng lệnh:

apt-get update

Sau đó, cài OpenSSH server và VIM để cài thực hiện cài đặt nhé:

apt-get install -y vim openssh-server

Sau khi cài đặt xong, chúng ta sang phần cấu hình OpenSSH server để có thể SSH từ host vào container nhé. Trước khi sửa file cấu hình của OpenSSH, chúng ta cứ backup lại một bản cho chắc:

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

Thực hiện sửa file sshd_config bằng lệnh vim /etc/ssh/sshd_config và sửa các cài đặt sang các giá trị sau:

Note: Trong VIM, bạn có thể search bằng cách dùng /<pattern|keyword|string> để search. Ví dụ: /MaxAuthTries

MaxAuthTries 3 # Bạn có thể thay đổi sang số khác, nếu thích
RSAAuthentication yes
PubkeyAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

Thoát VIM và khởi động lại SSH server bằng lệnh:

service ssh restart

Tạo thư mục .ssh để chứa publickey của máy mà chúng ta có thể SSH lên:

ssh-keygen -t rsa
# Sau đó bạn cứ enter cho đến hết (nếu muốn :D)

Vào thư mục ~/.ssh và tạo một file với tên authorized_keys để chứa publickey với lệnh:

touch authorized_keys && chmod 600 authorized_keys

Add publickey của host vào authorized_keys của container bằng cách bước sau:

  • Host:
    • cat ~/.ssh/id_rsa.pub và copy đoạn SSH key
  • Container
    • vi ~/.ssh/authorized_keys và paste đoạn SSH của host vào

Chúng ta thử SSH từ host vào container nhé. Để xem IP của container, chúng ta có thể sử dụng ifconfig trong container hoặc lệnh sau trên host:

sudo docker inspect virtual_server | grep IPAddress

Của mình là 172.17.0.2 (còn của bạn bạn có thể sẽ khác, nếu có nhiều container đã được khởi tạo trước đó). Thử SSH vào xem sao:

ssh root@172.17.0.2

OK, thế là xong phần basic. Bây giờ chúng ta đi cài đặt các thành phần cần thiết để có thể chạy được một ứng dụng Rails là Ruby, MySQL, NginX, ... nhé. Chúng ta thực hiện cài đặt các packages cần thiết như khi làm việc với một server thật là không dùng tới tab access vào docker container trước mà chúng ta sử dụng tab mới vừa SSH ở trên để thực hiện nhé             </div>
            
            <div class=

0