- 投稿日:2020-10-20T23:36:12+09:00
no CUDA-capable device is detected
rayでGPUを使用し、並列処理をしていると以下のようなエラーがでる。
RuntimeError: cuda runtime error (100) : no CUDA-capable device is detected at /opt/conda/conda-bld/pytorch_1591914855613/work/aten/src/THC/THCGeneral.cpp:47エラーの対処方法
長らくこのエラーについて考えたが明確な答えは分からなかった。。。。
しかし、このエラーが出てもrayでGPUを使うことができる方法を見つけた。
それは実行したいプログラムに以下のコードを追加することである。
while True: input = input() #以下実行したいコード : :上記のコードを説明する。
まず、while Trueは無限ループである。
input()は入力である。
そして、while Trueの中に実行したいコードを入れる。タイトルのようなエラーが出たらcontrol Cで再び入力に戻す。
そしてまた、適当な入力をする。
するとエラーがなくなり実行できる。実行し終えたら
無限ループなので
control Cを押して終了する。本当の意味の解決方法を見つけたらまた報告する。
- 投稿日:2020-10-20T22:43:48+09:00
sedメモ
- 確認環境:sed (GNU sed) 4.2.2
- PHP や JavaScript, VSCode の正規表現と挙動が違う部分がある
- 結論から言うとsed のマニュアルに書いてないことはできないんだと思う
- 個人的に慣れている正規表現エンジンは鬼車なので、どうしても違和感がある
置換の方法
基本
s/
が置換を表す
sed 's/検索文字/置換文字/'
拡張
- キャプチャしたい時に
-r
- キャプチャを使うときは
\
sed -r 's/検索(文字)/\1/'
特有のクセ
- 基本的にキャプチャ周りに癖がある
\s
は使えない[\t\n\v\f\r\x20]
で代用可能その 1
- キャプチャに癖がある(
?
の挙動が違う?)- 以下のテキストに対し
/.+?"records":"(.+?)".+/
をした時に、PHP や JS, VSCode では$1
でa @ 163.43.80.45\nmx @ 10\ntxt ....
をキャプチャできる
sed -r 's/.+?"records":"(.+?)".+/\1/'
ではa @ 163.43.80.45\nmx @ 10\ntxt ....","ttl":"60"},"request_id":"202010191733159039640087223V","request":{"path":"/v1/domains/example.com/dns","method":"GET","params
となる- 期待する結果を得るためには
sed -r 's/.+?"records":"([^"]+?)".+/\1/'
とする必要がある{"results":{"domainid":6526946,"domainname":"example.com","ns_type":"foobarbaz","records":"a @ 163.43.80.45\nmx @ 10\ntxt ....","ttl":"60"},"request_id":"202010191733159039640087223V","request":{"path":"/v1/domains/example.com/dns","method":"GET","params":[]}}その 2
- やっぱりキャプチャに癖がある
- 以下のテキストに対し
/^(?:[^ ]+? +?){3}([^ ]+) .+/
をした時に、PHP や JS, VSCode では$1
で1.0
をキャプチャできる
sed -r 's/^(?:[^ ]+? +?){3}([^ ]+) .+/\1/'
では次のエラーになるsed: -e expression #1, char 33: Invalid preceding regular expression
- 期待する結果を得るためには
sed -r 's/^([^ ]+? +?){3}([^ ]+) .+/\2/'
とする必要がある
- 恐らく
?:
が使えない(sed で non-capturing group は使えないのだと思う)root 51849 0.0 1.0 7488 812 ? Sl Oct16 0:52 docker-containerd-shim
- 投稿日:2020-10-20T21:12:55+09:00
Dockerfile リファレンス 日本語訳
Dockerfile reference の日本語訳。
Docker は Dockerfile から指示を読み取ることにより、イメージを自動的に構築できます。
Dockerfile はイメージを構築する為のコマンドを記述したテキストドキュメントです。
ユーザーがコマンドラインから呼び出して使用します。
docker build を使用することで、ユーザーは複数のコマンドライン命令を連続して実行する自動ビルドを作成できます。このページでは Dockerfile で使用できるコマンドについて説明します。
このページを読み終えたら Dockerfile Best Practices for a tip-oriented guide を参照してください。使用法
docker build コマンドは Dockerfile とコンテキストからイメージをビルドします。
ビルドのコンテキストは、指定された場所の PATH または URL にあるファイルのセットです。
PATH はローカルファイルシステム上のディレクトリです。
URL は Git リポジトリの場所です。コンテキストは再帰的に処理されます。
したがって PATH にはサブディレクトリが含まれ、 URL にはリポジトリとそのサブモジュールが含まれます。
次の例は、現在のディレクトリをコンテキストとして使用するビルドコマンドを示しています。$ docker build . Sending build context to Docker daemon 6.51 MB ...ビルドは CLI ではなく Docker デーモンによって実行されます。
ビルドプロセスが最初に行うことは、コンテキスト全体を(再帰的に)デーモンに送信することです。
ほとんどの場合、コンテキストとして空のディレクトリから開始し、Dockerfile をそのディレクトリに保持することをお勧めします。
Dockerfile の構築に必要なファイルのみを追加してください。警告
ルートディレクトリ/
を PATH として使用しないでください。
ビルド実行時にハードドライブの内容全体が Docker デーモンに転送されます。ビルドコンテキストでファイルを使用する際、 Dockerfile は
COPY
命令などの命令で指定されたファイルを参照します。
ビルドのパフォーマンスを向上させるには、コンテキストディレクトリに.dockerignore
ファイルを追加してファイルとディレクトリを除外します。
.dockerignore
ファイルを作成する方法については、このページのドキュメントを参照してください。慣例として Dockerfile はコンテキストのルートに配置しますが、
docker build で-f
フラグを使用して、ファイルシステム内の任意の場所にあるDockerfile
を指定できます。$ docker build -f /path/to/a/Dockerfile .ビルドが成功した場合に新しいイメージを保存するリポジトリとタグを指定できます。
$ docker build -t shykes/myapp .ビルド後にイメージを複数のリポジトリにタグ付けするには、ビルドコマンドの実行時に複数の
-t
パラメータを追加します。$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .Docker デーモンは Dockerfile の命令を実行する前に、 Dockerfile の事前検証を実行し、構文が正しくない場合はエラーを返します。
$ docker build -t test/myapp . Sending build context to Docker daemon 2.048 kB Error response from daemon: Unknown instruction: RUNCMDDocker デーモンは Dockerfile 内の命令を 1 つずつ実行し、必要に応じて各命令の結果を新しいイメージにコミットしてから、最終的に新しいイメージの ID を出力します。
Docker デーモンは、送信したコンテキストを自動的にクリーンアップします。各命令は独立して実行され、新しいイメージが作成されることに注意してください。
したがってRUN cd /tmp
は次の命令に影響を与えません。Docker は可能な場合は常に、中間イメージ(キャッシュ)を再利用して、Docker ビルドプロセスを大幅に高速化します。
中間イメージの再利用は、コンソール出力のUsing cache
メッセージによって示されます。
(詳細については Dockerfile ベストプラクティスガイド を参照してください)$ docker build -t svendowideit/ambassador . Sending build context to Docker daemon 15.36 kB Step 1/4 : FROM alpine:3.2 ---> 31f630c65071 Step 2/4 : MAINTAINER SvenDowideit@home.org.au ---> Using cache ---> 2a1c91448f5f Step 3/4 : RUN apk update && apk add socat && rm -r /var/cache/ ---> Using cache ---> 21ed6e7fbb73 Step 4/4 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh ---> Using cache ---> 7ea8aef582cc Successfully built 7ea8aef582ccビルドキャッシュは親チェーンを持つローカルイメージからのみ使用されます。
これはイメージが以前のビルドによって作成されたか、イメージのチェーン全体がdocker load
で読込まれたことを意味します。
特定のイメージのビルドキャッシュを使用する場合は--cache-from
オプションを使用して指定できます。
--cache-from
で指定されたイメージは、親チェーンを持つ必要はなく、他のレジストリから取得できます。ビルドが完了したら、リポジトリをレジストリにプッシュする方法を検討する準備が整います。
BuildKit
バージョン 18.09 以降の Docker は moby/buildkit プロジェクトによって提供されるビルドを実行するための新しいバックエンドをサポートします。
BuildKit バックエンドには、古い実装と比較して多くの利点があります。
たとえば BuildKit は次のことができます。
- 未使用のビルドステージの実行を検出してスキップします
- ビルドの独立したビルドステージを並列化します
- ビルド間でビルドコンテキスト内の変更されたファイルのみを段階的に転送します
- ビルドコンテキストで未使用のファイルの転送を検出してスキップします
- 多くの新機能を備えた外部 Dockerfile 実装を使用します
- 残りの API(中間イメージとコンテナー)での副作用を回避します
- 自動プルーニングのためにビルドキャッシュに優先順位を付けます
BuildKit バックエンドを使用するには docker build を呼び出す前に、 CLI で環境変数
DOCKER_BUILDKIT=1
を設定する必要があります。BuildKit ベースのビルドで使用できる実験的な Dockerfile 構文については BuildKit リポジトリのドキュメント を参照してください。
Format
Dockerfile の形式は次のとおりです。
# Comment INSTRUCTION arguments
命令では大文字と小文字は区別されません。
ただし、引数と区別しやすいように大文字にするのが慣例です。Docker は Dockerfile 内の命令を順番に実行します。
Dockerfile はFROM
命令で始まる必要があります。
これは、パーサーディレクティブ、コメント、およびグローバルスコープのARG
の後にある可能性があります。
FROM
命令は、構築元の親イメージを指定します。
FROM
の前には Dockerfile のFROM
行で使用される引数を宣言する 1 つ以上のARG
命令のみを付けることができます。Docker は行が有効なパーサーディレクティブでない限り
#
で始まる行をコメントとして扱います。
行内の他の場所にある#
マーカーは、引数として扱われます。
これにより、次のようなステートメントが可能になります。# Comment RUN echo 'we are running some # of cool things'Dockerfile 命令が実行される前にコメント行が削除されます。
つまり次の例のコメントは、echo
コマンドを実行するシェルによって処理されません。
以下の両方の例は同等です。RUN echo hello \ # comment worldRUN echo hello \ world行継続文字はコメントではサポートされていません。
空白に関する注意
下位互換性のために、コメント(
#
)および命令(RUN
など)の前の先頭の空白は無視されますが、推奨されません。
これらの場合、先頭の空白は保持されないため、次の例は同等です。# this is a comment-line RUN echo hello RUN echo world# this is a comment-line RUN echo hello RUN echo worldただし
RUN
に続くコマンドなど、命令引数の空白は保持されるため、次の例では、先頭に空白を指定してhello world
を出力します。RUN echo "\ hello\ world"パーサーディレクティブ
パーサーディレクティブはオプションであり、 Dockerfile の後続の行が処理される方法に影響を与えます。
パーサーディレクティブはビルドにレイヤーを追加せず、ビルドステップとして表示されません。
パーサーディレクティブは# directive=value
の形式で特別なタイプのコメントとして記述されます。
1 つのディレクティブは 1 回だけ使用できます。コメント、空の行、またはビルダー命令が処理されると、 Docker はパーサーディレクティブを検索しなくなります。
パーサーディレクティブとして記述されたものをコメントとして扱い、パーサーディレクティブである可能性があるかどうかの検証を試みません。
したがって、すべてのパーサーディレクティブは Dockerfile の最上部にある必要があります。パーサーディレクティブでは大文字と小文字は区別されません。
ただし慣例では小文字にする必要があります。
慣例ではパーサーディレクティブの後に空白行を含めることもできます。
行継続文字は、パーサーディレクティブではサポートされていません。これらの規則により、次の例はすべて無効です。
行継続のため無効
# direc \ tive=value2 回表示されるため無効
# directive=value1 # directive=value2 FROM ImageNameビルダーの指示の後に表示されるため、コメントとして扱われます。
FROM ImageName # directive=value
パーサーディレクティブではないコメントの後に表示されるため、コメントとして扱われます。
# About my dockerfile # directive=value FROM ImageName
unknowndirective
は、認識されないためコメントとして扱われます。
さらにknowndirective
は、パーサーディレクティブではないコメントの後に表示されるため、コメントとして扱われます。# unknowndirective=value # knowndirective=valueパーサーディレクティブでは、改行のない空白が許可されています。
したがって、次の行はすべて同じように扱われます。#directive=value # directive =value # directive= value # directive = value # dIrEcTiVe=value次のパーサーディレクティブがサポートされています。
- syntax
- escape
syntax
# syntax=[remote image reference]
例
# syntax=docker/dockerfile # syntax=docker/dockerfile:1.0 # syntax=docker.io/docker/dockerfile:1 # syntax=docker/dockerfile:1.0.0-experimental # syntax=example.com/user/repo:tag@sha256:abcdef...この機能は BuildKit バックエンドが使用されている場合にのみ有効になります。
syntax
ディレクティブは、現在の Dockerfile のビルドに使用される Dockerfile ビルダーの場所を定義します。
BuildKit バックエンドを使用すると Docker イメージとして配布され、コンテナーサンドボックス環境内で実行されるビルダーの外部実装をシームレスに使用できます。カスタム Dockerfile 実装により、次のことが可能になります。
- デーモンを更新せずにバグ修正を自動的に取得する
- すべてのユーザーが同じ実装を使用して Dockerfile をビルドしていることを保証できる
- デーモンを更新せずに最新の機能を使用することができる
- 新しい実験的またはサードパーティの機能を試すことができる
公式リリース
Docker は DockerHub の docker/dockerfile リポジトリーに Dockerfile を構築するために使用できるイメージの公式バージョンを配布しています。
新しいイメージがリリースされるチャネルは、安定版と実験版の 2 つです。安定版チャネルは、セマンティックバージョニングに従います。
例:
- docker/dockerfile:1.0.0 - 不変バージョン 1.0.0 のみを許可する
- docker/dockerfile:1.0 - バージョン 1.0.* を許可する
- docker/dockerfile:1 - versions 1.. を許可する
- docker/dockerfile:latest - 安定版チャネルの最新リリース
実験版チャネルは、リリース時の安定版チャネルからのメジャーコンポーネントとマイナーコンポーネントを使用したインクリメンタルバージョン管理を使用します。
例:
- docker/dockerfile:1.0.1-experimental - 不変バージョン 1.0.1-experimental のみを許可する
- docker/dockerfile:1.0-experimental - 1.0 以降の最新の実験版リリース
- docker/dockerfile:experimental - 実験版チャネルの最新リリース
ニーズに適したチャネルを選択する必要があります。
バグ修正のみが必要な場合は docker/dockerfile:1.0 を使用する必要があります。
実験的な機能を活用したい場合は、実験版チャネルを使用する必要があります。
実験チャネルを使用している場合、新しいリリースには下位互換性がない可能性があるため、不変のフルバージョンバリアントを使用することをお勧めします。マスタービルドとナイトリー機能リリースについては ソースリポジトリの説明 を参照してください。
escape
# escape=\ (backslash)
または
# escape=` (backtick)
エスケープディレクティブは Dockerfile 内の文字をエスケープするために使用される文字を設定します。
指定しない場合、デフォルトのエスケープ文字は\
です。エスケープ文字は、行内の文字をエスケープするためと、改行をエスケープするための両方に使用されます。
これにより Dockerfile 命令を複数行にまたがることができます。
escape
パーサーディレクティブが Dockerfile に含まれているかどうかに関係なく、エスケープは、行の終わりを除いて、RUN
コマンドでは実行されないことに注意してください。エスケープ文字を「 ` 」に設定すると Windows で特に役立ちます。
ここでは\
はディレクトリパスの区切り文字です。
「 ` 」は Windows PowerShell と一貫性があります。Windows で自明ではない方法で失敗する次の例を考えてみましょう。
2 行目の終わりにある 2 番目の\
は、最初の\
からのエスケープのターゲットではなく、改行のエスケープとして解釈されます。
同様に 3 行目の終わりにある\
は、実際に命令として処理されたとすると、行の継続として扱われます。
この dockerfile の結果は 2 行目と 3 行目が単一の命令と見なされることです。FROM microsoft/nanoserver COPY testfile.txt c:\\ RUN dir c:\実行結果:
PS C:\John> docker build -t cmd . Sending build context to Docker daemon 3.072 kB Step 1/2 : FROM microsoft/nanoserver ---> 22738ff49c6d Step 2/2 : COPY testfile.txt c:\RUN dir c: GetFileAttributesEx c:RUN: The system cannot find the file specified. PS C:\John>上記の解決策の 1 つは
COPY
命令とdir
の両方のターゲットとして/
を使用することです。
ただし、この構文は Windows のパスでは自然ではないため混乱を招きます。
最悪の場合 Windows のすべてのコマンドがパス区切り文字として/
をサポートしているわけではないため、エラーが発生しやすくなります。
escape
パーサーディレクティブを追加することにより、次の Dockerfile は Windows のファイルパスに自然なプラットフォームセマンティクスを使用して期待どおりに成功します。# escape=` FROM microsoft/nanoserver COPY testfile.txt c:\ RUN dir c:\実行結果:
PS C:\John> docker build -t succeeds --no-cache=true . Sending build context to Docker daemon 3.072 kB Step 1/3 : FROM microsoft/nanoserver ---> 22738ff49c6d Step 2/3 : COPY testfile.txt c:\ ---> 96655de338de Removing intermediate container 4db9acbb1682 Step 3/3 : RUN dir c:\ ---> Running in a2c157f842f5 Volume in drive C has no label. Volume Serial Number is 7E6D-E0F7 Directory of c:\ 10/05/2016 05:04 PM 1,894 License.txt 10/05/2016 02:22 PM <DIR> Program Files 10/05/2016 02:14 PM <DIR> Program Files (x86) 10/28/2016 11:18 AM 62 testfile.txt 10/28/2016 11:20 AM <DIR> Users 10/28/2016 11:20 AM <DIR> Windows 2 File(s) 1,956 bytes 4 Dir(s) 21,259,096,064 bytes free ---> 01c7f3bef04f Removing intermediate container a2c157f842f5 Successfully built 01c7f3bef04f PS C:\John>環境変数の置換
環境変数(
ENV
ステートメントで宣言)は、 Dockerfile によって解釈される変数として特定の命令で使用することもできます。
エスケープは、変数に似た構文をそのままステートメントに含めるためにも処理されます。環境変数は Dockerfile で
$variable_name
または${variable_name}
のいずれかで表記されます。
それらは同等に扱われ、中括弧構文は通常${foo} _bar
のように空白のない変数名の問題に対処するために使用されます。
${variable_name}
構文は、以下に指定されている標準の bash 修飾子のいくつかもサポートしています。
${variable:-word}
は変数が設定されている場合、結果がその値になることを示します。 変数が設定されていない場合word
が結果になります。${variable:+word}
は、変数が設定されている場合はword
が結果になり、それ以外の場合は結果が空の文字列になることを示します。すべての場合において
word
は、追加の環境変数を含む任意の文字列にすることができます。エスケープは変数の前に
\
を追加することで可能です。
たとえば\$ foo
または\${foo}
は、$foo
と${foo}
に変換されます。例(解析された表現は
#
の後に表示されます):FROM busybox ENV FOO=/bar WORKDIR ${FOO} # WORKDIR /bar ADD . $FOO # ADD . /bar COPY \$FOO /quux # COPY $FOO /quux環境変数は Dockerfile の以下に示す命令でサポートされています。
- ADD
- COPY
- ENV
- EXPOSE
- FROM
- LABEL
- STOPSIGNAL
- USER
- VOLUME
- WORKDIR
- ONBUILD (上記のサポートされている手順の 1 つと組み合わせた場合)
環境変数の置換では、命令全体を通じて各変数に同じ値が使用されます。
言い換えると、この例では次のようになります。ENV abc=hello ENV abc=bye def=$abc ENV ghi=$abc結果は
bye
ではなくhello
の値を持つdef
になります。
ただしghi
はabc
をbye
に設定したのと同じ命令の一部ではないため、bye
の値になります。.dockerignore ファイル
docker CLI はコンテキストを docker デーモンに送信する前に、コンテキストのルートディレクトリで
.dockerignore
という名前のファイルを探します。
このファイルが存在する場合 CLI はコンテキストを変更して、その中のパターンに一致するファイルとディレクトリを除外します。
これにより、大きなファイルや機密性の高いファイルやディレクトリをデーモンに不必要に送信したり、ADD
またはCOPY
を使用してイメージに追加したりすることを回避できます。CLIは
.dockerignore
ファイルを Unix シェルのファイルグロブに似た改行で区切られたパターンのリストとして解釈します。
照合の目的で、コンテキストのルートは作業ディレクトリとルートディレクトリの両方であると見なされます。
たとえば、パターン/foo/bar
とfoo/bar
はどちらも、PATH
のfoo
サブディレクトリまたは URL にある git リポジトリのルートにあるbar
という名前のファイルまたはディレクトリを除外します。
どちらも他のものを除外しません。
.dockerignore
ファイルの行が 1 列目の#
で始まる場合、この行はコメントと見なされ、 CLI によって解釈される前に無視されます。
.dockerignore
ファイルの記述例を示します:# comment */temp* */*/temp* temp?このファイルにより、次のビルド動作が発生します。
ルール 動作 # comment
無視します。 */temp*
ルートの直接のサブディレクトリで、名前が temp
で始まるファイルとディレクトリを除外します。たとえば、プレーンファイル/somedir/temporary.txt
は除外され、ディレクトリ/somedir/temp
も除外されます。*/*/temp*
ルートの 2 階層下にあるサブディレクトリから temp
で始まるファイルとディレクトリを除外します。たとえば、/somedir/subdir/temporary.txt
は除外されます。temp?
名前が temp + 1 文字であるルートディレクトリ内のファイルとディレクトリを除外します。たとえば、 /tempa
と/tempb
は除外されます。マッチングは Go の
filepath.Match
ルールを使用して行われます。
前処理ステップでは Go のfilepath.Clean
を使用して、先頭と末尾の空白を削除し、.
要素と..
要素を削除します。
前処理後に空白の行は無視されます。Docker は Go の
filepath.Match
ルールに加えて、任意の数のディレクトリ(ゼロを含む)に一致する特別なワイルドカード文字列**
もサポートしています。
たとえば**/*.go
はビルドコンテキストのルートを含むすべてのディレクトリにある.go
で終わるすべてのファイルを除外します。
!
(感嘆符)で始まる行を使用して、除外の例外を作成できます。
以下は、この仕組みを使用する.dockerignore
ファイルの例です。*.md !README.md
README.md
を除くすべてのマークダウンファイルはコンテキストから除外されます。
!
例外ルールの配置は、動作に影響を与えます。
特定のファイルに一致する.dockerignore
の最後の行は、そのファイルが含まれるか除外されるかを決定します。
次の例を考えてみましょう。*.md !README*.md README-secret.md
README-secret.md
以外のREADME
ファイルを除いて、マークダウンファイルはコンテキストに含まれていません。ここで、この例を検討します。
*.md README-secret.md !README*.mdすべての
README
ファイルが含まれています。
!README*.md
はREADME-secret.md
と一致し、最後に来るため、真ん中の行は効果がありません。
.dockerignore
ファイルを使用して Dockerfile ファイルと.dockerignore
ファイルを除外することもできます。
これらのファイルは、そのジョブを実行する必要があるため、引き続きデーモンに送信されます。
ただしADD
およびCOPY
命令はそれらをイメージにコピーしません。最後に、除外するファイルではなく、コンテキストに含めるファイルを指定することをお勧めします。
これを実現するには、最初のパターンとして*
を指定し、その後に 1 つ以上の!
例外パターンを指定します。注意
歴史的な理由から、パターン
.
は無視されます。FROM
FROM [--platform=<platform>] <image> [AS <name>]または
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]または
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
FROM
命令は、新しいビルドステージを初期化し、後続の命令のベースイメージを設定します。
そのため、有効な Dockerfile はFROM
命令で始まる必要があります。
イメージは任意の有効なイメージを指定することができます。
パブリックリポジトリからイメージを取得することから始めるのは特に簡単です。
ARG
は Dockerfile のFROM
の前にある可能性がある唯一の命令です。ARG
とFROM
の相互作用を理解する を参照してください。FROM
は、単一の Dockerfile 内に複数回出現して、複数のイメージを作成したり、あるビルドステージを別のビルドステージの依存関係として使用したりできます。 新しいFROM
命令の前に、commit
によって出力された最後のイメージ ID をメモするだけです。 各FROM
命令は、前の命令によって作成されたすべての状態をクリアします。- オプションで
FROM
命令にAS name
を追加することにより、新しいビルドステージに名前を付けることができます。 この名前は、後続のFROM
およびCOPY --from=<name>
命令で使用して、このステージで作成されたイメージを参照できます。- タグまたはダイジェスト値はオプションです。 いずれかを省略すると、ビルダーはデフォルトで最新のタグを想定します。 タグ値が見つからない場合、ビルダーはエラーを返します。
オプションの
--platform
フラグを使用して、FROM
がマルチプラットフォームイメージを参照する場合にイメージのプラットフォームを指定できます。
たとえば、linux/amd64
、linux/arm64
、またはwindows/amd64
です。
デフォルトでは、ビルドリクエストのターゲットプラットフォームが使用されます。
このフラグの値にはグローバルビルド引数を使用できます。
たとえば、自動プラットフォーム引数を使用すると、ステージをネイティブビルドプラットフォームに強制し、それを使用してステージ内のターゲットプラットフォームにクロスコンパイルできます。
(--platform=$BUILDPLATFORM
)
ARG
とFROM
の相互作用を理解する
FROM
命令は、最初のFROM
の前に発生するARG
命令によって宣言される変数をサポートします。ARG CODE_VERSION=latest FROM base:${CODE_VERSION} CMD /code/run-app FROM extras:${CODE_VERSION} CMD /code/run-extras
FROM
の前に宣言されたARG
はビルドステージの外にあるため、FROM
の後の命令では使用できません。
最初のFROM
の前に宣言されたARG
のデフォルト値を使用するには、ビルドステージ内で値なしでARG
命令を使用します。ARG VERSION=latest FROM busybox:$VERSION ARG VERSION RUN echo $VERSION > image_versionRUN
RUN
は 2 種類の形式があります:
RUN <command>
(シェル形式。コマンドはシェル上で実行される。 Linux の既定シェルは/bin/sh -c
。 Windows の既定シェルはcmd /S /C
)RUN ["executable", "param1", "param2"]
(exec
形式)
RUN
命令は、現在のイメージ上にある新しいレイヤーでコマンドを実行し、結果をコミットします。
結果がコミットされたイメージは Dockerfile の次のステップで使用されます。
RUN
命令を階層化し、コミットを生成することは、コミットが安価で、ソース管理のようにイメージの履歴の任意のポイントからコンテナを作成できる Docker のコアコンセプトに準拠しています。
exec
形式を使用すると、シェル文字列の変更を回避したり、指定したシェル実行可能ファイルを含まないベースイメージを使用してRUN
コマンドを実行できます。シェル形式の既定のシェルは
SHELL
コマンドを使用して変更できます。シェル形式では、
\
(バックスラッシュ)を使用して、単一のRUN
命令を次の行に続けることができます。
たとえば、次の 2 行について考えてみます。RUN /bin/bash -c 'source $HOME/.bashrc; \ echo $HOME'これらを合わせると、次の 1 行に相当します。
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
/bin/sh
以外の別のシェルを使用するには、目的のシェルを渡すexec
形式を使用します。例えば:RUN ["/bin/bash", "-c", "echo hello"]注意
exec
形式は JSON 配列として解析されます。
つまり一重引用符('
)ではなく、単語の前後に二重引用符("
)を使用する必要があります。シェル形式とは異なり、
exec
形式はコマンドシェルを呼び出しません。
これは、通常のシェル処理が行われないことを意味します。
たとえば、RUN ["echo", "$HOME"]
は、$HOME
の変数置換を行いません。
シェル処理が必要な場合は、シェル形式を使用するか、シェルを直接実行します。
例:RUN ["sh", "-c", "echo $ HOME"]
。
シェル形式の場合のように、exec
形式を使用してシェルを直接実行する場合、環境変数の展開を行うのは Docker ではなく、シェルです。注意
JSON 形式では、バックスラッシュをエスケープする必要があります。
これは、バックスラッシュがパス区切り文字である Windows に特に関係があります。
次の行は、有効な JSON ではないため、シェル形式として扱われ、予期しない方法で失敗します:RUN ["c:\windows\system32\tasklist.exe"]この例の正しい構文は次のとおりです:
RUN ["c:\\windows\\system32\\tasklist.exe"]
RUN
命令のキャッシュは、次のビルド中に自動的に無効になることはありません。
RUN apt-get dist-upgrade -y
のような命令のキャッシュは、次のビルドで再利用されます。
RUN
命令のキャッシュは--no-cache
フラグを使用して無効にすることができます(例:docker build --no-cache
)。詳細については Dockerfile ベストプラクティスガイド を参照してください。
RUN
命令のキャッシュは、ADD
およびCOPY
命令によって無効にすることができます。既知の問題(
RUN
)
- イシュー 783 は、 AUFS ファイルシステムの使用時に発生する可能性のあるファイル権限の問題に関するものです。 たとえば、ファイルを
rm
しようとしたときに気付くかもしれません。 最近の aufs バージョンがあるシステム(つまりdirperm1
マウントオプションを設定できる)の場合、 docker はdirperm1
オプションを使用してレイヤーをマウントすることで問題を自動的に修正しようとします。dirperm1
オプションの詳細については aufs の man ページ を参照してください。 システムでdirperm1
がサポートされていない場合、 イシュー 783 は回避策を説明しています。CMD
CMD
命令は 3 つの形式を持ちます:
CMD ["executable","param1","param2"]
(exec
形式。これが推奨される形式です)CMD ["param1","param2"]
(ENTRYPOINT
へのデフォルトパラメータとして使用します)CMD command param1 param2
(シェル形式)Dockerfile には 1 つの
CMD
命令しか存在できません。
複数のCMD
を列記すると、最後のCMD
のみが有効になります。
CMD
の主な目的は、実行中のコンテナに既定の動作を提供することです。
これらの既定の動作には、executable
を含めることも、executable
を省略することもできます。
executable
を省略する場合はENTRYPOINT
命令も指定する必要があります。
CMD
を使用してENTRYPOINT
命令のデフォルトの引数を提供する場合は、CMD
命令とENTRYPOINT
命令の両方を JSON 配列形式で指定する必要があります。注意
exec
形式は JSON 配列として解析されます。
つまり単語の前後に一重引用符('
)ではなく、二重引用符("
)を使用する必要があります。シェル形式とは異なり、
exec
形式はコマンドシェルを呼び出しません。
これは、通常のシェル処理が行われないことを意味します。
たとえばCMD ["echo", "$HOME"]
は、$HOME
で変数置換を行いません。
シェル処理が必要な場合は、シェル形式を使用するか、シェルを直接実行します。
例:CMD ["sh"、 "-c"、 "echo $ HOME"]
シェル形式の場合のように、exec
形式を使用してシェルを直接実行する場合、環境変数の展開を行うのは Docker ではなく、シェルです。シェル形式または
exec
形式で使用する場合、CMD
命令は、イメージの実行時に実行されるコマンドを設定します。
CMD
のシェル形式を使用する場合、<command>
は/bin/sh -c
で実行されます:FROM ubuntu CMD echo "This is a test." | wc -シェルなしで
<command>
を実行したい場合は、コマンドを JSON 配列として表現し、executable
へのフルパスを指定する必要があります。
この配列形式は、CMD
の推奨フォーマットです。
追加のパラメータは、配列内の文字列として個別に表現する必要があります。FROM ubuntu CMD ["/usr/bin/wc","--help"]コンテナで毎回同じ
executable
を実行したい場合は、ENTRYPOINT
をCMD
と組み合わせて使用することを検討する必要があります。
ENTRYPOINT
を参照してください。ユーザーが docker run の引数を指定すると、
CMD
で指定された既定値が上書きされます。注意
RUN
とCMD
を混同しないでください。
RUN
は実際にコマンドを実行し、結果をコミットします。
CMD
はビルド時に何も実行しませんが、イメージに実行させたいコマンドを指定します。LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL
命令はメタデータをイメージに追加します。
LABEL
はキーと値のペアです。
LABEL
の値にスペースを含めるには、コマンドライン解析の場合と同じように引用符とバックスラッシュを使用します。使用例:
LABEL "com.example.vendor"="ACME Incorporated" LABEL com.example.label-with-value="foo" LABEL version="1.0" LABEL description="This text illustrates \ that label-values can span multiple lines."イメージには複数のラベルを付けることができます。
1 行に複数のラベルを指定できます。
Docker 1.10 より前は、これにより最終イメージのサイズが小さくなりましたが、現在はそうではありません。
次の 2 つの方法のいずれかで、 1 つの命令で複数のラベルを指定することもできます。LABEL multi.label1="value1" multi.label2="value2" other="value3"LABEL multi.label1="value1" \ multi.label2="value2" \ other="value3"ベースイメージまたは親イメージ(
FROM
行のイメージ)に含まれるラベルは、子イメージに継承されます。
ラベルがすでに存在するが値が異なる場合、最後に適用された値が以前に設定された値を上書きします。イメージのラベルを表示するには
docker image inspect
コマンドを使用します。
--format
オプションを使用してラベルのみを表示できます。docker image inspect --format='' myimage{ "com.example.vendor": "ACME Incorporated", "com.example.label-with-value": "foo", "version": "1.0", "description": "This text illustrates that label-values can span multiple lines.", "multi.label1": "value1", "multi.label2": "value2", "other": "value3" }MAINTAINER (非推奨)
MAINTAINER <name>
MAINTAINER
命令は、生成されたイメージのAuthor
フィールドを設定します。
LABEL
命令はMAINTAINER
よりもはるかに柔軟に必要なメタデータを設定できます。
代わりにLABEL
を使用してください。
たとえばdocker inspect
を使用して簡単に表示できます。
MAINTAINER
フィールドに対応するラベルを設定するには:LABEL maintainer="SvenDowideit@home.org.au"これは、他のラベルとともに
docker inspect
から表示されます。EXPOSE
EXPOSE <port> [<port>/<protocol>...]
EXPOSE
命令は、コンテナ実行時に指定されたネットワークポートで待受けすることを Docker に通知します。
ポートが TCP と UDP のどちらで待受けするかを指定できます。
プロトコルが指定されていない場合、既定値は TCP です。
EXPOSE
命令は、実際にはポートを公開しません。
これは、イメージを作成する人とコンテナーを実行する人の間の一種のドキュメントとして機能し、ポートの公開が意図されています。
コンテナの実行時に実際にポートを公開するには、 docker run で-p
フラグを使用して 1 つ以上のポートを公開して紐づけするか、-P
フラグを使用して公開されたすべてのポートを公開し、それらを上位ポートに紐づけします。デフォルトでは
EXPOSE
は TCP を想定していますが、
UDP を指定することもできます。EXPOSE 80/udpTCP と UDP の両方で公開するには、次の 2 行を記述します。
EXPOSE 80/tcp EXPOSE 80/udpこの場合 docker run で
-P
を使用すると、ポートは TCP 用に 1 回、 UDP 用に 1 回公開されます。
-P
はホスト上で一時的な上位ホストポートを使用するため、ポートは TCP と UDP で同じではないことに注意してください。
EXPOSE
設定に関係なく-p
フラグを使用して実行時にそれらをオーバーライドできます。例:
docker run -p 80:80/tcp -p 80:80/udp ...ホストシステムでポートリダイレクションを設定するには
-P
フラグの使用を参照してください。
docker network
コマンドは、特定のポートを公開(expose または publish)する必要なしに、コンテナー間の通信用のネットワークの作成をサポートします。
これは、ネットワークに接続されたコンテナーが任意のポートを介して相互に通信できるためです。
詳細については、 docker network 機能の概要 を参照してください。ENV
ENV <key>=<value> ...
ENV
命令は、環境変数<key>
を値<value>
に設定します。
この値は、ビルドステージの後続のすべての命令の環境にあり、多くの場合、インラインで置き換えることができます。
値は他の環境変数に対して解釈されるため、引用符がエスケープされていない場合は削除されます。
コマンドライン解析と同様に、引用符とバックスラッシュを使用して値にスペースを含めることができます。例:
ENV MY_NAME="John Doe" ENV MY_DOG=Rex\ The\ Dog ENV MY_CAT=fluffy
ENV
命令では、複数の<key>=<value> ...
変数を一度に設定できます。
以下の例では、最終的なイメージで同じ最終結果が得られます。ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \ MY_CAT=fluffy
ENV
を使用して設定された環境変数は、結果のイメージからコンテナが実行されたときに保持されます。
docker inspect
を使用して値を表示し、docker run --env <key>=<value>
を使用して値を変更できます。環境変数の永続性は、予期しない副作用を引き起こす可能性があります。
たとえばENV DEBIAN_FRONTEND=noninteractive
を設定すると、apt-get
の動作が変更され、イメージのユーザーを混乱させる可能性があります。環境変数がビルド中にのみ必要であり、最終イメージでは必要ない場合は、代わりに単一のコマンドの値を設定することを検討してください。
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...または最終的なイメージに保持されない
ARG
を使用します。ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y ...代替記法
ENV
命令では代替構文ENV <key> <value>
を使用でき、=
を省略できます。例:
ENV MY_VAR my-valueこの構文では複数の環境変数を 1 つの
ENV
命令に設定することはできず、混乱を招く可能性があります。
たとえば次のように、単一の環境変数ONE
を値"TWO = THREE = world"
で設定します。ENV ONE TWO= THREE=world代替構文は下位互換性のためにサポートされていますが、上記の理由により推奨されておらず、将来のリリースで削除される可能性があります。
ADD
ADD
は 2 つの形式を持ちます:ADD [--chown=<user>:<group>] <src>... <dest> ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]空白を含むパスには後者の形式が必要です。
注意
--chown
機能は Linux コンテナの構築に使用される Dockerfile でのみサポートされており、 Windows コンテナでは機能しません。
ユーザーとグループの所有権の概念は Linux と Windows の間で変換されないため、ユーザー名とグループ名を ID に変換するために/etc/passwd
と/etc/group
を使用すると、この機能は Linux OS ベースのコンテナである場合に限り実行可能に制限されます。
ADD
命令は、新しいファイル、ディレクトリ、またはリモートファイルの URL を<src>
からコピーし、パス<dest>
でイメージのファイルシステムに追加します。複数の
<src>
リソースを指定できますが、それらがファイルまたはディレクトリの場合、パスはビルドのコンテキストのソースからの相対パスとして解釈されます。各
<src>
にはワイルドカードを含めることができ、照合は Go のfilepath.Match
ルールを使用して行われます。
例えばhom
で始まるすべてのファイルを追加するには:ADD hom* /mydir/
以下の例では
?
はhome.txt
などの任意の 1 文字に置き換えられています。ADD hom?.txt /mydir/
<dest>
は絶対パス、またはWORKDIR
から見た相対パスであり、ソースは宛先コンテナ内にコピーされます。以下の例では、相対パスを使用して
test.txt
を<WORKDIR>/relativeDir/
に追加しています:ADD test.txt relativeDir/この例では絶対パスを使用して
test.txt
を/abstractDir/
に追加します。ADD test.txt /absoluteDir/特殊文字(
[
や]
など)を含むファイルやディレクトリを追加する場合は、一致するパターンとして扱われないように、 Go 言語のルールに従ってこれらのパスをエスケープする必要があります。
たとえば、arr[0].txt
という名前のファイルを追加するには、次を使用します。ADD arr[[]0].txt /mydir/追加されたコンテンツの特定の所有権を要求するために、オプションの
--chown
フラグが特定のユーザー名、グループ名、またはUID / GIDの組み合わせを指定しない限り、すべての新しいファイルとディレクトリは UID と GID が 0 で作成されます。
--chown
フラグの形式では、ユーザー名とグループ名の文字列、または直接整数の UID と GID を任意の組み合わせで使用できます。
グループ名なしのユーザー名または GID なしの UID を指定すると、 GID と同じ数値の UID が使用されます。
ユーザー名またはグループ名が指定されている場合、コンテナのルートファイルシステムの/etc/passwd
ファイルと/etc/group
ファイルを使用して、名前から整数の UID または GID への変換がそれぞれ実行されます。
次の例は、--chown
フラグの有効な定義を示しています。ADD --chown=55:mygroup files* /somedir/ ADD --chown=bin files* /somedir/ ADD --chown=1 files* /somedir/ ADD --chown=10:11 files* /somedir/コンテナルートファイルシステムに
/etc/passwd
または/etc/group
ファイルが含まれておらず、ユーザー名またはグループ名が--chown
フラグで使用されている場合、ADD
操作でビルドは失敗します。
数値 ID の使用はルックアップを必要とせず、コンテナルートファイルシステムのコンテンツに依存しません。
<src>
がリモートファイルの URL の場合、宛先には 600 の権限があります。
取得するリモートファイルに HTTP Last-Modified ヘッダーがある場合、そのヘッダーのタイムスタンプを使用して、宛先ファイルの mtime を設定します。
ただしADD
中に処理される他のファイルと同様に、 mtime は、ファイルが変更されたかどうかの判断には含まれず、キャッシュを更新する必要があります。注意
Dockerfile を
STDIN
(docker build- <somefile
)に渡してビルドする場合、ビルドコンテキストがないため、 Dockerfile には URL ベースのADD
命令のみを含めることができます。
圧縮されたアーカイブをSTDIN
: (docker build- <archive.tar.gz
)を介して渡すこともできます。アーカイブのルートにある Dockerfile と、アーカイブの残りの部分がビルドのコンテキストとして使用されます。URL ファイルが認証を使用して保護されている場合、
ADD
命令は認証をサポートしていないため、RUN wget
やRUN curl
を使用するか、コンテナ内から別のツールを使用する必要があります。注意
最初に検出された
ADD
命令は、<src>
の内容が変更された場合、 Dockerfile からの後続のすべての命令のキャッシュを無効にします。
これにはRUN
命令のキャッシュの無効化が含まれます。
詳細については Dockerfile ベストプラクティスガイド – ビルドキャッシュを活用する を参照してください。
ADD
は次のルールに従います。
<src>
パスはビルドのコンテキスト内にある必要があります。 docker build の最初のステップはコンテキストディレクトリ(およびサブディレクトリ)を docker デーモンに送信することであるため、ADD ../something / something
はできません。<src>
が URL であり、<dest>
が末尾のスラッシュで終わっていない場合、ファイルは URL からダウンロードされ、<dest>
にコピーされます。<src>
が URL で、<dest>
が末尾にスラッシュで終わっている場合、ファイル名は URL から推測され、ファイルは<dest>/<filename>
にダウンロードされます。 たとえば、ADD http://example.com/foobar /
はファイル/foobar
を作成します。 この場合、適切なファイル名を検出できるように URL には重要なパスが必要です(http://example.com
は機能しません)。<src>
がディレクトリの場合、ファイルシステムのメタデータを含むディレクトリの内容全体がコピーされます。注意
ディレクトリ自体はコピーされず、その内容だけがコピーされます。
<src>
が認識された圧縮形式(gzip
,bzip2
またはxz
)のローカル tar アーカイブである場合、ディレクトリとして解凍されます。 リモート URL からのリソースは解凍されません。 ディレクトリがコピーまたは解凍されるとtar -x
と同じ動作になり、結果は次の和集合になります。
- 宛先パスに存在するものは何でも
- 競合するソースツリーの内容はファイルごとに
2
を優先して解決されます。注意
ファイルが認識された圧縮形式として識別されるかどうかは、ファイルの名前ではなく、ファイルの内容のみに基づいて行われます。
たとえば、空のファイルがたまたま.tar.gz
で終わっている場合、これは圧縮ファイルとして認識されず、解凍エラーメッセージは生成されず、ファイルは単に宛先にコピーされます。
<src>
が他の種類のファイルの場合、メタデータとともに個別にコピーされます。 この場合<dest>
の末尾にスラッシュ/
が付いていると、ディレクトリと見なされ、<src>
の内容は<dest>/base(<src>)
に書き込まれます。- 直接またはワイルドカードの使用により複数の
<src>
リソースが指定されている場合、<dest>
はディレクトリである必要があり、スラッシュ/
で終了する必要があります。<dest>
が末尾のスラッシュで終わっていない場合、それは通常のファイルと見なされ、<src>
の内容は<dest>
に書き込まれます。<dest>
が存在しない場合は、パスに欠落しているすべてのディレクトリとともに作成されます。COPY
COPY
は 2 つの形式を持ちます:COPY [--chown=<user>:<group>] <src>... <dest> COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]後者の形式は、空白を含むパスに必要です。
注意
--chown
機能は Linux コンテナの構築に使用される Dockerfile でのみサポートされており、 Windows コンテナでは機能しません。
ユーザーとグループの所有権の概念は Linux と Windows の間で変換されないため、ユーザー名とグループ名を ID に変換するために/etc/passwd
と/etc/group
を使用します。
この機能は Linux OS ベースのコンテナである場合に限り実行可能に制限されます。
COPY
命令は、新しいファイルまたはディレクトリを<src>
からコピーし、パス<dest>
でコンテナのファイルシステムに追加します。複数の
<src>
リソースを指定できますが、ファイルとディレクトリのパスは、ビルドのコンテキストのソースから見た相対パスとして解釈されます。各
<src>
にはワイルドカードを含めることができ、照合は Go のfilepath.Match
ルールを使用して行われます。
例えばhom
で始まるすべてのファイルを追加するには:COPY hom* /mydir/
以下の例では
?
はhome.txt
などの任意の 1 文字に置き換えられています。COPY hom?.txt /mydir/
<dest>
は絶対パス、またはWORKDIR
に相対的なパスであり、ソースは宛先コンテナ内にコピーされます。以下の例では相対パスを使用して
test.txt
を<WORKDIR>/relativeDir/
に追加しています。COPY test.txt relativeDir/この例では絶対パスを使用して
test.txt
を/abstractDir/
に追加します。COPY test.txt /absoluteDir/特殊文字(
[
や]
など)を含むファイルやディレクトリをコピーする場合は、Go 言語のルールに従ってこれらのパスをエスケープして、一致するパターンとして扱われないようにする必要があります。
たとえば、arr[0].txt
という名前のファイルをコピーするには、次を使用します。COPY arr[[]0].txt /mydir/オプションの
--chown
フラグが、コピーされたコンテンツの特定の所有権を要求するために特定のユーザー名、グループ名、またはUID / GIDの組み合わせを指定しない限り、すべての新しいファイルとディレクトリは UID と GID が 0 で作成されます。
--chown
フラグの形式では、ユーザー名とグループ名の文字列、または直接整数の UID と GID を任意の組み合わせで使用できます。
グループ名なしのユーザー名または GID なしの UID を指定すると、 GID と同じ数値の UID が使用されます。
ユーザー名またはグループ名が指定されている場合、コンテナのルートファイルシステムの/etc/passwd
ファイルと/etc/group
ファイルを使用して、名前から整数の UID または GID への変換がそれぞれ実行されます。
次の例は、--chown
フラグの有効な定義を示しています。COPY --chown=55:mygroup files* /somedir/ COPY --chown=bin files* /somedir/ COPY --chown=1 files* /somedir/ COPY --chown=10:11 files* /somedir/コンテナのルートファイルシステムに
/etc/passwd
または/etc/group
ファイルが含まれておらず、ユーザー名またはグループ名が--chown
フラグで使用されている場合、ビルドはCOPY
操作で失敗します。
数値 ID の使用はルックアップを必要とせず、コンテナルートファイルシステムのコンテンツに依存しません。注意
STDIN
(docker build- < somefile
)を使用してビルドする場合、ビルドコンテキストがないためCOPY
は使用できません。オプションで
COPY
は、ソースの場所を前のビルドステージ(FROM .. AS <name>
で作成)に設定するために使用できるフラグ--from=<name>
を受け入れます。
ユーザーが送信するビルドコンテキストの代わりに使用されます。
指定された名前のビルドステージが見つからない場合は、代わりに同じ名前のイメージが使用されます。
COPY
は次のルールに従います:
<src>
パスはビルドのコンテキスト内にある必要があります。dockerbuild
の最初のステップはコンテキストディレクトリ(およびサブディレクトリ)を docker デーモンに送信することであるため、COPY ../something /something
はできません。<src>
がディレクトリの場合、ファイルシステムのメタデータを含むディレクトリの内容全体がコピーされます。注意
ディレクトリ自体はコピーされず、その内容だけがコピーされます。
<src>
がディレクトリ以外の種類のファイルの場合、メタデータとともに個別にコピーされます。 この場合<dest>
の末尾にスラッシュ/
が付いていると、ディレクトリと見なされ、<src>
の内容は<dest>/base(<src>)
に書き込まれます。- 直接またはワイルドカードの使用により複数の
<src>
リソースが指定されている場合、<dest>
はディレクトリである必要があり、スラッシュ/
で終了する必要があります。<dest>
が末尾のスラッシュで終わっていない場合、それは通常のファイルと見なされ、<src>
の内容は<dest>
に書き込まれます。<dest>
が存在しない場合は、パスに欠落しているすべてのディレクトリとともに作成されます。注意
最初に検出された
COPY
命令は<src>
の内容が変更された場合、 Dockerfile からの後続のすべての命令のキャッシュを無効にします。
これにはRUN
命令のキャッシュの無効化が含まれます。
詳細については Dockerfile ベストプラクティスガイド – ビルドキャッシュを活用する を参照してください。ENTRYPOINT
ENTRYPOINT
は 2 つの形式を持ちます:推奨形式は
exec
形式です:ENTRYPOINT ["executable", "param1", "param2"]シェル形式:
ENTRYPOINT command param1 param2
ENTRYPOINT
を使用すると、executable
が実行されるコンテナを構成できます。たとえば次の例では、 nginx をデフォルトのコンテンツで開始し、ポート 80 で待受けます。
$ docker run -i -t --rm -p 80:80 nginx
docker run <image>
へのコマンドライン引数はexec
形式ENTRYPOINT
のすべての要素の後に追加され、CMD
を使用して指定されたすべての要素を上書きします。
これにより、引数をエントリポイントに渡すことができます。
つまりdocker run <image> -d
は-d
引数をエントリポイントに渡します。
docker run --entrypoint
フラグを使用してENTRYPOINT
命令を上書きできます。シェル形式では
CMD
またはコマンドライン引数の実行が使用されなくなりますが、ENTRYPOINT
が信号を渡さない/bin/sh -c
のサブコマンドとして開始されるという欠点があります。
これはexecutable
がコンテナの PID 1 ではなく、 Unix シグナルを受信しないことを意味します。
したがってexecutable
はdocker stop <container>
からSIGTERM
を受信しません。Dockerfile の最後の
ENTRYPOINT
命令のみが有効になります。Exec 形式の
ENTRYPOINT
の例
exec
形式のENTRYPOINT
を使用して、かなり安定したデフォルトのコマンドと引数を設定してから、いずれかの形式のCMD
を使用して、変更される可能性が高い追加の既定動作を設定できます。FROM ubuntu ENTRYPOINT ["top", "-b"] CMD ["-c"]コンテナを実行すると
top
が唯一のプロセスであることがわかります。$ docker run -it --rm --name test top -H top - 08:25:00 up 7:27, 0 users, load average: 0.00, 0.01, 0.05 Threads: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 2056668 total, 1616832 used, 439836 free, 99352 buffers KiB Swap: 1441840 total, 0 used, 1441840 free. 1324440 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 19744 2336 2080 R 0.0 0.1 0:00.04 top結果をさらに調べるには
docker exec
を使用できます。$ docker exec -it test ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 2.6 0.1 19752 2352 ? Ss+ 08:24 0:00 top -b -H root 7 0.0 0.1 15572 2164 ? R+ 08:25 0:00 ps auxまた
docker stop test
を使用してtop
を正常にシャットダウンするように要求できます。次の Dockerfile は
ENTRYPOINT
を使用して Apache をフォアグラウンドで(つまり PID 1 として)実行する方法を示しています。FROM debian:stable RUN apt-get update && apt-get install -y --force-yes apache2 EXPOSE 80 443 VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"] ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]単一の
executable
のスタータースクリプトを作成する必要がある場合はexec
およびgosu
コマンドを使用して、最後のexecutable
が Unix シグナルを確実に受信できるようにすることができます。#!/usr/bin/env bash set -e if [ "$1" = 'postgres' ]; then chown -R postgres "$PGDATA" if [ -z "$(ls -A "$PGDATA")" ]; then gosu postgres initdb fi exec gosu postgres "$@" fi exec "$@"最後に、シャットダウン時に追加のクリーンアップを実行する(または他のコンテナと通信する)必要がある場合、または複数の
executable
を調整する場合は、ENTRYPOINT
スクリプトが Unix シグナルを送受信してさらにいくつかの作業を実行することを確認する必要があります。#!/bin/sh # Note: I've written this using sh so it works in the busybox container too # USE the trap if you need to also do manual cleanup after the service is stopped, # or need to start multiple services in the one container trap "echo TRAPed signal" HUP INT QUIT TERM # start service in background here /usr/sbin/apachectl start echo "[hit enter key to exit] or run 'docker stop <container>'" read # stop service and clean up here echo "stopping apache" /usr/sbin/apachectl stop echo "exited $0"このイメージを
dockerrun -it --rm -p 80:80 --name test apache
で実行すると、docker exec
またはdocker top
でコンテナーのプロセスを調べることができ、後続のスクリプトに Apache を停止するように依頼します。$ docker exec -it test ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.1 0.0 4448 692 ? Ss+ 00:42 0:00 /bin/sh /run.sh 123 cmd cmd2 root 19 0.0 0.2 71304 4440 ? Ss 00:42 0:00 /usr/sbin/apache2 -k start www-data 20 0.2 0.2 360468 6004 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start www-data 21 0.2 0.2 360468 6000 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start root 81 0.0 0.1 15572 2140 ? R+ 00:44 0:00 ps aux $ docker top test PID USER COMMAND 10035 root {run.sh} /bin/sh /run.sh 123 cmd cmd2 10054 root /usr/sbin/apache2 -k start 10055 33 /usr/sbin/apache2 -k start 10056 33 /usr/sbin/apache2 -k start $ /usr/bin/time docker stop test test real 0m 0.27s user 0m 0.03s sys 0m 0.03s注意
--entrypoint
を使用してENTRYPOINT
設定を上書きできますが、これはbinary
をexec
にのみ設定できます(sh -c
は使用されません)。注意
exec
形式は JSON 配列として解析されます。
つまり単語の前後に一重引用符('
)ではなく二重引用符("
)を使用する必要があります。シェル形式とは異なり
exec
形式はコマンドシェルを呼び出しません。
これは通常のシェル処理が行われないことを意味します。
たとえばENTRYPOINT ["echo", "$HOME"]
は、$HOME
の変数置換を行いません。
シェル処理が必要な場合はシェル形式を使用するか、シェルを直接実行します。
例:ENTRYPOINT ["sh", "-c", "echo $HOME"]
シェル形式の場合のようにexec
形式を使用してシェルを直接実行する場合、環境変数の展開を行うのは Docker ではなくシェルです。シェル形式の ENTRYPOINT 記述例
ENTRYPOINT
にプレーンな文字列を指定すると/bin/sh -c
で実行されます。
この形式はシェル処理を使用してシェル環境変数を置き換え、CMD
または docker run コマンドライン引数を無視します。
長時間実行されているENTRYPOINT executable
をdocker stop
が正しく通知するようにするには、exec
で開始することを忘れないでください。FROM ubuntu ENTRYPOINT exec top -bこのイメージを実行すると単一の PID 1 プロセスが表示されます。
$ docker run -it --rm --name test top Mem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached CPU: 5% usr 0% sys 0% nic 94% idle 0% io 0% irq 0% sirq Load average: 0.08 0.03 0.05 2/98 6 PID PPID USER STAT VSZ %VSZ %CPU COMMAND 1 0 root R 3164 0% 0% top -b
docker stop
できれいに終了します:$ /usr/bin/time docker stop test test real 0m 0.20s user 0m 0.02s sys 0m 0.04s
ENTRYPOINT
の先頭にexec
を追加するのを忘れた場合:FROM ubuntu ENTRYPOINT top -b CMD --ignored-param1次にそれを実行できます(次のステップの名前を付けます)。
$ docker run -it --name test top --ignored-param2 Mem: 1704184K used, 352484K free, 0K shrd, 0K buff, 140621524238337K cached CPU: 9% usr 2% sys 0% nic 88% idle 0% io 0% irq 0% sirq Load average: 0.01 0.02 0.05 2/101 7 PID PPID USER STAT VSZ %VSZ %CPU COMMAND 1 0 root S 3168 0% 0% /bin/sh -c top -b cmd cmd2 7 1 root R 3164 0% 0% top -b指定された
ENTRYPOINT
は、top
の出力から PID 1 ではないことがわかります。その後
docker stop test
を実行すると、コンテナーは正常に終了しません。
タイムアウト後にstop
コマンドは強制的にSIGKILL
を送信します。$ docker exec -it test ps aux PID USER COMMAND 1 root /bin/sh -c top -b cmd cmd2 7 root top -b 8 root ps aux $ /usr/bin/time docker stop test test real 0m 10.19s user 0m 0.04s sys 0m 0.03s
CMD
とENTRYPOINT
の相互作用を理解する
CMD
命令とENTRYPOINT
命令はどちらも、コンテナの実行時に実行されるコマンドを定義します。
CMD
とENTRYPOINT
の協業を説明する規則を示します。
- Dockerfile は少なくとも 1 つの
CMD
またはENTRYPOINT
コマンドを指定する必要があります。- コンテナで
executable
を使用する場合はENTRYPOINT
を定義する必要があります。CMD
はENTRYPOINT
コマンドのデフォルト引数を定義する方法として、またはコンテナでアドホックコマンドを実行する方法として使用する必要があります。- 代替引数を使用してコンテナーを実行すると
CMD
が上書きされます。次の表はさまざまな
ENTRYPOINT
/CMD
の組み合わせに対して実行されるコマンドを示しています。
No ENTRYPOINT ENTRYPOINT exec_entry p1_entry ENTRYPOINT [“exec_entry”, “p1_entry”] No CMD error, not allowed /bin/sh -c exec_entry p1_entry CMD [“exec_cmd”, “p1_cmd”] exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry CMD [“p1_cmd”, “p2_cmd”] p1_cmd p2_cmd /bin/sh -c exec_entry p1_entry CMD exec_cmd p1_cmd /bin/sh -c exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry 注意
ベースイメージから
CMD
が定義されている場合、ENTRYPOINT
を設定するとCMD
が空の値にリセットされます。
このシナリオで値を設定するには現在のイメージでCMD
を定義する必要があります。VOLUME
VOLUME ["/data"]
VOLUME
命令は、指定された名前でマウントポイントを作成し、ネイティブホストまたは他のコンテナーから外部にマウントされたボリュームを保持するものとしてマークします。
値は JSON 配列VOLUME ["/var/log/"]
、またはVOLUME /var/log
や
VOLUME /var/log/ var/db
などの複数の引数を持つプレーン文字列にすることができます。
Docker クライアントを介した詳細、使用例とマウント手順については、ボリュームを介したディレクトリの共有を参照してください。docker run コマンドは、新しく作成されたボリュームをベースイメージ内の指定された場所に存在するデータで初期化します。
たとえば、次の Dockerfile スニペットについて考えてみます。FROM ubuntu RUN mkdir /myvol RUN echo "hello world" > /myvol/greeting VOLUME /myvolこの Dockerfile は docker run が
/myvol
に新しいマウントポイントを作成し、新しく作成されたボリュームにgreeting
ファイルをコピーするイメージになります。ボリュームの指定についての注意事項
Dockerfile のボリュームについては、次の点に注意してください。
- Windows ベースのコンテナー上のボリューム: Windows ベースのコンテナーを使用する場合、コンテナー内のボリュームの宛先は次のいずれかである必要があります。
- 存在しない、または空のディレクトリ
C:
以外のドライブ- Dockerfile 内からのボリュームの変更: ビルドステップで宣言後にボリューム内のデータが変更された場合、それらの変更は破棄されます。
- JSON フォーマット: リストは JSON 配列として解析されます。 単語は一重引用符(
'
)ではなく二重引用符("
)で囲む必要があります。- ホストディレクトリはコンテナの実行時に宣言されます。 ホストディレクトリ(マウントポイント)はその性質上、ホストに依存します。 特定のホストディレクトリがすべてのホストで使用可能であるとは限らないため、これはイメージの移植性を維持するためです。 このため Dockerfile 内からホストディレクトリをマウントすることはできません。
VOLUME
命令はhost-dir
パラメーターの指定をサポートしていません。 コンテナを作成または実行するときに、マウントポイントを指定する必要があります。USER
USER <user>[:<group>]または
USER <UID>[:<GID>]
USER
命令はイメージの実行時と、 DockerfileでRUN
、CMD
、ENTRYPOINT
に続く命令で使用するユーザー名(または UID)とオプションでユーザーグループ(またはGID)を設定します。ユーザーのグループを指定する場合、ユーザーは指定されたグループメンバーシップのみを持つことに注意してください。
その他の構成済みグループメンバーシップは無視されます。警告
ユーザーがプライマリグループを持っていない場合、イメージ(または次の手順)はルートグループで実行されます。
Windows では、組み込みアカウントでない場合は最初にユーザーを作成する必要があります。
これは Dockerfile の一部として呼び出されるnetuser
コマンドを使用して実行できます。FROM microsoft/windowsservercore # Create Windows user in the container RUN net user /add patrick # Set it for subsequent commands USER patrickWORKDIR
WORKDIR /path/to/workdir
WORKDIR
命令は、 Dockerfile でそれに続くすべてのRUN
、CMD
、ENTRYPOINT
、COPY
、およびADD
命令の作業ディレクトリを設定します。
WORKDIR
` が存在しない場合は、後続の Dockerfile 命令で使用されていなくても作成されます。
WORKDIR
命令は Dockerfile で複数回使用できます。
相対パスが指定されている場合、それは前のWORKDIR
命令のパスから見た相対パスになります。例えば:WORKDIR /a WORKDIR b WORKDIR c RUN pwd
この Dockerfile の最後の
pwd
コマンドの出力は/a/b/c
になります。
WORKDIR
命令は、以前にENV
を使用して設定された環境変数を解決できます。
Dockerfile で明示的に設定された環境変数のみを使用できます。
例えば:ENV DIRPATH=/path WORKDIR $DIRPATH/$DIRNAME RUN pwdこの Dockerfile の最後の
pwd
コマンドの出力は/path/$DIRNAME
になります。ARG
ARG <name>[=<default value>]
ARG
命令はユーザーがビルド時に `--build-arg <varname>=<value>
` フラグを使用して docker build コマンドでビルダーに渡すことができる変数を定義します。
ユーザーが Dockerfile で定義されていないビルド引数を指定すると、ビルドは警告を出力します。[Warning] One or more build-args [foo] were not consumed.Dockerfile には 1 つ以上の
ARG
命令が含まれる場合があります。
たとえば以下は有効な Dockerfile です。FROM busybox ARG user1 ARG buildno # ...
警告
github のキー、ユーザー資格情報などの秘密情報を渡すためにビルド時変数を使用することはお勧めしません。
ビルド時の変数値はdocker history
コマンドを使用してイメージのすべてのユーザーに表示されます。イメージをビルドするときに秘密情報を使用する安全な方法については BuildKit を使用してイメージをビルドする を参照してください。
既定値
ARG
命令には、オプションでデフォルト値を含めることができます。FROM busybox ARG user1=someuser ARG buildno=1 # ...
ARG
命令にデフォルト値があり、ビルド時に値が渡されない場合、ビルダーはデフォルトを使用します。Scope
ARG
変数の定義は、コマンドラインや他の場所での引数の使用からではなく、 Dockerfile で定義されている行から有効になります。
たとえば、次の Dockerfile について考えてみます。FROM busybox USER ${user:-some_user} ARG user USER $user # ...ユーザーは、次のコマンドを呼び出してこのファイルをビルドします。
$ docker build --build-arg user=what_user .2 行目の
USER
は、次の 3 行目でユーザー変数が定義されているためsome_user
と評価されます。
4 行目のUSER
は、ユーザーが定義され、what_user
値がコマンドラインに渡されたときにwhat_user
と評価されます。
ARG
命令で定義される前は、変数を使用すると文字列が空になります。
ARG
命令は、それが定義されたビルドステージの最後でスコープ外になります。
複数のステージでarg
を使用するには、各ステージにARG
命令を含める必要があります。FROM busybox ARG SETTINGS RUN ./run/setup $SETTINGS FROM busybox ARG SETTINGS RUN ./run/other $SETTINGS
ARG
変数の使用
ARG
またはENV
命令を使用してRUN
命令で使用可能な変数を指定できます。
ENV
命令を使用して定義された環境変数は、常に同じ名前のARG
命令を上書きします。
ENV
およびARG
命令を含むこの Dockerfile について考えてみます。FROM ubuntu ARG CONT_IMG_VER ENV CONT_IMG_VER=v1.0.0 RUN echo $CONT_IMG_VER次に、このイメージが次のコマンドで作成されていると仮定します。
$ docker build --build-arg CONT_IMG_VER=v2.0.1 .この場合
RUN
命令はuser:v2.0.1
によって渡されたARG
設定の代わりに v1.0.0 を使用します。
この動作は、ローカルスコープの変数が引数として渡された変数または環境から継承された変数を定義の観点から上書きするシェルスクリプトに似ています。上記の例を使用しますが、異なる
ENV
仕様を使用すると、ARG
とENV
命令の間にさらに便利な相互作用を作成できます。FROM ubuntu ARG CONT_IMG_VER ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0} RUN echo $CONT_IMG_VER
ARG
命令とは異なり、ENV
値は常にビルドされたイメージに保持されます。
--build-arg
フラグのない docker build を考えてみましょう:$ docker build .この Dockerfile の例を使用すると
CONT_IMG_VER
は引き続きイメージに保持されますが、ENV
命令によって 3 行目で設定された既定値であるため、その値は v1.0.0 になります。この例の変数展開手法を使用すると、コマンドラインから引数を渡し、
ENV
命令を利用してそれらを最終イメージに永続化できます。
変数展開は Dockerfile 命令の限られた組合せでのみサポートされます。定義済み
ARG
Docker には Dockerfile 内の対応する
ARG
命令なしで使用できる定義済みARG
変数のセットがあります。
- HTTP_PROXY
- http_proxy
- HTTPS_PROXY
- https_proxy
- FTP_PROXY
- ftp_proxy
- NO_PROXY
- no_proxy
これらを使用するには、フラグを使用してコマンドラインで渡すだけです。
--build-arg <varname>=<value>デフォルトでは、これらの定義済み変数は
docker history
の出力から除外されます。
定義済み変数を除外すると、HTTP_PROXY
変数内の機密認証情報が誤って漏洩するリスクが軽減されます。たとえば
--build-arg HTTP_PROXY=http://user:pass@proxy.lon.example.com
を使用して次の Dockerfile をビルドすることを検討してください。FROM ubuntu RUN echo "Hello World"この場合
HTTP_PROXY
変数の値は、docker history
で使用できず、キャッシュされません。
場所を変更し、プロキシサーバーがhttp://user:pass@proxy.sfo.example.com
に変更された場合、後続のビルドでキャッシュミスが発生することはありません。この動作を上書きする必要がある場合は、次のように Dockerfile に
ARG
ステートメントを追加することで上書きできます。FROM ubuntu ARG HTTP_PROXY RUN echo "Hello World"この Dockerfile をビルドすると、
HTTP_PROXY
はdocker history
に保存され、その値を変更するとビルドキャッシュが無効になります。グローバルスコープの自動プラットフォーム ARG
この機能は BuildKit バックエンドを使用している場合にのみ使用できます。
Docker は、ビルドを実行するノードのプラットフォーム(ビルドプラットフォーム)と結果のイメージのプラットフォーム(ターゲットプラットフォーム)に関する情報を使用して、一連の
ARG
変数を事前定義します。
ターゲットプラットフォームは docker build の--platform
フラグで指定できます。次の
ARG
変数が自動的に設定されます。
- TARGETPLATFORM - ビルド結果のプラットフォーム。 例: linux/amd64, linux/arm/v7, windows/amd64.
- TARGETOS - TARGETPLATFORM の OS コンポーネント
- TARGETARCH - TARGETPLATFORM のアーキテクチャーコンポーネント
- TARGETVARIANT - TARGETPLATFORM の変数コンポーネント
- BUILDPLATFORM - ビルドを実行するノードのプラットフォーム。
- BUILDOS - BUILDPLATFORM の OS コンポーネント
- BUILDARCH - BUILDPLATFORM のアーキテクチャーコンポーネント
- BUILDVARIANT - BUILDPLATFORM の変数コンポーネント
これらの引数はグローバルスコープで定義されているため、ビルドステージ内や
RUN
コマンドで自動的に使用することはできません。
ビルドステージ内でこれらの引数の 1 つを公開するには、値なしで再定義します。例えば:
FROM alpine ARG TARGETPLATFORM RUN echo "I'm building for $TARGETPLATFORM"ビルドキャッシュへの影響
ARG
変数は、ENV
変数のようにビルドされたイメージに永続化されません。
ただしARG
変数は同様の方法でビルドキャッシュに影響を与えます。
Dockerfile が以前のビルドとは値が異なるARG
変数を定義している場合、その定義ではなく、最初の使用時にcache miss
が発生します。
特にARG
命令に続くすべてのRUN
命令は、ARG
変数を暗黙的に(環境変数として)使用するため、キャッシュミスを引き起こす可能性があります。
Dockerfile に一致するARG
ステートメントがない限り、すべての定義済みARG
変数はキャッシュから除外されます。たとえば次の 2 つの Dockerfile について考えてみます。
FROM ubuntu ARG CONT_IMG_VER RUN echo $CONT_IMG_VERFROM ubuntu ARG CONT_IMG_VER RUN echo hello
コマンドラインで
--build-arg CONT_IMG_VER=<value>
を指定した場合、どちらの場合も、 2 行目の指定でキャッシュミスは発生しません。
3 行目はキャッシュミスを引き起こします。
ARG CONT_IMG_VER
により、RUN
行はCONT_IMG_VER=<value> echo hello
の実行と同じものとして識別されるため、<value>
が変更されるとキャッシュミスが発生します。同じコマンドラインで別の例を考えてみましょう。
FROM ubuntu ARG CONT_IMG_VER ENV CONT_IMG_VER=$CONT_IMG_VER RUN echo $CONT_IMG_VERこの例ではキャッシュミスは 3 行目で発生します。
キャッシュミスはENV
変数の値がARG
変数を参照し、その変数がコマンドラインで変更されるために発生します。
この例ではENV
コマンドにより、イメージに値が含まれます。この Dockerfile のように、
ENV
命令が同じ名前のARG
命令を上書きする場合:FROM ubuntu ARG CONT_IMG_VER ENV CONT_IMG_VER=hello RUN echo $CONT_IMG_VER3 行目では
CONT_IMG_VER
の値が定数(hello)であるため、キャッシュミスは発生しません。
その結果RUN
(4 行目)で使用される環境変数と値はビルド間で変更されません。ONBUILD
ONBUILD <INSTRUCTION>
ONBUILD
命令はイメージが別のビルドのベースとして使用されるときに、後で実行されるトリガー命令をイメージに追加します。
トリガーは、ダウンストリーム Dockerfile のFROM
命令の直後に挿入されたかのように、ダウンストリームビルドのコンテキストで実行されます。任意のビルド命令をトリガーとして登録できます。
これは他のイメージをビルドするためのベースとして使用されるイメージをビルドする場合に役立ちます。
たとえばアプリケーションビルド環境や、ユーザー固有の構成でカスタマイズできるデーモンなどです。たとえばイメージが再利用可能な Python アプリケーションビルダーである場合、特定のディレクトリにアプリケーションソースコードを追加する必要があり、その後にビルドスクリプトを呼び出す必要がある場合があります。
アプリケーションのソースコードにはまだアクセスできず、アプリケーションのビルドごとに異なるため、今は単純にADD
とRUN
を呼び出すことはできません。
アプリケーション開発者にボイラープレート Dockerfile を提供して、アプリケーションにコピーアンドペーストすることもできますが、
これは非効率的で、エラーが発生しやすく、アプリケーション固有のコードと混在するため、更新が困難です。解決策は
ONBUILD
を使用して、次のビルドステージで後で実行する事前命令を登録することです。仕組みは次のとおりです。
ONBUILD
命令が発生すると、ビルダーはビルド中のイメージのメタデータにトリガーを追加します。 それ以外の場合、命令は現在のビルドに影響を与えません。- ビルドの最後に、すべてのトリガーのリストがイメージマニフェストの
OnBuild
キーの下に保存されます。 それらはdocker inspect
コマンドで検査できます。- 後で
FROM
命令を使用して、イメージを新しいビルドのベースとして使用できます。FROM
命令の処理の一環として、ダウンストリームビルダーはONBUILD
トリガーを探し、登録されたのと同じ順序でそれらを実行します。 いずれかのトリガーが失敗すると、FROM
命令が中止され、ビルドが失敗します。 すべてのトリガーが成功すると、FROM
命令が完了し、ビルドは通常どおり続行されます。- トリガーは、実行後に最終イメージからクリアされます。 言い換えれば、それらは「孫」ビルドによって継承されません。
たとえば次のようなものを追加できます。
ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src警告
ONBUILD ONBUILD
を使用してONBUILD
命令を連鎖させることは許可されていません。
ONBUILD
命令はFROM
またはMAINTAINER
命令をトリガーしない場合があります。STOPSIGNAL
STOPSIGNAL signal
STOPSIGNAL
命令は、終了するためにコンテナに送信されるシステムコール信号を設定します。
このシグナルは、カーネルのsyscall
テーブル内の位置(たとえば 9)と一致する有効な符号なしの番号、またはSIGNAME
形式のシグナル名(たとえばSIGKILL
)にすることができます。HEALTHCHECK
HEALTHCHECK
命令には 2 種類の形式があります:
HEALTHCHECK [OPTIONS] CMD command
(コンテナ内でコマンドを実行して、コンテナの状態を確認します)HEALTHCHECK NONE
(ベースイメージから継承されたヘルスチェックを無効にする)
HEALTHCHECK
命令は、コンテナをテストしてコンテナがまだ機能していることを確認する方法を Docker に指示します。
これにより、サーバープロセスがまだ実行されていても Web サーバーが無限ループに陥り、新しい接続を処理できないなどのケースを検出できます。コンテナにヘルスチェックが指定されている場合、通常のステータスに加えてヘルスステータスがあります。
このステータスは最初は「開始中」です。
ヘルスチェックに合格すると、ヘルスチェックが「正常」になります(以前の状態に関係なく)。
一定数の連続した失敗の後、「異常」となります。
CMD
の前に表示されるオプションは次のとおりです。
--interval=DURATION
(既定値: 30s)--timeout=DURATION
(既定値: 30s)--start-period=DURATION
(既定値: 0s)--retries=N
(既定値: 3)ヘルスチェックは、最初にコンテナが開始されてから数秒後に実行され、次に前の各チェックが完了してから数秒後に再度実行されます。
チェックの 1 回の実行にタイムアウト秒より長い時間がかかる場合、チェックは失敗したと見なされます。
コンテナが異常であると見なされるには、ヘルスチェックの連続した失敗を再試行する必要があります。
開始期間はブートストラップに時間が必要なコンテナーの初期化時間を提供します。
その期間中のプローブ障害は、最大再試行回数にはカウントされません。
ただし、開始期間中にヘルスチェックが成功した場合、コンテナーは開始されたと見なされ、連続するすべての失敗は最大再試行回数にカウントされます。Dockerfile には 1 つの
HEALTHCHECK
命令しか存在できません。
複数列記すると最後のHEALTHCHECK
のみが有効になります。
CMD
キーワードの後のコマンドは、シェルコマンド(例:HEALTHCHECK CMD /bin/check-running
)またはexec
配列(他の Dockerfile コマンドと同様)のいずれかです。
(詳細についてはENTRYPOINT
を参照してください)コマンドの終了ステータスは、コンテナのヘルスステータスを示します。
有効な値は次のとおりです。
- 0: success - コンテナは正常ですぐに使用できます
- 1: unhealthy - コンテナが正しく機能していません
- 2: reserved - この終了コードは使用しないでください
たとえば 5 分ごとにチェックして、ウェブサーバーが 3 秒以内にサイトのメインページにサービスを提供できるようにするには、次のようにします。
HEALTHCHECK --interval=5m --timeout=3s \ CMD curl -f http://localhost/ || exit 1失敗したプローブのデバッグを支援するために、コマンドが
stdout
またはstderr
に書き込む出力テキスト(UTF-8 エンコード)はヘルスステータスに保存されdocker inspect
で検索できます。
このような出力は短くする必要があります(現在、最初の 4096 バイトのみが格納されています)。コンテナのヘルスステータスが変更されると、新しいステータスで
health_status
イベントが生成されます。
HEALTHCHECK
機能は Docker 1.12 から追加されました。SHELL
SHELL ["executable", "parameters"]
SHELL
命令を使用すると、シェル形式のコマンドに使用されるデフォルトのシェルを上書きできます。
Linux のデフォルトシェルは["/bin/sh", "-c"]
です。
Windows のデフォルトシェルは["cmd", "/S", "/C"]
です。
SHELL
命令は Dockerfile に JSON 形式で記述する必要があります。
SHELL
命令は一般的に使用されているまったく異なる 2 つのネイティブシェル(cmd
とpowershell
)と、sh
を含む代替シェルが利用可能な Windows で特に役立ちます。
SHELL
命令は複数回表示される可能性があります。
各SHELL
命令は、以前のすべてのSHELL
命令を上書きし、後続のすべての命令に影響を与えます。
例:FROM microsoft/windowsservercore # Executed as cmd /S /C echo default RUN echo default # Executed as cmd /S /C powershell -command Write-Host default RUN powershell -command Write-Host default # Executed as powershell -command Write-Host hello SHELL ["powershell", "-command"] RUN Write-Host hello # Executed as cmd /S /C echo hello SHELL ["cmd", "/S", "/C"] RUN echo hello次の命令はシェル形式が Dockerfile で使用されている場合に
SHELL
命令の影響を受ける可能性があります:
RUN
CMD
ENTRYPOINT
次の例は
SHELL
命令を使用して合理化できる Windows で見られる一般的なパターンです。RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"docker によって呼び出されるコマンドは次のようになります。
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"これは 2 つの理由で非効率的です。
まず、不要なcmd.exe
コマンドプロセッサ(別名シェル)が呼び出されています。
次に、シェル形式の各RUN
命令には、コマンドの前に追加のpowershell -command
が必要です。これをより効率的にするために 2 つのメカニズムのうちの 1 つを使用することができます。
1 つは次のようなRUN
コマンドの JSON 形式を使用することです。RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]JSON 形式は明確であり、不要な
cmd.exe
を使用しませんが、二重引用符とエスケープにより、より詳細な情報が必要になります。
別のメカニズムはSHELL
命令とシェル形式を使用することです。
これにより、特にエスケープパーサーディレクティブと組み合わせると Windows ユーザーにとってより自然な構文になります。# escape=` FROM microsoft/nanoserver SHELL ["powershell","-command"] RUN New-Item -ItemType Directory C:\Example ADD Execute-MyCmdlet.ps1 c:\example\ RUN c:\example\Execute-MyCmdlet -sample 'hello world'実行結果:
PS E:\docker\build\shell> docker build -t shell . Sending build context to Docker daemon 4.096 kB Step 1/5 : FROM microsoft/nanoserver ---> 22738ff49c6d Step 2/5 : SHELL powershell -command ---> Running in 6fcdb6855ae2 ---> 6331462d4300 Removing intermediate container 6fcdb6855ae2 Step 3/5 : RUN New-Item -ItemType Directory C:\Example ---> Running in d0eef8386e97 Directory: C:\ Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 10/28/2016 11:26 AM Example ---> 3f2fbf1395d9 Removing intermediate container d0eef8386e97 Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\ ---> a955b2621c31 Removing intermediate container b825593d39fc Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world' ---> Running in be6d8e63fe75 hello world ---> 8e559e9bf424 Removing intermediate container be6d8e63fe75 Successfully built 8e559e9bf424 PS E:\docker\build\shell>
SHELL
命令は、シェルの動作方法を変更する目的にも使用できます。
たとえば Windows でSHELL cmd /S /C /V:ON|OFF
を使用すると、遅延環境変数の拡張セマンティクスを変更できます。
SHELL
命令は zsh, csh, tcsh などの代替シェルが必要な場合に Linux でも使用できます。
SHELL
機能は Docker 1.12 で追加されました。外部実装機能
この機能は BuildKit バックエンドを使用している場合にのみ使用できます。
docker build は、構文ディレクティブを使用してビルダーの外部実装を使用することで有効になる、キャッシュマウント、ビルドシークレット、 ssh 転送などの実験的な機能をサポートします。
これらの機能については BuildKit リポジトリのドキュメント を参照してください。Dockerfile 記述例
以下に Dockerfile 構文の例をいくつか示します。
# Nginx # # VERSION 0.0.1 FROM ubuntu LABEL Description="This image is used to start the foobar executable" Vendor="ACME Products" Version="1.0" RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server# Firefox over VNC # # VERSION 0.3 FROM ubuntu # Install vnc, xvfb in order to create a 'fake' display and firefox RUN apt-get update && apt-get install -y x11vnc xvfb firefox RUN mkdir ~/.vnc # Setup a password RUN x11vnc -storepasswd 1234 ~/.vnc/passwd # Autostart firefox (might not be the best way, but it does the trick) RUN bash -c 'echo "firefox" >> /.bashrc' EXPOSE 5900 CMD ["x11vnc", "-forever", "-usepw", "-create"]# Multiple images example # # VERSION 0.1 FROM ubuntu RUN echo foo > bar # Will output something like ===> 907ad6c2736f FROM ubuntu RUN echo moo > oink # Will output something like ===> 695d7793cbe4 # You'll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with # /oink.
- 投稿日:2020-10-20T19:04:15+09:00
MKL taints symbol table (PLT / procedure linkage table)
はじめに
https://qiita.com/cielavenir/items/93d2b5b057bfe1383670 の関連。
A.soとB.soがあって、Aはlibmkl_rt、Bはlibblasに静的リンクしているとする。このとき、本来であれば、A.soおよびB.soを動的リンクするなら1、Aはlibmkl_rt、 BはlibblasをBLAS実装に使うはず。
ところが、実際には、AがMKLのBLAS関数を呼んだ後にBをロードすると、BもMKLをBLAS実装に使うようになってしまう。もし(そうそうないことだが)BがMKL以外のBLAS実装の挙動に依存する2なら、これは問題となりうる。が、今回は回避策はなさそうに思える…。デモ
scipy/spatial/qhull.soのバイナリパッケージはlibopenblasにリンクしているが、LD_DEBUG="libs symbols" 環境で以下を実行すると、(libopenblasでなく)MKLのdgetrf/dgetrs/dgeconがロードされることが観測される。
import scipy
ではscipy/spatial/qhull.soのロードに至らないことに注意。#!/usr/bin/python import numpy import scipy # this does not guarantee scipy.spatial safety. print(numpy.dot([[1,2]],[[3],[4]])) points = numpy.random.rand(30, 2) # 30 random points in 2-D import ctypes n=ctypes.c_int(3) alpha=ctypes.c_double(3) beta=ctypes.c_double(-2) A=(ctypes.c_double*9)(1,2,9,8,10,-5,3,8,-1) B=(ctypes.c_double*9)(9,3,-8,8,11,6,3,2.3,1) C=(ctypes.c_double*9)(3,8,6,3,4,1,1.2,8,-2) # this CDLL loads so using RTLD_LOCAL ctypes.CDLL("libmkl_rt.so").cblas_dgemm(102,111,111,n,n,n,alpha,A,n,B,n,beta,C,n) print(list(C)) print '=== check dgetrf/dgetrs/dgecon below ===' from scipy.spatial import ConvexHull hull = ConvexHull(points)おわりに
思うところがあって、先のデモでも複数個のモジュールを使うパターンを追加したところ、再現できた(あちらは(constructor attributeを使っているので)関数を呼ばずともロードしただけで再現する)。挙動を観測するに、libmkl_rtはあのdlopenし直すやつをやっているだけではないだろうか…?
- 投稿日:2020-10-20T19:04:15+09:00
MKL taints symbol table
はじめに
https://qiita.com/cielavenir/items/93d2b5b057bfe1383670 の関連。
A.soとB.soがあって、Aはlibmkl_rt、Bはlibblasに静的リンクしているとする。このとき、本来であれば、A.soおよびB.soを動的リンクするなら1、Aはlibmkl_rt、 BはlibblasをBLAS実装に使うはず。
ところが、実際には、AがMKLのBLAS関数を呼んだ後にBをロードすると、BもMKLをBLAS実装に使うようになってしまう。もし(そうそうないことだが)BがMKL以外のBLAS実装の挙動に依存する2なら、これは問題となりうる。が、今回は回避策はなさそうに思える…。デモ
scipy/spatial/qhull.soのバイナリパッケージはlibopenblasにリンクしているが、LD_DEBUG="libs symbols" 環境で以下を実行すると、(libopenblasでなく)MKLのdgetrf/dgetrs/dgeconがロードされることが観測される。
import scipy
ではscipy/spatial/qhull.soのロードに至らないことに注意。#!/usr/bin/python import numpy import scipy # this does not guarantee scipy.spatial safety. print(numpy.dot([[1,2]],[[3],[4]])) points = numpy.random.rand(30, 2) # 30 random points in 2-D import ctypes n=ctypes.c_int(3) alpha=ctypes.c_double(3) beta=ctypes.c_double(-2) A=(ctypes.c_double*9)(1,2,9,8,10,-5,3,8,-1) B=(ctypes.c_double*9)(9,3,-8,8,11,6,3,2.3,1) C=(ctypes.c_double*9)(3,8,6,3,4,1,1.2,8,-2) # this CDLL loads so using RTLD_LOCAL ctypes.CDLL("libmkl_rt.so").cblas_dgemm(102,111,111,n,n,n,alpha,A,n,B,n,beta,C,n) print(list(C)) print '=== check dgetrf/dgetrs/dgecon below ===' from scipy.spatial import ConvexHull hull = ConvexHull(points)おわりに
思うところがあって、先のデモでも複数個のモジュールを使うパターンを追加したところ、再現できた(あちらは(constructor attributeを使っているので)関数を呼ばずともロードしただけで再現する)。挙動を観測するに、libmkl_rtはあのdlopenし直すやつをやっているだけではないだろうか…?
- 投稿日:2020-10-20T18:58:21+09:00
CentOS7環境を2つ構築する方法/Windows10 + VirtualBox + Vagrant
はじめに
この記事ではWindows10で、VirtualBoxとVagrantを利用して、仮想マシンCentOS7を2つ構築する手順について説明する。
環境
- ホストOS:Windows10
- ゲストOS:CentOS7 2台(client, server)
- 仮想マシン構築ツール:VirtulaBox、Vagrant
環境構築の方法について
環境構築は、VirtuallBoxとVagrantとを組み合わせた方法を使う。
Vagarntを使う理由は、VirtualBoxを直接さわらなくても、コマンドプロンプト上でコマンド操作や必要なファイルの設定をするだけで、ネットワーク設定や仮想マシンの構築が簡単にできるためだ。
環境構築後の仮想マシンへの接続はコマンドプロンプトからSSH接続してLinuxのコマンド操作ができる。もちろん、TeraTermやPuTTYを使ってSSH接続することも可能。
前準備
VirtualBox(Windows版)のダウンロード&インストール
VirtualBoxの最新版は以下URLよりダウンロードする。
https://www.virtualbox.org/wiki/Downloadsダウンロード後、PCにインストールする。
Vagrant(Windows版)のダウンロード&インストール
Vagrantの最新版は以下URLよりダウンロードする。
https://www.vagrantup.com/downloads.htmlダウンロード後、PCにインストールする。
インストールが完了したら、コマンドプロンプトを開いて次のようにコマンドを打つ。
インストールした vagrant のバージョンが表示されればインストール完了。コマンドプロンプトC:¥>vagrant -v Vagrant 2.2.10CentOS7環境を2つ構築する手順
Vagrantfileの作成
任意のディレクトリで
vagrant init
コマンドと打つと、Vagrantfileが作成される。コマンドプロンプトD:\hoge>vagrant init D:\hoge>dir 2020/10/20 18:25 3,080 VagrantfileVagrantfileの編集
Vagrantfileを以下のように編集する。
Vagrantfile# -*- mode: ruby -*- # vi: set ft=ruby : # All Vagrant configuration is done below. The "2" in Vagrant.configure # configures the configuration version (we support older styles for # backwards compatibility). Please don't change it unless you know what # you're doing. Vagrant.configure("2") do |config| # The most common configuration options are documented and commented below. # For a complete reference, please see the online documentation at # https://docs.vagrantup.com. # Every Vagrant development environment requires a box. You can search for # boxes at https://vagrantcloud.com/search. config.vm.box = "centos/7" config.vm.define :client do | client | client.vm.hostname = "client" client.vm.network :private_network, ip: "192.168.33.10" end config.vm.define :server do | server | server.vm.hostname = "server" server.vm.network :private_network, ip: "192.168.33.20" end ...仮想マシンの構築
Vagrantfile編集後は、
vagrant up
コマンドを打てば、約2~3分でCentOS7が2台作成される。コマンドプロンプトD:\hoge>vagrant up --provider=virtualbox Bringing machine 'client' up with 'virtualbox' provider... Bringing machine 'server' up with 'virtualbox' provider... ==> client: Importing base box 'centos/7'... ==> client: Matching MAC address for NAT networking... ==> client: Checking if box 'centos/7' version '1905.1' is up to date... ~~~ 省略 ~~~ ==> server: Setting hostname... ==> server: Configuring and enabling network interfaces... ==> server: Rsyncing folder: /cygdrive/d/hoge/ => /vagrant仮想マシンの起動状態の確認
vagrant status
コマンドで仮想マシンの状態を確認できる。
running
となっていれば起動成功。コマンドプロンプトD:\hoge>vagrant status Current machine states: client running (virtualbox) server running (virtualbox) This environment represents multiple VMs. The VMs are all listed above with their current state. For more information about a specific VM, run `vagrant status NAME`.仮想マシンに接続
構築した仮想マシンへの接続は
vagrant ssh
コマンドを使う。
root権限のパスワードのデフォルトはvagrant
。
以下のように、コマンドプロンプトからCentOS環境にSSH接続できた。コマンドプロンプトD:\hoge>vagrant ssh client [vagrant@client ~]$ [vagrant@client ~]$ su - Password: [root@client ~]# [root@client ~]# cat /etc/centos-release CentOS Linux release 7.6.1810 (Core)以上。
- 投稿日:2020-10-20T18:27:09+09:00
Debianパッケージのデバッグシンボルを取得する
対応するpkgnameに対し、[pkgname]-dbgsymをインストールする。
apt-line
deb http://debug.mirrors.debian.org/debian-debug stretch-debug main contrib non-free手動
- http://debug.mirrors.debian.org/debian-debug/dists/stretch-debug/main/binary-amd64/ を確認する
- [pkgname]-dbgsym パッケージのエントリに対し、Filenameフィールドを確認する
- http://debug.mirrors.debian.org/debian-debug/pool/ 以下から取得する
- 投稿日:2020-10-20T17:47:15+09:00
[メモ] ラズパイ4Bのvmware ESXiで仮想マシン作成
概要
- vmware ESXi Arm Fling で、仮想マシンを作成してみる。
- [メモ] ラズパイ4Bへ vmware ESXi on Arm Flingのインストール の続き
環境
- Raspbery Pi 4B 8GB
- SATA-USB3.0変換ケーブル + SSD or HDD
- 有線LAN接続
- OSインストーラは、arm64のものを使う。
- Debian 10 (Buster) https://cdimage.debian.org/debian-cd/10.6.0/arm64/iso-cd/
- debian-10.6.0-arm64-netinst.iso (今回、これを使った)
- debian-10.6.0-arm64-xfce-CD-1.iso
- Ubuntu 20.04 - Ubuntu Server for ARM --- https://ubuntu.com/download/server/arm
ここから、isoファイルをダウンロードする =>ubuntu-20.04.1-live-server-arm64.iso
操作
基本設定 (時刻補正とsshログイン許可)
- ナビゲータ > ホスト > 管理
- [システム] > 日付と時刻 > [Edit NTP Settings]
- "NTP を使用 (NTP クライアントの有効化)"を選択
- NTP サービス起動ポリシー: ホストと連動して起動および停止します
- NTP サーバ: 0.pool.ntp.org, 1.pool.ntp.org, 2.pool.ntp.org, 3.pool.ntp.org
- [保存]
- [サービス] // ntpとsshの設定
- ntpd: 右クリック > 起動
- TSM-SSH:
- 右クリック > ポリシー > ホストと連動して起動および停止します
- 右クリック > 起動
- [ライセンス] // ライセンスコードがあれば
- ライセンスの割り当て > ライセンス キー : 12345=67890-ABCDE-12345-67890
- [ライセンスの確認] > [ライセンスの割り当て]
ファイルの転送
仮想マシンを設定するための、ISOファイルなどを転送する
仮想マシン作成
- 名前: {適当に}
- 互換性: ESXi 7.0 仮想マシン
- ゲストOSファミリ: Linux
- ゲストOSのバージョン: Debian GNU/Linux 10(64ビット)設定のカスタマイズ
- 仮想マシンのスペック。CPU 2個、メモリ2GB ハードディスク 32GB .. は適当に
- CD/DVDドライブ "データストアISOファイル"にして、CD/DVDメディアのとこの[参照] ボタンを押して、インストーラのISOファイルを[選択]
- [次へ]
起動したら
debian
- debian は、作成したユーザをsudoerに入れてくれないっぽいので、初回rootでログインして、設定する
/etc/ssh/sshd_config
を編集して、rootでパスワードでログインできるようにする。/etc/ssh/sshd_config... PermitRootLogin yes ... PasswordAuthentication yes ...
systemctl daemon-reload && systemctl restart ssh
するパスワードなしで sudo する
こんな感じで、sudoerに登録export SUDO_USER=mt08 echo "${SUDO_USER} ALL=(ALL) NOPASSWD: ALL " | sudo tee /etc/sudoers.d/${SUDO_USER}-nopasswd
open-vm-tools
のインストール
ビルド & インストール
コピペsudo apt update && \ sudo apt install -y build-essential git && \ sudo apt install -y --no-install-recommends automake libtool libmspack-dev libglib2.0-dev libpam0g-dev libssl-dev libxml2-dev libxmlsec1-dev libx11-dev libxext-dev libxinerama-dev libxi-dev libxrender-dev libxrandr-dev libxtst-dev libgtk2.0-dev && \ git clone https://github.com/vmware/open-vm-tools.git && \ cd open-vm-tools && \ git checkout stable-11.2.0 && \ cd open-vm-tools && \ autoreconf -i && \ ./configure --without-gtk3 --without-gtkmm && \ make -j && \ sudo make install && sudo ldconfig自動起動スクリプトの設定
コピペcat << 'EOF' | sudo tee /etc/systemd/system/vmtoolsd.service [Unit] Description=Open VM Tools After=network-online.target [Service] ExecStart=/usr/local/bin/vmtoolsd Restart=always RestartSec=1sec [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable vmtoolsd.service sudo systemctl restart vmtoolsd.service sudo systemctl status vmtoolsd.service最後こんな風に出てればOKmt08@debian10:~/open-vm-tools/open-vm-tools$ sudo systemctl status vmtoolsd.service ● vmtoolsd.service - Open VM Tools Loaded: loaded (/etc/systemd/system/vmtoolsd.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2020-10-20 01:39:20 PDT; 1s ago Main PID: 1011 (vmtoolsd) Tasks: 3 (limit: 2274) Memory: 1.6M CGroup: /system.slice/vmtoolsd.service └─1011 /usr/local/bin/vmtoolsd Oct 20 01:39:20 debian10 systemd[1]: Started Open VM Tools. mt08@debian10:~/open-vm-tools/open-vm-tools$その他
- (疑問)グラフィックスの解像度は変えられるの?? 1024x768 ?
スクショ
- 投稿日:2020-10-20T16:16:19+09:00
ファイルのパーミッションの"T"はスティッキービット
Chefでファイル作成した時、modeを
0644
とするところを644
とタイプミスしってしまったため
ファイルのパーミッションが以下のようになってしまった。--w----r-T 1 root rootこのTとはなんぞ? と思ったので、調べてみました。
スティッキービット
Tは、スティッキービットと呼ばれ、以下のような特徴があるらしいです。
スティッキービットの最も一般的な使用法は、ディレクトリに対して使う場合であり、 セットされるとディレクトリ配下のファイルのファイル名変更や削除は そのファイルの所有者、ディレクトリの所有者、スーパーユーザーのいずれかしかできなくなる。スティッキービットの設定方法
じゃあどうやったらスティッキービットを設定するの、という話ですが、以下の方法で設定できるようです。
chmod 1777 hoge
- 投稿日:2020-10-20T16:04:26+09:00
Ubuntu20.04で日本語入力ができなかった
はじめに
Ubuntu20.04で、
日本語を打ちたくなったときに「半角/全角キー」を押してもアルファベット表記から変わらない!
という問題に遭遇し、それを解決したのでその方法を書き記しておきます。環境
- Virtual Box 6.1
- Ubuntu20.04
注意:Ubuntu20.04のLanguageにはEnglishを指定しています。
解決方法(結論)
結論から述べると、
Japanese(Mozc)というものを導入すると、日本語入力が可能になりました。解決方法(解決経路 画像込み)
日本語入力できなかったとき、以下のようにInput sourcesにはJapaneseのみが指定されている状態でした。
Japanese入ってるのに、どうして日本語入力できないんや!といった具合でかなり困惑していましたが、
Japanese(Mozc)というものを導入すると解決するようです。導入手順
以上の手順により、Input SourcesにJapanese(Mozc)が追加されました。
補足として、画面右上にこのような記載があり、Japanese(Mozc)となっていることを確認します。
以上の手順で「半角/全角キー」を使ってアルファベット/ひらがな表記の切り替えが可能になりました。
そもそもMozcって何だったの
Google 日本語入力は、Android、Chrome OS、Windows でご利用いただけます。Linux ではオープンソース版の Mozc をご利用ください。
Google 日本語入力おわりに
Japanese(Mozc)ではないPureなJapaneseは、「キーボードをUSではなく日本語キーボード(JISキーボード)として認識する」機能だけを持つようです。
そしてJapanese(Mozc)では、これに加えて「ひらがななどの日本語を入力をする機能」がされるのかな、と解釈しています。参考
- 投稿日:2020-10-20T15:46:41+09:00
【Linux】RedhatにDocker環境構築
はじめに
RedhatでDocker環境構築する方法をメモ
環境情報
- OS:Redhat 7.7
Docker環境構築
yumをアップデート
yum updateyumをアップグレード
yum upgrade必要なパッケージをインストール
yum install -y yum-utils device-mapper-persistent-data lvm2リポジトリを有効化
yum-config-manager --enable rhel-7-server-rhui-optional-rpms yum-config-manager --enable rhel-7-server-rhui-rh-common-rpms yum-config-manager --enable rhel-7-server-rhui-rpms yum-config-manager --enable rhel-7-server-rhui-extras-rpmsdockerインストール
yum install docker-io
設定ファイルの修正
- 設定ファイル :/etc/sysconfig/docker
OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false --bip=172.20.250.1/24 -g /var/lib/docker'Dockerサービス有効化
systemctl daemon-reload systemctl start docker systemctl enable docker
Dockerの起動確認
systemctl status docker正常に起動しない場合はログを確認
journalctl -eu docker
Docker-composeを使用する場合
docker-composeダウンロード
curl -L "https://github.com/docker/compose/releases/download/【version】/docker-compose-$(uname -s)-$(uname -m)" -o /bin/docker-composedocker-composeに実行権限を付与
chmod +x /bin/docker-compose
- 投稿日:2020-10-20T15:40:25+09:00
【Linux】RedhatでDocker環境構築
はじめに
RedhatでDocker環境構築する方法をメモ
環境情報
- OS:Redhat 7.7
Docker環境構築
yumをアップデート
yum updateyumをアップグレード
yum upgrade必要なパッケージをインストール
yum install -y yum-utils device-mapper-persistent-data lvm2リポジトリを有効化
yum-config-manager --enable rhel-7-server-rhui-optional-rpms yum-config-manager --enable rhel-7-server-rhui-rh-common-rpms yum-config-manager --enable rhel-7-server-rhui-rpms yum-config-manager --enable rhel-7-server-rhui-extras-rpmsdockerインストール
yum install docker-io
設定ファイルの修正
- 設定ファイル :/etc/sysconfig/docker
OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false --bip=172.20.250.1/24 -g /var/lib/docker'Dockerサービス有効化
systemctl daemon-reload systemctl start docker systemctl enable docker
docker-composeダウンロード
curl -L "https://github.com/docker/compose/releases/download/【version】/docker-compose-$(uname -s)-$(uname -m)" -o /bin/docker-composedocker-composeに実行権限を付与
chmod +x /bin/docker-compose
- 投稿日:2020-10-20T15:40:25+09:00
【Linux】Amazon Linux 2でDocker環境構築
はじめに
Amazon Linux 2でDocker環境構築する方法をメモ
環境情報
- OS:Amazon Linux 2
Docker環境構築
yumをアップデート
yum updateyumをアップグレード
yum upgradedockerインストール
yum install docker-io
設定ファイルの修正
- 設定ファイル :/etc/sysconfig/docker
OPTIONS='--selinux-enabled --log-driver=journald --bip=172.20.250.1/24 -g /var/lib/docker'Dockerサービス有効化
systemctl daemon-reload systemctl start docker systemctl enable docker
Dockerの起動確認
systemctl status docker正常に起動しない場合はログを確認
journalctl -eu docker
Docker-composeを使用する場合
docker-composeダウンロード
curl -L "https://github.com/docker/compose/releases/download/【version】/docker-compose-$(uname -s)-$(uname -m)" -o /bin/docker-composedocker-composeに実行権限を付与
chmod +x /bin/docker-compose
- 投稿日:2020-10-20T15:25:11+09:00
【Bash】複数行内容の複数ファイルへのリダイレクト
- Bash利用時に、shellscript内で内容が複数行の文字列を、複数ファイルへ書き込みたい場合がある。
- その際に、複数
echo
や複数>
で、つい逐次書いてしまい、長くなったり重複が目立つことがある。- そのため今回は、一括で複数行内容を複数ファイルへ書き込む(リダイレクト)方法を記録する。
結果
- 以下に結果の内容を示す。
- こちらはBashのヒアドキュメントとteeコマンドを利用した方法である。
function multi(){ # ヒアドキュメントにて複数行文字列の定義 cat <<-EOF # list data aaa bbb ccc ddd eee fff ggg hhh iii EOF } # teeコマンドへ渡して、書き込み(リダイレクト)対象ファイルを指定 # 非出力のため、/dev/nullへ捨てる。 multi | tee result.txt result.bak.txt > /dev/null
- 任意のshellファイルへ記述後、実行と作成確認が出来たら完了。
内容
ヒアドキュメントの活用
- 複数文字列定義の際に、ヒアドキュメントを利用する。
- その際に意識した以下の2点。
<<-
を指定して、インデントを可能にする。
- こちらを指定して先頭のタブ文字を削除して、見栄えを整える。
- 関数の中に入れる。
- 書き込み内容は、直指定でも変数だとしても関数の中に入れて定数化しておく。
- 「書き込み内容の整理・利用の汎用性(パイプ等)」につながる。
teeコマンドの利用
- 入力から、出力と書き込みを同時に行う
tee
コマンドを利用する。- そうすることにより、定義した内容をteeへ渡すことで、出力と指定ファイルへの書き込みを同時に行ってくれる。
- ※ただし出力は行わないため、
/dev/null
へ内容を渡して非出力参考
- 投稿日:2020-10-20T15:10:23+09:00
【Linux】Dockerで通知メールを送る時のLinux環境(ホスト)でのSMTP設定方法
はじめに
Dockerで通知メールを送る時のLinux環境(ホスト)でのSMTP設定方法についてメモ
環境情報
- OS:Redhat 7.7
Docker環境構築
yumをアップデート
yum updateyumをアップグレード
yum upgrade必要なパッケージをインストール
yum install -y yum-utils device-mapper-persistent-data lvm2リポジトリを有効化
yum-config-manager --enable rhel-7-server-rhui-optional-rpms yum-config-manager --enable rhel-7-server-rhui-rh-common-rpms yum-config-manager --enable rhel-7-server-rhui-rpms yum-config-manager --enable rhel-7-server-rhui-extras-rpmsdockerインストール
yum install docker-io
設定ファイルの修正
- 設定ファイル :/etc/sysconfig/docker
OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false --bip=172.20.250.1/24 -g /var/lib/docker'Dockerサービス有効化
systemctl daemon-reload systemctl start docker systemctl enable docker
docker-composeダウンロード
curl -L "https://github.com/docker/compose/releases/download/【version】/docker-compose-$(uname -s)-$(uname -m)" -o /bin/docker-composedocker-composeに実行権限を付与
chmod +x /bin/docker-compose
- 投稿日:2020-10-20T14:15:50+09:00
【Linux】Redhat環境でDNS設定
はじめに
Redhat環境でのDNS設定方法についてメモ
環境情報
- OS:Redhat 7.7
DNS設定
ドメイン名とDNSサーバーのIPアドレスを設定ファイルに記載
設定ファイル:/etc/resolv.conf
search 【ドメイン名】 nameserver 【IPアドレス】※ サーバー再起動時に/etc/resolv.confファイルの自動更新を無効化する場合は下記を参照
https://qiita.com/UrTom/items/f0e91b606a2567d54b67NetworkManagerを再起動
systemctl restart NetworkManager疎通確認
DNSサーバーを設定したことにより、IPアドレスがホスト名で名前解決されることを確認
ping 【ホスト名】
- 投稿日:2020-10-20T14:04:37+09:00
【Linux】/etc/resolv.confファイルの自動更新を無効にする方法
はじめに
/etc/resolv.confファイルの自動更新を無効にする方法についてメモ
環境情報
- OS:Redhat 7.7
/etc/resolv.confファイルの自動更新を無効化
NetworkManager設定ファイルを編集
設定ファイル:/etc/NetworkManager/NetworkManager.conf
dnsにnoneを設定することで/etc/resolv.confファイルが自動的に更新されないようにする
[main] plugins=ifcfg-rh dns=none <= ここを追加NetworkManagerを再起動
systemctl restart NetworkManager
- 投稿日:2020-10-20T09:34:36+09:00
[メモ] ラズパイ4Bへ vmware ESXi on Arm Flingのインストール
概要
- ラズパイ4Bで、vmware ESXi on Arm Flingを使用する。
- オンボードのWifiは使えないので、有線LANを使う。
- ラズパイのUEFI関連のファイルも、SATA-USB変換+SSD (またはHDD)に入れるので、インストール・設定後は、起動用microSDは不要。
- インストーラー起動時にオプション(
autoPartitionOSDataSize=8192
)を設定しないと、使用できる領域が減る。参考
- ESXi Arm Edition - October 06, 2020 v1.0
- https://www.virtuallyghetto.com/category/esxi-arm
環境
- Raspbery Pi 4B (4GB/8GB) - 4GB以上でないと、はじかれる
- SATA-USB3.0変換ケーブル
- SSD(240GB) / HDD(1TB) --- 以下、SSDと書いてあるが、HDDもOK。
- 有線LAN接続 (オンボードのWifiは使えない)
- (冷却用ファン)
- インストール時に必要なもの
- microSD(1) (RaspberryPi OS - ラズパイのEEPROMの更新と、USBBoot設定に使用)
- microSD(2) (UEFI boot用)
- USB Flash (VMWare installer - VMware-VMvisor-Installer-7.0.0-16966451.aarch64.isoを焼く)
- ディスプレイ接続
- キーボード
- Windows 10で、microSD / USBフラッシュの準備をした。
手順
Windowsで作業
ファイルのダウンロード
- ラズパイのファームウェア
https://github.com/raspberrypi/firmware/archive/1.20200902.zip- ラズパイ4の UEFI
https://github.com/pftf/RPi4/releases/download/v1.20/RPi4_UEFI_Firmware_v1.20.zip- RaspberryPi OS
https://www.raspberrypi.org/downloads/ から. 必要あれば。- VMware-VMvisor-Installer-7.0.0-16966451.aarch64.iso
https://my.vmware.com/group/vmware/downloads/get-download?downloadGroup=ESXI-ARM
vmwareへの登録が必要microUSB / USBフラッシュの準備
VMWare ESXi イントーラ
Rufusで作成した。
1. USBフラッシュメモリをPCに挿す
2. Rufus起動
3. Device で、書き込み先を選択
4. [SELECT]を押して、VMware-VMvisor-Installer-7.0.0-16966451.aarch64.iso
を選択
5. [START]をおして書き込み開始
6. データが全部消えるよ、って警告が出るので、問題なければ、[OK]microSD - Raspbian OS
- いつも通り。Raspberry Pi Imager などで
microSD - UEFI boot
- FAT32 でフォーマット (SD formatter は、32GBまでのカードなら、FAT32でフォーマットしてくれるが、それ以上だと、exFATだったような..)
- ラズパイのファームウェア
firmware-1.20200902.zip
を解凍- "boot"フォルダの中身をmicroSDのルートにコピー
- kernel*.img (4ファイル)を削除
- ラズパイ4の UEFI
RPi4_UEFI_Firmware_v1.20.zip
を解凍して、microSDにコピー(上書きする)
config.txt
の最後の行に以下を追加gpu_mem=16ラズパイにて
EEPROMの更新とUSB Boot設定
- Raspberry Pi OS の microSDで、起動
- パッケージ更新・再起動
sudo apt update && sudo apt upgrade -y && sudo reboot
- 再起動後、
sudo raspi-config
3 Boot Options
>B5 Boot ROM Vesion
>E1 Latest
>Reset boot ROM to defaults?
で<Yes>
- 一度終了して、再起動. (次回起動時 EEPROMがフラッシュされる。)
sudo rpi-eeprom-update
で、バージョン確認こんな感じpi@raspberrypi:~ $ sudo rpi-eeprom-update BCM2711 detected VL805 firmware in bootloader EEPROM BOOTLOADER: up-to-date CURRENT: Thu 03 Sep 2020 12:11:43 PM UTC (1599135103) LATEST: Thu 03 Sep 2020 12:11:43 PM UTC (1599135103) FW DIR: /lib/firmware/raspberrypi/bootloader/stable VL805: up-to-date CURRENT: 000138a1 LATEST: 000138a1 pi@raspberrypi:~ $再度、
sudo raspi-config
3 Boot Options
>B4 Boot Order
>B1 USB Boot
USB device is default boot device
とでればOK.一度再起動する。
sudo poweroff
でシャットダウン。vmware ESXiインストールの準備
以下をラズパイに挿す。
- UEFIのmicroSD (起動用)
- USBフラッシュ(VMWareインストーラ)
- SATA-USB3ケーブル+SSD(インストール先)
- キーボード
- HDMIディスプレイ
- 有線LAN
UEFI設定 ("3GiB memory limit" を
Disabled
にする)
- 電源を入れて、UEFI microSDから起動する際、ESCをぽちぽち押して、UEFIの設定画面へ
Device Manager
>Raspberry Pi Configuration
>Advanced Configuration
>Limit RAM to 3 GB
を<Disabled>
にする- [F10] 'Y' を押して、設定保存
- [ESC]を3回押して、
Reset
を選択して、[Enter]ESXi-Armインストーラ起動
↑から続き
1. ESCをぽちぽち押して、UEFIの設定画面へ
2.Boot Manager
> (VMWare Installer USB)を↑↓で選んで、[Enter]
3. 起動し始めたら、すぐに SHIFT+o を押して、起動オプション設定表示
4.autoPartitionOSDataSize=8192
を追記して、[Enter]
> runweasel cdromBoot autoPartitionOSDataSize=8192
これをやらないと、ESXiシステムのパーティションが120GBくらいとられるESXi-Armインストール
- Welcome to the VMware ESXi on Arm Fling Installation
=> [Enter]- End User License Agreement (EULA)
=> [F11]- Select a Disk to Install or Upgrade
=> ↑↓でインストール先のディスクを選んで、[Enter]- Please select a keyboard layout
=> US Default (またはJapanese) で [Enter]- Enter a root password
↑↓で移動。入力後、[Enter]
Password must be at least 7 characters long. => 7文字以上
Password does not have enough character types. =>数字・記号とか入れる?- Confirm Install
[F11] を押してインストール開始- Installation Complete
[Enter] を押して再起動。 (再起動後 ESCをおして、UEFI設定に入る)とりあえず、ESXi を起動させる
↑から続き
1. ESCをぽちぽち押して、UEFIの設定画面へ
2. USBフラッシュ(VMwareESXiインストーラ)を抜く
3.Boot Manager
> (VMwareをインストールしたディスク)を↑↓で選んで、[Enter]
4. 何もせず、起動完了するまで待つ。(お好みで)固定IPに設定する
デフォルトは、DHCPなので、
- [F2]を押して、ログイン
Configure Management Network
>IPv4 Configuration
- [↑][↓]で、"Set static IPv4 address and network configuration:" を選んで [Space]キー
↓をうめたら、[Enter]キー
IPv4 Address Subnet Mask Default Gateway[ESC]をおして、Apply changes and restart management network? で、[Y] を押す
もう一度、[ESC]をおして、Logout
Webブラウザから、アクセス
- アドレスバーに IP アドレスを入れる。[詳細設定]をクリックして、
- xxx.xxx.xxx.xxxにアクセスする(安全ではありません)をクリック
- ESXiのログイン画面が表示。ユーザ名:
root
で、パスワードを入力して、[ログイン] ボタンクリック
- こんな感じ
- とりあえず、シャットダウン
- 確認画面で、ボタンぽち
ラズパイのUEFIファイルを、SSDにコピーして、SSDから起動できるようにする
ここでは、
F:
ドライブがmicroSDのドライブ。
- ESXi ArmをインストールしたSSD(たしか、5つのうち、2つパーティションがエクスプローラで見える、がここはさわらない)、と UEFI boot microSDカードを Windowsに接続する
- Win+R で、
diskpart
lis dis
で、接続されてるディスクを表示sel dis 1
で、ESXi ArmをインストールしたSSD を選択sel par 1
で、1つ目のパーティションを選択assign LETTER=P
で、P:
ドライブ(例)にアサインする (閉じずにこのまま)管理者で、
cmd
を開き、UEFIのmicroSDカードの中身を、P:\
にコピーする例:FドライブからPへコピーxcopy /E F:\*.* Pdiskpartにもどり、
remove LETTER=P
として、マウント解除。
exit
でdiskpartを抜ける実行例Microsoft DiskPart version 10.0.19041.1 Copyright (C) Microsoft Corporation. On computer: PC-90800 DISKPART> lis dis Disk ### Status Size Free Dyn Gpt -------- ------------- ------- ------- --- --- Disk 0 Online 476 GB 0 B * Disk 1 Online 931 GB 4096 KB * Disk 2 Online 3724 MB 4032 KB DISKPART> sel dis 1 Disk 1 is now the selected disk. DISKPART> lis par Partition ### Type Size Offset ------------- ---------------- ------- ------- Partition 1 System 100 MB 32 KB Partition 2 Primary 4095 MB 102 MB Partition 3 Primary 4095 MB 4198 MB Partition 4 Unknown 8 GB 8 GB Partition 5 Unknown 915 GB 16 GB DISKPART> sel par 1 Partition 1 is now the selected partition. DISKPART> assign LETTER=P DiskPart successfully assigned the drive letter or mount point. DISKPART> ... // ここで、別のウィンドウでファイルコピーをする。 ... DISKPART> remove LETTER=P DiskPart successfully removed the drive letter or mount point. DISKPART> exit例ファイルコピーMicrosoft Windows [Version 10.0.19041.572] (c) 2020 Microsoft Corporation. All rights reserved. C:\WINDOWS\system32>dir P: Volume in drive P has no label. Volume Serial Number is 5121-71B6 Directory of P:\ 09/01/2020 02:13 PM <DIR> EFI 0 File(s) 0 bytes 1 Dir(s) 104,224,768 bytes free C:\WINDOWS\system32>xcopy /E F:\*.* P:\ F:\bcm2708-rpi-b.dtb F:\bcm2708-rpi-b-plus.dtb F:\bcm2708-rpi-b-rev1.dtb F:\bcm2710-rpi-2-b.dtb . . ファイルたくさん . F:\overlays\w1-gpio-pullup.dtbo F:\overlays\w1-gpio.dtbo F:\overlays\w5500.dtbo F:\overlays\wittypi.dtbo 235 File(s) copied C:\WINDOWS\system32>exitSSD起動の設定をする
以下を接続
- SATA-USB3ケーブル+SSD(インストール先)
- キーボード
- HDMIディスプレイ
- 有線LAN
- ラズパイをUSB boot設定しておく (Raspberry Pi OSの
raspi-config
で)- ESCをぽちぽち押して、UEFIの設定画面へ
Boot Maintenance Manager
>Boot Options
>Delete Boot Option
(起動デバイスの削除)- 起動するSSD以外にチェックをつける (スペースキーで、チェックON/OFF)
Commit Changes and Exit
で、[Enter]- [ESC]を2回押して、
Continue
を選択して、[Enter]- 一度起動したら、シャットダウンして、電源ONで起動するか、確認
その他