docker教程之-Dockerfile书写

Dockerfile是可以被docker程序解释的脚本。由一条条命令组合而成。我们可以通过编写Dockerfile文件将应用根据自己的需求打包成docker镜像。也可以避免重复去修改镜像。

Dockerfile文件开头的D必须大写,在构建docker镜像的时候,通常寻找当前目录下的Dockerfile文件

Dockerfile 常用命令介绍

在编写Dockerfile的时候,Dockerfile的命令总是大写。下面来看看常用的Dockerfile命令吧

FORM

每个Dockerfile文件的开头都是FORM命令,后面跟着一个基础镜像,表示该Dockerfile文件基于这个基础镜像来进行构建

MAINTAINER

镜像维护者的基础信息

WORKDIR

指定工作目录,注意区分绝对路径和相对路径

ENV和ARG

设置容器的环境变量,格式为key=value,当有多个变量时使用空格隔开

ARG构建参数,在构建docker镜像时使用的环境变量,后续容器运行时不存在这些环境变量。这和ENV有区别

RUN

执行命令,一个Dockerfile可以有多个RUN,按照定义顺序执行。根据Dockerfile的构建规则,每执行一条命令,镜像就会多一层。会导致镜像臃肿。所以使用RUN命令的时候最好是多条能一起执行的语句都放在一个RUN命令内执行掉。RUN有两种运行格式,一种shell方式,一种参数列表方式.

shell格式

1
RUN echo 'This is a test ..'

exec格式,可执行文件需要是具体路径,使用双引号

1
RUN ["/usr/bin/echo","this is a test"]

COPY和ADD

COPY的时候有几种注意情况

当目标路径看不出是目录还是还是文件的时候,会根据原路径文件或目录名的属性自动拷贝并重命名

例如下面的

1
COPY dir /mydir
  • 当dir为文件时,mydir也是文件

  • 当dir为目录时,mydir是目录,相当于拷贝dir为mydir

区别于上面的命令,当目录路径是目录的时候,如果该目录不存在会先在容器内新建该文件夹,然后如果是文件则将文件拷贝到该目录,如果是目录则将目录里的内容拷贝到mydir文件夹内。

1
COPY dir /mydir/

ADD的使用和COPY一样,不过功能跟强大一些。与COPY相同的请参考COPY使用,这里介绍增加的功能。主要有两个不同点

  • 如果拷贝的是一个压缩文件,ADD命令会将其拷贝并解压到目标目录
  • 如果拷贝的文件是一个url的连接形式,ADD命令会自动从该url将文件下载后解压到目标目录

所以,当只是想单纯的拷贝一个文件或者压缩包的时候,建议使用COPY命令。如果拷贝后需要解压建议使用ADD命令

CMD

一个Dockerfile文件中,只能有一个CMD命令,如果有多个,最后一个有效。CMD主要用来提供容器启动执行命令提供默认值。可以包含可执行文件,也可以省略,当省略可执行文件的时候,必须制定ENTRYPOINT命令

CMD 有三种运行格式,shell格式,exec格式和参数列表格式。使用exec格式,容器内启动的任务进程pid为1。当使用参数列表格式时,必须指定ENTRYPOINT命令

为ENTRYPOINT命令提供默认参数

CMD [“param1”,”param2”]
另外两种使用方式分别是 exec 模式和 shell 模式:
CMD [“executable”,”param1”,”param2”] // 这是 exec 模式的写法,注意需要使用双引号。
CMD command param1 param2

ENTRYPOINT

CMD和ENTRYPOINT两者的目的一样,都是用来指定容器启动程序及参数的。如果指定了ENTRYPOINT命令,则CMD参数就不在是容器启动命令了。此时CMD的内容将作为参数传递给ENTRYPOINT命令。

ENTRYPOINT两种使用方式分别是 exec 模式和 shell 模式:
ENTRYPOINT [“executable”,”param1”,”param2”] // 这是 exec 模式的写法,注意需要使用双引号。
ENTRYPOINT command param1 param2

  • 指定 ENTRYPOINT 指令为 exec 模式时,命令行上指定的参数会作为参数添加到 ENTRYPOINT 指定命令的参数列表中
  • 由 CMD 指令指定默认的可选参数,当命令行没有指定参数时使用该默认参数
  • 指定 ENTRYPOINT 指令为 shell 模式时,会完全忽略命令行参数
  • 需要覆盖默认的 ENTRYPOINT 指令时,在启动容器的时候使用–entrypoint参数来指定覆盖命令

下面是几个Dockerfile样例

nginx源码编译安装Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
FROM centos
MAINTAINER chognlai
COPY nginx-1.19.1.tar.gz /tmp
RUN tar -xvf /tmp/nginx-1.19.1.tar.gz -C /tmp/ \
&& cd /tmp/nginx-1.19.1 \
&& yum install -y gcc-c++ gd-devel pcre-devel openssl-devel make \
&& useradd nginx -s /sbin/nologin \
&& ./configure --prefix=/usr/local/nginx \
--conf-path=/etc/nginx/nginx.conf \
--modules-path=/etc/nginx/ \
--sbin-path=/usr/sbin/nginx \
--user=nginx --group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_image_filter_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_stub_status_module \
--with-debug \
--with-http_realip_module \
--with-stream \
--with-stream_ssl_preread_module \
&& make && make install

#优化后的nginx.conf文件
COPY nginx.conf /etc/nginx/
EXPOSE 80 443
VOLUME /etc/nginx/vhosts

CMD ["nginx","-g","daemon off;"]

mysql

基于官方镜像修改后的Dockerfile

1
2
3
4
5
6
7
8
FROM mysql:5.7.30
MAINTAINER chonglai
COPY my.cnf /etc/mysql/my.cnf

VOLUME /var/lib/mysql
EXPOSE 3306

CMD ["mysqld"]

nginx+php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
FROM centos:7
MAINTAINER chognlai

RUN yum install -y wget epel-release && \
wget https://rpms.remirepo.net/enterprise/remi-release-7.rpm \
&& rpm -vih remi-release-7.rpm \
&& yum install -y php74-php-fpm php74-php-gd php74-php-mbstring


COPY nginx-1.19.1.tar.gz /tmp
RUN tar -xvf /tmp/nginx-1.19.1.tar.gz -C /tmp/ \
&& cd /tmp/nginx-1.19.1 \
&& yum install -y gcc-c++ gd-devel pcre-devel openssl-devel make \
&& useradd nginx -s /sbin/nologin \
&& ./configure --prefix=/usr/local/nginx \
--conf-path=/etc/nginx/nginx.conf \
--modules-path=/etc/nginx/ \
--sbin-path=/usr/sbin/nginx \
--user=nginx --group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_image_filter_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_stub_status_module \
--with-debug \
--with-http_realip_module \
--with-stream \
--with-stream_ssl_preread_module \
&& make && make install

COPY nginx.conf /etc/nginx/
EXPOSE 80 443
VOLUME /etc/nginx/vhosts

CMD /opt/remi/php74/root/sbin/php-fpm && nginx -g "daemon off;"

Dockerfile的构建命令如下:

docker build -t name:tag .