亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

directory search
Compose About versions and upgrading (Compose) ASP.NET Core + SQL Server on Linux (Compose) CLI environment variables (Compose) Command-line completion (Compose) Compose(組成) Compose command-line reference(組合命令行參考) Control startup order (Compose) Django and PostgreSQL (Compose) Docker stacks and distributed application bundles (Compose) docker-compose build(docker-compose構(gòu)建) docker-compose bundle docker-compose config docker-compose create docker-compose down docker-compose events docker-compose exec docker-compose help docker-compose images docker-compose kill docker-compose logs docker-compose pause docker-compose port docker-compose ps docker-compose pull docker-compose push docker-compose restart docker-compose rm docker-compose run docker-compose scale docker-compose start docker-compose stop docker-compose top docker-compose unpause docker-compose up Environment file (Compose) Environment variables in Compose Extend services in Compose Frequently asked questions (Compose) Getting started (Compose) Install Compose Link environment variables (deprecated) (Compose) Networking in Compose Overview of Docker Compose Overview of docker-compose CLI Quickstart: Compose and WordPress Rails and PostgreSQL (Compose) Sample apps with Compose Using Compose in production Using Compose with Swarm Engine .NET Core application (Engine) About images, containers, and storage drivers (Engine) Add nodes to the swarm (Engine) Apply custom metadata (Engine) Apply rolling updates (Engine) apt-cacher-ng Best practices for writing Dockerfiles (Engine) Binaries (Engine) Bind container ports to the host (Engine) Breaking changes (Engine) Build your own bridge (Engine) Configure container DNS (Engine) Configure container DNS in user-defined networks (Engine) CouchDB (Engine) Create a base image (Engine) Create a swarm (Engine) Customize the docker0 bridge (Engine) Debian (Engine) Default bridge network Delete the service (Engine) Deploy a service (Engine) Deploy services to a swarm (Engine) Deprecated Engine features Docker container networking (Engine) Docker overview (Engine) Docker run reference (Engine) Dockerfile reference (Engine) Dockerize an application Drain a node (Engine) Engine FAQ (Engine) Fedora (Engine) Get started (Engine) Get started with macvlan network driver (Engine) Get started with multi-host networking (Engine) How nodes work (Engine) How services work (Engine) Image management (Engine) Inspect the service (Engine) Install Docker (Engine) IPv6 with Docker (Engine) Join nodes to a swarm (Engine) Legacy container links (Engine) Lock your swarm (Engine) Manage nodes in a swarm (Engine) Manage sensitive data with Docker secrets (Engine) Manage swarm security with PKI (Engine) Manage swarm service networks (Engine) Migrate to Engine 1.10 Optional Linux post-installation steps (Engine) Overview (Engine) PostgreSQL (Engine) Raft consensus in swarm mode (Engine) Riak (Engine) Run Docker Engine in swarm mode Scale the service (Engine) SDKs (Engine) Select a storage driver (Engine) Set up for the tutorial (Engine) SSHd (Engine) Storage driver overview (Engine) Store service configuration data (Engine) Swarm administration guide (Engine) Swarm mode key concepts (Engine) Swarm mode overlay network security model (Engine) Swarm mode overview (Engine) Understand container communication (Engine) Use multi-stage builds (Engine) Use swarm mode routing mesh (Engine) Use the AUFS storage driver (Engine) Use the Btrfs storage driver (Engine) Use the Device mapper storage driver (Engine) Use the OverlayFS storage driver (Engine) Use the VFS storage driver (Engine) Use the ZFS storage driver (Engine) Engine: Admin Guide Amazon CloudWatch logs logging driver (Engine) Bind mounts (Engine) Collect Docker metrics with Prometheus (Engine) Configuring and running Docker (Engine) Configuring logging drivers (Engine) Control and configure Docker with systemd (Engine) ETW logging driver (Engine) Fluentd logging driver (Engine) Format command and log output (Engine) Google Cloud logging driver (Engine) Graylog Extended Format (GELF) logging driver (Engine) Journald logging driver (Engine) JSON File logging driver (Engine) Keep containers alive during daemon downtime (Engine) Limit a container's resources (Engine) Link via an ambassador container (Engine) Log tags for logging driver (Engine) Logentries logging driver (Engine) PowerShell DSC usage (Engine) Prune unused Docker objects (Engine) Run multiple services in a container (Engine) Runtime metrics (Engine) Splunk logging driver (Engine) Start containers automatically (Engine) Storage overview (Engine) Syslog logging driver (Engine) tmpfs mounts Troubleshoot volume problems (Engine) Use a logging driver plugin (Engine) Using Ansible (Engine) Using Chef (Engine) Using Puppet (Engine) View a container's logs (Engine) Volumes (Engine) Engine: CLI Daemon CLI reference (dockerd) (Engine) docker docker attach docker build docker checkpoint docker checkpoint create docker checkpoint ls docker checkpoint rm docker commit docker config docker config create docker config inspect docker config ls docker config rm docker container docker container attach docker container commit docker container cp docker container create docker container diff docker container exec docker container export docker container inspect docker container kill docker container logs docker container ls docker container pause docker container port docker container prune docker container rename docker container restart docker container rm docker container run docker container start docker container stats docker container stop docker container top docker container unpause docker container update docker container wait docker cp docker create docker deploy docker diff docker events docker exec docker export docker history docker image docker image build docker image history docker image import docker image inspect docker image load docker image ls docker image prune docker image pull docker image push docker image rm docker image save docker image tag docker images docker import docker info docker inspect docker kill docker load docker login docker logout docker logs docker network docker network connect docker network create docker network disconnect docker network inspect docker network ls docker network prune docker network rm docker node docker node demote docker node inspect docker node ls docker node promote docker node ps docker node rm docker node update docker pause docker plugin docker plugin create docker plugin disable docker plugin enable docker plugin inspect docker plugin install docker plugin ls docker plugin push docker plugin rm docker plugin set docker plugin upgrade docker port docker ps docker pull docker push docker rename docker restart docker rm docker rmi docker run docker save docker search docker secret docker secret create docker secret inspect docker secret ls docker secret rm docker service docker service create docker service inspect docker service logs docker service ls docker service ps docker service rm docker service scale docker service update docker stack docker stack deploy docker stack ls docker stack ps docker stack rm docker stack services docker start docker stats docker stop docker swarm docker swarm ca docker swarm init docker swarm join docker swarm join-token docker swarm leave docker swarm unlock docker swarm unlock-key docker swarm update docker system docker system df docker system events docker system info docker system prune docker tag docker top docker unpause docker update docker version docker volume docker volume create docker volume inspect docker volume ls docker volume prune docker volume rm docker wait Use the Docker command line (Engine) Engine: Extend Access authorization plugin (Engine) Docker log driver plugins Docker network driver plugins (Engine) Extending Engine with plugins Managed plugin system (Engine) Plugin configuration (Engine) Plugins API (Engine) Volume plugins (Engine) Engine: Security AppArmor security profiles for Docker (Engine) Automation with content trust (Engine) Content trust in Docker (Engine) Delegations for content trust (Engine) Deploying Notary (Engine) Docker security (Engine) Docker security non-events (Engine) Isolate containers with a user namespace (Engine) Manage keys for content trust (Engine) Play in a content trust sandbox (Engine) Protect the Docker daemon socket (Engine) Seccomp security profiles for Docker (Engine) Secure Engine Use trusted images Using certificates for repository client verification (Engine) Engine: Tutorials Engine tutorials Network containers (Engine) Get Started Part 1: Orientation Part 2: Containers Part 3: Services Part 4: Swarms Part 5: Stacks Part 6: Deploy your app Machine Amazon Web Services (Machine) Digital Ocean (Machine) docker-machine active docker-machine config docker-machine create docker-machine env docker-machine help docker-machine inspect docker-machine ip docker-machine kill docker-machine ls docker-machine provision docker-machine regenerate-certs docker-machine restart docker-machine rm docker-machine scp docker-machine ssh docker-machine start docker-machine status docker-machine stop docker-machine upgrade docker-machine url Driver options and operating system defaults (Machine) Drivers overview (Machine) Exoscale (Machine) Generic (Machine) Get started with a local VM (Machine) Google Compute Engine (Machine) IBM Softlayer (Machine) Install Machine Machine Machine CLI overview Machine command-line completion Machine concepts and help Machine overview Microsoft Azure (Machine) Microsoft Hyper-V (Machine) Migrate from Boot2Docker to Machine OpenStack (Machine) Oracle VirtualBox (Machine) Provision AWS EC2 instances (Machine) Provision Digital Ocean Droplets (Machine) Provision hosts in the cloud (Machine) Rackspace (Machine) VMware Fusion (Machine) VMware vCloud Air (Machine) VMware vSphere (Machine) Notary Client configuration (Notary) Common Server and signer configurations (Notary) Getting started with Notary Notary changelog Notary configuration files Running a Notary service Server configuration (Notary) Signer configuration (Notary) Understand the service architecture (Notary) Use the Notary client
characters

Dockerfile參考

Docker可以通過閱讀a的指示自動(dòng)構(gòu)建圖像Dockerfile。Dockerfile是一個(gè)文本文檔,其中包含用戶可以在命令行上調(diào)用以組裝圖像的所有命令。使用docker build用戶可以創(chuàng)建一個(gè)自動(dòng)構(gòu)建,連續(xù)執(zhí)行幾條命令行指令。

該頁面描述了您可以在Dockerfile中使用的命令。閱讀本頁后,請(qǐng)參閱Dockerfile面向提示的指南的最佳做法。

用法

docker build命令從Dockerfile和上下文構(gòu)建一個(gè)映像。 構(gòu)建的上下文是指定位置PATH或URL中的文件集。 PATH是本地文件系統(tǒng)上的一個(gè)目錄。 該URL是一個(gè)Git存儲(chǔ)庫(kù)位置。

上下文是遞歸處理的。因此, PATH包含任何子目錄,且URL包含存儲(chǔ)庫(kù)及其子模塊。此示例顯示了一個(gè)使用當(dāng)前目錄作為上下文的構(gòu)建命令:

$ docker build .Sending build context to Docker daemon  6.51 MB...

構(gòu)建由Docker守護(hù)進(jìn)程運(yùn)行,而不是通過CLI運(yùn)行。構(gòu)建過程所做的第一件事是將整個(gè)上下文(遞歸地)發(fā)送到守護(hù)進(jìn)程。在大多數(shù)情況下,最好以空目錄作為上下文開始,并將Dockerfile保存在該目錄中。僅添加構(gòu)建Dockerfile所需的文件。

警告:不要用你的根目錄下,/作為PATH因?yàn)樗鼤?huì)導(dǎo)致生成到您的硬盤驅(qū)動(dòng)器的全部?jī)?nèi)容傳輸?shù)酱a頭工人守護(hù)進(jìn)程。

要在構(gòu)建上下文中使用文件,Dockerfile引用指令中指定的文件,例如COPY指令。 要增加構(gòu)建的性能,請(qǐng)通過將.dockerignore文件添加到上下文目錄來排除文件和目錄。 有關(guān)如何創(chuàng)建.dockerignore文件的信息,請(qǐng)參閱此頁面上的文檔。

傳統(tǒng)上,Dockerfile被稱為Dockerfile并位于上下文的根部。您可以使用該-f標(biāo)志docker build指向文件系統(tǒng)中任何位置的Dockerfile。

$ docker build -f /path/to/a/Dockerfile .

如果構(gòu)建成功,您可以指定一個(gè)存儲(chǔ)庫(kù)和標(biāo)記來保存新映像:

$ docker build -t shykes/myapp .

要在構(gòu)建之后將圖像標(biāo)記到多個(gè)存儲(chǔ)庫(kù)中,請(qǐng)?jiān)?code>-t運(yùn)行此build命令時(shí)添加多個(gè)參數(shù):

$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .

在Docker守護(hù)進(jìn)程運(yùn)行Dockerfile中的指令之前,它會(huì)執(zhí)行Dockerfile的初步驗(yàn)證,并在語法不正確時(shí)返回錯(cuò)誤:

$ docker build -t test/myapp .Sending build context to Docker daemon 2.048 kB
Error response from daemon: Unknown instruction: RUNCMD

Docker守護(hù)進(jìn)程會(huì)Dockerfile逐個(gè)運(yùn)行指令,在必要時(shí)將每條指令的結(jié)果提交給新映像,最終輸出新映像的標(biāo)識(shí)。Docker守護(hù)進(jìn)程將自動(dòng)清理您發(fā)送的上下文。

請(qǐng)注意,每條指令都是獨(dú)立運(yùn)行的,并會(huì)創(chuàng)建一個(gè)新圖像 - 所以RUN cd /tmp不會(huì)對(duì)下一條指令產(chǎn)生任何影響。

只要有可能,Docker將重新使用中間映像(緩存),以docker build顯著加速該過程。這由Using cache控制臺(tái)輸出中的消息指示。(有關(guān)更多信息,請(qǐng)參閱Dockerfile最佳做法指南中的“構(gòu)建緩存”部分):

$ 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

構(gòu)建緩存僅用于具有本地父鏈的圖像。這意味著這些圖像是由以前的版本創(chuàng)建的,或者是整個(gè)圖像鏈加載的docker load。如果您希望使用特定映像的構(gòu)建緩存,則可以使用--cache-from選項(xiàng)指定它。指定的圖像--cache-from不需要有父鏈,可以從其他注冊(cè)表中提取。

當(dāng)你完成你的構(gòu)建時(shí),你已經(jīng)準(zhǔn)備好考慮將存儲(chǔ)庫(kù)推送到它的注冊(cè)表。

格式

以下是Dockerfile格式:

# Comment
INSTRUCTION arguments

該指令不區(qū)分大小寫。然而,約定是為了更容易將它們與爭(zhēng)論區(qū)分開來。

Docker按順序在Dockerfile中運(yùn)行指令。 Dockerfile必須以FROM指令開始。 FROM指令指定您正在構(gòu)建的基本映像。 FROM只能在一個(gè)或多個(gè)ARG指令之后,這些指令聲明在Dockerfile的FROM行中使用的參數(shù)。

Docker treats 把該行開始#一個(gè)評(píng)論,除非該行是一個(gè)合法的解析器指令。#一行中其他任何地方的標(biāo)記都被視為參數(shù)。這允許像這樣的語句:

# Comment
RUN echo 'we are running some # of cool things'

注釋中不支持換行符。

解析器指令

解析器指令是可選的,并影響處理Dockerfile中后續(xù)行的方式。 解析器指令不會(huì)將圖層添加到構(gòu)建中,并且不會(huì)顯示為構(gòu)建步驟。 解析器指令以#directive = value的形式寫入特殊類型的注釋。 單個(gè)指令只能使用一次。

一旦注釋,空行或構(gòu)建器指令已被處理,Docker不再查找解析器指令。相反,它將格式化為分析器指令的任何內(nèi)容視為注釋,并且不會(huì)嘗試驗(yàn)證它是否可能是解析器指令。因此,所有解析器指令都必須位于Dockerfile最頂端。

解析器指令不區(qū)分大小寫。但是,約定是小寫。約定還包括在任何解析器指令之后的空白行。解析器指令不支持行連續(xù)字符。

由于這些規(guī)則,以下示例都是無效的:

由于行延續(xù)而無效:

# direc \
tive=value

由于出現(xiàn)兩次而無效:

# directive=value1
# directive=value2

FROM ImageName

由于出現(xiàn)在建造者指令之后,作為評(píng)論對(duì)待:

FROM ImageName
# directive=value

由于在不是解析器指令的注釋之后出現(xiàn),所以作為注釋處理:

# About my dockerfile
# directive=value
FROM ImageName

未知指令由于未被識(shí)別而被視為評(píng)論。另外,由于在不是解析器指令的注釋之后出現(xiàn),已知指令被視為注釋。

# unknowndirective=value
# knowndirective=value

解析器指令中允許使用非分行空白。因此,以下幾行都是一致對(duì)待的:

#directive=value
# directive =value
#	directive= value
# directive = value
#	  dIrEcTiVe=value

以下解析器指令受支持:

  • escape

轉(zhuǎn)義

# escape=\ (backslash)

或是

# escape=` (backtick)

escape指令設(shè)置用于轉(zhuǎn)義字符的字符Dockerfile。如果未指定,則默認(rèn)轉(zhuǎn)義字符為\

轉(zhuǎn)義字符既用于轉(zhuǎn)義一行中的字符,又用于轉(zhuǎn)義換行符。這允許Dockerfile指令跨越多行。請(qǐng)注意,無論escape解析器指令是否包含在a中Dockerfile,轉(zhuǎn)義都不在 RUN 命令中執(zhí)行,除了在行的末尾。

將轉(zhuǎn)義字符設(shè)置`為特別有用Windows,其中\是目錄路徑分隔符。`與Windows PowerShell一致。

考慮下面的例子,它會(huì)以非顯而易見的方式失敗Windows。第二\,在第二行的端部將被解釋為用于換行的逃逸,而不是從第一逸出的目標(biāo)\。同樣,\假設(shè)它實(shí)際上是作為一條指令處理的,那么在第三行的末尾會(huì)導(dǎo)致它被視為連續(xù)行。這個(gè)dockerfile的結(jié)果是第二行和第三行被認(rèn)為是一條單獨(dú)的指令:

FROM microsoft/nanoserver
COPY testfile.txt c:\\
RUN dir c:\

結(jié)果是:

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>

上述的一個(gè)解決方案將是/用作COPY指令和目標(biāo)dir。然而,這種語法充其量是令人困惑的,因?yàn)槁窂讲⒉皇亲匀坏?code>Windows,并且最壞的情況是容易出錯(cuò),因?yàn)椴⒎撬?code>Windows支持的命令都/作為路徑分隔符。

通過添加轉(zhuǎn)義解析器指令,在Windows上使用自然平臺(tái)語義對(duì)文件路徑使用以下Dockerfile可以成功:

# escape=`

FROM microsoft/nanoserver
COPY testfile.txt c:\
RUN dir c:\

結(jié)果是:

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.txt10/05/2016  02:22 PM    <DIR>          Program Files10/05/2016  02:14 PM    <DIR>          Program Files (x86)10/28/2016  11:18 AM                62 testfile.txt10/28/2016  11:20 AM    <DIR>          Users10/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>

環(huán)境更換

環(huán)境變量(用ENV語句聲明)也可以在某些指令中用作由Dockerfile解釋的變量。 轉(zhuǎn)義也被處理,從字面上將類似于變量的語法包含到語句中。

使用$ variable_name或$ {variable_name}在Dockerfile中記錄環(huán)境變量。 它們被等價(jià)處理,括號(hào)語法通常用于解決變量名稱中沒有空格的問題,如$ {foo} _bar。

${variable_name}語法還支持一些標(biāo)準(zhǔn)bash修飾符,如下所示:

  • $ {variable:-word}表示如果設(shè)置了變量,那么結(jié)果就是該值。 如果變量沒有設(shè)置,則字將是結(jié)果。

  • $ {variable:+ word}表示如果設(shè)置了變量,那么word將是結(jié)果,否則結(jié)果是空字符串。

在任何情況下,word都可以是任何字符串,包括其他環(huán)境變量。

通過\在變量之前添加一個(gè)變量可以進(jìn)行轉(zhuǎn)義:\$foo或者\${foo},例如分別轉(zhuǎn)換為文字$foo${foo}文字。

示例(在之后顯示解析的表示#):

FROM busybox
ENV foo /bar
WORKDIR ${foo}   # WORKDIR /bar
ADD . $foo       # ADD . /bar
COPY \$foo /quux # COPY $foo /quux

Dockerfile中的以下指令列表支持環(huán)境變量:

  • ADD

  • COPY

  • ENV

  • EXPOSE

  • FROM

  • LABEL

  • STOPSIGNAL

  • USER

  • VOLUME

  • WORKDIR

以及:

  • ONBUILD (當(dāng)與上述支持的指令之一結(jié)合使用時(shí))

注意:在1.4之前,ONBUILD說明支持環(huán)境變量,即使與上面列出的任何指令結(jié)合使用。

整個(gè)指令中的環(huán)境變量替換將對(duì)每個(gè)變量使用相同的值。換句話說,在這個(gè)例子中:

ENV abc=hello
ENV abc=bye def=$abc
ENV ghi=$abc

將導(dǎo)致def的值為hello,而不是再見。 然而,ghi將具有再見值,因?yàn)樗皇菍bc設(shè)置為再見的同一指令的一部分。

.dockerignore文件

在docker CLI將上下文發(fā)送到docker守護(hù)程序之前,它會(huì)在上下文的根目錄中查找名為.dockerignore的文件。 如果此文件存在,CLI會(huì)修改上下文以排除與其中的模式匹配的文件和目錄。 這有助于避免不必要地將大型或敏感文件和目錄發(fā)送到守護(hù)程序,并可能使用ADD或COPY將它們添加到圖像。

CLI將.dockerignore文件解釋為與Unix shell文件大小相似的以換行符分隔的模式列表。為了匹配的目的,上下文的根被認(rèn)為是工作目錄和根目錄。例如,這些模式/foo/barfoo/bar兩者都不包含位于位于的git存儲(chǔ)庫(kù)barfoo子目錄PATH或根目錄中指定的文件或目錄URL。兩者都沒有排除其他任何東西。

如果.dockerignore文件中的一行以第一#列開頭,則此行被視為注釋,并在被CLI解釋之前被忽略。

這是一個(gè)示例.dockerignore文件:

# comment*/temp**/*/temp*
temp?

該文件導(dǎo)致以下構(gòu)建行為:

規(guī)則

行為

# comment

忽略。

*/temp*

排除在根目錄的任何直接子目錄中名稱以temp開頭的文件和目錄。例如,排除純文件/somedir/temporary.txt,就像目錄/ somedir / temp一樣。

*/*/temp*

從根目錄下兩個(gè)級(jí)別的任何子目錄中排除以temp開頭的文件和目錄。例如,排除/somedir/subdir/temporary.txt。

temp?

排除名稱為temp的一個(gè)字符擴(kuò)展名的根目錄中的文件和目錄。例如,/ tempa和/ tempb被排除在外。

匹配是使用Go的filepath.Match規(guī)則完成的。 預(yù)處理步驟刪除前導(dǎo)和尾隨空白并消除。 和..使用Go的filepath.Clean。 預(yù)處理后空白的行將被忽略。

除了Go的filepath.Match規(guī)則,Docker還支持**匹配任意數(shù)量目錄(包括零)的特殊通配符字符串。例如,**/*.go將排除.go以所有目錄中包含的文件結(jié)尾的所有文件,包括構(gòu)建上下文的根目錄。

!(感嘆號(hào))開頭的行可用于排除例外情況。以下是.dockerignore使用此機(jī)制的示例文件:

    *.md    !README.md

README.md上下文,所有減價(jià)文件均被排除在外。

!例外規(guī)則的放置會(huì)影響行為:.dockerignore匹配特定文件的最后一行確定是否包含或排除??紤]下面的例子:

    *.md    !README*.md
    README-secret.md

除README-secret.md以外的README文件除上下文外不包含任何降價(jià)文件。

現(xiàn)在考慮這個(gè)例子:

    *.md
    README-secret.md    !README*.md

所有的README文件都包含在內(nèi)。 中間行不起作用,因?yàn)?!README * .md與README-secret.md匹配并且最后一個(gè)。

您甚至可以使用.dockerignore文件來排除Dockerfile和.dockerignore文件。 這些文件仍然被發(fā)送到守護(hù)進(jìn)程,因?yàn)樗枰鼈儊硗瓿伤墓ぷ鳌?但ADD和COPY指令不會(huì)將它們復(fù)制到圖像上。

最后,您可能需要指定要在上下文中包含哪些文件,而不是要排除的文件。要實(shí)現(xiàn)這一點(diǎn),請(qǐng)指定*第一個(gè)模式,然后指定一個(gè)或多個(gè)!異常模式。

注意:由于歷史原因,該模式.被忽略。

FROM

FROM <image> [AS <name>]

或者

FROM <image>[:<tag>] [AS <name>]

或者

FROM <image>[@<digest>] [AS <name>]

FROM指令初始化一個(gè)新的編譯階段并為后續(xù)指令設(shè)置基本映像。因此,有效的Dockerfile必須以FROM指令開始。圖像可以是任何有效的圖像 - 通過從公共存儲(chǔ)庫(kù)中拉出圖像開始特別容易。

  • ARG是Dockerfile中可能位于FROM之前的唯一指令。 請(qǐng)參閱了解ARG和FROM的交互方式。

  • FROM可以在單個(gè)Dockerfile中多次出現(xiàn)以創(chuàng)建多個(gè)圖像或?qū)⒁粋€(gè)構(gòu)建階段用作另一個(gè)構(gòu)建階段的依賴關(guān)系。 只需在每個(gè)新的FROM指令之前記錄提交輸出的最后一個(gè)映像ID即可。 每條FROM指令清除以前指令創(chuàng)建的任何狀態(tài)。

  • 通過將AS名稱添加到FROM指令,可以給新的生成階段賦予一個(gè)名稱。 該名稱可用于后續(xù)的FROM和COPY --from = <name | index>指令以引用此階段中構(gòu)建的映像。

  • 標(biāo)簽或摘要值是可選的。 如果您忽略其中之一,則默認(rèn)情況下,構(gòu)建器會(huì)采用最新的標(biāo)記。 如果無法找到標(biāo)記值,構(gòu)建器將返回錯(cuò)誤。

了解ARG和FROM如何交互

FROM說明支持由ARG第一個(gè)之前發(fā)生的任何指令聲明的變量FROM。

ARG  CODE_VERSION=latest
FROM base:${CODE_VERSION}CMD  /code/run-app

FROM extras:${CODE_VERSION}CMD  /code/run-extras

在FROM之前聲明的ARG在構(gòu)建階段之外,所以它不能在FROM之后的任何指令中使用。 要使用在第一個(gè)FROM之前聲明的ARG的默認(rèn)值,請(qǐng)?jiān)跇?gòu)建階段內(nèi)使用沒有值的ARG指令:

ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version

RUN

RUN有兩種形式:

  • RUN <command>(shell形式,該命令在shell中運(yùn)行,默認(rèn)情況下是Linux上的/ bin / sh -c或Windows上的cmd / S / C)

  • RUN [“executable”,“param1”,“param2”](exec形式)

RUN指令將在當(dāng)前圖像頂部的新圖層中執(zhí)行任何命令并提交結(jié)果。由此產(chǎn)生的提交圖像將用于下一步Dockerfile

分層RUN指令和生成提交符合Docker的核心概念,其中提交很便宜,容器可以從圖像歷史中的任意點(diǎn)創(chuàng)建,就像源代碼控制一樣。

EXEC形式使得能夠避免殼串改寫(munging),且RUN使用不包含指定殼可執(zhí)行基本圖像命令。

shell表單的默認(rèn)shell 可以使用該SHELL命令進(jìn)行更改。

shell 形式中,您可以使用\(反斜杠)將單個(gè)RUN指令繼續(xù)到下一行。例如,考慮這兩行:

RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'

它們一起等同于這一行:

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'

:要使用不同于'/ bin / sh' 的shell ,請(qǐng)使用傳遞給所需shell 的exec表單。例如,RUN ["/bin/bash", "-c", "echo hello"] 注意exec表單被解析為JSON數(shù)組,這意味著您必須在單詞(而非單引號(hào)('))周圍使用雙引號(hào)(“)。注意:與shell形式不同,exec形式不會(huì)調(diào)用命令shell。這意味著正常的shell處理不會(huì)發(fā)生。例如,RUN [ "echo", "$HOME" ]不會(huì)對(duì)變量進(jìn)行替換$HOME。如果您想要進(jìn)行shell處理,請(qǐng)使用shell窗體或直接執(zhí)行shell,例如:RUN [ "sh", "-c", "echo $HOME" ]。當(dāng)使用exec表單并直接執(zhí)行一個(gè)shell時(shí)(如shell格式的情況),它是在執(zhí)行環(huán)境變量擴(kuò)展的shell,而不是docker。  注意:在JSON形式中,必須避免反斜杠。這在反斜杠是路徑分隔符的Windows上尤其重要。由于不是有效的JSON,以下行將被視為shell形式,并以意外的方式失?。?code>RUN ["c:\windows\system32\tasklist.exe"]此示例的正確語法為:RUN ["c:\\windows\\system32\\tasklist.exe"]

RUN指令緩存在下一次構(gòu)建期間不會(huì)自動(dòng)失效。 像RUN運(yùn)行apt-get dist-upgrade -y這樣的指令的緩存將在下一次構(gòu)建時(shí)重用。 RUN指令緩存可以通過使用--no-cache標(biāo)志失效,例如docker build --no-cache。

有關(guān)Dockerfile更多信息,請(qǐng)參閱最佳實(shí)踐指南。

說明的高速緩存RUN可能會(huì)因ADD指令而失效。詳情請(qǐng)參閱下文。

已知問題(RUN)

  • 問題783是關(guān)于使用AUFS文件系統(tǒng)時(shí)可能發(fā)生的文件權(quán)限問題。 例如,您可能會(huì)在嘗試制作文件時(shí)注意到它。對(duì)于具有最新aufs版本的系統(tǒng)(即可以設(shè)置dirperm1安裝選項(xiàng)),docker將嘗試通過使用dirperm1選項(xiàng)安裝圖層來自動(dòng)修復(fù)問題。 有關(guān)dirperm1選項(xiàng)的更多詳細(xì)信息,請(qǐng)參閱aufs手冊(cè)頁。如果您的系統(tǒng)不支持dirperm1,則說明問題是解決方法。

CMD

CMD指令有三種形式:

  • CMD ["executable","param1","param2"]執(zhí)行形式,這是首選形式)

  • CMD ["param1","param2"](作為進(jìn)入點(diǎn)的默認(rèn)參數(shù)

  • CMD command param1 param2形式)

只能有一條CMD指令Dockerfile。如果列出多個(gè),CMD則只有最后一個(gè)CMD會(huì)生效。

CMD的主要目的是為執(zhí)行容器提供默認(rèn)值。 這些默認(rèn)值可以包含可執(zhí)行文件,或者可以省略可執(zhí)行文件,在這種情況下,您還必須指定ENTRYPOINT指令。

:如果CMD用于為ENTRYPOINT指令提供缺省參數(shù),則應(yīng)該使用JSON數(shù)組格式指定CMDENTRYPOINT指令。注意exec表單被解析為JSON數(shù)組,這意味著您必須在單詞(而非單引號(hào)('))周圍使用雙引號(hào)(“)。注意:與shell形式不同,exec形式不會(huì)調(diào)用命令shell。這意味著正常的shell處理不會(huì)發(fā)生。例如,CMD [ "echo", "$HOME" ]不會(huì)對(duì)變量進(jìn)行替換$HOME。如果您想要進(jìn)行shell處理,請(qǐng)使用shell窗體或直接執(zhí)行shell,例如:CMD [ "sh", "-c", "echo $HOME" ]。當(dāng)使用exec表單并直接執(zhí)行一個(gè)shell時(shí)(如shell格式的情況),它是在執(zhí)行環(huán)境變量擴(kuò)展的shell,而不是docker。

當(dāng)以shell或exec格式使用時(shí),CMD指令設(shè)置運(yùn)行映像時(shí)要執(zhí)行的命令。

如果你使用的是shell的形式CMD,那么<command>將執(zhí)行在/bin/sh -c

FROM ubuntu
CMD echo "This is a test." | wc -

如果您想在沒有shell的情況下運(yùn)行<command>,那么您必須將該命令表示為JSON數(shù)組并給出可執(zhí)行文件的完整路徑。 這種數(shù)組形式是CMD **的首選格式。**任何附加參數(shù)都必須在數(shù)組中單獨(dú)表示為字符串:

FROM ubuntu
CMD ["/usr/bin/wc","--help"]

如果您希望您的容器每次都運(yùn)行相同的可執(zhí)行文件,那么您應(yīng)該考慮ENTRYPOINT與其結(jié)合使用CMD。見入口點(diǎn)。

如果用戶指定碼頭運(yùn)行的參數(shù),那么它們將覆蓋CMD中指定的默認(rèn)值。

注意:不要將RUN與CMD混淆。 RUN實(shí)際上運(yùn)行一個(gè)命令并提交結(jié)果; CMD在構(gòu)建時(shí)不執(zhí)行任何操作,但是指定了圖像的預(yù)期命令。

LABEL

LABEL <key>=<value> <key>=<value> <key>=<value> ...

LABEL指令為圖像添加元數(shù)據(jù)。 LABEL是一個(gè)鍵值對(duì)。 要在LABEL值中包含空格,請(qǐng)像在命令行解析中一樣使用引號(hào)和反斜杠。 幾個(gè)用法示例:

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."

一張圖片可以有多個(gè)標(biāo)簽。 要指定多個(gè)標(biāo)簽,Docker建議盡可能將標(biāo)簽結(jié)合到單個(gè)LABEL指令中。 每個(gè)LABEL指令都會(huì)產(chǎn)生一個(gè)新圖層,如果您使用多個(gè)標(biāo)簽,則會(huì)導(dǎo)致圖像效率低下。 這個(gè)例子導(dǎo)致一個(gè)圖像層。

LABEL multi.label1="value1" multi.label2="value2" other="value3"

以上內(nèi)容也可以寫成:

LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"

標(biāo)簽是添加的,包括圖像中的LABELs FROM。如果Docker遇到已存在的標(biāo)簽/鍵,則新值將覆蓋任何以前具有相同鍵的標(biāo)簽。

要查看圖像的標(biāo)簽,請(qǐng)使用該docker inspect命令。

"Labels": {    "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 (deprecated)

MAINTAINER <name>

MAINTAINER指令設(shè)置生成圖像的Author字段。 LABEL指令是一個(gè)非常靈活的版本,您應(yīng)該使用它,因?yàn)樗梢栽O(shè)置您需要的任何元數(shù)據(jù),并且可以很容易地查看,例如使用docker檢查。 要設(shè)置與MAINTAINER字段對(duì)應(yīng)的標(biāo)簽,您可以使用:

LABEL maintainer="SvenDowideit@home.org.au"

這將從docker inspect其他標(biāo)簽中可見。

EXPOSE

EXPOSE <port> [<port>...]

EXPOSE指令通知Docker,該容器在運(yùn)行時(shí)偵聽指定的網(wǎng)絡(luò)端口。 EXPOSE不會(huì)使主機(jī)可以訪問容器的端口。 要做到這一點(diǎn),您必須使用-p標(biāo)志來發(fā)布一系列端口或使用-P標(biāo)志來發(fā)布所有暴露的端口。 您可以公開一個(gè)端口號(hào)并在另一個(gè)號(hào)碼外部發(fā)布它。

要在主機(jī)系統(tǒng)上設(shè)置端口重定向,請(qǐng)參閱使用-P標(biāo)志。Docker網(wǎng)絡(luò)功能支持創(chuàng)建網(wǎng)絡(luò),而無需公開網(wǎng)絡(luò)中的端口,有關(guān)詳細(xì)信息,請(qǐng)參閱此功能的概述)。

ENV

ENV <key> <value>ENV <key>=<value> ...

ENV指令將環(huán)境變量<key>設(shè)置為值<value>。 該值將處于所有“后代”Dockerfile命令的環(huán)境中,并且可以在許多內(nèi)聯(lián)中被替換。

ENV指令有兩種形式。 第一種形式ENV <key> <value>將把單個(gè)變量設(shè)置為一個(gè)值。 第一個(gè)空格之后的整個(gè)字符串將被視為<value> - 包括諸如空格和引號(hào)之類的字符。

第二種形式ENV <key> = <value> ...允許一次設(shè)置多個(gè)變量。 請(qǐng)注意,第二種形式在語法中使用等號(hào)(=),而第一種形式不使用。 與命令行解析一樣,引號(hào)和反斜杠可用于包含值中的空格。

例如:

ENV myName="John Doe" myDog=Rex\ The\ Dog \
    myCat=fluffy

且如下:

ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy

將在最終圖像中產(chǎn)生相同的凈結(jié)果,但首選形式是首選,因?yàn)樗鼤?huì)生成單個(gè)緩存層。

使用ENV設(shè)置的環(huán)境變量將在從結(jié)果圖像運(yùn)行容器時(shí)保留。 您可以使用docker inspect查看這些值,并使用docker run --env <key> = <value>更改它們。

注意:環(huán)境持久性可能會(huì)導(dǎo)致意想不到的副作用。例如,設(shè)置ENV DEBIAN_FRONTEND noninteractive可能會(huì)將apt-get用戶混淆在基于Debian的映像上。要為單個(gè)命令設(shè)置值,請(qǐng)使用RUN <key>=<value> <command>

ADD

ADD有兩種形式:

  • ADD <src>... <dest>

  • ADD ["<src>",... "<dest>"] (此表單對(duì)于包含空格的路徑是必需的)

ADD指令從<src>中復(fù)制新文件,目錄或遠(yuǎn)程文件URL,并將它們添加到路徑<dest>中圖像的文件系統(tǒng)中。

<src>可以指定多個(gè)資源,但如果它們是文件或目錄,則它們必須與正在構(gòu)建的源目錄(構(gòu)建的上下文)相關(guān)。

每個(gè)<src>可能包含通配符,匹配將使用Go的filepath.Match規(guī)則完成。例如:

ADD hom* /mydir/        # adds all files starting with "hom"ADD hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

<dest>是一個(gè)絕對(duì)路徑或相對(duì)路徑,WORKDIR源將在目標(biāo)容器中復(fù)制到該路徑中。

ADD test relativeDir/          # adds "test" to `WORKDIR`/relativeDir/ADD test /absoluteDir/         # adds "test" to /absoluteDir/

添加包含特殊字符(例如[])的文件或目錄時(shí),您需要按照Golang規(guī)則轉(zhuǎn)義這些路徑,以防止它們被視為匹配模式。例如,要添加一個(gè)名為的文件arr[0].txt,請(qǐng)使用以下內(nèi)容;

ADD arr[[]0].txt /mydir/    # copy a file named "arr[0].txt" to /mydir/

所有新文件和目錄都是使用UID和GID創(chuàng)建的。

在<src>是遠(yuǎn)程文件URL的情況下,目標(biāo)將具有600的權(quán)限。如果正在檢索的遠(yuǎn)程文件具有HTTP Last-Modified標(biāo)頭,則將使用來自該標(biāo)頭的時(shí)間戳來設(shè)置目的地上的mtime 文件。 但是,與在ADD期間處理的任何其他文件一樣,mtime不會(huì)包含在文件是否已更改以及緩存應(yīng)該更新的確定中。

注意:如果通過STDIN(docker build - <somefile)傳遞Dockerfile來構(gòu)建,則不存在構(gòu)建上下文,因此Dockerfile只能包含基于URL的ADD指令。 您還可以通過STDIN傳遞一個(gè)壓縮歸檔文件:(docker build - <archive.tar.gz),歸檔文件根目錄下的Dockerfile以及歸檔文件的其余部分將用作構(gòu)建的上下文。 注意:如果您的URL文件使用身份驗(yàn)證進(jìn)行保護(hù),則需要使用RUN wget,RUN curl或使用容器內(nèi)的其他工具,因?yàn)锳DD指令不支持身份驗(yàn)證。 注意:如果<src>的內(nèi)容已更改,則第一次遇到的ADD指令將使Dockerfile中所有后續(xù)指令的緩存無效。 這包括使RUN指令的緩存無效。 有關(guān)更多信息,請(qǐng)參閱Dockerfile最佳實(shí)踐指南。

ADD 遵守以下規(guī)則:

  • <src>路徑必須位于構(gòu)建的上下文中; 你不能添加../something / something,因?yàn)閐ocker build的第一步是將上下文目錄(和子目錄)發(fā)送到docker守護(hù)進(jìn)程。

  • 如果<src>是一個(gè)URL并且<dest>不以結(jié)尾的斜杠結(jié)尾,那么文件將從URL下載并復(fù)制到<dest>。

  • 如果<src>是一個(gè)URL,并且<dest>以尾部的斜線結(jié)尾,則從URL中推斷出該文件名,并將該文件下載到<dest> / <filename>。 例如,添加http://example.com/foobar /會(huì)創(chuàng)建文件/ foobar。 該URL必須有一個(gè)不平凡的路徑,以便在這種情況下可以找到適當(dāng)?shù)奈募╤ttp://example.com將不起作用)。

  • 如果<src>是一個(gè)目錄,則復(fù)制該目錄的全部?jī)?nèi)容,包括文件系統(tǒng)元數(shù)據(jù)。

注意:目錄本身不被復(fù)制,只是它的內(nèi)容。

  • 如果<src>是以可識(shí)別的壓縮格式(身份,gzip,bzip2或xz)的本地 tar歸檔文件,則將其解壓縮為目錄。來自遠(yuǎn)程 URL的資源不被解壓縮。當(dāng)一個(gè)目錄被復(fù)制或解壓縮時(shí),它的行為tar -x與結(jié)果相同,結(jié)果是:

1. Whatever existed at the destination path and2. The contents of the source tree, with conflicts resolved in favor of “2.” on a file-by-file basis.

注意:文件是否被識(shí)別為可識(shí)別的壓縮格式完全是基于文件的內(nèi)容而不是文件的名稱。例如,如果一個(gè)空文件恰好結(jié)束,.tar.gz這將不會(huì)被識(shí)別為一個(gè)壓縮文件,并且不會(huì)生成任何類型的解壓縮錯(cuò)誤消息,而是將該文件簡(jiǎn)單地復(fù)制到目標(biāo)。

  • 如果<src>是任何其他類型的文件,則將其與其元數(shù)據(jù)一起單獨(dú)復(fù)制。 在這種情況下,如果<dest>以結(jié)尾斜杠/結(jié)尾,則它將被視為一個(gè)目錄,<src>的內(nèi)容將寫入<dest> / base(<src>)。

  • 如果指定了多個(gè)<src>資源(直接或由于使用通配符),則<dest>必須是目錄,并且必須以斜杠/結(jié)尾。

  • 如果<dest>不以結(jié)尾的斜杠結(jié)尾,則它將被視為常規(guī)文件,<src>的內(nèi)容將寫入<dest>。

  • 如果<dest>不存在,則會(huì)在其路徑中創(chuàng)建所有缺少的目錄。

COPY

COPY有兩種形式:

  • COPY <src>... <dest>

  • COPY ["<src>",... "<dest>"] (此表單對(duì)于包含空格的路徑是必需的)

COPY指令復(fù)制新文件或目錄<src>并將其添加到路徑中容器的文件系統(tǒng)<dest>。

<src>可以指定多個(gè)資源,但它們必須相對(duì)于正在構(gòu)建的源目錄(構(gòu)建的上下文)。

每個(gè)<src>可能包含通配符,匹配將使用Go的filepath.Match規(guī)則完成。例如:

COPY hom* /mydir/        # adds all files starting with "hom"COPY hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

<dest>是一個(gè)絕對(duì)路徑或相對(duì)路徑,WORKDIR源將在目標(biāo)容器中復(fù)制到該路徑中。

COPY test relativeDir/   # adds "test" to `WORKDIR`/relativeDir/COPY test /absoluteDir/  # adds "test" to /absoluteDir/

在復(fù)制包含特殊字符(如[])的文件或目錄時(shí),您需要按照Golang規(guī)則轉(zhuǎn)義這些路徑,以防止它們被視為匹配模式。例如,要復(fù)制一個(gè)名為arr[0].txt的文件,請(qǐng)使用以下內(nèi)容;

COPY arr[[]0].txt /mydir/    # copy a file named "arr[0].txt" to /mydir/

所有新文件和目錄都是使用UID和GID創(chuàng)建的。

注意:如果使用STDIN(docker build - < somefile)構(gòu)建,則沒有構(gòu)建上下文,因此COPY無法使用。

可選地,COPY接受一個(gè)flag --from = <name | index>,它可以用來將源位置設(shè)置為以前的構(gòu)建階段(使用FROM .. AS <name>創(chuàng)建),而不是由 用戶。 該標(biāo)志還接受為以FROM指令開始的所有以前的構(gòu)建階段分配的數(shù)字索引。 如果無法找到具有指定名稱的構(gòu)建階段,則嘗試使用具有相同名稱的圖像。

COPY 遵守以下規(guī)則:

  • <src>路徑必須位于構(gòu)建的上下文中; 你不能COPY ../something / something,因?yàn)閐ocker build的第一步是將上下文目錄(和子目錄)發(fā)送到docker守護(hù)進(jìn)程。

  • 如果<src>是一個(gè)目錄,則復(fù)制該目錄的全部?jī)?nèi)容,包括文件系統(tǒng)元數(shù)據(jù)。

注意:目錄本身不被復(fù)制,只是它的內(nèi)容。

  • 如果<src>是任何其他類型的文件,則將其與其元數(shù)據(jù)一起單獨(dú)復(fù)制。 在這種情況下,如果<dest>以結(jié)尾斜杠/結(jié)尾,則它將被視為一個(gè)目錄,<src>的內(nèi)容將寫入<dest> / base(<src>)。

  • 如果指定了多個(gè)<src>資源(直接或由于使用通配符),則<dest>必須是目錄,并且必須以斜杠/結(jié)尾。

  • 如果<dest>不以結(jié)尾的斜杠結(jié)尾,則它將被視為常規(guī)文件,<src>的內(nèi)容將寫入<dest>。

  • 如果<dest>不存在,則會(huì)在其路徑中創(chuàng)建所有缺少的目錄。

ENTRYPOINT

ENTRYPOINT有兩種形式:

  • ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)

  • ENTRYPOINT command param1 param2 (shell form)

一個(gè)ENTRYPOINT允許您配置將要運(yùn)行一個(gè)可執(zhí)行的容器。

例如,以下內(nèi)容將啟動(dòng)nginx及其默認(rèn)內(nèi)容,并在端口80上偵聽:

docker run -i -t --rm -p 80:80 nginx

docker run <image>的命令行參數(shù)將被添加到exec表單ENTRYPOINT中的所有元素之后,并且將覆蓋使用CMD指定的所有元素。 這允許將參數(shù)傳遞給入口點(diǎn),即docker run <image> -d將-d參數(shù)傳遞給入口點(diǎn)。 您可以使用docker run --entrypoint標(biāo)志覆蓋ENTRYPOINT指令。

shell形式阻止使用任何CMD或運(yùn)行命令行參數(shù),但具有缺點(diǎn),即您的ENTRYPOINT將作為/ bin / sh -c的子命令啟動(dòng),該命令不傳遞信號(hào)。 這意味著可執(zhí)行文件不會(huì)是容器的PID 1 - 并且不會(huì)接收Unix信號(hào) - 所以您的可執(zhí)行文件將不會(huì)從docker stop <container>收到SIGTERM。

只有最后一條ENTRYPOINT指令Dockerfile才會(huì)起作用。

Exec form ENTRYPOINT示例

您可以使用ENTRYPOINT的exec形式來設(shè)置相當(dāng)穩(wěn)定的默認(rèn)命令和參數(shù),然后使用CMD的任何一種形式來設(shè)置更可能更改的其他默認(rèn)值。

FROM ubuntu
ENTRYPOINT ["top", "-b"]CMD ["-c"]

當(dāng)你運(yùn)行容器時(shí),你可以看到這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.05Threads:   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

要進(jìn)一步檢查結(jié)果,您可以使用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

你可以優(yōu)雅地請(qǐng)求top關(guān)閉使用docker stop test。

以下Dockerfile顯示使用ENTRYPOINT前臺(tái)運(yùn)行Apache(即as PID 1):

FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

如果您需要為單個(gè)可執(zhí)行文件編寫啟動(dòng)腳本,則可以通過使用execgosu命令確保最終的可執(zhí)行文件接收到Unix信號(hào):

#!/usr/bin/env bashset -eif [ "$1" = 'postgres' ]; then
    chown -R postgres "$PGDATA"    if [ -z "$(ls -A "$PGDATA")" ]; then
        gosu postgres initdb
    fi

    exec gosu postgres "$@"fi

exec "$@"

最后,如果您需要在關(guān)閉時(shí)進(jìn)行一些額外的清理(或與其他容器進(jìn)行通信),或者協(xié)調(diào)多個(gè)可執(zhí)行文件,則可能需要確保ENTRYPOINT腳本接收到Unix信號(hào),并將其傳遞,然后執(zhí)行一些更多的工作:

#!/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"

如果使用docker run -it -rm -p 80:80運(yùn)行此鏡像--name test apache,則可以使用docker exec或docker top檢查容器的進(jìn)程,然后讓腳本停止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                COMMAND10035               root                {run.sh} /bin/sh /run.sh 123 cmd cmd210054               root                /usr/sbin/apache2 -k start10055               33                  /usr/sbin/apache2 -k start10056               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設(shè)置,但是這只能將二進(jìn)制設(shè)置為exec(不會(huì)使用sh -c)。 注意:exec表單被解析為JSON數(shù)組,這意味著您必須在單詞(而非單引號(hào)('))周圍使用雙引號(hào)(“)。 注意:與shell形式不同,exec形式不會(huì)調(diào)用命令shell。 這意味著正常的shell處理不會(huì)發(fā)生。 例如,ENTRYPOINT [“echo”,“$ HOME”]不會(huì)在$ HOME上進(jìn)行變量替換。 如果您想要進(jìn)行shell處理,那么可以使用shell窗體或直接執(zhí)行shell,例如:ENTRYPOINT [“sh”,“-c”,“echo $ HOME”]。 當(dāng)使用exec表單并直接執(zhí)行一個(gè)shell時(shí)(如shell格式的情況),它是在執(zhí)行環(huán)境變量擴(kuò)展的shell,而不是docker。

Shell form ENTRYPOINT示例

您可以為ENTRYPOINT指定一個(gè)純字符串,它將在/ bin / sh -c中執(zhí)行。 該表單將使用shell處理來替換shell環(huán)境變量,并且將忽略任何CMD或docker run命令行參數(shù)。 為了確保docker stop會(huì)正確地告訴任何長(zhǎng)時(shí)間運(yùn)行的ENTRYPOINT可執(zhí)行文件,你需要記住用exec來啟動(dòng)它:

FROM ubuntu
ENTRYPOINT exec top -b

當(dāng)你運(yùn)行這個(gè)圖像時(shí),你會(huì)看到單個(gè)PID 1進(jìn)程:

$ 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

如果您忘記將EXEC添加到入口點(diǎn)的開頭:

FROM ubuntu
ENTRYPOINT top -b
CMD --ignored-param1

然后你可以運(yùn)行它(給它下一步的名字):

$ 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

您可以從輸出中top看到指定ENTRYPOINT的不是PID 1。

如果你然后運(yùn)行docker stop test,那么容器不會(huì)干凈地退出 - 在超時(shí)之后,stop命令將被迫發(fā)送一個(gè)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和進(jìn)入點(diǎn)如何交互

兩者CMDENTRYPOINT指令都定義了運(yùn)行容器時(shí)執(zhí)行的命令。有幾條規(guī)則描述了他們的合作。

  1. Dockerfile應(yīng)至少指定一個(gè)CMDENTRYPOINT命令。

  2. ENTRYPOINT 應(yīng)該在使用容器作為可執(zhí)行文件時(shí)定義。

  3. CMD應(yīng)該用作為ENTRYPOINT命令定義默認(rèn)參數(shù)或在容器中執(zhí)行ad-hoc命令的一種方式。

  4. CMD 在使用替代參數(shù)運(yùn)行容器時(shí)將被覆蓋。

下表顯示了針對(duì)不同ENTRYPOINT/ CMD組合執(zhí)行的命令:


No ENTRYPOINT

ENTRYPOINT exec_entry p1_entry

ENTRYPOINT “exec_entry”, “p1_entry”

No CMD

error, not allowed

/bin/sh -c exec_entry p1_entry

exec_entry p1_entry

CMD “exec_cmd”, “p1_cmd”

exec_cmd p1_cmd

/bin/sh -c exec_entry p1_entry

exec_entry p1_entry exec_cmd p1_cmd

CMD “p1_cmd”, “p2_cmd”

p1_cmd p2_cmd

/bin/sh -c exec_entry p1_entry

exec_entry p1_entry p1_cmd p2_cmd

CMD exec_cmd p1_cmd

/bin/sh -c exec_cmd p1_cmd

/bin/sh -c exec_entry p1_entry

exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

VOLUME

VOLUME ["/data"]

VOLUME指令創(chuàng)建一個(gè)具有指定名稱的掛載點(diǎn),并將其標(biāo)記為從本機(jī)主機(jī)或其他容器中存儲(chǔ)外部安裝的卷。 該值可以是JSON數(shù)組,VOLUME [“/ var / log /”]或具有多個(gè)參數(shù)的純字符串,例如VOLUME / var / log或VOLUME / var / log / var / db。 有關(guān)通過Docker客戶端的更多信息/示例和安裝說明,請(qǐng)參閱通過卷文檔共享目錄。

docker run命令使用基礎(chǔ)映像中指定位置存在的任何數(shù)據(jù)初始化新創(chuàng)建的卷。例如,請(qǐng)考慮以下Dockerfile代碼片段:

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

此Dockerfile導(dǎo)致導(dǎo)致docker運(yùn)行的映像,在/ myvol處創(chuàng)建新的掛載點(diǎn),并將問候語文件復(fù)制到新創(chuàng)建的卷中。

有關(guān)指定卷的說明

記住Dockerfile中的卷的以下幾點(diǎn)。

  • 基于Windows的容器上的卷:使用基于Windows的容器時(shí),容器內(nèi)的卷的目標(biāo)必須是以下之一:

- a non-existing or empty directory- a drive other than `C:`
  • 在Dockerfile中更改卷:如果任何構(gòu)建步驟在聲明后更改了卷內(nèi)的數(shù)據(jù),則這些更改將被丟棄。

  • JSON格式:列表被解析為JSON數(shù)組。您必須用雙引號(hào)(")括住單詞而不是單引號(hào)(')。

  • 主機(jī)目錄在容器運(yùn)行時(shí)聲明:主機(jī)目錄(掛載點(diǎn))本質(zhì)上是與主機(jī)相關(guān)的。這是為了保持圖像的可移植性。因?yàn)闊o法保證給定的主機(jī)目錄在所有主機(jī)上都可用。因此,您無法從Dockerfile中掛載主機(jī)目錄。該VOLUME指令不支持指定host-dir參數(shù)。您必須在創(chuàng)建或運(yùn)行容器時(shí)指定安裝點(diǎn)。

USER

USER <user>[:<group>] or
USER <UID>[:<GID>]

USER指令設(shè)置用戶名(或UID)和可選的用戶組(或GID),以在運(yùn)行映像時(shí)以及在Dockerfile中執(zhí)行后續(xù)的任何RUN,CMD和ENTRYPOINT指令。

警告:當(dāng)用戶確實(shí)沒有主組時(shí),圖像(或下一個(gè)指令)將與root組一起運(yùn)行。

WORKDIR

WORKDIR /path/to/workdir

WORKDIR指令為Dockerfile中后面的任何RUN,CMD,ENTRYPOINT,COPY和ADD指令設(shè)置工作目錄。 如果WORKDIR不存在,即使未在任何后續(xù)的Dockerfile指令中使用它,它也將被創(chuàng)建。

WORKDIR指令可以在Dockerfile中多次使用。 如果提供了相對(duì)路徑,它將相對(duì)于以前的WORKDIR指令的路徑。 例如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

最終的輸出pwd命令Dockerfile將是/a/b/c。

WORKDIR指令可以解析先前使用ENV設(shè)置的環(huán)境變量。 您只能使用在Dockerfile中顯式設(shè)置的環(huán)境變量。 例如:

ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

此Dockerfile中最終pwd命令的輸出將是/ path / $ DIRNAME

ARG

ARG <name>[=<default value>]

ARG指令定義了一個(gè)變量,用戶可以使用--build-arg <varname> = <value>標(biāo)志在構(gòu)建器中通過docker build命令將其傳遞給構(gòu)建器。 如果用戶指定了Dockerfile中未定義的構(gòu)建參數(shù),則構(gòu)建會(huì)輸出警告。

[Warning] One or more build-args [foo] were not consumed.

Dockerfile可能包含一條或多ARG條指令。例如,以下是有效的Dockerfile:

FROM busybox
ARG user1
ARG buildno...

警告:建議不要使用構(gòu)建時(shí)變量來傳遞github密鑰,用戶憑據(jù)等秘密。構(gòu)建時(shí)變量值對(duì)于具有docker history命令的圖像的任何用戶都是可見的。

默認(rèn)值

ARG指令可以可選地包括一個(gè)默認(rèn)值:

FROM busybox
ARG user1=someuser
ARG buildno=1...

如果ARG指令具有默認(rèn)值,并且在構(gòu)建時(shí)沒有值傳遞,那么構(gòu)建器將使用默認(rèn)值。

Scope

一個(gè)ARG變量定義從它在其中定義的行開始生效,而Dockerfile不是來自參數(shù)在命令行或其他地方使用的行。例如,考慮這個(gè)Dockerfile:

1 FROM busybox2 USER ${user:-some_user}3 ARG user4 USER $user...

用戶通過調(diào)用以下命令構(gòu)建該文件:

$ docker build --build-arg user=what_user .

第2行的用戶評(píng)估為some_user,因?yàn)橛脩糇兞渴窃诤罄m(xù)行3上定義的。第4行的用戶評(píng)估為用戶定義的what_user,并在命令行上傳遞了what_user值。 在通過ARG指令定義之前,任何使用變量都會(huì)導(dǎo)致一個(gè)空字符串。

ARG指令在構(gòu)建階段結(jié)束時(shí)超出了范圍。 要在多個(gè)階段使用arg,每個(gè)階段都必須包含ARG指令。

FROM busybox
ARG SETTINGS
RUN ./run/setup $SETTINGS

FROM busybox
ARG SETTINGS
RUN ./run/other $SETTINGS

使用ARG變量

您可以使用ARG或ENV指令來指定RUN指令可用的變量。 使用ENV指令定義的環(huán)境變量總是覆蓋相同名稱的ARG指令。 用ENV和ARG指令考慮這個(gè)Dockerfile。

1 FROM ubuntu2 ARG CONT_IMG_VER3 ENV CONT_IMG_VER v1.0.04 RUN echo $CONT_IMG_VER

然后,假設(shè)這個(gè)圖像是用這個(gè)命令建立的:

$ docker build --build-arg CONT_IMG_VER=v2.0.1 .

在這種情況下,RUN指令使用v1.0.0而不是用戶傳遞的ARG設(shè)置:v2.0.1這種行為類似于shell腳本,其中本地作用域變量覆蓋作為參數(shù)傳遞的變量或從環(huán)境繼承的變量, 定義點(diǎn)。

使用上面的示例但不同的ENV規(guī)范,您可以在ARG和ENV指令之間創(chuàng)建更多有用的交互:

1 FROM ubuntu2 ARG CONT_IMG_VER3 ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0}4 RUN echo $CONT_IMG_VER

與ARG指令不同,ENV值始終保留在構(gòu)建的映像中。 考慮一個(gè)沒有--build-arg標(biāo)志的docker build:

$ docker build .

使用這個(gè)Dockerfile示例,CONT_IMG_VER仍然保留在圖像中,但其值為v1.0.0,因?yàn)樗荅NV指令在第3行默認(rèn)設(shè)置的值。

本例中的變量擴(kuò)展技術(shù)允許您通過命令行傳遞參數(shù),并通過利用ENV指令將它們保存在最終圖像中。 變量擴(kuò)展僅支持有限的Dockerfile指令集。

預(yù)定義的ARG

Docker有一組預(yù)定義的ARG變量,您可以在Dockerfile中使用沒有相應(yīng)的ARG指令的變量。

  • HTTP_PROXY

  • http_proxy

  • HTTPS_PROXY

  • https_proxy

  • FTP_PROXY

  • ftp_proxy

  • NO_PROXY

  • no_proxy

要使用這些,只需使用標(biāo)志在命令行上傳遞它們即可:

--build-arg <varname>=<value>

默認(rèn)情況下,這些預(yù)定義的變量將從Docker歷史記錄的輸出中排除。 將它們排除在外可以減少在HTTP_PROXY變量中意外泄漏敏感身份驗(yàn)證信息的風(fēng)險(xiǎn)。

For example, consider building the following Dockerfile using --build-arg HTTP_PROXY=http://user:pass@proxy.lon.example.com

FROM ubuntu
RUN echo "Hello World"

在這種情況下,HTTP_PROXY變量的值在Docker歷史記錄中不可用,并且不會(huì)被緩存。 如果您要更改位置,并且您的代理服務(wù)器更改為http:// user:pass@proxy.sfo.example.com,則后續(xù)構(gòu)建不會(huì)導(dǎo)致緩存未命中。

如果您需要重寫此行為,則可以通過在Dockerfile中添加ARG語句來執(zhí)行此操作,如下所示:

FROM ubuntu
ARG HTTP_PROXY
RUN echo "Hello World"

構(gòu)建此Dockerfile時(shí),HTTP_PROXY將保留在Docker歷史記錄中,并且更改其值可使構(gòu)建緩存失效。

對(duì)構(gòu)建緩存的影響

作為ENV變量,ARG變量不會(huì)保留在構(gòu)建的映像中。 但是,ARG變量確實(shí)會(huì)以類似的方式影響構(gòu)建緩存。 如果一個(gè)Dockerfile定義了一個(gè)ARG變量,它的值與以前的版本不同,那么第一次使用時(shí)會(huì)發(fā)生“緩存未命中”,而不是其定義。 尤其是,遵循ARG指令的所有RUN指令都隱式使用ARG變量(作為環(huán)境變量),因此可能導(dǎo)致緩存未命中。 除非在Dockerfile中存在匹配的ARG語句,否則所有預(yù)定義的ARG變量都可以免于緩存。

例如,考慮這兩個(gè)Dockerfile:

1 FROM ubuntu2 ARG CONT_IMG_VER3 RUN echo $CONT_IMG_VER
1 FROM ubuntu2 ARG CONT_IMG_VER3 RUN echo hello

如果在命令行中指定--build-arg CONT_IMG_VER = <value>,則在這兩種情況下,第2行上的規(guī)范不會(huì)導(dǎo)致緩存未命中; 第3行確實(shí)導(dǎo)致緩存未命中.ARG CONT_IMG_VER導(dǎo)致RUN行被識(shí)別為與運(yùn)行CONT_IMG_VER = <value> echo hello相同,因此如果<value>發(fā)生更改,則會(huì)導(dǎo)致緩存未命中。

考慮同一命令行下的另一個(gè)示例:

1 FROM ubuntu2 ARG CONT_IMG_VER3 ENV CONT_IMG_VER $CONT_IMG_VER4 RUN echo $CONT_IMG_VER

在此示例中,第3行發(fā)生高速緩存未命中。發(fā)生未命中是因?yàn)镋NV中的變量值引用了ARG變量,并且該變量通過命令行進(jìn)行了更改。 在此示例中,ENV命令會(huì)使圖像包含該值。

如果ENV指令覆蓋ARG同名的指令,就像這個(gè)Dockerfile一樣:

1 FROM ubuntu2 ARG CONT_IMG_VER3 ENV CONT_IMG_VER hello4 RUN echo $CONT_IMG_VER

第3行不會(huì)導(dǎo)致緩存缺失,因?yàn)镃ONT_IMG_VER的值是常量(hello)。 因此,RUN(第4行)上使用的環(huán)境變量和值在構(gòu)建之間不會(huì)更改。

ONBUILD

ONBUILD [INSTRUCTION]

當(dāng)圖像被用作另一個(gè)構(gòu)建的基礎(chǔ)時(shí),ONBUILD指令為圖像添加一個(gè)稍后執(zhí)行的觸發(fā)指令。 觸發(fā)器將在下游構(gòu)建的上下文中執(zhí)行,就好像它已經(jīng)在下游Dockerfile中的FROM指令之后立即插入一樣。

任何構(gòu)建指令都可以注冊(cè)為觸發(fā)器。

如果您正在構(gòu)建將用作構(gòu)建其他圖像的基礎(chǔ)的圖像(例如應(yīng)用程序構(gòu)建環(huán)境或可使用用戶特定配置進(jìn)行自定義的守護(hù)程序),這非常有用。

例如,如果您的映像是可重用的Python應(yīng)用程序構(gòu)建器,則需要將應(yīng)用程序源代碼添加到特定目錄中,并且可能需要在此之后調(diào)用構(gòu)建腳本。 您現(xiàn)在不能僅僅調(diào)用ADD和RUN,因?yàn)槟€沒有訪問應(yīng)用程序源代碼,并且每個(gè)應(yīng)用程序構(gòu)建都會(huì)有所不同。 您可以簡(jiǎn)單地向應(yīng)用程序開發(fā)人員提供樣板Dockerfile以復(fù)制粘貼到他們的應(yīng)用程序中,但效率低下,容易出錯(cuò)并且難以更新,因?yàn)樗c特定于應(yīng)用程序的代碼混合在一起。

解決方案是使用ONBUILD注冊(cè)先行指令在稍后的構(gòu)建階段運(yùn)行。

以下是它的工作原理:

  1. 當(dāng)它遇到ONBUILD指令時(shí),構(gòu)建器會(huì)為正在構(gòu)建的映像的元數(shù)據(jù)添加一個(gè)觸發(fā)器。 該指令不會(huì)影響當(dāng)前的構(gòu)建。

  2. 在構(gòu)建結(jié)束時(shí),所有觸發(fā)器的列表都存儲(chǔ)在圖像清單中的OnBuild鍵下。 可以使用docker inspect命令檢查它們。

  3. 稍后,可以使用FROM指令將圖像用作新構(gòu)建的基礎(chǔ)。 作為處理FROM指令的一部分,下游構(gòu)建器會(huì)查找ONBUILD觸發(fā)器,并按照它們的注冊(cè)順序執(zhí)行它們。 如果任何觸發(fā)器失敗,那么FROM指令將中止,從而導(dǎo)致構(gòu)建失敗。 如果所有觸發(fā)器都成功,則FROM指令完成并且構(gòu)建繼續(xù)照常。

  4. 觸發(fā)器在執(zhí)行后從最終圖像中清除。 換句話說,它們不會(huì)被“grand-children”構(gòu)建遺傳。

例如,你可能會(huì)添加如下內(nèi)容:

[...]ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src[...]

警告:不允許使用ONBUILD ONBUILD鏈接ONBUILD指令。 警告:ONBUILD指令可能不會(huì)觸發(fā)FROM或MAINTAINER指令。

STOPSIGNAL

STOPSIGNAL signal

STOPSIGNAL指令設(shè)置將被發(fā)送到容器的系統(tǒng)呼叫信號(hào)以退出。這個(gè)信號(hào)可以是一個(gè)有效的無符號(hào)數(shù)字,與內(nèi)核syscall表中的位置相匹配,例如9,或者SIGNAME格式的信號(hào)名稱,例如SIGKILL。

HEALTHCHECK

HEALTHCHECK指令有兩種形式:

  • HEALTHCHECK [OPTIONS] CMD command (通過在容器中運(yùn)行一個(gè)命令來檢查容器的健康狀況)

  • HEALTHCHECK NONE (禁用從基礎(chǔ)映像繼承的任何健康檢查)

HEALTHCHECK指令告訴Docker如何測(cè)試容器以檢查它是否仍在工作。這可以檢測(cè)到一些情況,例如即使服務(wù)器進(jìn)程仍在運(yùn)行,仍停留在無限循環(huán)中但無法處理新連接的Web服務(wù)器。

當(dāng)容器指定了健康狀況檢查時(shí),除了正常狀態(tài)之外,它還具有健康狀態(tài)。這是最初的狀態(tài)starting。每當(dāng)健康檢查通過時(shí),就會(huì)變成healthy(無論以前處于何種狀態(tài))。經(jīng)過一定次數(shù)的連續(xù)失敗后,它變成了unhealthy。

之前可以顯示的選項(xiàng)CMD是:

  • --interval=DURATION(默認(rèn)值:30s

  • --timeout=DURATION(默認(rèn)值:30s

  • --start-period=DURATION(默認(rèn)值:0s

  • --retries=N(默認(rèn)值:3

運(yùn)行狀況檢查將首先在容器啟動(dòng)后的間隔秒內(nèi)運(yùn)行,然后在每次前一次檢查完成后再次間隔幾秒。

如果單次運(yùn)行檢查花費(fèi)的時(shí)間超過了超時(shí)秒數(shù),那么檢查將被視為失敗。

需要重試連續(xù)的容器運(yùn)行狀況檢查失敗才會(huì)被視為不健康。

啟動(dòng)期為需要時(shí)間啟動(dòng)的容器提供初始化時(shí)間。在此期間探測(cè)失敗不會(huì)計(jì)入最大重試次數(shù)。但是,如果在啟動(dòng)期間運(yùn)行狀況檢查成功,則認(rèn)為容器已啟動(dòng),并且所有連續(xù)的故障都將計(jì)入最大重試次數(shù)。

Dockerfile中只能有一個(gè)HEALTHCHECK指令。 如果您列出多個(gè),則只有最后一個(gè)HEALTHCHECK將生效。

CMD關(guān)鍵字后面的命令可以是shell命令(例如HEALTHCHECK CMD /bin/check-running)或exec陣列(與其他Dockerfile命令一樣;請(qǐng)參閱ENTRYPOINT詳細(xì)信息)。

該命令的退出狀態(tài)指示容器的健康狀態(tài)??赡艿闹凳牵?/p>

  • 0:success - 容器健康并且可以使用

  • 1:unhealthy - 容器工作不正常

  • 2:reserved - 不要使用此退出代碼

例如,要每五分鐘檢查一次,網(wǎng)絡(luò)服務(wù)器能夠在三秒鐘內(nèi)為網(wǎng)站的主頁面提供服務(wù):

HEALTHCHECK --interval=5m --timeout=3s \
  CMD curl -f http://localhost/ || exit 1

為了幫助調(diào)試失敗的探測(cè)器,命令在stdout或stderr上寫入的任何輸出文本(UTF-8編碼)都將存儲(chǔ)在健康狀態(tài)中,并且可以使用它進(jìn)行查詢docker inspect。這樣的輸出應(yīng)該保持很短(目前僅存儲(chǔ)前4096個(gè)字節(jié))。

當(dāng)容器的健康狀況發(fā)生變化時(shí),health_status會(huì)生成一個(gè)新狀態(tài)的事件。

HEALTHCHECK功能添加到Docker 1.12中。

SHELL

SHELL ["executable", "parameters"]

SHELL指令允許覆蓋用于shell命令形式的默認(rèn)shell。 Linux上的默認(rèn)shell為[“/ bin / sh”,“-c”],在Windows上為[“cmd”,“/ S”,“/ C”]。 SHELL指令必須以JSON格式寫入Dockerfile中。

SHELL指令在Windows中有兩個(gè)常用且完全不同的本機(jī)shell特別有用:cmd和powershell,以及可用的備用shell,包括sh。

SHELL指令可以出現(xiàn)多次。 每個(gè)SHELL指令都會(huì)覆蓋所有先前的SHELL指令,并影響后面的所有指令。 例如:

FROM microsoft/windowsservercore

# Executed as cmd /S /C echo defaultRUN echo default# Executed as cmd /S /C powershell -command Write-Host defaultRUN 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

當(dāng)它們的shell形式在Dockerfile中使用時(shí),以下指令可能受到SHELL指令的影響:RUN,CMD和ENTRYPOINT。

以下示例是Windows上可以通過使用該SHELL指令簡(jiǎn)化的常見模式:

...RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"...

docker調(diào)用的命令是:

cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

這是無效的,原因有兩個(gè)。 首先,調(diào)用一個(gè)不必要的cmd.exe命令處理器(aka shell)。 其次,shell格式中的每條RUN指令都需要在命令前加上一個(gè)額外的powershell命令。

為了提高效率,可以采用兩種機(jī)制之一。一種是使用RUN命令的JSON格式,例如:

...RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]...

盡管JSON格式是明確的,并且不使用不必要的cmd.exe,但它通過雙引號(hào)和轉(zhuǎn)義確實(shí)需要更多的冗長(zhǎng)。另一種機(jī)制是使用SHELL指令和shell形式,為Windows用戶提供更自然的語法,尤其是與escape解析器指令結(jié)合使用時(shí):

# 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'

導(dǎo)致:

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指令也可以用來修改shell的運(yùn)行方式。 例如,在Windows上使用SHELL cmd / S / C / V:ON | OFF,可以修改延遲的環(huán)境變量擴(kuò)展語義。

SHELL指令也可用于Linux,如果需要備用shell,如zsh,csh,tcsh等。

SHELL功能添加到Docker 1.12中。

Dockerfile示例

下面你可以看到一些Dockerfile語法的例子。如果您對(duì)更真實(shí)的東西感興趣,請(qǐng)查看Dockerization示例列表。

# Nginx
#
# VERSION               0.0.1FROM      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.3FROM 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 5900CMD    ["x11vnc", "-forever", "-usepw", "-create"]
# Multiple images example
#
# VERSION               0.1FROM 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.
Previous article: Next article: