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
いくつかの引数を渡しました。
-
-it
実際、これらはシェルを使用してコンテナと対話することを可能にする2つの引数です(たとえば、キーボードショートカットCtrl + Cを渡すため)。 -
--env
コンテナに環境変数を渡すことができます。 ここでは、データベース接続パラメーターの設定に使用されます。 -
--rm
作業が終了した後(たとえば、Ctrl + Cを押した後)、コンテナーを削除するようにドッカーに指示します。 -
--publish
コンテナーのポート3000をホストのポート3000に--publish
します。 したがって、ホスト上で直接実行されているかのようにサービスに接続できます(たとえば、http://localhost:3000
)。 -
--volume
現在のホストディレクトリをコンテナにマウントするように--volume
指示します。 したがって、ホスト上のコードを編集する機会が得られますが、同時にコンテナーで使用可能になります。 これがないと、コードを変更するたびにコンテナを再作成する必要があります。
データベースコンテナーの起動
アプリケーションを含むコンテナは起動しましたが、残念ながら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は、コンテナーとコンテナーの相互作用を記述するように設計されています。
参照: