最近会社でDocker講座+ハンズオンを開催したので、内容をここで共有します。
講座のスライドはSpeakerDeckに挙げていますので良かったらご覧ください。
Web開発における開発環境構築の歴史と変遷〜原始時代から現代(Docker)まで〜
本記事ではハンズオンの内容を記載します。
■ハンズオンについて
ゴール(目的):
Dockerのスローガンである「Build/Ship/Run」を経験して基本的な使い方を理解しよう
Step1,2ではDockerfile→イメージ→コンテナの作成を行います。(Build,Run)
Step3ではDockerHubにオリジナルのイメージを登録し、それをベースイメージとしたDockefileから新しいイメージ作成〜コンテナを起動します。 (Ship)
対象者:
Docker初心者(中級者以上でも良い復習になるかも)
前提条件:
・DockerHubアカウントがあること
・Docker for Windows/Macをインストール済でdockerコマンドを叩けること
Docker for Windowsのインストール
https://ops.jig-saw.com/techblog/docker-for-windows-install/
Docker for Macのインストール
https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81
それではハンズオンスタート!
Step1. 「Hello, Docker World」
Dockerfileを作ってイメージをビルドしてみよう
手始めにDockerfileを格納するためのディレクトリを作ります
※基本的にMacでのコマンドとなります。Windowsは特に注意する部分だけ補足説明を行いますので悪しからず。
例.
mkdir ~/workspace/docker/sample
cd sample
作成したディレクトリ内でDockerfileを作成
内容は以下をコピペしてください
# 利用するベースイメージの指定
FROM ubuntu:18.04
# コマンド
CMD echo 'Hello docker world!'
作成したDockerfileを基にイメージをビルド!
docker build ./ -t sample
イメージが出来たかを確認
$ docker images | grep sample
sample latest 50bca976fdec 1 minute ago 64.2MB
イメージからコンテナを起動してみよう
コンテナよ、起動せよ(以下コマンド実行)
$ docker run sample
Hello docker world!
起動時にコンテナ内部に接続してみる
$ docker run -it sample /bin/bash
root@ecaf5cd9e646:/#
runコマンドで-it
オプションをつけてbash
を起動するように指定すると、ターミナルでコンテナ内部を操作できます。
オプションの詳細については以下をご参考に
【図解】docker runのオプションいろいろ #マンガでわかるDocker 番外編
なのでコンテナに接続してからじゃなくても、直接起動と同時にコマンドを実行可能。
$ docker run -it sample ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
コンテナの起動について
これまでの操作で実はrunした分コンテナは作成されているのにお気づきでしょうか?
試しにコンテナリストを表示する docker ps
コマンド を実行
$ docker ps -a | grep sample
804a41759e16 sample "ls" 22 seconds ago Exited (0) 21 seconds ago elastic_mayer
1a8b5f7bee72 sample "/bin/bash" 2 minutes ago Exited (0) 24 seconds ago cocky_darwin
a98cd2ab3cfa sample "/bin/sh -c 'echo 'H…" 3 minutes ago Exited (0) 3 minutes ago laughing_darwin
デフォルトでは起動しているコンテナだけ表示するが、-a
オプションをつけると起動していないコンテナも含めた全てのコンテナを表示
要らないコンテナ・イメージを削除
docker rm コンテナID|コンテナ名
で指定したコンテナを削除できますが、めんどくさいので一括で削除しちゃいましょう
まずはこのコマンドで先程psコマンドとコンテナID群が一致している事を確認
docker ps -a -f "ancestor=sample" -q
-f
: フィルターオプション。ancestor=***
で指定したイメージ名から作成されたコンテナを絞り込むことができる
-q
: コンテナIDだけ表示
こいつをrmコマンドで使うと一括で削除できる
docker rm `docker ps -a -f "ancestor=sample" -q`
イメージも削除
docker rmi sample
Step2. Nginxコンテナを使ってみる
Nginxのコンテナを起動してホストPCからアクセスしてみよう
※今度はDockerfileを書く必要がなく公式イメージから直接コンテナを起動します
docker run -d --name nginx1 -p 8080:80 nginx
-d
: デタッチドモード。バッググラウンドで実行
-p
: ポートフォワーディング [ホスト側ポート番号]:[コンテナ側ポート番号]
localhost:8080にアクセスしてnginxデフォルトページを確認
わずか数十秒でnginxの環境が出来上がった。これこそがDockerの手軽さ!
しかしここで一つの重要な疑問
「あれ?さっきのHello worldと違ってNginxコンテナは動き続けてる。これって何で?」
冒頭で共有したスライドでも説明してますが、コンテナが起動し続けるには何かしらのプロセスがフォアグラウンドで動く必要があります
端末からの入力を受け付ける状態になっているプロセスはフォアグラウンドプロセスといい、そうでない他の全てのプロセスはバックグラウンドプロセスです。
フォアグラウンドプロセスの例:topコマンドを叩いたらプロセスがフォアグラウンドで起動します。
Ctrl + Cを入力することによってプロセスにSIGINTを通知され、プロセスが終了します。
Nginxはデフォルトはデーモンで動きますが、実はNginxコンテナはフォアグラウンドで動くようDockerfileで設定しています。
NginxのDockerfileを見てみると、最後に CMD ["nginx", "-g", "daemon off;"]
の行がありますね。
このおかげでコンテナが起動し続けることが出来るわけです。
ハンズオンに戻り、今度はNginxコンテナに接続します
(runではなくexecで実行)
docker exec -it nginx1 /bin/bash
コンテナ内でNginxバージョンを確認
root@4ee30cf1b12c:/# nginx -v
nginx version: nginx/1.17.8
bash立ち上げなくても普通にコマンド実行もできる
docker exec -it nginx1 ls
Step3. DockerHubを使ってみよう
DockerHubへイメージを登録
まずはStep1で使用したHelloWorldのDockerfileを基に登録用のイメージを作成
さっきはdocker build ./ -t sample
で作りましたが、DockerHubに登録する為には{DockerHubアカウント名}/{イメージ名}
にする必要があります
アカウント名はログインする時のユーザー名となります。
DockerHubのプロフィールページから確認もできます。
DockerHubのページから「My Profile」をクリックするとプロフィールページに飛びます。
{DockerHubアカウント名}/sample
でイメージを作成しましょう。
docker build ./ -t endam/sample
作成したイメージを確認
$ docker images | grep sample
endam/sample latest 50bca976fdec 3 days ago 64.2MB
コマンドラインからDockerHubにログイン
DockerHubに画面上からログインする時のユーザー名(アカウント名)・パスワードと同じです。
$ 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: xxxxxxxxxxxxxxx
Password:
Login Succeeded
既にログインしている人は「Login Succeeded」が表示されればOKです。
$ docker login
Authenticating with existing credentials...
Login Succeeded
イメージをDockerHubにアップローード!
docker push endam/sample:latest
DockerHubに登録したイメージを基に新しくコンテナを作る
新しいDockerfileを作るのでHelloWorldのDockerfileをコピー&退避させてあげましょう
cp Dockerfile Dockerfile.bak
Dockerfileを修正
# 利用するベースイメージの指定
FROM endam/sample
# ディレクトリ作成
RUN mkdir sample
Dockerfileからイメージをビルド
docker build ./ -t sample2
イメージからコンテナを起動すると「Hello docker world!」が出力されます
(ベースイメージがちゃんと自分が作ったオリジナルイメージだということが分かる!)
$ docker run sample2
Hello docker world!
ちなみに新しいDockerfileの内容であるsampleディレクトリの作成が行われていることも確認
$ docker run -it sample2 ls
bin dev home lib64 mnt proc run sbin sys usr
boot etc lib media opt root sample srv tmp var
ホストPCのディレクトリをコンテナにマウントしてみる
今回はコンテナ起動時にホストPCのディレクトリをコンテナにマウントするのでその準備をする
Dockerfileがあるディレクトリ内でsrcディレクトリを作成。
mkdir src
srcディレクトリ内で適当に新しいファイルを作成する。(マウント確認用)
↓はMacの場合なのでtouchコマンドで空ファイルを作成しています。
Windowsの人は【Windows】空のファイルを作成するの記事を参考にしてください。
cd src
touch a.txt
コンテナ起動時にマウントの指定
docker run -v /Users/***/workspace/docker/sample/src:/app --name sample2 -it sample2 /bin/bash
-v
で指定するホストとコンテナのパスは絶対パスなので要注意
docker run -v [ホストディレクトリの絶対パス]:[コンテナの絶対パス] [イメージ名] [コマンド]
特にWindowsの人はここでハマりやすいです。
C:¥**ではなく
、/C/***
という記述になります。
例:/C/Users/{ユーザディレクトリ}/Documents/workspace/docker/sample/src:/app
コンテナに接続後はappディレクトリ内に事前準備で作ったファイルが置かれていることを確認しましょう。
root@da7bcd4255d1:/# ls app
a.txt
ハンズオンComplete!
これでDockerのスローガンであるBuild/Ship/Runを全て体験完了しました!
もしやってみて詰まったり、疑問がある方、「勉強になったので***のハンズオン内容も載せて欲しい」という方は気軽にコメントをください。お待ちしています。