こんにちは。最近、精力的に活動しているRockinWoolです。
今日はDocker Desktop for Linuxを使ってWordPressをより理解し、上手に活用することを目標に調査していきます。WordPressを雰囲気で使っている人々、Docker Desktop for Linuxに興味がある方に刺さってくれれば嬉しいですね。(逆にいえば、皆様には私のスキルの低さを温かい目で見守ってもらえばと思います)
Contents
1. 現在のWordPress環境:予測と懸念
現在、ロリポップさんのサーバをお借りし、WordPressを使って記事を作成しています。WordPressはロリポップさんのサーバ側に用意していただき、LocalのWeb browserからアクセスしております。ロリポップさんのサーバにはムームーさんのドメインをお借りしてアクセスしておりますので、現在の環境構成は下図のようになっていると予測しております。この時点で危惧すべきことは、資産がサーバ側にあるということです。つまり、何らかの状況でLolipopさんへの支払いが遅れたりした際には、一発でこの記事を含めたすべての情報が失われる危険性があるということです。
2. WordPress環境を試しに構築してみる
理解できないものに関しては、まずローカルで環境を作ってみるのが一番良いと思います。ただし、なるべく新品のローカルUbuntu環境を荒らしたくないので、Dockerを使って再現していきます。
2.1 Docker Desktop for Linux(DD4L)環境の構築
今回はこちらを使いながら確認していきます。まずはDocker Desktopをインストールしていきます。普段はCLIでdockerコンテナを使っているのですが、かねてよりナウな仕組みを使って高速化を狙うべくDockerDesktopも触ってみたいと思っていました。ちなみにDockerDesktopの有料化が先日話題になっておりましたが、FAQでは個人レベルであれば無料である旨が記載されています。
インストール作業は非常に簡単で、公式配布サイトに行ってdebパッケージを取得&apt installでインストールするだけです。
sudo apt install ./docker-desktop-4.17.0-amd64.deb
systemctl --user start docker-desktop
2.2 WordPressコンテナの作成
WordPressコンテナについても公式サイトからGithubの説明ページに飛ぶことで作り方がわかるようになっているようです。試しにやっていきましょう。
まずは空のプロジェクトを作れと言われているので、単純に作業場所を作ります。その上でdocker-compose.ymlを作ることを指示されています。docker-compose.ymlの記述は下記の通りです。
雑な解説ですが、このdocker-compose.ymlではdb(database)とwordpressの2つのserviceが動いています。また、volumesでホストのdb_dataとwp_dataフォルダを各コンテナと共有しています。ちなみにcommand行がイマイチよくわかっていなくて、デフォルトのコマンドの上書きとしか日本語公式には書かれていないんですよね。ちょっと宿題にしておきます。
2.3 コンテナの起動とWordPressの設定
docker compose up -d
上記のいつものコマンドをdocker-compose.ymlのあるディレクトリで実行すればコンテナが作成され、自動的に動き出します。今回はここでDocker Desktopからアクセスをしてみました。
WordPressにアクセスできたら、そのままの指示に従ってユーザを登録してパスワードを設定します。正直使い切りなのでそこまで深く考えて設定しませんでしたが、あとでコンテナ内のWordPressにアクセスする際にユーザとパスワードが必要になったので、Googleの自動生成パスワードに頼らないことが大切です。(1敗)
3. 【地獄編】Docker Desktop for Linuxを用いた際のvolumeについて
さて、ここからは興味本位で覗いてみたら地獄を見たDocker Desktop for LinuxのVolumesに関する仕様について解説していきます。なお、調査に時間がかかったせいで、前の章を書いた日から3日経っています。
ことの発端は2.2節で引っかかった「ユーザとパスワードの情報」をコンテナ外から見ることができるか?と考えたことでした。今までのdocker(CLI), docker composeを用いた場合ではdocker-compose.ymlに下記のように記述することで、そういった情報をホスト側から救出することができていました。
services:
example1:
build: .
environment:
- "DISPLAY=${DISPLAY}"
tty: true
privileged: true
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
- ./volume:/home/volume
ところが、今回はdbのvolume紐付け先はdb_dataとなっており、db_dataはservice外にあるvolumesにて定義されています。また、ホストのフォルダパスにあたる記述はなくなっているので、どこにあるのかが不明です。
3.1 Volumeを調べてみる
そもそもvolumeとは何なのか?
調べてみると、今回のようにservice外にvolumesを記述するパターンと、service内にホストのパスを書いてvolumeを設定するパターンでは種類が異なることがわかってきました。簡単にいえば前者が共有ボリューム、後者がバインドマウントという呼び方をします。違いはdockerが管理している領域が自動で共有されるか、ユーザが管理している領域を手動で共有するかです。詳細についてはここのサイトに書いてあります。
さて、今回は共有ボリュームで設定していることになりますが、そうなると「dockerが管理している領域はどこなのか」を知ることでホストからファイルを操作できることになります。これは下記コマンドでVolumeのホストに対するMountPointを確認できます。
$docker volume inspect wordpress_db_data
[
{
"CreatedAt": "2023-03-02T05:38:34Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "wordpress",
"com.docker.compose.version": "2.15.1",
"com.docker.compose.volume": "db_data"
},
"Mountpoint": /var/lib/docker/volumes/wordpress_db_data/_data,
"Name": "wordpress_db_data",
"Options": null,
"Scope": "local"
}
]
上記の情報より、共有ボリュームの配置場所が/var/lib/docker/volumes/wordpress_db_data/_data
にあることがわかったので、中身を確認してみます。
#sudo ls /var/lib/docker/volumes/wordpress_db_data/_data
ls: '/var/lib/docker/volumes/wordpress_db_data/_data' にアクセスできません: そのようなファイルやディレクトリはありません
????
マウントポイントが無い?そんなはずは無いと色々確認してみましたが、やっぱり影も形も無い・・・。
一方でDocker Desktop for Linuxの表示を見ても、/var/lib/dockerを参照しているので、マウントポイントが絶対にそこにあるはず・・・。どういうこと???
3.2 格闘(2日間)
この状況に遭遇し最初に疑ったのは、「LinuxのNameSpaceの関係で/var/lib/docker/以下が一般ユーザにのみ見えていて、rootでは見えない」という事象でした。しかし、そもそも/var/lib/dockerそのものがroot:rootになっているので、/var/lib/docker/volumesがdocker経由とはいえユーザ所有で作成できるのか?ということを考え、おそらく無いだろうと排除しました。
次に考えたのは、ホストのどこかを新しいrootとしてchrootしたのち、そこから数えて/var/lib/docker/volumesにあたる部分が共有ボリュームになっているパターンです。こちらの場合、どっか(渾身のギャグ)にchrootポイントがあるはずなので、ホストを一生懸命探せば見つかるはずでした。しかし、/usr/local/libや/usr/lib、/var/lib、/run/lib等々を当たってみても全く気配も無い感じです。
徐々にフラストレーションが溜まってきて、家族に心配されるようになった頃、ついにとっかかりになりそうな情報がみつかりました。それがこのサイトにあった次の文章です。
MacのDockerEngineはVMの上で動いている罠・・・!
3.3 ホストから見えない場所にVolumeがあるっ!!
ここの情報を持った上で改めて公式サイトの説明文を読んでみると、LinuxでもVMを作り、Docker Desktop for Linuxを動かしているような記述があります。
Docker Desktop for Linux は、コンテナとイメージを 仮想マシン内の 分け隔てられた保管場所に保存し、 リソースを制限するよう制御 します。Docker Desktop 用(のコンテナやイメージ)は専用の場所に保存するため、同じマシン上にインストールした Docker Engine との干渉を防げます。
同じサイトにKVMを使っている旨が記載されているので、あくまでドキュメントからの推測になりますが下記のような構成になっていると考えられます。
従って、自力でVolumeを見に行くためにはDD4L(Docker Desktop for Linux)が作り出した仮想マシンにアクセスし、その中にある/var/lib/docker/volumesへ行く必要があると推測されます。また、このような構成であればホストubuntu上の/var/lib/docker/volumesに共有ボリュームが存在しないことやdocker volume inspectの結果が/var/lib/docker/volumesになることが説明できそうです。なにせdockerコマンドを実行するためのエンジンが仮想マシン上にあれば、パスも仮想マシン上の値になりますからホストで見つからないのも当然になります。
ちなみにDocker Desktopじゃない方のDocker Engineも前回入れてしまったので、この記事のように共存してしまっている状態になっています。詳しくはご参照してください。
3.4 解決策
その後、なんとかしてDD4Lの仮想マシンを特定しようと試みたのですが、イマイチvirtiofsなどの仕様がわからず紛糾していました。そうこうしているうちにDD4Lの拡張機能でアクセスできることが判明したため、今後はそれを使ってデータを救出することにします。さっきの図を見ても、VMのエントリーポイントがDD4Lに限定されるためセキュリティ的にもいい感じですね。
ということで、WordPressの構成を確かめるつもりだったのがDocker Desktop for Linuxの仕様との格闘に発展しちゃいました。ただ、有意義な調査だったと思うので、あまり反省せずWordPressの調査も進めていこうと思います。
ここまで読んでくださった辛抱強い皆様に感謝いたします。次回もみてくださいね。
参考リンク: Volumeを救出するための拡張機能
追記: WordPressのデータをローカルに保存する方法