目次
Docker
初学者のメモ書きなので、適当な理解と誤った記述が大量に含まれる恐れがあります。
できること
仮想環境を作る技術・ツール。
環境構成の設定ファイルさえあれば、それをもとにコマンド一発で、 たとえば「ApacheとMySQLとPHPが入って設定も済んだ仮想サーバ」がすぐできるよ!みたいな。
使用場面
- 開発環境構築の時短
- 普通、「Web開発ではApacheとPHPとMySQL」など、だいたい“よく使われる構成”を使う
- 「○○をするための構成テンプレート」みたいなのからすぐに環境が用意できればうれしい
- →Docker Hub などで、様々なイメージが共有されている
- →Official Image として公式が厳選しているものも豊富にあるのである程度安心
- ちょっとは構成が変わるかもしれないので、柔軟性があればうれしい
- →設定ファイルでカスタマイズできる
- バージョン管理
- 開発で使う言語・サービスは、バージョン違いで不整合を引き起こす可能性が捨てきれない
- 開発・運用中は簡単にはバージョンを上げたくない
- かといって新しいプロジェクトまで古いバージョンを強制されるのは避けたい
- プロジェクトごとに言語・サービスおよびそのバージョンを分けたい
- →Dockerは仮想化しているのでそれができる
- 使い方の勉強
- 話題のツールの使い方を勉強したい
- →イメージがリポジトリで共有されているれば、とりあえずすぐ使える状態にできる
- 変な使い方してOS環境がまるごと壊れたら怖い
- →仮想化してるので壊れたら作り直せる。安心していろいろ試せる
- メンバー間での環境統一
- 開発環境を個々人が用意すると、バージョンや設定などに違いが発生し、一方の環境で動くものが他方で動かなくなりがち
- →設定ファイルを共有すれば確実に同じ環境ができる
基本的にはこんなところと理解。
従来のツールとの違い
仮想化だけならVirtualBoxなどのツールも以前からあったけど、 Dockerは動作・消費メモリが軽いというところが大きなメリット。
なので、「1つの仮想環境にApacheとPHPを入れる」より、「Apacheだけ入った仮想環境、PHPだけ入った仮想環境を個別に用意して、連携させる」というやり方が主流っぽい? それでも、PCスペック的にそこまで重くない。
このやり方は、「MySQLで開発してたけど、MongoDBの方がいいかな」みたいな時に、 サービスを簡単に入れ替えられるなどのメリットがある。
使用するDockerの選択
Windowsでの使用を想定すると、ややこしいことに「Docker Desktop for Windows」とか「Docker on WSL2」とか、 同じDockerでも複数のツールの名前が出てくる。
基本的にDockerはLinux向けに開発されたツールなので、Windowsでは仮想化されたLinux上から使うことになる。
(つまり、仮想Linuxの中からさらにDockerの仮想環境を立ち上げることになる)
2019年に、WSL2(Windows上で仮想Linuxを走らせるシステムのver.2)がWindowsに標準装備され、 その上でDockerも実行できるようになったので、現在はこれを使っとけば問題ない。(WSL1の頃はできなかった)
WSL2上でDockerを動かすのは各ツールで共通していて、
- Docker on WSL2は、直接WSL2上でDockerを利用する方法(Linuxでやるのと一緒)
- DockerDesktopは、Windows側で動き、GUIで、WSL2上でのDockerの起動・設定を操作できるツール
なお、Docker Desktopは、2021年9月から、ビジネスで使う際には有料化されている。
また、Docker Desktopは、Hyper-Vなど、WSL2以外のDockerが動く仮想環境もサポートしているが、まぁ、WSL2でいいと思う。
事前準備
WSL2の設定
Dockerのインストール
WSL2上のLinux(ここではUbuntu)で、dockerをインストール。
$ sudo apt update $ sudo apt install docker
起動
$ sudo service docker start
毎回手動で起動させるのは手間なので、自動起動させたい。
普通の(WSLでない)Linuxと同様の方法とはいかないが、一応タスクスケジューラなどで設定できる。
Docker Composeのインストール
サービスごとに仮想環境を作成して連携させる、という使い方をするにあたり、 複数の仮想環境間の連携を1つの設定ファイルで管理できるようにするツール。
dockerのプラグイン(という呼び方でいいのかな)としてインストールする方法と、バイナリとしてインストールする方法がある。
-
- “Install Compose” の章のタブで、「Linux」がプラグイン、「Linux Standalone binary」がバイナリ
コマンドに若干の違いはあるが、大きな違いは無さそう?
Web上の解説記事ではバイナリの方法を紹介している例が多いか。
プラグインの場合 $ docker compose ○○ バイナリの場合 $ docker-compose ○○
基本的に上記サイトのコマンドを実行していけばよい。
バージョン番号だけ、現在有効な最新バージョン(または希望のバージョン)を調べて書き換える。
使い方
docker-compose.yml を書く。
フォルダ構成としては、例えば以下のようになる。
project-root/ | |- src/ ... プログラムのソースコードなど | |- docker/ ... docker用の設定ファイルなど | |- httpd/ ... dockerの各サービスごとのファイル | | |- Dockerfile | | |- httpd.conf ... サービスの設定ファイル | | | |- php/ | | |- php.ini ... サービスの設定ファイル | |- docker-compose.yml
docker-compose.yml に所定の情報を記述して、その階層をカレントフォルダとして
$ docker-compose up -d
のコマンドで、コンテナたちが起動して利用可能になる。
また、各フォルダの意図は下記の通りとなる。
- ソースコードフォルダ
- 永続化
- Dockerでは、コンテナ内で作成したファイルなどはコンテナの削除や再作成で消失する
- ソースコードが消えたら困るので、Dockerの外部に用意して、マウントするという形を取る
- これで消えなくなり、Docker内外での編集の結果が双方向に反映される
- docker/サービスごとのフォルダ
- Dockerfile
- Dockerfile とは
- 各サービスの設定では、元となるイメージを指定するが、その際
- 「リポジトリにあるイメージから作成されるコンテナをそのまま使う」こともできるし、
- 「コンテナ作成後、必要なアプリのインストールなど追加で何かするところまで自動化する」こともできる。
- 追加で何かする場合の設定ファイルが Dockerfile である
- Dockerfile は1サービスごとの設定ファイルであり、慣習的にデフォルト名 “Dockerfile” のまま使うことが多いため、サービスごとにフォルダが分かれていた方が混在しなくてよい
- サービスの設定ファイル
- PHPやMySQLなどの設定ファイルは、
- アップデートにより更新されるのでユーザがいじることを想定していない設定ファイル
- アップデートで上書きされない、ユーザが自由に編集できる設定ファイル
- この2つで、前者を起点として後者も読み込み同じ設定項目は上書きする、という形を取っているものが多い
- 後者を用意しておき、コンテナ作成後、所定の場所にコピーすると便利
- どのサービスの設定ファイルかわかりやすくするためにも、サービスごとにフォルダは分けて管理した方がよい
- docker-compose.yml例
version: "3.9" services: apache: build: ./docker/httpd volumes: - ./html:/usr/local/apache2/htdocs - ./docker/httpd/httpd.conf:/usr/local/apache2/conf/extra/httpd.conf
- マウント情報は、volumes ブロックに記述する
- コロン(:)で挟んで、左にローカルのパス、右に仮想環境上のパス
- ファイルを指定する場合は、docker-compose.ymlで指定する代わりに、Dockerfile上で “COPY” を使ってもよい。
トラブルシューティング
実行ユーザによる権限エラー
「マウントしたボリュームに、Dockerユーザも書き込むし、Docker外のLinuxユーザも書き込む」場合などに、発生しうる。
Linux(WSL2)側のユーザと、Dockerのユーザが異なっていることが原因。
通常、WSL2のユーザは、UID:1000 GID:1000 の名無しさんになる。
一方、Dockerのユーザは、そのイメージに依存するが、rootだったり、別ユーザだったりする。
マウントしたボリューム上のファイル権限は基本的にLinux側を引き継ぐため、たいてい 1000:1000 が所有者・所有グループとなる。
個人でしか使わない場合、docker-compose.ymlではそのコンテナを実行するユーザを指定できるので、user: 1000:1000
を指定してDocker側でも同じUIDで実行するようにしてやればよい。が、
- もしコンテナの起動過程でroot権限を前提としていた場合、起動自体に失敗する
- 他人とymlを共有する場合、相手の環境も
1000:1000
とは限らない
などの問題が発生する。(後者は外部注入できるかもしれない)