なんでDockerの一人勝ちということになったのかというとゲストOSが不要ということです。従来のハイパーバイザ型と比較してOSのカーネル部分(OSのほとんどの部分です)自分のPC、つまりホストマシンと共有することでサイズ的には極小で仮想環境を構築できるというわけです。一人勝ちの後押しをしたのはサーバーレスというクラウドサービスでした。Azureの「Azure Container Instances」、AWSの「Amazon Elastic Container Service(AWS Fargate )」、GCPの「Cloud Run」などDockerコンテナをそのままデプロイできるシステム(つまりサーバーレスと言われるようにサーバーの構築や設定が不要になる)がすでに実用面で充分な力を発揮しているところです。
とはいえ、自分のPCでいろいろやってみるというレベルでも充分にその役目と用途、目的を達成できるというところがDockerのよいところです。
ここではmac環境を基本に解説していますが、基本的にはwindows環境も同じです。
macの場合はchipの選択が必要です。2021-10-18現在appleが独自開発したCPUとintel製のCPUと二種類あってDockerの機能はその影響を受けます。ダウンロードソースには二種類あるので気をつけましょう。
https://hub.docker.com/editions/community/docker-ce-desktop-mac/
無事インストールできたら、Docker Desktop for Macを起動して、ターミナルでバージョンだけ確認しておきましょう。
$ docker --version
Docker version 20.10.6, build 370c289
これでdockerが使えるようになっています。
dockerは「何でもできるようになっている」が基本です。従来サーバー側でやっていたことアプリ側でやっていたことは何でもできます。もちろんCDNのdocker化とかナンセンスな開発などもありますが、それでもほとんど再現できます。もし欠点を探すとしたら複雑なネットワークを設定するとか妙なプロキシをかますとかそういったことは kubernetesという別の仕組みを利用しなくてはいけないということがありますが、そもそもネットワークはコンテナの仕事ではないので欠点とはいえないでしょう。Dockerはアプリケーションのコンテナ化に焦点を当てています。
Dockerの仕組みはいたるところで解説されているので、ここでは割愛します。ただ順序だけ明確にしておこうと思います。上述したようにゲストOSが不要であるということで基盤になるOSのダウンロードなどは不要です。DebianにしろCentOSにしろUbuntuにしろOSをコンテナ化するときはカーネル以外の最低限のファイルを取り込むことで実現します。この「最低限のファイル」がイメージと呼ばれるディスクをまるごとコピーしたデータになります。ただ実際はまるごとコピーというふうにはなっていなくてDocker(コンテナ)に特化したイメージになっているので通常のイメージバックアップなどと区別してdocker-imageという言い方をします。dockerイメージはdockerアプリケーションがないと起動できません。Dockerの基本的な流れは、
docker-imageのダウンロード(pull)
dockerの設定(Dockerfile)
dockerの起動
という流れになります。docker-imageの保管場所はdockerのアプリケーションがよしなにやってくれるので、物理的な保存場所はほとんど意識しなくてOKです。実際は~/Library/Containers/com.docker.docker/Data/vms/0
に保存されていますが、ここを見てもあまり意味がないので、削除やpullなどの管理はコマンド上で行います。いろいろありますが手を動かしてみないことにはわからないことが多いのがDockerなので、いろいろ手を動かしてみましょう。
とりあえずhello worldしてみましょう。ほとんど意味がないhello worldですが、以下を実行してみてください。PC内(またはDockerを起動しているマシン内であれば)どこででも実行してOKです。
$ docker run hello-world
Hello from Docker!
いろいろ補足的なメッセージがいろいろ出ますが「Hello from Docker!」が表示されれば成功です。
ここではDockerの基本的なことをすべてしています。dockerのhello-worldイメージをpullしてきて、コンテナを起動し「Hello from Docker!」を出力しています。(後述しますがdocker run
は該当のイメージがあれば、そのdocker-imageのlatest(最新)を自動的にpullしようとします。)
ではhello-worldのdocker-imageをdockerhubで探してみます。
$ docker search hello-world
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
hello-world Hello World! (an example of minimal Dockeriz… 1544 [OK]
こういう感じでイメージを検索でいます。dockerhubのwebサイトではhttps://hub.docker.com/_/hello-world
で見ることができます。こんな感じで必要なイメージを検索してバージョンや機能など詳細情報を確認したりすることができます。
チュートリアルとして最もわかりやすいのがWEBサーバーの構築かと思います。つい最近まで私達はちょっとした開発でも動的なプログラム言語が必要な際にはそれ相当の開発環境をつくらないといけませんでした。それが比較的容易にできるのと、その開発環境をメンバーで共有し更にアップデートできるというのがとてもよいのです。さっそくWEBサーバーを作ってみましょう。WEBサーバーを作成するにはいくつかの方法があります。というよりもどういったイメージを選択するか?という問題でもあります。ここではhttpd:2.4
というイメージを使ってみます。
ここではApacheの設定自体をよくわかっている方はおもしろいと思いますが、わからない人は機械的に実行するだけでもWebサーバーを動かすことができます。
まずはイメージを落とします。今回はhttpd:2.4をpullします。
#docker pull [image]
$ docker pull httpd:2.4
イメージがpullできているかどうか確認します。
$ docker images | grep httpd
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd 2.4 d54056386fbb 5 days ago 138MB
大丈夫そうです。
次にコンテナを作成します。 コンテナのハッシュが発行されれば成功です。(後述しますが、コンテナIDとかいう際にはこのハッシュの頭12桁を使います。頭12桁で充分アイデンティファイできるという理屈になります。)
#docker create [image]
$ docker create httpd:2.4
0e500166666628525be68a2837aa72ffd0074ed48648fe7762637e83e979fff1
コンテナが作成されたか確認します。
$ docker ps -a | grep httpd
0e5001666666 httpd:2.4 "httpd-foreground" 52 seconds ago Created strange_pasteur
このコンテナ(docker環境)はdocker内ではコンテナIDで識別されますが、これだとランダムな文字列なので非常に使いづらいです。コンテナ名も自動的に付与されますが、開発者の目的にかなっている名前になっているとは限りません。今回の例でも「strange_pasteur」という奇妙な名前が付いています。また、開発が乱立してくるとほぼ人間が直感的にアイデンティファイできなくなります。ですのでdocker-nameを意識的に指定してあげるのがベターです。一度立ち上げてしまったコンテナ名は変更することができないので、一度コンテナごと削除してから作り直します。
コンテナを削除します。
#docker rm [container id]
$ docker rm 0e5001666666
名前をつけてコンテナを立ち上げます。
#docker create --name [container name] [image]
$ docker create --name my-apache httpd:2.4
確認します。新しいコンテナIDが発行されて、設定したコンテナ名になっていると思います。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
02352b099fca httpd:2.4 "httpd-foreground" 30 seconds ago Created my-apache
これでコンテナをスタートさせてみます。
#docker start [container name]
$ docker start my-apache
dcocker ps -a
で確認してステータスがupになっていれば成功です。さてここまででwebサーバー自体のコンテナは起動できましたが、 webサーバーにアクセスできないと話になりまません。webページにアクセスできないwebサーバーとかデータにアクセスできないデータベースだと困るわけです。しかしDockerは開放するポートを指定してやらないとアクセスできません。開放ポートを指定するオプションを追加して起動します。
$ docker stop my-apache
$ docker rm my-apache
$ docker create --name my-apache -p 8080:80 httpd:2.4
$ docker start my-apache
うまく起動できたら`http://localhost:8080/
にアクセスしてください。DebianのApacheのデフォルト画面「It's work!」がブラウザーに表示されれば成功です。ここまでが基本的な上がれになりますが、Dockerは実はもっと複雑です。前述したようにDockerはほぼなんでもできます。
さてDockerは仮想サーバーです。その仮想サーバーにログインしてみます。通常レンタルサーバーやクラウドインスタンスにはSSHなどでログインしますがDockerは手元にあるので手元の仮想環境にログインすることになります。コンテナ名(またはコンテナIDを指定して以下の書式でログインするとユーザー名やパウワードなどなしでログインできます。
$ docker exec -it my-apache /bin/bash
ログインしてから中の様子をみるとまるでサーバーの中にいるようであることがわかります。(いや、サーバーの中なのです。)ここで自由に設定を変えたりテストしたりすることができます。中ではviが普通に使えてLinuxのコマンドが普通に使えます。しかしそれらの動作はコンテナを削除し再度立ち上げるとすべて失われてしまいます。
Dockerのイメージはそれだけでは実際の開発に必要な要件をほぼ満たしていません。そんなわけでDocker内で操作した内容はまたイメージとして保存しなくてはなりません。面倒くさい作業のように思えますがコストのかかるサーバー構築とちがってDocker の作業は無料で行えるのと、それらを作ったり壊しったりとsandboxとしていろいろ試すことができるというのが特徴です。要件を満たし設定がある程度完了したらそのイメージを自分で保存し、また呼び出して再利用できるようにします。
サーバーの中に入るとCentOSではyum、DebianやUbuntuではapt-getやaptなど様々なパッケージをインストールします。またインストールと同時に/etc/*
以下で設定ファイルを修正します。場合によってはcronの起動なども行うことがあるでしょう。そういった場合はその設定をイメージとして保存しておくわけです。保存したイメージはDockerhubからpullしたイメージと同じように手元で再利用することができます。このイメージはDockerhubにpushしておくこともできます。誰かがそれを必要としているかもしれません。
もう一つ大切な機能は、更新ファイル(開発ファイル群)をDocker側とホスト側(自分のPC側)で共有できるということです。毎回Dockerにログインしてファイルを修正しイメージを保存するという開発方法でも開発自体は可能です。しかし更新ファイルをgitで管理したり、手元のお好みのエディタで開いたりする場合には手続きが多すぎて非常に不便です。そのような場合はホスト側のファイル(ディレクトリ)をDocker側にマウントすることができます。こうすることで開発が活発なファイルはーメージとして保存するのではなく、Docker側が呼び出すというかたちで仮想環境を実現するわけです。具体的な例でいうとWEBサーバーのDocumentRoot以下などはDockerの外に出してしまって、Docker立ち上げ時にマウントします。Wordpressの場合は公式のイメージでは、themeディレクトリとpluginsディレクトリのみを外に出してそれ以外のデータはすべてイメージ化しています。またApacheの細やかな設定の開発をする場合でしたら/etc/Apache/conf以下をマウントしたり、データベースの情報を別のDockerで共有したり(互いに同じファイルをマウントしたり)することもできます。DjangoやLaravel、Railsなどのフレームワークはそのフレームワークごと外に出して保存するのが主流です。開発上ごく頻繁にパラメータ変更やファイルの更新が走る場合には、マウントしておくとよいです。
ここからしばらくサーバーサイドの専門的な話になってきます。ちょっと退屈な人にいるかもしれませんが、お付き合いください。
Dockerにログインしたらサーバーサイドエンジニアだったらほぼ自動的にいろいろなことをします。pwd
なんて呼吸をするように使うし、このサーバーがどんなOSなのかとかユーザーなんだとか、いろんなコマンドを一気に打って環境を把握します。結果からいうとこのDocker内はDebian 10.11であり、比較的何もインストールされていないプレーンなOSです。Apache2.4だけインストールされているような感じです。そこで自分が必要とするサーバー環境を作ってあげます。まずはDockerにログインしておきましょう。
例えばcurl
というコマンドがありますが、デフォルトではインストールされていません。APIなどの開発では欠かせないこのコマンドをインストールしておきます。
# apt update
# apt install curl
先程表示した「It work!」を取りに行ってみます。
# curl http://127.0.0.1/
<html><body><h1>It works!</h1></body></html>
取得できました。
さてこのDockerはPCを再起動したり、Docker自体をrmしてしまうと消えてしまいます。ですので、このDockerをイメージまたはコンテナとして保存し後から使えるようにしておきます。イメージとして保存するにはdocker commit
コマンドを使います。
#docker commit -m "MESSSSAGE OR MEMO" [container ID] [image]
$ docker commit -m "Dockerの使い方 (初心者の序盤 no.1)" e82be6a3f6f8 httpd-24
保存のためのハッシュが表示されたら成功です。docker images
で確認します。
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd-24 latest 2f6c0490eb9f 3 minutes ago 157MB
イメージとして保存されていたら成功です。
このイメージは冒頭でdocker pull
したときのようにdocker-hubにpushしておくことができます。(これも後述します。)
参考:
https://qiita.com/minato-naka/items/e1f91e1df2c4fe7411dc