Docker学习笔记五:Dockerfile

通用参考和推荐

docker build命令使用Dockerfile或者上下文构建镜像,构建上下文是指定的本地路径或者URL的文件。本地路径是本地文件系统的目录,URL是本地的Git仓库。构建是由Docker守护进程运行的,而不是CLI。构建过程首先要做的就是把整个上下文递归的传给守护进程,强烈建议在一个空目录下进行构建过程。

  • 容器应该是短暂的
  • 使用一个.dokerignore文件
  • 避免安装不必要的包
  • 每个容器只运行一个进程
  • 最小化层的数量
  • 多行参数排序
  • 建立缓存

Dockerfile指令

格式:

# Commnet
INSTRUCTION arguments

INSTRUCTION(指令)大小写不敏感,但约定使用大写。

环境变量:

环境变量的格式可以是 $variable_name 或者 ${variable_name}${variable:-word}表示如果variable设置了,结果将是那个值,如果没有设置,则
结果是word;${variable:+word} 表示如果设置了variable,结果将是word,如果没有设置,则结果为空。

FROM

FROM <image>

OR

FROM <image>:<tag>

OR

FROM <image>@<digest>

FROM指令为后面的指令设置基础镜像。一个有效的Dockerfile文件必须以FROM作为第一条非注释指令。

MAINTAINER

MAINTAINER <name>

设置生成的镜像的Author字段

RUN

RUN有两种格式:

  • RUN <command> shell格式,这个命令在shell中执行,Linux中默认是/bin/sh -c,windows系统默认是cmd /S /C
  • RUN ["executable", "param1", "param2"] exec格式

RUN指令将在当前镜像的新的一层执行任何命令并提交结果。

apt-get

避免执行apt-get upgradedist-upgrade,因为许多基础镜像中的必须包不会在特权容器中升级。

CMD

CMD有三种格式:

  • CMD ["executable", "param1", "param2"] exec格式,首选的格式
  • CMD ["param1", "param2"] 作为ENTRYPOINT的默认参数
  • CMD command param1 param2 shell格式

CMD的主要目的是为执行容器提供默认值。这些默认值可以包含可执行文件,或它们可以忽略可执行文件,在这种情况下,必须指定ENTRYPOINT指令。

当使用shell格式或exec格式时,CMD指令设置的命令将会在运行容器时执行。使用JSON数组声明一个命令是,必须使用执行文件的绝对路径。

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

在一个Dockerfile文件中只允许有一条CMD指令,如果有多条CMD指令,那么最后一条CMD指令生效。如果用户在执行docker run命令是指定了参数,那么将覆盖CMD指定的默认值。

注意: exec格式作为JSON数组的格式被解析,因此必须使用双引号将单词引起来,而不是单引号。

RUNCMD的区别:RUN实际上在构建镜像过程中运行命令并提交结果;CMD在构建镜像过程中不执行任何操作,但指定了预执行命令(即在运行镜像时执行)。

LABEL

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

Docker可以指定多个标签,每个标签产生一个新层,多个层会导致效率低下,因此建议将多个标签合并到一个标签:

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

或:

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

查看镜像的LABEL可以使用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"
},

EXPOSE

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

EXPOSE指令通知Docker容器在运行时监听的端口。

ENV

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

ENV指令设置环境变量的值为。第二种格式可以设置多个键值对,推荐在一条ENV指令中设置多个键值对,因为这样产生一个缓存层。

ADD

  • ADD …
  • ADD [“”,… “”] 对于包含空格的路径,使用这种格式

ADD指令复制新文件、目录或远程文件URL并添加他们到容器的文件系统路径,可以指定多个。每个可以包含通配符。

所有的新文件或目录使用UID和GID为0创建。如果是一个远程文件URL,目标将会是600的权限。如果远程文件有HTTP Last-Modified头,这个HTTP头部的时间戳将用于设置目标文件的mtime。

ADD指令遵循以下规则:

  • 必须包含在构建的上下文中,不能使用ADD ../something /something
  • 如果是一个URL,不是以斜杠结束,文件将被从URL下载并拷贝到。
  • 如果是一个URL,以斜杠结束,文件名将从URL中获取,文件被下载到/。例如:ADD http://example.com/foobar /将会创建文件/foobar。不能是http://example.com类的URL。
  • 如果是目录,目录的所有内容将被复制,包括文件系统元数据(目录本身不复制,只是它的内容)。
  • 如果是一个gzip,bzip2或者xz类型的压缩归档文件,文件将被作为一个目录解压。远程URL文件不会被解压。如果一个目录被复制或者解压,与tar -x的行为相同:结果唯一:
    1、无论在目标路径是否存在和
    2、源目录树的内容,冲突以逐个文件为基础解析为”2.”

注意:文件是否被识别为识别的压缩格式仅基于文件的内容,而不是文件的文件名。例如:一个空文件以.tar.gz结尾,则不会被识别为压缩文件,并且不会生成任何解压缩错误消息,而是该文件将被文件简单的复制到目的地。

  • 如果是其他类型的文件,它将于它的元数据一起单独的复制。在这种情况下,如果以/结尾,它将被认为是目录,的内容将被写在/base()。
  • 如果指定了多个,无论是直接或使用通配符,必须是目录,并且以/结束。
  • 如果不是以斜杠结束,将会被认作是一个常规文件,的内容将被写入。
  • 如果不存在,所有在路径中不存在的目录将会被创建。

COPY

  • COPY <src>... <dest>
  • COPY ["<src>",... "<dest>"] 路径中包含空格时需要这种格式

COPY指令从复制新文件文件或目录并添加它们到容器的文件系统路径。是一个绝对路径,或者相对WORKDIR的路径,其中源将被复制到目标容器内。

COPY test relativeDir/   # 添加 "test" 到 `WORKDIR`/relativeDir/
COPY test /absoluteDir/  # 添加 "test" 到 /absoluteDir/

所有的文件和目录以UID和GID 0 创建。

COPY遵循如下规则:

  • 路径必须在构建的上下文中,不能使用COPY ../something /something
  • 如果是一个目录,目录的所有内容包括元数据将会被复制。

注意:目录本身不会被复制,只有它的内容。

  • 如果是其他类型的文件,它将于它的元数据一起被单独复制。这种情况下,如果以斜杠/结束,它将会被认作是目录,的内容将被写在/base()。
  • 如果指定了多个,或者直接或者使用通配符,必须是目录,且以/结束。
  • 如果没有以斜杠结束,将会认作是一般文件,并且的内容将被写入。
  • 如果不存在,所有在路径中不存在的目录将会被创建。

ENTRYPOINT

  • ENTRYPOINT ["executable", "param1", "param2"] exec格式,推荐
  • ENTRYPOINT command param1 param2 shell格式

ENTRYPOINT允许配置容器作为可执行文件运行。

例如,下面的例子将会以默认内容启动nginx,监听端口80:

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

docker run <image>的命令行参数将附加在exec格式的ENTRYPOINT中的所有元素之后,并将覆盖使用CMD指令所有元素。这允许将参数传递到入口点,例如:docker run <iamge> -d将把-d参数传给入口点,可以使用–entrypoint标志覆盖ENTRYPOINT指令。

shell形式防止使用任何CMD或者运行命令行参数,但是缺点是ENTRYPOINT将作为/bin/sh -c的子命令启动,不传递信号。这意味着可执行文件将不是容器的PID 1,并且不接收Unix信号,因此您的可执行文件将不会从docker stop <container>接收到SIGTERM。

只有Dockerfile文件的最后一条ENTRYPOINT指令生效。

CMD和ENTRYPOINT是如何互相影响的

1、Dockerfile应该至少指定一个CMD或者ENTRYPOINT命令
2、当使用容器作为可执行文件使用时,应该定义ENTRYPOINT
3、CMD应该用作定义ENTRYPOINT命令的默认参数或在容器中执行ad-hoc命令的一种方法
4、当运行带有替代参数的容器时,CMD将被覆盖

下表显示了对不同ENTRYPOINT/CMD组合执行的命令:

No ENTRYPOINTENTRYPOINT exec_entry p1_entryENTRYPOINT [“exec_entry”, “p1_entry”]
No CMDerror,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 exec_cmd p1_cmd
CMD [“p1_cmd”, “p2_cmd”]p1_cmd p2_cmd/bin/sh -c 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 /bin/sh -c exec_cmd p1_cmd

VOLUME

VOLUME ["/data"]

VOLUME命令创建指定名称的挂载点,并将其标记为从本地主机或者其他容器保留外部挂载的卷。该值可以是JSON数组或者具有多个参数的纯字符串。

USER

USER daemon

USER指令设置在运行镜像时使用的用户名或UID,以及Dockerfile中任何RUNCMDENTRYPOINT指令的用户名。

WORKDIR

WORKDIR /path/to/worddir

WORKDIR用来设置在Dockerfile文件中接下来的RUNCMDENTRYPOINTCOPYADD等指令的工作目录。如果不存在,将会被创建,即使以后的Dockerfile指令都不使用。

通过Dockerfile创建镜像

制作Dockerfile文件

1、创建工程目录

$ mkdir mydockerbuilder

2、进入工程目录,创建Dockerfile

$ cd mydockerbuilder && touch Dockerfile

3、编写Dockerfile

$ vim Dockerfile

FROM docker/whaleasy:latest
RUN apt-get -y update && apt-get install -y fortunes
CMD /usr/games/fortune -a | cowsay

三行内容分别为:

指定基础镜像,即基于whaleasy:latest创建新镜像

更新镜像并安装fortunes引用程序

镜像加载后执行的命令

4、创建镜像

$ docker build -t docker-whale .
Sending build context to Docker daemon 2.048 kB
...snip...
Removing intermediate container a8e6faa88df3
Successfully built 7d9495d03763

镜像的创建过程

docker build -t docker-whale .命令使用当前目录下的Dockerfile文件制作一个叫docker-whale的镜像。制作过程中出现的信息含义如下:

首先Docker检查以确保它有它需要构建的一切。

Sending build context to Docker daemon 2.048 kB

然后Docker加载whalesay:latest镜像,如果本地没有,Docker将会下载此镜像。

Step 1 : FROM docker/whalesay:latest
 ---> fb434121fc77

接下来Docker使用apt-get包管理器更新包并安装fortunes

Step 2 : RUN apt-get -y update && apt-get install -y fortunes
 ---> Running in 27d224dfa5b2
Ign http://archive.ubuntu.com trusty InRelease
Ign http://archive.ubuntu.com trusty-updates InRelease
Ign http://archive.ubuntu.com trusty-security InRelease
Hit http://archive.ubuntu.com trusty Release.gpg
....snip...
Get:15 http://archive.ubuntu.com trusty-security/restricted amd64 Packages [14.8 kB]
Get:16 http://archive.ubuntu.com trusty-security/universe amd64 Packages [134 kB]
Reading package lists...
---> eb06e47a01d2

Reading package lists...
Building dependency tree...
Reading state information...
The following extra packages will be installed:
  fortune-mod fortunes-min librecode0
Suggested packages:
  x11-utils bsdmainutils
The following NEW packages will be installed:
  fortune-mod fortunes fortunes-min librecode0
0 upgraded, 4 newly installed, 0 to remove and 3 not upgraded.
Need to get 1961 kB of archives.
After this operation, 4817 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu/ trusty/main librecode0 amd64 3.6-21 [771 kB]
...snip......
Setting up fortunes (1:1.99.1-7) ...
Processing triggers for libc-bin (2.19-0ubuntu6.6) ...
 ---> c81071adeeb5
Removing intermediate container 23aa52c1897c

最后Docker完成构建并报告结果:

Step 3 : CMD /usr/games/fortune -a | cowsay
 ---> Running in a8e6faa88df3
 ---> 7d9495d03763
Removing intermediate container a8e6faa88df3
Successfully built 7d9495d03763
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当然,我会帮助你记录和学习Docker的知识点。下面是一份Docker学习笔记: 1. 什么是DockerDocker是一个开源的容器化平台,可以帮助开发者创建、打包、部署和运行应用程序,使应用程序可以在不同的环境无缝运行。 2. Docker的优势有哪些? - 轻量化:Docker容器与虚拟机相比更加轻量级,启动和停止速度更快。 - 可移植性:Docker容器可以在任何支持Docker的平台上运行,无需担心环境不一致的问题。 - 隔离性:Docker使用容器技术进行隔离,每个容器之间相互独立,不会相互影响。 - 效率:Docker可以将应用程序及其依赖项打包为一个镜像,部署和扩展非常方便。 3. Docker常用的概念: - 镜像(Image):一个只读的模板,包含了运行应用程序所需的所有文件和依赖项。 - 容器(Container):基于镜像创建的可执行实例,可以运行、停止、删除等操作。 - 仓库(Registry):用于存储和分享镜像的地方,常用的有Docker Hub。 - Dockerfile:用于定义镜像构建过程的文本文件,包含了一系列的指令和配置。 4. Docker基本使用命令: - `docker pull <image-name>`:从仓库拉取指定镜像。 - `docker run <image-name>`:创建并运行一个新的容器。 - `docker ps`:查看当前正在运行的容器。 - `docker stop <container-id>`:停止指定容器的运行。 - `docker rm <container-id>`:删除指定容器。 - `docker rmi <image-name>`:删除指定镜像。 5. Docker常见应用场景: - 镜像管理:可以通过Docker镜像进行应用程序开发、测试和部署。 - 微服务架构:通过容器化实现应用程序的模块化,方便管理和扩展。 - CI/CD:在持续集成和持续部署过程使用Docker来构建、测试和发布应用程序。 这些是Docker学习过程的一些基础知识点和常用命令。希望对你有帮助!如果你还有其他问题,可以随时问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wooowlili

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值