Docker(七)Dockerfile

本文详细介绍Dockerfile的组成及常用指令,包括基础镜像信息、维护者信息、镜像操作指令和容器启动指令等。同时提供了如何使用Dockerfile创建镜像的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dockerfile 由一行行命令语句组成,并且支持以#开头的注释行。一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

如果使用Dockerfile来构建镜像,Dockerfile的第一条有效信息(注释除外)必须是基础镜像信息,维护者信息紧随其后。而镜像操作指令则在维护者信息之后因为操作指令的不同,自然会构建出千差万别的镜像来。最后是镜像启动指令,它被用作设置镜像的默认启动命令。

Dockerfile指令

指令的一般格式为 INSTRUCTION arguments ,指令包括 FROMMAINTAINERRUN 等。下面列出常用的几个指令:

FROM:
格式为 FROM <image>FROM <image>:<tag>
第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。

FROM scratch		制作基础镜像
FROM ubuntu:14.04	使用基础镜像

LABEL/MAINTAINER:

LABEL maintainer="xxx@xxx.com"
LABEL version="1.0"
LABEL description="this is description"

格式为 MAINTAINER <name> ,指定维护者信息。

RUN:
格式为 RUN <command>RUN ["executable", "param1", "param2"]
前者将在 shell 终端中运行命令,即 /bin/sh -c ;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", “-c”, “echo hello”] 。
每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行。

为避免无用分层,合并多条命令成一行,复杂的RUN用反斜线换行

EXPOSE:
格式为 EXPOSE <port> [<port>...]
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。

CMD:
支持三种格式:
CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。

ENTRYPOINT:
两种格式:

ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2 (shell中执行)。

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。每个 Dockerfile 中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。

VOLUME:
格式为 VOLUME ["/data"]
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。如果和host共享目录,Dockerfile中必须先创建一个挂载点,然后在启动容器时通过-v来挂载。

ENV:
格式为 ENV <key> <value> 。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。(尽量使用ENV增加可维护性)

ENV MYSQL_VERSION 5.6	#设置常量
RUN apt-get install -y mysql-server= "${MYSQL_VERSION}"

ADD:
格式为 ADD <src> <dest>
该命令将复制指定的 <src> 到容器中的 <dest> 。 其中 <src> 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。

COPY:
格式为 COPY <src> <dest>
复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 <dest> 。当使用本地目录为源目录时,推荐使用 COPY 。

大部分情况,COPY优于ADD!ADD除了COPY还有自动解压缩功能!添加远程文件/目录请使用curl或者wget

WORKDIR:
格式为 WORKDIR /path/to/workdir
为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

则最终路径为 /a/b/c

USER:
格式为 USER daemon
指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如: RUN groupadd -r postgres && useradd -r -g postgres postgres 。要临时获取管理员权限可以使用 gosu ,而不推荐 sudo 。

ONBUILD:
格式为 ONBUILD [INSTRUCTION]
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。

详细用法请查看:Dockerfile 指令详解
dockerfile参考:https://github.com/docker-library


20181203补充:
RUN && CMD && ENTRYPOINT
RUN:执行命令并创建新的image layer
CMD:设置容器启动后默认执行的命令和参数
ENTRYPOINT:设置容器启动时执行的命令

两种书写格式:
shell格式:

RUN apt-get install -y vim 
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"

exec格式:

RUN ["apt-get","install","-y","vim"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/echo","hello docker"]

说明:
Dockerfile1

FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"
	
-----------> hello Docker 

Dockerfile2

FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo","hello $name"]
		
-----------> hello $name
	
修改为:
ENTRYPOINT ["/bin/bash","-c","echo hello $name"]

CMD:
容器启动时默认执行的命令
如果docker run指定了其他命令,CMD命令被忽略
如果定义了多个CMD,只有最后一个会执行

ENTRYPOINT:
让容器以应用程序或者服务的形式运行
不会被忽略,一定会执行
最佳实践:写一个shell脚本作为entrypoint

COPY xxx.sh /usr/local/bin/
ENTRYPOINT ["xxx.sh"]
		
EXPOSE 27017
CMD ["mongod"]

使用Dockerfile制作镜像

使用docker build 命令给定一个Dockerfile可以制作一个镜像,其操作顺序为:

  • 解析Dockerfile,并找到基础镜像(可能会从Docker Hub上下载);
  • 以基础镜像为基础创建一个容器;
  • 在容器中顺序执行dockerfile中的命令;
  • 如果不是RUN命令,比如ENV命令,记录下来以便启动的时候执行
  • 属性命令记录在Image的属性中;
  • 所有指令执行完后,commit该容器为新的镜像。

简单例子:

新建一个目录和Dockerfile:

mkdir -p /opt/dockerfile/nginx/
cd /opt/dockerfile/nginx/
# tree
.
├── Dockerfile
└── index.html

Dockerfile 中每一条指令都创建镜像的一层,如:

# vim Dockerfile
FROM centos
RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
RUN yum install -y nginx
ADD index.html /usr/share/nginx/html/index.html
RUN echo "daemon off;" >>/etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx"]

编写完成 Dockerfile 后可以使用 docker build 来生成镜像。

docker build -t localhost/nginx:v1 /opt/dockerfile/nginx/

查看镜像:

# docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
localhost/nginx              v1                  1f18116982c3        2 minutes ago       378 MB
...

后台启动,这时候我们访问服务器的80端口,返回的就是index.html的页面了

docker run -d -p 80:80 localhost/nginx:v1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值