+2

Deploy 1 app Ruby on Rails bằng AWS AppRunner

Xin chào các bạn. Lâu lắm mới lên bài có làm hands-on.

Gần đây do công việc cá nhân nên mình đã thử khá nhiều cách deploy trên AWS. Và hiện thì mình đã deploy thành công trên AWS AppRunner với khá nhiều thứ phải config nên muốn viết lại chia sẻ cho các bạn. Đó là lý do bài viết này sinh ra.

Giới thiệu về AWS AppRunner

AWS App Runner là một dịch vụ ứng dụng bộ chứa được quản lý toàn phần cho phép bạn xây dựng, triển khai và chạy các ứng dụng web cũng như dịch vụ API được đưa vào container mà không cần có cơ sở hạ tầng hoặc kinh nghiệm về container trước đó.

Nôm na các bạn sẽ không cần quan tâm tới infra, chỉ cần build 1 cái docker image thật chuẩn rồi đưa lên là xong.

Còn về giá cả thì khá rẻ, nhưng không nằm trong Free Tier 😂😂😂

image.png

Tổng quan hệ thống sẽ làm

Sau khi dựng hệ thống và xem lại thì đây là hệ thống mình đã triển khai thành công:

Các bước chuẩn bị cho phía local

Setup project Ruby on Rails

Bước đầu tiên chúng ta cần làm là chuẩn bị 1 Dockerfile:

FROM ruby:3.1.2

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -\
    && echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list

RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -

RUN apt-get update -qq && apt-get install -y nodejs build-essential postgresql-client yarn \
    curl dirmngr apt-transport-https lsb-release ca-certificates

WORKDIR /rails-lyrics-site
COPY Gemfile /rails-lyrics-site/Gemfile
COPY Gemfile.lock /rails-lyrics-site/Gemfile.lock
RUN bundle install

COPY . /rails-lyrics-site
RUN mkdir -p tmp/sockets

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

VOLUME /rails-lyrics-site/public
VOLUME /rails-lyrics-site/tmp

CMD bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
EXPOSE 3000

Ở bên trên, ngoài các thao tác lq tới file entrypoint chúng ta sẽ thiết lập sau thì chúng ta cần định nghĩa volume tmp và public, đồng thời phía dưới mở port 3000 để container đọc được

Nội dung của entrypoint.sh

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

if [ "$RAILS_ENV" = "production" ]; then
  bundle exec rails assets:precompile
  bundle exec rails db:create
  bundle exec rails db:migrate
fi

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

Và cuối cùng là file docker-compose.yml:

version: '3'

services:

  app-runner:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/rails-lyrics-site
      - bundle:/usr/local/bundle
      - tmp-data:/rails-lyrics-site/tmp
      - public-data:/rails-lyrics-site/public
    ports:
      - "3000:3000"

volumes:
  bundle:
  tmp-data:
  public-data:

Tại sao ở đây mình chỉ dùng duy nhất 1 container và không dùng container nào khác? Well, AppRunner chỉ cho chạy 1 container và nếu mình tạo file như chạy local thông thường thì lúc deploy sẽ bị báo không tìm thấy container phụ thuộc dẫn tới deploy hỏng.

Sau đó thì theo các bước tạo Gemfile, Gemfile.lock, khởi tạo project như ở bài Tạo project Rails 6 với PostgresSQL 11 bằng Docker (bài hơi cũ, Rails version cũng cũ nhưng mà cách làm vẫn y hệt), chúng ta sẽ có 1 project Rails 7

Setup database và assets compile

# config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

production:
  <<: *default
  database: lyrics_site_production
  host: <%= ENV["DB_HOST"] %>
  username: <%= ENV["DB_USERNAME"] %>
  password: <%= ENV["DB_PASSWORD"] %>

Setup database như trên bởi các bạn chỉ cần 1 database cho hệ thống, còn host, username và password để connect tới database server sẽ không cố định và là thông tin cần bảo mật nên ta sẽ dựa vào biến môi trường.

Tiếp đó, chúng ta sửa ở config/environments/production.rb như sau:

 config.assets.compile = true

Về cơ bản ta đã thiết lập xong phía local.

Các bước chuẩn bị cho phía AWS

Trước khi vào bước đầu tiên thì phần này mình cứ giả sử các bạn có tài khoản AWS rồi để bài có thể đi vào nội dung chính nhất có thể

Tạo 1 ECR

Phần này là phần tạo đơn giản, vào màn hình quản lý ECR, chọn "Create Repository" và nhập tên vào là xong

Sau khi tạo xong, các bạn nhớ hãy push image vừa được tạo phía lên ECR repository mới tạo

Screenshot 2023-09-30 at 13.42.43.png

Tạo RDS

Đây là phần cơ bản với AWS nên mình cũng xin chỉ nêu ra. Các bước cụ thể các bạn cứ làm như bình thường. Kết quả cuối cùng đã che là đây:

Nhân tiện đừng thấy cái AZ mình dùng và ảnh có che ở trên mà có những suy nghĩ mở rộng nhé các bạn 😂😂😂

Deploy

Đầu tiên, vào AppRunner, bấm Create Service và màn hình hiện ra:

Mục Container image URI thì điền URI của ECR mới tạo bên trên, ví dụ: xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/lyrics-site-app-runner:latest

Mục Deployment Setting, chọn như sau:

Screenshot 2023-09-30 at 14.16.26.png

ECR access role ở đây mình đã từng tạo rồi nên dùng luôn cái đã tạo. Các bạn chọn Create new role cũng không vấn đề gì.

Còn deploy thì mình xác định là deploy tạm và Automatic deploy tốn tiền nên mình chọn Manual

Sang trang tiếp theo:

Các bạn điền service name tuỳ ý, tự setup Virtual CPU và Virtual memory theo nhu cầu

Phần Environment Variables các bạn điền các biến sau

Để kết nối với database, các bạn vào Networking, custom như dưới:

VPC, Subnets, SecurityGroups là thông tin của phía RDS.

Sau đó các bạn deploy và trang web trống sẽ hiện ra. Bước tiếp theo bạn hãy import 1 chút data vào database mới tạo ở RDS.

Và đây là sản phẩm sau khi deploy và import data. Hãy chú ý tới domain gạch đỏ: https://hmmhmdmsb7.ap-northeast-1.awsapprunner.com

Các bạn cũng có thể custom domain hay gì đó vì trong AppRunner cũng có option này

Kết bài

Mình có để lại branch mình đã làm để các bạn tham khảo: https://github.com/BlazingRockStorm/rails-lyrics-site/tree/app-runner. Các bạn clone branch này về và thử deploy nếu có hứng thú nhé.

  • P/s: Các bạn nên deploy thử chứ link trên kia mình sẽ tắt và xoá trong vì đây chỉ là deploy thử nghiệm của mình. Mình không có ý định dùng nó lâu dài

Tham khảo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí