基于dockerfile制作镜像
dockerfile是什么?
Dockerfile可以说是一种可以被docker程序解释的脚本,Dockerfile是由一条条的命令组成的,每条命令对应Linux下面的一条命令,docker程序将这些Dockerfile指令再翻译成真正的Linux命令,其有自己的书写方式和支持的命令,docker程序读取Dockerfile并根据指令生成docker镜像。
结构规整
将每个不同的系统以及web镜像都创建对应的目录和dockerfile,制作基础镜像,然后是基于这些基础镜像进一步的构建生产中用的环境,就不用每次都重新去底层开始构建镜像了,直接去镜像仓库拉取就行。
[root@localhost opt]# tree dockerfile/
dockerfile/
├── system
│ ├── alpine
│ │ ├── Dockerfile
│ │ └── repositories
│ ├── centos
│ │ └── Dockerfile
│ ├── debian
│ ├── redhat
│ └── ubuntu
└── web
├── apache
├── jdk
│ ├── Dockerfile
│ └── jdk-8u191
│ ├── Dockerfile
│ └── jdk-8u191-linux-x64.tar.gz
├── nginx
│ ├── alpine
│ │ ├── Dockerfile
│ │ ├── nginx-1.16.1.tar.gz
│ │ └── repositories
│ ├── centos
│ │ ├── Dockerfile
│ │ └── nginx-1.16.1.tar.gz
│ └── ubuntu
├── php
└── tomcat
├── tomcat7
└── tomcat8
├── apache-tomcat-8.5.42.tar.gz
├── build-tomcat.sh
├── Dockerfile
└── run.sh
dockerfile文件中使用命令
dockerfile官方文档:https://docs.docker.com/engine/reference/builder/
参考链接:https://blog.csdn.net/qq_41734645/article/details/105012588
FROM
FROM:基于那个镜像构建当前镜像,构建镜像时会先在本地寻找基础镜像,如果本地没有会去dockerhub或者远程仓库去下载。
LABEL,MAINTAINER
- 解释
LABEL:作者信息或者描述。(现在都是用这个)
MAINTAINER:作者信息或者描述。
- 例
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates that label-values can span multiple lines."
USER
USER:指定该容器运行时使用的用户名和UID(即设置构建用户),后续的RUN命令也会使用这个指定用户。生成容器之后登录进去会是user指定的用户,不是root。
USER <user>[:<group>]
USER <uid>:<gid>
USER nginx
WORKDIR
指定工作目录,和cd一样,这个指定的目录会成为容器启动后登陆进去的第一个目录。
VOLUME
- 解释
设置容器挂载宿主机的目录
- 例
VOLUME ["/dir_1","/dir_2",...]
VOLUME [“/data”,”/data2”]
VOLUME /data
ENV,ARG
- 解释
ENV:设置镜像环境变量,在构建镜像时有效,在镜像被创建后和启动容器时环境变量依旧也有效,并且可以重写覆盖。print env可查看其值常用于向容器内传递用户密码等。
ARG:在构建镜像时,指定一些参数,仅在build docker imag的过程中有效 - 例
例:ENV Name tiemrovers
#无默认值
ENV hey
#默认值
ENV foo /bar
#或ENV foo=/bar
#在构建过程中可以使用ENV值
ADD . $foo
#or ADD . ${foo}
#翻译为:添加。/酒吧
#使用以下docker命令设置env
docker run -e "env_var_name=another_value" alpine env
docker run -e env_var_name alpine env
docker run --env-file=env_file_name alpine env
#在Dockerfile中
ARG some_variable_name
#或硬编码默认值:
#ARG some_variable_name=默认值
RUN echo "Oh dang look at that $some_variable_name"
#在shell命令中
docker build --build-arg some_variable_name=a_value
#然后你会得到
Oh dang look at that a_value
- 配合使用
#需要一个构建时变量
ARG A_VARIABLE
#使用该值设置ENV var默认值
ENV an_env_var=$A_VARIABLE
#如果不被覆盖,您的容器将继续使用an_env_var的值!
RUN
- 解释
它接受命令作为参数并用于创建镜像。RUN会在shell或者exec的环境下执行命令。
- 例
例:RUN cd /opt
RUN echo helloworld
RUN [“命令”,“参数1”,“参数2”] #可以免除运行/bin/sh的消耗,如果参数中引号等特殊字符,需要进行转义
ADD,COPY
- 解释
ADD:ADD和COPY作用相似,可以从一个URL地址下载内容复制到容器的文件系统中,还可以将压缩打包格式的文件解压后复制到指定位置。
文件复制均使用 COPY 指令,在需要自动解压缩的场合使用 ADD
COPY:用来将本地的文件或者文件夹复制到镜像的指定路径下,但是不会解压
- 例
COPY /local/path/file /images/path/file
ADD file /images/path/file
ADD latest.tar.gz /var/www
EXPOSE
- 解释
标明这个镜像中的应用将会监听某个端口,并且希望能将这个端口映射到主机的网络界面上,使容器内的应用可以通过端口和外界交互。
这里只是暴露了容器的端口,具体指定映射需要在运行容器的时候指定-p(小写)。
- 例
例:EXPOSE 80 443 多个端口空格隔开
ENTRYPOINT,CMD
1.ENTRYPOINT 解释
类似CMD配置容器启动后执行的命令,但是它不可被 docker run 提供的参数覆盖;
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效
- ENTRYPOINT例:
ENTRYPOINT [ "sh", "-c", "echo $HOME" ]
ENTRYPOINT ["executable", "param1", "param2"] #exec 格式
ENTRYPOINT command param1 param2 #shell格式
1.Exec 格式
这种格式在容器run的时候指定的命令会覆盖ENTRYPOINT,CMD同样会覆盖
ENTRYPOINT 的 Exec 格式用于设置要执行的命令及其参数,同时可通过 CMD 提供额外的参数。
ENTRYPOINT 中的参数始终会被使用,而 CMD 的额外参数可以在容器启动时动态替换掉。
2.Shell 格式
ENTRYPOINT 的 Shell 格式会忽略任何 CMD 或 docker run 提供的参数。
Dockerfile 片段:
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
#当容器通过 docker run -it [image] 启动时,输出为:
Hello world
#而如果通过 docker run -it [image] haha启动,则输出为:
Hello haha
- CMD解释
CMD和RUN命令相似,CMD可以用于执行特定的命令。CMD每次启动容器时运行,RUN在创建镜像时执行一次,固化在image中。RUN命令先于CMD和ENTRYPOINT。
Dockerfile只允许使用一次CMD指令,一般都是脚本中最后一条指令。
如果docker run后面出现与CMD指定的相同的命令,那么CMD就会被覆盖。而ENTRYPOINT会把容器名后面的所有内容都当成参数传递给其指定的命令
CMD:设置镜像在启动容器时执行的命令。
- CMD例:
CMD ["sbin/nginx","-g","daemon off;"]
CMD ["executable","param1","param2"] #CMD 的推荐格式。
CMD ["param1","param2"] #为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT 必须使用 Exec 格式。
CMD command param1 param2 #Shell 格式
STOPSIGNAL(停止)
- 解释
该STOPSIGNAL指令设置将被发送到容器退出的系统调用信号。该信号可以是与内核syscall表中的位置匹配的有效无符号数字(例如9),也可以是格式为SIGNAME的信号名称(例如SIGKILL)。
默认的stop-signal是SIGTERM,在docker stop的时候会给容器内PID为1的进程发送这个signal,通过--stop-signal可以设置自己需要的signal,主要的目的是为了让容器内的应用程序在接收到signal之后可以先做一些事情,实现容器的平滑退出,如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,这个时间默认是10s。
- 例
#STOPSIGNAL 信号
STOPSIGNAL 9
ONBUILD
- 解释
为镜像添加触发器。其指令在构建镜像时候并不执行,而是在其子镜像中执行
当我们在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A镜像)不会产生实质性影响。但是当我们编写一个新的Dockerfile文件来基于A镜像构建一个镜像(比如为B镜像)时,这时构造A镜像的Dockerfile文件中的ONBUILD指令就生效了,在构建B镜像的过程中,首先会执行ONBUILD指令指定的指令,然后才会执行其它指令。需要注意的是,如果是再利用B镜像构造新的镜像时,那个ONBUILD指令就无效了,也就是说只能再构建子镜像中执行,对孙子镜像构建无效。
- 例
FROM ubuntu:14.04
ONBUILD RUN echo “you not see me later”
基于dockerfile构建镜像命令
1. 指定其他路径的dockerfile
docker build -t 镜像名:tag -f dockerfile文件 .
2. 本目录构建镜像
docker build -t 镜像名:tag .
docker build -t 仓库名/镜像名:tag .
3. 可以将一个dockerfile构建成不同名称的镜像
docker build -t 镜像名01:tag01 -t 镜像名02:tag02 .
docker build -t 仓库名01/镜像名01:tag01 -t 仓库名02/镜像名02:tag02 .
基于dockerfile制作nginx镜像
dockerfile文件分类
mkdir -p /opt/dockerfile/{web/{nginx,tomcat,php,jdk,apache},system/{centos,ubuntu,redhat}}
Nginx yum安装Dockerfile内容
#Docker image for nginx
FROM centos:7.7.1908
LABEL description=timerovers<18932665502@163.com>
ENV NGINX-VERSION nginx-1.16.1
RUN yum -y install epel-release && yum -y install $NGINX-VERSION
Nginx编译安装Dockerfile内容
准备好nginx-1.16.1.tar.gz放到构建镜像的目录
#Docker image for nginx
FROM centos:7.7.1908
LABEL description=timerovers<18932665502@163.com>
ARG NGINX-VERSION=nginx-1.16.1
RUN yum -y install epel-release && yum -y install gcc gcc-c++ automake pcre pcre-devel zlib \
zlib-devel openssl openssl-devel libxml2 libxml2-dev libxslt-devel gd-devel perl-devel \
perl-ExtUtils-Embed GeoIP GeoIP-devel GeoIP-data
ADD $NGINX-VERSION.tar.gz /usr/local/src/
RUN cd /usr/local/src/$NGINX-VERSION && useradd -M -s /sbin/nologin nginx \
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx \
--with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module \
--with-http_realip_module --with-http_addition_module --with-http_xslt_module \
--with-http_image_filter_module --with-http_geoip_module --with-http_sub_module \
--with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module \
--with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module \
--with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module \
&& make && make install && yum clean all && rm -rf /usr/local/src/$NGINX-VERSION
EXPOSE 80
EXPOSE 443
WORKDIR /usr/local/nginx/
CMD ["sbin/nginx","-g","daemon off;"]
启动生成镜像
把配置和存放代码的目录映射出来
nginx-data可以提前创建好
docker run -d -p 50000:80 -p 50001:443 -v nginx-data:/usr/local/nginx --name nginx nginx:1.14.2