[RoR] Auto deploy ứng dụng rails trên Amazon EC2 [Part 1]

Mở đầu

Là một developer mới vào nghề, tôi (cũng như nhiều những developer khác như tôi) thường chỉ quan tâm tới quá trình phát triển của một ứng dụng như là xử lý logic, xử lý nghiệp vụ, code như thế nào cho đẹp, cho sạch sẽ, v.v.. hơn là chú ý tới khâu sau cùng đó là deploy lên môi trường production và mặc định nghĩ rằng đó là trách nhiệm của ông leader hay ông SystemAdmin. Tuy nhiên để chuẩn bị cho những tình huống xấu nhất xảy ra (cả 2 ông nghỉ ở nhà trông con chẳng hạn !!), thì việc có kiến thức về deploy là rất cần thiết. Tiếp sau bài viết tìm hiểu về Amazon S3, trong bài viết này mình xin giới thiệu về dịch vụ Amazon EC2 và deploy ứng dụng Ruby on Rails trên đó sử dụng Capistrano. Bài viết chia làm 2 phần, trong phần đầu này tôi sẽ giới thiệu sơ qua về EC2, cách tạo một instance và config trên instance đó.

Trong bài viết này sẽ sử dụng bộ 3 Puma + Nginx + PostgreSQL. Puma là application server, Nginx đóng vai trò là một proxy server trung gian giữa app server và client, PostgreSQL là database.

Giới thiệu dịch vụ Amazon EC2

Theo định nghĩa của Amazon thì:

Amazon EC2 (Elastic Cloud) là một trong những gói dịch vụ của AWS cung cấp giải pháp điện toán đám mây cho phép người dùng có thể tạo, thiết lập và sử dụng một server một cách dễ dàng. Do Amazon EC2 là một giải pháp điện toán đám mây nên nó giảm tối thiểu các bước cài đặt và cấu hình một server. Ngoài ra, khi có nhu cầu người dùng có thể dễ dàng scale công năng của server một cách dễ dàng. Điều này rất khó khăn nếu bạn mua và setup một server vật lý.

Đăng ký sử dụng dịch vụ

Để sử dụng được dịch vụ EC2, ta follow theo các steps như sau:

  1. Đăng ký AWS account Bạn có thể xem lại cách tạo tài khoản trong bài viết Giới thiệu dịch vụ S3

  2. Tạo EC2 Instance

  • Từ màn hình dashboard search dịch vụ EC2 - Virtual Server on the Cloud

  • Click ‘Launch Instance’:

  • Chọn Amazon Machine Image (AMI), ở đây tôi chọn Ubuntu Server 14.04 LTS

  • Chọn cấu hình phù hợp với nhu cầu của bạn, ở đây tôi chọn t2.micro bời vì nó free rồi Click Next:Configure Instance Details để tiếp tục

  • Sử dụng cấu hình default là ổn, tiếp tục click Next: Add Storage

  • Tại đây, chọn dung lượng ổ cứng phù hợp với nhu cầu của bạn, với tài khoản free thì ta có 30GB dung lượng miễn phí, tiếp theo Click Next: Add Tags

  • Đặt tên cho instance của bạn và Click Next: Configure Security Group

  • Click Add Rule và chọn type là HTTP, config thế này để request từ bên ngoài internet có thể tới được Nginx server. Rồi click Review And Launch

  • Check lại setting rồi click Launch

  • Tạo một cặp key pair và download về máy, ta sẽ sử dụng file config này để ssh vào server sau này, thường file này lưu trong thư mục ~/.ssh. Click Launch Instance -> chờ một chút -> Click View Instances, ta sẽ thấy instance đang trong trạng thái running

  • Chọn instance và click Connect

  • Ở đây ta sẽ thấy hướng dẫn để connect tới con vps của chúng ta.

Setup môi trường trên EC2 instance

  • Trước hết cần ssh vào server sử dụng cặp key mà ta đã download bên trên
ssh -i "DuyBuffetPrivate.pem" [email protected]
  • Tạo user deploy dùng để deploy code
sudo useradd -d /home/deploy -m deploy
  • user deploy sẽ được tạo ra cùng với home directory của nó. Ứng dụng sẽ được deploy ở thư mục này, vì vậy ta cần set cả password nữa
sudo passwd deploy
  • set quyền sudo cho user deploy, chạy lệnh sau sudo visudo và paste đoạn dưới đây vào:
deploy ALL=(ALL:ALL) ALL
  • trong bài viết này, ta sẽ đặt repo trên github, vì vậy, user deploy sẽ cần quyền access vào github. Gen cặp key-pair sau (Chỉ enter enter không nhập thêm thông tin gì cả)
su - deploy
ssh-keygen
cat .ssh/id_rsa.pub
  • Copy output và paste vào danh sách ssh keys của bạn trên Github

  • Ta sẽ deploy app từ local lên EC2 instance thông qua user deploy, và AWS yêu cầu chỉ authentication thông qua public key, vì vậy ta cần copy public key từ máy local (default là ở ~/.ssh/id_rsa.pub) lên EC2 instance. Trên server:

nano .ssh/authorized_keys
  • Paste và save là xong.

  • Để auto deploy, ta cần install thêm git

sudo apt-get install git

Install Nginx

  • Install Nginx bằng lệnh apt-get
sudo apt-get install nginx
  • Config sao cho Nginx trở thành server proxy để hướng mọi HTTP Request đến Puma app server của chúng ta thông qua UNIX socket: Mở file config
sudo nano /etc/nginx/sites-available/default
  • Comment hết những config default và copy đoạn dưới đây vào
upstream app {
  # Path to Puma SOCK file, as defined previously
  server unix:/home/deploy/auto_deploy_app/shared/tmp/sockets/puma.sock fail_timeout=0;
}

server {
  listen 80;
  server_name localhost;

  root /home/deploy/auto_deploy_app/public;

  try_files $uri/index.html $uri @app;

  location / {
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Connection '';
    proxy_pass http://app;
  }

  location ~ ^/(assets|fonts|system)/|favicon.ico|robots.txt {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
}

Install PostgreSQL

sudo apt-get install postgresql postgresql-contrib libpq-dev
  • Sau khi install xong, tạo user và production database
sudo -u postgres createuser -s duybuffet
  • Set password cho user từ psql console
sudo -u postgres psql
postgres=# \password duybuffet
  • Thoát ra khỏi console (\q) và tạo database production
sudo -u postgres createdb -O duybuffet demo_production

Install RVM & Ruby

  • Ở đây mình cài RVM để quản lý ruby version
su - deploy
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
  • Logout (Ctrl + D) rồi login lại su - deploy để load thành công rvm vào shell của user deploy
  • Install ruby
rvm install ruby
  • Chuyển sang version ruby mới nhất vừa install xong:
rvm use ruby
  • Install bunlder
gem install bundler --no-ri --no-rdoc

Kết luận

Trong bài viết này, tôi đã giới thiệu qua về Amazon EC2, cách thiết lập 1 instance cũng như cấu hình nó nhằm phục vụ cho mục đích deploy một ứng dụng rails. Trong phần tới, tôi sẽ nói nốt về cách cấu hình rails app, sử dụng Capistrano để auto deploy app từ local.

Tài liệu tham khảo

  1. Amazon EC2
  2. Sitepoint