さて、前回に引き続いてDockerでのRailsの開発環境の構築。
前回:DockerでRails5.2の環境を構築する その1
https://developer-collaboration.com/2018/08/03/docker-rails5-2-1/
前回の手順で気になっていた部分として初期の立ち上げの時にイメージをあげて何度か作り直していた点です。
今回は起動時にシェルを読み込むことでプロジェクトがなければ作ったりなどを実施しています。
実施している手順は以下になります。
1. rubyのイメージを利用したDockerコンテナでrails5.2をインストールしたイメージを作成し起動シェルを導入。
2. 上記イメージとpostgresのイメージでコンテナを作成し起動。
3. 起動シェルが状態を確認し、「rails new」、「bundle install」、「rake db:create」をvolume上に実施。
構築環境の準備
どこか適当なディレクトリを作成し以下の6つのファイルを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
FROM ruby:2.5.1 ENV APP_HOME /myapp ENV BUNDLE_JOBS=4 RUN apt-get update -qq && \ apt-get install -y --no-install-recommends \ build-essential \ libpq-dev \ nodejs && \ apt-get clean RUN mkdir /docker ADD database.yml /docker/database.yml ADD boot.sh /docker/boot.sh RUN chmod 755 /docker/boot.sh RUN mkdir -p /tmp/rails_tmp && cd /tmp/rails_tmp ADD Gemfile Gemfile RUN touch Gemfile.lock RUN bundle config build.nokogiri --use-system-libraries RUN bundle install RUN rm -rf /tmp/rails_tmp WORKDIR $APP_HOME |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
version: '3' services: db: image: "postgres:10.4" environment: - "POSTGRES_USER=postgres" - "POSTGRES_PASSWORD=password" volumes: - ./work/db:/var/lib/postgresql/data ports: - "5432:5432" web: build: context: . command: bash -c "/docker/boot.sh && bundle exec rails s -p 3000 -b '0.0.0.0'" env_file: - "./.env.dev" volumes: - ./myapp:/myapp ports: - "3000:3000" depends_on: - db |
1 2 3 4 5 6 |
DATABASE_HOST=db DATABASE_PORT=5432 DATABASE_USER=postgres DATABASE_PASSWORD=password |
1 2 3 4 |
source 'https://rubygems.org' gem 'rails', '~> 5.2.0' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
default: &default adapter: postgresql encoding: unicode pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: <%= ENV.fetch('DATABASE_USER') { 'root' } %> password: <%= ENV.fetch('DATABASE_PASSWORD') { 'password' } %> host: <%= ENV.fetch('DATABASE_HOST') { 'localhost' } %> port: <%= ENV.fetch('DATABASE_PORT') { 5432 } %> development: <<: *default database: myapp_development test: <<: *default database: myapp_test production: <<: *default database: myapp_production |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#!/bin/bash cd /myapp if [ ! -e Gemfile ]; then rails new . --force --database=postgresql sed -i -e "s/# gem 'mini_racer', platforms: :ruby/gem 'mini_racer', platforms: :ruby/g" Gemfile bundle install cp -p /docker/database.yml config/database.yml fi if [ -e schema.rb ]; then rake db:migrate else rake db:create fi # pidファイルを削除 rm -f ./tmp/pids/server.pid |
シェルを切り出したりなど主に悩んだ点は以下です。
- プロジェクトの作成などはvolumeをマウントした後でないとできないので、ENTRYPOINTかCOMMANDなどイメージ作成後でないといけない。
- 「rake db:create」もDBのコンテナが上がった後に実施の必要がある。
上記は1度でも良いので複数回立ち上げたりなどでも回避できるが手順が煩雑になる。 - pidファイル削除など毎度実施したいコマンドもある。
- 実際に作り込んでいくとシェル切り出しの方が使い回しが良さそうなので、ENTRYKITなど利用せずに実施。
- 「--path vendor/bundle」などしてプロジェクト内にbundleファイルを落としてもいいが、起動やデプロイに時間がかかるのでパス指定なし。
- COMMANDを複数指定した際にアプリをlistenしているプロセスIDが「1」になるか。
コンテナの作成
起動に関しては以下のコマンドを実行します。
1 2 3 4 |
$ mkdir myapp $ docker-compose up |
2度目からは「docker-compose up」のコマンドのみで大丈夫です。
尚、「web」のコンテナ上でのプロセスの状態は以下になります。
1 2 3 4 5 |
# ps -axu USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.3 4.0 1318140 83776 ? Ssl 02:41 0:01 puma 3.12.0 (tcp://0.0.0.0:3000) [myapp] |
無事、3000でlistenしているプログラムがPID 1になりました。
実際にはこの後に「spring」を設定してみたり、「redis」も一緒に動かしちゃえだったり、諸々の自動化の設定をシェルに書いていったりと改変は大きくなりそうですが、基本的なところは実施できたかなというところです。
このブログは株式会社CoLabMixによる技術ブログです。
GCP、AWSなどでのインフラ構築・運用や、クローリング・分析・検索などを主体とした開発を行なっています。
Ruby on RailsやDjango、Pythonなどの開発依頼などお気軽にお声がけください。
開発パートナーを増やしたいという企業と積極的に繋がっていきたいです。
お問い合わせやご依頼・ご相談など