使用Dockerfile创建镜像

  • Dockerfile是一个文本格式的配置文件,我们可以利用Dockerfile来快速的创建一个自定义的镜像。
基本结构
  • Dockerfile由一行命令语句组成,并且支持以#开头的注释
  • 一般包括四个部分:基础镜像信息,维护者信息,镜像操作指令,容器启动时执行指令,如下一个案例
# This Dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
# Base image to use, this must be set as the first line
FROM ubuntu
# Maintainer: docker_user <docker_user at email.com> (@docker_user)
MAINTAINER docker_user docker_user@email.com
# Commands to update the image
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/
sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# Commands when creating a new container
CMD /usr/sbin/nginx
  • 如上是一个官网的Demo,一开始指定所基于的镜像名称,之后是维护者的信息,后面才是镜像操作的指令,例如RUN指令将对镜像执行跟随在后面的命令,CMD用来指定运行容器时候的操作命令。
  • 如下是一个更复杂一点的案例,基于buildpack-deps:jessie-scm基础镜像,安装Golang相关环境,制作一个GO语言的运行环境镜像(先看看就行):
FROM buildpack-deps:jessie-scm
# gcc for cgo
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
gcc \
libc6-dev \
make \
&& rm -rf /var/lib/apt/lists/*
ENV GOLANG_VERSION 1.6.3
ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
ENV GOLANG_DOWNLOAD_SHA256 cdde5e08530c0579255d6153b08fdb3b8e47caabbe717bc7bcd
7561275a87aeb
RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \
&& echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \
&& tar -C /usr/local -xzf golang.tar.gz \
&& rm golang.tar.gz
ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
WORKDIR $GOPATH
COPY go-wrapper /usr/local/bin/
指令说明
  1. FROM
  • 指定所创建镜像的基础镜像,如果本地不存在,默认去Docker Hub上下载,格式:FROM < image>
  • 任何一个Dockerfile中第一条指令必须是FROM,并且,如果在同一个Dockerfile中创建多个镜像,可以用多个FROM指令
  1. MAINTAINER
  • 指定维护者信息,格式MAINTAINER< name>。信息会写入生成镜像的Author属性域中例如:
MAINTAINER ljmadmin@docker.com
  1. RUN
  • 运行指定命令格式如下
  • 上面第一个命令默认将在shell中断中运行,即 /bin/sh -C ,后面的使用exec执行不会启动shell环境
  • 每一条RUN指令将在当前镜像的基础上执行指定的命令,并且提交为新的进行,当命令比较长的时候,可以用\ 来换行,比如:
RUN <command>  或者 RUN ["executable", "param1","param2"],
//案例
RUN apt-get update \&& apt-get install -y libsnappy-dev zliblg-dev libbz2-dev \&& rm -rf /var/cache/apt
  1. CMD
  • CMD指令用来指定启动容器时候默认执行的命令,他支持三种格式:

    • CMD[“executable”, “param1”, “param2”] 使用exec执行,是推荐使用的方式
    • CMD command param1 param2 在/bin/sh 中执行,提供给需要交互的应用
    • CMD [“param1”, “param2”]提供给ENTRYPOINT的默认数
  • 每个DOckerfile只能有一条CMD命令,如果指定多条,最后一条覆盖之前的
  1. LABEL
  • LABEL指令用来指定生成镜像的元数据标签信息
  • 格式为如下例如
LABEL<key> = <value><key>=<value>....
//案例
LABEL version="1.0"
LABEL description="This text illustrates \ that label-values can span multiple lines."
  1. EXPOSE
  • 声明镜像内服务所监听的端口
  • 格式如下。 例如
EXPOSE <port>[ <port>......]
//案例
EXPOSE 22 80 8443
  • 改指令只是起到声明作用,不会自动完成端口映射
  • 启动容器时候需要使用-P,Docker主机会自动分配一个宿主机临时端口转发到指定的端口,使用-p,则可以具体的指定哪个宿主机本地端口会映射过来。
  1. ENV
  • 指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在
  • 格式…。如下:
ENV <key><value> 或者 EVN <key>=<value>
//案例
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/
postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
  • 指令指定的环境变量在运行时可以被覆盖掉,比如docker run --evn< key>=< value>built_image
  1. ADD
  • 该命令将复制指定额< src> 路径下的内容到容器中的< dest> 路径下,格式如下
  • 其中< src> 可以是Dockerfile所在的目录的一个相对路径,也可以是一个URL,还可以是一个tar文件。< desc>可以使镜像内部的绝对路径,或者相对于工作目录的相对路径。
ADD <src><desc>
  1. COPY
  • 格式如下,复制本地主机的< src> (为Dockerfile所在目录的相对路径,文件,或者目录) 下的内容 到镜像中的< dest> 下。目标路径不存在时候回自动创建 。路径支持正则,当使用本地目录为源目录时候,推荐使用COPY
COPY<src><desc>
  1. ENTRYPOINT
  • 指定镜像的默认入口命令,该入口命令会在启动容器时候作为命令执行,所有传入值作为改命令的参数,支持如下两种格式
ENTRYPOINT ["executable", "param1", "param2"](exec调用执行)
ENTRYPOINT command param1 param2(shell中执行)
  • 每个Dockerfila中只能有一个ENTRYPOINT,当指定过个时候,只有最后一个有效,在运行时候可以被–entrypoint参数覆盖掉,如docker run–entrypoint
  1. VOLUME
  • 创建一个数据卷挂载点, 可以从本地主机或者其他容器挂载数据卷,一般用来存放数据库和需要保存的数据等。格式如下
VULUME ["/data"]
  1. USER
  • 指定运行容器时候的用户名或者UID,后续的RUN等指令也会使用指定的用户身份格式如下:
USER daemon
//案例
RUN groupadd -r postgres && useradd -r -g postgres postgres
  • 需要临时获取管理员权限可以使用gosu或者sudo
  1. WORKDIR
  • 为后续的RUN,CMD和ENTRYPOINT指令配置工作目录,格式如下
WORKDIR /path/to/workdir
//案例
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
  • 如上案例,可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。最终的路径为/a/b/c
  1. ARG
  • 指定一些镜像内使用的参数(例如版本号信息等),这些参数在执行docker build命令时以下格式传入
ARG<name>[=<default value>]
//案例
docker build--build-arg<name>=<value>
  1. ONBUILD
  • 配置当所有创建的镜像作为其他镜像的基础镜像时,所执行的创建操作指令,格式如下:
ONBUILD [INSTRUCTION]
//Dockerfile使用如下内容创建镜像image-A
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bing/python-build --dir /app/src
[...]
  • 如果基于image-A创建新的镜像时候,新的Dockerfile使用FROM image-A指定基础进行,会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令,如下:
FROM image-A
#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src
  • 使用ONBUILD指令的镜像,推荐在边去中注明,例如ruuby:1.9-onbuild
  1. STOPSIGNAL
  • 指定所创建的镜像启动的容器接受退出的信号值,例如:
STOPSIGNAL signal
  1. HEALTHCHECK
  • 配置所启动容器如何进行健康检查(如何判断健康与否),自Docker1.12开始支持,格式如下:
HEALTHCHECK [OPTIONS] CMS command :根据执行命令返回值是否为0 判断
HEALTHCHECK NONE : 禁止基础镜像中的监看检查
  • OPTION参数支持如下:

    • __interval=DURATION(默认30s):过多久检查一次
    • __timeout=DURATION(默认30s):每次检查等待结果的超时
    • __retries=N(默认为3):如果失败,重试几次才最终确定失败。
创建镜像
  • 编写完Dockerfile后,可以通过docker build命令来创建镜像,基础格式如下:
docker build [选项]
  • 如上命令将读取指定路径下(包括子目录)的Dockerfile文件,并将该路劲下所有内容发送给Docker 服务端,由服务端来创建镜像,因此除非生成镜像需要,否则一般建议放置Dockerfile的目录为空目录。

    • 如果使用非内容路径下Dockerfile,可以通过-f 选项指定其他路径
    • 要指定生成镜像的便签可以用-t 选项
  • 案例:指定Dockerfile路径/tmp/docker_builder/,并且生成镜像标签为build_repo/first_image,命令如下
docker build -t build_repo/first_image /temp/docker_builder
使用.dockerignore文件
  • 上说的,Dockerfile路径下的所有文件都会发到Docker服务端打包,那肯定有响应的规避措施,
  • 我们通过.dockerignore文件(没一行添加一条匹配模式)来让Docker忽略匹配模式路径下的目录和文件。如下:
#comment*/temo**/*/temp*tmp?~*

Dockerfile实战测试

  • 以下将分别通过docker commit命令方式,Dockerfile的方式分别为镜像添加SSH服务并且生成新的镜像文件,来对象两者的区别,
通过docker commit 方式创建镜像
  • Docker提供了docker commit 命令,支持用户提交自己对指定容器的修改,并且生成新的镜像在本地。格式如下:
docker commit CONTAINER [REPOSITORY[:TAG]]
  • 如下步骤依次执行:
//使用ubuntu:lasted
docker run -it ubuntu:lasted /bin/bash
//更新apt缓存,并安装openssh-server
apt-get update; apt-get install openssh-server -y
//如需正常启动SSH服务,则目录/var/run/sshd必须存在,手动创建,并启动SSH服务
mkdir -p /var/run/sshd
/usr/sbin/ssh -D &
//修改SSH服务的安全登录配置,取消pam登录限制
sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
//在root账户下创建.ssh目录,并负责需要登录的公钥(公钥信息一般为本机主机用户目录下.ssh/id_rsa.pub文件,可由ssh-keygen-t rsa命令生成)到authorized_keys文件中:
mkdir root/.ssh
vi /root/.ssh/authorized_keys
//创建自动启动ssh服务的可执行文件run.sh,并添加权限:
vi /run.sh
chmod +x run.sh
//编辑内容
#!/bin/bash
/usr/sbin/sshd -D
//退出容器
exit
//保存镜像
docker commit [CONTAINER ID] sshd:ubuntu
//使用docker images查看本地生成的镜像sshd:ubuntu,目前拥有镜像信息如下截图
//使用镜像
docker run -p 10022:22 -d ssh:ubuntu /run.sh
//启动成功后可以在宿主机上看到容器运行的详细信息
docker ps
//可以通过该宿主机ip访问,通过ssh 10022 端口登录容器
ssh 192.168.*.* -p 10022

使用Dockerfile创建
  • 依次按如下步骤
//创建工作目录sshd_ubuntu工作目录
mkdir sshd_ubuntu
//在其中创建Dockerfile和run.sh文件
cd /sshd_ubuntu/
touch Dockerfile run.sh
//编写run.sh脚本和authorized_key文件
#!/bin/bash
/usr/sbin/sshd -d
//在宿主机上生成SSH秘钥对,并创建authorized_keys文件:
ssh-keygen -t rsa
....
cat ~/.ssh/id_rsa.pub > authorized_keys
  • 编写Dockerfile,下面是Dockerfile的内容以及部分的解释信息,可以对比docker commit 命令创建的过程,操作基本一致:
#设置基础镜像
FROM ubuntu:latest
#提供一些作者信息
MAINTAINER ljmadmin (645121107@qq.com)
#下面开始运行更新命令
RUN apt-get update
#安装ssh服务
RUN apt-get install -y openssh-server
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh
#取消pam限制
RUN sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
#复制配置文件到相应位置,并赋予可执行权限
ADD authorized_keys /root/.ssh/authorized_keys
ADD run.sh /run.sh
RUN chmod 755 /run.sh
#开放端口
EXPOSE 22
#设置自启动命令
CMD ["/run.sh"]
  • 创建镜像:在sshd_ubuntu目录下使用docker build命令创建镜像,
cd sshd_ubuntu
docker build -t ssh:Dockerfile .
  • 查看本地ssh:Dockerfile镜像已经存在:
  • 测试启动镜像运行容器效果与上面一致

总结

  • Dockerfile使用前需要熟悉每个命令,多实践,自己写一些简单的案例测试,弄清楚原理在写,Docker Hub官方仓库有很多优秀镜像对应的Dockerfile可以借鉴学习
  • 创建原则有如下几个:
    • 精简镜像用途:
    • 选合适基础镜像
    • 提供足够清晰的命令注释和维护者信息
    • 正确使用版本号码
    • 减少镜像层数
    • 及时删除临时文件和缓存文件
    • 提高生成速度
    • 调整合理的指令顺序
    • 减少外部源干扰

上一篇:Docker中数据管理
下一篇:Docker容器实战思维

Docker之Dockerfile详解相关推荐

  1. Docker(四) Dockerfile 详解

    一.Dockerfile文件介绍 1.1 什么是Dockerfile Dockerfile 是构建docker镜像的构建文件,是由一系列命令和参数构成的脚本,即构建镜像的脚本文件.如下为centos的 ...

  2. Docker系列07—Dockerfile 详解

    Docker系列07-Dockerfile 详解 1.认识Dockerfile 1.1 镜像的生成途径 基于容器制作  dockerfile,docker build 基于容器制作镜像,已经在上篇Do ...

  3. docker实践(2)常用命令和DockerFile详解

    <docker实践(1) 入门和springBoot实践部署> <docker实践(2)常用命令和DockerFile详解> <docker实践(3) 仓库registr ...

  4. docker常用命令详解

    docker常用命令详解 本文只记录docker命令在大部分情境下的使用,如果想了解每一个选项的细节,请参考官方文档,这里只作为自己以后的备忘记录下来. 根据自己的理解,总的来说分为以下几种: Doc ...

  5. 『中级篇』Dockerfile详解(17)

    一般的,Dockerfile 分为四部分:基础镜像信息.维护者信息.镜像操作指令和容器启动时执行指令. ####官网学习 https://docs.docker.com/engine/referenc ...

  6. 附005.Docker Compose文件详解

    一 Docker Compose文件简介 compose文件使用yml格式,主要分为了四个区域: version:用于指定当前docker-compose.yml语法遵循哪个版本 services:服 ...

  7. docker常用参数详解,docker run常用参数详解(精)

    1. 查询github上的镜像 docker search sybase 2. 下载 docker pull ifnazar/sybase_15_7 3. 删除镜像 docker rmi -f run ...

  8. dockerfile详解-dockerfile构建过程解析,dockerfile体系结构保留字解析,案例解析

    Dockerfile详解 1.定义:Dockerfile是用来构建Docker镜像的构建文件,是一系列命令和参数构成的脚本 2.步骤: --手动编写一个dockerfile文件,必须要要符合规范 -- ...

  9. Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)

    文章目录 1. Dockerfile介绍 2. Dockerfile指令说明 3. 制作Centos镜像 3.1 编写Dockerfile的文件 3.2 通过这个文件构建镜像(注意最后加个点!!!) ...

最新文章

  1. BAT都在悄悄“拆”中台,“碎片化中台” 时代已来!
  2. mysql2008无法启动_SQL Server 2008突然无法正常启动
  3. 计算机网络第三章-数据链路层
  4. 计算机视觉与深度学习 | TensorMask: A Foundation for Dense Object Segmentation(何凯明团队新作)近5年目标检测综述
  5. 遍历List过程中同时修改
  6. 使用开源的openssl的md5头文件,实现对于文件的md5代码
  7. 4012最长的最短路径的求解(C++,迪杰斯特拉算法,注释全,附迪杰斯特拉算法详解文章)
  8. 中国13个新职业薪酬待遇如何?这个岗位平均薪酬惊人!
  9. [POJ 2503] Babelfish【二分查找】
  10. 一些比较小众的小程序类型,如AI算命,影视视频等
  11. Python 读取/存储 yaml 文件
  12. java如何使用md5加密_Java中MD5加密
  13. Prim算法实现最小生成树MST(java)
  14. 通过高德开放平台用出租车数据找出乘客上下车最频繁区域
  15. Unity商店下载的资源路径
  16. ORA-00600: internal error code, arguments: [2037]
  17. IDO已经OUT ?3分钟了解NFT的新玩法INO
  18. python使用126发邮件代码
  19. 条款30:透彻了解inlining的里里外外
  20. 计算机网络 | 实验二 WINPCWP编程

热门文章

  1. Android之运行的错误:java.lang.UnsatisfiedLinkError: Couldn‘t find cibloger.so
  2. python函数返回多个值时的数据类型是_Python3 注释多个返回值的函数类型
  3. 交友软件上的两种网友类型......
  4. 这个外挂要上天了!教一千遍都不会的数理技巧,还不如搞懂最根本的概念!
  5. 太漂亮了!66个高颜值的矿物晶体,吸引到你的目光了吗
  6. 全校师生放6天春假;清华大学设立天文系;郭守敬望远镜光谱数突破千万;《自然》发表最新发现;百度败诉需道歉;这就是今天的大新闻...
  7. 从串行线程封闭到对象池、线程池
  8. python self 值自动改变,在python中对self的理解
  9. 抽屉远离在计算机的应用,抽屉原理的应用及其推广优秀毕业论文
  10. 面试问外观模式???这不就是设计模式里面的吗?我给你上一课吧,面试官