- Docker概要
- 環境構築: WSL2 + Docker
- 環境構築: Docker for Mac
- 環境構築: Docker for Windows(Windows10 Home では使用不可)
- 環境構築: Docker Toolbox
- イメージの利用(Apache + PHP 環境の構築)
- イメージを作成
- イメージをファイルとして保存
- イメージを Docker Hub に保存
- イメージを Docker Hub に保存(イメージの更新とlatestタグの指定)
- イメージの連携(Apache + PHP + MySQL 環境の構築)
- イメージの削除
- Docker Compose
- データベースの永続化
- データベースのバックアップ
- プロジェクト名の指定
- 読み書きの制限
- ファイル共有で一部を除外
- Docker Compose と Dockerfile の併用
- Docker Compose の内容を一部上書き
- 値のやりとり
- まとめ
- コマンドまとめ
- その他の環境構築例
- Cronでの定期実行
- Laradockによる開発環境構築
- Laravel Sailによる開発環境構築
- WordPress
- メール送信
- VagrantのCentOSでDockerを使用する
- VagrantのUbuntuでDockerを使用する
- EC2でDockerを使用する
- ホストOSとコンテナで相互にファイルを読み書き(Linux環境)
- トラブル
- コマンドの新旧
- メモ
Docker概要
コンテナ型のアプリケーション実行環境。
当初は開発環境やテスト環境における利用が多かったが、
現在ではパブリッククラウドからオンプレミスシステムまで、さまざまなシーンで急速に普及しつつある。
DockerはLinuxの1プロセスとして動作するが、名前空間やリソースは他のプロセスやコンテナから隔離して扱われる。
そのため、コンテナ内のアプリケーションから見ると独立したコンピュータ上で実行されているかのようになる。
「namespace」「cgroups」「仮想NIC」といった、既存のLinuxの技術を組み合わせて実現している。
Vagrantでは「Linux環境自体を一から構築して使う。扱いは通常のLinuxサーバに近い」という方針になるが、
Dockerでは「必要なイメージを組み合わせて環境を構築する。使い捨ての環境を手軽に導入できる」という方針になる。
Dockerは軽量なテキストで環境を管理できるので、gitなどでの配布が容易。
Dockerについて基本から最近追加された機能までまとめ - Qiita
https://qiita.com/yuki_ycino/items/b94ae2bf7d78685cd6f5
Docker入門(第一回)〜Dockerとは何か、何が良いのか〜 | さくらのナレッジ
https://knowledge.sakura.ad.jp/13265/
Docker Compose入門 (1) 〜アプリケーションをコンテナで簡単に扱うためのツール〜 | さくらのナレッジ
https://knowledge.sakura.ad.jp/21387/
超入門Docker:第1回 Dockerとは - @IT
http://www.atmarkit.co.jp/ait/articles/1701/30/news037.html
知らぬはエンジニアの恥。今さら聞けない【コンテナ/仮想化技術】11選 - paiza開発日誌
http://paiza.hatenablog.com/entry/2014/10/21/%E7%9F%A5%E3%82%89%E3%81%AC%E3%81%AF%E3%82%A8%E3%83%B3%...
原理原則で理解するDocker - Qiita
https://qiita.com/tajima_taso/items/28938415846dcc2e83ff
Linux コンテナの内部を知ろう / OSC 2018 Kyoto - Speaker Deck
https://speakerdeck.com/tenforward/osc-2018-kyoto
コンテナ技術入門 - 仮想化との違いを知り、要素技術を触って学ぼう - エンジニアHub|若手Webエンジニアのキャリアを考える!
https://employment.en-japan.com/engineerhub/entry/2019/02/05/103000
入門 Docker
https://y-ohgi.com/introduction-docker/
Docker入門資料「入門 Docker」を5年ぶりにアップデートしました。 - y-ohgi's blog
https://y-ohgi.blog/entry/2024/08/19/Docker%E5%85%A5%E9%96%80%E8%B3%87%E6%96%99%E3%80%8C%E5%85%A5%E9...
いまさらDockerに入門したので分かりやすくまとめます - Qiita
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1
Dockerについて深くまとめてみた - その1 Docker概要編 - ecbeing labs(イーシービーイング・ラボ)
https://blog.ecbeing.tech/entry/2019/08/02/114014
Dockerとはどういったものなのか、めちゃくちゃ丁寧に説明してみる - Qiita
https://qiita.com/SatoshiSobue/items/a612ebbb3a9242c09db5
DockerとAnsibleの使い分けを手探りで考えてみた - Taste of Tech Topics
http://acro-engineer.hatenablog.com/entry/2015/12/01/120500
社内勉強会で作ったDocker/Kubernetes入門の資料を公開しました - inductor's blog
https://inductor.hatenablog.com/entry/2019/10/15/165014
社内でインフラエンジニア向けに作ったFargate勉強会の資料を公開します - inductor's blog
https://inductor.hatenablog.com/entry/2019/11/15/150908
とほほのDocker入門 - とほほのWWW入門
http://www.tohoho-web.com/docker/
レガシーエンジニアによるDocker入門 - Qiita
https://qiita.com/mamoru12150927/items/5fdab2ac8bb817344291
最短で使うDocker入門〜Dockerを体験しよう (1/3):CodeZine(コードジン)
https://codezine.jp/article/detail/12830
Dockerfileのベストプラクティス - Qiita
https://qiita.com/Tsuyozo/items/c706a04848c3fbbaf055
コンテナ監視って何見るの?〜初心者編〜 - Speaker Deck
https://speakerdeck.com/kaojiri/kontenajian-shi-tutehe-jian-rufalse-chu-xin-zhe-bian
軽量Dockerイメージに安易にAlpineを使うのはやめたほうがいいという話 - inductor's blog
https://blog.inductor.me/entry/alpine-not-recommended
良いDockerfileの書き方まとめ - Qiita
https://qiita.com/Thang_TQ/items/44a9115fec88a4a619e2
今使ってるLinuxをDockerイメージ化する - Qiita
https://qiita.com/syo0901/items/a08a801ec296a6c627d5
Dockerイメージの理解を目指すチュートリアル - Qiita
https://qiita.com/zembutsu/items/24558f9d0d254e33088f
Dockerfileのベストプラクティス Top 20 - Sysdig
https://sysdig.jp/blog/dockerfile-best-practices-2/
Dockerfileを書く時の注意とかコツとかハックとか | Program Is Made At Night
https://kimh.github.io/blog/jp/docker/gothas-in-writing-dockerfile-jp/
実践 Docker - ソフトウェアエンジニアの「Docker よくわからない」を終わりにする本
https://zenn.dev/suzuki_hoge/books/2022-03-docker-practice-8ae36c33424b59
Docker Compose V2で変わったdocker-compose.ymlの書き方
https://zenn.dev/miroha/articles/whats-docker-compose-v2
Docker初学者がやるべきこと3選 - Qiita
https://qiita.com/nuco_fn/items/22cf85a2646d96361d0b
ドッカー入門
https://zenn.dev/raltos/books/e50ef289c7565c
Dockerの"分からない"を簡単にメモ - Qiita
https://qiita.com/fsd-fukufuku/items/f8539e562352c046f39c
今更聞けないDockerのしくみ(「Dockerとは?」から「docker-composeファイルを1人で作れるようになる」まで) #Ruby - Qiita
https://qiita.com/a16111k/items/0e152a096c4934b1a193
Dockerのコンテナイメージサイズを1/10以下に軽量化してみた #Python - Qiita
https://qiita.com/SBS_Takumi/items/9e3c3e5bdc0aaa6cab1d
個人的docker composeおすすめtips 9選 | フューチャー技術ブログ
https://future-architect.github.io/articles/20240620a/
2024年版のDockerfileの考え方&書き方 | フューチャー技術ブログ
https://future-architect.github.io/articles/20240726a/
【2024年版】Dockerfileのベストプラクティスを整理しながらNode.jsで実践する
https://zenn.dev/mutex_inc/articles/nodejs-ts-docker-best-practice
環境構築: WSL2 + Docker
「Docker for Windows」や「Docker Toolbox」よりも後発の技術。
今は基本的にこれを使うのが無難。
環境構築の詳細は「WSL.txt」を参照。
環境構築: Docker for Mac
※可能ならWindowsでWSL2を使うのが無難。
Windowsよりも、Macの方が簡単にインストールできるはず。
【初心者向け】MacにDockerを手軽にインストールする方法! | Aprico
https://aprico-media.com/posts/2375
DockerをMacにインストールする(更新: 2019/7/13) - Qiita
https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81
ただし、Macならではな問題はあるみたいなので注意。
また、実際に試すと非常に重くて使い物にはならなかった。
Docker for Macでは定期的にdisk imageをお掃除する必要がある - モヒカンは正義
https://blog.pinkumohikan.com/entry/cleanup-docker-disk-image
Docker for Mac が遅いので代わりに VirtualBox 上で Docker を使う - Qiita
https://qiita.com/kawanet/items/a0920fc7c59c2612f064
Docker Desktopの場合、virtiofsを導入することで高速になるかもしれない。(未検証。)
Docker Desktop for Macを使ってる人はみんな今すぐvirtiofsを使うんだ! - Sweet Escape
https://www.keisuke69.net/entry/2022/03/25/083002
環境構築: Docker for Windows(Windows10 Home では使用不可)
※WSL2を使うのが無難。
Windows管理者のためのDocker入門:無償の「Docker for Windows」で手軽にLinuxコンテナを利用する (1/2) - @IT
http://www.atmarkit.co.jp/ait/articles/1609/01/news053.html
https://docs.docker.com/docker-for-windows/install/
の「Get Docker for Windows (Stable)」からDockerをダウンロード&実行。
…と思ったが、いきなりエラーになってインストールできない。
俺のDocker - Windows10にインストール - Qiita
https://qiita.com/Ogaaaan/items/99fe54f052ca450889f7
Windows10 Home では使えない。Professional にする必要がある。
Homeの環境は多そうなので、Docker for Windows は使いづらいかも。
環境構築: Docker Toolbox
※WSL2を使うのが無難。
Windows10にDockerでLAMP環境を構築する - Qiita
https://qiita.com/kamonamban/items/e0150a2a7a4d28db10c4
Windows10マシンにDocker Toolbox を入れて個人用の開発環境を作る - Qiita
https://qiita.com/osuo/items/99a2b7413ce75f8217be
Docker Toolboxのインストール:Windows編 - Qiita
https://qiita.com/maemori/items/52b1639fba4b1e68fccd
Docker Toolbox だと、Windows10 Home でも使える。
Docker Toolbox は Docker 環境を簡単に構築するためのインストーラらしい。
■インストール
Docker Toolboxを使ってみる | GWT Center
https://www.gwtcenter.com/using-docker-toolbox
を参考にインストール。
まずは以下からDockerの最新版(DockerToolbox-19.03.1.exe)をダウンロード&インストール。
Releases - docker/toolbox
https://github.com/docker/toolbox/releases
Welcome画面が表示されるので、確認してNext。
インストール先が表示されるので、確認してNext。
コンポーネントの追加が表示されるので、確認してNext。
追加作業について表示されるので、「Install VirtualBox with NDIS5 driver[default NDIS6]」にチェックを入れてNext。
インストール内容を確認してInstall。
Finishをクリックして完了。
Docker Toolboxのインストール:Windows編 - Qiita
https://qiita.com/maemori/items/52b1639fba4b1e68fccd
インストールは主にこのページを参考にした。
■インストールエラーメモ(2020年6月)
あらかじめVirtualBoxをインストールしていても、Dockerインストール時に再インストールされる。
DockerToolbox-19.03.1.exe をインストール。インストール時、「Install VirtualBox with NDIS5 driver[default NDIS6]」にチェックを入れて進める。
Docker Quickstart Terminal の起動に失敗するのでVirtualBoxのみアンイストール。
VirtualBox-5.2.2-119230-Win.exe をインストール。
vagrant_2.2.9_x86_64.msi をインストール。
これでDockerもVagrantも使えるようになった。
すでに起動させていたVagrantを起動できなくなった場合、
以下のように、プラグインをインストールしなおせば起動できた。
>vagrant plugin repair
>vagrant plugin expunge --reinstall
Continue? [N]: Y … 「Y」を入力してEnter。
>vagrant plugin update
>vagrant box list
■インストールエラーメモ(2019年8月)
あらかじめVirtualBox6.0をインストールしていたが、Docker起動時に以下のエラーになった。
Error setting up host only network on machine start: The host-only adapter we just created is not visible. This is a well known VirtualBox bug. You might want to uninstall it and reinstall at least version 5.0.12 that is is supposed to fix this issue
Looks like something went wrong in step ´Checking status on default´... Press any key to continue...
5.0.12 なら動作するようだが、いったんVer5の最終版である VirtualBox-6.0.10-132072-Win.exe をダウンロード&インストール。
そうするとDockerを起動できるようになった。Vagrantも起動できる。
■インストールエラーメモ(2018年)
インストールが完了するとVirtualBoxが5.2になっていた。
バージョン問題でVagrantが起動しなくなった。
Dockerも起動途中でエラーになる。
VirtualBoxを5.1に戻すと、VagrantもDockerも起動するようになった。
(ただしその後のWindowsアップデートの影響で、5.1では動かなくなったので5.2に上げた。
が、環境によっては 5.1.30 でないと動かない。などがあり謎。)
Kitematic (Alpha)はエラーになって起動しなかった。(DockerのGUI。)
起動後、もともとインストールしていた Oracle VM VirtualBox が起動しなくなった。
…が、Windowsを再起動すると、再度起動するようになった。
いったん放置。
■起動
Docker Quickstart Terminal を起動。
コンソールが開いて処理が始まった。
数分で完了し、コンソールが入力待ち状態になった。
この時点で、再度「Oracle VM VirtualBox」を起動させると、新たに「default」サーバが追加されて起動中になっていた。
「Dockerを起動=VirtualBoxでDocker用の仮想マシンを起動」となっているみたい。
$ docker container run hello-world
Unable to find image 'hello-world:latest' locally … 初回実行時はイメージがダウンロードされる。
latest: Pulling from library/hello-world
b04784fba78d: Pull complete
Digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
Status: Downloaded newer image for hello-world:latest
Hello from Docker! … 2回目からはここからの表示となる。
This message shows that your installation appears to be working correctly.
〜略〜
動作確認コマンドを試すと、正常に動いているみたい。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 725dcfab7d63 2 weeks ago 1.84kB
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default * virtualbox Running tcp://192.168.99.100:2376 v17.06.0-ce
イメージとマシンが追加されている。
■終了
「Oracle VM VirtualBox」を起動させ、「default」サーバを右クリックして「閉じる → ACPI シャットダウン」とするといいみたい。
「閉じる → 電源オフ」でも終了できるが、これは強制終了のようなものかもしれない。
■同一ネットワークの他端末からのブラウザアクセス
※XAMPPやSkypeが80番ポートを使っている場合、あらかじめソフトを終了させておく。
Docker Quickstart Terminal から以下を実行することにより、
SSHのポートフォワーディングでネットワーク上にポートを公開する。
(DockerのIPアドレスが 192.168.99.100 であるとする。)
$ ssh -fNCL 0.0.0.0:80:localhost:80 docker@192.168.99.100 … SSHをバックグラウンドで起動。
The authenticity of host '192.168.99.100 (192.168.99.100)' can't be established.
ECDSA key fingerprint is SHA256:MU512WSVjrCJ8FHD45UtuOjzAB0UJeaG5zxOMCojEK8.
Are you sure you want to continue connecting (yes/no)? … 「yes」を入力。(初回のみ。)
Warning: Permanently added '192.168.99.100' (ECDSA) to the list of known hosts.
docker@192.168.99.100's password: … 「tcuser」を入力。
これで自身からは
http://192.168.99.100/
だけでなく、
http://127.0.0.1/
http://localhost/
でもDockerにアクセスできるようになる。
コマンドプロンプトから以下を実行。
(自身のPCのIPアドレスを調べる。)
>ipconfig
IPv4 アドレス . . . . . . . . . . . .: 192.168.1.6
自身のIPアドレス
http://192.168.1.6/
でもDockerにアクセスできることを確認する。
この状態なら、同一ネットワークの他端末からのブラウザアクセスが可能。
バックグラウンドで起動しているSSHを終了させる場合、以下のようにする。
$ ps … SSHを確認。
PID PPID PGID WINPID TTY UID STIME COMMAND
10220 8708 10220 6160 cons0 197609 14:49:45 /usr/bin/ps
8708 1 8708 11020 cons0 197609 14:35:13 /usr/bin/bash
5388 1 5388 5388 ? 197609 14:45:28 /usr/bin/ssh
$ kill 5388 … SSHを終了。
Windows - WindowsのDockerのコンテナに外部からアクセスしたい。(54259)|teratail
https://teratail.com/questions/54259
イメージの利用(Apache + PHP 環境の構築)
ベースとなるイメージが、Docker公式イメージとして利用できる。
Apacheやnginxなど、よく使われるものはたいてい揃っている。(公式以外のイメージもある。)
Docker Hubのオフィシャルイメージを使ったLAMP環境(Apache+PHP+MySQL)構築 - Qiita
https://qiita.com/naga3/items/be1a062075db9339762d
■Apache+PHPのイメージを取得
$ docker container run -d php:8.1-apache … PHP+ApacheのイメージをDocker Hubから取得し、バックグラウンド(-d)でコンテナを起動。
$ docker image ls … 取得したイメージ一覧を表示。
$ docker container ls … 起動しているコンテナ一覧を表示。
「-d」を指定しない場合、フォアグラウンドで起動される。
この場合、プロセスの標準入出力・標準エラーをコンソールに出力する。
■ブラウザで確認
$ docker container run -p 80:80 -d php:8.1-apache … ホストの80番ポートとコンテナの80番ポートを結びつけて、コンテナを起動。
$ docker container ls … 起動しているコンテナ一覧を表示。
ブラウザで以下にアクセスし、「403 Forbidden」が表示されれば成功。
http://127.0.0.1/
■コンテナを終了する場合
$ docker container ls … コンテナのIDを確認。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06256413da0f php:8.1-apache "docker-php-entryp..." 14 minutes ago Up 14 minutes 0.0.0.0:80->80/tcp thirsty_bardeen
957ba4371700 hello-world "/hello" 38 minutes ago Exited (0) 38 minutes ago vigorous_colden
$ docker container rm -f 06256413da0f … ID「06256413da0f」のコンテナを終了する場合。
$ docker container rm -f $(docker container ls -a -q) … すべてのコンテナを終了する場合。
■イメージを削除する場合
$ docker image ls … イメージのIDを確認。
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker-whale latest 2f37bab81128 About a minute ago 274.1 MB
hello-world latest 0a6ba66e537a 2 weeks ago 960 B
$ docker image rm 2f37bab81128 … ID「2f37bab81128」のイメージを削除する場合。
■コンテンツを作成
$ docker container run --name php -p 80:80 -d php:8.1-apache … コンテナに「php」という名前を付けて起動。
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# echo '<?php phpinfo();' > index.php … index.php を作成。(初期状態ではviはインストールされていない。)
ブラウザで以下にアクセスし、phpinfoが表示されれば成功。
http://127.0.0.1/
# exit
$ docker container rm -f $(docker container ls -a -q) … 確認できたら終了。
docker exec -itって実際は何をしてるの?【90日目】 - エンジニアのひよこ_level10
https://www.nyamucoro.com/entry/2018/01/11/224932
■ファイル共有(C:\Users 配下を対象にする)
※Windows側とファイルを共有。
Vagrantとは違い、コンテナを終了させるとデータも初期化されるため、データ保持のためにも。
以下、作業フォルダが C:\Users\refirio であるとする。
docker\test\code\index.php を作成し、以下の内容を記述。
<?php phpinfo() ?>
以下のようにして起動。
$ docker container run --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:8.1-apache … docker\test\code と /var/www/html を共有。
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# ls /var/www/html … 同期されたファイルを確認。
# exit
ブラウザで以下にアクセスし、phpinfoが表示されれば成功。
http://127.0.0.1/
$ docker container rm -f $(docker container ls -a -q) … 確認できたら終了。
「$PWD」は現在のフォルダを表す。
$PWD/docker/test/code:/var/www/html をフルパスで指定する場合、以下のようにする。相対パスでは指定できないみたい。
/home/refirio/docker/test/code:/var/www/html
フォルダがWindows領域なら以下のようになる。(Docker Toolboxの使用時など。)
/c/Users/refirio/docker/test/code:/var/www/html
■ファイル共有(C:\Users 配下以外を対象にする)
※Docker Toolboxで検証していたときに発生した問題。
WSL2ならWSL2内にコンテンツを配置すればいいので問題にならない。
C:\Users 配下以外をファイル共有対象にして起動しようとすると、以下のようなエラーになる。
ERROR: for php Cannot start service php: oci runtime error: container_linux.go:262:
starting container process caused "chdir to cwd (\"/var/www/html\") set in config.json failed: no such file or directory"
C:\Users 配下以外を対象にしたい場合、マウントの指定を行う必要がある。
ここでは
・Docker用のマシン名は「default」である。
・C:\localhost\home\test\public_html\docker を作業フォルダにする。
という場合を想定する。
Dockerを起動させている場合、「Oracle VM VirtualBox マネージャ」で「default」の電源をオフにしておく。
VboxManageでVirtualBox共有フォルダを追加する。 (初回のみ実行する。)
>cd C:\Program Files\Oracle\VirtualBox
>VBoxManage sharedfolder add default --name data --hostpath "C:\localhost\home\test\public_html\docker"
「Docker Quickstart Terminal」を起動し、マウントを行う。 (Dockerを起動させるたび実行する。)
docker-machine ssh default 'sudo mkdir -p /c/localhost/home/test/public_html/docker'
docker-machine ssh default 'sudo mount -t vboxsf -o uid=0,gid=0 data /c/localhost/home/test/public_html/docker'
以降は通常どおりの手順で起動できる。
Dockerにホストのフォルダをマウントしたい! - Qiita
https://qiita.com/dojineko/items/f623894ef2436bef890e
イメージを作成
■イメージを作成(commitコマンド)
※実際にコンテナに対して行った操作内容をもとに、イメージを作成する。
$ docker container run --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:8.1-apache
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# touch /root/test1.txt … テストファイルを作成しておく。
# touch /root/test2.txt
# exit
$ docker container diff php … コンテナ「php」内の差分を表示。(テストファイルの存在を確認する。)
$ docker container commit php php:create_file … コンテナ「php」のイメージを「php:create_file」という名前で作成。
$ docker container run --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:create_file
… 作成したイメージから起動。
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# ls /root … テストファイルを確認する。
$ docker container rm -f $(docker container ls -a -q) … 作成済みのコンテナをいったん終了。
■イメージを作成(buildコマンド)
※コンテナへの操作内容をDockerfile(テキストファイル)に記載し、それをもとにイメージを作成する。
※Dockerfileさえ渡せば、他の人も同じ環境を再現できる。
※操作内容が明確になり、gitで変更履歴を管理することもできるため、原則としてこちらの方法を推奨。
$ docker image ls … 上で作成したイメージのIDを確認。
$ docker image rm f51b32dd3fc4 … 削除しておく。
docker\php_create_file\Dockerfile … Dockerfileを作成。
FROM php:8.1-apache
RUN touch /root/test1.txt
RUN touch /root/test2.txt
$ docker image build -t php:create_file docker/php_create_file … Dockerfileをもとに、新しいイメージをビルド。
$ docker image ls … 作成されたイメージを確認。
$ docker container run --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:create_file
… 作成したイメージから起動。
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# ls /root … テストファイルを確認する。
$ docker container rm -f $(docker container ls -a -q) … 作成済みのコンテナをいったん終了。
イメージをファイルとして保存
$ mkdir docker/images
$ docker image save php:create_file > docker/images/php_create_file.tar … 「php:create_file」イメージを「php_create_file.tar」として保存。
$ docker image ls … 上で作成したイメージのIDを確認。
$ docker image rm 7a1505eda9dd … 削除しておく。
$ docker image load < docker/images/php_create_file.tar … 保存したイメージを読み込む。
$ docker image ls … 読み込んだイメージを確認。
イメージを Docker Hub に保存
Docker Hub は、Docker社が管理する公開レジストリ
■Docker Hubに登録
https://hub.docker.com/ にアクセスし、以下を登録。
(Docker IDにハイフンは使えなかった。)
Docker ID: refirio
Email: refirio@example.com
Password: **********
「Choose a Plan」画面になるので、「Continue with Free」をクリック。
「Please verify your email address」画面になるので、メールを確認して認証する。
認証後、Docker Hubにログインできることを確認する。
Docker Hub Container Image Library | App Containerization
https://hub.docker.com/
Docker Hub にイメージを保管する - Docker-docs-ja 1.9.0b ドキュメント
https://docs.docker.jp/engine/userguide/dockerrepos.html
【docker】DockerHubへの登録 - 自由気ままに書いちゃおう
https://www.guri2o1667.work/entry/2020/11/02/%E3%80%90docker%E3%80%91DockerHub%E3%81%B8%E3%81%AE%E7%...
■リポジトリの作成
Repositories → Create Repository にアクセスし、以下でリポジトリを作成。
Name: test
Description: (空欄)
Visibility: Public
以下にリポジトリが作成された。
https://hub.docker.com/repository/docker/refirio/test
リポジトリ作成直後は、「Last pushed」が「never」となっている。
■イメージを作成
ローカル環境でイメージを作成。
「php:8.1-apache」をもとに、追加でファイルを作成するだけのイメージを作成する。
docker\php_create_file\Dockerfile … Dockerfileを作成。
FROM php:8.1-apache
RUN touch /root/test1.txt
$ docker image build -t php:create_file docker/php_create_file … Dockerfileをもとに、新しいイメージをビルド。
$ docker image ls … 作成されたイメージを確認。
$ docker container run --name php_create_file -v $PWD/docker/php_create_file/code:/var/www/html -p 80:80 -d php:create_file
… 作成したイメージから起動。
$ docker container exec -it php_create_file bash … phpコンテナのターミナルに接続。
# ls /root … テストファイルを確認する。
確認できたら、起動したコンテナは終了しておく。
$ docker container ls
$ docker container rm -f aac2e02145eb
■イメージを登録
ローカル環境でDocker Hubにログイン。
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: refirio
Password:
WARNING! Your password will be stored unencrypted in /home/refirio/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
※ログイン情報は /home/refirio/.docker/config.json に保存されるみたい。
暗号化されていないらしいが、生のままというわけでも無い。
ログアウトすると削除されるみたい。
いきなりプッシュしようとしても、以下のようなエラーになる。
$ docker image push refirio/php_create_file:0.1
The push refers to repository [docker.io/refirio/php_create_file]
An image does not exist locally with the tag: refirio/php_create_file
プッシュしたいイメージを確認し、まずはタグ(別名)をつける。
別名は「ユーザ名/イメージ名:タグ名」とする。タグ名は通常はバージョン情報を指定する。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
php create_file 2f5eeeeb3991 15 minutes ago 414MB
$ docker image tag php:create_file refirio/test:0.1
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
php create_file 2f5eeeeb3991 20 minutes ago 414MB
refirio/test 0.1 2f5eeeeb3991 20 minutes ago 414MB
$ docker image push refirio/test:0.1
The push refers to repository [docker.io/refirio/test]
682dac57ee22: Pushed
e91015d98cd4: Pushed
a8ada76173c3: Mounted from library/php
46a0f0111934: Mounted from library/php
d6da32e9bff2: Mounted from library/php
400f5ced50ab: Mounted from library/php
7485c1ee99c3: Mounted from library/php
b98c6acdec28: Mounted from library/php
86b5e34374f3: Mounted from library/php
c52f69d9a297: Mounted from library/php
c24f05541085: Mounted from library/php
82f581b09510: Mounted from library/php
3b7e206db54c: Mounted from library/php
575b147c7c31: Mounted from library/php
814bff734324: Mounted from library/php
0.1: digest: sha256:4ff22738d7b3a4fc343fb9d498f9c9e2d7d4d3f10086855f1db2daee8e957d80 size: 3449
以下などで確認すると、「Last pushed」が「2 minutes ago」などとなっている。
https://hub.docker.com/repository/docker/refirio/test
https://hub.docker.com/r/refirio/test
Docker Hubからログアウト。
$ docker logout
■イメージを利用
Docker Hubからの取得を確認できるようにするため、
「イメージを登録」でタグ付けしたイメージを以下で削除しておく。
$ docker image ls
$ docker image rm refirio/test:0.1
イメージを再取得。
$ docker container run --name dockerhub_test -v $PWD/docker/php_create_file/code:/var/www/html -p 80:80 -d refirio/test:0.1
… プッシュしたイメージから起動。
$ docker container exec -it dockerhub_test bash … phpコンテナのターミナルに接続。
# ls /root … テストファイルを確認する。
確認できたら、起動したコンテナは終了しておく。
$ docker container ls
$ docker container rm -f 6d668f84cbad
■削除
以下からタグごとにイメージを削除できる。
https://hub.docker.com/repository/docker/refirio/test/tags
■制限
Docker HubからのPullには回数制限が設けられているので注意。
制限は徐々に強化されているみたい?
Docker HubのPull回数制限はすでに始まっている - Qiita
https://qiita.com/zizi4n5/items/7b9676aa2cfc9c5679ae
Docker Hub の pull 回数制限について - Qiita
https://qiita.com/zettaittenani/items/8693c600b24baa426fa7
仕事用にプライベートリポジトリを作成するなら、今はAWSのECRを使う方がいいかも。
ECRを検証した時の内容は、AWS.txt の「Amazon Elastic Container Registry(Amazon ECR)」を参照。
[速報]AWS、Docker Hubの代替を狙う「Amazon Elastic Container Registry Public」提供開始。AWS re:Invent 2020 − Publickey
https://www.publickey1.jp/blog/20/awsdocker_hubamazon_elastic_container_registry_publicaws_reinvent_...
イメージを Docker Hub に保存(イメージの更新とlatestタグの指定)
■latestタグについて
以下で「refirio/test:0.1」を取得&起動できるとして、
$ docker container run --name dockerhub_test -v $PWD/docker/php_create_file/code:/var/www/html -p 80:80 -d refirio/test:0.1
以下のようにタグを指定せずに起動しようとすると、
「refirio/test:latest」を取得しようとして、かつ「そんなイメージは無い」というエラーになる。
$ docker container run --name dockerhub_test -v $PWD/docker/php_create_file/code:/var/www/html -p 80:80 -d refirio/test
Unable to find image 'refirio/test:latest' locally
docker: Error response from daemon: manifest for refirio/test:latest not found: manifest unknown: manifest unknown.
See 'docker container run --help'.
手動で「latest」というタグを付与してプッシュしておくことにより、
タグを指定しなかった場合に取得されるイメージを指定できる。
■latestタグの付与
以下でlatestタグを付与する。
$ docker image tag refirio/test:0.1 refirio/test:latest
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
refirio/test latest 780c832a5fcc 39 minutes ago 414MB
refirio/test 0.2 780c832a5fcc 39 minutes ago 414MB
そのままプッシュしてみる。
$ docker image push refirio/test:latest
以下で確認すると、「0.1」と「latest」のタグを確認できた。
https://hub.docker.com/r/refirio/test/tags?page=1&ordering=last_updated
以下でlatestタグの付いた refirio/test を削除できる。
$ docker image rm refirio/test
以下で refirio/test:latest を取得できる。(latest を明示的に指定しても同じ。)
$ docker container run --name dockerhub_test -v $PWD/docker/php_create_file/code:/var/www/html -p 80:80 -d refirio/test
■latestタグの更新
Dockerfile を以下のように編集。
FROM php:8.1-apache
RUN touch /root/test1.txt
RUN touch /root/test2.txt
イメージをビルド。
$ docker image build -t php:create_file docker/php_create_file
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
php create_file 780c832a5fcc 5 seconds ago 414MB
refirio/test latest 2f5eeeeb3991 26 hours ago 414MB
タグ付けしてプッシュ。
$ docker image tag php:create_file refirio/test:0.2
$ docker image push refirio/test:0.2
この状態で latest を再取得しても 0.2 よりも古い。
latestタグを上書きしてプッシュ。
$ docker image tag refirio/test:0.2 refirio/test:latest
$ docker image push refirio/test:latest
イメージを再取得。
$ docker image rm refirio/test:0.1
$ docker image rm refirio/test:0.2
$ docker image rm refirio/test:latest
$ docker container run --name dockerhub_test -v $PWD/docker/php_create_file/code:/var/www/html -p 80:80 -d refirio/test
最新の内容を取得できている。
イメージの連携(Apache + PHP + MySQL 環境の構築)
■MySQLのイメージを取得
※Apache+PHPのイメージにMySQLをインストール。
…という方法でも構築できるが、Dockerの場合は一般的に「Apache+PHPのイメージとMySQLのイメージを取得し、連携させる」のようにする。
$ docker container run --name mysql -e MYSQL_ROOT_PASSWORD=pass -d mysql:5.7 … MySQLのパスワードを「pass」にして起動。
$ docker container exec -it mysql bash … mysqlコンテナのターミナルに接続。
# mysql -u root -p … MySQLに接続。
$ docker container rm -f $(docker container ls -a -q) … 確認できたら終了。
「MYSQL_ROOT_PASSWORD」は環境変数と呼ばれるもの。これに値をセットすることで、コンテナに設定の指定を行うことができる。
環境変数は、コンテナのターミナルに接続して「env」と入力すれば一覧表示できる。
起動直後にMySQLにログインしようとすると、以下のエラーになることがある。
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
何度か試していると以下のエラーに変わることがある。
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
さらに何度か試しているとログインできた。その後は普通にアクセスできる。
MySQLが完全に起動するまでタイムラグがあるみたい。焦らずに1〜2分程度待つ。
Dockerの公式MySQLイメージの使い方を徹底的に解説するよ - DQNEO起業日記
http://dqn.sakusakutto.jp/2015/10/docker_mysqld_tutorial.html
■PHPとMySQLの連携(準備)
※Apache+PHPのイメージに、MySQLを扱うためのライブラリを追加する。
それを新しいイメージとして保存する。
Dockerfileを作成。
FROM php:8.1-apache
RUN apt-get update
RUN apt-get install -y libonig-dev
RUN docker-php-ext-install pdo_mysql mysqli mbstring
イメージをビルド。
$ docker image build -t php:custom docker/test/php … Dockerfileをもとに、新しいイメージをビルド。
$ docker image ls … 作成されたイメージを確認。
■PHPとMySQLの連携
※ネットワークを作成し、そこに参加させることでコンテナを連携させることができる。
※PHPコンテナ起動時に「--link mysql:mysql」のように指定することで、コンテナを連携させることもできる。が、それは古い方法で非推奨。
$ docker network ls … ネットワークを確認。はじめは3つ。
NETWORK ID NAME DRIVER SCOPE
620a2ccffb63 bridge bridge local
8b789d2d1514 host host local
16b9ed4aa1c6 none null local
$ docker network create my_network … ネットワーク「my_network」を作成。
$ docker network ls … ネットワークの追加を確認。
NETWORK ID NAME DRIVER SCOPE
620a2ccffb63 bridge bridge local
8b789d2d1514 host host local
2234c63a488d my_network bridge local
16b9ed4aa1c6 none null local
$ docker container run --net my_network --name mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7
… ネットワークを指定してMySQLコンテナを起動。
MySQLのパスワードは「pass」にして、データベース「test」を作成する。
$ docker container run --net my_network --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:custom
… ネットワークを指定してPHPコンテナを起動。
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# exit
$ docker container exec -it mysql bash … mysqlコンテナのターミナルに接続。
# mysql -u root -p … MySQLに接続。(パスワードは上で指定した「pass」を入力する。)
mysql> SHOW DATABASES; … testデータベースを確認。(「MYSQL_DATABASE=test」によって自動作成されている。)
mysql> CREATE DATABASE test; … 別途データベースを作成する場合。
mysql> QUIT;
docker/test/code(/var/www/html)内に適当なデータベース管理ツールを設置し、テーブルを作成&データ登録&表示をテスト。
http://www.php-labo.net/download/new/db_admin/ の場合、以下の接続情報でアクセスできた。
define('HTTP_URL', 'http://127.0.0.1/db_admin/');
define('ADMIN_PASSWORD', '1234');
define('DATABASE_TYPE', 'mysql');
define('DATABASE_HOST', 'mysql');
define('DATABASE_PORT', '');
define('DATABASE_USER', 'root');
define('DATABASE_PASSWORD', 'pass');
define('DATABASE_CHARSET', '');
define('DATABASE_NAME', 'test');
以下で登録テスト。
CREATE TABLE address(
no INT,
name VARCHAR(80),
tel VARCHAR(80)
);
INSERT INTO address(no, name, tel) VALUES(1, '山田太郎', '090-1234-5678');
INSERT INTO address(no, name, tel) VALUES(2, "山田花子", "090-2345-6789");
SELECT * FROM address;
※DATABASE_CHARSETを指定すると、データ登録時に
「Incorrect string value: '\xE5\xB1\xB1\xE7\x94\xB0...' for column 'name' at row 1」
のエラーになった。
$ docker container ls … コンテナを確認する場合。
$ docker container rm -f $(docker container ls -a -q) … コンテナを終了する場合。
■次回起動時
以下で起動する。
ファイル共有している以外のデータは削除されているので、テーブルの作成などは都度必要。
$ docker container run --net my_network --name mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7
$ docker container run --net my_network --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:custom
以下でアクセスできる。
http://127.0.0.1/
http://127.0.0.1/db_admin/
■MariaDB
一例だが、以下のようにイメージ名を変更すればMariaDBを使える。
MYSQL_ROOT_PASSWORD や MYSQL_DATABASE の設定項目は、原則同じ名前で同じように使えるみたい。
mysql:5.7
↓
mariadb:10.2
■Docker Compose
上記の方法はコンテナの数が増えると作業が複雑になる。
よって通常はDocker Composeを使用して管理する。
詳細は後述の「Docker Compose」を参照。
イメージの削除
以下のイメージがあるとする。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker_php latest 60dd49c01909 8 minutes ago 603MB
<none> <none> d292eab3dce7 4 days ago 603MB
<none> <none> a656156c0a2b 4 days ago 603MB
<none> <none> 33ce37dfdb33 4 days ago 603MB
<none> <none> c1ef894332bd 4 days ago 603MB
<none> <none> 7263119c7e17 4 days ago 603MB
<none> <none> d7736e2e65fc 4 days ago 414MB
<none> <none> b7ea7f94f833 4 days ago 603MB
<none> <none> 43b73c46dc15 4 days ago 603MB
<none> <none> 72dd023deba3 4 days ago 603MB
<none> <none> 8891c90f9e4b 4 days ago 603MB
<none> <none> 76a32ff5c3a5 4 days ago 603MB
<none> <none> 8d9bb844d512 5 days ago 614MB
<none> <none> b24d7823befb 5 days ago 613MB
test_php latest cf48df93a65d 5 days ago 603MB
<none> <none> b6e175038af3 5 days ago 599MB
<none> <none> d97cd6ded3b1 5 days ago 599MB
<none> <none> d07e102c50d4 5 days ago 612MB
<none> <none> 10f32240ac7f 5 days ago 483MB
<none> <none> 0f314af243a7 5 days ago 479MB
<none> <none> 5cff5db49f52 5 days ago 603MB
<none> <none> c47cc7bb154a 5 days ago 603MB
<none> <none> 2eeb0b38ae6b 5 days ago 469MB
<none> <none> 00395ae4f436 5 days ago 668MB
<none> <none> 8cf20ab9261b 5 days ago 566MB
<none> <none> adb4648095e3 5 days ago 804MB
<none> <none> cbd0da7691d3 5 days ago 809MB
<none> <none> 25b1e7007ed5 5 days ago 466MB
code_ec-cube latest 96a12f7e05cf 7 days ago 1.11GB
unicolle_ec-cube latest 96a12f7e05cf 7 days ago 1.11GB
<none> <none> 9f25ec1ecdd7 7 days ago 1.11GB
<none> <none> d324f1c84dac 9 days ago 1.08GB
<none> <none> 197c01a416f5 9 days ago 1.08GB
eccube_ec-cube latest f7b92d781afa 12 days ago 1.09GB
<none> <none> ce73334a9207 12 days ago 918MB
<none> <none> 9e66155efbe9 12 days ago 569MB
php 7.4-apache 93e55f680811 12 days ago 414MB
<none> <none> 66c0f082674c 13 days ago 420MB
postgres 10 07d80b49d8bc 2 weeks ago 200MB
docker_mysql latest 8cf625070931 2 weeks ago 448MB
mysql 5.7 8cf625070931 2 weeks ago 448MB
test_mysql latest 8cf625070931 2 weeks ago 448MB
php 7.3-apache-stretch 65f81adeb23e 2 weeks ago 375MB
php 7.3-apache 666b66927747 2 weeks ago 411MB
hello-world latest d1165f221234 5 months ago 13.3kB
php 8.1-apache 24c791995c1e 2 years ago 355MB
schickling/mailcatcher latest a92223e5253a 3 years ago 86.4MB
以下のようなエラーになって削除できないことがある。
$ docker image rm cf48df93a65d
Error response from daemon: conflict: unable to delete cf48df93a65d (cannot be forced) - image has dependent child images
$ docker image rm 8cf625070931
Error response from daemon: conflict: unable to delete 8cf625070931 (cannot be forced) - image has dependent child images
【docker】child imagesのせいでimageが消せなくてキレそうなあなたへ
https://zenn.dev/msickpaler/articles/607e562a52cf07
シェルスクリプトで対応する手もあるようだが、
今回は以下のように、「IMAGE ID」ではなく「REPOSITORY」を指定して削除できた。
$ docker image rm test_php
Untagged: test_php:latest
$ docker image rm test_mysql
Untagged: test_mysql:latest
それでも削除できないことがあったが、リポジトリとタグを指定して削除できた。
$ docker image rm public.ecr.aws/v0u7u3g9/base-nginx
Error: No such image: public.ecr.aws/v0u7u3g9/base-nginx
$ docker image rm public.ecr.aws/v0u7u3g9/base-nginx:1.0.3
Untagged: public.ecr.aws/v0u7u3g9/base-nginx:1.0.3
■REPOSITORYとTAGがnoneのイメージ
「<none>」のイメージが大量の残っている件について。
Dockerで none なイメージを一括で削除するワンライナー - Qiita
https://qiita.com/DQNEO/items/e3a03a14beb616630032
> docker pullを何回も叩いていると、ローカルのイメージが<none>になってしまうことがあります。
> <none>になる条件は、新しいイメージが既存のタグを再利用したときにそうなるようです。
> 古い方のイメージがタグを剥奪されるみたいな感じ。
Dockerに<none>:<none>なイメージが生まれてくる理由
https://suin.io/540
> <none>:<none>のイメージができるのは、同じ名前のイメージを作り直すのが原因です。Dockerでは異なるイメージに同じイメージ名を付けられません。
> この<none>:<none>のイメージのことをDockerではdangling imageと呼びます。基本的にコンテナがこのイメージを参照していなければ、不要なイメージとなるので削除してかまいません。
以下をもとに削除したこともあった。
docker imagesに表示される<none>を消す。dangling | codechord
https://codechord.com/2019/08/docker-images-none-dangling/
Docker imageが削除できない - Scribble
https://scribble.washo3.com/docker-cannot-image.html
Dockerのイメージを削除ができない時は「-f」オプションを使う - Qiita
https://qiita.com/jungissei/items/5907819063a177ac7c81
■不要なイメージを一括削除
Dockerの不要なコンテナ・イメージを一括削除する方法
https://suin.io/537
イメージを確認。
docker image ls
コンテナが使っていないイメージをすべて削除。
docker image prune
Docker Compose
docker container run で起動する場合、一度に起動すべきコンテナの数が多くなると管理しづらくなるので、Docker Compose で管理するといい。
これなら依存管理の手間が無くなり、さらに起動コードや関連ファイルを丸ごとGitで管理することもできる。
当初はシェルスクリプトを作成するなど独自に対応する必要があったが、
公式に手順が用意されたので人によっての方法の差異を防げるようになった。
docker-composeを使うと複数コンテナの管理が便利に - Qiita
https://qiita.com/y_hokkey/items/d51e69c6ff4015e85fce
検証時の docker-compose.yml のバージョンは3だったので、「version: '3'」と指定している。
必要に応じて「version: '3.8'」などバージョンを指定する。
Compose ファイル | Docker ドキュメント
https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/
■ファイルの準備
C:\Users\refirio\docker\ 内に以下を作成するとする。
(PHP+MySQLの環境を作る例。)
compose_test\html\index.php
<?php phpinfo() ?>
compose_test\docker\mysql\my.cnf
[mysqld]
character-set-server=utf8
compose_test\docker-compose.yml
version: '3'
networks:
my_network:
services:
mysql:
container_name: mysql
volumes:
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
environment:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: test
networks:
- my_network
image: mysql:5.7
php:
container_name: php
volumes:
- ./:/var/www
ports:
- 80:80
networks:
- my_network
image: php:custom
■起動
各ファイルを用意できたら以下で起動する。
$ cd docker/compose_test
$ docker-compose up … docker-compose.ymlをもとに起動。
画面にログが表示される。以下でストップした。
mysql | Version: '5.7.35' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
しばらく時間をおいてからブラウザから http://127.0.0.1/ にアクセスすると画面が表示され、以下のようなアクセスログが表示された。
php | 192.168.99.1 - - [16/Dec/2017:08:56:09 +0000] "GET / HTTP/1.1" 200 24541 "-" "Mozilla/5.0 以下略
Ctrl+C で終了できるが、コンテナも終了される。
「docker container exec -it php bash」のように接続したければ、バックグラウンドで起動する必要がある。
■起動(バックグラウンド)
$ cd docker/compose_test
$ docker-compose up -d … docker-compose.ymlをもとにバックグラウンドで起動。
$ docker container ls … コンテナを確認。
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# exit
$ docker container exec -it mysql bash … mysqlコンテナのターミナルに接続。
$ mysql -u root -p … testデータベースを作成する場合。
mysql> CREATE DATABASE test;
mysql> QUIT;
# exit
docker/compose_test/code(/var/www/html)内に適当なデータベース管理ツールを設置し、テーブルを作成&データ登録&表示をテスト。
http://www.php-labo.net/download/new/db_admin/ の場合、以下の接続情報でアクセスできた。
define('HTTP_URL', 'http://127.0.0.1/db_admin/');
define('ADMIN_PASSWORD', '1234');
define('DATABASE_TYPE', 'mysql');
define('DATABASE_HOST', 'mysql');
define('DATABASE_PORT', '');
define('DATABASE_USER', 'root');
define('DATABASE_PASSWORD', 'pass');
define('DATABASE_CHARSET', '');
define('DATABASE_NAME', 'test');
$ docker-compose down … コンテナを終了。
$ docker container rm -f $(docker container ls -a -q) … 「docker rm」でも終了できる。
データベースの永続化
データベースをファイル共有の対象にすれば、データの永続化ができる。
※後述の「トラブル代替案」ように、ファイル共有ではなくデータボリュームを使う方が良さそう。
ファイル共有だと、環境によっては正しく動作しなかった。
※docker-compose.ymlでrootパスワードなどを指定している場合、変更しても永続化済みのデータには影響しない。
つまり「何故かパスワードの変更が反映されない」となるので注意。
手動でパスワードなどを変更するか、永続化済みのデータを初期化するなどする。
※データベースを永続化していると、MySQLコンテナが完全に起動するまでの時間が短くなっているかも?
諸々のデータ作成が短縮できるから…かもしれない。
■docker container run の場合
※後述の「トラブル代替案」ように、ファイル共有ではなくデータボリュームを使う方が良さそう。
ファイル共有だと、環境によっては正しく動作しなかった。
-v $PWD/docker/test/data:/var/lib/mysql
を追加して起動する。
/var/lib/mysql を同期すれば、MySQLのデータを保持できる。
/docker/test/data フォルダはあらかじめ作成しておく。
$ docker container run --net my_network --name mysql -v $PWD/docker/test/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7
$ docker container run --net my_network --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:custom
■Docker Compose の場合
※後述の「トラブル代替案」ように、ファイル共有ではなくデータボリュームを使う方が良さそう。
ファイル共有だと、環境によっては正しく動作しなかった。
- ./database:/var/lib/mysql
を追加して起動する。意味は上と同じ。
compose_test\docker-compose.yml
version: '3'
networks:
my_network:
services:
mysql:
container_name: mysql
volumes:
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- ./docker/database:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: test
networks:
- my_network
image: mysql:5.7
php:
container_name: php
volumes:
- ./:/var/www
ports:
- 80:80
networks:
- my_network
image: php:custom
■ボリュームの削除(データベースの削除)
$ docker volume ls ... ボリュームを確認。
$ docker volume rm compose_mysql_data ... ボリュームを削除。
■トラブル
2018/01/06 にWindowsアップデートするとDockerが起動しなくなった。
再インストールで起動するようになったが、データベースの永続化ができないようになっていた。
Composeを使う使わないにかかわらず永続化できず、MariaDBの場合でも同じ。
「-d」なしで起動すると以下のようなエラーを確認できるが、原因不明のまま解決せず。
Windows側で権限管理やファイルシステムの仕様が変更されたとか?
$ docker container run --name mysql -v $PWD/docker/test/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test mysql:5.7
Initializing database
2018-01-06T17:47:41.143661Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2018-01-06T17:47:41.150773Z 0 [Warning] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
2018-01-06T17:47:41.627330Z 0 [ERROR] InnoDB: Operating system error number 22 in a file operation.
2018-01-06T17:47:41.627674Z 0 [ERROR] InnoDB: Error number 22 means 'Invalid argument'
2018-01-06T17:47:41.628023Z 0 [ERROR] InnoDB: File ./ib_logfile101: 'aio write' returned OS error 122. Cannot continue operation
2018-01-06T17:47:41.628357Z 0 [ERROR] InnoDB: Cannot continue operation.
次の手段へ。
データはbusyboxに保存するのが定番らしいので試す。
$ docker container run --net my_network --name storage -v /var/lib/mysql -d busybox
$ docker container run --net my_network --name mysql --volumes-from storage -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7
とすればmysqlのデータをbusyboxに保存できる。
が、mysqlコンテナを再起動してもデータは消えないが、busyboxを再起動するとデータが消える。
よってbusyboxからエクスポート&インポートする必要があるが、それだとmysqlをデータ同期無しで使っている状態と変わらない。
次の手段へ。
コンテナとローカルでデータ転送ができるらしいので試す。
以下のようにすればデータ転送ができる。
コンテナからローカルへ。
$ docker container cp mysql:/var/lib/mysql /Users/refirio/docker/backup … 絶対パスの場合。
$ docker container cp mysql:/var/lib/mysql ./docker/backup … 相対パスの場合。
ローカルからコンテナへ。
$ docker container cp /Users/refirio/docker/backup mysql:/var/lib/mysql … 絶対パスの場合。
$ docker container cp ./docker/backup mysql:/var/lib/mysql … 相対パスの場合。
が、ローカルからコンテナに転送すると所有者がrootになる。chownで所有者を変更してもmysqlからは読み込めなかった。
権限なども調整が必要かも。
非常に面倒なので、phpMyAdminのようなツールでエクスポート&インポートする方が現実的。
つまりは実質、データベースは永続化せずに作業する状態となり、かなり面倒。
■トラブル代替案
ホストの特定のパスではなく、データボリュームになら保存できた。
むしろ、ファイルシステムや権限の問題を回避するためにも、データボリュームを使う方がいいみたい。
データボリュームに保存したデータベースをバックアップしたければ、phpMyAdminなどのツールを使う。
dockerコマンドから起動する場合。(「mysql_data」に保存。)
$ docker volume ls ... ボリュームを確認。
$ docker volume create --name mysql_data ... 明示的に作成できるが省略可。
$ docker container run --net my_network --name mysql -v mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7
$ docker container exec -it mysql bash
$ mysql -u root -p
Docker Compose から起動する場合、以下のように指定する。(「compose_mysql_data」に保存する場合。)
services:
mysql:
container_name: mysql
volumes:
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- compose_mysql_data:/var/lib/mysql
ボリュームの削除は以下のようにする。
$ docker volume ls ... ボリュームを確認。
$ docker volume rm compose_mysql_data ... ボリュームを削除。
Dockerのデータ永続化関連について - Qiita
https://qiita.com/onokatio/items/fcc9f8f94f8533bb030a
dockerのデータボリュームとそのバックアップ方法 - Qiita
https://qiita.com/74th/items/41393f506d223850f2c3
Docker Data Volume を理解する - Carpe Diem
http://christina04.hatenablog.com/entry/2016/05/04/134323
データベースのバックアップ
■結論
以下のようにして、docker container cp を挟めばバックアップとリストアができた。
以下でバックアップ。
$ docker container exec -it mysql bash
# mysqldump -u dbuser -p eccubedb --default-character-set=binary --no-tablespaces > /tmp/eccubedb_20210804.sql
# exit
$ docker container cp mysql:/tmp/eccubedb_20210804.sql eccubedb_20210804.sql
以下でリストア。
$ docker container cp eccubedb_20210804.sql mysql:/tmp/eccubedb_20210804.sql
$ docker container exec -it mysql bash
$ mysql -u dbuser -p eccubedb --default-character-set=binary < /tmp/eccubedb_20210804.sql
ただしmysqlコンテナの /tmp の内容は、コンテナの終了によって消えてしまうので注意。
■試行錯誤メモ
一例だが以下のようにすれば、MySQLのコンテナに接続できる。
$ docker container exec -it code_mysql_1 bash
$ mysql -u dbuser -p
secret
ただし以下のように別コンテナ内から接続しようとしても、mysqlコマンドが存在しない可能性がある。
$ docker container exec -it code_ec-cube_1 bash
# mysql -u dbuser -p
bash: mysql: command not found
# mysql -h mysql -u dbuser -p
bash: mysql: command not found
このような場合、mysqlコマンドの追加インストールなしにデータベースのバックアップとリストアができるか。
ローカルから直接Dockerのデータベースを操作する - Qiita
https://qiita.com/mgmgmogumi/items/119e1e26fe44955c705e
以下でコンテナ外から、直接データベースに接続できた。
$ docker container exec -it code_mysql_1 mysql -u dbuser -p
secret
$ docker container exec -it code_mysql_1 mysqldump -u dbuser -p eccubedb --default-character-set=binary > /home/refirio/docker/myshop/code/eccubedb_20210804.sql
secret
ただしこの方法だと、エクスポートはできるがインポートができない。
以下の方法は一応インポートできそうだが、今回は「-bash: /usr/bin/docker: Argument list too long」となった。
catで展開するので、データサイズが大きすぎるのだと思われる。
$ docker container exec -it code_mysql_1 mysql -u dbuser -p eccubedb -e"$(cat eccubedb_20210804.sql)"
対策として、docker container cp でSQLファイルをコンテナ内部と外部でやりとりする方法がある。
具体的な方法は、前述の「結論」を参照。
dockerのmysqlにダンプファイルをインポートする | かぴトラベル
https://kapi-travel.com/programing/docker%E3%81%AEmysql%E3%81%AB%E3%83%80%E3%83%B3%E3%83%97%E3%83%95...
Dockerでホストとコンテナ間でのファイルコピー - Qiita
https://qiita.com/gologo13/items/7e4e404af80377b48fd5
プロジェクト名の指定
■プロジェクト名を指定しない場合の問題
例えば eccube4/code フォルダ内でECCubeを起動すると、以下のようになる。
つまり、フォルダ名である code をプレフィックスとして、各ボリュームが作られる。
$ docker volume ls
DRIVER VOLUME NAME
local code_mailcatcher-data
local code_mysql-database
local code_node_modules
local code_pg-database
local code_var
local code_vendor
local docker_compose_mysql_data
コンテナ名も、フォルダ名である code をプレフィックスとして作られる。
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------------------------------------
code_ec-cube_1 docker-php-entrypoint apac ... Up 0.0.0.0:443->443/tcp,:::443->443/tcp,
0.0.0.0:80->80/tcp,:::80->80/tcp
code_mailcatcher_1 mailcatcher --no-quit --fo ... Up 0.0.0.0:1025->1025/tcp,:::1025->1025/tcp,
0.0.0.0:1080->1080/tcp,:::1080->1080/tcp
code_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:13306->3306/tcp,:::13306->3306/tcp, 33060/tcp
code_postgres_1 docker-entrypoint.sh postgres Up 0.0.0.0:15432->5432/tcp,:::15432->5432/tcp
この状態で例えば myshop/code 内で別案件用にECCubeを起動すると、やはりプレフィックスは code になる。
つまり eccube4/code 内のECCubeと myshop/code 内のECCubeで、データベースなどは共通のものが参照されてしまう。
■プロジェクト名の指定
dockerでプロジェクト名を指定する - Qiita
https://qiita.com/reflet/items/b7b384d202a9f5514fb3
Docker Compose の -p オプションで VS Code でのコンテナ管理を便利にする / Twin Turbo Computing
https://tt-computing.com/docker-project-vscode
通常以下のようにして起動するが、
$ docker-compose up -d
以下のようにして起動&終了すると、プロジェクト名を指定して起動できる。
(終了時も同様に指定する必要があるので注意。)
$ docker-compose -p myshop up -d
$ docker-compose -p myshop down
「-p プロジェクト名」もしくは「--project-name プロジェクト名」とする。
これで以下のように、プロジェクト名をプレフィックスとして各ボリュームが作成される。
$ docker volume ls
DRIVER VOLUME NAME
local code_mailcatcher-data
local code_mysql-database
local code_node_modules
local code_pg-database
local code_var
local code_vendor
local docker_compose_mysql_data
local myshop_mailcatcher-data
local myshop_mysql-database
local myshop_node_modules
local myshop_pg-database
local myshop_var
local myshop_vendor
コンテナ名もプロジェクト名をプレフィックスとして作られるため、一例だが以下のように接続する。
$ docker container exec -it myshop_ec-cube_1 bash
$ docker container exec -it myshop_mysql_1 bash
ただし、DockerデスクトップをGUIで起動した場合など、プロジェクト名の指定が困難な場合がある。
また単純に、プロジェクト名を付け忘れると意図しない挙動になる可能性がある。
よってそもそもプロジェクト名を指定しなくてもいいように、
以下のように「docker-compose.yml はプロジェクトごとのフォルダ直下に置く」とするのが無難そうではある。
docker/project1/docker-compose.yml
docker/project2/docker-compose.yml
docker/project3/docker-compose.yml
docker-compose.ymlはプロジェクトRoot直下に置くか、Dir名を工夫しよう | DevelopersIO
https://dev.classmethod.jp/articles/docker-compose-yml-dir/
読み書きの制限
以下のように「:ro」を付けてボリュームを指定すると、読み込み専用(Read-Only)になる。
- ..:/var/www:ro
以下のように「:rw」を付けてボリュームを指定すると、読み書き可能(Read-Write)になる。
- ./database:/var/lib/mysql:rw
ファイル共有で一部を除外
以下のようにすれば、共有の除外になるみたい。
プログラムはファイル共有したいが、PHPのvenderは各々の環境で作らせたい。のような場合に活用できそう。
volumes:
- ./server:/home/app/nodeapp
- /home/app/nodeapp/node_modules
- www:/home/app/nodeapp/out
Dockerでnginx+node.jsのSPA構成を試す - Qiita
https://qiita.com/KeitaMoromizato/items/bfc3e22dae47211eff4f
Docker Compose と Dockerfile の併用
例えば以下のファイルを作成しておく。
compose_test\docker\php\Dockerfile
FROM php:custom
RUN touch /root/test1.txt
RUN touch /root/test2.txt
compose_test\docker-compose.yml の最後を以下のように修正すると、phpフォルダ内のDockerfileから起動されるようになる。
image: php:custom
↓
build: ./docker/php
Docker Compose の内容を一部上書き
docker-compose.yml と同じ場所に docker-compose.override.yml を置くと、起動時に自動で読み込まれる。
docker-compose.override.yml に設定を書いておくと、その部分が上書きして利用される。
「プロジェクト共通の docker-compose を使うが、一部の設定を手元の開発環境に合わせて変更したい」
という場合に利用できる。
例えば以下の内容を記述しておくと、作成されるデータベースの名前が test から test2 に変更される。
version: '3'
services:
mysql:
environment:
MYSQL_DATABASE: test2
サービスの拡張と Compose ファイル - Docker-docs-ja 17.06.Beta ドキュメント
http://docs.docker.jp/compose/extends.html
値のやりとり
■environment
docker-compose.yml にて以下のように指定すると、
environment:
TZ: Asia/Tokyo
phpinfo() では以下が表示されている。
Environment
TZ: Asia/Tokyo
PHP Variables
$_ENV['TZ']: Asia/Tokyo
date
Default timezone: Asia/Tokyo
date.timezone: Asia/Tokyo
この値は自由に定義することができ、その内容は環境変数として取得できる。
具体的には docker-compose.yml にて以下のように指定すると、
environment:
TZ: Asia/Tokyo
TEST_VALUE1: TEST
TEST_VALUE2: TEST MESSAGE
TEST_VALUE3: "This is a test message!"
phpinfo() では以下が表示された。
Environment
TZ: Asia/Tokyo
TEST_VALUE1: TEST
TEST_VALUE2: TEST MESSAGE
TEST_VALUE3: This is a test message!
PHP Variables
$_ENV['TZ']: Europe/Rome
$_ENV['TEST_VALUE1']: TEST
$_ENV['TEST_VALUE2']: TEST MESSAGE
$_ENV['TEST_VALUE3']: This is a test message!
また、PHPプログラム内で以下のようにすると、
<p>TEST_VALUE1: <?php echo $_ENV['TEST_VALUE1'] ?></p>
<p>TEST_VALUE2: <?php echo $_ENV['TEST_VALUE2'] ?></p>
<p>TEST_VALUE3: <?php echo $_ENV['TEST_VALUE3'] ?></p>
以下のように各値を取得できた。
TEST_VALUE1: TEST
TEST_VALUE2: TEST MESSAGE
TEST_VALUE3: This is a test message!
日本語も扱えるが、その場合は docker-compose.yml の文字コードをUTF-8Nにしておく必要がある。
■.env
docker-compose.yml にて以下のように指定すると、
environment:
TZ: Asia/Tokyo
TEST_VALUE1: TEST
TEST_VALUE2: テストメッセージ!
TEST_VALUE3: "This is a test message!"
TEST_VALUE4: ${SAMPLE_VALUE4}
TEST_VALUE5: ${SAMPLE_VALUE5}
TEST_VALUE4 と TEST_VALUE5 の内容は、docker-compose.yml と同階層に置いた .env で以下のように指定できる。
SAMPLE_VALUE4=TEST
SAMPLE_VALUE5="メッセージ"
さらに docker-compose.yml にて以下のように指定すると
TEST_VALUE6: ${SAMPLE_VALUE6:-XXX}
TEST_VALUE7: ${SAMPLE_VALUE7-YYY}
.env で値が未設定またはカラの場合に「XXX」が、
.env で値が未設定の場合に「YYY」が、
それぞれのデフォルト値として使用される。
つまり、.env はデフォルト値の定義場所として使用できる。
案外知られてないdocker-composeの環境変数定義の記法 - Qiita
https://qiita.com/fagai/items/b944950b26af19453c02
■secrets
※ファイルを参照できなかった。
改めて検証したい。
environment や .env の方法で機密情報を渡すと、環境変数に値が現れるので意図しない値の流出が起こりえる。
開発環境で使う分には問題無いが、本番環境では問題になる。
機密情報は secrets の仕組みで渡す必要があるらしい。
Docker Composeの環境変数ではなくsecretsで秘密情報を扱う - Qiita
https://qiita.com/myabu/items/89797cddfa7225ff2b5d
Docker/Docker ComposeのSecretsを試す - そんな今日この頃の技術ネタ
https://blue1st-tech.hateblo.jp/entry/2017/08/27/230546
以下は機密情報を環境変数で扱おうとしている?
Dockerコンテナのクレデンシャル設計パターン | DevelopersIO
https://dev.classmethod.jp/articles/creds-design-pattern-in-docker/
以下も参考になるか。
docker secretsの部分的導入 | WordPress試用
https://elephantcat.work/2021/10/15/post-1020/
以下によると、暗号化して環境変数に展開するくらいしかなかった?
ECSの場合はマネージドな仕組みに任せることができそうだが、ECSを使わない場合は簡単では無い問題かもしれない。
ECSでごっつ簡単に機密情報を環境変数に展開できるようになりました! | DevelopersIO
https://dev.classmethod.jp/articles/ecs-secrets/
まとめ
PHP+MySQLの環境を作る例。
■ファイルの作成
C:\Users\refirio\docker\ 内に以下を作成するとする。
apache_php8_mysql\html\index.php
<?php phpinfo() ?>
apache_php8_mysql\docker\mysql\Dockerfile
FROM mysql:5.7
apache_php8_mysql\docker\mysql\my.cnf
[mysqld]
character-set-server=utf8
apache_php8_mysql\docker\php\Dockerfile
FROM php:8.1-apache
RUN apt-get update
RUN apt-get install -y libonig-dev
RUN docker-php-ext-install pdo_mysql mysqli mbstring
apache_php8_mysql\docker\php\php.ini
date.timezone = Asia/Tokyo
apache_php8_mysql\docker-compose.yml
version: '3'
networks:
compose_network:
volumes:
compose_mysql_data:
services:
mysql:
container_name: mysql
volumes:
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
- compose_mysql_data:/var/lib/mysql:rw
environment:
TZ: Asia/Tokyo
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_USER: user
MYSQL_PASSWORD: userpass
MYSQL_DATABASE: test
networks:
- compose_network
build: ./docker/mysql
php:
container_name: php
volumes:
- ./docker/php/php.ini:/usr/local/etc/php/conf.d/php.ini:ro
- ./:/var/www:rw
environment:
TZ: Asia/Tokyo
ports:
- 80:80
networks:
- compose_network
build: ./docker/php
■設定の上書き
docker-compose.yml と同じ階層に docker-compose.override.yml を置くと、その設定内容が優先される。
以下の場合、MySQLのユーザ情報が「user / userpass」から「test / testpass」に変更される。
apache_php8_mysql\docker-compose.override.yml
version: '3'
services:
mysql:
environment:
MYSQL_USER: test
MYSQL_PASSWORD: testpass
■よく使用するコマンド
$ cd docker/apache_php8_mysql
$ docker-compose build … ビルドする場合。(構成を変更した場合など。)
$ docker-compose up -d … 起動。
$ docker-compose down … 終了。
$ docker container exec -it php bash … phpコンテナのターミナルに接続する場合。
$ docker container exec -it mysql bash … mysqlコンテナのターミナルに接続する場合。
$ mysql -u root -p … MySQLに接続。
$ docker volume ls ... ボリュームを確認。
$ docker volume rm compose_mysql_data ... ボリュームを削除。
■ブラウザからのアクセス
http://127.0.0.1/
また以下のようなコードで、PHPからMySQLに接続できる。
エラーになる場合、mysqlコンテナの起動が完了していない可能性があるので待つ。
<?php
try {
$pdo = new PDO(
'mysql:dbname=test;host=mysql',
'test',
'testpass'
);
$stmt = $pdo->query('SELECT NOW() AS now;');
$data = $stmt->fetch(PDO::FETCH_ASSOC);
echo "<p>" . $data['now'] . "</p>\n";
$pdo = null;
} catch (PDOException $e) {
exit($e->getMessage());
}
コマンドまとめ
■docker
# 起動しているコンテナを一覧
docker container ls
# 起動しているコンテナを終了
docker container rm -f XXXXXXXXXX
# 起動しているコンテナを一括終了
docker container rm -f $(docker container ls -a -q)
# 取得したイメージを一覧
docker image ls
# イメージを削除
$ docker image rm XXXXXXXXXX
# イメージを一括削除
docker image rm `docker image ls | sed -ne '2,$p' -e 's/ */ /g' | awk '{print $1":"$2}'`
# 作成したボリュームを一覧
docker volume ls
# 作成したボリュームを削除
docker volume rm XXXXXXXXXX
# 未使用ボリュームを一括削除
docker volume prune
# 作成したネットワークを一覧
docker network ls
# 作成したネットワークを削除
docker network rm XXXXXXXXXX
# 未使用ネットワークを一括削除
docker network prune
■docker-compose
# イメージをまとめてプル
docker-compose pull
# イメージをまとめてビルド。イメージがローカルになければプル
docker-compose build
# キャッシュを無視して、イメージをまとめてビルド
docker-compose build --no-cache
# 関係するコンテナを起動
docker-compose up -d
# キャッシュを無視して、関係するコンテナを起動
docker-compose up -d --build
# 関係するコンテナすべてのログを出力
docker-compose logs
# 関係するコンテナをすべて停止
docker-compose stop
# 関係するコンテナをすべて削除
docker-compose rm
# 関係するコンテナをすべて再起動
docker-compose restart
# 関係するコンテナをすべて停止して削除
docker-compose down
# プロジェクト名を指定して起動&終了
$ docker-compose -p myshop up -d
$ docker-compose -p myshop down
■その他
# llを使用する(コンテナ内でエイリアスを設定する場合の例)
alias ll="ls -l"
# Vimを使用する(コンテナ内でインストールする場合の例)
apt-get update
apt-get install vim
その他の環境構築例
■nginx+PHP7(Laravelの使用例)
※Laradockによる開発環境構築は「Laradockによる開発環境構築」を参照。
※あらかじめ、nginx+PHP7でURLルーティングありで http://127.0.0.1/ にアクセスできるところまで構築しておく。
phpコンテナで作業。(nginxコンテナではPHPを使えない。)
$ docker container exec -it php bash
Programming.txt の内容をもとに、Composerをインストール&動作確認。
# composer
さらに関連ツールをインストール。
# apt-get install git
# apt-get install zip unzip
上記作業はDockerを再起動しても保持されていたが、いったん停止してから起動すると消えていた。
docker/php/Dockerfile
に記載しておく方が良さそう。(要検証。)
composerでLaravelをインストール。
create-projectを実行した際。
Do not run Composer as root/super user! See https://getcomposer.org/root for details
と表示されるが、開発環境なので気にせず進めた。(しばらく放置すると進んだ。)
# mkdir /var/www/vhosts
# cd /var/www/vhosts
# composer create-project --prefer-dist laravel/laravel blog
インストール完了後、ドキュメントルートをLaravelのものに変更。
C:\Users\Refirio\docker\laravel\docker\nginx\nginx.conf
root /var/www/html;
↓
root /var/www/vhosts/blog/public;
Dockerを再起動。
# exit
$ docker-compose restart
以下にアクセスすると、Laravelの画面が表示される。
http://127.0.0.1/
以降は動作確認。要点のみ。
日本語化などを試す。
$ docker container exec -it php bash
# cd ../blog
# composer require laravel-ja/comja5
# vendor/bin/comja5
# vendor/bin/comja5 -c
# vendor/bin/comja5 -f
データベースへのアクセスを試す。あらかじめ、mysqlコンテナ側でデータベースを作成し、userがアクセスできるようにしておく。
$ docker container exec -it mysql bash
> CREATE DATABASE `laravel-blog` CHARACTER SET utf8mb4;
> GRANT ALL PRIVILEGES ON `laravel-blog`.* TO user IDENTIFIED BY 'userpass';
phpコンテナからマイグレーションを試す。
$ docker container exec -it php bash
# php artisan migrate
Laravelの基本機能は使えているみたい。
はじめてのLaravel5+Docker - Qiita
https://qiita.com/kukimo/items/c044ad42fffac062e2f5
以下も参考になりそう。
最強のLaravel開発環境をDockerを使って構築する【新編集版】 - Qiita
https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4
■PHP+PostgreSQL
C:\Users\refirio\docker\ 内に以下を作成するとする。
apache_php8_postgresql\html\index.php
<?php phpinfo() ?>
apache_php8_postgresql\docker\php\Dockerfile
FROM php:8.1-apache
RUN apt-get update
RUN apt-get install -y libonig-dev libpq-dev
RUN docker-php-ext-install pdo_pgsql mbstring
apache_php8_postgresql\docker\php\php.ini
date.timezone = Asia/Tokyo
apache_php8_postgresql\docker\postgresql\Dockerfile
FROM postgres:9.2
apache_php8_postgresql\docker-compose.yml
version: '3'
networks:
compose_network:
volumes:
compose_postgresql_data:
services:
postgresql:
container_name: postgresql
volumes:
- compose_postgresql_data:/var/lib/postgresql/data:rw
environment:
TZ: Asia/Tokyo
POSTGRES_USER: user
POSTGRES_PASSWORD: userpass
POSTGRES_DB: test
networks:
- compose_network
build: ./docker/postgresql
php:
container_name: php
volumes:
- ./docker/php/php.ini:/usr/local/etc/php/conf.d/php.ini:ro
- ./:/var/www:rw
environment:
TZ: Asia/Tokyo
ports:
- 80:80
networks:
- compose_network
build: ./docker/php
以下のように起動する
$ cd docker/apache_php8_postgresql
$ docker-compose build … ビルドする場合。(構成を変更した場合など。)
$ docker-compose up -d … 起動。
$ docker-compose down … 終了。
$ docker container exec -it php bash … phpコンテナのターミナルに接続する場合。
$ docker container exec -it postgresql bash … postgresqlコンテナのターミナルに接続する場合。
root@bca889e7662a:/# psql -U user test … PostgreSQLに接続。(「psql -l」だと「role "root" does not exist」というエラーになる。)
psql (9.2.23)
Type "help" for help.
test=# CREATE TABLE test(no INT, name TEXT);
test=# INSERT INTO test VALUES(1, 'Taro');
test=# INSERT INTO test VALUES(2, 'Hanako');
test=# SELECT * FROM test LIMIT 100;
no | name
----+--------
1 | Taro
2 | Hanako
(2 rows)
test=# \q
http://127.0.0.1/
以下のようなコードで、PHPからPostgreSQLに接続できる。
エラーになる場合、postgresqlコンテナの起動が完了していない可能性があるので待つ。
<?php
try {
$pdo = new PDO(
'pgsql:dbname=test;host=postgresql',
'user',
'userpass'
);
$stmt = $pdo->query('SELECT NOW() AS now;');
$data = $stmt->fetch(PDO::FETCH_ASSOC);
echo "<p>" . $data['now'] . "</p>\n";
$pdo = null;
} catch (PDOException $e) {
exit($e->getMessage());
}
PHPからPostgreSQLに接続し、以下のコードで動作確認を行う。
CREATE TABLE test(no INT, name TEXT);
INSERT INTO test VALUES(1, '山田タロウ');
INSERT INTO test VALUES(2, '山田ハナコ');
SELECT * FROM test;
[備忘録]Dockerでapache+php+postgresql環境 - Qiita
https://qiita.com/cyclon2joker/items/39e620d3d16fa1f6edf0
■nginx+Node.js
C:\Users\refirio\docker\ 内に以下を作成するとする。
(common.css はテストで作成しているのみで、他から参照されていない。node.jsからMySQLへの接続は未確認。)
nginx_node\html\css\common.css
@charset "utf-8";
body {
line-height: 1.4;
margin: 0 auto;
padding: 10px 20px;
background-color: #FFFFFF;
color: #000000;
font-size: 80%;
font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, "MS Pゴシック", sans-serif;
}
nginx_node\docker\mysql\Dockerfile
FROM mysql:5.7
nginx_node\docker\mysql\my.cnf
[mysqld]
character-set-server=utf8
nginx_node\docker\nginx\Dockerfile
FROM nginx:1.12
nginx_node\docker\nginx\nginx.conf
server {
listen 80 default_server;
server_name _;
index index.php index.html;
root /var/www/html;
sendfile off;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://node:3000/;
}
location ~ .*\.(jpg|JPG|gif|GIF|png|PNG|swf|SWF|css|CSS|js|JS|inc|INC|ico|ICO) {
}
}
nginx_node\docker\node\Dockerfile
FROM node:8.4
nginx_node\docker\node\server.js
const http = require('http');
const port = 3000;
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World!\n');
}).listen(port);
console.log('Server running at port ' + port + '.');
nginx_node\docker-compose.yml
version: '3'
networks:
compose_network:
volumes:
compose_mysql_data:
services:
mysql:
container_name: mysql
volumes:
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
- compose_mysql_data:/var/lib/mysql:rw
environment:
TZ: Asia/Tokyo
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_USER: user
MYSQL_PASSWORD: userpass
MYSQL_DATABASE: test
networks:
- compose_network
build: ./docker/mysql
node:
container_name: node
volumes:
- ./docker/node:/var/nodeapp:rw
command: node /var/nodeapp/server.js
environment:
TZ: Asia/Tokyo
PORT: 3000
ports:
- 3000:3000
networks:
- compose_network
build: ./docker/node
nginx:
container_name: nginx
volumes:
- ./docker/nginx/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro
- ./:/var/www:rw
environment:
TZ: Asia/Tokyo
ports:
- 80:80
networks:
- compose_network
build: ./docker/nginx
以下のように起動する
$ cd docker/nginx_node/docker
$ docker-compose build
$ docker-compose up -d
http://127.0.0.1:3000/ ... node.js
http://127.0.0.1/ ... nginx経由でnode.js
■Node.js(Docker Compose なしで単体起動する場合)
dockerコンテナ上でnode.jsのサーバを起動し、ホスト端末からアクセスする - Qiita
https://qiita.com/hotdrop_77/items/a2ca316c97ba4b748d9a
docker\node\server.js
const http = require('http');
const port = 3000;
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World.\n');
}).listen(port);
console.log('Server running at port ' + port + '.');
以下のように起動する。
$ docker container run -v docker/node:/var/nodeapp -p 3000:3000 -it node:8.4.0 /bin/bash
# node /var/nodeapp/server.js
http://127.0.0.1:3000/ でアクセスできる。
# node /var/nodeapp/server.js
の代わりに以下も有効?
# cd /var/nodeapp
# node server.js &
curl localhost:3000
# exit
$ docker container rm -f $(docker container ls -a -q)
上記手順で起動できた。
以下は本番環境での稼働手順の参考に。
AWS EC2でNodeを動作させる - Qiita
https://qiita.com/oishihiroaki/items/bc663eb1282d87c46e97
Cronでの定期実行
※未検証。
ホスト側でCronを設定し、ログもホスト側に記録されるようにするのが無難か。
ホスト側のCronで docker run する - Qiita
https://qiita.com/acro5piano/items/a9ec64f78e7da304a661
[Docker] ホストマシンのcronからコンテナ内のphpコマンドを実行する │ M0DE
https://www.m0de.ml/c0d3man/posts/k78e5r2n1cty0ygv3ie5
Dockerコンテナをホスト側のcronで実行する - 202号室の手記
http://paperlefthand.hateblo.jp/entry/2017/06/14/214834
ただし以下ページの解説では「起動用スクリプトから起動しています」のように紹介されているので、すんなり実行できるかどうかは要検証。
Docker + Cron環境を実現する3つの方法 - Qiita
https://qiita.com/YuukiMiyoshi/items/bb7f14436d60d4bd8a8b
以下はDocker内で行う例。
ログの出力などに問題が無いかは要確認。
Dockerを用いたcronでの定時処理 - Qiita
https://qiita.com/midoribi/items/496dcb6f8307ce7e2af0
ECSを使う場合、EC2側のCronから定期実行したりはできないはず。
専用の仕組みは用意されているみたい。
AWS ECSを使ったバッチサーバ環境を試してみる - Qiita
https://qiita.com/pokotyan/items/36ab249db0e8aeb16e76
Amazon ECS ScheduledTaskで実現するスマートなDockerベースのバッチ実行環境 - コネヒト開発者ブログ
https://tech.connehito.com/entry/2017/09/13/171914
Amazon ECS でタスクをスケジューリングして定期的に実行する
https://www.ritolab.com/entry/222
Laradockによる開発環境構築
Homesteadは必要なものが揃った開発環境だが、実運用ではこんな多機能なサーバを用意することはまず無い。
本番環境に近づけた開発環境を用意できるように、Docker用の環境が提供された。
Laradockを使ってLaravel 5.5環境を構築する - Qiita
https://qiita.com/rock619/items/62c2ab2252c405e26479
Laravel使った開発にLaradockを使うというのはどうだろう - Qiita
https://qiita.com/niisan-tokyo/items/d4485b8bb4fbfcfcc6be
■前提
・docker/laravel を作業ディレクトリとする。(ここが共有ディレクトリとして設定される。)
・docker/laravel/laradock にLaradockをインストールするものとする。
・docker/laravel/blog にプロジェクトをインストールするものとする。(複数プロジェクトがあれば、同階層に作成する。)
・MySQLはデフォルトで8が使用されるが、セキュリティが強化されて扱いづらいので5.7に変更して使用する。
【Docker】MySQL8.0系を使う時に発生する問題について - websandbag ブログ
http://blog.websandbag.com/entry/2018/05/17/121730
■Laradockの起動
$ cd docker/laravel
$ git clone https://github.com/laradock/laradock.git docker/laravel/laradock … Laradockの入手。
$ cd laradock
$ cp env-example .env … .envファイル(Laradockの設定ファイル)の作成。
Laradock の .env を編集。(MySQLのバージョンを5.7にする。)
MYSQL_VERSION=latest
↓
MYSQL_VERSION=5.7
以下のように起動する。
$ docker-compose up -d nginx mysql workspace phpmyadmin … コンテナの初期化。(初回は非常に時間がかかる。)
$ docker container ls
http://127.0.0.1/
(この時点では「404 Not Found」と表示される。)
■Laravelの起動
workspaceコンテナからLaravelを操作できる。
これはcomposerやnodeなど、Laravelに必要なツール一式が格納されたコンテナ。
$ docker-compose exec --user=laradock workspace bash … 仮想環境へログイン。
$ composer create-project --prefer-dist "laravel/laravel=5.5.*" blog … Laravelをインストール。
$ exit … 仮想環境をいったん抜ける。
Laradock の .env を編集。(公開ディレクトリをblog内のpublicにする。)
APP_CODE_PATH_HOST=../
↓
APP_CODE_PATH_HOST=../blog
$ docker-compose stop … 仮想環境を再起動。(いったん停止させてから起動。)
$ docker-compose up -d nginx mysql workspace phpmyadmin
$ docker-compose exec --user=laradock workspace bash … 仮想環境へ再度ログインする場合。
$ php artisan --version
■PHPからMySQLへの接続
いったんPure-PHPでMySQLへの接続を検証してみる。
/var/www/public/mysql.php
<?php
try {
$pdo = new PDO(
'mysql:dbname=blog;host=mysql',
'laradock',
'secret'
);
$stmt = $pdo->query('SELECT NOW() AS now;');
$data = $stmt->fetch(PDO::FETCH_ASSOC);
echo "<p>" . $data['now'] . "</p>\n";
$pdo = null;
} catch (PDOException $e) {
exit($e->getMessage());
}
実行すると以下のエラーになる。(この時点では、laradockユーザもblogデータベースも作っていないので当然。)
SQLSTATE[HY000] [1045] Access denied for user 'laradock'@'172.20.0.6' (using password: YES)
以下のように、MySQLコンテナでユーザを作成するとアクセスできるようになる。
$ docker-compose exec mysql bash
# mysql -u root -p
root
> CREATE USER 'laradock'@'172.20.0.6' IDENTIFIED BY 'secret';
> GRANT ALL PRIVILEGES ON blog.* TO laradock;
> CREATE DATABASE blog DEFAULT CHARACTER SET utf8mb4;
■phpMyAdminの利用
以下にphpMyAdminがある。
http://127.0.0.1:8080/
サーバ: mysql
ユーザ名: laradock
パスワード: secret
ログインしようとすると以下のエラーになる。(phpMyAdminコンテナからの接続設定をしていないため。)
mysqli_real_connect(): (HY000/1045): Access denied for user 'laradock'@'172.20.0.5' (using password: YES)
ユーザを作成するとアクセスできるようになる。
> CREATE USER 'laradock'@'172.20.0.5' IDENTIFIED BY 'secret';
■LaravelからMySQLへの接続
マイグレーションしようとすると以下のエラーになる。(workspaceコンテナからの接続設定をしていないため。)
$ docker-compose exec --user=laradock workspace bash
$ php artisan migrate
SQLSTATE[HY000] [1045] Access denied for user 'laradock'@'172.20.0.4' (using password: YES)
ユーザを作成するとマイグレーションできるようになる。
> CREATE USER 'laradock'@'172.20.0.4' IDENTIFIED BY 'secret';
■次回からの起動
以下で起動できる。
しばらく待たないと「502 Bad Gateway」のエラーになる可能性があるので注意。
$ cd docker/laravel/laradock
$ docker-compose up -d nginx mysql workspace phpmyadmin
以下でLaravelの操作ができる。
$ docker-compose exec --user=laradock workspace bash
$ php artisan --version
以下でMySQLの操作ができる。
$ docker-compose exec mysql bash
# mysql -u root -p
root
■MySQLコンテナが起動しなくなった場合
Laradock の .env を以下のように編集すると、その後MySQLコンテナが起動しなくなった。
MYSQL_VERSION=latest
↓
MYSQL_VERSION=5.7
LaradockでMySQLがどうしても立ち上がらない人あつまれー! - Qiita
https://qiita.com/lara_bell/items/d4bd1340a5cc7dfcfcb4
MySQLのデータは、.envの以下の場所で永続化されている。
# Choose storage path on your machine. For all storage systems
DATA_PATH_HOST=~/.laradock/data
壊れたデータが残っている可能性がある。以下のフォルダを削除して各コンテナを再起動すると、MySQLコンテナが起動する。
C:\Users\refirio\.laradock
■参考
Laradockを使ってLaravel 5.5環境を構築する - Qiita
https://qiita.com/rock619/items/62c2ab2252c405e26479
LaradockでMySQL5.5を使う(Docker + Laravel) - Qiita
https://qiita.com/mom0tomo/items/40219773c705b5175825
DockerとLaradockでPHPフレームワークとCMSの開発環境を構築する【MySQL( latest)8.0.11対応】 - Qiita
https://qiita.com/2no553/items/c1da7bb6dfed68c5af1b
Laravel Sailによる開発環境構築
※未検証。
Laravel + Docker | Laravel Sailを使って開発環境を楽に構築する|エンジニアBLOG|株式会社クラウドスミス
https://cloudsmith.co.jp/blog/virtualhost/docker/2021/07/1845910.html
【Docker】Laravel Sailのインストールと使い方を確認 | アールエフェクト
https://reffect.co.jp/laravel/laravel-sail
WordPress
※後から以下がリリースされた。
未検証だが、次回にWordPress環境を作るときは検討したい。
WordPress公式dockerパッケージ wp-env による開発環境構築 - Tips - Capital P - WordPressメディア
https://capitalp.jp/2020/05/15/head-first-wp-env/
以下、上のパッケージとは関係なく検証したもの。
ミドルウェアだけでなく、アプリケーションも含めて構築できる。
以下はGit管理も想定した例。
■ファイルの作成
C:\Users\refirio\docker\ 内に以下を作成するとする。
wordpress\.gitignore
Thumbs.db
.DS_Store
/docker-compose.override.yml
/html/wp-config.php
/html/.htaccess
/html/.htpasswd
/html/index.php
/html/license.txt
/html/readme.html
/html/wp-*.php
/html/xmlrpc.php
/html/wp-admin/*
/html/wp-content/*
!/html/wp-content/themes
/html/wp-content/themes/*
!/html/wp-content/themes/simple
/html/wp-includes/*
/html/tool/*
wordpress\html\wp-content\themes\simple
テーマを配置。
wordpress\docker\wordpress\Dockerfile
FROM wordpress:5-php7.2-apache
RUN apt-get update && \
docker-php-ext-install pdo_mysql mysqli mbstring
RUN curl --location --output /usr/local/bin/mhsendmail https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64
RUN chmod +x /usr/local/bin/mhsendmail
RUN echo 'sendmail_path="/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025 --from=no-reply@docker.dev"' > /usr/local/etc/php/conf.d/mailhog.ini
RUN usermod -u 1000 www-data && \
groupmod -g 1000 www-data
wordpress\docker\wordpress\php.ini
date.timezone = Asia/Tokyo
wordpress\docker\mysql\Dockerfile
FROM mysql:5.7
wordpress\docker\mysql\my.cnf
[mysqld]
character-set-server=utf8
wordpress\docker\mailhog\Dockerfile
FROM mailhog/mailhog
wordpress\docker-compose.yml
version: '3'
networks:
compose_network:
volumes:
compose_wordpress_data:
services:
mailhog:
container_name: mailhog
ports:
- 8025:8025
- 1025:1025
networks:
- compose_network
build: ./docker/mailhog
mysql:
container_name: mysql
volumes:
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
- compose_wordpress_data:/var/lib/mysql:rw
environment:
TZ: Asia/Tokyo
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_USER: user
MYSQL_PASSWORD: userpass
MYSQL_DATABASE: wordpress
networks:
- compose_network
build: ./docker/mysql
wordpress:
container_name: wordpress
volumes:
- ./docker/wordpress/php.ini:/usr/local/etc/php/conf.d/php.ini:ro
- ./html:/var/www/html
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: user
WORDPRESS_DB_PASSWORD: userpass
WORDPRESS_DB_NAME: wordpress
ports:
- 80:80
networks:
- compose_network
build: ./docker/wordpress
■設定の上書き
docker-compose.yml と同じ階層に docker-compose.override.yml を置くと、その設定内容が優先される。
wordpress\docker-compose.yml
version: '3'
services:
mysql:
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_USER: user
MYSQL_PASSWORD: userpass
MYSQL_DATABASE: wordpress
wordpress:
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: user
WORDPRESS_DB_PASSWORD: userpass
WORDPRESS_DB_NAME: wordpress
■よく使用するコマンド
※初回は特に、起動まで時間がかかる。
httpでアクセスできなくても、mysqlに接続できなくても、しばらく待てば解決することがある。
$ cd docker/wordpress
$ docker-compose build … ビルドする場合。(構成を変更した場合など。)
$ docker-compose up -d … 起動。
$ docker-compose down … 終了。
$ docker container exec -it php bash … phpコンテナのターミナルに接続する場合。
$ docker container exec -it mysql bash … mysqlコンテナのターミナルに接続する場合。
$ mysql -u root -p … MySQLに接続。
$ docker volume ls ... ボリュームを確認。
$ docker volume rm compose_wordpress_data ... ボリュームを削除。
■ブラウザからのアクセス
http://127.0.0.1/
http://127.0.0.1:8025/
メール送信
Postfix - メールサーバの構築方法について(Docker)|teratail
https://teratail.com/questions/144828
VagrantのCentOSでDockerを使用する
■Vagrantfile
Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
config.vm.box_check_update = false
config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.synced_folder "./code", "/var/www"
end
■起動
cd C:\vagrant\docker
vagrant up
■SELinuxを無効化
# getenforce
Enforcing … SELinuxが有効。
# setenforce 0 … SELinuxを無効化。
# getenforce
Permissive … SELinuxが無効。
# vi /etc/sysconfig/selinux
■日本語化
#SELINUX=enforcing
SELINUX=disabled … システム起動時にSELinuxを無効化。
# localectl set-locale LANG=ja_JP.UTF-8
# localectl status
■タイムゾーンを設定
# timedatectl set-timezone Asia/Tokyo
# timedatectl status
■Dockerをインストール
# yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
… 古いDocker環境を削除。
# yum install -y yum-utils device-mapper-persistent-data lvm2 … Dockerのインストールに必要なツールをインストール。
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo … Docker-CEのリポジトリを追加。
# yum install -y docker-ce docker-ce-cli containerd.io … Dockerをインストール。
# systemctl start docker
# systemctl enable docker
# docker --version
# docker info
# docker container run hello-world
# docker image ls
以下でインストールすることもできるが、
今は原則 docker-ce をインストールするといい。
# yum install -y docker
DockerとDocker-CEの違いについて - Qiita
https://qiita.com/s-suefusa/items/cb3c4044da3b3657dbd0
Install Docker on CentOS 7 - Qiita
https://qiita.com/ymasaoka/items/b6c3ffea060bcd237478
Docker CEをCentOS 7にyumインストールする手順 |
https://weblabo.oscasierra.net/docker-ce-install-centos7/
■一般ユーザでDockerを実行できるようにする
# groupadd docker … dockerグループを作成。(環境によっては作成済みみたい。)
# usermod -a -G docker vagrant … vagrantをdockerグループに入れる。これでvagrantがdockerコマンドを実行できる。
# systemctl restart docker … dockerを再起動。(必須。)
# exit
$ docker info … 上記変更は、再接続後に反映されるので注意。
■Apache+PHPの動作確認
$ docker container run --name php -p 80:80 -d php:7.3-apache
$ docker image ls
$ docker container ls
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# echo 'Hello!' > index.html
# exit
ブラウザで以下にアクセスし、「Hello!」と表示されれば成功
http://192.168.33.10/
$ docker container rm -f $(docker container ls -a -q) … 終了。
■終了
cd C:\vagrant\docker
vagrant halt
■Apache+PHPが動かなかったとき
$ docker container exec -it php bash … phpコンテナのターミナルに接続…できない。
Error response from daemon: Container 9e8f5dd165b29e2257b66b3d021bf65e59c3d0e9339c0606b12761d4be97680d is not running
$ docker container ls -a … コンテナが終了している。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9e8f5dd165b2 php:7.1-apache "docker-php-entryp..." 2 minutes ago Exited (1) 2 minutes ago php
c8e92257c12f hello-world "/hello" 7 minutes ago Exited (0) 7 minutes ago frosty_booth
$ docker container rm -f $(docker container ls -a -q) … いったんすべてのプロセスを終了。
$ docker container ls
$ docker container run --name web -p 80:80 -d devilbox/apache-2.4 … 別のApache2.4を試す。
$ docker container exec -it web bash … phpコンテナのターミナルに接続。
# cd /var/www/default/htdocs/
# echo 'Hello!' > index.html
# exit
devilbox/apache-2.4 なら動くが、公式のApache+PHPコンテナだけ動かないことがある?
Docker自体をインストールする環境による?
Vagrant公式の centos/7 上でなら大丈夫かも?
■補足
Apache+PHPを稼働させようとすると、環境によっては以下のエラーメッセージが表示される?
$ docker container run --name php -p 80:80 php:8.1-apache
AH00534: apache2: Configuration error: No MPM loaded.
nginxだと問題なく起動できる。
$ docker container run --name php -p 80:80 -d nginx:1.12
Apache2.2でも問題なく起動できる。
$ docker container run --name php -p 80:80 -d devilbox/apache-2.2
PHPバージョンアップのときもそうだったが、Apache2.4には色々と相性の問題があるかも?
…と思ったけど、以下でApache2.4は使える。
$ docker container run --name web -p 80:80 -d devilbox/apache-2.4
要確認。
VagrantのUbuntuでDockerを使用する
■Vagrantfile
Vagrant.configure(2) do |config|
config.vm.box = "bento/ubuntu-18.04"
config.vm.box_check_update = false
config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.synced_folder "./code", "/var/www"
end
■起動
cd C:\vagrant\ubuntu_docker
vagrant up
■日本語化
インストールに20分ほど時間がかかった。
言語切り替え後、再ログインすると反映される。
$ sudo apt install language-pack-ja-base language-pack-ja ibus-mozc
$ sudo localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
【Ubuntu 18.04 LTS Server】日本語環境にする(日本語ロケールとタイムゾーンの変更) | The modern stone age.
https://www.yokoweb.net/2018/05/04/ubuntu-18_04-lts-server-japanese/
■タイムゾーンを設定
$ sudo dpkg-reconfigure tzdata
地域の選択画面が表示されるので、「アジア」「東京」を選択する。
(カーソルキーで対象を変更し、Enterを押すと決定できる。)
■Dockerをインストール
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ 不明 ] Docker Release (CE deb) <docker@docker.com>
sub rsa4096 2017-02-22 [S]
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
… add-apt-repository の部分は、環境によって実行すべき内容が変わるので注意。
$ sudo apt-get update
$ sudo apt-get install -y docker-ce
$ sudo docker info
$ sudo docker container run hello-world
$ sudo docker image ls
Ubuntuにdockerをインストールする - Qiita
https://qiita.com/tkyonezu/items/0f6da57eb2d823d2611d
Get Docker Engine - Community for Ubuntu | Docker Documentation
https://docs.docker.com/install/linux/docker-ce/ubuntu/
■一般ユーザでDockerを実行できるようにする
$ sudo usermod -aG docker vagrant
$ docker info … 上記変更は、再接続後に反映されるので注意。
$ docker container run hello-world
$ docker image ls
■Apache+PHPの動作確認
$ docker container run --name php -p 80:80 -d php:7.3-apache
$ docker image ls
$ docker container ls
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# echo 'Hello!' > index.html
# exit
$ curl http://localhost/
Hello!
ブラウザで以下にアクセスし、「Hello!」と表示されれば成功…だが、表示されない?
vagrant up のときにエラーが表示されたから、かも。
http://192.168.33.10/
$ docker container rm -f $(docker container ls -a -q) … 終了。
■Docker Compose をインストール
$ sudo curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo docker-compose --version
$ docker-compose --version … vagrantユーザでも実行できることを確認。
■Docker Compose
Docker Compose 用のファイルはあらかじめ配置しておく。
$ cd /var/www/docker/apache_php7_mysql_gd
$ docker-compose build … ビルドする場合。(構成を変更した場合など。)
$ docker-compose up -d … 起動。
$ docker-compose down … 終了。
$ docker container exec -it php bash … phpコンテナのターミナルに接続する場合。
$ docker container exec -it mysql bash … mysqlコンテナのターミナルに接続する場合。
$ mysql -u root -p … MySQLに接続。
http://192.168.33.10/
■終了
cd C:\vagrant\ubuntu_docker
vagrant halt
■ubuntu/trusty64 の場合
Docker実行時にエラーになった。
カーネルのバージョンアップで対応できるかもしれないが、bento/ubuntu-18.04 を使うのが無難そう。
$ sudo docker container run hello-world
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:297: copying bootstrap data to pipe caused \"write init-p: broken pipe\"": unknown.
Ubuntu日本語フォーラム / ubuntu14.04でdockerコンテナが実行できない
https://forums.ubuntulinux.jp/viewtopic.php?pid=120508
■ubuntu/bionic64 の場合
Vagrant起動時にエラーが表示されたが、SSHで接続はできた。
ただしホストPCからHTTP接続できない?フォルダ同期もできていない?
bento/ubuntu-18.04 なら大丈夫だった。
==> default: Attempting graceful shutdown of VM...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default: Warning: Connection reset. Retrying...
default: Warning: Connection aborted. Retrying...
default: Warning: Remote connection disconnect. Retrying...
default: Warning: Connection aborted. Retrying...
default: Warning: Connection reset. Retrying...
default: Warning: Connection aborted. Retrying...
default: Warning: Connection reset. Retrying...
default: Warning: Connection aborted. Retrying...
default: Warning: Connection reset. Retrying...
default: Warning: Connection aborted. Retrying...
default: Warning: Connection reset. Retrying...
default: Warning: Connection aborted. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!
/sbin/ifdown 'enp0s8' || true
/sbin/ip addr flush dev 'enp0s8'
# Remove any previous network modifications from the interfaces file
sed -e '/^#VAGRANT-BEGIN/,$ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces.pre
sed -ne '/^#VAGRANT-END/,$ p' /etc/network/interfaces | tac | sed -e '/^#VAGRANT-END/,$ d' | tac > /tmp/vagrant-network-interfaces.post
cat \
/tmp/vagrant-network-interfaces.pre \
/tmp/vagrant-network-entry \
/tmp/vagrant-network-interfaces.post \
> /etc/network/interfaces
rm -f /tmp/vagrant-network-interfaces.pre
rm -f /tmp/vagrant-network-entry
rm -f /tmp/vagrant-network-interfaces.post
/sbin/ifup 'enp0s8'
Stdout from the command:
Stderr from the command:
bash: 行 4: /sbin/ifdown: そのようなファイルやディレクトリはありません
bash: 行 20: /sbin/ifup: そのようなファイルやディレクトリはありません
以下でApacheをインストールしても、ホストのPCからはアクセスできない?
Dockerの問題では無さそう。
Vagrantのネットワーク関連の問題かも。
$ sudo apt-get install apache2 ... Apacheをインストール。
$ apache2 -v ... Apacheのバージョンを確認。
$ sudo service apache2 start ... Apacheを起動。
$ sudo service apache2 stop ... Apacheを停止させる場合。
$ sudo service apache2 restart ... Apacheを再起動させる場合。
以下を削除するといいと解説されているページがあった。
$ sudo rm -rf /etc/udev/rules.d/70-persistent-net.rules
$ sudo rm -rf /etc/udev/rules.d/70-persistent-cd.rules
$ sudo rm -rf /etc/udev/rules.d/60-vboxadd.rules
コマンドプロンプトから以下を実行。
$ vagrant reload
…としてみたが、状況は変わらなかった。
Vagrantを扱うときにハマりがちポイントをまとめてみた - Qiita
https://qiita.com/srockstyle/items/233ef326a75362200a91
package化したboxを使うときによく出るエラー -- blog.10rane.com
http://blog.10rane.com/2015/08/28/errors-out-when-using-to-package-the-box/
vagrant upでネットワークエラーが出たら - Qiita
https://qiita.com/Esfahan/items/ec900276f0894cc9abdd
EC2でDockerを使用する
通常の手順でEC2を作成し、SSHでアクセスできることを確認しておく。
ここではAmazonLinux2を使うものとする。
通常の手順で言語・タイムゾーン・アップデート・開発ツールインストール・メール送信など最低限のものを設定しておく。
※EC2のIPアドレスは「203.0.113.1」であるとする。
※AmazonLinux2の場合、DockerはExtrasリポジトリからインストールすることができる。
※ECSなどAWSのマネージドサービスについては「AWS.txt」を参照。
■Dockerをインストール
EC2(Amazon Linux 2)にDocker CEをインストールしてみる - Qiita
https://qiita.com/simis/items/902e18c82f602917ccf2
※もとは「yum install -y docker」としてインストールすれば良かったようだが、
今は「yum install -y docker-ce」としてCE版をインストールする方が良さそう。
ただしAmazonLinux2ならExtrasリポジトリにdockerがあるので、AmazonLinux2の場合は原則これをインストールすると良さそう。
# amazon-linux-extras install docker -y … dockerをインストール。
# systemctl start docker … dockerを起動。
# systemctl enable docker … dockerの自動起動を設定。
# docker info … dockerの起動を確認。
# docker container run hello-world … hello-worldの起動を確認。
# docker image ls
■一般ユーザでDockerを実行できるようにする
一般ユーザでDockerを実行すると、「Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock」のようなエラーになる。
これはグループを調整することで対処できる。
# groupadd docker … dockerグループを作成。(環境によっては作成済みみたい。)
# usermod -a -G docker ec2-user … ec2-userをdockerグループに入れる。これでec2-userがdockerコマンドを実行できる。
# systemctl restart docker … dockerを再起動。(必須。)
# exit
$ docker info … 上記変更は、再接続後に反映されるので注意。
■Apache+PHPの動作確認
$ docker container run --name php -p 80:80 -d php:8.1-apache … 「php」という名前を付けてApacheの起動を確認。
$ docker image ls
$ docker container ls
$ docker container exec -it php bash … phpコンテナのターミナルに接続。
# echo '<?php phpinfo();' > index.php … index.php を作成。(初期状態ではviはインストールされていない。)
# exit
ブラウザで以下にアクセスし、phpinfoの内容が表示されれば成功。
(コンテンツを何も作成していない場合、「403 Forbidden」が表示される。)
http://203.0.113.1/
$ docker container rm -f $(docker container ls -a -q) … いったんすべてのプロセスを終了。
$ docker container ls
■Docker Composeをインストール
【AWS】EC2にDockerとDocker Composeをインストール - ふにノート
https://kacfg.com/aws-ec2-docker/
最新のバージョンは https://github.com/docker/compose/releases/ で確認できる。
今回は検証時最新版の 2.14.2 を使用する。
$ sudo su -
# curl -L https://github.com/docker/compose/releases/download/v2.14.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# docker-compose --version
# exit
$ docker-compose --version … ec2-userでも実行できることを確認。
■Docker Composeの動作確認
/home/ec2-user/docker/test にPHP環境構築用の Docker Compose を配置するものとする。
起動中のコンテナがあれば、終了させておく。
$ cd /home/ec2-user/docker/test
$ docker-compose build
$ docker-compose up -d
$ docker-compose down
$ docker container exec -it php bash
# ls -l /var/www/public
# exit
$ docker container exec -it mysql bash
# mysql -u user -p
> exit
# exit
http://203.0.113.1/
■参考
AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法 - Qiita
https://qiita.com/y-do/items/e127211b32296d65803a
EC2上でDockerのnginxコンテナを動かしてアクセスを確認した - やる気がストロングZERO
https://yaruki-strong-zero.hatenablog.jp/entry/ec2_docker_nginx
AWS EC2 Amazon LinuxでDocker, Docker Composeをインストールする - Qiita
https://qiita.com/shinespark/items/a8019b7ca99e4a30d286
ECSを試す際は以下も参考になるかも。
知識0から Docker 環境を AWS の ECS でデプロイするまで - istyle Tech Blog
https://techblog.istyle.co.jp/archives/1652
ホストOSとコンテナで相互にファイルを読み書き(Linux環境)
■問題の確認
以下のようにしてComposeのためのファイルを取得し、
$ git clone git@bitbucket.org:refirio/docker_wordpress.git /home/ec2-user/docker/wordpress
Dockerで起動してWordPressを実行しても、何故か日本語版にならなかった。
テーマを配置するためにGitにより作成された wp-content ディレクトリ内に書き込めないのが原因みたい。
同じくメディアのアップロードもできない。
drwxrwxr-x 4 ec2-user ec2-user 52 5月 16 17:26 wp-content
■コンテナ内で状況を確認
Dockerにより作成されたファイルは、コンテナ内では以下のように見える。
# ls -l
total 200
-rw-r--r-- 1 www-data www-data 420 Nov 30 2017 index.php
-rw-r--r-- 1 www-data www-data 19935 Jan 1 20:37 license.txt
-rw-r--r-- 1 www-data www-data 7447 Apr 8 22:59 readme.html
ec2-userにより作成されたファイルは、コンテナ内では以下のように見える。
idが 1000 のユーザはいないため数字表示。
# ls -l ..
total 4
drwxrwxr-x 5 1000 1000 4096 May 16 08:41 html
www-data は以下のIDを持つ。
# id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
■コンテナ外で状況を確認
Dockerにより作成されたファイルは、コンテナ外では以下のように見える。
(idが 33 のユーザはいないため数字で表示されている。)
$ ll
合計 200
-rw-r--r-- 1 33 tape 420 12月 1 2017 index.php
-rw-r--r-- 1 33 tape 19935 1月 2 05:37 license.txt
-rw-r--r-- 1 33 tape 7447 4月 9 07:59 readme.html
■解決策
Docker: マウントしたVolumeにApacheが書き込めないとき - Qiita
https://qiita.com/suin/items/3a0361102af83d0b69aa
dockerでvolumeをマウントしたときのファイルのowner問題 - Qiita
https://qiita.com/yohm/items/047b2e68d008ebb0f001
「ユーザ・グループを1000:1000にする」という方法で対処してみる。
「1000」が決め打ちなのが気にはなる(システム以外で最初に作成されたユーザが 1000 となる)が、
Linux(EC2)とWindowsの両方で大丈夫だったのでいったん良しとする。
$ vi docker/wordpress/Dockerfile … ファイルの最後に以下を追記。
■再実行例
最初から実行しなおしたい場合の例。
コンテナを終了し、データベースを削除し、不要なファイルを削除してからGitに一致させている。
RUN usermod -u 1000 www-data && \
groupmod -g 1000 www-data
$ cd /home/ec2-user/docker/wordpress
$ docker-compose down
$ docker volume rm docker_compose_wordpress_data
$ sudo rm -rf html
$ git reset --hard origin/master
トラブル
■イメージを削除できない
削除しようとするとエラー。
$ docker image rm 7a8792605f8c
Error response from daemon: conflict: unable to delete 7a8792605f8c (must be forced) - image is referenced in multiple repositories
オプション「-f」を指定すると削除できることがある。
$ docker image rm 7a8792605f8c -f
それでも削除できない。
$ docker image rm 7a8792605f8c -f
Error response from daemon: conflict: unable to delete 7a8792605f8c (cannot be forced) - image has dependent child images
リポジトリとタグを指定すると削除できる。
docker image rm 949004901725.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php74_apache:1.1.0
【docker】〜image has dependent child images 対応〜 - Qiita
https://qiita.com/s-inoue-git/items/3096b86fe1bbb1ad155d
■Dockerが配置したファイルを上書きできない
Dockerが配置したファイルを直接FTPで上書きできない。
以下で解決するかと思ったが、
# mkdir /home/ec2-user/docker/wordpress/html
# chown ec2-user. /home/ec2-user/docker/wordpress/html
# chmod 0777 /home/ec2-user/docker/wordpress/html
# chmod g+s /home/ec2-user/docker/wordpress/html
Dockerによって作成されたファイルは以下の所有者になってしまう。
# ll
-rw-r--r-- 1 33 tape 420 12月 1 2017 index.php
rootによって作成されたファイルは以下のように ec2-user グループになるので謎。
# ll
-rw-r--r-- 1 root ec2-user 10 5月 16 12:05 test.txt
…だったが、このファイル内「ホストOSとコンテナで相互にファイルを読み書き(Linux環境)」の方法で一応は解決した。
より良い方法が無いかは、また検証したい。
■Conflict となって起動できない
Dockerでコンテナ名が重複してしまった時の古いコンテナ削除方法 (Conflictエラー) | FRONTL1NE (フロントライン)
https://frontl1ne.net/2019/05/docker-fix-conflict-error/
コンテナを起動すると「すでに名前が使われている」というエラーになる。
$ docker-compose -p campus up -d
Creating network "campus_compose_network" with driver "bridge"
Creating php ... error
Creating mariadb ...
Creating mailhog ...
Creating mysql ...
ERROR: for php Cannot create container for service php: Conflict. The container name "/php" is already in use by contaiCreating mysql ... error be able to reuse that name.
Creating mariadb ... done
container "f671ca345d4aa2db89003e1f35a39aa4aef9330f95e2cda1d0205364a0762e38". You have to remove (or rename) that contaiCreating mailhog ... done
ERROR: for php Cannot create container for service php: Conflict. The container name "/php" is already in use by container "2c32a66a679a1e3905aa8caa58ee6d29a6bf6af3d8fb03f5fc43f9dee07f0dce". You have to remove (or rename) that container to be able to reuse that name.
ERROR: for mysql Cannot create container for service mysql: Conflict. The container name "/mysql" is already in use by container "f671ca345d4aa2db89003e1f35a39aa4aef9330f95e2cda1d0205364a0762e38". You have to remove (or rename) that container to be able to reuse that name.
ERROR: Encountered errors while bringing up the project.
いったん終了する。
$ docker-compose -p campus down
Stopping mailhog ... done
Stopping mariadb ... done
Removing mailhog ... done
Removing mariadb ... done
Removing network campus_compose_network
コンテナ一覧には何も表示されない。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
起動していないコンテナも含めて表示すると、
「example_php」「example_mysql」によって「php」「mysql」の名前が使われていることが確認できる。
8日前にエラーで終了したままになっているものみたい。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2c32a66a679a example_php "docker-php-entrypoi…" 8 days ago Exited (0) 8 days ago php
f671ca345d4a example_mysql "docker-entrypoint.s…" 8 days ago Exited (0) 8 days ago mysql
068065dc757c example_nginx "/docker-entrypoint.…" 8 days ago Exited (137) 8 days ago nginx
8dd90e083667 5f2e213b9d0c "/bin/sh -c 'apt-get…" 3 months ago Exited (100) 3 months ago determined_roentgen
f6eef1ae5a21 6adef0082129 "/bin/sh -c 'apt-get…" 4 months ago Exited (100) 4 months ago festive_franklin
79ebe67688db 6adef0082129 "/bin/sh -c 'apt-get…" 4 months ago Exited (100) 4 months ago gracious_driscoll
2a02cc7dfd35 65a3756de1d8 "/bin/sh -c 'docker-…" 4 months ago Exited (1) 4 months ago thirsty_sammet
1f5d6e0395dc 8e17cf6d251e "/bin/sh -c 'docker-…" 4 months ago Exited (1) 4 months ago jolly_noether
それぞれ、IDを指定して終了させる。
$ docker rm 2c32a66a679a
$ docker rm f671ca345d4a
$ docker rm 068065dc757c
終了できた。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8dd90e083667 5f2e213b9d0c "/bin/sh -c 'apt-get…" 3 months ago Exited (100) 3 months ago determined_roentgen
f6eef1ae5a21 6adef0082129 "/bin/sh -c 'apt-get…" 4 months ago Exited (100) 4 months ago festive_franklin
79ebe67688db 6adef0082129 "/bin/sh -c 'apt-get…" 4 months ago Exited (100) 4 months ago gracious_driscoll
2a02cc7dfd35 65a3756de1d8 "/bin/sh -c 'docker-…" 4 months ago Exited (1) 4 months ago thirsty_sammet
1f5d6e0395dc 8e17cf6d251e "/bin/sh -c 'docker-…" 4 months ago Exited (1) 4 months ago jolly_noether
この状態なら、以下のとおり起動できるようになった。
$ docker-compose -p campus up -d
Creating network "campus_compose_network" with driver "bridge"
Creating mysql ... done
Creating mariadb ... done
Creating mailhog ... done
Creating php ... done
■php_network_getaddresses となってMySQLに接続できない
Docker Compose でPHPコンテナとMySQLコンテナを起動し、
PHPからMySQLに接続しようとしたときに以下のエラーになることがあった。
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known
起動コマンドを以下のように変更(バックグラウンドの指定を無くしてログを表示する)して様子を見る。
$ docker-compose up -d
↓
$ docker-compose up
MySQLに関してコンソールに以下のログが表示された。
設定ファイルに問題があり、具体的には文字コードの指定に問題があるらしい。
mysql | 2021-10-07 10:42:41+09:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.5.12+maria~focal started.
mysql | 2021-10-07 10:42:41+09:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
mysql | command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.GgJeIcAyzq
mysql | 2021-10-07 10:42:41 0 [ERROR] COLLATION 'utf8mb4_general_ci' is not valid for CHARACTER SET 'utf8'
mysql exited with code 1
Docker Compose 用ファイルの docker\mysql\my.cnf を修正。(文字コードが怪しいので変更。)
[mysqld]
character-set-server=utf8
↓
[mysqld]
character-set-server=utf8mb4
ファイルの修正を行っているので、事前に「docker-compose build」が必要なので注意。
あわせて、以下のようにして対象のボリュームも削除しておく。
$ docker volume ls
$ docker volume rm xxxxx
これで「mysql:5.7」「mariadb:10.5」の両方ですぐに起動できるようになった。
■ポートが使われているとなってMySQLが起動しない
ある日突然、以下のエラーで起動できなくなった。
$ docker-compose -p campus-asp up -d
Creating network "campus-asp_default" with the default driver
Creating campus-asp_redis_1 ...
Creating campus-asp_mysql_1 ...
Creating campus-asp_mysql_1 ... error
Creating campus-asp_nginx_1 ...
Creating campus-asp_smtp4dev_1 ...
Creating campus-asp_redis_1 ... done
Creating campus-asp_php_1 ... done
Creating campus-asp_nginx_1 ... done
Creating campus-asp_smtp4dev_1 ... done
ERROR: for mysql Cannot start service mysql: driver failed programming external connectivity on endpoint campus-asp_mysql_1 (8a6f1c812a648295f4016ef3b6eb8810eaae2fbb07f042ef07a571d7c0813d5c): Bind for 127.0.0.1:3306 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
以下を参考に対応した。
example_mysqlが不正な状態で残り続けていた?削除することで解消できた。
(直近でexample案件でエラーが発生し、その解消のために試行錯誤していたが、その影響だと思われる。)
Docker Composeでdriver failed programming external connectivity on endpointとなった時の対応方法 - Qiita
https://qiita.com/ponsuke0531/items/f3490f571b5eee16ea87
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
98d7976c7795 campus-asp_smtp4dev "dotnet /app/Rnwood.…" About a minute ago Up About a minute 25/tcp, 143/tcp, 127.0.0.1:5000->80/tcp campus-asp_smtp4dev_1
2aa9aca11681 campus-asp_php "docker-php-entrypoi…" About a minute ago Up About a minute 0.0.0.0:5174->5174/tcp, :::5174->5174/tcp, 9000/tcp campus-asp_php_1
23fc6ec06392 campus-asp_nginx "/docker-entrypoint.…" About a minute ago Up About a minute 127.0.0.1:80->80/tcp campus-asp_nginx_1
9b1a13ed6e90 campus-asp_redis "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp campus-asp_redis_1
d4d1bfdaa839 campus-asp_mysql "docker-entrypoint.s…" About a minute ago Created campus-asp_mysql_1
f8d3d168bea9 example_apache "sh /entrypoint.sh" 4 days ago Exited (127) 3 days ago example_apache_1
324895e1dfff example_mysql "docker-entrypoint.s…" 4 days ago Up 4 minutes 127.0.0.1:3306->3306/tcp example_mysql_1
d71118e77a41 example_smtp4dev "dotnet /app/Rnwood.…" 4 days ago Exited (0) 3 days ago
$ docker rm 324895e1dfff
Error response from daemon: You cannot remove a running container 324895e1dfffd5e4cb5b5c2f06d96d1fe35e0a1274f8b116f6738802ee01c52b. Stop the container before attempting removal or force remove
$ docker container rm -f 324895e1dfffd5e4cb5b5c2f06d96d1fe35e0a1274f8b116f6738802ee01c52b
324895e1dfffd5e4cb5b5c2f06d96d1fe35e0a1274f8b116f6738802ee01c52b
$ docker rm f8d3d168bea9
f8d3d168bea9
$ docker rm d71118e77a41
d71118e77a41
コマンドの新旧
Docker 1.13 からコマンドが「docker 何を どうするか」の形式に再編成されている。
新旧のコマンドに互換性はあるが、できるだけ新体系のコマンドを使用しておくといい。
旧コマンド 新コマンド
- - - - - - - - - - - - - - - - - - - -
docker build docker image build
docker images docker image ls
docker rmi docker image rm
docker tag docker image tag
docker push docker image push
docker pull docker image pull
docker run docker container run
docker logs docker container logs
docker exec docker container exec
docker stop docker container stop
メモ
以下、引き続き検証メモ。
■Node.js(Docker Compose なしで単体起動する場合)
Node.js ウェブ・アプリの Docker 化 - Docker-docs-ja 1.11.0 ドキュメント
http://docs.docker.jp/engine/examples/nodejs_web_app.html
起動したが、CentOS6のダウンロードからなので時間がかかる?
Node.js用のイメージがあれば、その方が良さそう。
docker image build -t refirio/centos-node-hello .
docker image ls
docker container run -p 49160:8080 -d refirio/centos-node-hello
curl -i 127.0.0.1:49160
http://127.0.0.1:49160/
以下なども参考にして、再度構築を試したい。
3000版ポートでnode.jsにアクセスできるようにして、さらにnginx経由でポート指定無しでアクセスできるようにしてみる。
nginx無しで80版ポートにアクセスさせられるかも試したい。
Dockerでnginx+node.jsのSPA構成を試す - Qiita
https://qiita.com/KeitaMoromizato/items/bfc3e22dae47211eff4f
■Ruby on Rails
Docker + Ruby on Rails 5 のメモ - Qiita
https://qiita.com/yuki-maru/items/3ee8e52cebbfc036c023
この手順でRailsを起動できた。
http://127.0.0.1:3000/
次回からは以下で起動できる。
$ cd docker/compose_ruby
$ docker-compose build
$ docker-compose up -d
$ docker-compose down
docker-compose.yml を以下のように編集すると、http://127.0.0.1/ でアクセスできた。
web:
build: .
command: bundle exec rails s -p 80 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "80:80"
■疑問点とメモ
・dockerのgit管理。
汎用的な環境というより、特定の案件の環境を管理するためのもの。だと思う。
それなら、プログラムと同じリポジドリで管理すれば良さそう。
・fake s3 というものがあるらしい。ローカルでs3を試せるらしい。
LocalStack というのもよく使われるみたい。
・上の手順で docker-compose build した場合、REPOSITORYもTAGも「<none>」のイメージが作られる?こういうもの?名前は指定できる?
以下で環境を立ち上げるとどうなるか試す。
http://koni.hateblo.jp/entry/2017/01/28/150522
・apache_php8_mysql のファイル構成は以下も参考に再考する。
http://koni.hateblo.jp/entry/2017/01/28/150522
・カスタムイメージを作成した場合、それも同梱するか。
つまりイメージ自体に手を加えたら、各々の環境でイメージをインポートしなおしてもらう。
Dockerは専用リポジトリで管理すべきか。
・custom.cnf はこの名前でいいか。
と思ったが、公式の推奨手順みたい。
Dockerの公式MySQLイメージの使い方を徹底的に解説するよ - DQNEO起業日記
http://dqn.sakusakutto.jp/2015/10/docker_mysqld_tutorial.html
・複数人が同じ開発環境を再現する場合、イメージを更新した場合はどうするか。
小さな更新なら Docker Compose や Dockerfile の CMD で実行すれば良さそう。
大きな修正なら、Docker Hub などで管理しておく必要がある?でも Docker Hub のプライベートリポジトリは有料みたい。
イメージ自体をリポジトリに入れて、必要なときにインポートしてもらえばいいかも?
docker - コマンドはdocker-compose.ymlとDockerfileのどちらで定義するほうがいい? - スタック・オーバーフロー
https://ja.stackoverflow.com/questions/30495/%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AFdocker-com...
・本番環境に使う場合、Amazon ECS を検証したい。
・VagrantにDockerをインストールする方法。本番環境のCentOSなどにも応用できるかも。
http://tech.respect-pal.jp/docker_tutorial/
■以下を参考に、上の構成を調整する
ファイルの設定内容のを参考に。
https://qiita.com/osyoyu/items/a039b7e05abc6e97fb25
php.iniの配置方法の参考に。
https://github.com/koni/docker-php-nginx-mysql-memcached/
復習に良い。
https://dev.classmethod.jp/tool/docker/develop-with-docker/
参考に。
https://qiita.com/aild_arch_bfmv/items/d47caf37b79e855af95f
■Docker で Amazon Linux を動かす
amazonlinux - Docker Hub
https://hub.docker.com/_/amazonlinux/
Docker for Windows から Amazon Linux を起動してみた | KDL 情's Cafe BLOG
https://blog.ismg.kdl.co.jp/virtualization/docker/docker_run_amazonlinux
DockerにAmazon Linuxを入れて、Nginxが動くようにする - Qiita
https://qiita.com/areaz_/items/4f79a7c0175c7ef20cc0
■Fargate
AWS Fargate(サーバーやクラスターの管理が不要なコンテナの使用)| AWS
https://aws.amazon.com/jp/fargate/
AWS Fargateとは? - Qiita
https://qiita.com/riywo/items/1a5b50028542d9bb06cc
2019年1月にAWS Fargateが大幅値下げしたのでEC2との価格比を確認してみた | DevelopersIO
https://dev.classmethod.jp/cloud/aws/compare-fees-for-fargat-and-ec2-2019-1/
■Kubernetes
今さら人に聞けない Kubernetes とは? - Qiita
https://qiita.com/MahoTakara/items/85096f8b2632c802ab22
10分くらいでわかる、KubernetesとEKSの何が便利なのか - Qiita
https://qiita.com/masachaco/items/3e50a1ac65cdd661a734
数時間で完全理解!わりとゴツいKubernetesハンズオン!! - Qiita
https://qiita.com/Kta-M/items/ce475c0063d3d3f36d5d
Amazon EKS(AWS でマネージド Kubernetes を実行)| AWS
https://aws.amazon.com/jp/eks/
コンテナ移行ってこんなに大変? 〜「家族アルバム みてね」を支えるインフラの裏側〜 / Container migration in FamilyAlbum - Speaker Deck
https://speakerdeck.com/isaoshimizu/container-migration-in-familyalbum
数時間で完全理解!わりとゴツいKubernetesハンズオン!! - Qiita
https://qiita.com/Kta-M/items/ce475c0063d3d3f36d5d
2019年版・Kubernetesクラスタ構築入門 | さくらのナレッジ
https://knowledge.sakura.ad.jp/20955/
Kubernetesの自前運用は難しい? はてなの撤退事例:「専任エンジニアが2人以上欲しい」 - @IT
https://www.atmarkit.co.jp/ait/articles/1911/08/news009.html
Kubernetes ベスト プラクティス 6 選 | Google Cloud Blog
https://cloud.google.com/blog/ja/products/containers-kubernetes/your-guide-kubernetes-best-practices
急成長のfreeeに学ぶ、進化するアーキテクチャ――Kubernetes×AWSで複雑化したマイクロサービス基盤を改善 (1/2):CodeZine(コードジン)
https://codezine.jp/article/detail/11863
■引き続き参考にしたいページ
Dockerのイメージ削除時のエラー「Error response from daemon: Conflict, cannot delete image」対策 - tsunokawaのはてなダイアリー
http://tsunokawa.hatenablog.com/entry/2016/04/26/000507
そろそろDockerを始めないとやばいと思い始めたあなたへ | 東北ギーク
http://tech.respect-pal.jp/docker_tutorial/
docker-composeを使うと複数コンテナの管理が便利に - Qiita
https://qiita.com/y_hokkey/items/d51e69c6ff4015e85fce
docker-composeのvolumesで指定したホストのディレクトリがマウントされずハマった | Black Everyday Company
https://kuroeveryday.blogspot.jp/2016/11/docker-compose-volumes.html
Dockerで作る最強のWeb開発環境2017 - Qiita
https://qiita.com/osyoyu/items/a039b7e05abc6e97fb25
Dockerで開発環境構築を10倍楽にしたはなし - KAYAC engineers' blog
http://techblog.kayac.com/developing-with-docker-compose
社内用Docker環境をつくる〜Docker Registry on EC2とDocker for AWSについて〜 | Recruit Jobs TECHBLOG
https://techblog.recruitjobs.net/development/docker-registry-on-ec2_and_docker-for-aws
AWS ECSでDockerコンテナ管理入門(基本的な使い方、Blue/Green Deployment、AutoScalingなどいろいろ試してみた) - Qiita
https://qiita.com/uzresk/items/6acc90e80b0a79b961ce
Amazon EC2 Container Serviceで構築されたシステムでDockerコンテナを入れ替える | Developers.IO
https://dev.classmethod.jp/cloud/aws/switch-docker-container-using-ecs/
Amazon EC2 Container Service コンソールチュートリアルをやってみた | Developers.IO
https://dev.classmethod.jp/tool/docker/try-the-amazon-ecs-console-tutorial/
Dockerfileを書くときに気をつけていること10選 - Qiita
https://qiita.com/c18t/items/f3a911ef01f124071c95
さくらVPSでdocker使って5分でWordPressを構築する - Qiita
https://qiita.com/haruto167/items/0faba1b67ceb14e035e0
Amazon Linux 2 でdockerを使ってみる (Apache2.4) - Qiita
https://qiita.com/reflet/items/3b818fbfb14ba5c7ef47
CentOS7にDockerをインストールしてみた。 - Qiita
https://qiita.com/ysuzuki963/items/a31c31735e5b8bed06fe
【アップデート】ECSタスク定義を利用したローカル環境でのテスト実行が可能に! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/ecs-local/
プラットフォームの上でものを作るということ | TORI
https://toris.io/2019/12/what-i-think-about-when-i-think-about-kubernetes-and-ecs/
DXを大幅に低下させるDocker for Macを捨ててMac最速のDocker環境を手に入れる - Qiita
https://qiita.com/yuki_ycino/items/cb21cf91a39ddd61f484
【ハンズオン】Docker+KubernetesでHelmを使ってみよう - Qiita
https://qiita.com/kimurayut/items/df6cb2c418bcfba66f59
Dockerfileのベストプラクティス Top 20 | Sysdig
https://sysdig.jp/blog/dockerfile-best-practices/
長年運用されてきたモノリシックアプリケーションをコンテナ化しようとするとどんな問題に遭遇するか? / SRE NEXT 2022 - Speaker Deck
https://speakerdeck.com/nulabinc/sre-next-2022