■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に入門したので分かりやすくまとめます - 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
■Docker for Mac
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 では使用不可)
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 は使いづらいかも
■WSL2 + Docker
「Docker for Windows」や「Docker Toolbox」よりも後発の技術
今は基本的にこれを使うのが無難
詳細は WSL.txt に記載している
また、「WSL2 + Docker + Docker Desktop」の環境を作成したときの内容も WSL.txt に記載している
以降の内容は、原則としてWSL2を使う前に Docker Toolbox で検証したもの
■Docker Toolbox
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 シャットダウン」とするといいみたい
「閉じる → 電源オフ」でも終了できるが、これは強制終了のようなものかもしれない
■イメージの利用(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:5.6-apache
… PHP+ApacheのイメージをDocker Hubから取得し、バックグラウンド(-d)でコンテナを起動
$ docker image ls
… 取得したイメージ一覧を表示
$ docker container ls
… 起動しているコンテナ一覧を表示
「-d」を指定しない場合、フォアグラウンドで起動される
この場合、プロセスの標準入出力・標準エラーをコンソールに出力する
■ブラウザで確認
$ docker container run -p 80:80 -d php:5.6-apache
… ホストの80番ポートとコンテナの80番ポートを結びつけて、コンテナを起動
$ docker container ls
… 起動しているコンテナ一覧を表示
$ docker-machine ip
… dockerのアドレスを確認
192.168.99.100
ブラウザで以下にアクセスし、「403 Forbidden」が表示されれば成功
http://192.168.99.100/
■コンテナを終了する場合
$ docker container ls
… コンテナのIDを確認
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06256413da0f php:5.6-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:5.6-apache
… コンテナに「php」という名前を付けて起動
$ docker container exec -it php bash
… phpコンテナのターミナルに接続
# echo '<?php phpinfo();' > index.php
… index.php を作成(初期状態ではviはインストールされていない)
ブラウザで以下にアクセスし、phpinfoが表示されれば成功
http://192.168.99.100/
# 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:5.6-apache
… docker\test\code と /var/www/html を共有
$ docker container exec -it php bash
… phpコンテナのターミナルに接続
# ls /var/www/html
… 同期されたファイルを確認
# exit
ブラウザで以下にアクセスし、phpinfoが表示されれば成功
http://192.168.99.100/
$ docker container rm -f $(docker container ls -a -q)
… 確認できたら終了
「$PWD」は現在のフォルダを表す
$PWD/docker/test/code:/var/www/html をフルパスで指定する場合、以下のようにする。相対パスでは指定できないみたい
/c/Users/refirio/docker/test/code:/var/www/html
■フォルダ共有(C:\Users 配下以外を対象にする)
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:5.6-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 9dbd220d50c7
… 削除しておく
docker\php_create_file\Dockerfile
… Dockerfileを作成
FROM php:5.6-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)
… 作成済みのコンテナをいったん終了
■イメージをファイルとして保存
$ 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 0515d11a2846
… 削除しておく
$ 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:7.4-apache」をもとに、追加でファイルを作成するだけのイメージを作成する
docker\php_create_file\Dockerfile
… Dockerfileを作成
FROM php:7.4-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 を以下のように編集
docker\php_create_file\Dockerfile
FROM php:7.4-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を扱うためのライブラリを追加する
それを新しいイメージとして保存する
docker\test\php\Dockerfile
… Dockerfileを作成
FROM php:5.6-apache
RUN apt-get update && \
docker-php-ext-install pdo_mysql mysqli mbstring
$ docker image build -t php:custom docker/test/php
… Dockerfileをもとに、新しいイメージをビルド
$ docker image ls
… 作成されたイメージを確認
docker/test/php をフルパスで指定する場合、以下のようにする。フォルダ共有のときとはルールが違うので注意
C:/Users/refirio/docker/test/php
■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に接続
mysql> show databases;
… testデータベースを確認(「MYSQL_DATABASE=test」によって自動作成されている)
mysql> create database test;
… 別途データベースを作成する場合
mysql> exit;
/c/Users/refirio/docker/test/code(/var/www/html)内に適当なデータベース管理ツールを設置し、テーブルを作成&データ登録&表示をテスト
http://www.php-labo.net/download/new/db_admin/ の場合、以下の接続情報でアクセスできた
define('HTTP_URL', 'http://192.168.99.100/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://192.168.99.100/
http://192.168.99.100/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 5.6-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
■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\docker-compose.yml
version: '3'
networks:
my_network:
services:
mysql:
container_name: mysql
volumes:
- ./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 /c/Users/refirio/docker/compose_test/docker
$ docker-compose up
… docker-compose.ymlをもとに起動
ログが以下でストップするが、こういうものみたい
[Note] Beginning of list of non-natively partitioned tables
[Note] End of list of non-natively partitioned tables
ブラウザから
http://192.168.99.100/ にアクセスすると、以下のようなアクセスログが表示される
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 /c/Users/refirio/docker/compose_test/docker
$ 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> exit;
$ exit
/c/Users/refirio/docker/compose_test/code(/var/www/html)内に適当なデータベース管理ツールを設置し、テーブルを作成&データ登録&表示をテスト
http://www.php-labo.net/download/new/db_admin/ の場合、以下の接続情報でアクセスできた
define('HTTP_URL', 'http://192.168.99.100/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\docker-compose.yml
version: '3'
networks:
my_network:
services:
mysql:
container_name: mysql
volumes:
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- ./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:
- ./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
■読み書きの制限
以下のように「: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
■古い通信方法
※PHPコンテナ起動時に「--link mysql:mysql」のようにMySQLコンテナを指定することで、コンテナを連携させることができる
が、それは古い方法で今は非推奨
※これまで紹介したように、ネットワークを作成し、そこに参加させることでコンテナを連携させる方法が推奨されている
通信できない例
$ docker container run --name mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7
$ docker container run --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:custom
「--link」で通信(非推奨の古い方法だが、参考までに)
$ docker container run --name mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7
$ docker container run --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 --link mysql:mysql -d php:custom
Docker Compose での「--link」使用例(非推奨の古い方法だが、参考までに)
mysql:
container_name: mysql
volumes:
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
environment:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: test
image: mysql:5.7
php:
container_name: php
volumes:
- ..:/var/www
ports:
- 80:80
links:
- mysql:mysql
image: php:custom
■Docker Compose と Dockerfile の併用
例えば以下のファイルを作成しておく
compose_test\php\Dockerfile
FROM php:custom
RUN touch /root/test1.txt
RUN touch /root/test2.txt
compose_test\docker\docker-compose.yml の最後を以下のように修正すると、phpフォルダ内のDockerfileから起動されるようになる
image: php:custom
↓
build: 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
■同一ネットワークの他端末からのブラウザアクセス
※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
ここまでできれば、Dockerを開発環境として使えそう
■値のやりとり
■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_php5_mysql\html\index.php
<?php phpinfo() ?>
apache_php5_mysql\docker\mysql\Dockerfile
FROM mysql:5.7
apache_php5_mysql\docker\mysql\my.cnf
[mysqld]
character-set-server=utf8
apache_php5_mysql\docker\php\Dockerfile
FROM php:5.6-apache
RUN apt-get update && \
docker-php-ext-install pdo_mysql mysqli mbstring
apache_php5_mysql\docker\php\php.ini
date.timezone = Asia/Tokyo
apache_php5_mysql\docker\docker-compose.yml
version: '3'
networks:
compose_network:
volumes:
compose_mysql_data:
services:
mysql:
container_name: mysql
volumes:
- ./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: ./mysql
php:
container_name: php
volumes:
- ./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: ./php
■設定の上書き
docker-compose.yml と同じ階層に docker-compose.override.yml を置くと、その設定内容が優先される
apache_php5_mysql\docker\docker-compose.yml
version: '3'
services:
mysql:
environment:
MYSQL_USER: user
MYSQL_PASSWORD: userpass
■よく使用するコマンド
$ cd /c/Users/refirio/docker/apache_php5_mysql/docker
$ 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://192.168.99.100/
以下のようなコードで、PHPからMySQLに接続できる
エラーになる場合、mysqlコンテナの起動が完了していない可能性があるので待つ
<?php
try {
$pdo = new PDO(
'mysql:dbname=test;host=mysql',
'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());
}
■コマンドまとめ
■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
■その他の環境構築例
■PHP7+GD
※Dockerfileのみ抜粋
libfreetype6-dev, libjpeg62-turbo-dev, libpng-dev を事前にインストールする必要がある
また、docker-php-ext-configure gd --with-jpeg-dir=/usr がないとJpegが扱えない
※最後の rm や a2enmod の部分は省略できるか。要検証
apache_php7_mysql\docker\php\Dockerfile
FROM php:7.3-apache
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
&& docker-php-ext-configure gd --with-jpeg-dir=/usr \
&& docker-php-ext-install gd pdo_mysql mysqli mbstring \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& a2enmod rewrite
PHP GD をインストールするための Dockerfile の少し複雑な内容メモ - oki2a24
https://oki2a24.com/2018/08/29/how-to-install-php-gd-to-php-5-6-apache-with-dockerfile/
KUSANAGI RODのphp7でphp-gdのJPEGを有効にする - Qiita
https://qiita.com/tpywao/items/1243b0311561beaf77d2
■PHP7.4+GD(2021年5月に検証)
ECCube用に作っていたものだが、以下にPHP7.4環境ができた(ただ、mod_rewriteの有効化が難しかったのでECCubeは起動できなかった)
docker/eccube4_php74
以下をベースにPHP7.4用の環境にする方がいいか。GD関連は eccube4_php74 から移植するか。要検討
docker/apache_php7_mysql_gd
【PHP】Docker PHP7.4系でgdをインストールしてimagecreatefromjpegを使う | WEBコンサルティング・WEB制作のフリーランス uiuifree
https://uiuifree.com/blog/develop/docker-gd-php-7/
php7.4-apacheイメージのビルド時に "No package 'oniguruma' found" エラーが発生する際の対処 - Qiita
https://qiita.com/June8715/items/1df5958b95c1ff2d4c1b
PHP7.4のインストール時に発生したエラーと解決方法 | Public Constructor
https://public-constructor.com/php74-installation-errors/
コマンドラインでMySQLに接続する際、以下の警告が表示された
# mysql -u user -p
mysql: [Warning] World-writable config file '/etc/mysql/conf.d/my.cnf' is ignored.
# cd /etc/mysql/conf.d
# chmod 644 /etc/mysql/conf.d/my.cnf
としても変化しない
mysqld: [Warning] World-writable config file '/etc/mysql/conf.d/my.cnf' is ignored.
https://sunday-morning.app/posts/2020-07-31-mysqld-warning-world-writable-config-file-etc-mysql-conf...
Windows + docker-compose + mysql で文字化けさせない方法 - Qiita
https://qiita.com/waterada/items/1dbf6a977611e0e8f5c8
文字化けはしていないので、いったんこのまま進めた
$ docker container exec -it php bash
# composer install --no-plugins --no-scripts
bash: composer: command not found
Composerが無いのでエラーになった
ECCube用なら以下で導入できるが、必要に応じてDockerでの構築内容に含めておきたい
# curl -sS
https://getcomposer.org/installer | php -- --version=1.10.15
# mv composer.phar /usr/local/bin/composer
# composer
http://eccube4-docker.local/install にアクセス…すると404エラーになる
mod_rewriteが有効になっていない
対策にとして以下を試していたが、コンテナの再起動によって作業が消えてしまう
いったん作業を中断
# apt-get install vim
Docker - docker コンテナの中で vim が使えない場合 - Qiita
https://qiita.com/YumaInaura/items/3432cc3f8a8553e05a6e
# cd
# vi .vimrc
以下を記述
set clipboard=unnamed,autoselect
dockerコンテナ内で実行したviで、マウス右クリックでペーストしようとしたら"(insert) VISUAL"となってペーストできない場合の対応方法 - Qiita
https://qiita.com/VA_nakatsu/items/b92771fcda9023cb2bb6
# vi /etc/apache2/sites-available/000-default.conf
「<VirtualHost *:80> 〜 </VirtualHost>」内の最後に以下を追加
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
# exit
$ docker-compose up -d
$ docker-compose down
$ docker-compose up -d
$ docker container exec -it php bash
■nginx
C:\Users\refirio\docker\ 内に以下を作成するとする
※nginx.conf の「sendfile off;」は、これが無いとHTMLファイルを更新しても反映されない(キャッシュされる)
後から追加した場合、Dockerを起動しなおせばいい(buildまでは不要)
ただしHTMLファイルに何らかの変更をするまではキャッシュされ続けるみたい
※「location / { }」のブロックは省略しても大丈夫みたい
nginx\html\index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>nginx</title>
</head>
<body>
<h1>nginx</h1>
<p>テストページ。</p>
</body>
</html>
nginx\docker\nginx\Dockerfile
FROM nginx:1.12
nginx\docker\nginx\nginx.conf
server {
listen 80 default_server;
server_name _;
index index.html;
root /var/www/html;
sendfile off;
location / {
}
}
nginx\docker\docker-compose.yml
version: '3'
services:
nginx:
container_name: nginx
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro
- ..:/var/www:rw
environment:
TZ: Asia/Tokyo
ports:
- 80:80
build: ./nginx
起動方法
$ cd /c/Users/refirio/docker/nginx/docker
$ docker-compose build
$ docker-compose up -d
http://192.168.99.100/ でアクセスできる
各コンテナに接続する場合
$ docker container exec -it nginx bash
終了方法
$ docker-compose down
■nginx(ホスト名でのアクセスについて)
nginx.conf の以下の部分を
listen 80 default_server;
server_name _;
一例だが以下のように設定すると、
server_name nginx.test;
C:/windows/System32/drivers/etc/hosts で以下の設定をして
http://nginx.test/ にアクセスする必要がある
192.168.99.100 nginx.test
バーチャルホストが前提の場合は問題ないが、Dockerなら通常1つの環境で1つのアプリケーションを扱う
開発環境として使うならhostsの設定無しでアクセスできる方が手軽で良さそう
■nginx+PHP7
C:\Users\refirio\docker\ 内に以下を作成するとする
nginx_php7\html\index.php
<?php phpinfo() ?>
nginx_php7\docker\mysql\Dockerfile
FROM mysql:5.7
nginx_php7\docker\mysql\my.cnf
[mysqld]
character-set-server=utf8
nginx_php7\docker\nginx\Dockerfile
FROM nginx:1.12
nginx_php7\docker\nginx\nginx.conf
server {
listen 80 default_server;
server_name _;
index index.php index.html;
root /var/www/html;
sendfile off;
location / {
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
}
}
nginx_php7\docker\php\Dockerfile
FROM php:7.0-fpm
RUN apt-get update && \
docker-php-ext-install pdo_mysql mysqli mbstring
nginx_php7\docker\php\php.ini
date.timezone = Asia/Tokyo
nginx_php7\docker\docker-compose.yml
version: '3'
networks:
compose_network:
volumes:
compose_mysql_data:
services:
mysql:
container_name: mysql
volumes:
- ./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: ./mysql
php:
container_name: php
volumes:
- ./php/php.ini:/usr/local/etc/php/conf.d/php.ini:ro
- ..:/var/www:rw
environment:
TZ: Asia/Tokyo
networks:
- compose_network
build: ./php
nginx:
container_name: nginx
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro
- ..:/var/www:rw
environment:
TZ: Asia/Tokyo
ports:
- 80:80
networks:
- compose_network
build: ./nginx
起動方法
$ cd /c/Users/refirio/docker/nginx_php7/docker
$ docker-compose build
$ docker-compose up -d
http://192.168.99.100/ でアクセスできる
各コンテナに接続する場合
$ docker container exec -it nginx bash
$ docker container exec -it php bash
$ docker container exec -it mysql bash
終了方法
$ docker-compose down
Docker + Nginx + PHP-FPM なら40秒くらいで環境を準備できる docker-compose が楽しくなってきました。 - Qiita
https://qiita.com/mochizukikotaro/items/b398076cb57492980447
CentOSにてnginxでPHPを動かす - Qiita
https://qiita.com/utano320/items/36b6eac2bbd5bb5657f6
CentOS 6.5でnginxを動かす為の最低限の設定 - Qiita
https://qiita.com/ksworks/items/cbc7b73c62c5e115d830
nginxで /welcomeとかを静的ファイルにマッピングする - Qiita
https://qiita.com/sarukun99/items/e30cc945ec6243ebac57
【php】nginxとphp-fpmが動く環境を手っ取り早く入れるメモ - tweeeetyのぶろぐ的めも
http://tweeeety.hateblo.jp/entry/2015/07/05/224827
nginx と PHP-FPM の仕組みをちゃんと理解しながら PHP の実行環境を構築する - Qiita
https://qiita.com/kotarella1110/items/634f6fafeb33ae0f51dc
■nginx+PHP7(URLルーティングの例)
nginx_php7\html\index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>nginx + PHP7</title>
</head>
<body>
<h1>nginx + PHP7</h1>
<?php
if (!isset($_SERVER['REQUEST_URI'])) {
$_SERVER['REQUEST_URI'] = '/';
$_SERVER['SCRIPT_NAME'] = '/index.php';
}
$request_uri = explode('/', strtok($_SERVER['REQUEST_URI'], '?'));
$script_name = explode('/', $_SERVER['SCRIPT_NAME']);
for ($i = 0; $i < sizeof($script_name); $i++) {
if ($request_uri[$i] === $script_name[$i]) {
unset($request_uri[$i]);
}
}
$_params = array_values(array_map('urldecode', $request_uri));
print('<pre>');
print_r($_params);
print('</pre>');
?>
</body>
</html>
nginx_php7\docker\nginx\nginx.conf
server {
listen 80 default_server;
server_name _;
index index.php index.html;
root /var/www/html;
sendfile off;
location / {
try_files $uri /index.php?$query_string; … URLルーティング用に追加
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
}
}
http://192.168.99.100/
http://192.168.99.100/test1
http://192.168.99.100/test1/test2
などでアクセスし、PHPでパラメータを解釈できていることを確認する
■nginx+PHP7(Laravelの使用例)
※Laradockによる開発環境構築は「Laradockによる開発環境構築」を参照
※あらかじめ、nginx+PHP7でURLルーティングありで
http://192.168.99.100/ にアクセスできるところまで構築しておく
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://192.168.99.100/
以降は動作確認。要点のみ
日本語化などを試す
$ 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_php5_postgresql\html\index.php
<?php phpinfo() ?>
apache_php5_postgresql\docker\php\Dockerfile
FROM php:5.6-apache
RUN apt-get update && apt-get install -y libpq-dev && docker-php-ext-install pdo pdo_pgsql mbstring
apache_php5_postgresql\docker\php\php.ini
date.timezone = Asia/Tokyo
apache_php5_postgresql\docker\postgresql\Dockerfile
FROM postgres:9.2
apache_php5_postgresql\docker\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: ./postgresql
php:
container_name: php
volumes:
- ./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: ./php
$ cd /c/Users/refirio/docker/apache_php5_postgresql/docker
$ 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=# SELECT * FROM test LIMIT 100;
no | name
----+------------
1 | 山田タロウ
2 | 山田ハナコ
(2 rows)
test=# \q
http://192.168.99.100/
以下のようなコードで、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
「postgresql-dev libpq-dev」は無くても動いた。付けておくべきかは要検証
portの指定は無くても動いた。付けておくべきかは要検証
■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\docker-compose.yml
version: '3'
networks:
compose_network:
volumes:
compose_mysql_data:
services:
mysql:
container_name: mysql
volumes:
- ./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: ./mysql
node:
container_name: node
volumes:
- ./node:/var/nodeapp:rw
command: node /var/nodeapp/server.js
environment:
TZ: Asia/Tokyo
PORT: 3000
ports:
- 3000:3000
networks:
- compose_network
build: ./node
nginx:
container_name: nginx
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro
- ..:/var/www:rw
environment:
TZ: Asia/Tokyo
ports:
- 80:80
networks:
- compose_network
build: ./nginx
起動方法
$ cd /c/Users/refirio/docker/nginx_node/docker
$ docker-compose build
$ docker-compose up -d
http://192.168.99.100:3000/ ... node.js
http://192.168.99.100/ ... nginx経由でnode.js
■Node.js(Docker Compose なしで単体起動する場合)
dockerコンテナ上でnode.jsのサーバを起動し、ホスト端末からアクセスする - Qiita
https://qiita.com/hotdrop_77/items/a2ca316c97ba4b748d9a
C:\Users\refirio\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 /c/Users/refirio/docker/node:/var/nodeapp -p 3000:3000 -it node:8.4.0 /bin/bash
# node /var/nodeapp/server.js
http://192.168.99.100: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
■前提
・/c/Users/refirio/docker/laravel を作業ディレクトリとする(ここが共有ディレクトリとして設定される)
・/c/Users/refirio/docker/laravel/laradock にLaradockをインストールするものとする
・/c/Users/refirio/docker/laravel/blog にプロジェクトをインストールするものとする(複数プロジェクトがあれば、同階層に作成する)
・MySQLはデフォルトで8が使用されるが、セキュリティが強化されて扱いづらいので5.7に変更して使用する
【Docker】MySQL8.0系を使う時に発生する問題について - websandbag ブログ
http://blog.websandbag.com/entry/2018/05/17/121730
■Laradockの起動
$ cd /c/Users/refirio/docker/laravel
$ git clone
https://github.com/laradock/laradock.git /c/Users/refirio/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://192.168.99.100/
(この時点では「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://192.168.99.100: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 /c/Users/refirio/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/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\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: ./mailhog
mysql:
container_name: mysql
volumes:
- ./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: ./mysql
wordpress:
container_name: wordpress
volumes:
- ./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: ./wordpress
■設定の上書き
docker-compose.yml と同じ階層に docker-compose.override.yml を置くと、その設定内容が優先される
wordpress\docker\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 /c/Users/refirio/docker/wordpress/docker
$ 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://192.168.99.100/
http://192.168.99.100: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:5.6-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
$ 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
$ docker-compose build
$ docker-compose up -d
$ docker-compose down
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
… ファイルの最後に以下を追記
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RUN usermod -u 1000 www-data && \
groupmod -g 1000 www-data
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
■再実行例
最初から実行しなおしたい場合の例
コンテナを終了し、データベースを削除し、不要なファイルを削除してからGitに一致させている
$ cd /home/ec2-user/docker/wordpress/docker
$ docker-compose down
$ docker volume rm docker_compose_wordpress_data
$ cd /home/ec2-user/docker/wordpress
$ sudo rm -rf html
$ git reset --hard origin/master
■トラブル
■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環境)」の方法で一応は解決した
より良い方法が無いかは、また検証したい
■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
■メモ
以下、引き続き検証メモ
■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 192.168.99.100:49160
http://192.168.99.100: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://192.168.99.100:3000/
次回からは以下で起動できる
$ cd /c/Users/refirio/docker/compose_ruby
$ docker-compose build
$ docker-compose up -d
$ docker-compose down
docker-compose.yml を以下のように編集すると、
http://192.168.99.100/ でアクセスできた
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_php5_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