docker build コマンド 練習ドリル|研修コースに参加してみた
今回参加したコースは docker build コマンド 練習ドリル です。
Docker で pull や run したり、docker compose up
で WordPress をコマンド一発で立ち上がるさまをみて、「 Docker 便利!」と思って、いざ自社の開発環境で試そうとすると、オリジナルイメージを作るのに困って止まってしまいがちです(私はそうです … )。 世の中はやれ GitHub Codespaces だ、 Kubernetes だ、とドンドン進化しているのに。
そう、 Docker Compose でシュッとコマンド一発で自社の開発環境を立ち上げるには、その基礎となる docker build 力、つまり Dockerfile 作成力と Docker コマンド力が必要なのです。 このコースはそれをドリルで能力養成するものでした。
が、受講してみると、それ以前の別の知識とスキルも必要だったのでした … 。
では、どのような内容だったのか、レポートします!
もくじ
コース情報
想定している受講者 | 以下の項目の知識や経験がある
|
---|---|
受講目標 | オリジナルイメージの作り方がわかる |
講師紹介
インフラやクラウドでの登壇が多い 一戸 英男 さんが講師でした。
一戸 英男
「とにかく昔からサーバ構築が大好き」から現場に役立つベストセラーが誕生。研修でも明日から現場で使える技術を教えます
Azure Kubernetes Service ( AKS ) を使ってみよう|研修コースに参加してみたDocker 入門 ~たった 5 つのコマンドで出来る環境構築 研修コースに参加してみた
一戸さんからは自己紹介とともに、このコースの位置づけを簡単に紹介いただきました。
- Docker 入門
- このコース
- Kubernetes とクラウドでコンテナ運用
だいたい 1. → 3. となって、いきなり Kubernetes で苦労するケースが多いとのことでした。
このコースは 1. の入門レベルを抜け出し、 3. の基本となる docker build や Dockerfile に慣れるものです。
docker build とは
改めて、 docker build を使う意味を考えてみます。
- なくてもリリースはできる
- Docker は自動化が魅力
- できあいのイメージから人力で構築するのではオンプレと変わらない
- オリジナルのイメージを作って自動化する
- 従来は、開発してテストしたあとのリリースが人力だった
- Docker を使えば、コードの修正とリリースを連動させて自動化できる
- Docker Compose / GitHub / Docker Hub を組み合わせるとチームで共有できる
docker build がないと、自社で開発したシステムがリリースできない?
Docker は自動でアップデートや再配布ができるというが、どういう意味?
“できあいのイメージから人力で~” というお話には、うう、耳が痛いです。
docker build コマンドもおさらいしておきましょう。
# docker build [オプション] パス名
# -t でリポジトリ名 . で現在のパス
docker build -t mynginx .
なお、コースでは Docker Desktop を使って実習しました。
このレポートではブラウザで docker コマンドを実行できて、サーバとしても使える Docker Playground を使用しています。 この記事で紹介するコマンドは動作確認済みなので、読者の方もぜひお試しください。
Dockerfile を作ってみよう
まずはウォーミングアップとして、 Dockerfile を作ってみます。
# Image extract from docker hub
FROM rockylinux/rockylinux
LABEL OreOreDocker ore@seplus.net
RUN dnf update -y
# this execution call to make new instance
CMD ["pwd"]
CMD ["/bin/bash"]
ビルドします。
docker build -t rockylinux .
ビルドが終わったら、イメージが作られていることを確認します。
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rockylinux latest 10515997a1df 6 seconds ago 430MB
rockylinux/rockylinux latest 523ffac7fb2e 5 months ago 196MB
動かしてみましょう。
docker run -dit --name rocky rockylinux
cd56a7efd1e90862d1355723f0f4007dd6c25ad0a192b28dbc679ff6582c3b86
# -dit は -d: デーモンモード と -it: インタラクティブモードを組み合わせたオプション
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cd56a7efd1e9 rockylinux "/bin/bash" 4 seconds ago Up 3 seconds rocky
続いて、立ち上げたコンテナに入ってみましょう。
docker exec -it rocky bash
パッケージをインストールしてみます。
# rockylinux はパッケージ管理に dnf コマンドを使う
dnf install procps-ng
Last metadata expiration check: 0:06:12 ago on Tue Dec 13 05:26:32 2022.
# 中略
Installed:
procps-ng-3.3.15-9.el8.x86_64
Complete!
このあと コンテナの停止 docker stop
→ コンテナの削除docker rm
→ イメージの削除 docker rmi
をしました。
Dockerfile の命令
続いて、 Dockerfile に書く命令を紹介いただきました。
- コマンド一覧
- よく使うコマンド
- スクリプト実行
RUN
- ビルド中に実行するスクリプト
CMD
- コンテナ生成と同時に実行されるスクリプト
ENTRYPOINT
- CMD と同じだが、コマンド引数を無視
- コンテナへのファイルコピー
ADD
- リモートからでも OK
COPY
- ローカルから追加
- スクリプト実行
共有ディレクトリを設定してみよう
コンテナ作成時に生成されたファイルは削除されてしまうため、ほとんどの場合、共有ディレクトリを設定してデータやファイルを永続化します。
コンテナへのマウントには 2 つの方法があります。
- ボリューム
-
- Docker コンテナ外の Docker 管理領域を利用
- 複数のインスタンス間で共有するときに使用
- バインド
-
- ホストコンピュータ側のディレクトリを利用
- コンテナに接続しなくても直接ファイル編集可能
ボリューム Volume
まずはボリュームを試してみましょう。
2 つの Dockerfile を使って、コンテナ間でディレクトリを共有します。
- Dockerfile1
FROM rockylinux/rockylinux RUN dnf update -y RUN dnf install httpd -y RUN mkdir /data RUN echo "Welcome to my Linux." > /data/greeting VOLUME /data
VOLUME
で共有ディレクトリを指定
- Dockerfile2
FROM ubuntu RUN apt update -y
では、やってみます。
- ビルド
docker build -t myos1 -f Dockerfile1 . Successfully tagged myos1:latest docker build -t myos2 -f Dockerfile2 . Successfully tagged myos2:latest
-f
でファイル指定
- コンテナ作成
docker run -dit --name priserv myos1 docker run -dit --volumes-from priserv --name secserv myos2
--volumes-from
でコンテナを指定
- 接続
docker exec -it secserv /bin/bash
- priserv にあるファイルが secserv でも見えることを確認
cat /data/greeting Welcom to my Linux.
コンテナ間でログやデータベースなどを共有するときに使えそうですね。
バインド Bind Mount
次に、バインド (Bind Mount) でホストのディレクトリを共有します。
- バインドは Dockerfile では指定できない
- docker run のオプションで指定
Dockerfile は以下を使用します。 なお、 Docker Playground ではエラーが発生するため、一部編集しています。
FROM rockylinux/rockylinux
RUN dnf update -y
RUN dnf install -y httpd
RUN yum install -y procps-ng
RUN yum install -y iproute
# Docker Playground 用のコマンド。 Docker Desktop では不要
RUN chmod -R 755 /var/www/html/
# Docker Desktop で実行されたコマンド
# CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
# Docker Playground 用のコマンド
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
では、やってみましょう。
- ローカルに html ファイルを置く /html を作って、 index.html を配置
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>The Rockylinux initial content</title> <meta name="description" content="Apache sample html"> <meta name="author" content="SiteUser"> </head> <body> <h1>This is first RockyLinux Page</h1> <p> Docker Sample COntent.</p> </body> </html>
- ビルド
docker build -t bind-mount-image .
- コンテナ作成(バインドを指定)
docker run -dit -p 80:80 \ --mount type=bind,src=/root/html,dst=/var/www/html \ --name bind-mount bind-mount-image
--mount type=bind
でバインドを指定src=
でホスト側のパスを指定dst=
でコンテナ側のパスを指定
- (Dokcer Playground では OPEN PORT > 80 を入力 > OK でタブを開く)
では、実際にブラウザから見てみましょう。
開発ではとても便利ですね!
docker build ドリル
これまでの演習で docker build の基礎固めが終わったので、ここからはドリル形式の演習です。
docker build 入門
1 つめのお題は次のとおりです。 最初はとっても単純で易しいものからです。
問題
以下の Dockerfile を作成し、コンテナを作成してください。
- Ubuntu の latest をインストール
- パッケージを update
- コンテナを生成 → ps コマンドで起動できているか確認 → スクリーンショットを送信
- コンテナ停止 → コンテナ and イメージ削除
制限時間 10 分
解答
- Dockerfile
FROM ubuntu RUN apt update && apt upgrade -y
- ビルド
docker build -t ubuntu_image .
- コンテナ作成
docker run -dit --name ubuntu-test ubuntu_image 2f08aea64ae96cb9b037e9ca6cf66581484f32f90517346d3fdc83305c6333dc docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2f08aea64ae9 ubuntu_image "bash" 4 seconds ago Up 3 seconds ubuntu-test
docker build 初級
2 つめのお題は次のとおりです。 先程の入門の Dokckerfile をもとに進めます。
問題
入門で使用した Dockerfile をもとに次のソフトウェアをインストールし、起動してください。
- Nginx (Web サーバ)
- MariaDB (MySQL 互換 DB)
- プロセスが起動している状態をスクリーンショットを送信
- コンテナ停止 → コンテナ and イメージ削除
制限時間 10 分
/bin/bash
を末尾に入れましょう(このあと解説)
解答
- Dockerfile
FROM ubuntu RUN apt update && apt upgrade -y RUN apt install -y mariadb-server RUN apt install -y nginx COPY startserv.sh /root RUN chmod 755 /root/startserv.sh EXPOSE 3306 80 CMD ["/bin/bash", "/root/startserv.sh"]
- シェルスクリプト
#!/bin/bash service mariadb start service nginx start /bin/bash
- ビルド and 実行
docker build -t service-test . docker run --name service_test service-test * Starting MariaDB database server mariadbd ...done. * Starting nginx nginx ...done.
- 接続して確認
docker exec -it service_test bash
ps ax PID TTY STAT TIME COMMAND 1 pts/0 Ss 0:00 /bin/bash /root/startserv.sh 41 pts/0 S 0:00 /bin/sh /usr/bin/mysqld_safe 137 pts/0 Sl 0:00 /usr/sbin/mariadbd --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysq 138 pts/0 S 0:00 logger -t mysqld -p daemon error 213 ? Ss 0:00 nginx: master process /usr/sbin/nginx 214 ? S 0:00 nginx: worker process 257 pts/1 Ss 0:00 bash 265 pts/1 R+ 0:00 ps ax
docker build 実践
3 つめのお題は次のとおりです。 ただし、今回のレポートでは割愛します。 ぜひコースに参加して実際に演習してみましょう!
問題
今度は mariadb の初期セットアップまで行ってビルドするケースを作ってみましょう。
初級で作成した Dockerfile を改良し、以下を完了してください。
- コンテナ生成時に環境変数で mariadb に root のパスワードを設定
- staff_db データベースと users テーブルを作成
- id: int, Auto increment, 主キー / name: varchar(40) / passwd: varchar(50)
- 適当なレコードを 4 行追加
- users テーブルを全件出力したスクリーンショットを送信
- コンテナ停止 → コンテナ and イメージ削除
よくある失敗ポイント
最後に docker build で失敗しがちなポイントをおさえます。
コースでは最後の 3 つを解説いただいたのですが、このレポートでは
記述したとおりの実行順で動作しておらず、プログラムやアプリが起動できていない
こちらを取り上げます。
CMD / ENTRYPOINT の罠
記述したとおりの実行順で動作しておらず、プログラムやアプリが起動できていない
という場合は、高確率で CMD や ENTRYPOINT から呼び出したコマンドで失敗しているとのことです。
- CMD / ENTRYPOINT で指定するプログラムはすぐに終了してはいけない
- service コマンドなどはプロンプトがすぐに返ってきてしまう
- デーモンモードをオフにする or /bin/bash を使おう
CMD ["/bin/bash"]
この失敗リストと対応方法を解説いただいたところで、このコースは修了しました。
まとめ
docker build を使ってオリジナルイメージを作れるように、 Dockerfile やコマンドをドリル形式で演習しました。
ドリル形式で自分で考えてみると、うる覚えだったり、命令が抜けていたり、自分の知識の見直しができるので、とてもいい体験でした!
一方でシェルスクリプトや SQL など、そもそもこれまでにインフラ構築・運用で培われた知識や経験がないと、エラーどハマることもわかりました。 シェルスクリプト、ググらなくてもわかるようにならなければ … 。
Docker の入門レベルを抜けたいと思う方や、環境構築の自動化をしたいという方には、とってもオススメのコースでした!
label SEカレッジを詳しく知りたいという方はこちらから !!
IT専門の定額制研修 月額 28,000 円 ~/ 1社 で IT研修 制度を導入できます。
年間 670 講座をほぼ毎日開催中!!
SEプラスにしかないコンテンツや、研修サービスの運営情報を発信しています。