Dockerfile

2023-03-17 11:04:02 浏览数 (1)

文章目录

    • Dockerfile
      • Docker镜像构建
        • 1、docker commit制作镜像(不建议)
        • 2、基于本地模板导入
        • 3、Dockerfile制作镜像
          • 3.1 Dockerfile简介
          • 3.2 docker build命令
          • 3.3 Dockerfile镜像构建指令
        • 4、Dockerfile案例

Dockerfile

Docker镜像构建

Docker镜像可以通过Docker hub仓库中获取,这些镜像是由官方或者社区人员提供的,对于Docker用户来说并不能满足我们的需求,但是从无开始构建镜像成本大。常用的数据库、中间件、应用软件等都有现成的Docker官方镜像或社区创建的镜像,我们只需要稍作配置就可以直接使用。

使用现成镜像的好处除了省去自己做镜像的工作量外,更重要的是可以利用前人的经验。特别是使用那些官方镜像,因为Docker的工程师知道如何更好的在容器中运行软件。

当然,某些情况下我们也不得不自己构建镜像,比如找不到现成的镜像,比如自己开发的应用程序,需要在镜像中加入特定的功能。

Docker提供了三种构建镜像的方法:

  • docker commit制作镜像
  • 基于本地模板导入
  • Dockerfile制作镜像
1、docker commit制作镜像(不建议)

docker commit命令可以基于容器创建镜像,创建过程大致分为三步,先创建容器,在容器中安装我们所需要的内容,再使用docker commit将容器打包为镜像

代码语言:javascript复制
格式:
    docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

选项:
    --author		//指定修改的作者
    --message		//记录本次修改的内容

实例:

在centos的base镜像中安装vim-common并保存为新镜像。

代码语言:javascript复制
# 先基于centos7运行容器,容器名为zhao,并使用-it生成终端进入容器。
[root@localhost ~]#  docker run --name zhao -it centos:7
# 在容器中安装vim-common
[root@3ecc8e3777df yum.repos.d]# yum -y install vim-common
# 退出容器后,使用docker commit将zhao容器打包为镜像,新镜像名为centoscy:7
[root@localhost ~]#  docker commit zhao centoscy:7
sha256:ffaf86b4f3fc25579640aee5ac65618f47cf071fffd45874cd13d67a68f75520
[root@localhost ~]# docker images | grep centos
centoscy     7         ffaf86b4f3fc   10 seconds ago   402MB
centos       7         eeb6ee3f44bd   11 months ago    204MB

缺点:容易出错,效率低且可重复性弱,存在安全隐患

2、基于本地模板导入

用户可以直接从一个操作系统模板文件导入一个镜像,主要使用 docker [container] import 命令;要直接导入一个镜像,可以使用 OpenVZ 提供的模板来创建,或者用其他已导入的镜像模板来创建。OpenVZ 模板的下载地址为 http://openvz.org/Download/templates/precreated。

代码语言:javascript复制
格式:
		docker [image] import [OPTIONS] file|URL|-[REPOSITORY[:TAG]]

实例:

下载了 ubuntu:12.04 的模板压缩包,之后使用以下命令导入

代码语言:javascript复制
[root@zhao ~]#cat ubuntu-12.04-x86-minimal.tar.gz | docker import - ubuntu:12.04
sha256:c0676abae91df4188f3a35e0325816fadc6b1eebc3ea40dff3ca01615de037db
[root@zhao ~]#docker images 
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
ubuntu       12.04     c0676abae91d   5 seconds ago    146MB
kod          v1        dbb4a9a529ea   22 minutes ago   566MB
centoscy     7         ffaf86b4f3fc   47 minutes ago   402MB
centos       7         eeb6ee3f44bd   11 months ago    204MB
3、Dockerfile制作镜像
3.1 Dockerfile简介

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明;Docker 通过读取Dockerfile 中的指令自动生成镜像。

Dockerfile 是官方推荐的方式,这样可以让使用者更清晰地看到这个镜像的制作细节,逻辑清晰,便于管理。

Docker分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时默认要执行的指令

例如:

代码语言:javascript复制
# 1、第一行必须指定,基础镜像信息
FROM centos:7
# 2、维护者信息
MAINTAINER Alone@example.com
# 3、镜像操作指令
RUN yum install -y httpd
# 4、容器启动执行指令
CMD ["/bin/bash"]     

Dockerfile 文件编写完成后需要使用 docker build 命令将 Dockerfile 文件中的构建镜像指令加载运行,由此生成镜像。

3.2 docker build命令

docker build 命令用于从Dockerfile构建镜像。

代码语言:javascript复制
格式:
    docker build  -t 镜像名:镜像标签 -f Dockerfile文件名 .

选项:
    -t		//指定通过Dockerfile文件构建的镜像名称和标签
    -f		//指定Dockerfile文件名
3.3 Dockerfile镜像构建指令

FROM : Dockerfile中第一条指令必须是FROM指令,表示从哪个基础镜像开始构建镜像

代码语言:javascript复制
FROM centos:7	//基于centos7基础镜像构建新的镜像
FROM scratch	//表示不以任何镜像为基础

MAINTAINER : 镜像维护者个人信息,维护者的姓名和邮箱

代码语言:javascript复制
MAINTAINER Alone@example.com

RUN : 构建镜像时需要执行的命令,有两种命令执行方式

代码语言:javascript复制
shell形式执行
格式:
    RUN <command>	//RUN后边直接跟shell命令,linux操作系统上默认shell为/bin/sh -c
    
exec形式执行
格式:
    RUN ["executable", "param1", "param2"]	//执行可执行文件,executable为可执行文件,param为选项或参数;exec形式可以指定使用其他终端

两种形式对比:
    RUN echo "zsl"
    RUN ["/bin/bash", "-c", "echo hello"]

注:多行命令不要写多个RUN,Dockerfile中每一个RUN指令都会建立一层镜像,多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。

ADD :将本地文件添加到构建的镜像中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget

代码语言:javascript复制
 ADD <src>... <dest>
 ADD ["<src>",... "<dest>"]	//用于支持包含空格的路径
示例:
    ADD test /tmp/    		//添加"test"文件到镜像的"/tmp"目录
    ADD hom* /mydir/		//添加所有以"hom"开头的文件到镜像的"/mydir"目录

COPY :该指令用于将宿主机文件拷贝至镜像内的指定路径

代码语言:javascript复制
COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]	//用于支持包含空格的路径
示例:
    ADD hom* /mydir/		//添加所有以"hom"开头的文件到镜像的"/mydir"目录

CMD : 指定镜像启动为容器后默认执行的命令,每个 Dockerfile 只能有一条 CMD 命令;如果指定了多条命令,只有最后一条会被执行,如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令

代码语言:javascript复制
格式:
    CMD ["executable","param1","param2"]	//执行可执行文件,此方式优先
    CMD command param1 param2 			//执行shell内部命令
    CMD ["param1","param2"]			//设置了ENTRYPOINT,则为ENTRYPOINT添加参数

示例:
    CMD ["echo","This is a test"]
    CMD echo "This is a test"

ENTRYPOINT : 类似于 CMD 指令,但其不会被创建容器时指定的命令覆盖,如果创建容器时指定了命令那么这些命令会被当作参数送给 ENTRYPOINT 指令指定的程序;CMD 和ENTRYPOINT 同在时 CMD 的内容会被当作参数传递给 ENTRYPOINT 指定的命令。

代码语言:javascript复制
格式:
    ENTRYPOINT ["executable", "param1", "param2"] 	//执行可执行文件, 此方式优先
    ENTRYPOINT command param1 param2 			//shell内部命令

ENV :设置环境变量。此环境变量为镜像启动为容器之后容器中的环境变量

代码语言:javascript复制
格式:
    ENV <key> <value>		//<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
    ENV <key>=<value> ...	//可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用来进行转义,也可以通过""来进行标示

示例:
    ENV myName zhuang han
    ENV myName="zhuang han" myAge="100"
    ENV HTTPD_MPM="event"

EXPOSE :指定镜像启动为容器后开放的端口

代码语言:javascript复制
格式:
    EXPOSE <port> [<port>...]

示例:
    EXPOSE 80 443
    EXPOSE 8080
    EXPOSE 11211/tcp 11211/udp

注:EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口。

WORKDIR :工作目录,类似于cd命令

代码语言:javascript复制
格式:
    WORKDIR /path/to/workdir

示例:
    WORKDIR /hzz  //这时工作目录为/zsl

注:通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。

USER :指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户

代码语言:javascript复制
格式:
  USER user
  USER user:group
  USER uid
  USER uid:gid

 示例:
  USER zhao

 注:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。

ARG :在构建镜像时设置变量,此变量只在Dockerfile中有效

代码语言:javascript复制
格式:
    ARG <name>[=<default value>]

示例:
    ARG Site="/var/www/html"
    RUN mkdir $Site

VOLUME :创建镜像时指定挂载点,一旦此镜像被启动为容器,则自动为该容器挂载匿名卷

代码语言:javascript复制
格式:
    VOLUME ["/path/to/dir"]

示例:
    VOLUME ["/data"]
    VOLUME ["/var/www","/var/log/apache2","/etc/apache2"]

ONBUILD :用于设置镜像触发器,当有其他镜像以此镜像为基础镜像时自动调用 ONBUILD 指定的命令

代码语言:javascript复制
格式:
  ONBUILD [INSTRUCTION]

示例:
    ADD test /tmp/
    ONBUILD ADD test /tmp/	//ONBUILD用于基础镜像中

HEALTHCHECK :镜像启动为容器后健康状况检查命令

代码语言:javascript复制
格式:
    HEALTHCHECK [OPTIONS] CMD command	//在容器内部运行一个命令来检查容器的健康状况
    HEALTHCHECK NONE			//如果基础镜像有健康检查指令,使用此指令可以屏蔽掉其健康检查指令

选项
    --interval=<间隔>	//两次健康检查的间隔,默认为 30 秒
    --timeout=<时长>	//健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒
    --retries=<次数>	//当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次

示例:
    HEALTHCHECK --interval=5m --timeout=3s CMD curl http://localhost || exit 1
4、Dockerfile案例

一、扫雷案例 1、所需软件包和环境 Centos-7.repo epel-7.repo saolei.zip server1:部署docker扫雷案例 server2:部署apache,将saolei.zip软件包上传上去 2、编辑Dockerfile,使用基础镜像centos:7 3、构建镜像saolei:v1 4、运行容器,指定映射端口8081:8080,容器名为自己名字的全拼 5、使用浏览器访问http://自己docker服务器的ip/saolei.jsp,能够实现扫雷游戏的使用

代码语言:javascript复制
# server1
[root@server1 ~]#yum -y install unzip
[root@server1 ~]#unzip saolei.zip 
Archive:  saolei.zip
   creating: saolei/
   creating: saolei/imgs/
  inflating: saolei/imgs/bai22.jpg   
  inflating: saolei/imgs/caidao.jpg  
  inflating: saolei/imgs/hei22.jpg   
  inflating: saolei/imgs/lei.jpg     
  inflating: saolei/imgs/notlei.jpg  
  inflating: saolei/imgs/paichu.jpg  
  inflating: saolei/imgs/paicuo.jpg  
  inflating: saolei/imgs/qipan.jpg   
  inflating: saolei/imgs/query.jpg   
  inflating: saolei/saolei.jsp       
[root@server1 ~]#tar -zcvf saolei.tar.gz saolei/
saolei/
saolei/imgs/
saolei/imgs/bai22.jpg
saolei/imgs/caidao.jpg
saolei/imgs/hei22.jpg
saolei/imgs/lei.jpg
saolei/imgs/notlei.jpg
saolei/imgs/paichu.jpg
saolei/imgs/paicuo.jpg
saolei/imgs/qipan.jpg
saolei/imgs/query.jpg
saolei/saolei.jsp
[root@server1 ~]#vim Dockerfile 
FROM centos:7
MAINTAINER Alone@example.com
ADD Centos-7.repo /etc/yum.repos.d/
ADD epel-7.repo /etc/yum.repos.d/
RUN yum -y install tomcat unzip curl
WORKDIR /var/lib/tomcat/webapps/
RUN curl -O http://192.168.111.138/saolei.zip && 
unzip saolei.zip && 
mv saolei ROOT
ADD init.sh /init.sh
EXPOSE 8080
CMD ["/bin/bash","/init.sh"]
[root@server1 ~]#vim init.sh
#!/bin/bash
/usr/libexec/tomcat/server start
[root@server1 ~]#docker build -t saolei:v1 .
Sending build context to Docker daemon  779.3kB
Step 1/10 : FROM centos:7
7: Pulling from library/centos
2d473b07cdd5: Pull complete 
Digest: sha256:c73f515d06b0fa07bb18d8202035e739a494ce760aa73129f60f4bf2bd22b407
Status: Downloaded newer image for centos:7
 ---> eeb6ee3f44bd
Step 2/10 : MAINTAINER Alone@example.com
 ---> Running in 6211743b3ff8
Removing intermediate container 6211743b3ff8
 ---> dc234f5a21f5
Step 3/10 : ADD Centos-7.repo /etc/yum.repos.d/
 ---> 988b3c3dc4d5
Step 4/10 : ADD epel-7.repo /etc/yum.repos.d/
 ---> a4c6c36a5f31
Step 5/10 : RUN yum -y install tomcat unzip curl
 ---> Running in 9bf201c6ad68
Loaded plugins: fastestmirror, ovl
Repository base is listed more than once in the configuration
Repository updates is listed more than once in the configuration
Repository extras is listed more than once in the configuration
Repository centosplus is listed more than once in the configuration
......
[root@server1 ~]#docker run -d -P saolei:v1 
112e98b9db62e68f3991dad8cc70b09571335c0f8e7a9c36c8ba8cbd84d7657a
[root@server1 ~]#docker ps
CONTAINER ID   IMAGE       COMMAND                CREATED         STATUS         PORTS                                         NAMES
112e98b9db62   saolei:v1   "/bin/bash /init.sh"   6 seconds ago   Up 5 seconds   0.0.0.0:49153->8080/tcp, :::49153->8080/tcp   ecstatic_dewdney


# server2
[root@server2 ~]#yum -y install httpd
[root@server2 ~]#systemctl enable httpd
[root@server2 ~]#systemctl stop firewalld.service 
[root@server2 ~]#systemctl disable firewalld.service 
[root@server2 ~]#vim /etc/selinux/config
SELINUX=disabled
[root@server2 ~]#cd /var/www/html/
[root@server2 /var/www/html]#ls
saolei.zip
[root@server2 ~]#systemctl restart httpd

二、可道云案例 1、所需软件包 Centos-7.repo epel-7.repo kodexplorer4.40.zip nginx.conf 2、创建/opt/dockerfile/kod目录,将所需的软件包和文件放置该目录下 3、在该目录下编辑dockerfile,使用基础镜像centos:7 4、构建镜像kod:v1 5、运行容器,指定映射端口80:80,容器名为自己名字的全拼 6、使用浏览器访问http://自己docker服务器的ip/index.php,能够实现可道云的使用

代码语言:javascript复制
[root@zhao ~]#mkdir -p /opt/dockerfile/kod

[root@zhao ~]#cd /opt/dockerfile/kod

[root@zhao /opt/dockerfile/kod]#ls
Centos-7.repo  epel-7.repo  kodexplorer4.40.zip  nginx.txt

[root@zhao /opt/dockerfile/kod]#mv nginx.txt nginx.conf
[root@zhao /opt/dockerfile/kod]#ls
Centos-7.repo  epel-7.repo  kodexplorer4.40.zip  nginx.conf

[root@zhao /opt/dockerfile/kod]#vim dockerfile 
FROM centos:7
ADD Centos-7.repo /etc/yum.repos.d/
ADD epel-7.repo /etc/yum.repos.d/
RUN yum -y install nginx php-fpm php-gd php-mbstring unzip && sed -i '/^user/c user=nginx' /etc/php-fpm.d/www.conf && sed -i '/^group/c group=nginx' /etc/php-fpm.d/www.conf
COPY nginx.conf /etc/nginx/nginx.conf
RUN mkdir /code
WORKDIR /code
COPY kodexplorer4.40.zip .
RUN unzip kodexplorer4.40.zip && 
chown -R nginx.nginx .
ADD init.sh /init.sh
EXPOSE 80
ENTRYPOINT ["/bin/bash","/init.sh"]

[root@zhao /opt/dockerfile/kod]#vim init.sh
#!/bin/bash
php-fpm -D
echo "$1" >> /etc/nginx/nginx.conf
nginx -g 'daemon off;'

[root@zhao /opt/dockerfile/kod]#docker build -t kod:v1 .
[root@zhao /opt/dockerfile/kod]#docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
kod          v1        51f3b808d40d   3 minutes ago   599MB
saolei       v1        6ea942523102   3 hours ago     640MB
centos       7         eeb6ee3f44bd   11 months ago   204MB

[root@zhao /opt/dockerfile/kod]#docker run -d -p 80:80 --name zhaoshulin  kod:v1 '#runtime'
b6966e8a5ca4d4dc1aadadd9da14179a9bae86930d51d8b08ef368cde599635d
[root@zhao /opt/dockerfile/kod]#docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                               NAMES
b6966e8a5ca4   kod:v1    "/bin/bash /init.sh …"   12 seconds ago   Up 11 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   zhaoshulin

[root@zhao /opt/dockerfile/kod]#docker exec -it zhaoshulin /bin/bash
[root@b6966e8a5ca4 code]# tail -1 /etc/nginx/nginx.conf
#runtime

0 人点赞