Nic Lin's Blog

喜歡在地上滾的工程師

從零搭建,如何讓 Rails 跑在 Kubernetes(k8s)(一)

Kubernetes(k8s) 是一個由 Google open source 的自動部屬、擴展、管理都容器化的系統。

詳細介紹這邊就不多說了,基本上搜一下都能夠有個脈絡,這篇主要會是講如何在自己的本機掛起一個新的 Rails 專案並且用 k8s 管理部屬。

開發前準備

本篇教學使用 MacOS 10.14 Mojave 系統

新建一個 Rails 專案

在這邊我會使用 ruby-2.4.4 以及 Rails 5.2.1.1 作為示範

  • 用 Devise 做登入系統
  • 資料庫採用 Postgresql

創建一個新的 app,名稱為 rails-app

rails new rails-app --database=postgresql

新增 devise 到 Gemfile

gem 'devise'

裝完要跑 bundle install

建立 devise 的設定以及 model

rails generate devise:install
rails generate devise user

這裡因為有建立一個 user.rb 的 model,要記得跑 migration

run rake db:create db:migrate

到這裡如果沒問題,可以在本地跑 rails server,測試是不是正常運行。

Docker-compose

接下來我們要將 Rails App 容器化,也可以參考 docker 官方的教學

建立容器所需的檔案

touch Dockerfile

並將內容編輯如下

FROM ruby:2.4.4

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

RUN mkdir /rails-app

WORKDIR /rails-app

ADD Gemfile /rails-app/Gemfile
ADD Gemfile.lock /rails-app/Gemfile.lock

RUN bundle install

ADD . /rails-app

COPY docker-entrypoint.sh /usr/local/bin

RUN chmod 777 /usr/local/bin/docker-entrypoint.sh \
    && ln -s /usr/local/bin/docker-entrypoint.sh /

ENTRYPOINT ["docker-entrypoint.sh"]

建立進入點檔案 touch docker-entrypoint.sh

#!/bin/sh
set -e
if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi
exec bundle exec "$@"

這個腳本會避免重新啟動 Rails App 時因為沒有殺掉 server.pid 而卡住的問題。

建立設定檔

touch docker-compose.yml

編輯內容如下:

version: "3"
services:
  db:
    image: postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=mysecurepass
      - POSTGRES_DB=rails-app_development
      - PGDATA=/var/lib/postgresql/data
  app:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/rails-app
    ports:
      - "3000:3000"
    depends_on:
      - db

等下會用到 postgres 的 docker image,我們要先設定要用到的環境變數,必須先修改 config/database.yml,可以參考 image 設定說明

修改 config/database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: mysecurepass
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  port: 5432

development:
  <<: *default
  database: rails-app_development

test:
  <<: *default
  database: rails-app_test

在建立容器之前,避免不必要的檔案被加入

touch .dockerignore

tmp/*
log/*

一切就緒後,就可以容器化了

docker-compose build

這時候應該會看到 docker 在執行腳本,並且出現熟悉的 bundle install 了。

啟動 docker

docker-compose up app

透過 docker 跑 migrate

docker-compose run app rails db:create db:migrate

這時候在瀏覽器中打開 http://localhost:3000 應該就可以看到熟悉的畫面了。

comments powered by Disqus