DockerでRuby on Railsを始めよう



Dockerは、アプリケーションとその環境を分離し、異なる環境(dev、test、beta、prodなど)間の状態の配布と複製を容易にするという素晴らしい仕事をしています。 その使用により、「すべてが私のマシンで動作する」という問題を取り除くことができ、アプリケーションが成長するにつれて簡単にスケーリングできます。







Dockerは、アプリケーションに多くの依存関係がある場合、またはライブラリと構成ツールの特定のバージョンを使用する必要がある場合に特に優れています。







この記事では、単純なRailsアプリケーションを取り上げ、Dockerコンテナーで使用できるように準備します(「dockerize」)。







必要なコンポーネント



このアプリケーションはRails 5で作成されます。 データベースPostgreSQLを使用します。 別のDBMSに接続する場合は、いくつかのファイルを修正する必要があります。







事前定義されたテンプレートを使用して、 Dockerfile



config/database.yml



を使用して構成されたアプリケーションを作成できconfig/database.yml









 $ rails new --database=postgresql --skip-bundle --template=https://gist.githubusercontent.com/cblunt/1d3b0c1829875e3889d50c27eb233ebe/raw/01456b8ad4e0da20389b0b91dfec8b272a14a635/rails-docker-pg-template.rb my-app $ cd my-app
      
      





データベース構成



データベースパラメータを設定するには、環境変数を使用します。 PostgreSQLでコンテナに接続するために、後で必要になります。







config/database.yml



設定ファイルを編集します







上記のテンプレートを使用した場合、ファイルを編集する必要はありません。







環境変数をconfig/database.yml



追加しconfig/database.yml









 # config/database.yml default: &default adapter: postgresql encoding: unicode pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: db username: <%= ENV.fetch('POSTGRES_USER') %> password: <%= ENV.fetch('POSTGRES_PASSWORD') %> development: <<: *default database: my-app_development test: <<: *default database: my-app_test production: <<: *default database: my-app_production
      
      





Dockerfileを作成する



アプリの準備ができました。Dockerの時間です。 Dockerfile



作成することから始めましょう。 これは、アプリケーションの画像を作成するための指示を含む単純なテキストファイルです。 依存関係の設定、デフォルトの環境変数の設定、コードのコンテナへのコピーなどに使用されます。







ディスク容量を節約するために、基本的なalpine-linux Rubyイメージを使用することを好みます。 Alpine linuxは、コンテナ使用に最適な小さなLinuxディストリビューションです。 基本的なruby:alpine



画像はDockerで利用できます。これを使用します。







Dockerfile



、アプリケーションのルートディレクトリに配置する必要がある単純なDockerfile



を作成します。







上記のテンプレートを使用した場合、ファイルを編集する必要はありません。







 # /path/to/app/Dockerfile FROM ruby:2.3-alpine #    RUN apk add --update tzdata && \ cp /usr/share/zoneinfo/Europe/London /etc/localtime && \ echo "Europe/London" > /etc/timezone #    runtime-  RUN apk add --update --virtual runtime-deps postgresql-client nodejs libffi-dev readline sqlite #      WORKDIR /tmp ADD Gemfile* ./ RUN apk add --virtual build-deps build-base openssl-dev postgresql-dev libc-dev linux-headers libxml2-dev libxslt-dev readline-dev && \ bundle install --jobs=2 && \ apk del build-deps #      ENV APP_HOME /app COPY . $APP_HOME WORKDIR $APP_HOME #     production ENV RAILS_ENV=production \ RACK_ENV=production #   3000 EXPOSE 3000 #     puma CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
      
      





PostgreSQLを使用したくない場合はどうすればよいですか?







別のDBMS(たとえば、MySQL)を使用する場合、適切なパッケージをインストールするには、Dockerfileを変更する必要があります。







次のDockerコマンドを使用して、必要なパッケージを検索できます。







 $ docker run --rm -it ruby:2.3-alpine apk search --update mysql | sort ... mariadb-client-libs-10.1.22-r0 mariadb-dev-10.1.22-r0 mariadb-libs-10.1.22-r0 mysql-10.1.22-r0 mysql-bench-10.1.22-r0 ...
      
      





Dockerfileの準備ができたので、アプリケーションのDockerイメージの構築を開始します。







画像をまとめる







 $ docker build . -t my-app
      
      





画像の準備ができたら、開始できます! 次のコマンドでコンテナを実行します。







 $ docker run --rm -it --env RAILS_ENV=development --env POSTGRES_USER=postgres --env POSTGRES_PASSWORD=superSecret123 --publish 3000:3000 --volume ${PWD}:/app my-app
      
      





docker run



いくつかの引数を渡しました。









データベースコンテナーの起動



アプリケーションを含むコンテナは起動しましたが、残念ながらlocalhost:3000リンクを開こうとするとエラーになります。







 could not translate host name “db” to address: Name does not resolve
      
      





アプリケーションで使用できるPostgreSQLサーバーはまだありません。 PostgreSQLでDockerコンテナを実行して修正します。










ヒント。 Dockerでは、1つのコンテナーが1つの機能のみを実行する必要があることを忘れないでください。







この場合、2つのコンテナがあります。1つはアプリケーション用で、もう1つはデータベース用です(PostgreSQL)。










PostgreSQLで新しいコンテナーを起動する







アプリケーションでコンテナを停止(および削除)するには、Ctrl + Cを押して、PostgreSQLで新しいコンテナを開始します。







 $ docker run -d -it --env POSTGRES_PASSWORD=superSecret123 --env DB_NAME=my-app_development --name mydbcontainer postgres:9.6
      
      





-d



フラグは、コンテナをターミナルから切断し、バックグラウンドで動作できるようにするために必要です。 mydbcontainer



を呼び出し、この名前がさらに必要になります。







シングルタスクコンテナの使用







Dockerコンテナは1回の使用を目的としています。1つのタスクの性質により、タスクが完了するとすぐに停止され、削除される可能性があります。







railsコマンド(例: bin/rails db:setup



)などの1回限りのタスクに最適です。







mydbcontainerでデータベースを構成するために、このコマンドを実行します。







rails db:migrate



実行rails db:migrate



コンテナを使用したタスクのrails db:migrate









アプリケーションでコンテナのコピーを開始するには、次のコマンドを実行します。 次に、 bin/rails db:setup



コンテナでbin/rails db:setup



し、オフにします。







注意:データベースに接続するには環境変数を設定する必要があります(以前に編集したconfig/database.yml



挿入されconfig/database.yml



)。







--link



オプションを使用すると、 db



ホスト名を使用して、PostgreSQL( mydbcontainer



)でコンテナーに接続できます。







 $ docker run --rm --env RAILS_ENV=development --env POSTGRES_USER=postgres --env POSTGRES_PASSWORD=superSecret123 --link mydbcontainer:db --volume ${PWD}:/app my-app bin/rails db:create db:migrate
      
      





--rm



フラグは、完了後にコンテナを削除します。







mydbcontainer



コンテナでこのコマンドを実行すると、必要なアプリケーション用にmydbcontainer



が構成されます。 最後に実行できます!







アプリケーションの起動







アプリケーションの画像に基づいて別のコンテナを起動しましょう。 コマンドのいくつかの追加オプションに注意してください。







 $ docker run --rm -it --env RAILS_ENV=development --env POSTGRES_USER=postgres --env POSTGRES_PASSWORD=superSecret123 --publish 3000:3000 --volume ${PWD}:/app --link mydbcontainer:db my-app => Puma starting in single mode... => * Version 3.8.2 (ruby 2.4.1-p111), codename: Sassy Salamander => * Min threads: 5, max threads: 5 => * Environment: development => * Listening on tcp://0.0.0.0:3000 => Use Ctrl-C to stop
      
      





ブラウザでlocalhost:3000



ページを開きます。Dockerの下からアプリケーションが完全に動作していることがわかります。







次のステップ



Dockerは非常に便利な開発者ツールです。 時間が経つにつれて、アプリケーションのすべてのコンポーネント(DB、redis、sidekiq、cronワークフローなど)をそこに転送できます。







次のステップは、 Docker Composeを使用することです。DockerComposeは、コンテナーとコンテナーの相互作用を記述するように設計されています。







参照:







  1. オリジナル: Rails on Docker:DockerとRuby on Railsの入門



All Articles