Laradocを使用した環境構築を例にdockerの使い方を整理する

#本記事の目的
本記事の目的は、dockerを学習したが、期間が開いてもすぐに使用できるよう記憶を定着させるためである。(dockerを使用した環境構築において、普段常にdockerを使用するわけではなく、期間が開くと忘れてしまっていた。)
Docker関連を読み直すだけでは頭に入らない。

今回は、Laravelの開発においてLaradocを使用するが、その一般的な手順から、dockerの意味合いを整理し理解することにより記憶の定着を図りたい。

以下のようにまとめた(つもり)
◇1.laradocを使用したlaravelを動かすまでの手順
◇2.1の手順にて使用されているdockerコマンドの整理
◇3.docker-composerの整理
◇4.まとめ
◇5.その他

#1.laradocを使用したlaravelを動かすまでの手順
とりあえずlaradoc初期画面まで出す手順をざっくり4ステップで記載
1.laradocをダウンロードする

```
$ git clone https://github.com/shonansurvivors/laradock-like.git laradock
```

完了するとlaradocのディレクトリ ができる。
laradocを使用すれば、laravelの開発環境を簡単に構築できる。

2.laradocディレクトリ の.env修正
環境変数を決めている。

3.laradocディレクトリ にて下記実行(例)

```
docker-compose up -d workspace php-fpm nginx postgres
```
複数のコンテナ(workspace、php-fpm、nginx、postgres)を同時に立ち上げ、コンテナをバックグランドで立ち上げている。(今回はpostgresは必要ないが記載)

4.laravelのインストール(例)

```
docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "5.5.*"
```

laradocディレクトリ の直下で実行する。コンテナworkspaceに入り、composerよりlaravelをダウンロードしている。

ブラウザでlocalhostにアクセスすると、画面が表示される。

参考にしたQiita資料
[Laradockを使ってLaravelを動かすまで](https://qiita.com/ichimura/items/27d4a628ff22e2ba8b35)
[Laradockでの環境構築方法２パターンを細かめに説明](https://qiita.com/wajima/items/69fad6c2b42c52928e82)


#2. 「1」の手順にて使用されているdockerコマンドの整理
使用しているコマンドは、docker-compose upと、docker-compose execである。
以下のステップで整理する。
1.docker-compose upとdocker-compose execの確認
2.execで行っていることの整理
3.docker-composeの意味合い

##2.1 docker-compose upとdocker-compose execの確認
リファレンス https://docs.docker.jp/compose/overview.html を参照すれば良いと思うが、項目を分けて記載する。
###2.1.1 docker-compose upについて
[docker-composer up](https://docs.docker.jp/compose/reference/up.html)
コンテナをまとめて立ち上げる。-dでバックグラングで立ち上がる。
今回は必要なコンテナ(workspace、php-fpm、nginx、postgres)を選択して実行している。


###2.1.2 docker-compose exec
起動中のコンテナに入ることで、今回は起動したコンテナworkspaceに入り、composerのコマンドを実行している。
[docker-composeのコマンドリファレンス](https://docs.docker.jp/compose/reference/toc.html)を見たら、execコマンドの記載がない。
[Docker ドキュメント](https://matsuand.github.io/docs.docker.jp.onthefly/compose/reference/exec/)を見れば一応記載はあった。
またhelpコマンドで確認すると、下記が表示された。

```
$ docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [--] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name
                              (default: directory name)
  -c, --context NAME          Specify a context name
  --verbose                   Show more output
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the
                              name specified in the client certificate
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert keys
                              in v3 files to their non-Swarm equivalent (DEPRECATED)
  --env-file PATH             Specify an alternate environment file

Commands:
  build              Build or rebuild services
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show version information and quit

```
 exec               Execute a command in a running container
より、起動中のコンテナに入ること。


##2.2 execで行っていることの整理
```
docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "5.5.*"
```

「2.1.2」でとりあえずコンテナに入って処理しているのはわかるが、久しぶりに上記コマンドを確認すると、workspaceコンテナで、laravelがでてきていまいちわからなかったので、もう少し確認する。
以下の流れで確認する。
1.composerの確認
2.workspaceでのcomposerの適用の確認

###2.2.1 composerの確認
composerを使用している理由として、LaravelはComposerを依存パッケージの管理に使用しているからである。
[laravelサイト](https://readouble.com/laravel/7.x/ja/installation.html)より、laravelを使用するにあたり、以下の手順になる。
1.開発機にComposerを確実にインストール
2.Composerのcreate-projectコマンドを実行し、laravelをインストール

###2.2.2 workspaceでのcomposerの適用の確認

```
$ docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "6.8.*"
```
workspaceのコンテナに入り、composerを実行しているが、workspaceのコンテナにcomposerをインするトールする必要があり、暗黙にそういう処理をしていることが想像できる。

コンテナ開発時に、Dockerfileを使用して、composerのインストールをしているのは予想され、その箇所を確認してみる。

```dockerfile:./workspaceのDockerfile
FROM laradock/workspace:2.6.1-${LARADOCK_PHP_VERSION}
~省略
###########################################################################
# Composer:
###########################################################################

USER root

# Add the composer.json
COPY ./composer.json /home/laradock/.composer/composer.json

# Add the auth.json for magento 2 credentials
COPY ./auth.json /home/laradock/.composer/auth.json

# Make sure that ~/.composer belongs to laradock
RUN chown -R laradock:laradock /home/laradock/.composer

# Export composer vendor path
RUN echo "" >> ~/.bashrc && \
    echo 'export PATH="$HOME/.composer/vendor/bin:$PATH"' >> ~/.bashrc

USER laradock

# Check if global install need to be ran
ARG COMPOSER_GLOBAL_INSTALL=false
ENV COMPOSER_GLOBAL_INSTALL ${COMPOSER_GLOBAL_INSTALL}

RUN if [ ${COMPOSER_GLOBAL_INSTALL} = true ]; then \
    # run the install
    composer global install \
;fi

# Check if auth file is disabled
ARG COMPOSER_AUTH=false
ENV COMPOSER_AUTH ${COMPOSER_AUTH}

RUN if [ ${COMPOSER_AUTH} = false ]; then \
    # remove the file
    rm /home/laradock/.composer/auth.json \
;fi

ARG COMPOSER_REPO_PACKAGIST
ENV COMPOSER_REPO_PACKAGIST ${COMPOSER_REPO_PACKAGIST}

RUN if [ ${COMPOSER_REPO_PACKAGIST} ]; then \
    composer config -g repo.packagist composer ${COMPOSER_REPO_PACKAGIST} \
;fi

# Export composer vendor path
RUN echo "" >> ~/.bashrc && \
    echo 'export PATH="~/.composer/vendor/bin:$PATH"' >> ~/.bashrc

###########################################################################
# Non-root user : PHPUnit path
###########################################################################

# add ./vendor/bin to non-root user's bashrc (needed for phpunit)
USER laradock

RUN echo "" >> ~/.bashrc && \
    echo 'export PATH="/var/www/vendor/bin:$PATH"' >> ~/.bashrc
省略~

```

行っていることはcomposerをインストールし、workspaceで使えるようにしていることだと思われる。

composerコマンドで具体的にできることは下記を参照したりした。
[Composerのcreate-projectが何をやっているのか調べてみた](https://qiita.com/DQNEO/items/74f4bb8fe447e4582a97)
[【Laravel入門】プロジェクト作成から起動まで](https://qiita.com/yukibe/items/5ee27163b603d7f68250)


#3.docker-composerの整理
１、2を通し、laradocを使用してlaravelを動く環境を作るのに、手順の意味を理解できたが、docker-composeと、それに付随して利用されるDockerfileについて得た理解を忘れぬようまとめておく。

docker-composeを使用する時は、基本的に下記３つのステップを踏む
1.コンテナを使用したアプリケーション環境を、Dockerfileに定義する。
2.アプリケーションを構成するサービスをdocker-compose.yml内に定義する。
 こうすることで各サービスは独立した環境において起動することになる。
3.最後にdocker-compose upを実行したら、Composeはアプリケーション全体を起動・実行する。
(リファレンス https://docs.docker.jp/compose/overview.html をほぼ抜粋。)

つまり、docker-composeは、複数のコンテナを定義し実行するDocker アプリケーションのためのツール。docker-compose.ymlのファイルがある直下のディレクトリで実行する。
手順1-3の場合、使用したコンテナだけとりあげると、以下のような構成になっている。

```
.
├── docker-compose.yml
├── nginx
├── php-fpm
├── postgres
└── workspace
```

```docker-compose.yml
version: '3'
services:
    workspace:
      build:
        context: ./workspace
      省略
    postgres:
      build: ./postgres
      省略
    php-fpm:
      build:
        context: ./php-fpm
      省略
    nginx:
      build:
        context: ./nginx
      省略 

```
docker-composer.ymlファイルのserveicesのworkspace、postgres、php-fpm、nginxがコンテナである。
docker-compose up によって、上記４つのコンテナが立ち上がる。
それぞれのコンテナは、build:のcontext:に記載ある箇所のDockerfileによってイメージが作成される。

#まとめ(感想)
今回はdocker-composeとDockerfileの使用方法をざっと整理した。
dockerコマンドを手広く応用できるよう整理したかったが、本件のテーマで整理すると、docker-composeとDockerfileの理解を軸に進めた。
深堀するとdocker以外のことで不明点がボロボロ出て、逆にその確認で時間を要した。

#その他
docker諸々を思い出すために、基礎となりそうな所でメモっていたことを備忘記録として残ししておく。
本記載においては、主に以下文献を使用させて頂いた。
[大澤 文孝,浅居 尚. さわって学ぶクラウドインフラ　docker基礎からのコンテナ構築 (Japanese Edition)](https://www.amazon.co.jp/%E3%81%95%E3%82%8F%E3%81%A3%E3%81%A6%E5%AD%A6%E3%81%B6%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9-docker%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E6%A7%8B%E7%AF%89-%E5%A4%A7%E6%BE%A4-%E6%96%87%E5%AD%9D-ebook/dp/B089VZXX63)

##DockerEngine
DockerはLinux上で動作するソフト。Linuxに「DockerEngine」をインストールすると、Dockerのコンテナを実行できるようになる。
DockerはLinux環境で動かす以外に、Windows環境やMac環境において「DockerDesktop」というソフトを動かす方法がある。
DockerEngineをインストールしたコンピューター（＝Dockerコンテナを動かすコンピューター）のことを「Dockerホスト」と呼ぶ。

##Dockerイメージ
Dockerでは、コンテナ作りを支援するために、基本的なソフトやアプリケーションをインストールした「コンテナの元」が提供される。このようなコンテナの元のことを「Dockerイメージ」と言う。
Dockerイメージは、Docker社が運営している[DockerHub](https://hub.docker.com/)で公開されている。DockerHubのように、Dockerイメージを管理しているサーバーを「Dockerレジストリ」と言う。
イメージはDocker-Hubから取得するが、修正を加えたい場合の手段として、Dockerfileを作成しイメージを作ることができる。

##Dockerコンテナ
イメージよりコンテナ作る。
docker run コマンドは、「docker pull」、「docker create」、「docker start」という3つの一連のコマンドをまとめて実行する利便性を重視したコマンド。

##Dockerfileについて
https://knowledge.sakura.ad.jp/15253/
Dockerfileの使用の仕方は、コンテナを実行する時のカレントディレクトリに置くと、自動でDockerfileの記載に基づき実行される。
Dockerfileを使用しなければ、イメージを作成後に、コンテナで処理する作業を手作業で行う必要がある。
カスタムのDockerイメージを作るときは、手作業でファイルコピーやコマンド実行をするのではなく、Dockerfileと呼ばれる設定ファイルにファイルコピーや実行したいコマンドなど一連の設定を記述し、そのファイルを適用して作るのが一般的である。

##コマンド
Dockerイメージ、Dockerコンテナはまめに確認し削除しておく。
イメージのダウンロード、コンテナ作成は簡単にでき、学習にて使用しているとどんどんたまっていき、使用マシンのレスポンスへの影響が無視できなくなる。
その関連のコマンドを記載。

```
・実行中のコンテナを参照する
docker ps
docker container ls

全コンテナの状態を確認する
docker ps -a

コンテナの停止、スタート、破棄
docker stop my-apache-app
docker start my-apache-app
docker rm my-apache-app

どのようなイメージをダウンロードしたか
docker image ls

Dockerイメージを削除
docker image rm httpd:2.4
docker rmi httpd:2.4
```

###envとは何か
本件ではあまり触れなかったが、気になったのでメモっておく。
「.envファイル」だが、ladarac直下にある。
envというと、envコマンド、.envファイルがあるらしいが、
「.envファイル」は環境変数を記載し、他で使用するためのものである
>env（エンブ）は Unix系オペレーティングシステム (OS) で使われるユーティリティである。環境変数のリストを出力したり、現在の環境を変えることなく異なる環境変数の下で他のコマンドを実行するのに使われる。envを使うことで、変数の追加や削除、変数の値の変更を行える。
( https://ja.wikipedia.org/wiki/Env を参照)

.envファイルの説明で下記等を参考
https://qiita.com/harutakaoka522/items/e0abddfd0311eb4fb32b