概要

Railsで非同期処理をするライブラリとして、Sidekiqがあります。

ここでは、Sidekiqを実行することを前提としたdocker-compose.ymlファイルを紹介したいと思います。

環境

  • Ruby on Rails 6.0.3

Sidekiqの実行について

Sidekiqは、Railsで非同期処理を行うためのライブラリですが、実行の際にはRailsのプロセスとは別に実行する必要があります。

また、負荷分散等で複数のRailsアプリを動かす場合は、Sidekiqをアプリケーションとは別の場所から動かしたいということがあります。

このようなことを普通の開発環境で実現しようとすると面倒ですが、DockerやDocker Composeを使うと簡単にできます。

設定ファイル

ここでは、Docker Composeを使った、アプリケーションとは別のコンテナでSidekiqを実行する設定ファイルについて紹介します。

docker-compose.ymlファイルでは、5つのコンテナを実行します。

  • アプリケーション(rails)
  • Sidekiq(sidekiq)
  • コマンド実行用(spring)
  • データベース(db)
  • Redis(redis)

Redisは、Sidekiqが処理する情報を保存するためのものです。

実際のファイルはこのようになりました。

version: '3'
services:
  rails: &app_base
    build: .
    command: ["bundle", "exec", "rails", "s", "-p", "3000", "-b", "0.0.0.0"]
    environment:
      - "DATABASE_HOST=db"
      - "DATABASE_PORT=5432"
      - "DATABASE_USER=postgres"
      - "DATABASE_PASSWORD=password"
      - "REDIS_URL=redis://redis:6379"
    volumes:
      - ".:/app"
      - "bundle:/usr/local/bundle"
    ports:
      - "3000:3000"
    tty: true
    stdin_open: true
  sidekiq:
    <<: *app_base
    command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"]
    ports:
      - "6379:6379"
  spring:
    <<: *app_base
    command: ["bundle", "exec", "spring", "server"]
    ports: []
    tty: false
    stdin_open: false
  db:
    image: postgres:12
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=password"
    volumes:
      - "db:/var/lib/postgresql/data"
    ports:
      - "5432:5432"
  redis:
    image: redis:6.0-alpine

volumes:
  bundle:
    driver: local
  db:
    driver: local

Dockerfileは次のようにしました。

FROM ruby:2.7

ENV APP_ROOT /app

ENV LANG C.UTF-8

WORKDIR $APP_ROOT

RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - && \
  apt-get install -y nodejs && \
  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
  echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
  apt-get update && \
  apt-get install -y yarn && \
  apt-get install -y build-essential && \
  apt-get install -y default-mysql-client && \
  apt-get install -y postgresql-client && \
  apt-get install -y sqlite3 && \
  apt-get install -y optipng jpegoptim && \
  gem install bundler

ENV ENTRYKIT_VERSION 0.4.0

RUN wget https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz && \
  tar -xvzf entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz && \
  rm entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz && \
  mv entrykit /bin/entrykit && \
  chmod +x /bin/entrykit && \
  entrykit --symlink

COPY Gemfile $APP_ROOT
COPY Gemfile.lock $APP_ROOT

ENTRYPOINT ["prehook", "bundle install", "--"]

かなり長い設定となってしまいましたが、Sidekiqを別のコンテナとして動かすことができるようになりました。

さいごに

Dockerを使うのは簡単なのですが、Dockerのためのイメージを作成しようとすると、デバッグが正直面倒です。

Dockerはもう少しこの辺りがいい感じになったら、もっと使いやすいツールになりそうです。