【Docker】Docker ~ 基本編 / Dockerfile ~

■ はじめに

https://dk521123.hatenablog.com/entry/2020/04/24/160044

の続き。

今回は、Dockerfileファイル のサンプルをいくつかあげておく。
また、以下の動画を見ながらやるといいかも。

https://dotinstall.com/lessons/basic_docker

目次

【1】Dockerfile の基本構成
 例:Python/Flask
【2】主なインストラクション(命令)
 補足:コメント文
【3】使用しているDocker コマンド
【4】Dockerfileを作るコツ
 1)先に手動で手順を確認する
 2)無駄な差分イメージを減らす工夫をする
 3)実行コストが高いコマンドは独立させる
【5】サンプル
 例1)Hello World
 例2)nginx インストール
 例3)apacheインストール

【1】Dockerfile の基本構成

[1] ベースイメージの指定
[2] イメージ情報を登録
[3] パッケージのインストール
[4] ソースコードコピー
[5] デフォルト環境変数の設定
[6] 実行コマンドの指定

例:Python/Flask

server.py

import os, flask

PORT = int(os.environ["PORT"])

app = flask.Flask("app server")

@app.route("/")
def index():
  return "Hello, dockerfile!!"

app.run(debug=True, host="0.0.0.0", port=PORT)

Dockerfile

# ベースイメージの指定
FROM python:3.10

# パッケージのインストール
RUN pip install --upgrade pip
RUN pip install flask==2.3.2

# ソースコードコピー
COPY ./server.py /server.py

# デフォルト環境変数の設定
ENV PORT 18080

# 実行コマンドの指定
CMD ["python", "-u", "/server.py"]

コマンド例

# [1] イメージのビルド(docker image build [DockerfilePath] -t [ImageName])
docker image build ./ -t demo-flask

# [2] イメージの確認
docker image ls

# [3] コンテナ起動
docker container run --rm -d -p 18081:18080 --name hello-flask demo-flask

# [4] コンテナのプロセス確認
docker container ps

# [5] ブラウザで「http://localhost:18081/」にアクセス
# => 「Hello, dockerfile!!」が表示されることを確認

# [6] 停止
docker container stop hello-flask

【2】主なインストラクション(命令)

インストラクション 用途 メモ
FROM ベースイメージの指定
MAINTAINER (非推奨) 作成者情報
LABEL バージョン情報などのラベル情報(メタデータ)
ENV 環境変数の指定
ARG 一時変数の指定
RUN コマンドの実行 DockerfileからDockerイメージになる時に実行
CMD 実行コマンド DockerイメージからDockerコンテナになる時に実行
ADD File/Directory追加 ネット経由でもファイル追加可能
COPY File/Directoryコピー 基本はローカルPCからのみ可能。ADDではなくCOPYを推奨
EXPOSE 指定したポート番号をコンテナが公開
VOLUME ボリュームのマウント
USER 実行ユーザ指定
WORKDIR 作業ディレクトリの指定

CMD

* 書き方は以下の表の通り。

https://docs.docker.jp/engine/reference/builder.html#cmd

# 記法 説明
1 CMD ["実行ファイル","パラメータ1","パラメータ2"] exec 形式。推奨方法
2 CMD コマンド パラメータ1 パラメータ2 シェル形式
3 CMD ["パラメータ1", "パラメータ2"] ENTRYPOINT 命令に対するデフォルトのパラメータとして扱う

補足:コメント文

* 「#」で行う。

【3】使用しているDocker コマンド

* 詳細は、以下の関連記事を参照のこと。

Docker ~ 基本編 / dockerコマンド ~
https://dk521123.hatenablog.com/entry/2020/04/13/000000

# コマンド 説明 構文例
1 docker image build Dockerイメージ作成 docker image build -t {イメージ名}:{タグ名} {Dockerfileのあるディレクトリ}
2 docker image ls Dockerイメージ一覧(イメージID)を確認 docker images
3 docker container run Dockerコンテナ起動 docker run {イメージ名}
4 docker container ps コンテナの確認 docker ps(動いているコンテナ) / docker ps -a(停止しているコンテナ)
5 docker stop Dockerコンテナ停止 docker stop {イメージ名}
6 docker rm Dockerコンテナの削除 docker rm {コンテナID}
7 docker rmi Dockerイメージの削除 docker rmi {イメージID}
8 docker login Docker Hubへログイン docker login
9 docker puch DockerイメージのPush docker puch {イメージ名}

【4】Dockerfileを作るコツ

1)先に手動で手順を確認する

* 自分が手動で展開できないものは、
 Dockerfile上の手順に落とし込むことができない

2)無駄な差分イメージを減らす工夫をする

* 複数コマンドを見やすく、同時に発行
 => yum/apt などを「&&」でつなげる(以下の例を参照)

* コピーはファイルごとではなく、ディレクトリでまとめる

RUN yum update && \
    yum install -y epel-release && \
    yum install -y \
      unzip \
      nginx \
      ansible && \
    rm -rf /var/chache/yum/* && \
    yum clean all

3)実行コストが高いコマンドは独立させる

* 大きいパッケージのインストールなどの実行コストが高いコマンド
 は、キャッシュのことを考えると、そのゴミ処理コマンドなどを除けば
 他のコマンドから独立することを検討した方がいい

【5】サンプル

例1:Hello World

以下の手順で行う。
~~~~~
[1] Dockerfile作成
[2] Dockerイメージ作成
[3] Dockerイメージ一覧を確認
[4] Dockerコンテナ起動
~~~~~

[1] Dockerfile作成

vi Dockerfile
# 修正内容は、以下「Dockerfile」を参照

Dockerfile

FROM centos
MAINTAINER SampleAuth <sample@demo.com>

# RUN : Buildするときに実行
RUN echo "Hello, World!"

# CMD : runするときに実行
CMD ["echo", "Hello, World!!"]

[2] Dockerイメージ作成

# docker buildコマンドで、Dockerイメージ作成
# docker build -t {イメージ名} {Dockerfileのあるディレクトリ}
sudo docker build -t admin/echohello .

Sending build context to Docker daemon  73.2 MB
Step 1/4 : FROM centos
 ---> e934aafc2206
Step 2/4 : MAINTAINER SampleAuth <sample@demo.com>
 ---> Running in ad5148834bdd
 ---> adce8ebe2485
Removing intermediate container ad5148834bdd
Step 3/4 : RUN echo "Hello, World!"
 ---> Running in a48fde0a07b3

Hello, World!
 ---> 18cb7bdc2a80
Removing intermediate container a48fde0a07b3
Step 4/4 : CMD echo Hello, World!!
 ---> Running in 6281dade472f
 ---> 5eb35baf720b
Removing intermediate container 6281dade472f
Successfully built 5eb35baf720b

[3] Dockerイメージ一覧を確認

# docker imagesコマンドで、Dockerイメージ一覧を確認
sudo docker images

[4] Dockerコンテナ起動

# docker runコマンド で、Dockerコンテナ起動
# docker run {イメージ名}
sudo docker run admin/echohello

# Dockerファイルに記載されていた echo が実行された
Hello, World!!

例2:nginx インストール

[1] Dockerfile作成

vi Dockerfile
# 修正内容は、以下「Dockerfile」を参照

Dockerfile

FROM ubuntu
LABEL sample-docker <xxxx@gmail.com>
RUN apt-get update
RUN apt-get install -y nginx
ADD index.html /usr/share/nginx/html/

[2] コンテンツ作成

# index.html を作成
echo 'Hello!' > index.html

[3] Dockerイメージ作成

# docker buildコマンドは、Dockerイメージ作成
# docker build -t {イメージ名}:{タグ名} {Dockerfileのあるディレクトリ}
docker build -t hello/nginx:1.0 .

[4] Dockerイメージ一覧を確認

# docker imagesコマンド で、Dockerイメージ一覧を確認
docker images

[5] Dockerコンテナ起動

# docker runコマンド で、Dockerコンテナ起動
docker run -d -p 80:80 --name hello-nginx hello/nginx:1.0 /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

# 確認
curl localhost

[6] 動いているコンテナの確認

# docker ps コマンドで、動いているコンテナの確認
docker ps

[7] Dockerコンテナ停止

# docker stopコマンドで、Dockerコンテナ停止
# docker stop {イメージ名}
docker stop hello-nginx

[8] 停止しているコンテナの確認

# docker ps -a コマンドで、停止しているコンテナの確認
docker ps -a

[9] コンテナの削除

# docker rm コマンドで、コンテナの削除
# docker rm {コンテナID}
docker rm aa86b93fb393

[10] イメージの削除

# イメージIDを確認
docker images

# docker rmi コマンドで、イメージの削除
# docker rmi {イメージID}
docker rmi 56d4dc831403

# 削除確認
docker images

例3:apacheインストール

[1] Dockerfile作成

vi Dockerfile
# 修正内容は、以下「Dockerfile」を参照

Dockerfile

FROM centos
MAINTAINER SampleAuth <sample@demo.com>

# RUN : Buildするときに実行
RUN yum install -y httpd
ADD ./index.html /var/www/html/
# ポートをあける
EXPOSE 80

# CMD : runするときに実行
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

[2] コンテンツ作成

vi index.html
# 修正内容は、以下「index.html」を参照

index.html

<html>
<body>Hello World...</body>
</html>

[3] Dockerイメージ作成

# docker buildコマンドで、Dockerイメージ作成
# docker build -t {イメージ名} {Dockerfileのあるディレクトリ}
sudo docker build -t  admin/apache .

[4] Dockerコンテナ起動

# docker runコマンド で、Dockerコンテナ起動
# 実行(サーバが立ち上げる)
sudo docker run -p 8080:80 -d admin/apache

# 確認
curl http://localhost:8080/

<html>
<body>Hello World...</body>
</html>

[5] Docker Hub にアカウント作成

imageのpushするために
Docker Hub にアカウント作成しておく必要あり 

https://hub.docker.com/

[6] ログイン

sudo docker login

[7] push

# push (Docker Hubで確認)
# docker puch {イメージ名}
sudo docker puch admin/apache

参考文献

https://www.atmarkit.co.jp/ait/articles/1407/08/news031.html
http://www.tohoho-web.com/docker/dockerfile.html
https://blog.codecamp.jp/docker-file-how-to
https://www.wakuwakubank.com/posts/270-docker-build-image/

関連記事

Docker ~ Windows / 環境構築編 ~
https://dk521123.hatenablog.com/entry/2017/09/23/235818
Docker ~ Linux / 環境構築編 ~
https://dk521123.hatenablog.com/entry/2018/04/10/234030
Docker ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2022/01/14/102719
Docker ~ 基本編 / docker-compose ~
https://dk521123.hatenablog.com/entry/2020/04/11/000000
Docker ~ 基本編 / dockerコマンド ~
https://dk521123.hatenablog.com/entry/2020/04/13/000000
Docker ~ Data Volume について ~
https://dk521123.hatenablog.com/entry/2018/09/08/222100
Docker に関するトラブル
https://dk521123.hatenablog.com/entry/2017/09/24/162257
Docker ~ トラブルシュート方法 ~
https://dk521123.hatenablog.com/entry/2023/12/12/034018