前回、ローカル環境で開発中のアプリケーションをローカルのDockerに移行して動かしてみました。
今回は、TravisCIというCICDツールを使ってテストを行い、Herokuにデプロイします。
参考
前回はローカルで開発中のアプリをローカルのDocker環境に移行して動かしてみました。
https://qiita.com/igat/items/9292ccae9f413170edda
全体構成
Heroku ... ④Dockerごとアプリをデプロイして公開する
^ ・Container2: Web(Ruby on Rails)
| ・HerokuPostgresql
TravisCI ... ③対象のアプリケーションがGithubにpushされるとテストを自動実行する。
^
|
Github ... ②ローカルPCからDockerを含むアプリケーションのコードがpushされる
^
|
ローカルPC ... ①Docker上でアプリケーションが動く
・Container1: DB(postgresql)
・Container2: Web(Ruby on Rails)
Dockerfile作成
Dockerfileを作成します。
ローカルで使うDBをMySQLからコンテナ上のpostgresqlに移行するため、前回作成したものを書き換えています。
・コメントアウト部分が、MySQL環境でのコードになります。
・Travisでrubyのバージョンが不整合となったため、バージョンを変更しました。
## For MySQL running on host Environment.
# FROM ruby:2.5.1
# RUN apt-get update
# RUN apt-get install -y mysql-client nodejs vim --no-install-recommends
# RUN rm -rf /var/lib/apt/lists/*
# RUN mkdir /myproject
# WORKDIR /myproject
# ADD Gemfile /myproject/Gemfile
# ADD Gemfile.lock /myproject/Gemfile.lock
# RUN gem install bundler
# ADD . /myproject
# RUN rm /myproject/Gemfile.lock
# RUN bundle install
## For Postgresql running on container environment
FROM ruby:2.5.3
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
vim \
postgresql-client \
yarn
RUN rm -rf /var/lib/apt/lists/*
ENV APP_HOME /myproject
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
COPY Gemfile $APP_HOME
COPY Gemfile.lock $APP_HOME
RUN bundle install
database設定修正
・postgresqlを利用します。
・postgresqlのパスワードは環境変数から取得します。
# MySQL. Versions 5.0 and up are supported.
#
# Install the MySQL driver
# gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
# gem 'mysql2'
#
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.7/en/old-client.html
#
##########################################
# Settings on Postgresql Environment
##########################################
default: &default
adapter: postgresql
encoding: unicode
# host名はpostgresqlコンテナのServicesとして記載した名称を指定
host: db
user: postgres
port: 5432
# パスワードはコンテナに設定する環境変数を指定する
password: <%= ENV.fetch("POSTGRES_PASSWORD") %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
##########################################
# Settings on MySQL Environment
##########################################
# default: &default
# adapter: mysql2
# encoding: utf8
# pool: 5
# username: root
# password:
# socket: /tmp/mysql.sock
development:
<<: *default
database: memo-space_v2_development
### Settings for host mysql database.
# host: docker.for.mac.localhost
...
docker-compose.yml
ファイルdocker-compose.yml
作成します。
version: '3'
# dbコンテナのボリュームに指定した名称を指定する。
volumes:
db-data:
services:
web:
build: .
ports:
- '3000:3000'
# Setting for only Mysql environment on host
# - '3306:3306'
volumes:
- '.:/myproject'
environment:
- 'POSTGRES_USER=postgres'
- 'POSTGRES_PASSWORD=********'
# コンテナの起動状態を保つための設定
tty: true
# コンテナの標準入力をオープンにして、ターミナルからの操作を可能にする。
stdin_open: true
#依存するコンテナを指定し、起動時の順序が決まる
depends_on:
- db
#アクセス可能なコンテナを指定する。
links:
- db
db:
# docker-hubのpostgresのイメージを使う
image: postgres
# ホストのボリュームにDBデータを保管することでコンテナが消えてもデータが残るようにする
volumes:
- 'db-data:/var/lib/postgresql/data'
コンテナ起動
dockerコンテナをビルドしてバックグラウンドで起動します。
$ docker-compose up --build -d
コンテナのステータスを確認します。
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------
memo-space_v2_db_1 docker-entrypoint.sh postgres Up 5432/tcp
memo-space_v2_web_1 irb Up 0.0.0.0:3000->3000/tcp
dbコンテナ(postgresql)とwebコンテナ(Ruby on Rails)が起動していることがわかります。
データベース作成
起動しているwebコンテナに入ります。
$ docker-compose exec web bash
root@0cd7c2024bc0:/myproject# rails db:create
root@0cd7c2024bc0:/myproject# rails db:migrate
root@0cd7c2024bc0:/myproject# rails s -b '0.0.0.0'
ブラウザでアクセスできることを確認します。
URL : localhost:3000
Dockerfileで指定したボリュームを確認できます。
$ docker volume inspect memo-space_v2_db-data
[
{
"CreatedAt": "2020-07-18T14:24:32Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "memo-space_v2",
"com.docker.compose.version": "1.25.5",
"com.docker.compose.volume": "db-data"
},
"Mountpoint": "/var/lib/docker/volumes/memo-space_v2_db-data/_data",
"Name": "memo-space_v2_db-data",
"Options": null,
"Scope": "local"
}
]
githubにpush
git add .
git commit -m 'commit'
git push origin master
TravisCIアカウント設定
次のURLでアカウントを作成します。
https://travis-ci.org/
・ページ右上の「アカウントアイコン」をクリックし、「settings」を選択します。
・左ペインの「Sync account」をクリックする。
・自分のGithubのアカウント情報を入力する。
自分のGithubアカウントが同期される、RepositoriesにGithubレポジトリが表示されることを確認します。
・herokuにデプロイするアプリのレポジトリのボタンをクリックする。
・Dashboardボタンをクリックする。
・Active repositoriesに、選択肢たgithubレポジトリが表示されていることを確認する。
Travisファイル記述
アプリケーションフォルダの直下に、ファイル.travis.yml
を作成します。
Travisサーバで実行してテストする内容を記述します。
# 権限の設定
sudo: required
service: docker
# インストール前に実行する内容を記述する
before_install:
# Dockerをビルドして起動
- docker-compose up --build -d
# 実行したいスクリプトを記述する。
script:
# Databaseを作成する(rails db:create)
- docker-compose exec --env 'RAILS_ENV=test' web rails db:create
# tableを作成する(rails db:migrate)
- docker-compose exec --env 'RAILS_ENV=test' web rails db:migrate
# RSpecによるテストを実行する(bundle exec rspec)
- docker-compose exec --env 'RAILS_ENV=test' web bundle exec rspec
※実行時にはコメント部分を削除しないとsyntaxエラーになるかもしれません。
docker-compose.yml
TravisCI実行用の環境変数を記述します。
version: '3'
volumes:
db-data:
services:
web:
build: .
ports:
- '3000:3000'
# Setting for only Mysql environment on host
# - '3306:3306'
volumes:
- '.:/myproject'
environment:
- 'POSTGRES_USER=postgres'
- 'POSTGRES_PASSWORD=postgres'
tty: true
stdin_open: true
depends_on:
- db
links:
- db
db:
image: postgres
# ホストのボリュームにDBデータを保管
volumes:
- 'db-data:/var/lib/postgresql/data'
environment:
# テスト環境でTravisCIから実行する際POSTGRESQLの認証を通すため
- 'POSTGRES_HOST_AUTH_METHOD=trust' # <- 追加
テストを実行
githubにpushします。
git add .
git commit -m 'update travis and compose'
git push origin master
ブラウザからTravisCIのWEBページを確認します。
joblog タブに実行内容が出力されます。
記述したテストが実行された結果が出力されます。
Worker information
0.14s0.00s0.01s0.00s0.00s
system_info
Build system information
0.01s0.01s0.49s0.19s0.05s0.00s0.04s0.00s0.01s0.01s0.01s0.01s0.01s0.00s0.00s0.02s0.00s0.01s0.25s0.00s0.00s0.00s0.01s0.00s0.09s0.01s0.76s0.00s0.09s6.03s0.00s2.45s0.00s2.18s
docker_mtu
resolvconf
services
3.01s$ sudo systemctl start docker
git.checkout
0.77s$ git clone --depth=50 --branch=master https://github.com/igatai/memo-space_v2.git igatai/memo-space_v2
0.01s
Setting environment variables from repository settings
$ export HEROKU_USERNAME=_
$ export HEROKU_APP_NAME=memo-space-v2
$ export HEROKU_API_KEY=[secure]
rvm
0.61s$ rvm use default
$ export BUNDLE_GEMFILE=$PWD/Gemfile
ruby.versions
$ ruby --version
before_install.1
$ docker-compose up --build -d
before_install.2
0.52s$ docker login -u "$HEROKU_USERNAME" -p "$HEROKU_API_KEY" registry.heroku.com
install.bundler
178.44s$ bundle install --jobs=3 --retry=3 --deployment
2.42s$ docker-compose exec --env 'RAILS_ENV=test' web rails db:create
Created database 'memo-space_v2_test'
The command "docker-compose exec --env 'RAILS_ENV=test' web rails db:create" exited with 0.
2.39s$ docker-compose exec --env 'RAILS_ENV=test' web rails db:migrate
== 20200206094020 DeviseCreateUsers: migrating ================================
-- create_table(:users)
...
== 20200603012332 CreateEvents: migrated (0.0089s) ============================
The command "docker-compose exec --env 'RAILS_ENV=test' web rails db:migrate" exited with 0.
2.41s$ docker-compose exec --env 'RAILS_ENV=test' web bundle exec rspec
User
#create
nameがない場合は登録できないこと
emailがない場合は登録できないこと
passwordがない場合は登録できないこと
password_confirmationがない場合は登録できないこと
passwordとpassword_confirmationが一致しない場合は登録できないこと
重複したemailが存在する場合は登録できないこと
Finished in 0.13822 seconds (files took 1.54 seconds to load)
6 examples, 0 failures
The command "docker-compose exec --env 'RAILS_ENV=test' web bundle exec rspec" exited with 0.
Done. Your build exited with 0.
heroku設定
herokuアカウントにサインアップし、ログイン状態にします。
https://dashboard.heroku.com/apps
アプリケーションを登録
・トップページ右上の「New」ボタンをクリックします。
・プルダウンメニューから「create new app」をクリックします。
・「App name」にユニークなアプリケーション名を入力します。
・「Choose Regionは」デフォルトのまま
・「Create app」をクリックします
databaseを設定
・アプリケーション名をクリックします。
・「Resource」タブをクリックします。
・「Add-ons」フォームから postgresを入力し、 「Heroku Postgres」を探してクリックします。
・「plan name」から「Hobby Dev - free」を選択します。
・「provision」をクリックします。
環境変数を設定
・「settings」タブをクリックします。
・「Reveal Config Vars」をクリックします。
・設定済み環境変数を確認します。(key / value)
DATABASE_URL / postgres://xxxx...
-> 後ほどアプリケーションのデータベース定義で、production環境部分に上記の環境変数を設定します。
・次の環境変数を設定します。(key / value)
SECRET_KEY_BASE / xxxxxxxx (config/master.keyに記述された値)
※ master.keyがない場合
コンソールから以下を実行する。
EDITOR="vi" rails credentials:edit
エラーが出る場合は、以下を削除し、再度前述のコマンドを実行する。
config/credentials.yml.enc
deployタブを選択します。
・githubアイコンボタンをクリックし、デプロイ対象アプリケーションのリポジトリを同期させます。(connected状態)
・チェックボックス「wait for CI to pass before deploy」をクリックします。
・ボタン「Enable Automatic Deploy」をクリックします。
データベース定義のproduction環境設定を修正
データベースのproduction環境のurlとして、herokuに設定された環境変数DATABASE_URL
を設定します。
# 以下のコメントアウトを外し、有効化する
production:
url: <%= ENV['DATABASE_URL'] %>
# 以下をコメントアウトする
# production:
# <<: *default
# database: memo-space_v2_production
# adapter: postgresql
# # database: postgresql
# encording: unicorde
# pool: 5
# username: memo-space_v2
# url: <%= ENV['DATABASE_URL'] %>
# password: <%= ENV['MEMO-SPACE_DATABASE_PASSWORD'] %>
.travis.ymlに追記
.travis.yml
に本番環境の記述を追加します。
sudo: required
service: docker
before_install:
- docker-compose up --build -d
- docker login -u "$HEROKU_USERNAME" -p "$HEROKU_API_KEY" registry.heroku.com #<-追記
script:
- docker-compose exec --env 'RAILS_ENV=test' web rails db:create
- docker-compose exec --env 'RAILS_ENV=test' web rails db:migrate
- docker-compose exec --env 'RAILS_ENV=test' web bundle exec rspec
# 以下追記
# デプロイ時に実行する内容を記述
deploy:
provider: script
script:
# Dockerfile.prodを元に、本番環境用のDockerImageをherokuのDockerレジストリにpushし、ビルドします。
# -tオプションにより、レジストリ名を「registry.heroku.com/$HEROKU_APP_NAME/web」としてタグづけします。
docker build -t registry.heroku.com/$HEROKU_APP_NAME/web -f Dockerfile.prod .;
# pushします
docker push registry.heroku.com/$HEROKU_APP_NAME/web;
# runする際に db:migrateします。
heroku run --app $HEROKU_APP_NAME rails db:migrate;
# マージされたときに実行するブランチを指定します。
on:
branch:
- master
- DeployWithTravisCI
TravisCIに環境変数を設定する。
macにheroku cliをインストールします。
$ brew tap heroku/brew && brew install heroku
※https://devecnter.heroku.com/articles/heroku-cli
herokuトークンキーを取得します。
$ heroku authorizations:create
Creating OAuth Authorization... done
Client: <none>
ID: xxxxxxxxxxxxxxxxxx
Description: Long-lived user authorization
Scope: global
Token: xxxxxxxxxxxxxxxxxx
Updated at: Wed Jul 15 2020 12:10:07 GMT+0900 (GMT+09:00) (less than a minute ago)
・ブラウザでTravisCIのwebページにアクセスする。
・アプリケーションページから「More options」をクリックする。
・プルダウンメニューから「Settings」をクリックする。
・「Environment Variables」蘭にて以下を追加する。
HEROKU_USERNAME : _
HEROKU_APP_NAME : herokuに設定したアプリケーション名
HEROKU_API_KEY : 確認したherokuトークンキーを設定します。
本番環境用Dockerfileを作成する
FROM ruby:2.5
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
postgresql-client \
yarn
ENV APP_HOME /myproject
WORKDIR $APP_HOME
COPY Gemfile Gemfile.lock $APP_HOME
# RUN gem install bundler
RUN bundle install
# カレントディレクトリのファイルを本番環境にコピーする
COPY . .
# railsサーバスタート
CMD ["rails","s"]
gitにpushします。
$ git add .
$ git commit -m 'add deploy code'
$ git push origin master
TravisCIを確認
TravisCIのwebページ(デプロイするアプリケーションページのcurrentタブのjob log)から以下を確認します。
・テストを実行してパスすること
・デプロイがされていること
※初回実行時にherokuに各種rails環境変数が自動追加されるが、それが反映されずエラーが出る場合があります。
その場合、2回目にデプロイを実行したときに正常に実行できます。
デプロイしたアプリの確認
herokuから「open app」をクリックし、ブラウザでアクセスします。