Rails + webpacker on Dockerの環境をdocker-composeで構築する
dockerは知識として入れてはいましたが、実際にdocker上で開発をしたことはなかったので、勉強がてらやってみました。そんなにハマりどころもなく、便利なので今後はこれを基本にしていくと思います。
まず前提として、今回はdocker-composeで開発環境を作るというところまでを想定していて、本番運用はスコープ外とします。細かい手順は覚えていないので、ファイルベースで進めていきます。
# docker-compose.yml version: '2' services: rails: &app_base build: context: . dockerfile: "Dockerfile.dev" command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" env_file: - "./.env.dev" volumes: - ".:/app" volumes_from: - data - bundle ports: - "3000:3000" depends_on: - db tty: true stdin_open: true webpack: <<: *app_base command: bash -c "rm -rf /app/public/packs; /app/bin/webpack-dev-server" ports: - "3035:3035" depends_on: - rails tty: false stdin_open: false bundle: image: app_rails # 開発環境による。前述のrails imageの名前を記載 volumes: - /bundle data: image: "busybox" volumes: - "/local_path:/var/lib/mysql/data" # どこでも良いのでローカル環境にsharedとしてdirectoryを用意する db: image: mysql:5.7 restart: always environment: MYSQL_USER: root MYSQL_ROOT_PASSWORD: password ports: - "3306:3306" volumes_from: - data command: --innodb-use-native-aio=0 --ignore-db-dir=data
だいたい読んで頂けばわかるかと思いますが、rails, webpack, data, dbという4つを用意しています。volumesを".:/app"
とすることで、通常の開発のように手元で好きなエディタで開発できるのが良いです。また、dbもbusyboxでサンドボックス的に気軽に用意できるので、例えば案件によって違うバージョンを使いたい、違うDBを使いたいとかでも問題なく対応できます。
# Dockerfile.dev FROM node:11.12.0 as node FROM ruby:2.6.1 ENV LANG C.UTF-8 ENV BUILD_PACKAGES="ruby-dev bash" \ DEV_PACKAGES="libxml2-dev libxslt-dev tzdata" \ RUBY_PACKAGES="ruby-json nodejs" RUN apt-get update -qq -y && \ apt-get upgrade -y && \ apt-get install -y --no-install-recommends \ build-essential \ libpq-dev \ wget \ ca-certificates \ $BUILD_PACKAGES \ $DEV_PACKAGES \ $RUBY_PACKAGES \ libfontconfig1 && \ rm -rf /var/lib/apt/lists/* 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 ENV YARN_VERSION 1.15.2 COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn COPY --from=node /usr/local/bin/node /usr/local/bin/ RUN ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \ && ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg ENV BUNDLE_JOBS=4 \ APP_DIR=/app/ \ BUNDLE_PATH=/bundle/ RUN mkdir $APP_DIR WORKDIR $APP_DIR COPY ./Gemfile $APP_DIR COPY ./Gemfile.lock $APP_DIR RUN gem install bundler RUN bundle config build.nokogiri --use-system-libraries RUN bundle install --no-deployment --quiet --path /bundle RUN yarn install --check-files COPY ./ $APP_DIR CMD [ \ "prehook", "rm /app/tmp/pids/server.pid" \ "prehook", "ruby -v", "--", \ "prehook", "bundle install -j3 --quiet --path /bundle", "--"]
Dockerfileはこんな感じです。こちらは基本的なインストール周りを行い準備しているだけという感じですね。必要に応じて変更してください。Railsの場合、ポイントとしてconfig/database.yml
をどう書くかというところで迷うかと思うのですが、こちらもdockerの記述をうまく使えばとても簡単です。
# config/database.yml default: &default adapter: mysql2 host: db pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password timeout: 5000 development: <<: *default database: app_development test: <<: *default database: app_test production: <<: *default host: <%= ENV['HOST'] %> database: app_production username: username password: <%= ENV['PASSWORD'] %>
defaultのhostがdb
になっているところに注目してください。これはdocker-compose.ymlで指定したdbを指しています。これだけでうまく連携してくれるので簡単ですよね。
基本的には以上となりあます。あとは適当にdocker-compose, dockerコマンドを組み合わせて開発をすすめましょう。例えば下記のような感じでコマンドを使えます。
$ docker-compose up $ docker-compose run rails rake db:create $ docker-compose run rails bundle exec rails db:migrate $ docker-compose exec rails bundle exec rails c $ docker-compose logs -f # see logs
以上です。