はじめに
上司「おう、ちびまろ。おつかれ!今度の案件でDocker使うから勉強しといて」
ちびまろ「イエッサー!!」
と二つ返事でDockerの勉強をすることが決まったので自分なりに落とし込んだ内容をアウトプットしたいと思います。
私もまだまだ初学者なので、何か間違えていることを記載してしまっていた場合はコメント頂けると嬉しいです!
Dockerとは
Dockerはコンテナ仮想化を用いたOSレベルの仮想化によりアプリケーションを開発・実行環境から隔離し、アプリケーションの素早い提供を可能にする。かつその環境自体をアプリケーションと同じようにコード(イメージ)として管理可能にする。Dockerを開発・テスト・デプロイに用いることで「コードを書く」と「コードが製品として実行される」間の時間的ギャップを大きく短縮できる。
Dockerとは、Docker社が開発しているコンテナ型仮想環境を構築・配布・実行するためのプラットフォームです。
ホスト型(後述)では実現できなかった環境自体をコードで管理できるということが個人的には相当に魅力的でした。
とにかく今は以下のメリットがあることを頭の片隅に覚えておいて欲しいです。
- 環境をコードで管理できる
- 設定次第でコマンド1回環境構築が可能
例:nginx(Webサーバー)、Laravel、MySQLといった3つの環境が1回のコマンドで完成する - コードを別メンバーと共有すると、環境の違いによるエラーなどが発生せず、スムーズに環境構築ができる
仮想化のアーキテクチャ(仮想環境構築時の構造の種類)
先ほど出てきた「コンテナ型」や「ホスト型」について簡単に説明します。
絶対にこの概念を理解しないとDockerを使えないということはないので、一旦飛ばして後から読み返すなどでも大丈夫です。
一昔前までは、PCの中にもう一つ仮想のPC環境を作成し、その中でLinuxなどのOSをインストールし動かしていました。
上記の方法で行う構造をホスト型と言います。
本当は他にもいくつかありますが、その中からホスト型と、Dockerのコンテナ型について説明します。

ホスト型
1番下の土台であるハードウェアの上にホストOS、さらに仮想化ソフトと専門用語が飛び交っていますが全く難しくありません!
1つずつ説明すると
ハードウェア
パソコンその物です。
ホストOS
OS(Operations System)は基本ソフトウェアとも呼ばれており、ハードウェアやアプリケーションソフトウェアを管理・制御するソフトウェアです。
そこまで難しく考えずに、WindowsOS | MacOS | Linux | など聞いたことあるかと思います。あぁ、聞いたことある!となればそれでOKです。
PCより身近なスマホOSだと、IOS | AndroidOS | などですかね!
仮想化ソフト
今あなたが使っているPCの中に、仮想的に別のPCを作成するためのソフトです。
有名どころで言えば、Oracle製のVirtualBoxやVMware社のVMwareなどがあります。
これらのいずれかのソフトをインストールして使います。
ゲストOS
仮想化ソフト上にインストールするOSのことです。
あくまで個人的にですが、私はホストOS = 親玉
、ゲストOS = 居候
という感じでざっくり覚えています笑
ちなみに、WindowsOSの購入は必要ですが、MacPCに仮想化ソフトをインストールし、仮想化ソフトの中にWindowsOSをインストールすることも可能です。
アプリ
これはそのままですね。ゲストOS内でインストールしたアプリのことです。
ホストOSの上で動くソフトウェアと何ら変わらないです。
コンテナ型
さぁ今回の本題とも言えるコンテナ型の説明です。
コンテナ型とは、ホストOS上に直接インストールされたコンテナエンジンによって運用・管理されています。
コンテナ型の最大の特徴は、先ほどホスト型で説明した「ゲストOS」がいらないことです。
そのため、コンテナは仮想マシン(仮想ソフト)より相当に軽量だと言われています。
また、仮想マシンは完全に独立したOSのインストールが必要になりますが、コンテナはホストOSのカーネルを共有しているため、リソース使用量が少なく、起動が迅速です。
コンテナエンジン
ざっくり、Dockerのことだと考えてください。
今回はDockerの環境構築は省きますが、Docker for Desktopを起動させると、Docker Engine が起動して、コンテナエンジンが立ち上がります。
このイメージを持っていれば、最初の入りは大丈夫かと思います。
コンテナエンジンが立ち上がると、その上でWebサーバーやアプリケーションサーバーなどが起動します。
画像で言うアプリに当たる部分です。
イメージ(Image)
Dockerを触っていると、よく聞く単語「イメージ」は覚えてください。
コンテナを起動させるためには、このイメージが必須です。
イメージはコンテナを作成するための元です。ざっくりCDなどのディスクだと考えてください。
このディスクイメージを共有することで、他のマシン上でも同じ環境を構築することが可能となります。
Tag
DockerイメージにはTagという概念があり、イメージのバージョンを表記するために利用されます。
docker hub - nginxにアクセスすると、以下画面のようにTagsに「latest」や「stable-perl」などが存在し、どのバージョンを使うかを選択できます。
デフォルトはlatestです。

Docker Compose
複数のコンテナを定義してコマンドを実行するDockerのためのツールです。
「.yml」の拡張子がついたファイルを使ってサービスを設定します。
簡単に言うと、「PHPのアプリ」「NGINXのサーバー」「MYSQLのDBサーバ」
Laravelを使っている方は是非@ucan-labさんのリポジトリを覗いてみてください。
色々得られるものがあるかと思います。
そんなucan-labさんが公開しているdocker-laravelの環境を使って勉強しました。
コード全文
volumes:
db-store:
psysh-store:
configs:
db-config:
file: ./infra/docker/mysql/my.cnf
services:
app:
build:
context: .
dockerfile: ./infra/docker/php/Dockerfile
target: ${APP_BUILD_TARGET:-development}
volumes:
- type: bind
source: ./src
target: /workspace
- type: volume
source: psysh-store
target: /root/.config/psysh
volume:
nocopy: true
environment:
# Please remove this environment variable, after created the Laravel project. Please write in .env
- DB_CONNECTION=${DB_CONNECTION:-mysql}
- DB_HOST=${DB_HOST:-db}
- DB_PORT=${DB_PORT:-3306}
- DB_DATABASE=${DB_DATABASE:-laravel}
- DB_USERNAME=${DB_USERNAME:-phper}
- DB_PASSWORD=${DB_PASSWORD:-secret}
web:
build:
context: .
dockerfile: ./infra/docker/nginx/Dockerfile
ports:
- target: 80
published: ${WEB_PUBLISHED_PORT:-80}
protocol: tcp
mode: host
volumes:
- type: bind
source: ./src
target: /workspace
db:
build:
context: .
dockerfile: ./infra/docker/mysql/Dockerfile
ports:
- target: 3306
published: ${DB_PUBLISHED_PORT:-3306}
protocol: tcp
mode: host
configs:
- source: db-config
target: /etc/my.cnf
volumes:
- type: volume
source: db-store
target: /var/lib/mysql
volume:
nocopy: true
environment:
- MYSQL_DATABASE=${DB_DATABASE:-laravel}
- MYSQL_USER=${DB_USERNAME:-phper}
- MYSQL_PASSWORD=${DB_PASSWORD:-secret}
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD:-secret}
mailpit:
image: axllent/mailpit
ports:
- target: 8025
published: ${MAILPIT_PUBLISHED_PORT:-8025}
protocol: tcp
mode: host
volumes
volumesはDockerコンテナをマウントするボリュームを指定します。
マウントする/しないでかなり変わることが分かりました。
マウントしないと、コンテナを削除したりするとDBのデータも一緒に削除されてしまいます。
テストデータとしてまとめて登録できるデータならまだしも、消えてはいけないデータまで完全に消えてしまうため、マウントは必須だと思います。
DBデータを残したいなら絶対です!!
コンテナ内の記憶領域のデータは削除されますが、別でDataVolumeという領域にデータのバックアップが保管されているイメージです。
volumesを設定することで、このDataVolumeという領域が使えるようになるとイメージすればOKかな?
volumes:
db-store:
psysh-store: