注意:指令是顺序执行的,不区分大小写,但是默认使用大写字母,第一个非注释行指令必须是FROM,

0、基于基础容器手工制作镜像

0.1 基于容器制作镜像(Aliyun ECS)

1)启动基础镜像容器
docker run -it —name=”centos_c1” centos
2)安装所需要的软件包,并启动测试
mv /etc/yum.repos.d/*.reop /tmp
配置本地的yum源
cat > /etc/yum.repos.d/ftp.repo <[ftp]
name=ftpbase
baseurl=ftp://172.17.0.1/centos6.9
enabled=1
gpgcheck=0
EOF
yum clean all && yum makcache && yum install -y openssh-server
/etc/init.d/sshd start —->重要:ssh第一次启动时,需要生成密钥,生成pam验证配置文件
/etc/init.d/sshd stop
3)镜像的制作
docker commit centos_c1 scxiang/centos6_sshd:v1
4)基于新镜像启动容器实现,centos6+sshd的功能
docker container run -d —name=centos_sshd -p 2222:22 scxiang/centos6_sshd:v1 /usr/sbin/sshd -D

0.2 构建企业网站定制镜像(centos6.9_sshd_lamp_bbs)

1)启动基础镜像容器
[root@docker ~]# docker container rm -f docker ps -a -q
[root@docker ~]# mkdir -p /opt/vol/{mysql,html}
[root@docker ~]# docker run -it —name=”centos_c1_bbs” -v /opt/vol/mysql:/var/lib/mysql -v /opt/vol/html:/var/www/html centos6.9
2)优化yum源并安装软件
mv /etc/yum.repos.d/.repo /tmp
echo -e “[ftp]\nname=ftp\nbaseurl=ftp://172.17.0.1/centos6.9\ngpgcheck=0”>/etc/yum.repos.d/ftp.repo
yum makecache fast && yum install openssh-server httpd mysql-server mysql php php-mysql -y
3)软件初始化
/etc/init.d/sshd start
/etc/init.d/sshd stop
echo “abc123..” | passwd root —stdin
4)mysql的初始化
[root@8247baf75b26 /]# /etc/init.d/mysqld start
mysql> grant all on
. to root@’%’ identified by ‘abc123..’;
mysql> grant all on
. to discuz@’%’ identified by ‘abc123..’;
mysql> create database discuz charset utf8;
5)apache初始化
[root@8247baf75b26 /]# /etc/init.d/httpd start
6)制作LAMP第一版基础镜像
[root@docker ~]# docker commit 8247baf75b26 scxiang/centos_lamp:v1
7)根据第一版镜像,启动新容器
[root@docker ~]# docker run -it —name=”scxiang_centos_bbs_v2” -v /opt/vol/mysql:/var/lib/mysql -v /opt/vol/html:/var/www/html -p 8080:80 scxiang/centos_lamp:v1
[root@406c1aa7effb /]# /etc/init.d/mysqld start
[root@406c1aa7effb /]# /etc/init.d/httpd start
8)测试php功能
vim /var/www/html/index.php
<?php
phpinfo();
?>
9)安装bbs论坛
上传bbs代码到宿主机/opt/vol/html并解压
安装
image.png
10)制作LAMP+bbs第二版镜像
[root@docker ~]# docker commit scxiang_centos_bbs_v2 scxiang/centos6.9_sshd_lamp_bbs:v1
11)创建启动脚本
cd /opt/vol/html
vim init.sh
#!/bin/bash
/etc/init.d/mysqld start
/etc/init.d/httpd start
/usr/sbin/sshd -D
chmod 777 init.sh
12)启动容器,映射端口,挂载数据卷,自动启多服务
[root@docker ~]# docker container run -d —name=”centos_lamp_bbs” -v /opt/vol/mysql:/var/lib/mysql -v /opt/vol/html:/var/www/html -p 22222:22 -p 8080:80 -p 33060:3306 scxiang/centos6.9_sshd_lamp_bbs:v1 /var/www/html/init.sh
*CentOS7镜像在安装好ssh之后,在需要手工添加证书

[root@docker ~]# docker run -it —name=”centos_c1” centos:6.9
yum install -y openssh-server
mkdri /var/run/sshd
echo ‘UseDNS no’ >>/etc/ssh/sshd_config
sed -i -e ‘/pam_loginuid.so/d’ /etc/pam.d/sshd
echo ‘root:abc123..’ | chpasswd
/usr/bin/ssh-keygen -A
[root@docker ~]# docker commit centos7.5_c1 scxiang/centos7.5_ssh
[root@docker ~]# docker container run -d -p 2222:22 —name=”centos_sshd” 70fbdf064eb0 /usr/sbin/sshd -D

Dockerfile示例

  1. # CentoS6.9_sshd_LAMP
  2. FROM centos:6.9
  3. RUN mv /etc/yum.repos.d/*.repo /tmp && echo -e "[ftp]\nname=ftp\nbaseurl=ftp://172.17.0.1/centos6.9\ngpgcheck=0">/etc/yum.repos.d/ftp.repo && yum makecache fast && yum install openssh-server httpd mysql-server mysql php php-mysql -y
  4. RUN /etc/init.d/sshd start %% echo "abc123.." | passwd root --stdin && /etc/init.d/mysqld start && /etc/init.d/httpd start
  5. #RUN mysql -e "grant all on *.* to root@'%' identified by 'abc123..';grant all on *.* to discuz@'%' identified by 'abc123..';create database discuz charset utf8;"
  6. COPY init.sh /
  7. COPY index.php /var/www/html
  8. ADD bbs.tar.gz /var/www/html
  9. ADD http://nginx.org/download/nginx-1.18.0.tar.gz /var/www/html
  10. EXPOSE 22
  11. EXPOSE 80
  12. EXPOSE 3306
  13. #CMD ["/bin/bash","/init.sh"]
  14. ENTRYPOINT ["/bin/bash","/init.sh"]
  15. [root@docker centos6.9_sshd_lamp]# docker build -t scxiang/centos6.9_bbs_dkf:v1 ./
  16. [root@docker centos6.9_sshd_lamp]# docker run -it --name="centos_c1_bbs" -v /opt/vol/mysql:/var/lib/mysql -v /opt/vol/html:/var/www/html 2199b8eb8390

一、FROM指令

FROM指令是最重要的一个,且必须为Dockerfile文件开篇的第一个非注释行,用于为映像文件构建过程执行基准镜像,后续的指令运行于此基准镜像所提供的运行环境,在实践中,基准镜像可以是任何可用镜像文件,默认情况下,docker bulid会在docker主机上查找执行的镜像文件,在其不存在时,则会从DockerHub Registry上拉取所需的镜像文件,如果找不到指定的镜像文件,docker build会返回一个错误信息
语法:
FROM [:]或者
FROM @
:指定作为基础镜像的名称
:基础镜像的标签,为可选项,省略时默认为latest
可选项:MAINTANIER已经被遗弃,现在使用LABEL

二、MAINTAINER指令

用于让Dockerfile制作者提供本人的详细信息,Dockerfile并不限制MAINTAINER指令可在出现的位置,但推荐将其放置于FROM指令之后
语法:
MAINTAINER
可是任何文本信息,但约定俗成地使用作者名称以及邮件地址
MAINTAINER “Evn Evn@scxiang.com

三、LABEL指令

同MAINTAINER指令用法一样,用于为镜像添加元数据信息
语法:
LABEL = = =

四、COPY指令

用于从Docker主机复制文件至创建的新映像文件
语法:
COPY
COPY [““,…”“]
:要复制的源文件或目录,支持使用通配符,可以有多个源
:目标路径,即正在创建的images的文件系统路径;建议为使用绝对路径,否则,COPY指定则以WORKDIR为其起始路径
注意:在路径中有空白字符时,通常使用第二种格式
文件复制准则:
必须是build上下文中的路径,不能是其父目录中文件
如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
如果指定了多个,或在中使用了通配符,则必须是一个目录,且必须以/结尾
如果事先不存在,它将会被自动创建,这包括其父目录路径

实例1:

构建目录
image.png
Dockerfile

  1. # Description:test image
  2. FROM busybox:latest
  3. MAINTAINER "Evn.xiang"
  4. # LABEL mainrainer="Evn.xiang"
  5. ENV DOC_ROOT=/data/web/html/ \
  6. WEB_SERVER_PACKAGE="nginx-1.15.2.tar.gz"
  7. COPY index.html ${DOC_ROOT:-/data/web/html/} #复制index.html复制到DOC_ROOT目录下,不存在此目录时复制到/data/web/html目录下
  8. COPY yum.repos.d /etc/yum.repos.d/ #将yum.repos.d目录下的文件复制/etc/yum.repos.d/

构建状态
image.png
构建的镜像
image.png
运行容器查看结果,可见在Dockerfile构建时已经将index.html文件拷贝到容器的该目录下
# docker run —name testdockerfile1 —rm testdockerfile:v0.1-1 cat /data/web/html/index.html
image.png

五、ADD指令

ADD指令类似于COPY指令,ADD支持对TAR格式文件进行解压和对URL路径指向的文件进行下载
语法:
ADD 或,可以有多个源
ADD [““,…”“]
操作准则
1、同COPY指令
2、如果为URL且不以/结尾,则指定的文件将被下载并直接被创建为;如果以/结尾,则文件名URL指定的文件将被直接下载并保存为/
3、如果是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于”tar -x”命令;然后,通过URL获取到的tar文件将不会自动展开
4、如果有多个,或其间接或直接使用了通配符,则必须是一个/结尾的目录路径;如果不以/结尾,则其被视作一个普通文件,的内容将被直接写入到

六、WORKDIR指令

用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录
语法
WORKDIR
1、在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过,其是相对此前一个WORKDIR指令指定的路径
2、另外,WORKDIR也可调用由ENV指定定义的变量
例如:
WORKDIR /var/log
WORKDIR $STATEPATH

实例2:

构建目录:
image.png
Dockerfile

  1. # Description:test image
  2. FROM busybox:latest
  3. MAINTAINER "Evn.xiang"
  4. # LABEL mainrainer="Evn.xiang"
  5. ENV DOC_ROOT=/data/web/html/ \
  6. WEB_SERVER_PACKAGE="nginx-1.15.2.tar.gz"
  7. ADD http://nginx.org/download/${WEB_SERVER_PACKAGE} /usr/local/xsc/
  8. #ADD nginx-1.18.0.tar.gz /usr/local/src
  9. WORKDIR /usr/local
  10. ADD nginx-1.18.0.tar.gz ./src

构建状态
image.png
构建的镜像
image.png
运行的容器
# docker run —name testdockerfile1 —rm testdockerfile:v0.1-2 ls /usr/local/xsc /usr/local/src
image.png

七、VOLUME指令

用于在image中创建一个挂载点目录,以挂载Docker host上的卷或其他容器上的卷
语法
VOLUME
VOLUME [““]
如果挂载点目录路径下此前在文件存在,docker run命令会在卷挂在完成后将此前的所有文件复制到新挂载的卷中

八、EXPOSE指令

用于为容器打开指定要监听的端口以实现与外部通信
语法
EXPOSE [/][[/]…]
用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议
EXPOSE指令可一次指定多个端口,列如
EXPOSE 11211/udp 11211/tcp

九、ENV指令

1、用于为镜像定义所需要的环境变量,并可被Dockerfile文件中位于其后的其它指令(如ENV,ADD,COPY等)所调用
2、调用格式为$variable_name或${variable_name}
语法
ENV
ENV =
3、第一种格式中,之后的所有内容均会被视作其的组成部分,因此,一次只能设置一个变量
4、第二种格式可用一次设置多个变量,每个变量为一个”=“的键值对,如果中包含空格,可以以反斜线()进行转义,也可以通过如引号进行标识,另外,反斜线也可以用于续行
5、定义多个变量时,建议使用第二种方式,以便在同一层中完成所有功能

十、RUN指令

用于指定docker build过程中运行的程序,其可以是任何命令
语法
RUN
RUN [““,”“>]
●第一种格式中,通常是一个shell命令,且以”/bin/sh -c”来运行它,这意味着此进程在容器中的PID不为1,不能接收Unix信号,因此,当使用docker stop 命令停止容器时,此进程接收不到SIGTERM信号;
●第二种语法格式中的参数是一个JSON格式的数组,其中为要运行的命令,后面的 为传递给命令的选项或参数;然而,此种格式指定的命令不会以”/bin/sh -c”来发起,因此常见的shel操作如变 量替换以及通配符(?,*等)替换将不会进行;不过,如果要运行的命令依赖于此shell特性的话,可以将其替换为 类似下面的格式。
●RUN I”/bin/bash”, “-c”, ““, ““]
image.png

实例3

构建目录
image.png
Dockerfile

  1. # Description:test image
  2. FROM busybox:latest
  3. MAINTAINER "Evn.xiang"
  4. ENV DOC_ROOT=/data/web/html/ \
  5. WEB_SERVER_PACKAGE="nginx-1.15.2.tar.gz"
  6. VOLUME /data/mysql/
  7. EXPOSE 80/tcp
  8. ADD http://nginx.org/download/${WEB_SERVER_PACKAGE} /usr/local/xsc/
  9. RUN cd /usr/local/xsc && \
  10. tar -xf ${WEB_SERVER_PACKAGE} && \
  11. ls /usr/local/xsc

构建状态
image.png
构建的镜像
image.png
运行容器
image.png
image.png
image.png
image.png
image.png
image.png

十一、cmd指令

●类似于RUN指令,CMD指令也可用于运行任何命令或应用程序,不过,二者的运行时间点不同
●RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时
●CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,CMD指定的命令其可以被docker run的命令行选项所覆盖
●在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效
●Syntax
●CMD
●CMD ““,““,”“]或
●CMD [““,”“]
●前两种语法格式的意义同RUN
●第三种则用于为ENTRYPOINT指令提供默认参数

实例4

构建目录
image.png
Dockerfile

  1. FROM busybox
  2. LABEL maintainer="xiangshihchuan" app="httpd"
  3. ENV WEB_DOC_ROOT="/data/web/html/"
  4. RUN mkdir -p ${WEB_DOC_ROOT} && \
  5. echo "<h1>busybox httpd server.</h1>" >${WEB_DOC_ROOT}/index.html
  6. #CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
  7. CMD ["/bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]

构建过程
image.png
运行容器
image.png
image.png

十二、ENTRYPOINT指令

●类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序
●与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令 行参数会被当作参数传递给ENTRYPOINT指定的程序
●不过,docker run命令的—entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序
●语法
●ENTRYPOINT
●ENTRYPOINT l”“, ““, ““]
●docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用
●Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效
image.png
json数组中需要使用双引号,单引号会报错

  1. FROM busybox
  2. LABEL maintainer="xiangshihchuan" app="httpd"
  3. ENV WEB_DOC_ROOT="/data/web/html/"
  4. RUN mkdir -p ${WEB_DOC_ROOT} && \
  5. echo "<h1>busybox httpd server.</h1>" >${WEB_DOC_ROOT}/index.html
  6. #CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
  7. #CMD ["/bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
  8. ENTRYPOINT /bin/httpd -f -h ${WEB_DOC_ROOT}
  1. FROM nginx:alpine
  2. LABEL maintainer="xiangshichuan"
  3. ENV NGX_DOC_ROOT='/data/web/html/'
  4. ADD index.html ${NGX_DOC_ROOT}
  5. ADD entrypoint.sh /bin/
  6. EXPOSE 80/tcp
  7. HEALTHCHECK --start-period=3s CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT}:-80/
  8. CMD ["/usr/sbin/nginx","-g","daemon off;"]
  9. ENTRYPOINT ["/bin/entrypoint.sh"]
  1. #!/bin/sh
  2. cat > /etc/nginx/conf.d/www.conf <<EOF
  3. {
  4. server_name $HOSTNAME;
  5. listen ${IP:-0.0.0.0}:${PORT:-80};
  6. root ${NGX_DOC_ROOT:-/usr/share/nginx/html};
  7. }
  8. EOF
  9. exec "$@"

十三、USER指令

●用于指定运行image时的或运行Dockerfile中任何RUN、CMD或ENTRYPOINT指令指定的程序时的用户名或UID
●跌认情况下,container的运行身份为root用户
●Syntax
●USER |
●需要注意的是,可以为任意数字,但实践中其必须为/etc/passwd中某用户的有效UID,否则,docker run命令将运行失败

十四、HEALTHCHECK

HEALTHCHECK指令告诉容器引擎怎么去检测容器去测试是否依然正常工作
语法:包含两种语法格式
HEALTHCHECK [OPTIONS] CMD command (检测容器健康通过一个容器内部命令)
HEALTHCHECK NONE(禁用从基础镜像继承任何健康检测)
OPTIONS:
—inerval=DURATION (default:30s)
—timeout=DURATION(default:30s)
—start-period=DURATION(default:0s)
—retries=N(default:3)
命令退出状态返回值展示了容器的状态,可能值有
0:成功-容器是健康
1:不健康-容器没有正确工作
2:保留代码,不使用此代码
例如:
HEALTHCHECK —internel=5m —timeout=3s CMD curl -f http://localhost/ || exit 1

十五、SHELL指令

SHELL指令可以修改shell终端默认使用shell
linux默认的shell是[“/bin/sh”,”-c”],windows默认是[“cmd”,”/S”,”/C”]
在Dockerfile中SHELL指令必须是JSON格式
语法:SHELL [“executable”,”parameters”]
SHELL指令可以出现多次
每个SHELL指令覆盖所有以前的SHELL指令,并影响所有随后的指令。

十六、STOPSIGNAL指令

image.png

十七、ARG指令

image.png

十八、ONBUILD指令

用于在Dockerfile中定义一个触发器,ONBUILD用于配置当前所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。意思就是:这个镜像创建后,如果其它镜像以这个镜像为基础,会先执行这个镜像的ONBUILD命令
语法
ONBUILD
实例