docker 学习笔记之实战 lnmp 环境搭建系列 (3) ------ dockerfile 定制属于自己的镜像

从镜像中产生的容器应该尽量轻量化,能在足够短的时间内停止、销毁、重新生成并替换原来的容器。为了减少镜像的大小,减少依赖,仅安装需要的软件包。我们就得拥有最适合自己项目的镜像。接下来就引入我们得下一个知识点 —— dockerfile

镜像的定制实际上就是定制每一层所添加的配置、文件。我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像。使用dockerfile可以解决docker复用性、安全性、透明性等问题。接下来我们先了解下dockerfile的一些基本命令吧。

dockerfile 基本命令介绍

FROM 指定基础镜像

FROM 指令用于指定其后构建新镜像所使用的基础镜像。FROM 指令必是 Dockerfile 文件中的首条命令,启动构建流程后,Docker 将会基于该镜像构建新镜像,FROM 后的命令也会基于这个基础镜像。

//语法格式
// FROM <image>:<tag>
FROM centos:latest

MAINTAINER 镜像创建者

//语法格式
//MAINTAINER info
MAINTANWE bossaiguo@qq.com

RUN 镜像构建过程中执行命令

在镜像的构建过程中执行特定的命令(注意区分 CMD 和 ENTRYPOINT) RUN 指令在定制镜像时是最常用的指令之一。其格式有两种

shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式。
exec 格式:RUN ["可执行文件", "参数1", "参数2"],这更像是函数调用中的格式。

注意:Dockerfile 中每一个指令都会建立一层,RUN 也不例外。每一个 RUN 的行为就会新建立一层,在其上执行这些命令,执行结束后,commit 这一层的修改,构成新的镜像。因此,这里没有使用很多个 RUN 对一一对应不同的命令,而是仅仅使用一个 RUN 指令,并使用 && 将各个所需命令串联起来。

//shell 格式
RUN echo 'Hello, Docker!' 
//exec 格式
RUN["/bin/bash", "-c", "echo hello world"]

CMD 容器启动后所要执行的命令

CMD service nginx start
shell格式: CMD <命令> \
exec格式:CMD [“可执行文件”,”参数1”,”参数2”]

//错误示范
CMD service nginx start

发现容器执行后就立即退出了。甚至在容器内去使用 **systemctl** 命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器。

对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。

而使用 `service nginx start` 命令,则是希望 **upstart** 来以后台守护进程形式启动 **nginx** 服务。而刚才说了 `CMD service nginx start` 会被理解为
    CMD [ "sh", "-c", "service nginx start"]
因此主进程实际上是 **sh**。那么当 `service nginx start` 命令结束后,**sh** 也就结束了,**sh** 作为主进程退出了,自然就会令容器退出。

正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如:
    CMD ["nginx", "-g", "daemon off;"]

#### CMD 容器启动后所要执行的命令

ENTRYPOINT 的 Exec 格式用于设置容器启动时要执行的命令及其参数,同时可通过CMD命令或者命令行参数提供额外的参数。ENTRYPOINT 中的参数始终会被使用,这是与CMD命令不同的一点。

ENTRYPOINT ["/bin/echo", "Hello"]  

RUN CMD ENTRYPOINT 区别

  1. RUN命令执行命令并创建新的镜像层,通常用于安装软件包
  2. CMD命令设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换
  3. ENTRYPOINT配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 docker run时指定了其他命令)

    COPY 复制文件

    和 RUN 指令一样,也有两种格式,一种类似于命令行,一种类似于函数调用。COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的<目标路径>位置。

    COPY package.json /usr/src/app/

    ADD 更高级的复制文件

    ADD 指令和 COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能。比如<源路径>可以是一个 URL,这种情况下,Docker 引擎会试图去下载这个链接的文件放到<目标路径>去。而且会将文件自动解压

ENV 设置环境变量

这个指令很简单,就是设置环境变量而已,无论是后面的其它指令,如 RUN,还是运行时的应用,都可以直接使用这里定义的环境变量

ENV VERSION=1.0 DEBUG=on 

EXPOSE

EXPOSE 指令并不会让容器监听 host 的端口,如果需要,需要在 docker run 时使用 -p-P 参数来发布容器端口到 host 的某个端口上

VOLUME 定义匿名卷

VOLUME用于创建挂载点,即向基于所构建镜像创始的容器添加卷

dockerfile 示例

构建php镜像

FROM centos:latest
MAINTAINER https://blog.51cto.com/andyxu
ENV TIME_ZOME Asia/Shanghai
ARG PV="php-7.2.11"

ADD $PV.tar.gz /tmp
RUN yum -y install gcc gcc-c++ make gd-devel libxml2-devel libcurl-devel libjpeg-devel libpng-devel openssl-devel bison \
    && mkdir /data \
    && cd /tmp/$PV \
    && ./configure --prefix=/data/php \
        --with-config-file-path=/data/php/etc \
        --with-gd --with-mysqli \
        --with-openssl --with-zlib --with-curl \
        --with-jpeg-dir --with-png-dir --with-iconv \
        --enable-fpm --enable-zip --enable-mbstring \
    && make -j 4 \
    && make install \
    && cp /data/php/etc/php-fpm.conf.default /data/php/etc/php-fpm.conf \
    && cp /data/php/etc/php-fpm.d/www.conf.default /data/php/etc/php-fpm.d/www.conf \
    && sed -i '/;daemonize/a\daemonize = no' /data/php/etc/php-fpm.conf \
    && sed -i 's/127.0.0.1/0.0.0.0/g' /data/php/etc/php-fpm.d/www.conf \
    && echo "${TIME_ZOME}" > /etc/timezone \
    && ln -sf /usr/share/zoneinfo/${TIME_ZOME} /etc/localtime \
    && rm -rf /tmp/php* \
    && yum clean all \
    && yum -y remove gcc gcc-c++ make

WORKDIR /data/php/
EXPOSE 9000
CMD ["sbin/php-fpm","-c","etc/php-fpm.conf"]
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!