Dockerの使い方 (初心者の序盤 no.1)

Docker

なんでDockerの一人勝ちということになったのかというとゲストOSが不要ということです。従来のハイパーバイザ型と比較してOSのカーネル部分(OSのほとんどの部分です)自分のPC、つまりホストマシンと共有することでサイズ的には極小で仮想環境を構築できるというわけです。一人勝ちの後押しをしたのはサーバーレスというクラウドサービスでした。Azureの「Azure Container Instances」、AWSの「Amazon Elastic Container Service(AWS Fargate )」、GCPの「Cloud Run」などDockerコンテナをそのままデプロイできるシステム(つまりサーバーレスと言われるようにサーバーの構築や設定が不要になる)がすでに実用面で充分な力を発揮しているところです。
とはいえ、自分のPCでいろいろやってみるというレベルでも充分にその役目と用途、目的を達成できるというところがDockerのよいところです。
ここではmac環境を基本に解説していますが、基本的にはwindows環境も同じです。

Docker Desktop for Macのインストール

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の基本的なところ

dockerは「何でもできるようになっている」が基本です。従来サーバー側でやっていたことアプリ側でやっていたことは何でもできます。もちろんCDNのdocker化とかナンセンスな開発などもありますが、それでもほとんど再現できます。もし欠点を探すとしたら複雑なネットワークを設定するとか妙なプロキシをかますとかそういったことは kubernetesという別の仕組みを利用しなくてはいけないということがありますが、そもそもネットワークはコンテナの仕事ではないので欠点とはいえないでしょう。Dockerはアプリケーションのコンテナ化に焦点を当てています。

Dockerの仕組みはいたるところで解説されているので、ここでは割愛します。ただ順序だけ明確にしておこうと思います。上述したようにゲストOSが不要であるということで基盤になるOSのダウンロードなどは不要です。DebianにしろCentOSにしろUbuntuにしろOSをコンテナ化するときはカーネル以外の最低限のファイルを取り込むことで実現します。この「最低限のファイル」がイメージと呼ばれるディスクをまるごとコピーしたデータになります。ただ実際はまるごとコピーというふうにはなっていなくてDocker(コンテナ)に特化したイメージになっているので通常のイメージバックアップなどと区別してdocker-imageという言い方をします。dockerイメージはdockerアプリケーションがないと起動できません。Dockerの基本的な流れは、

  1. docker-imageのダウンロード(pull)

  2. dockerの設定(Dockerfile)

  3. dockerの起動

という流れになります。docker-imageの保管場所はdockerのアプリケーションがよしなにやってくれるので、物理的な保存場所はほとんど意識しなくてOKです。実際は~/Library/Containers/com.docker.docker/Data/vms/0に保存されていますが、ここを見てもあまり意味がないので、削除やpullなどの管理はコマンド上で行います。いろいろありますが手を動かしてみないことにはわからないことが多いのがDockerなので、いろいろ手を動かしてみましょう。

hello world

とりあえず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のimage

では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で見ることができます。こんな感じで必要なイメージを検索してバージョンや機能など詳細情報を確認したりすることができます。

Apacheのwebサーバーをつくってみる

チュートリアルとして最もわかりやすいのが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はほぼなんでもできます。

Apacheにログインする

さてDockerは仮想サーバーです。その仮想サーバーにログインしてみます。通常レンタルサーバーやクラウドインスタンスにはSSHなどでログインしますがDockerは手元にあるので手元の仮想環境にログインすることになります。コンテナ名(またはコンテナIDを指定して以下の書式でログインするとユーザー名やパウワードなどなしでログインできます。

$ docker exec -it my-apache /bin/bash

ログインしてから中の様子をみるとまるでサーバーの中にいるようであることがわかります。(いや、サーバーの中なのです。)ここで自由に設定を変えたりテストしたりすることができます。中ではviが普通に使えてLinuxのコマンドが普通に使えます。しかしそれらの動作はコンテナを削除し再度立ち上げるとすべて失われてしまいます。

Dockerの操作の肝

自分のイメージを作成する

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


  • News

  • Categories

  • Tags

  • Archives

  • Page index