LoginSignup
0
0

More than 3 years have passed since last update.

Dockerfile:実践体験&シェルを使ったインタラクティブな使い方

Posted at

このチュートリアルでは、Alibaba Cloud上でのDockerfileの使用方法について実践的な経験を積むことに焦点を当てています。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

前提条件

最近のバージョンのDockerが既にインストールされているAlibaba Cloud Elastic Compute Serviceインスタンスにアクセスする必要があります。

私はCentOSを使ってこのチュートリアルを書いています。Debian / Ubuntuを使用することができます。このチュートリアルの99%は、ほとんどがDockerコマンドを使用しているので、どのようなLinuxディストロでも動作します。このチュートリアルを参照して、LinuxサーバにDockerをインストールする方法を学ぶことができます。

あなたは、docker rundocker ps -aを使用したり...Docker、イメージ、コンテナの非常に基本的な理解と知識が必要です。

このチュートリアルの目的は、非常にシンプルなDockerfileをいくつか構築してもらうことです。使っていくうちに、Dockerの概念の理解が深まっていくでしょう。

準備

コンテナをいくつか(できれば何もない)実行している場合には、本当に役立つでしょう。そうすれば、docker ps -a の出力リストで簡単にチュートリアルコンテナを見つけることができます。

そこで、実行している必要のないすべてのコンテナを停止してプルーニングしてください。

(開発環境で)次のようにしてすばやく実行できます。

docker stop $(docker ps -a -q) #stop all container

すべてのコンテナを削除するには、次のように実行します。

docker rm -f $(docker ps -a -q) # remove ALL containers

Dockerfile FROM 命令

このチュートリアルの最初の部分は、あまりエキサイティングなものではありません。Alpine version 3.8のイメージをダウンロードして、それをベースに独自のコンテナを構築するだけです。

DockerfileのFROM命令は、コンテナを構築するためのベースとなるイメージ/Linuxディストロを指定します。

すべてのDockerfileには必ずFROM命令が必要です。

Dockerfileのチュートリアルでは、小さなAlpineのベースイメージで十分です。

https://hub.docker.com/_/alpine/

私は必要になる前に画像をpull / downloadしたいと思っています。( Dockerfileで画像を参照すると自動的にダウンロードされます。)

実行:

docker pull alpine:3.8

期待される出力

3.8: Pulling from library/alpine
4fe2ade4980c: Already exists
Digest: sha256:621c2f39f8133acb8e64023a94dbdf0d5ca81896102b9e57c0dc184cadaf5528
Status: Downloaded newer image for alpine:3.8

Dockerfilesは別のディレクトリに置いた方が良いでしょう。同じディレクトリにあるすべてのファイルとディレクトリは、Dockerビルド中に使用されます。イメージのビルドに必要なファイルとディレクトリだけを入れてください。画像ごとに1つのディレクトリ:これらすべての属性により、きちんと整理され、小さく、効率的で、完全に理解できます。

したがって、入力します。

mkdir dockerfile-tutorials
cd dockerfile-tutorials

Linuxディストロでよく使われるエディタにはvimとnanoの2つがあります。私は nano の方が好きなので、nano のみを使うことになります。

nanoをインストールするには

Debian / Ubuntu :

apt install nano

CentOS :

yum install nano

Nano初心者ガイド:
1、nano file-to-edit ... これはnanoエディタを起動します。
2、カーソルキーが期待通りに動きます。
3、alibabaチュートリアルのウェブページからDockerfileのテキストをカットすると、期待通りに動作します。
4、Dockerfileへの貼り付けは期待通りに動作します。
5、F3を押して作業を保存します。
6、F2を押してエディタを終了します。
これであなたは nano のエキスパートです。このチュートリアルの4つのチュートリアルでnanoを使うために必要な知識はこれだけです。

nano を使って、以下のような Dockerfile を作成してみましょう。

nano Dockerfile

FROM alpine:3.8

実行:

docker build --file Dockerfile 

期待される出力

Sending build context to Docker daemon  84.48kB
Step 1/1 : FROM alpine:3.8
 ---> 196d12cf6ab1
Successfully built 196d12cf6ab1
Successfully tagged tutorial:demo

Sending build context to Docker daemon 84.48kBに注目してください。これは、DockerfileがあるディレクトリのFULLコンテンツがビルドコンテキストとして使用されていることを意味します。ファイルやディレクトリを選択的に最終的なビルドイメージにコピーすることができます。

FROM alpine:3.8は、ダウンロードしたAlpine 3.8イメージを読み込んで、ビルドイメージに追加します。ビルドイメージの中には、小さなAlpine Linuxディストロが入っています。

ビルドコンテキストとは、Dockerfileと同じディレクトリにある全てのファイルとディレクトリのことです。そのため、Dockerfileは別のディレクトリに配置する必要があります。もしDockerfileをルートディレクトリに置いていると、フルリナックスディストロがビルドコンテキストの一部になってしまいます。

Dockerfileが必要なときに自動的にダウンロードしてくれることを証明するために、Alpineのイメージを削除してみましょう。

docker image remove alpine:3.8

期待される出力

Untagged: alpine:3.8
Untagged: alpine@sha256:621c2f39f8133acb8e64023a94dbdf0d5ca81896102b9e57c0dc184cadaf5528
Deleted: sha256:196d12cf6ab19273823e700516e98eb1910b03b17840f9d5509f03858484d321

rerun

docker build --file Dockerfile .

下のPulling from library/alpineに気付きました。インターネットから画像をダウンロードすると時間がかかります。

Sending build context to Docker daemon  2.048kB
Step 1/1 : FROM alpine:3.8
3.8: Pulling from library/alpine
4fe2ade4980c: Already exists
Digest: sha256:621c2f39f8133acb8e64023a94dbdf0d5ca81896102b9e57c0dc184cadaf5528
Status: Downloaded newer image for alpine:3.8
 ---> 196d12cf6ab1
Successfully built 196d12cf6ab1

Dockerfileで画像を参照すると自動的にダウンロードされます。alpine:3.8のイメージを削除したので、Dockerfileで参照すると自動的にダウンロードされるようになりました。

提案です。私はイメージをローカルマシンに引っ張ってくる方が好きです。そうすれば、ライブのインターネット接続を必要とせずに一日中作業することができます。

まとめ:
1、Nano the editor
2、ビルドコンテキストと個別のディレクトリの必要性
3、docker pullを使って画像をダウンロードする
4、アルパインバージョン3.8のイメージを使用するには、FROM alpine:3.8を使用してください。
5、docker build --file Dockerfile .を使用して、ベースとして使用するイメージを構築します。

追加とコピー

コンテナが便利な機能を提供するためには、いくつかのソフトウェアを含まなければなりません。

このステップでは、コンテナにファイルやディレクトリを追加するためのADDとCOPYの使い方を学びます。

まず、いくつかのファイルとtarred / zipファイルを作成する必要があります。

実行:

touch in-tar-file-1
touch in-tar-file-2
touch in-tar-file-3

tar -cvf tarredfiles.tar in-tar-*

touch コマンドは空のファイルを作成します。

tar コマンドは in-tar- で始まるすべてのファイルを tarredfiles.tar に追加します。

1、c フラグは新しい .tar アーカイブファイルを作成します。
2、v フラグは、ファイル上の .tar ファイルの進行状況を一度に表示します。
3、f フラグは、このアーカイブ操作の出力ファイルの名前です。
さらに3つのファイルを作成して、別の tar ( zip アーカイブ ) に追加する必要があります: more-tarredfiles.tar

touch more-in-tar-file-1 ; touch more-in-tar-file-2 ; touch more-in-tar-file-3 ;
tar -cvf more-tarredfiles.tar more-in-tar-*

現在、tarredfiles.tar とmore-tarredfiles.tarの2つのtar化されたアーカイブがあります。

を使ってDockerfileに追加します。

nano Dockerfile

FROM alpine:3.8
ADD tarredfiles.tar /root
COPY more-tarredfiles.tar /root

を使用して画像を構築します。

docker build --tag tutorial:demo --file Dockerfile  .

期待される出力

Sending build context to Docker daemon  84.48kB
Step 1/3 : FROM alpine:3.8
 ---> 196d12cf6ab1
Step 2/3 : ADD tarredfiles.tar /root
 ---> f2ac949250b2
Step 3/3 : COPY more-tarredfiles.tar /root
 ---> 972dbad70e51
Successfully built 972dbad70e51
Successfully tagged tutorial:demo

このチュートリアルでは、実行する非常に小さなDockerfileのサンプルがたくさん含まれています。

次の実行のたびに、実行中の前のコンテナを停止してプルーニングしなければなりません。そうしないと、このようなエラーメッセージが表示されます。

docker: Error response from daemon: Conflict. The container name "/tutorial" is already in use by container "d2f5d27b1edc16e33bb8378b555fd61fd1e3ca244b5e8c1b682e79b76e39c660". You have to remove (or rename) that container to be able to reuse that name.

したがって

docker stop -t 0 tutorial   ;   docker container prune -f   ;   docker ps -a

そのため、これらのコマンドを頻繁に目にすることになるでしょう: 彼らは前のコンテナを停止し、それを削除/プルーニングします。

結果を見るためにコンテナを起動してみましょう。

docker stop -t 0 tutorial ;   docker container prune -f  
docker run -ti -d --name tutorial tutorial:demo /bin/sh -c 'while true; do sleep 60; done'
docker exec -it tutorial /bin/sh

/# shell promptの /# で** ls /root/** と入力して、カレントディレクトリ内のファイルを一覧表示します。

期待される出力

/ # ls /root
in-tar-file-1         in-tar-file-2         in-tar-file-3         more-tarredfiles.tar
/ # exit

予想通り、ADDはtarファイルのアンタースを自動化します。
COPYはtarファイルを自動化しません。

覚えやすいですね。ADDは二重の役割を果たします...追加とtarファイルの展開 / 解凍を行います。

COPYはコピー&ペーストのようにコピーするだけで、余分な処理は行われません。写真のコピー機はコピーするだけで、二重の役割はありません。

ベストプラクティス: この二重の役割を果たす機能が必要な場合のみADDを使用してください。

DockerfileのADD tarredfiles.tar /rootは、tarredfiles.tarを自動で/root/に展開します。

DockerfileのCOPY more-tarredfiles.tar /rootは単にmore-tarredfiles.tarを/root/にコピーするだけです。

個々のファイルをコンテナにコピーする際にも全く同じ構文を使用します。

ADDとCOPYについては、https://docs.docker.com/engine/reference/builder/#add でかなり詳しい情報を得ることができます。

少なくともこれで、この2つのコマンドを使った実践的な経験ができるようになりました。公式のDockerリファレンスドキュメントを読むことで、より意味のあるものになるでしょう。

ファイルの所有権を変更するための chown の使用

ここでは、CHOWNを使ってADDやCOPYでファイルの所有権を変更する方法を説明します。

を使って2つのファイルを作成してみましょう。

touch gamefile
touch anothergame

を使ってDockerfileに追加します。

nano Dockerfile

FROM alpine:3.8
COPY --chown=games:games gamefile /root/
COPY --chown=35:35 anothergame /root/

を使用して画像を構築します。

docker build --tag tutorial:demo --file Dockerfile  .

コンテナを起動して結果を見てみましょう。

docker stop -t 0 tutorial ;   docker container prune -f  
docker run -ti -d --name tutorial tutorial:demo /bin/sh -c 'while true; do sleep 60; done'
docker exec -it tutorial /bin/sh

期待される出力

/ # ls -l /root
total 0
-rw-r--r--    1 games    games            0 Oct 16 14:26 anothergame
-rw-r--r--    1 games    games            0 Oct 16 14:26 gamefile
/ # exit

何が起こったのか : Dockerfileから解凍します。

COPY --chown=games:games gamefile /root
COPY --chown=35:35 anothergame /root

最初のコピーコマンドでは、所有権を変更するためにユーザ名とグループ名を使用していることに注意してください。

2 番目のコピーでは UID と GID を使用して所有権を変更しています。35はゲームのユーザーIDのUIDです。

GID = グループ識別子 (GID)

UID = ユーザー識別子(GID)

https://en.wikipedia.org/wiki/User_identifier

パスワードファイルを覗いてみると、長いテキストのユーザ ID とそれらの UID を見つけることができるでしょう。私たち人間は簡単なテキストのユーザ名を使いますが、カーネルでは短くて効率的な数字だけを使います。UIDsです。

Dockerfileにこれら2つのコマンドを入力し、イメージから実行中のコンテナを作成するだけで、5段落の理論を読むのに比べて、--chgownについてより多くのことを学ぶことができました。

私はaddではなく、各行に1つのファイルをコピーするためにCOPYを使用しました。

Dockerfile COPYを使用したdirsの再帰的コピー

目的:Dockerfile COPYを使用してdirsの再帰的なコピーをデモする

まず、入れ子になったディレクトリを表示するための小さな、しかし便利なツールをインストールする必要があります。

tree コマンドは、入れ子になったディレクトリをツリー構造としてきれいに表示するのに便利なツールです。

私はCentOSを使っているので、実行する必要があります。

yum install tree

( Ubuntu / Debian の場合は apt install tree )が必要です。

mkdir -p demo-directories/dir-a/dir-a1/dir-a2

mkdir はディレクトリを作成します。p は必要に応じて自動的に親ディレクトリを作成します。

これらのディレクトリを作成するための初心者の方法は

mkdir demo-directories
cd demo-directories
mkdir dir-a
cd dir-a
mkdir dir-a1
cd dir-a1
mkdir dir-a2

シェルで man mkdir を使って、mkdir のすべての機能を読むことができます。

入れ子になったディレクトリがどのように見えるか見てみましょう

実行:

tree demo-directories

期待される出力

demo-directories/
+-- dir-a
    +-- dir-a1
        +-- dir-a2
3 directories, 0 files

シェルで** ls -R demo-directories** を実行してみてください。違いがわかります。ツリーがよりわかりやすくなりました。

それぞれのディレクトリにファイルを追加してみましょう。

touch demo-directories/demo-file
touch demo-directories/dir-a/file-a
touch demo-directories/dir-a/dir-a1/file-a1
touch demo-directories/dir-a/dir-a1/dir-a2/file-a2

touch が自動的にネストされたディレクトリを作成できるようになれば、これらの touch コマンドのみを使用することができれば良いですが残念ながら、それはできません。そのため、まずディレクトリを作成してから touch でディレクトリ内のファイルを作成する必要があります。

実行:

tree demo-directories

期待される出力

demo-directories
+-- demo-file
+-- dir-a
    +-- dir-a1
    ��� +-- dir-a2
    ��� ��� +-- file-a2
    ��� +-- file-a1
    +-- file-a
3 directories, 4 files

これで、それぞれのディレクトリに1つのファイルができました。

Dockerfileを以下のように編集します。

FROM alpine:3.8

WORKDIR demo-work-dir
COPY demo-directories/ .

COPYコマンドの最後の .は現在のdirを意味します。WORKDIR demo-work-dirを使用しているので、現在のディレクトリはdemo-work-dirです。

そのため、COPYはdemo-directoriesからすべてのファイルをdemo-work-dirにコピーします。

実行:

docker build --tag tutorial:demo --file Dockerfile .

期待される出力

Sending build context to Docker daemon  84.48kB
Step 1/3 : FROM alpine:3.8
 ---> 196d12cf6ab1
Step 2/3 : WORKDIR demo-work-dir
 ---> Using cache
 ---> c9996f2cdedc
Step 3/3 : COPY demo-directories/ .
 ---> Using cache
 ---> 350a93964377
Successfully built 350a93964377
Successfully tagged tutorial:demo

ビルド完了、実行

docker stop -t 0 tutorial ; docker container prune -f;docker ps -a

docker run -ti -d --name tutorial tutorial:demo /bin/sh -c 'while true; do sleep 60; done'

Dockerでは実行中のコンテナのコンテナIDが表示されます。

ビルドの効果を確認するためにコンテナに入ってみましょう。# shell promptで ls -R と入力します。

docker exec -it tutorial /bin/sh

期待される出力

/demo-work-dir # ls -R
.:
demo-file  dir-a
./dir-a:
dir-a1  file-a
./dir-a/dir-a1:
dir-a2   file-a1
./dir-a/dir-a1/dir-a2:
file-a2

このディレクトリはDockerfileのWORKDIR demo-work-dirで作成されたものです。

DockerfileのCOPY demo-directories/ .コマンドは、demo-directories/の再帰的な内容をすべてdemo-work-dirにコピーしています。

注: demo-directoriesディレクトリ自体はコピーされず、中身だけがコピーされることに注意してください。

コンテナ内で作成された demo-directories ディレクトリ自体が必要な場合は、Dockerfile で WORKDIR demo-directories を指定します。WORKDIRは存在しなければdirを作成します。

上記のことを本当に理解しているかどうかをテストするために、両方の名前を変更します。

demo-directories

demo-work-dir

次に、Dockerfileを新しいdir名で動作するように変更します。その後、イメージを再構築して実行し、コンテナに入り、新しいディレクトリにあるコンテンツを探してください。

これでうまくいっていれば問題ありません。次に、これらのdir名のうちの1つを意図的に間違えてください。上記のすべてを再実行してください。表示されるエラーメッセージを読んで、修正してください。これで、どんな理論が教えてくれるよりも、WORKDIRとCOPYがよく理解できるようになりました。

これでパート1の4つのうちの1つ、Dockerfileの説明書をすべて知ることができました。もっと学ぶためにパート2を読み続けてください。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

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