Deploy Rails project to AWS EC2 using Capistrano, Puma and Nginx
Đầu tiên ta cần đăng kí tài khoản AWS đã. Để có thể sử dụng free thì mình đăng kí tài khoản AWS Free Tier. Đầu tiên bạn cần 1 thẻ thanh toán quốc tế VISA/MasterCard có ít nhất 1 đô trong đó. Sau đó có thể đăng kí tại Đây . Tài khoản này được dùng miễn phí trong một năm với những giới hạn sử dụng ...
Đầu tiên ta cần đăng kí tài khoản AWS đã. Để có thể sử dụng free thì mình đăng kí tài khoản AWS Free Tier. Đầu tiên bạn cần 1 thẻ thanh toán quốc tế VISA/MasterCard có ít nhất 1 đô trong đó. Sau đó có thể đăng kí tại Đây . Tài khoản này được dùng miễn phí trong một năm với những giới hạn sử dụng nhất định.
Đã có tài khoản AWS rồi giờ thì cùng nhau deploy 1 project Rails lên đó thôi ~.~
1. Config Rails app
Tạo ứng dụng Rails:
rails new rails-aws-ec2-deploy
Thêm static page:
rails generate controller home index
Thêm vào routes:
root :to => "home#index"
Thêm capistrano, puma gem bằng cách thêm vào Gemfile:
gem 'figaro' gem 'puma' group :development do gem 'capistrano' gem 'capistrano3-puma' gem 'capistrano-rails', require: false gem 'capistrano-bundler', require: false gem 'capistrano-rvm' end
Tạo ra các file config Capistrano:
cap install STAGES=production
Sẽ tạo ra forder deploy trong config chứa production.rb, Capfile, deploy.rb
Thêm vào Capfile:
require 'capistrano/rvm' require 'capistrano/bundler' require 'capistrano/rails/assets' require 'capistrano/rails/migrations' require 'capistrano/puma' install_plugin Capistrano::Puma
Thêm vào deploy.rb: Ở đây ta chỉ cần quan tâm set :application và set :repo_url
# Tên application của mình set :application, 'urlshortner' # Repository github của bạn. Tạo 1 repo mới trên github set :repo_url, 'git@github.com:ngocvu3010/rails-aws-ec2-deploy.git' set :branch, :master set :deploy_to, '/home/deploy/urlshortner' set :pty, true set :linked_files, %w{config/database.yml config/application.yml} set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads} set :keep_releases, 5 set :rvm_type, :user set :rvm_ruby_version, 'ruby-2.2.3' set :puma_rackup, -> { File.join(current_path, 'config.ru') } set :puma_state, "#{shared_path}/tmp/pids/puma.state" set :puma_pid, "#{shared_path}/tmp/pids/puma.pid" set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock" #accept array for multi-bind set :puma_conf, "#{shared_path}/puma.rb" set :puma_access_log, "#{shared_path}/log/puma_error.log" set :puma_error_log, "#{shared_path}/log/puma_access.log" set :puma_role, :app set :puma_env, fetch(:rack_env, fetch(:rails_env, 'production')) set :puma_threads, [0, 8] set :puma_workers, 0 set :puma_worker_timeout, nil set :puma_init_active_record, true set :puma_preload_app, false
Thêm config/database.yml trong .gitignore Sau đó ta đẩy project lên Github.
2. Tạo 1 instance trên AWS EC2
Vào EC2 trên AWS, chọn Launch Instance
Chọn amazon machine image: Ubuntu Server 14.04 LTS (HVM), SSD Volume
Next qua các step đến Step 6: Configure Security Group: Chọn add thêm HTTP
Step cuối Chọn Launch. Lúc đó sẽ hiển thị ra modal tạo Key pair:
Màn hình hiển thị ntn là đã tạo instance ec2 thành công
Chuyển file pem vào ssh sau đó chmod 400 cấp quyền đọc
Trên AWS: Click vào connect sẽ thấy hướng dẫn để connect tới instance
Ta thử chạy ssh -i "urlshorter.pem" ubuntu@ec2-18-218-162-201.us-east-2.compute.amazonaws.com
Màn hình giống như vậy tức là đã connect thành công từ máy local mình tới instance EC2
Giờ thì config server thôi
3. Config server
Step 1: Update và Upgrade server:
sudo apt-get update && sudo apt-get -y upgrade
Step 2: Tạo 1 user mới cho ubutun server: Mình để là deploy
sudo useradd -d /home/deploy -m deploy sudo passwd deploy
Sau đó cấp quyền cho user deploy
sudo visudo
Thêm deploy ALL=(ALL:ALL) ALL ngay dưới dòng root ALL=(ALL:ALL) ALL
Step 3: Login user deploy và tạo public key
su - deploy
Ở teminar chuyển từ ubuntu@ip-172-31-36-238: thành deploy@ip-172-31-36-238: nghĩa là ta đã đăng nhập thành công
Tạo public key:
ssh-keygen
Copy ssh-key vào Settings => SSH and GPG keys, tạo 1 ssh key mới cho github Sau đó ta authenticate ssh đó trên máy của mình
Step 4: Copy public key và paste vào server authorized_keys
Sau đó paste vào file authorized_keys server instance:
deploy@ip-172-31-36-238:~/.ssh$ vi authorized_keys
Cấp quyền truy cập:
sudo chmod 700 .ssh sudo chmod 600 authorized_keys
Step 5: Cài đặt git, nginx
Cài đặt git trên server:
sudo apt-get install git
Cài đặt Nginx:
sudo apt-get install nginx
Sau đó sửa file config của nginx: deploy@ip-172-31-36-238:~$ sudo vi /etc/nginx/sites-available/default. Xóa config mặc định đi Paste đoạn config này vào đó:
upstream app { # Thay đường dẫn đến File Puma.sock server unix:/home/deploy/urlshortner/shared/tmp/sockets/puma.sock fail_timeout=0; } server { listen 80; server_name localhost; # Thay đường dẫn đến public root /home/deploy/urlshortner/current/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; }
Step 6: Cài đặt mysql cho server:
sudo apt-get install mysql-server mysql-client libmysqlclient-dev
Tạo 1 database mới bằng cách :
mysql -u root -p CREATE DATABASE database_production CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
Như vậy đã tạo xong DB cho production
Step 7: Cài RVM cho server
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 curl -sSL https://get.rvm.io | bash -s stable rvm install 2.3.1
Step 8: Cài đặt bundler gem cho server:
gem install bundler --no-ri --no-rdoc
Step 9: Tạo cấu trúc thư mục cho server:
Ở trong folder deploy.rb ta để ý dòng set :deploy_to, '/home/deploy/urlshortner'. Hiện tại trên server ta gõ pwd sẽ ra thư mục hiện tại /home/deploy. cần tạo thư mục tên theo mình set ở trên là urlshortner
mkdir urlshortner mkdir -p urlshortner/shared/config nano urlshortner/shared/config/database.yml
Điền các thông tin vào database.yml
production: adapter: mysql2 encoding: utf8mb4 pool: 5 database: <your_database_name> # Ở đây của mình là database_production username: root password: <your_mysql_password> socket: /var/run/mysqld/mysqld.sock
Tiếp đến tạo application.yml: Tạo secret key ở local bằng cách: RAILS_ENV=production rake secret sẽ sinh ra secret key. Ta paste SECRET_KEY_BASE: "<your_secret_key_base>" vàp application.yml ở server
nano urlshortner/shared/config/application.yml
Step 10: Thêm vào config/deploy/production.rb ở local:
server '18.218.162.201', user: 'deploy', roles: %w{web app db}
18.218.162.201 là địa chỉ IPv4 Public IP mà các bạn có thể thấy ở trang thông tin instance lấy từ đường link này: ec2-18-218-162-201.us-east-2.compute.amazonaws.com
Sau đó chạy lệnh
cap production deploy
Hiển thị ntn là đang deploy:
sau khi deploy xong ta restart lại nginx
sudo service nginx restart
Cùng nhìn kết quả nào:
Vậy là chúng ta đã deploy xong!
Nếu không thể rails c trên server được thì add thêm
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
vào deploy.rb Sau đó deploy lại và chạy rails c bằng cách
RAILS_ENV=production bundle exec rails console
Bạn có thể tham khảo github: https://github.com/ngocvu3010/rails-aws-ec2-deploy
Hi vọng bài viết sẽ giúp ích cho bạn.
Nguồn tham khảo
https://www.youtube.com/watch?v=imdrYD4ooIk
https://viblo.asia/p/huong-dan-deploy-ung-dung-ruby-on-rails-len-server-aws-ec2-su-dung-gem-capistrano-puma-va-nginx-Eb85oXDWK2G