Rails開発環境構築におけるDockerの使い方の基礎をまとめてみました

Rails学習のため、ローカルmac osで開発環境の構築してみましたが、大変苦労しました。その時、Dockerという技術に出会い、ゼロからDockerを学び、また、Dockerを利用してrails開発環境を構築してみました。まず、ここでは、Dockerの基本的な使い方をメモとして残しておきます。

#Dockerとは
Dockerは一言というと、実行環境、テスト環境、本番環境を簡易に構築できるようにするためのツール

#Docker(コンテナ型仮想技術)とVM(ホスト型仮想技術)の主な違い
オーバーヘッドとはコンピュータが処理を行うにあたって、本来の処理とは別に、間接的な処理のこと。
Dockerはホスト型仮想技術と比べると、ゲストOSというオーバヘッドがなくなるというなるのが一番大きな違い

#Docker関連コマンド

##イメージの制御コマンド
docker images：イメージ一覧表示
docker inspect イメージ名：imageの情報確認
docker tag 元イメージ名 ターゲットイメージ名：イメージ名前を変更
docker rmi -f：イメージ強制削除

##コンテナの制御コマンド
docker ps -a：コンテナ実行状況確認
docker rm -f：コンテナ強制削除
docker stop コンテナID：コンテナを停止する
docker system prune：全の停止中のコンテナを削除
docker inspect コンテナ名：コンテナのあらゆる情報を表示してくれる
docker inspect コンテナ名 | grep -i cpu：コンテナのCPUの情報を表示する（-iは大文字小文字を無視する意味）
　
##コンテナ起動
docker run イメージ名：名前指定なしでコンテナ作成（create + startで二つのコマンドが実行される）
docker run イメージ名 bash：デフォルトコマンド上書きして    、コマンドを起動する
docker run --name コンテナ名 イメージ名：名前指定でコンテナ起動
docker run --it イメージ名 bash：ホストとコンテナのstdinインプットチャンネルを開いて(-i)、出力結果を綺麗に出るように(-t)、コンテナを起動する
docker run --rm イメージ名：コンテナを起動して、実行終了後、コンテナが削除される
docker run -d イメージ名：コンテナをバックグラウンド実行で起動させる
docker run -it -v ホストフォルダ名:コンテナフォルダ名 イメージ名 bash：コンテナ起動時、ホストのフォルダをコンテナにマウントするようにする（ソースコード共有時よく使われる、コンテナフォルダが存在しない場合、フォルダを勝手に作成してくれる）
docker run -it -u $(id -u):$(id -g) -v ホストフォルダ名:コンテナフォルダ名 イメージ名 bash：権限指定してコンテナを起動する（複数のユーザがホストを共有で使う際に、誤って他のユーザのデータを書き込みしたり、上書きしたりするために使用する。）
docker run -it -p ホストポート:コンテナポート：ホストポートをコンテナポートに繋げる
docker run -it --cpus 4 --memory 2 イメージ名：リソース指定して、コンテナ起動
docker restart：コンテナを再起動する。その際に、デフォルトプロセスが動くようになる
　　　　　　　①docker exec -it コンテナID bash→detach→attachすると、デフォルトプロセスにattachするため、再度exitを実行すると、コンテナがDOWNする
　　　　　　　②docker exec -it コンテナID bash→exitすると、デフォルトプロセスがまだ動いているので、コンテナまだUPのまま

##コンテナへコマンド実行
docker exec -it コンテナID /bin/bash：起動中のコンテナのbashコマンドを実行して、bashに接続する
docker attach コンテナID：デタッチされたコンテナを再度アタッチする

##コンテナへの接続を切断
EXIT：コンテナのプロセス自体が削除される。コンテナへ接続するには、コンテナを再起動する必要がある
デタッチ(CTRL+p+q)：コンテナのプロセス自体が残り、アタッチすることでコンテナへの再接続が可能

##コンテナからイメージファイルを作成
docker commit  コンテナID コンテナ名：コンテナでイメージを作成する
#イメージファイルの圧縮
docker save イメージID > 圧縮後のイメージ名（xxx.tar）

##DockerHub関連
docker push ユーザ名/リポジトリ名：ローカルのイメージをDockerHubにアップロードする
docker pull ユーザ名/リポジトリ名：DockerHubからイメージをローカルに取得する

##Dockerイメージのビルド
docker build .：デフォルトとして、Dockerfileもビルドコンテキストもカレントディレクトリーになる。
docker build -t イメージ名 .：生成する名前を指定して、ビルドを行う
docker build -f パス名 .：Dockerfileがカレントディレクトにいない場合、パス指定で、Dockerfileを場所を指定することができる。

＃Dockerファイルの作成のベストプラクティス
・FROMは、必要最低限の必要なイメージを指定する
・Dockerimageのレイヤー数を最小限すること（イメージのサイズが小さくなる   ）
・レイヤーを作るのがCOPY,RUN,ADD三つ
・コマンドを＆＆で繋げる
・バックスラッシュで改行を行う

#Dockerファイル作成のポイント
Docker fileを作成（ビルド）時、インストラクタ（RUN、CMDなど）ごとににレイヤーが生成され、レイヤーがキャッシュされる仕組みとなっている
キャッシュとは、同じレイヤーに対して、一度ビルドされると、２回目以降がビルドが必要なくなる。
①Dockerfileの作成が未完了前、極力レイヤーを分けるように記載する
　→キャッシュの仕組みをうまく利用することで、ビルド時間を大幅に短縮できる
②Dockerfileの作成が完成時、極力複数のレイヤーを一つのレイヤーに纏めるように記載する
　→レイヤーごとにストレージ空間が取られるため、レイヤーを纏めることで、イメージのサイズを大幅に小さくすることができる

#インストラクタの役割
RUN：レイヤーを作成する
CMD：レイヤーを作成しない。（コンテナ起動時のデフォルト実行コマンドを指定、基本的にDockerfileの最後に指定する）
ENTRYPOINT：レイヤーを作成しない（コンテナ起動時のデフォルト実行コマンドを指定。デフォルトコマンドがRUN時に上書きできないが、オプションが上書きできる）
COPY：レイヤーを作成する（単純にホストとコンテナのファイルの引き渡し時に使われる）
ADD：レイヤーを作成する（ファイルやフォルダなどをtarコマンドで圧縮した圧縮ファイルをホストからコンテナにコピーして、コンテナ内で解凍してくれる）
WORKDIR：レイヤーを作成しない（カレントディレクトリの切り替え時使用、指定しなければ、RUNを実行する度、/（ルート）がデフォルトとして使われる）
　　　（例外として、RUN cd /tmp && touch testの場合、/tmpにtestファイルが作成される）

#Dockerビルドの仕組み
①Dockerコンテキスト（Dockerビルドの実行環境、いわゆるフォルダ全体）をDocker デーモンに送って、
②DockerデーモンがDockerコンテキストを参照して、Dockerイメージを作成する
※Dockerコンテキストとは、Docker build実行時指定したフォルダのこと

#Dockerオブジェクトの格納先
linux:/var/lib/docker
mac:~/Library/Containers/com.docker.docker/Data
Docker Daemonのオブジェクト保存先を変更：/etc/docker/daemon.json   

#AWSでのdocker環境構築
・ssh -i 認証ファイル ユーザ名＠ホスト名：ec2へのssh接続
・sudo apt-get update ：apt-getを更新
・sudo apt-get install docker.io ：dockerのインストール
・sudo gpasswd -a ubuntu docker：sudo権限のdockerグループを作成して、ubuntuユーザをdockerグループに追加（実行後、ログインし直す必要がある）(上記により、sudo docker → dockerで実行できるようにする)
・docker save イメージID > 圧縮後のイメージ名（xxx.tar）：イメージファイルを圧縮
・sftp -i 認証ファイル ユーザ名＠ホスト名：ec2へのファイル転送
・put ローカルパス リモートパス：ファイルのアップロード
・docker load < 圧縮ファイル名：イメージファイルを解凍される
・docker run -it イメージファイル名 sh

#AWSへのイメージファイルを送る方法
①docker レジストリを使う
②Dockerfileを使う
③Docker file をtar にして送る
                
#Docker-composeとは
Docker -composeとは、複数のコンテナを簡単に実行できるDockerツールのこと
使う場面として：
・Docker Runが長くなるとき
・複数のコンテナをまとめて起動したいとき

#Docker-composeとDockerの比較
docker-compose build => docker build ビルドコンテキスト
docker-compose up => docker run イメージ名
  ->イメージファイルがなければ、ビルドするが、あれば、ずっと古いイメージファイルを使用する（Dockerfileが更新されてもビルドしてくれない）
  ->docker-compose up --buildで強制的にイメージファイルをビルドさせる
docker-compose exec コンテナID サービス名 コマンド=> docker exec コンテナID コマンド
docker-compose down => コンテナを停止して、削除してくれる
docker-compose ps => docker ps

#Dockerを使ってCI/CDを用いての開発フロー
①ローカルでトピックブランチを新規する
②トピックブランチに対して変更をかける
③GitHubに修正内容をpushする
④CIツールでテストが走る
⑤プルリクエストを作成する
⑥問題なければ、トピックブランチからマスタブランチへマージする
⑦CIツールでテストが再度走る
⑨修正版のアプリがデプロイされる