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など)ごとににレイヤーが生成され、レイヤーがキャッシュされる仕組みとなっている
キャッシュとは、同じレイヤーに対して、一度ビルドされると、2回目以降がビルドが必要なくなる。
①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ツールでテストが再度走る
⑨修正版のアプリがデプロイされる