はじめてのDocker
プラハチャレンジのDB課題にてDocker使って実際にテーブル作ってみようとのこと。
Dockerやらないとと思いつつ避けて生きてきた…ついにやるときがきた。なんとなく聞いたことがあるレベルで、まだそもそもその有用性があまりわかっていない
書いてる途中で本が来たので追記する(出典1)→わかりやすい。概念を知る最初の本としてよさそう。ただ入門書で、実践的なDockerfileの書き方とかまでは言及されてないのでがんばって調べる。どんなこと調べてても入門の資料は豊富にあるが、実践の資料ってなかなか見つからない…githubを漁るとか?
こんなサイトもあった
そもそもなんでDockerが必要
例えばフロント開発していて、素で環境構築するのと、Docker上でするのと、何が違うのだろうか…
下記らしい…
- コード化されたファイルを共有することで、どこでも誰でも同じ環境が作れる。
- 作成した環境を配布しやすい。
- スクラップ&ビルドが容易にできる。
けど、みんなMac使ってたらそこまで環境差異なくない…?という素人考えしか現時点では湧いてこない。開発環境をそのまま本番環境に持っていけるとのことだが、それもいまいちピンとこないな…クラスタ構成ってなに。ミドルウェアってよく出てくるけどなんか自分の中ではぼやけてしまっている…全然ピンときてないし触ってみるしかないな。
インフラのコード化がでかいのかな?DBとかそのレベルまでインストールしたインフラコードができるのか。それはすごいかも。インフラのpackage.json?
これわかりやすいかも
出典1より
Dockerとは「データやプログラムを隔離できる」仕組み。依存ソフトウェアやライブラリなどを隔離しておかないと、バージョン管理などが厳しい。あとはコンテナは持ち運べる。
とりあえず動かす
→やっぱCLIだけなら無料なのか。と思ったけどリンク先に行くと質問消えてるな。gitで考えるとこういう↓関係性?
- git <-> Docker CLI + Docker Engine
- source tree <-> DockerDesktop:これが有料
- github <-> DockerHub
上記イメージちょっと違ったかも。出典1より、そもそもDockerはLinuxでしか使えない。だから、下記の方法で使う必要がある。
- Linuxであれば、DockerEngineをいれれば使える
- それ以外
- 仮想化技術等を使ってなんとかLinuxを入れて、その上にDockerEngineを入れる
- LinuxっぽいものなどがパッケージングされたDockerDesktopを入れる
なぜLinuxでしか使えないかは、LinuxカーネルのLinuxコンテナ機構?というのを使っているかららしい。
RancherDesktop
containerd vs dockerd
This is provided by either the Docker CLI (when you choose Moby/dockerd as you engine) or nerdctl (when you choose containerd as your engine). nerdctl is a "Docker-compatible CLI for containerd" provided by the containerd project.
インストールして最初に選択する画面でたが、何が違うの…
dockerdの方はdockerと同じコマンドでできるってこと…?dockerも内部的にはcontainerdを使っている。たぶん個人でちょっと使うくらいのレベルなら、コマンドがdocker xxxになるか、nerdctl xxxになるかくらいの違いなのかな?細かくは機能の違いがあるようだが…Dockerエコシステムとかとの互換性を考えるとdockerにしとくのが無難かな?あとはkubernetesがcontainerdベースだから云々みたいなの書いてあるがよくわからんのでとりあえずdockerにしてみる(dockerある程度わかったところでこの辺ちゃんと読めばわかりそう)
立ち上げたらterminalでdockerコマンドが使えるようになった。こういう感じなのね。docker info
と入力してClientとServerの情報がでれば準備完了とのこと。
Docker with MySQL
もともとはDB課題用にDockerを触りはじめたので、MySQLいりのDockerを立ち上げたい。
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
some-mysqlはコンテナの名前で自分でつけたいやつ。my-secret-pwも自分で設定。tagがいまいちわからない。何が違うんだろう。とりあえず試すだけだしlatestでよさそう。
- 8.0.32, 8.0, 8, latest, 8.0.32-oracle, 8.0-oracle, 8-oracle, oracle
- 8.0.32-debian, 8.0-debian, 8-debian, debian
- 5.7.41, 5.7, 5, 5.7.41-oracle, 5.7-oracle, 5-oracle
- 5.7.41-debian, 5.7-debian, 5-debian
Docker Composeありなし
DockerComposeがなにかわからなかったが、起動時の設定をファイル化しておけるのか…なしでもコマンドの引数に指定していけば起動できるが、まあ普通はめんどいから、さくっとデフォルで起動だけしたいみたいな感じでなければ普通はDockerCompose使うんだろうな。
なし
ちなみになしで起動するならこんな感じらしい。一回やってみる。
# Docker-hubからMySQLのイメージをインストールする
$ docker pull mysql
公式にはdocker pullないけど必要なの?と思ったけど一番上に別枠で書いてあった。たぶんするのが当たり前なんだろうな…。pullしてもファイル増えないが…RanckerDesktopがどこかに持ってる?RanckerDesktopのImagesには追加されてる。500MB…結構あるな。けど仮想マシンとかと比べると小さい?
# インストールしたイメージから、コンテナを起動・作成する
# MYSQL_ROOT_PASSWORDにログインする際のパスワードを設定する
$ docker run -it --name mysql-docker-test -e MYSQL_ROOT_PASSWORD=mysql -d mysql:latest
オプションはこんな感じらしい。イマイチわからんけどつけておく。
ぬ…なんか変な文字列で終わった。どゆこと?docker ps
すると行が追加されてる。変な文字列はContainerIDか。てことは成功したのかな?成功しましたとか出してほしいな…
$ docker exec -it test-wolrd-mysql bash -p
pオプションなんだろ…--privileged
?調べても出てこんな。portオプション?コピペミス?怖いから外す。
おお、入れたっぽい。
# MySQLのコンテナにログインする
$ mysql -u root -p -h 127.0.0.1
ここからはmysqlの領域。この辺かな?hostは省略してもよさそうなので省略。
入れた!すごい!
でもこれどうやって閉じるの。mysqlはexitでいいとしてbashから抜けるのは…exitでいけた。けど、なんかbashから抜けるだけとかコンテナ停止とかいろいろありそう?あとでちゃんと調べた方がいいかも。今docker ps
したらまだ生きてるっぽい?
別途まとめるか…
あり
とりあえずdocker-compose.yml
を作ってそこに設定を書いていけばいいっぽい。
あれ、これ見ると複数コンテナ作るわけじゃないしDockerfileでいいんじゃ…
ああ、やっぱDockerfileだけでいいのか。たぶんDockerfileとDockerComposeの役割を全く理解してないな…とりあえず両方やってみよう。
公式にDockerfileのサンプルないのなんでだと思ったらあった。タグのところにあったのか。でもこれ長すぎて何してるのかわからない…なんか煮詰まってきた。。Dockerfile/DockerComposeがよくわからない。
ちょっとDockerfileとかは別スレッドにしよう
出典1より、そもそもDockerは複数コンテナ同時稼働するのが前提なのか…だからDockerComposeなのかな?複数コンテナ同時ってのがまだイマイチわかってないが、1Docker1アプリみたいな思想もあるらしいし、ApacheとMySQLと…っていう複数もあれば、環境とかバージョンの違いで複数とかもあるのかな?たぶん今回みたいにMySQLとか1アプリをちょっと動かしたいだけっていうケースに実質的なメリットはあまりないが、まあ勉強のため…まあでも環境を隔離できる、他のメンバに共有できるメリットはあるか。
Dockerfile
docker image build -t イメージ名[:タグ名] [Dockerfileが配置されているディレクトリパス]
docker image build -t xxxx/xxxx:latest .
これでDockerfileからイメージが作れる。公式のDockerImageとかもDockerfile…?
ふむふむ…公式のやつはビルド済みのやつが配布されてるってこと…?
Dockerfileは公式イメージをそのまま使うんであれば不要なんだな。それになにかCOPYしたりADDしたり引数をいっぱい指定したりする場合は、Dockerfileとして記述した方がわかりやすい。
FROM mysql:8
ENV MYSQL_ROOT_PASSWORD=root
MySQLのイメージ作成する場合の最小構成。
ただ、ここだとDockerComposeだな…Dockerfileでテーブルの作成までやっているケースが検索に出てこない。やろうと思えばできるのだと思うが、とりあえず記事通りDockerComposeでやってみるか…
DockerCompose
Dockerfileとの違いを出典1よりそのまま引用
DockerComposeは、いわば、「docker run」コマンドの集合体で、作成するのは、コンテナと周辺環境です。ネットワークやボリュームも合わせて作成できます。
一方、Dockerfileは、イメージを作るものなので、ネットワークやボリュームを作成できません。
チュートリアル中エラーがでた。DockerComponse使わずに構築した時は出なかった気がするが…
versionってなんなんやろ…
つまり、versionは後方互換性のための飾りで、Docker ComposeはCompose Specificationに則ったスキーマを利用する、ということである。
気にしなくてよさそう?
とりあえずここまではできた。あまり原理はわかってないが…フォルダの構成とかはMySQL側の設定?MySQLのrootレス設定とかもあるらしいけど一旦飛ばす。
こちらもできたが、記事の通りだと無理で、initDb.sql
にuse mysqldb;
を追加した。これでテーブルを作成した状態のDBを起動できる!
こちらのエラーが発生した。コマンド追加したのがいけなかったぽい?
command:
echo test
Kubernetes
複数サーバが必要になるようなある程度以上の規模のシステムで使うもの。
DockerComposeとの違いを出典1よりそのまま引用
Kubernetesは、コンテナを管理するものであるのに対し、DockerComposeは、ざっくり言えばコンテナを作って消すだけで、管理機能はありません。
結構大変そうなので今はおいておこう…とりあえず下記を入れる必要があるらしい(手元で試してみるだけならDockerDesktopに内蔵されている)
- マスタノード(コンテナを管理するサーバ)
- Kubernetes/kubectl
- CNI
- etcd
- ワーカーノード(実際にコンテナを入れるサーバ)
- Kubernetes
- CNI
- ContainerEngine
Kubenetesはあるべき姿を管理者が記述しておいて、あとはKubenetesが自動でその状態を維持してくれるイメージ。DockerComposeはどうやってあるべき姿を作るかを管理者が記述して実行するイメージ。
AWSのオートスケールとは何が違うのだろうか…組み合わせて使う?
run, cmdの違い
run=docker build
cmd=docker runのデフォルト挙動
Dockerのライフサイクル
Dockerは作っては捨てるものらしい。あんまりわかってないが、アップデートするなら現行を動かしたまま次のDockerを別途作って、できたら移行するみたいな感じ?
あとマウント!Docker調べると結構コマンドとかが出てきたがなんのためにそんな頻繁に出てきそう&重要そうに書いてあるのかわからなかったが、異なるDocker間でデータを共有するためなのかな?Dockerを削除すればデータは消えてしまうとのことなので、旧Dockerから新Dockerにデータを引き継ぐには、どちらもDockerが乗っているクライアントのディスクにマウントしてしまえばいいってことか。
でもDBの構成を変えたときとかデータ構成が変わりそうなケースとかどうするんだろう。
コマンド
ライフサイクル等々入れるとこんな感じか…?
フロー図の描画のされ方ってコントロールできないんだろうか…→subgraphとかでなんとかできそうだったが一旦これで。
pull + create + start = run
イメージのまま移動はできないので、tar化イメージ/Dockerfile、またはDockerHub経由での移動となる。
イメージからDockerfileへの変換は公式のツールとかはなさそう?自作している人はいた。
Awsとかだとfargateにはdocker runtimeが入っている?
ECRにimageをアップ
ECRを参照して、fargateでコンテナを動かす
コンテナが実際に動いているやつ。Imageはテンプレ的なもの
docker compose
- build + run
- 複数imageをまとめて動かせる
メモ
- dockerのローカル開発時つかう?
- ローカルでも使ったほうがいいけど、
- Dev以降はDockerになるからわかるはず
- デプロイ
- dockerfileはstart用だけが多い
- マルチステージビルド
- ビルドして、必要なものだけコンテナにコピー
- PORTをDockerのオプションにしてもいいが、composeに入れておけば省略できる
マウント
ボリュームマウント
Docker内にフォルダを作る…?コンテナ内にすでにフォルダ構造はあるわけだし追加で特に何もしなくてもいけそうだけど…Dockerはこちらを推奨しているらしい。コンテナを他のユーザとかに移した時は消えるんだろうか?
あー何を言っているんだ…コンテナ消しても消えない領域を別途作るっていうことだから、コンテナ内に普通にファイルを置くのとは違うし、他のコンテナにもマウントできる。volumeはvolumeとして独立して存在できるから、docker volume create xxx
で作成して、その後マウントする。
バックアップ大変。バックアップのためにコンテナを起動して、起動時のオプションでvolumeを圧縮して別のバインドマウントされたフォルダにコピーするらしい。
バインドマウント
これはわかりやすい。Docker外にあるフォルダ/ファイルをマウントする。たぶんボリュームマウントだとファイルを編集してボリュームに移す操作が必要そうだが、バインドマウントであれば直接編集できそう。ただ、他の人に移す場合はパスが変わってしまう可能性が高いのでそこは修正する必要がある。
その他
Docker外からのアクセス
createするときに、ポートの設定が必要。-p
オプションを使って、
-p ホストのポート番号:コンテナのポート番号
-p 8080:80
Docker一強は終わるかも?
ただ、コンテナ技術はますます重要になりそう。とりあえず今はDockerを学んでおいて損はなさそう。とはいえやっぱDockerHubが強いのかな?Nodeにおけるnpm的な。Dockerの歴史もわかるすごい記事
terminal補完
補完を入れようとしたがもとから入れてるpreztoとoh-my-zshの同居のさせかたがわからなかった…沼りそうだったので一旦断念。rdctlならいける…?シェルよくわからんので一旦置いとく。
雑記
- Javaとか言語実行環境も作れるのかー便利。