Docker on Rails デモ ヤリマスヵ...


はじめに

                 )
                 ( _
            , - ニ ̄   ̄  、
           /               `ヽ
        , - '、      -=-  -=- ',_
       r´   ヽ.    γ  ̄ ヽ γ ̄ヽ ',ヽ.
      {      i=={ l    l.=l l   .} | i__  Docker デモ ヤリマスヵ...
.      i  < ̄`ヽ、 弋ゝ _ノ 弋ゝ ノ >´ , ィ´
      弋__ _> 、 ヽ、  ̄       ̄ / /ヽ
         |     ` ー
             }
         ゝ、                  /
           `ー -、 - ______ , ィ´
           /    l /   |>く| \ ハ
             /_   .l > .|:H:| く l ハ
           , ‐´  `ヽ、l /  .l:l l:l  l.l-‐'ー、
        γ       ヽ.',  l:l l:l  l l    ヽ
         {        }. ',  l:l l:l  .l l      }
          ',         /  ', l:l l:l  l  l    /

やりたいこと

  • Postgresql と Redis がつながる Rails を Docker の上でつくりたい
    • Docker
      • できるだけ軽く、速く、安全なコンテナを作る
      • Ubuntu で Docker を使うと権限関連がひどいことになるので、それを防ぎたい
    • PostgreSQL
      • Rails でマスタとレプリカを使いたいので、コンテナは2台は必要
    • Redis
      • Rails でキャッシュと Sidekiq 用に2台ほしい
    • Ruby on Rails
      • 快適な Rails 開発環境を手に入れたい

開発環境について

$ uname -a
Linux def 5.4.0-29-generic #33-Ubuntu SMP Wed Apr 29 14:32:27 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ docker -v
Docker version 19.03.8, build afacb8b7f0
$ docker-compose -v
docker-compose version 1.25.0, build unknown

コード

Github のレポジトリ にあります。

まずは Ruby の Dockerfile をつくろう

FROM node:14.1.0-alpine3.11 as node

FROM ruby:2.7.1-alpine3.11 as ruby

ENV LANG=C.UTF-8
ENV RAILS_ENV=development
ENV RACK_ENV=development
ENV USER_NAME=un
ENV GROUP_NAME=gn
ENV USER_ID=1000
ENV GROUP_ID=1000

WORKDIR /usr/www/com/

COPY --from=node /usr/local/bin/node /usr/local/bin/

COPY Gemfile Gemfile.lock yarn.lock package.json ./

RUN addgroup -S ${GROUP_NAME} -g ${GROUP_ID} && \
    adduser -S ${USER_NAME} -G ${GROUP_NAME} -u ${USER_ID} && \
    apk update && apk upgrade && \
    apk add build-base tzdata libxml2-dev curl imagemagick postgresql-client postgresql-dev yarn && \
    if [ ${RAILS_ENV} != "production" ]; then apk add git chromium-chromedriver chromium zlib-dev xvfb wait4ports xorg-server dbus ttf-freefont mesa-dri-swrast curl udev graphviz; fi && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    gem update --system && \
    if [ ${RAILS_ENV} = "production" ]; then bundle config set without 'production'; fi && \
    bundle install --jobs 20 --retry 5 && \
    bundle update && \
    yarn install && \
    yarn upgrade && \
    yarn cache clean

USER 1000:1000

つぎは docker-compose でも組み立てよう

version: '3.7'

volumes:
  pg-volume:
  redis-sidekiq-volume:
  redis-cache-store-volume:    

networks:
  main:
    driver: bridge

services:
  database-master:
    image: postgres:12-alpine
    ports:
      - 54321:5432
    environment:
      POSTGRES_USER: asdf
      POSTGRES_PASSWORD: qwer
      POSTGRESQL_REPLICATION_MODE: master
      TZ: Etc/GMT
    volumes:      
      - pg-volume:/var/lib/postgresql/data      
    networks:
      main:

  database-replica:
    image: postgres:12-alpine
    ports:
      - 54322:5432
    environment:
      POSTGRES_USER: asdf
      POSTGRES_PASSWORD: qwer
      POSTGRESQL_REPLICATION_USER: asdf
      POSTGRESQL_REPLICATION_PASSWORD: asdf
      POSTGRESQL_MASTER_HOST: database-master
      POSTGRESQL_REPLICATION_MODE: slave
      POSTGRESQL_MASTER_PORT_NUMBER: 5432
      TZ: Etc/GMT
    depends_on:
    - database-master
    networks:
      main:

  redis-cache-store:
    networks:
      main:
    image: redis:5.0.7
    environment:
      TZ: Etc/GMT
    ports:
      - 6379:6379
    volumes:
      - redis-cache-store-volume:/var/lib/redis
    networks:
      main:

  redis-sidekiq:
    networks:
      main:
    image: redis:5.0.7
    environment:
      TZ: Etc/GMT      
    ports:
      - 6380:6379
    volumes:
      - redis-sidekiq-volume:/var/lib/redis
    networks:
      main:

  application-server:
    user: 1000:1000
    build:
      context: ./rails/
      target: ruby
    ports:
      - 3001:3000
    volumes:
      - ./rails/:/usr/www/com/
    stdin_open: true
    tty: true
    environment:
      REDIS_CACHE_STORE_URI: 'redis://redis-cache-store:6379/0'
      REDIS_SIDEKIQ_URI: 'redis://redis-sidekiq:6379/0'
      DATABASE_MASTER_HOST: 'database-master'
      DATABASE_MASTER_USERNAME: 'asdf'
      DATABASE_MASTER_PASSWORD: 'qwer'
      DATABASE_MASTER_PORT: 5432
      DATABASE_REPLICA_HOST: 'database-replica'
      DATABASE_REPLICA_PASSWORD: 'qwer'
      DATABASE_REPLICA_USERNAME: 'asdf'
      DATABASE_REPLICA_PORT: 5432
    command: 
      /bin/sh -c "yarn install --check-files && bundle update && bundle exec rails db:migrate:reset && bundle exec rails s -p 3000 -b '0.0.0.0' --early-hints"
    links:
      - redis-cache-store
      - redis-sidekiq      
      - database-master
      - database-replica
    networks:
      main:

動作確認

$ docker-compose up -d && xdg-open http://localhost:3001/    


これがみれるとホッとしますね...

やれていないこと

  • リバースプロキシが入っていない
  • Docker
    • Trivyでイメージの安全性を確認する。
    • マルチステージビルドを活用して、コンテナを軽量化する
    • Production環境で使えるイメージには程遠い...

おわりに

計算機科学ノ進歩、発展ノタメニハ、犠牲ガツキモノナノデース.

参考文献

更新履歴

  • 2020-05-07: Dockerfile を更新