Dockerはアプリケーションを軽量なコンテナとしてパッケージ化し、どこでも動作させることができる便利なツールです。
この記事では、まだまだ初学者ではある私ですが既存のwebアプリを任意のlocal環境で動作させる為のdocker化を覚えましたので、他者様が作った既に完成しているwebアプリをDockerとDocker Composeを使用してDocker化してlocalで起動する手順を解説したいと思います。
今回は railsアプリ、またdbはPostgreSQLを使用します。
追加で必要なファイルは2つ、修正するファイルは1つ
既存webアプリのdocker化の大まかな流れ
1. Dockerfileの作成
2. docker-compose.ymlの作成
3. database.ymlファイルの一部修正
4. Dockerイメージのビルド
5. データベースのセットアップ
6. アプリケーションの起動
7. localhost:3000にアクセス
まず手順だけ先に書き、その下に各解説を書いていきます。
1. Dockerfileの作成
まず、railsアプリのルートディレクトリ(README.mdやGemfileがあるディレクトリ)にDockerfile
を作成、中身は下記の通り。
# 以下、[app_name]はご自身で用意したアプリのルートディレクトリ名に変えて記入してください
# インデントが大事なので十分注意してください
FROM ruby:3.2.2 #任意のバージョンを指定してください RUN apt-get update -qq && apt-get install -y \ build-essential \ libpq-dev \ node.js WORKDIR /app_name COPY Gemfile Gemfile.lock /app_name/ RUN gem install bundler && bundle install COPY . /rails-docker/
2. docker-compose.ymlの作成
docker-compose.yml
ファイルをアプリのルートディレクトリ(先程作ったDockerfileと同じディレクトリ)に作成し、中身は下記の通り。
# 以下、[app_name]はご自身で用意したアプリのルートディレクトリ名に変えて記入してください
# インデントが大事なので十分注意してください
version: "3" volumes: postgresql-data: services: web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' environment: - "POSTGRES_USER=postgres" - "POSTGRES_PASSWORD=postgres" tty: true stdin_open: true volumes: - .:/app_name ports: - "3000:3000" depends_on: - db db: image: postgres:12 #任意のバージョンを指定してください environment: - "POSTGRES_USER=postgres" - "POSTGRES_PASSWORD=postgres" ports: - "5432:5432" volumes: - postgresql-data:/var/lib/postgresql/data
3. database.ymlファイルの一部修正
/app_name(用意したアプリ)/config/databse.ymlの中の
一部記述(default: &defaultから下部の数行)を以下のように変更します。
default: &default adapter: postgresql encoding: unicode host: db username: postgres password: postgres port: 5432 # For details on connection pooling, see Rails configuration guide # https://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
4. Dockerイメージのビルド
Dockerfileが正しく設定されたら、次のコマンドでDockerイメージをビルドします。
$ docker-compose build
※初回はビルドもするので処理が終わるまで数分かかります。
また、途中でダウンロードが失敗しエラーが出ることもあります(私も一度なりました)が、
再度$ docker-compose build
を行うことでダウンロード含め、処理は成功します。
5. データベースのセットアップ
$ docker-compose run --rm web rails db:create
6. アプリケーションの起動
$ docker-compose up
次回以降は5.のデータベースのセットアップは必要なくこの$ docker-compose up
1行を実行するだけでアプリケーションを起動できます。
7. localhost:3000にアクセス
$ docker-compose up
後、シェルはそのままの状態(アプリケーションが起動している状態)で、http://localhost:3000
にてアプリケーションが動作しているはずですので、
http://localhost:3000
にアクセスするとwebアプリケーションとして使用開始できます。
終了方法は$ docker-compose up
を行ったシェルに戻り、cmd + c (ctrl + c)を押すと終了します。
再度起動するときはシェルで$ docker-compose up
を実行するだけ。
以上が流れです。
解説はこちら↓
Dockerfile
FROM ruby:3.2.2 #任意のrubyバージョンを選択 RUN apt-get update -qq && apt-get install -y \ build-essential \ libpq-dev \ node.js # イメージのビルド時にOSのパッケージリストを更新と下記パッケージ郡をインストール # build-essential: コンパイラやライブラリなどの開発に必要な基本的なパッケージ群 # libpq-dev: PostgreSQLデータベースを扱うためのライブラリ # node.js: JavaScriptのランタイム環境であるNode.js WORKDIR /app_name #以降のコマンドは、/app_nameディレクトリ内(アプリのルートディレクトリ内)で実行 COPY Gemfile Gemfile.lock /app_name/ # ホストのGemfileとGemfile.lockをコンテナの/app_nameディレクトリにコピー # 複数のファイルをコピーする際はapp_nameの後ろに`/`が必要 RUN gem install bundler && bundle install # 最新のbundlerをインストールした後、コピーしたGemfileとGemfile.lockをもとに必要なRubyのライブラリをインストール COPY . /rails-docker/ # ホストの現在のディレクトリ全内容をコンテナの/app_name/にコピー
docker-compose.yml
version: "3" # 使用するDocker Composeのファイル形式のバージョン(ほとんど3なのでこう書くものだと思ってオッケー) volumes: postgresql-data: # postgresql-dataという名前のボリュームを定義 services: # このComposeファイルで定義するサービス群を示します。具体的には次のインデントのwebとdb。 # この2つがそれぞれコンテナ化されて相互に利用される。 web: webという名前のサービスを定義(アプリ側) build: . # webサービスのDockerイメージを、現在のディレクトリ( . )にあるDockerfileを使用してビルド command: bundle exec rails s -p 3000 -b '0.0.0.0' # webサービスを起動する際のコマンドを指定。railsサーバーを起動、ポートは3000(railsのデフォルト) environment: - "POSTGRES_USER=postgres" - "POSTGRES_PASSWORD=postgres" # 環境変数を設定。PostgreSQLのユーザ名とパスワードを指定 tty: true # ttyを有効にします。これにより、コンテナ内でのインタラクティブな操作が可能に stdin_open: true # 標準入力をオープンします。これもインタラクティブな操作のため volumes: - .:/app_name # ホストの現在のディレクトリ( . )と、コンテナの/app_nameディレクトリをマウント(同期)する ports: - "3000:3000" # ホストの3000番ポートと、コンテナの3000番ポートを紐づけし、 # localhost:3000にアクセスした時にコンテナにアクセス depends_on: - db # webサービスはdbサービスに依存しているため、dbサービスが先に起動するように指定 # これにより、dbが起動してからrailsサーバーを起動するコマンドを行うようにする db: image: postgres:12 #任意のバージョンを指定してください environment: - "POSTGRES_USER=postgres" - "POSTGRES_PASSWORD=postgres" ports: - "5432:5432" # ホストの5432番ポートと、コンテナの5432番ポートを紐づけ。これはPostgreSQLのデフォルトのポート番号 volumes: - postgresql-data:/var/lib/postgresql/data # 先に定義したpostgresql-dataボリュームとコンテナ内のPostgreSQLのデータディレクトリ/var/lib/postgresql/dataをマウント # これにより、データベースのデータが永続化可能に
docker-composeコマンド
$ docker-compose build # Dockerfileを元にdocker imageをビルド
データベースの設定
docker-compose run --rm web rails db:create # 初回アプリ起動前にデータベースの作成が必要(コマンド`$ rails db:create`)、このコマンドをwebコンテナのrailsに対して指示するコマンドの書き方が上記になる また、--rmオプションをつけることで、コマンドが終わりコンテナからexitされたらこのコンテナが自動で削除されるように設定。
アプリケーションの起動
`docker-compose.yml`内のコマンド`bundle exec rails s -p 3000 -b '0.0.0.0'`でrails serverの起動も行っているため、 `$ docker-compose up`1行で完結するようになっている
まとめ
DockerとDocker Composeを使用してWebアプリをDocker化する方法を解説しました。この手順を参考にあなたもrailsアプリをDocker環境での動作確認をしてみてください。