【5】GCP(GCE)でRailsアプリを外部IPアドレス+3000番ポートで動かしてみる(環境変数COMPOSE_FILE、GCE+Docker+Rails+Puma+PostgreSQL)
- 1. 公式サイト
- 2. 目標
- 3. 注意点
- 4. 参考サイト様
- 5. 環境変数 COMPOSE_FILE を GCE に設定して複数ある環境用の docker-compose.yml を読み込めるようにする
- 6. 3000番ポートを開ける
- 7. Docker Compose コマンドを実行して Rails アプリが動くのを確認する
- 8. 関連リンク
これはHerokuからGCP無料枠にRailsアプリを引越ししたときにやったことシリーズの【4】の続きです。
GCE に 作成した VM インスタンス上で Rails アプリを動かしてみるところのメモです。
http://localhost:3000/ でテストしていたものをそのまま GCE に持っていって動かすようなことをします。
1. 公式サイト
- Compose CLI environment variables | Docker Documentation
- Reference documentation | Docker Documentation
- Overview of Docker Compose | Docker Documentation
- ファイアウォール ルールの概要 | VPC | Google Cloud
2. 目標
- 環境変数 COMPOSE_FILE を GCE に設定して複数ある環境用の docker-compose.yml を読み込めるようにする
- 3000 番ポートを開ける
- Docker Compose コマンドを実行して Rails アプリが動くのを確認する
3. 注意点
Docker は勉強中ですので、Dockerfile や docker-compose.yml などはとりあえず動くことを確認するもの程度に考えていただければと思います。
作業対象である Rails アプリ「ポケット糖質量」のデータは csv ファイルから投入すれば出来上がり、しかも ReadOnly なデータです。
ほとんどソースコードの一部のようなものなので、DB をコンテナの外に設定していません。
コンテナを消せば DB もすべて消えてしまいます。
アプリの仕様によりこのような環境になっておりますので、参考にする時はご注意ください。
4. 参考サイト様
本当に参考になりました。ありがとうございます!
5. 環境変数 COMPOSE_FILE を GCE に設定して複数ある環境用の docker-compose.yml を読み込めるようにする
参考サイト様によると、
環境ごとに別名で作ってある docker-compose.yml を-f
オプション無しで使う方法として環境変数 COMPOSE_FILE
を設定すればよいということですので、設定してみたいと思います。
例として次の 2 つの環境用のファイルを用意します。
stage | ファイル名 |
---|---|
development | docker-compose.development.yml |
production | docker-compose.production.yml |
なお docker-compose.yml を用意しておいて共通の処理を書いておき、各環境用ファイルは差分を書いておくことで AND 合体されるというやり方もできるようです。
5.1. コマンドで環境変数 COMPOSE_FILE を設定する(一時的)
export
コマンドを使ってファイル名を COMPOSE_FILE 変数に入れます。
2 行目は COMPOSE_FILE 変数の中身を表示しています。
この方法はログアウトしてログインし直すと COMPOSE_FILE 変数自体消えてしまいます。
$export COMPOSE_FILE=docker-compose.development.yml $env | grep COMPOSE_FILE
5.2. bashrc に環境変数 COMPOSE_FILE を設定する(永続的)
.bashrc を編集して環境変数 COMPOSE_FILE を設定します。
ログアウトしても COMPOSE_FILE 変数の設定はそのままです。
$nano ~/.bashrc
エディタを起動したら次の例のように書き加えます。
# docker-composeのデフォルトComposeファイルを本番用に設定 export COMPOSE_FILE=docker-compose.production.yml
保存後、次のように実行します。
$source ~/.bashrc
これでいつでも$env | grep COMPOSE_FILE
を実行すると設定したファイル名が表示されると思います。
6. 3000番ポートを開ける
GCE のインスタンスのファイアウォールルールを設定して、Rails のデフォルトポート番号である 3000 番のポートを開ける処理を行います。
ポートを開ける処理はこのシリーズ記事の
【2】GCP(GCE)で無料の VM インスタンスを作る(Always Free 無料枠、外部 IP アドレス取得、SSH 接続、22 番ポート対応)
でも記述しております。
6.1. ファイアウォールルールの作成
ナビゲーションメニューから「ネットワーク詳細の表示」を選択します。
「ファイアウォールルール」→「ファイアウォールルールを作成」をクリックします。
次の項目を設定します。
入力項目 | 内容 |
---|---|
名前 | デフォルトのルールにならって、 allow-3000 (3000 はポート番号)にするとよい |
ターゲットタグ | デフォルトのルールにならって、 allow3000-server にするとよい |
ソース IP の範囲 | 0.0.0.0/0 |
プロトコルとポート | 指定したプロトコルとポートをクリックし tcp のところに 3000 を入力する |
入力し終えたら「保存」を押して追加されたのを確認します。 ここで入力したターゲットタグをインスタンスのネットワークタグに追加します。
「VM インスタンスの詳細」→「編集」画面でターゲットタグを追加します。
GCE 側の設定はこれでできました。
7. Docker Compose コマンドを実行して Rails アプリが動くのを確認する
このエントリの題名に「GCE+Docker+Rails+Puma+PostgreSQL」と書いてありますが、GCE と Docker 以外はローカルで Rails5 でrails new
した時の構成とほとんど同じです。
DB が PostgreSQL になってるところぐらいが違うでしょうか。
http://localhost:3000/ でテストしていたものをそのまま GCE に持っていって動かすようなイメージで動作確認してみたいと思います。
前提としてアプリのソースコードが入ったプロジェクトディレクトリは VM 上にコピー済みとします。
環境変数 COMPOSE_FILEはdevelopmentをセットしておきます。
7.1. Dockerfile
Dockerfile は必死でググってこんな感じにしました。内容の説明は割愛させていただきます。
FROM ruby:2.5.3-alpine3.8 LABEL maintainer="My Name" Name=pocket_carbo Version=0.0.1 ENV LANG C.UTF-8 ENV APP_PATH /usr/src/app WORKDIR $APP_PATH COPY Gemfile $APP_PATH COPY Gemfile.lock $APP_PATH ENV RUNTIME_PACKAGES="libxml2-dev libxslt-dev libstdc++ bash tzdata postgresql-dev postgresql-client nodejs ca-certificates"\ DEV_PACKAGES="build-base" RUN set -x && \ apk add --update --no-cache $RUNTIME_PACKAGES &&\ apk add --update\ --virtual build-dependencies\ --no-cache\ $DEV_PACKAGES &&\ gem install bundler --no-document &&\ bundle config build.nokogiri --use-system-libraries &&\ bundle install &&\ apk del build-dependencies && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \ rm -rf /var/cache/apk/* COPY . APP_PATH EXPOSE 3000
7.2. docker-compose.yml
この時点での docker-compose.development.yml ファイルはこんな感じです。
version: '3' services: db: image: postgres:11.1-alpine ports: - '5432' volumes: - db-data:/var/lib/postgresql/data web: build: . command: bash -c "rm -f ./tmp/pids/server.pid; bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/usr/src/app - bundle-data:/bundle environment: RAILS_ENV: development ports: - "3000:3000" depends_on: - db volumes: bundle-data: db-data:
7.3. /config/database.yml
この時点での/config/database.yml はこんな感じです。
staging は結局環境を作らなかったんですが、定義だけしてあります。
DB が外部ではないのでコンテナを削除するとデータも全てなくなります。
default: &default adapter: postgresql encoding: utf8 # For details on connection pooling, see rails configuration guide # http://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: db username: postgres password: development: <<: *default database: db/pocket_carbo_development test: <<: *default database: db/pocket_carbo_test staging: <<: *default database: db/pocket_carbo_staging production: <<: *default database: db/pocket_carbo_production
7.4. docker-compose コマンドでビルド&起動
これらのコマンドを実行していきます。
自分が実行する時はスクリプトファイルを実行する形にしてますが、あまりイケてないですね。
私のアプリでは初期データ投入が必要なのでrails db:seed
しています。
#!/usr/bin/env bash docker-compose build docker-compose run --rm web bin/rails db:create docker-compose run --rm web bin/rails db:migrate docker-compose run --rm web bin/rails assets:precompile docker-compose run --rm web bin/rails db:seed docker-compose up -d
うまくいけばhttp://[外部IPアドレス]:3000
でアプリ画面が表示されます。
今回は以上です。
このシリーズでは今後独自ドメインで表示、SSL対応をするのでdocker-compose.ymlは変わっていきます。
次回は今回動かしたアプリをhttps+独自ドメインでアクセス出来るようにするための下準備として、テスト用の独自ドメインを取得してDNSサーバーの設定をして動かしてみます。
8. 関連リンク
- 【1】HerokuからGCP無料枠にRailsアプリを引越ししたときにやったこと(GCE+Docker+Rails+Puma+PostgreSQL+Nginx+Let's Encrypt)
- 【2】GCP(GCE)で無料のVMインスタンスを作る(Always Free無料枠、外部IPアドレス取得、SSH接続、22番ポート対応)
- 【3】GCEのVMインスタンスにDockerとDocker Composeをインストールする。他設定(スワップ領域追加、タイムゾーン設定)
- 【4】GCP(GCE)のVMインスタンスにファイルを転送する(Cyberduck, scpコマンド)
- 【5】GCP(GCE)でRailsアプリを外部IPアドレス+3000番ポートで動かしてみる(環境変数COMPOSE_FILE、GCE+Docker+Rails+Puma+PostgreSQL)
- 【6】DNSテスト用に無料の独自ドメインを取得してGoogle Cloud DNSでネームサーバの設定をする(GCE,freenom,http+独自ドメイン+ポート3000でアクセスする)
- 【7】SteveLTN/HTTPS-PORTALを使ってLet's Encryptで全自動SSL対応を行う(GCP(GCE),Rails,Nginxリバースプロキシ,Docker)