##背景
アプリケーション開発をチームで行うにあたり、メンバー共有用及び備忘録としてまとめました。
■Dockerとはなんぞや?って方は下記を視聴推奨
https://www.youtube.com/watch?v=VIzLh4BgKck
※2倍速だと約7分で視聴可能
↓
■時間なくて見れないから、Dokcerを何かに例えてって言う方へ
例:冷凍チャーハン
以下の手順でチャーハンを食べる、つまり仮想環境で作業する。
■Dokcerのインストールしてないよって方は下記を参照推奨
https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81
※インストールまでできればOK
##この記事の目標
Dockerを活用し、仮想環境で開発を行える知識を得る。
##開発環境
ruby 2.6.5
rails 6.0
bundler 2.1.4
node 14
mysql 5.6
##最終的なディレクトリ階層を理解する
■Rails(api)の中身
##1. 各ファイルの作成
まず、アプリケーションの土台となるディレクトリを作成し、作成したディレクトリに移動する。
$ mkdir testApp ←実際にアプリケーションを作成する場合は、任意の名前にする
$ cd testApp
Rails→api、React→frontendと別々に管理した方が使い分けしやすいので、
まずapiのディレクトリを作成。
testApp % mkdir api
api用のファイル一式と、Dockerfileを作成する。
testApp % rails new api --api --database=mysql --skip-test --skip-turbolinks
testApp % touch api/Dockerfile
無事に終了したら、この時に作成されたdatabase.ymlを編集する。
default: &default
adapter: mysql2
encoding: utf8 ##utf8へ修正
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: password ##追加
host: db ##追加
development:
<<: *default
database: testapp_development ##アプリ名へ修正
test:
<<: *default
database: testapp_test ##アプリ名へ修正
production:
<<: *default
database: testapp_production ##アプリ名へ修正
username: testapp ##アプリ名へ修正
password: <%= ENV['TESTAPP_DATABASE_PASSWORD'] %> ##アプリ名へ修正
frontend用のファイル一式(frontendディレクトリも同時に生成される)、Dockerfileを作成する。
testApp % npx create-react-app frontend
testApp % touch frontend/Dockerfile
それぞれのDockerfileを起動させるための、docker-compose.ymlを作成する。
testApp % touch docker-compose.yml
手動で行うディレクトリ、ファイル作成はひとまず完成。
それぞれのファイルの説明は後ほど行う。
##2. Dockerfileの記述
〜おさらい〜
Dockerfileとは、仮想環境を構成するための情報を記載するファイル。
このファイルが無いとイメージが作れない、つまり、冷凍チャーハンを用意できない。
Dockerfile=チャーハンのレシピ
まずはapiのDockerfileから記述する。
FROM ruby:2.6.5
WORKDIR /testApp/api
RUN gem install bundler -v 2.1.4
続いて、frontのDockerfileを記述。
FROM node:14.15.1-alpine
WORKDIR /usr/src/app
##3. docker-compose.ymlの記述
今回、Dockerfileを2つ作成した。
しかし、これらを1つ1つビルドし、イメージを作成するのも面倒だ。
先ほどのチャーハンの例だと、1つ1つ調理し、冷凍チャーハンにするということになる(現実なら普通だが)
そこでdocker composeの登場である。
これは、複数あるDockerfileを一括でビルド、ラン(コンテナ化)させることができる。
チャーハンの例だと、複数段あって温め順等を設定できる高機能な調理器具になる。
version: "3.8"
services:
api:
build: ./api
command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle install --path=vendor/bundle && bundle exec rails s -p 3000 -b '0.0.0.0'"
ports:
- "3000:3000"
volumes:
- ./api:/testApp/api
depends_on:
- db
tty: true
stdin_open: true
frontend:
build: ./frontend
command: sh -c "yarn start"
ports:
- "8000:3000"
volumes:
- ./frontend:/usr/src/app
depends_on:
- api
db:
platform: linux/x86_64
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: root
ports:
- "3306:3306"
volumes:
- db-volume:/var/lib/mysql
volumes:
db-volume:
##4. ビルドを行う
ここまで準備ができたら、下記コマンドでビルドする
testApp % docker-compose build
##5. コンテナを作成する
ここまで来たら、あとはコンテナを起動するだけ。
Railsの「rails s」の要領で下記を実行する。
# -dはバックグラウンドで稼働するという意味
testApp % docker-compose up -d
これで問題なく終了すれば、下記のURLでそれぞれのブラウザが開くか確認。
Rails → localhost:3000
※この時点ではデータベースを作成していないためエラーが出るが、無視して進む
React → localhost:8000
※Reactのマークが出ていればOK
最後に下記コマンドでデータベースを作成する
testApp % docker exec testApp_api_1 rails db:create
基本的に、railsコマンドを入力したい場合は、下記のように行う。
①コンテナがup(動いている)のが前提
②docker exec コンテナ名 rails ~~
もしrails db:createができずに下記のエラーが出たら
OCI runtime exec failed: exec failed: container_linux.go:367: starting container process caused: exec: "rails": executable file not found in $PATH: unknown
まずコンテナにログインする
testApp % docker ps
コンテナID testapp_frontend "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:8000->3000/tcp testapp_frontend_1
コンテナID testapp_api "/bin/sh -c 'rm -f t…" About a minute ago Up About a minute 0.0.0.0:3000->3000/tcp testapp_api_1
コンテナID mysql:5.6 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:3306->3306/tcp testapp_db_1
ここで「testapp_api」のコンテナIDをコピー
testApp % docker exec -it コンテナID bash
root@コンテナID:/testApp/api# ←コンテナへログイン中
ログインできたら、下記コマンドでDBを作成する
root@コンテナID:/testApp/api# rails db:create
もし、「bash: rails: command not found」となってしまったら下記コマンドで再度実行
root@コンテナID:/testApp/api# bundle exec rails db:create
###ローカルホスト動かないよって方
①まずプロセスが動いているか確認する
$ docker-compose ps
下記のように1つだけしか動いていなければ、NG。
本来なら、testApp_api_1、testApp_frontend_1の2つも追加で動いていてほしい。
testApp % docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
32b0b01d40b9 mariadb:10.0 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:3306->3306/tcp testApp_db_1
②ログを確認する
# -dをつけないことで、ログを出力させる
$ docker-compose up
すると、下記のようにapiのところでyarnのインストールが求められていることがわかった。
③yarnをインストールする
$ docker-compose run api yarn install --check-files
無事完了したら、再度下記コマンドを実行し、プロセスが動いているか確認する。
$ docker-compose up -d
$ docker ps
動いていたら、
http://localhost:3000/
http://localhost:8000/
へ再度アクセス(反映されるまで少し時間かかるかも)
動いていなかったら、再度ログや今までの記述に誤りがないか確認する。
##7. コンテナを停止する
使わなくなったり環境の編集が行われたら、下記の手順で停止する。
# プロセス確認
docker ps
# プロセスを止める
docoker stop プロセスの名前
# 再度コンテナを起動させる
docker-compose up -d
##8. 軽量化について
dockerではよく動いていないコンテナやイメージが残り続けます。
PCの容量を圧迫する原因になりかねないので、
下記のコマンド「prune」を使って定期的にオブジェクトを削除して軽量化する。
■ イメージの prune
docker image prune -a
※既存のコンテナ~使われていないイメージすべてを削除するには、 -a フラグを使う。
■ コンテナの prune
docker container prune
docker container prune --filter "until=24h"
※--filter フラグを使うと、範囲を制限できる。たとえば、以下のコマンドは24時間より以前に停止したコンテナのみを削除する。
■ ボリュームの prune
docker volume prune
docker volume prune --filter "label!=keep"
※--filter フラグを使うと、範囲を制限できる。たとえば、以下のコマンドは keep ラベルがないボリュームのみを削除する。
■ ネットワークの prune
docker network prune
docker network prune --filter "until=24h"
※--filter フラグを使うと、範囲を制限できる。たとえば、以下のコマンドは24時間より以前のネットワークのみを削除する。
■ 全てを prune
docker system prune
※docker system prune コマンドは、イメージ、コンテナ、ネットワークを削除(prune)
docker system prune --volumes
※Docker 17.06.1 以上でボリュームも削除したい場合は、 --volumes フラグを使う。