0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【🔰Docker初心者向け】自作のDockerfile問題(1~10)の解答・解説🐳

Last updated at Posted at 2025-12-11

はじめに

こんにちは!ITスクールRareTECHにてCS(Customer Support)を担当している池村です。
今回の記事は、前回書いた自作のDockerfile問題(2~10)の解答記事になります。

Whisk_88df1c61fce27a4bf9e47aaf788ff5f5dr.jpeg

まずは以下にある問題を、git cloneして解いてみてください。

解き方の解説は👇の記事をご確認ください。

問題1については上記の記事で解説をしているので、そちらをご確認ください。

問題2の解答

さて、早速問題2を見ていきましょう。

image.png

問題1ではAlpine Linuxを使っていましたが、今回はUbuntuを使う問題です。
なので、FROM句を変更すれば良さそうですね。

ではディレクトリに移動して、Dockerfileを編集しましょう。

image.png

今回はバージョンの指定があります。22.04ですね。
最新版はlatestにすれば良いですが、細かなバージョンを指定したい場合はタグにバージョンを書き込む必要があります。

FROM ubuntu:22.04

CMD ["echo", "Hello Docker!!"]

上記が解答になります。
書き込みが終わったら、ビルドして実行、正誤チェックしてみましょう。

docker build -t q02 .
docker run --rm q02
bash check.sh

正解です!が出たら完了です。次の問題にいきましょう。

問題3の解答

次は問題3ですね。CMD句のちょっと違う使い方です。

image.png

まずCMDにはexec形式とshell形式があります。

exec形式とは

シェルを使わず、コマンドの実行ができる書き方。
ただ、パイプ、環境変数、リダイレクトなどが使えません。

例えば
CMD ["echo", "Hello"]

これはDockerがjson形式で解釈してくれています。
1つ目がコマンド、それ以降が引数として扱われます。

DockerのReferenceでは以下のように書かれています。

The exec form is a JSON array.
The shell is not invoked.

  • exec形式は JSON 配列でなければならない
  • シェルは起動しない

これについて詳しくお話しすると、1記事分に相当するので、ここでは詳しくお話しする気がありません。PID1の存在が関係してきますが、別記事で詳しく解説する予定です。

基本的に推奨されている書き方はexec形式になります。

shell形式とは

shell形式は、シェルを介してコマンドを実行できる書き方です。
json形式ではないので、直接コマンドを書くことが可能です。

例えば
CMD echo "Hello"

こうすると、Docker内部的には/bin/sh -c "echo Hello"と解釈します。
※Alpineの場合

環境変数や、パイプ、リダイレクトも使用可能です。

環境変数の場合
ENV NAME=World
CMD echo "Hello $NAME"

※exec形式だと変数の中身は展開されません。

パイプの場合
CMD echo "Hello World" | grep World

のような書き方ができる。上記に意味はないですが。

リダイレクトの場合
CMD echo "Hello" > /tmp/hello.txt
コマンド連結の場合
CMD echo "start" && echo "next"

これらのシェルに備わった機能が様々使えます。

初心者のレベルでは、まず二つの書き方があるんだな。といった理解で十分です。
システムコール周りはややこしいですからね。

さて、ここまできたら解答を見ていきましょう。

問題3の解答
FROM alpine:latest

CMD echo "Hello Docker!!"

これだけです。
これを書いてファイルを保存したら、ビルド・実行・正誤チェックをしましょう。

docker build -t q03 .
docker run --rm q03
bash check.sh

正解です!と出たらOKです。

問題4の解答

では次に問題4です。

image.png

ここからRUN句が出てきますね。
核となるのはmessage.txtファイルを作成して、中に文字列Hello Docker!!を書き込む必要があるというところです。

まずRUN句ですが、これはビルド時に行われるコマンドを書くところです。
ファイルを作るわけですが、今回はコンテナ内のどこに作るのかの指定がないので、適当に作ってしまいますが、以下のように書いてみましょう。

RUN echo "Hello Docker!!" > /message.txt

これはshell形式で書いていますが、基本的に複雑なコマンドを書く傾向にあるため、基本的にshell形式で書くことになります。

一応exec形式でも書けるのですが

RUN ["/bin/sh", "-c", "echo 'Hello Docker!!' > /message.txt"]

面倒ですよね。
結局リダイレクトとか、パイプとか、連結等の複雑な処理を書くとすごい量になってしまいます。

まず、RUNとCMDでは根本的に違うところがあります。
イメージをビルドする時に実行されるか、コンテナが起動時に実行されるかになります。

RUNはイメージを作る際の作業なので、shell形式の方が便利。CMDは本番のコンテナでのプロセスなので、exec形式でより安全に。

安全な理由は、シグナルの無視やゾンビプロセスが関連してきますが、ここでは詳しく解説しません。問題3の時と同様です。

解答はこちらになります。

解答
FROM alpine:latest

RUN echo "Hello Docker!!" > /message.txt

CMD ["cat", "/message.txt"]
  1. RUN句でmesseage.txt/に作成します
  2. CMDで、そのファイルをcatコマンドで読み込んでいます

これで問題4は完了です。
ビルド・実行・正誤チェックしましょう。

docker build -t q04 .
docker run --rm q04
bash check.sh

正解です!と出たら、次の問題にいきましょう。

問題5の解答

では問題5に入ります。

image.png

今回はWORKDIR句を使っていきます。
WORKDIR句は、コンテナの中でどのフォルダを基本の作業場所にするかを指定する命令になります。
前回までの問題で行われてきた、RUN句・CMD句のコマンドが実行される際のカレントディレクトリを設定することができます。

WORKDIRを使わないと
RUN echo "Hello" > /app/message.txt
CMD ["cat", "/app/message.txt"]

と言った書き方になり、少々面倒ですよね。
これをしっかり/app以下に作りたいと決まっている際に使っていきます。

なので解答は

解答
FROM alpine:latest

WORKDIR /app

RUN echo "Hello from /app" > message.txt

CMD ["cat", "message.txt"]

このWORKDIR句で設定したディレクトリのおかげで、その後の作業が/app以下で行われることが確定しています。

これで問題5は終了です。
ビルド・実行・正誤チェックしましょう。

docker build -t q05 .
docker run --rm q05
bash check.sh

正解です!と出たら、次の問題にいきましょう。

問題6の解答

続いて問題6です。

image.png

今回は環境変数を利用する問題です。
コンテナの中で自由に使えるようにする変数のことです。

ただ、環境変数を設定した場合、CMDでは2通りの書き方があります。

では解答1です。

解答1
FROM alpine:latest

ENV GREETING="Hello from ENV"

CMD ["/bin/sh", "-c", "echo $GREETING"]

CMDのexec形式では、シェルを指定してあげることで、環境変数を扱うことができます。
シェルを使います!と宣言した上で、変数を展開する形です。

解答2です。

解答2
FROM alpine:latest

ENV GREETING="Hello from ENV"

CMD echo $GREETING

shell形式だと、そのまま変数を使えますので、execに比べると短く書くことができます。
※CMDではexec形式が推奨されています。

ビルド・実行・正誤チェックしましょう。

docker build -t q06 .
docker run --rm q06
bash check.sh

正解です!と出たら、次の問題にいきましょう。

問題7の解答

問題7に入りましょう。

image.png

ここではDockerfileでよく使われるCOPY句を使います。
問題を読むと、message.txtを作成する必要があるようなので、問題が格納されているディレクトリの中で作ってしまいましょう。

echo "Hello from COPY" > message.txt

これでファイルはOKなので、次にDockerfileを作成します。

FROM alpine:latest

COPY message.txt /message.txt

CMD ["cat", "/message.txt"]

これでOKです。
COPY句の場合、左が現在いるローカルのファイル、右がコンテナの中のCOPY先になります。ビルドは.を指定するので、今いるディレクトリにあるファイルを見ます。ローカルの方はそのままmessage.txtでOK。
右は、コンテナの中の話なので、/ディレクトリにそのまま作成しています。

ビルド・実行・正誤チェックしましょう。

docker build -t q07 .
docker run --rm q07
bash check.sh

正解です!と出たら、次の問題にいきましょう。

問題8の解答

では8問目。
image.png

この問題ではRUN句を二つ使ってみます。
指定の場所にmessage.txtを作成して、その後のRUNで場所を変えます。
移動はmvコマンドを使いましょう。

解答
FROM alpine:latest

RUN echo "Hello from multi RUN" > /tmp/message.txt
RUN mv /tmp/message.txt /message.txt

CMD ["cat", "/message.txt"]

これでOKです。
ビルド・実行・正誤チェックしましょう。

docker build -t q08 .
docker run --rm q08
bash check.sh

正解です!と出たら、次の問題にいきましょう。

このRUN句のコマンドに大した意味はありません。

問題9の解答

では問題9に入ります。
image.png

ここが一番難しいかもしれません。
シェルスクリプトを学習していない人も多いと思いますが、その内容自体は決して難しくありませんので頑張ってほしいです。

ではまず2パターンありますので、1つ目から。

解答1
FROM alpine:latest

RUN echo '#!/bin/sh' > /hello.sh \
 && echo 'echo "Hello from script"' >> /hello.sh \
 && chmod +x /hello.sh

CMD ["/hello.sh"]

解答1では、RUN句で、シェルスクリプトの内容を1行ずつ&&を使って連結させながら入力していっています。
そして最後にchmodコマンドで実行権限をつけています。

解答2
FROM alpine:latest

COPY hello.sh /hello.sh
RUN chmod +x /hello.sh

CMD ["/hello.sh"]

解答2ではローカルでhello.shファイルを作成して。COPYしている形です。
これはこれで、chmodを行う必要があります。
ローカルのhello.shには以下の内容を書いておきます。

#!/bin/sh
echo "Hello from script"

ビルド・実行・正誤チェックしましょう。

docker build -t q09 .
docker run --rm q09
bash check.sh

正解です!と出たら、次の問題にいきましょう。

問題10の解答

beginnerコース最後です。
image.png

この問題はENTRYPOINT句を使います。
ENTRYPOINT句は、コンテナ起動時に行うべきコマンドを固定することができます。
おそらく何を言っているかわからない人もいると思うので解説すると、CMD句に書かれたコマンドは、コンテナを実行する人によって書き換え可能なんです。なので以下のような場合を想定して説明します。

CMD ["echo", "Hello"]

上記のような内容が最後に書かれたDockerfileをビルドして、コンテナを起動したとします。その際に以下のようなコンテナ起動のコマンドを使うと。。

docker run イメージ名 echo Docker

# 実行結果
Docker

このdockerコマンドの実行の際に渡される引数は、CMDを上書きしちゃうんですね。
ENTRYPOINTはユーザーに変えてほしくないコマンドを設定できます。

なので、以下のように書けば正解です。

解答
FROM alpine:latest

ENTRYPOINT ["echo"]
CMD ["Hello from ENTRYPOINT"]

今回は指定として、ENTRYPOINTにechoを書きましょうとあります。
最終的な出力結果はHello from ENTRYPOINTなので、CMDに書き込みます。これで、ENTRYPOINTへの引数としてCMDの値が渡される形になります。

使い分けは以下です。

  • ENTRYPOINT

    • 変えられたくないコマンド本体
    • 必ず実行してほしいアプリケーション
    • コンテナのメインプロセス
  • CMD

    • ENTRYPOINT のためのデフォルト引数
    • あってもなくても良い
    • ユーザーが run で変更可能

こちらもCMD同様、exec形式で書くことが推奨されています。

ビルド・実行・正誤チェックしましょう。

docker build -t q10 .
docker run --rm q10
bash check.sh

CLEARと出たら、全問終了です。お疲れ様でした。

おわりに

今回は前回の記事の解答・解説を行いました。
まずは書いて覚える。これが大事です。初歩の初歩から始めることは、遠回りのようで近道です。この後は11~20問目の作成と記事を書きますので、今しばらくお待ちください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?