RailsアプリにDockerを導入する手順
Rails6+Webpacker+Postgresql 既存のRailsアプリをDocker化する手順について綴っていこうと思います。誤っている点や改善点などありましたらご指摘いただけると幸いです。
前提条件
~$ gem info rails rails (7.0.4.3, 7.0.4, 6.1.7.3, 6.1.5, 6.0.6.1, 6.0.3) #今回は6.1.5を使用します ~$ruby -v ruby 3.1.2 ~$ docker -v Docker version 20.10.16 ~$ docker-compose -v docker-compose version 1.29.2 ~$ docker login Authenticating with existing credentials... Login Succeeded
事前準備
手順
rails _6.1.5_ new <app名 or . > --webpack
でrails アプリケーションを作成する。(rails new .の場合カレントディレクトリをアプリ名としてrailsアプリが作成されます。)rails generate scaffold task title:string
で簡単なタスクアプリを作成する。rails db:migrate
でdb/migrate以下のファイルの変更をdbに反映するconfig/routes.rb
を編集する(rootにアクセスした際にtasksコントローラのindexアクションを用いるように記述する)
Rails.application.routes.draw do resources :tasks # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html root 'tasks#index' # <=この記述を追加 end
export NODE_OPTIONS=--openssl-legacy-provider
をterminalで実行(openSSL互換エラーを防ぐための環境変数を追加)- 1つの目端末(terminalのタブ)で
bin/webpacker-dev-server
を実行(コンパイル用のサーバー) - 2つ目の端末(terminalのタブ)で'rails server'を実行(アプリケーションサーバー)
事前準備が終わった際のrepository構成は以下のgithubページから確認できます。
動作確認と簡単な解説 www.loom.com
Railsアプリのdocker化
手順
- Dockerfile作成
app名/Dockerfileを以下の内容で作成します。
# nodeイメージに対してasでエイリアスをつけます。エイリアスはCOPYコマンド等で使用することが可能となります # このDockerfileではrubyのイメージに対して命令を記載しているため、FROM の定義順番もnode,rubyである必要があります # 下記のnode全体は最終的なイメージには保存されません FROM node:16.20.0-bullseye as node FROM ruby:3.1.2 # Install Node.js and Yarn、nodeイメージがcreateされstartしてbashで入った際に以下のフォルダーが確認できた # /opt/yarn-* , /usr/local/bin/node , /usr/local/lib/node_modules/ # 以下の記述はnodeコンテナで生成されたフォルダーをrubyコンテナにコピーしている # ln -fs では左のソースを右のターゲット名で呼び出せるようにシンボリックリンクを作成している COPY --from=node /opt/yarn-* /opt/yarn COPY --from=node /usr/local/bin/node /usr/local/bin/ COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/ RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \ && ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx \ && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \ && ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg # apt-getで必要なパッケージをインストールします # -y オプションはyes/noのダイアログに対してyesと答えますという意味です、 RUN apt-get update && apt-get install -y \ build-essential \ libpq-dev \ postgresql-client # WORKDIR 以降の命令は、/myappで実行されます myapp$ WORKDIR /myapp # build contextの中のファイルをdockerイメージに組み込んでコンテナが起動した際にコンテナのファイルシステムの/myapp/Gemfileに配置をしている # ADDもCOPYもbuild contextファイルをdockerイメージに組み込んでコンテナのファイルシステムに配置している # tarの圧縮ファイルをコピーして解凍したい時はADD、単純にファイルやフォルダをコピーする場合はCOPY ADD Gemfile /myapp/Gemfile ADD Gemfile.lock /myapp/Gemfile.lock COPY package.json /myapp/package.json COPY yarn.lock /myapp/yarn.lock # bundle install -> Gemfile.lockの内容をもとにインストール # yarn install -> yarn.lockの内容をもとにインストール RUN bundle install && yarn install # build contextに渡してディレクトリをコンテナファイルシステムの/myappに配置する ADD . /myapp
- docker-compose.yml作成
app名/docker-compose.ymlを以下の内容で作成します。
version: '3' # 名前つきボリュームを定義します # ボリュームはデータを永続化するための機能 # コンテナ上で生成されたファイルはコンテナのライフサイクルと共に消えてしまう。ボリュームはコンテナのライフサイクルとは独立してファイルの管理を行います。 volumes: db-data: driver: local #driverはAmazon EBS のような外部のストレージ・システムと統合した環境に Docker をデプロイできるようにする際に詳細に設定する bundle: driver: local services: web: # Dockerfileを使ってbuildします。build contextにはdocker-composeが実行された際のカレントディレクトリを渡します build: . volumes: # ホスト上のカレントディレクトリ(.)の内容をコンテナ上の/myappに割り当てます(バインドマウント) - '.:/myapp' # コンテナ上のgemインストール先(/usr/local/bundle)をbuldleという名前でボリュームに割り当てますs - bundle:/usr/local/bundle # コンテナ稼働時に実行されるコマンドです # RUN -> volumes(マウント) ->CMD command: /bin/sh -c "rm -f tmp/pids/server.pid && rails db:create && rails db:migrate && rails s -p 3000 -b '0.0.0.0'" # 'ホスト側:コンテナ側'のポートを3000でマッピングしています ports: - '3000:3000' environment: # DB_PASSWORDに.envのDB_PASSWORD のバリューを格納してwebホスト上の環境変数として使用できるようにしています - 'DB_PASSWORD=${DB_PASSWORD}' # WEBPACKER_DEV_SERVER_HOSTでdev-serverの接続先を指定しています - 'WEBPACKER_DEV_SERVER_HOST=webpacker' # 擬似端末(キーボードによる入力)をコンテナに結びつけます(docker run -itの-tと同じ意味) tty: true # 標準入出力とエラー出力をコンテナに結びつけます(docker run -itの-iと同じ意味) stdin_open: true # dbコンテナが起動してからwebを起動します depends_on: - db webpacker: build: . volumes: - .:/myapp - bundle:/usr/local/bundle command: ./bin/webpack-dev-server environment: WEBPACKER_DEV_SERVER_HOST: 0.0.0.0 #webpackerホスト名を指している ports: - "3035:3035" db: image: postgres:12 volumes: - 'db-data:/var/lib/postgresql/data' environment: - 'POSTGRES_USER=${POSTGRES_USER}' - 'POSTGRES_PASSWORD=${POSTGRES_PASSWORD}'
- .env作成
app名/.envを以下の内容で作成します。
DB_PASSWORD=postgres POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres
- .gitignore修正
app名/.gitignoreに以下の内容を追記します。
# .gitignoreファイルの最下部 .env
- .dockerignore作成
app名/.dockerignoreを以下の内容で作成します。
.env .git .gitignore **/.gitkeep **/Dockerfile docker-compose.yml public/packs log/* tmp/* vendor/bundle node_modules
- database.yml修正
app名/config/database.ymlを以下の内容に修正します。
default: &default adapter: postgresql encoding: unicode # docker-composeで割り当てられたhostname(db)に変更 host: db user: postgres port: 5432 password: <%= ENV.fetch("DB_PASSWORD") %> pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> development: <<: *default database: myapp_development test: <<: *default database: myapp_test production: <<: *default database: myapp_production
- Gemfile修正
app名/Gemfileにいかのgemを追記 && bundle install
(bundle updateの際にpostgresqlが入ってないとエラーが発生するので、その際はbrew install postgresql
の後にbundle install
を実行してください)
以下の記述をGemfileに追加したらbundle install
を実行してください。
gem 'pg', '~> 1.1'
- webpacker.yml修正
app名/config/webpacker.ymlのdevelopmentを以下のように修正してください
development: <<: *default compile: true # Reference: https://webpack.js.org/configuration/dev-server/ dev_server: https: false host: localhost #docker-compose.ymlのenvironment: WEBPACKER_DEV_SERVER_HOST: host名 で上書きされる。 port: 3035 public: localhost:3035 #ここでのlocalhostはdev_server: host: で指定したホスト名を指す hmr: true # Inline should be set to true if using HMR inline: true overlay: true compress: true disable_host_check: true use_local_ip: false quiet: false pretty: false headers: 'Access-Control-Allow-Origin': '*' watch_options: ignored: '**/node_modules/**'
Railsアプリのdocker化が終わった際のrepository構成は以下のgithubページから確認できます。
動作確認と簡単な説明
docker-compose up
points
- RUN -> volumes -> CMD
- docker-composeはアプリに対して1つのネットワークを作成します。サービス用の各コンテナはデフォルトのネットワークにservice:セクションで指定されたホスト名で接続し、そのネットワーク上でコンテナは相互に接続可能な状態になります
- volumesを共有する設定にしないと、Railsが起動しているコンテナで新しいgemをインストールした際に、Webpackerのコンテナでgemがインストールされていないというエラーが発生します。そのエラーを回避するために、webpackerとrailsの両方のサービスでvolumesを指定して共有しています
めっちゃ参考にしたサイト
参考にしたサイト
- Rails6Dockerize
- Library | Loom
- gitをpushする際にエラー発生(error: src refspec ブランチ名 does not match any) - Qiita
- git push -u オプションで”上流ブランチ”を設定 | WWWクリエイターズ
- デフォルトブランチを変更する - GitHub Docs
- ruby on rails - Can't find the 'libpq-fe.h header when trying to install pg gem - Stack Overflow
- docker-compose links - Google 検索
- Webpacker の概要 - Railsガイド
- 【Ruby・Rails】 バージョン切り替えコマンド | Almonta Blog
- ruby Tags | Docker Hub
- webpacker.yml docker-compose host public - Google 検索
- Linuxコマンド【 hostname 】マシンのホスト名を表示・設定 - Linux入門 - Webkaru
- Compose ファイル version 2 リファレンス — Docker-docs-ja 20.10 ドキュメント
- Compose の ネットワーク機能(networking) — Docker-docs-ja 20.10 ドキュメント
- docker network inspect | Docker Documentation
- ダイアログ - Google 検索
- Image Layer Details - node:16.20.0-bullseye | Docker Hub
- webpacker.yml dev_server: public option meaning - Google 検索
- network - 入門 Docker
- 週刊Railsウォッチ: Webpackerが公式に引退宣言、『Everyday Rails』日本語版がRails 7に対応ほか(20220124前編)|TechRacho by BPS株式会社
- HTML Standard
- docker-composeでwebpack-dev-serverを使う
- Webpacker in production (Webpacker can't find application in...) · Issue #2071 · rails/webpacker
- Railsアプリでwebpackerを使う場合はbin/webpack-dev-serverコマンド実行しておかないと生産性落ちるぞ! - カクカクしかじか
- 既存のRailsアプリにDockerを導入する手順 - Qiita
- DockerでRails+Webpackerの開発環境を構築するテンプレート - Qiita
- 既存の開発環境をDocker化する手順 Rails6+Webpacker+Postgresql+Sidekiq - 行動すれば次の現実
- Railsで使っているgemを一部またはすべてupdateする | vdeep
- ruby - Official Image | Docker Hub
- docker network inspect — Docker-docs-ja 20.10 ドキュメント
- 米国AI開発者がゼロから教えるDocker講座 | Udemy
- Compose の ネットワーク機能(networking) — Docker-docs-ja 20.10 ドキュメント
- Node.js のビルドツール「esbuild」について!
- bundle install パッケージはどこに保存される? - Google 検索
- Docker(Docker compose)でRails6.1 + Webpacker + MySQL構成の環境構築をする
- [Web フロントエンド] esbuild が爆速すぎて webpack / Rollup にはもう戻れない - 株式会社カブク | 株式会社カブク
- Compose の ネットワーク機能(networking) — Docker-docs-ja 20.10 ドキュメント
- 【Rails】Webpackerの基本情報と実装方法 - AUTOVICE | 坂井光太郎のポートフォリオサイト
- Webpacker — Ruby on Rails Guides
- webpacker/webpacker.yml at master · rails/webpacker
- DevServer | webpack
- Awesome webpack | webpack
- rails ライブラリの保存場所
- chatgpt code渡す - Google 検索
- .dockerignore Gemfile.lock - Google 検索
- dockerfile ruby version - Google 検索
- localhost
- bundle install と bundle updateの違いについて - Qiita
- gemfileにコマンドでgemをインストールする方法 - Google 検索
- 【Ruby初学者向け】Gemfileとは?ライブラリ関連の基礎知識をまとめてご紹介! | MillionTech
- 理解必須!gemsのインストール方法とインストール場所 | 侍エンジニアブログ
- 新しいタブ
- Rails6Dockerize
- 20代若手エンジニアに伝えたい「圧倒的に成長する秘訣」 - Qiita
- railsアプリをdocker化する
- バインド マウント(bind mount) の使用 — Docker-docs-ja 20.10 ドキュメント
- gitmojiの絵文字ってどれを使えばいいの? | cloud.config Tech Blog
- GitHubのコミットメッセージに絵文字を入れて開発効率をあげる - Qiita
- emoji-cheat-sheet/README.md at master · ikatyang/emoji-cheat-sheet
自己紹介
23歳 | flutter, AWS 少し触ってました | 筋トレ・ランニング・散歩・サウナ・読書・スプラが好き。 2023/4/18~ Happiness chainで勉強中 twitter フォローしてくれると喜ぶかもしれない。