12/08/2018, 15:37

Vận hành một Website Free trên Heroku, tại sao không?

Chắc hẳn với những ai mới làm quen với Rails hay đã quá quen thuộc với Rails đều biết đên Heroku và cũng ít nhất 1 lần thử deploy ứng dụng lên đây. Không thể phủ nhận một điều là Heroku giúp chúng ta deploy một ứng dụng Rails hết sức dễ dàng chỉ với vài thao tác. Chúng ta thường sử dụng heroku như ...

Chắc hẳn với những ai mới làm quen với Rails hay đã quá quen thuộc với Rails đều biết đên Heroku và cũng ít nhất 1 lần thử deploy ứng dụng lên đây. Không thể phủ nhận một điều là Heroku giúp chúng ta deploy một ứng dụng Rails hết sức dễ dàng chỉ với vài thao tác. Chúng ta thường sử dụng heroku như một nơi để deploy các ứng dụng làm demo, một số app đơn giản những đã có ai suy nghĩ đến việc sử dụng luôn app đó như một sản phẩm thực sự? trên thực tế Heroku có thể hỗ trợ các website chạy lâu dài và ổn định.

Bài viết này mình xin đưa ra một số mẹo nhỏ giúp mọi người có thể triển khai một ứng dụng web lên heroku một cách lâu dài và ổn định mà không phải lo nghĩ về vấn đề kinh phí duy trì hệ thống mỗi tháng.

Heroku cho phép app bạn sử dụng hạn chế và số records được phép với các dạng free, tuy nhiên, đối với các website hoạt động lâu dài hoặc có lượng dữ liệu lớn thì phải chịu phí với các gói khác nhau. Chi phí này tính ra không hề rẻ và có thể còn đắc hơn cả giá thuê 1 VPS.

Solution: Như đã nói ở trên là chi phí sử dụng các gói db khác của heroku đắc hơn nhiêu so với thuê riêng một VPS, vì vậy giải pháp đơn giản ở đây là bạn sử dụng (nếu đã có sẵn VPS) hoặc reg một cái để chạy DB server, hỗ trợ remote connection cho nhiều apps. Dưới đây là lệnh config lạ DATABASE_URL trỏ đến một DB server khác.

$ heroku config:set DATABASE_URL:postgres://<user>:<password>@<host>:<port>/<db_name>

Đối với các ứng dụng chạy trên heroku thì việc tạo ra các files sẽ chỉ có thể tồn tại trong thời là 20 phút hoặc cho đến lần deploy tiếp theo. Nếu app bạn cho phép post hình ảnh hoặc files thì không thể tồn tại lâu dài trong quá trình sử dụng được.

Solution: Sử dụng Amazon S3 để lưu trữ files, hầu hết các gem upload files đều hỗ trợ tích hợp upload lên S3 một cách rất dễ dàng. Hiện nay Amazon Services đang hỗ trợ các startup với mức giá khá hợp lý, bao gồm free 1 năm đầu trong một giới hạn cho phép, chi phí để lưu trữ files trên S3 có thể nói là giải pháp tiết kiệm nhất hiện nay.

Ví dụ cấu hình việc upload avatar với Paperclip:

has_attached_file :avatar, 
  storage: :s3, 
  bucket: '<bucket_name>', 
  s3_host_name: '<host_name>',
  s3_credentials: {
    access_key_id: 'access_key',
    secret_access_key: 'sectrect_key',
}

Ngoài Amazon S3, để upload ảnh có thể sử dụng Cloudinary, đây là một dịch vụ khá tốt, mỗi tài khoản miễn phí có thể kiếm được lên tới hơn 3GB dung lượng lưu trữ miễn phí.

Mặc định mỗi app trên Heroku sẽ có 1 ID, đường dẫn truy cập website sẽ có dạng <app_id>.herokuapp.com, nếu là một website hoạt động thực tế thì tên miền như vậy có lẽ hơi kỳ.

Solution: Heroku hỗ trợ việc trỏ tên miền vào app khá đơn giản, với hạn chế là chỉ trỏ được với domain www, bạn cần thực hiện theo 2 bước sau:

  1. Trỏ cname www record trỏ đến địa chỉ app của bạn. VD: www –> sample.herokuapp.com
  2. Add domain của bạn vào setting của app trên heroku để cho phép domain này trỏ đến app.
$ heroku domains:add -a sample-app www.sample.com

Các app chạy trên heroku đơn giản là không được cấp 1 ip tĩnh nào cố định như lúc chạy trên VPS, vì vậy bạn không thể config A @ record trong DNS trỏ đến IP tĩnh được.

VD: Bạn muốn sample-app.com trỏ đến app của bạn trên heroku thì rất khó, ngoại trừ dùng DNS Simple với một mức phí nào đó.

Solution: Cách đơn giản là bạn add một A record @ trỏ đến một VPS, có thể là VPS chứa DB đã nói ở trên của bạn. Sau đó config apache hay nginx để redirect non-www đến www đối với domain này.

Do mỗi app chỉ được free 1 dyno, từ 2 dynos trở lên sẽ phải trả một khoảng phí tương đối không phải nhỏ. Tuy nhiên app vẫn có thể chạy tốt với tốc độ thỏa yêu cầu cơ bản mà không cần phải tốn chi phí để mua thêm 1 dyno khác từ heroku.

Solution: Giải pháp đơn giản trong trường hợp này là sử dụng Unicorn để chạy web app thay vì dùng server Puma của Rails như thông thường, Unicorn cho phép cấu hình file config với số processes và thời gian timeout tùy chọn, vì vậy chỉ cần bạn tăng số process xử lý của Unicorn từ 1 lên 3, vậy là app của bạn đã đảm bảo được tương đối những yêu cầu về tốc độ rồi đúng không.

Cách config Unicorn cho app trên heroku:

  1. Tạo file Procfile tại root của app với nội dung
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
  1. Thêm gem 'unicorn' vào Gemfile
  2. Thêm file config/unicorn.rb như sau:
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 60
preload_app true
 
before_fork do |server, worker|
   Signal.trap 'TERM' do
     puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
     Process.kill 'QUIT', Process.pid
   end
   defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
end
 
after_fork do |server, worker|
   Signal.trap 'TERM' do
     puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
   end
 
   defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

Thật đơn giản phải không? Chỉ với một số bước đơn giản bạn đã có thể giúp website của mình hoạt động ổn định trên một free host. Chúc bạn thành công!

0