今回達成すること
Dockerコンテナ上にRailsアプリを作成します。
ここまでの整理
前回までに、2つのDockerfileを作成しました。
そしてDockerfileを操作するComposeファイルを作成しました。
今回は「docker-compose」を使ってRailsアプリを作成し、初期画面をhttp://localhost:3000に表示することをゴールとします。
ブラウザにこの画面を表示する
Dockerイメージを作成する
まずはComposeファイルがある「root」ディレクトリに移動しておきましょう。
root $ # ここに移動しとく
Dockerイメージを作成するビルトコマンドを実行します。
root $ docker-compose build
...
Successfully built 98dae7be26a8
Successfully tagged udemy_demoapp_v1_front:latest
できたか確認してみましょう。
root $ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
udemy_demoapp_v1_front latest 83a00baafff6 46 seconds ago 117MB
udemy_demoapp_v1_api latest cfd72c5564fc 58 seconds ago 561MB
ruby 2.7.1-alpine 5325e6e0d2cb 5 days ago 51.7MB
node 14.4.0-alpine 3bf5a7d41d77 13 days ago 117MB
REPOSITORY
... イメージの名前。TAG
... タグ名。イメージのバージョン管理に使う。IMAGE ID
... 一意のイメージID。コマンドでイメージを指定する時などに使う。CREATED
... 作成日。
Railsアプリを作成する
続いてRailsアプリを作成します。
root $ docker-compose run --rm api rails new . -f -B -d postgresql --api
このコマンドはDockerとRailsの2つに分けて説明します。
docker-compose run <--オプション> <サービス名>
-
run
... 指定したサービスのコンテナを立ち上げ、任意のコマンドを実行する時に使います。 -
--rm
オプション ... 任意のコマンドを実行後、コンテナを自動で削除します。これは、コンテナを削除する
$ docker-compose rm
コマンドを実行するのと同じことをしています。 -
api
... Composeファイルに記述したサービス名。
上記コマンドの場合、api
サービスに対しRails newコマンドを実行しています。
rails new <ディレクトリ名> <-オプション> <--モードオプション>
-
.
... カレントディレクトリ(現在のディレクトリ)内にRailsアプリを作成する指定です。通常
rails new
の後はアプリ名兼、ディレクトリ名を指定します。ただ今回のように既にある「api」ディレクトリの中にRailsアプリを作成したい場合は、
.
ドットを指定します。カレントディレクトリと判断される場所は、
docker-compose.yml のcontext
で指定した場所となります。
docker-compose.yml
api:
build:
context: ./api # ここが rails new . のカレントディレクトリとなる
-
-f
オプション ... ファイルが存在する場合に上書きします。ここでは Gemfile を対象としています。 -
-B
オプション ... Gemをインストールするbundle installコマンドを実行しません。後でイメージを作り替えるときに実行されるため、ここでは省略しています。
-
-d <データベース名>
オプション ... 使用するデータベースを指定します。今回は、
postgresql
を指定していますが、指定がない場合はデフォルトのsqlite3
が使用されます。ちなみに
–database=postgresql
こういった書き方もできます。 -
--api
オプション ... API専用のRailsアプリケーションを作成する場合に指定するオプションです。
書き換わったGemfileを確認してみよう
コマンドを実行したことによって
確認してみましょう。
api/Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.7.1'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.1'
...
Dockerイメージを再ビルドする
Gemfileが書き換わったのでapi
サービスのDockerイメージを再ビルドします。
root $ docker-compose build api
このコマンドにより$ bundle install
も実行されます。
イメージをビルドするタイミングとは?
イメージを再ビルドするタイミングは、基本的に2つです。
-
Dockerfileを書き換えたとき
-
パッケージ管理を行うファイルを書き換えた時
Dockerfileに記載しているファイルを書き換えたとき(ここではGemfileのこと)
引用
新しいGemfileを入手したので、イメージを再度ビルドする必要があります。(これと、GemfileまたはDockerfile への変更は、再構築が必要な唯一の場合です。)
Railsアプリの起動を確認してみる
これでRailsアプリが作成できました。
ただ今のままでは動きません。
試しにapi
コンテナを起動して、ブラウザでhttp://localhost:3000にアクセスしてみてください。
root $ docker-compose up api
-
up <サービス名(任意)>
... コンテナの生成・起動を一発で行うコマンドです。サービス名の指定がない場合は、全てのサービスが起動します。
このような画面が出てこれば成功です。
DockerがRailsを起動していることが確認取れました。
確認が取れたらapi
コンテナを停止しましょう。
root $ 「Control」+「C」
Stopping udemy_demoapp_v1_api_1 ... done
依存関係として指定したdb
コンテナも一緒に起動しています。停止しましょう。
root $ docker-compose stop
Stopping udemy_demoapp_v1_db_1 ... done
stop
... コンテナを停止するコマンドです。
今のコンテナの状態を確認してみます。
StateがExit
となっていればコンテナが停止している証です。
root $ docker-compose ps -a
Name Command State Ports
-----------------------------------------------------------------------
udemy_demoapp_v1_api_1 rails server -b 0.0.0.0 Exit 1
udemy_demoapp_v1_db_1 docker-entrypoint.sh postgres Exit 0
ps
... コンテナの一覧を表示するコマンドです。-a
オプション ... 起動中、停止中関わらず、全てのコンテナを表示します。
停止の確認が取れたらコンテナを削除しましょう。
root $ docker-compose rm -f
Removing udemy_demoapp_v1_api_1 ... done
Removing udemy_demoapp_v1_db_1 ... done
rm
... 停止中のコンテナを削除するコマンドです。-f
オプション ... 「本当に削除しますか?」の確認メッセージを出さずそのまま削除します。
コンテナ削除の確認を取りましょう。
root $ docker-compose ps -a
Name Command State Ports
------------------------------
これで綺麗になりました。
コンテナは常に削除しよう
これからDocker開発を進めていく上で、コンテナは常に削除することをおすすめします。
理由として、
ps
コマンドのコンテナ一覧にどんどんコンテナリストが溜まってくる- コンテナに直接インストールしたgemやパッケージがそのまま残ってしまう
ためです。
本番環境ではDockerfileから作成されたコンテナをデプロイしますので、コンテナに直接インストールしたものは反映されません。
常に本番環境と同じ状態で開発を進めるためにも、コンテナは一度削除して再度立ち上げることを心がけましょう。
Railsのデータベース設定を行う
上記画像のエラーは、Railsのデータベースが作成されていないことで起こる接続エラーです。
そこでRailsの
api/config/database.yml
default: &default
adapter: postgresql
encoding: unicode
host: db # 追加
username: postgres # 追加
password: <%= ENV["POSTGRES_PASSWORD"] %> # 追加
...
-
host
... PostgreSQLが動いているホスト名を指定します。ここではComposeファイルの
db
サービスを指定しています。 -
username
... PostgreSQLのユーザー名を指定します。ここはデフォルトのユーザー名である
postgres
を指定します。 -
password
... PostgreSQLのアクセスに必要なパスワードです。ここは、Composeファイルで指定した
POSTGRES_PASSWORD
の環境変数と一致させます。
設定が完了したらデータベースを作成します。
root $ docker-compose run --rm api rails db:create
上手くいくとこのように表示されます。
Created database 'app_development'
Created database 'app_test'
もう一度Railsの起動を確認してみよう
データベース設定が終わったら再度Railsの起動を確認します。
root $ docker-compose up api
起動後は、ブラウザでhttp://localhost:3000/にアクセスしてみましょう。
OK!上手くいきました。
それではapi
コンテナを停止して、
root $ 「control」+「C」
コンテナの停止・削除を同時に行います。
root $ docker-compose down
削除できたか確認を取りましょう。
root $ docker-compose ps -a
# OK
Name Command State Ports
------------------------------
まとめ
今回はdocker-compose.ymlファイルを使ってコンテナ上にRailsアプリを立ち上げました。
いつでも見返せるように、この記事で出てきたDockerコマンドを整理しておきますね。
# コンテナ内で任意のコマンドを実行する
$ docker-compose run <サービス名> <任意のコマンド>
# Dockerイメージを作成する
$ docker-compose build
# 複数のコンテナの生成し起動する
$ docker-compose up
# コンテナを停止する
$ docker-compose stop
# 停止中のコンテナを削除する
$ docker-compose rm -f
# コンテナの停止・削除を一度に行う
$ docker-compose down
# コンテナの一覧を表示する
$ docker-compose ps -a
次回予告!!番長
次回はNuxt.jsのアプリを作成して、ブラウザ上にNuxtの初期画面を表示させます。
お楽しみに!!
お時間ある方は、どうぞコラムへお進みください。↓
【コラム】PostgreSQLのパスワードを変更したい場合
PostgreSQLのデフォルトパスワードは、Composeファイルで指定した環境変数のPOSTGRES_PASSWORD
の値となります。
docker-compose.yml
services:
db:
image: postgres:12.3-alpine
environment:
POSTGRES_PASSWORD: $POSTGRES_PASSWORD # .envファイルで指定
この値はデータベースが初期化されるタイミングで設定されるため、以後この環境変数を変えてもコンテナ内のPostgreSQLのパスワードを変更することができません。
パスワードを変えるには、イメージを作り直すか、コンテナ内で直接変更を行う必要があります。
コンテナ内でパスワードを変更する
まず、db
コンテナを立ち上げます。
root $ docker-compose up -d db
-d
オプション ... バックグラウンドでコンテナを実行する。
次に、PostgreSQLに入ります。
root $ docker-compose exec -u postgres db psql
-
-u <ユーザー名>
... ユーザーを指定するオプションです。特に変更がなければデフォルトのユーザー名
postgres
を指定します。
中に入ったら変更したいパスワードをセットします。
postgres=# ALTER ROLE postgres WITH PASSWORD 'password';
確認しましょう。暗号化されたパスワードが表示されます。
postgres=# SELECT * FROM pg_shadow;
usename | usesysid | passwd |
postgres | 10 |md532e12f215ba27cb750c9e093ce4b5127 |
PostgreSQLから抜けます。
postgres=# \q
パスワード変更後の対応
Composeファイルを新しいパスワードに変更します。
docker-compose.yml
services:
db:
image: postgres:12.3-alpine
environment:
POSTGRES_PASSWORD: <新たなパスワード>
Raisに直接パスワードを書き込んでいる場合は
api/config/database.yml
default: &default
password: <新たなパスワード>
以上で完了です。
修正情報
-
2020年12月10日
目次「#イメージをビルドするタイミングとは?」の2つ目を「パッケージ管理を行うファイルを書き換えた時」に書き換えました。言い回しが曖昧であったため、より具体的な言い方に変えました。