廃墟

本ブログは更新を終了しました。 技術的な記事のみ、有用性を鑑みて残しておきます。

rails + sunspot なアプリケーションの本番環境をdocker-composeでつくる

Dockerやdocker-composeの話って結構「いいよ」と目にするんですが、いざ始めようと思うとハードルが高いですよね。

僕も今日は丸一日Docker(-compose)に吸われてしまいましたが、その成果をちょっとメモしておきます。

やりたいこと

やりたいのは以下のような構成。

  • Railsが動くコンテナをDockerで作る
  • Sunspotによる検索をしたいのでsolrをDockerで動かす
  • DBはRDSを想定するのでコンテナでは作らず外部に繋ぐ

想定環境

  • Mac OSX Sierra (10.12.4)
  • Docker 17.06.1-ce
  • docker-compose 1.14.0

DBをローカル宛にする方法

まず簡単な方から。

これは、単に docker.for.mac.localhost というホスト名でホストOSが見えるようになっているので、以下のようにすればOK。

# .env.production (抜粋)
DATABASE_URL=mysql2://root:@docker.for.mac.localhost:3306/my_app
# database.yml (抜粋)
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000
  username: root
  password: ''
  socket: /tmp/mysql.sock
production:
  <<: *default
  database: my_app
  # ↓ ここが重要。他はデフォルト。
  url: <%= ENV['DATABASE_URL'] %>

この場合のDockerfile/docker-composeは後述のsolrを使う場合のから読み取って欲しい。

SolrをDockerベースで動かしつつsunspotと連携させる方法

こっちが難しかった。

先にコードを示す。

#Dockerfile
FROM ruby:2.4.1
RUN apt-get update -qq && \
  apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle config build.nokogiri --use-system-libraries && \
  bundle install -j3 --without test development --no-cache
COPY . /app

こっちは割と普通の例だと思う。 bundle install--deployment を付けるとrakeがないって怒られるようになってしまったので、つけるのやめた。

# docker-compose.yml
version: '2'
services:
  web:
    restart: always
    build: .
    env_file: .env.production
    command: "bundle exec rails s -p 3000 -b '0.0.0.0' -e production"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - solr
  solr:
    image: solr:6.6.0
    volumes:
      - ./solr/configsets/sunspot/conf:/opt/solr/server/solr/production
      - solr:/opt/solr/server/solr/production/data
    entrypoint:
      - docker-entrypoint.sh
      - solr-precreate
      - production
      - /opt/solr/server/solr/configsets/sunspot

volumes:
  solr:

何のことはなく、volumesでホストOSのディレクトリをゲストに使わせてるだけなんだけど、これが重要だった。

この状態で docker-compose build && docker-compose up -d で立ち上げた後、solrの Core というのを作るために次のコマンドを打つ

# このコマンドは打たなくてよくなった
# docker-compose exec solr bin/solr create_core -c production

↑entrypointのセクションで不要に出来ました。

solrのwebコンソールとかにらめっこしながら、とにかく開発時にsunspotが生成する schema.xmlsolrconfig.yml をdockerのsolrに認識してもらおうとしてたらこのようになった。

現状の課題

現状だと solr/configsets/sunspot/conf/core.propertiessolr/configsets/sunspot/conf/data/ にsolrのデータが生成されてしまう。 開発環境で邪魔になるという問題もあるし、本来これらはvolumeを定義してそこに保存されて欲しい。 しかし、solrのconfig類を渡す必要もあるので、いまひとつどうすればいいか分からなかった。 ……solrについては元々あまり詳しくないので、誰か補足してくれたら凄く嬉しいです。是非コメントください。

参考

以上、調べるのに割と苦戦したのでメモでした。誰かの助けになれば幸い。