Dockerfile
什么是Dockerfile?
Dockerfile可以看做是被Docker程序所解释翻译的脚本,由一组命令集合而成,每一条命令都对应一条操作命令,有其翻译为Linux下的具体命令。用户可以通过自定义内容来快速构建镜像。
构建docker镜像时有两种方式,一种是用commit的方式构建镜像,而Dockerfile是另一种构建镜像的方式。
Dockerfile构建镜像是以基础镜像为基础的,Dockerfile是一个文本文件,内容是用户编写的一些docker指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
Dockerfile的基本指令有十三个,分别是:FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、USER、WORKDIR、ONBUILD.
学习Dockerfile之前,我们先来学习一些Dockerfile常用的指令。
Dockerfile常用指令:
| 类型 | 命令 |
| 基础镜像信息 | FROM |
| 维护者信息 | MAINTAINER |
| 镜像操作指令 | RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER、VOLUME ENV等 |
| 容器启动时执行指令 | CMD、ENTRYPOINT |
1、FROM指令
两种形式如下:
FROM <IMAGE>
FROM <IMAGE>:<TAG>
通过FROM指定的镜像名称必须是一个已经存在的镜像,这个镜像称之为基础镜像,必须位于第一条非注释指令。
2、MAINTAINER 指令
指定镜像的作者信息,包含镜像的所有者和联系人信息。
MAINTAINER <NAME>
3、RUN 指令
用于指定构建镜像时运行的命令,两种模式:
RUN <command> (shell模式) RUN [ "executable", "param1", "param2" ] (exec模式)
多条RUN指令可以合并为一条,这样在构建的时候会减少产生中间层镜像。
RUN cd /usr/src/nginx-1.10.2 \ && mkdir /usr/local/nginx \ && ./configure --prefix=/usr/local/nginx && make && make install \ && nginx
4、EXPOSE 指令
指定运行该镜像的容器使用的端口,可以是多个。
EXPOSE <端口1> [<端口2>...]
使用这个指令的目的是告诉应用程序容器内应用程序会使用的端口,在运行时还需要使用-p参数指定映射端口。这是docker处于安全的目的,不会自动打开端口。
docker run --name tomcat -p 8080:8080 -v /root/webapps:/usr/local/tomcat/webapps/ -d tomcat
5、CMD 指令
CMD 命令用于容器启动时需要执行的命令,CMD 在 Dockerfile 中只能出现一次,如果出现多个,那么只有最后一个会有效。
其作用是在启动容器的时候提供一个默认的命令项。如果用户执行docker run的时候提供了命令项,就会覆盖掉这个命令,没提供就会使用构建时的命令。
格式:
shell 格式: CMD <命令> exec 格式: CMD ["可执行文件", "参数1", "参数2"...]
如容器启动时进入bash:
CMD /bin/bash
也可以用exec写法:
CMD ["/bin/bash"]
6、ENTRYPOINT指令
与CMD类似,ENTRYPOINT不会被docker run中指定的命令覆盖,如果想覆盖ENTRYPOINT,则需要在docker run中指定--entrypoint选项.
它有两种模式:
ENTRYPOINT <command> (shell模式) ENTRYPOINT [ "executable", "param1", "param2" ] (exec模式)
7、ADD 和 COPY 指令
作用都是将文件或目录复制到Dockerfile构建的镜像中
COPY [--chown=<user>:<group>] <源路径>... <目标路径> COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"] ADD [--chown=<user>:<group>] <源路径>... <目标路径> ADD [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
ADD包含了类似tar的解压功能,如果只是单纯复制文件,建议使用COPY,而且,两者的源文件路径使用Dockerfile相对路径,目标路径使用绝对路径。
8、VOLUME 指令
用于向容器添加卷,可以提供共享存储等功能
VOLUME ['/data']
9、WORKDIR 指令
在容器内部设置工作目录,这样ENTRYPOINT和CMD指定的命令都会在容器中这个目录下进行,如果切换到的目录不存在,WORKDIR会为此创建目录。
WORKDIR /path/to/workdir
10、USER 指令
指定运行容器时的用户,需要注意的是这个用户必须是已经存在,否则无法指定.
USER daemon
镜像就会以daemon身份运行,可以使用uid,gid等各种组合使用
11、ENV 指令
ENV 指令用于设置容器的环境变量,这些变量以”key=value”的形式存在,在容器内被脚本或者程序调用,容器运行的时候这个变量也会保留。
1) 设置一个: ENV <key> <value> 2) 设置多个:ENV <key1>=<value1> <key2>=<value2>...
12、ONBUILD 指令
ONBUILD 用于配置当前所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令,意思就是:这个镜像创建后,如果其它镜像以这个镜像为基础,会先执行这个镜像的ONBUILD命令.
ONBUILD [INSTRUCTION]
实例:
使用dockerfile构建Nginx镜像
1.在某一个目录下面创建一个专门存放此demo的目录.
[root@localhost ~]# mkdir -p docker_demo/nginx [root@localhost ~]# cd docker_demo/nginx [root@localhost nginx]# touch Dockerfile [root@localhost nginx]# pwd /root/docker_demo/nginx
2.接下来就开始编写Dockerfile文件了,这里以编译nginx提供web服务来构建新的镜像.
1、>下载nginx源码包到docker_demo这个目录下
[root@localhost nginx]# ll -rw-r--r-- 1 root root 386 May 6 11:13 dockerfile -rw-r--r-- 1 root root 885562 Nov 17 2015 nginx-1.9.7.tar.gz
2、> 以下是编写好的Dockerfile:
FROM centos:7 MAINTAINER saneri 838118461@qq.com RUN yum install -y wget proc-devel net-tools gcc zlib zlib-devel make openssl-devel #RUN wget http://nginx.org/download/nginx-1.9.7.tar.gz ADD nginx-1.9.7.tar.gz . WORKDIR nginx-1.9.7 RUN ./configure --prefix=/usr/local/nginx && make && make install EXPOSE 80 ENV PATH /usr/local/nginx/sbin:$PATH CMD /bin/sh -c 'nginx -g "daemon off;"'
3、> 执行docker build进行构建:
[root@localhost nginx]# docker build -t nginx_centos .
构建成功后,查看新构建的镜像:
[root@localhost nginx]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx_centos latest 4c79631898cb 21 minutes ago 366 MB
4、>然后使用构建的镜像启动一个container并开启nginx服务:
[root@localhost ~]# docker run -d -p80:80 --name nginx_centos nginx_centos
5、> 查看container运行状态:
[root@localhost ~]# docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b7ce7b4ca2e3 nginx_centos "/bin/sh -c '/bin/..." 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp nginx_centos
5.> 测试nginx 80 端口访问
[root@localhost ~]# lsof -i:80 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME docker-pr 45542 root 4u IPv6 472743 0t0 TCP *:http (LISTEN) [root@localhost ~]# curl -I http://192.168.10.20:80 HTTP/1.1 200 OK Server: nginx/1.9.7 Date: Wed, 06 May 2020 09:20:24 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Wed, 06 May 2020 03:32:24 GMT Connection: keep-alive ETag: "5eb22fc8-264" Accept-Ranges: bytes [root@localhost ~]#
使用Dockerfile安装centos7镜像,并完成ssh连接
1.创建一个专门存放此demo的目录.
[root@localhost ~]# mkdir -p docker_demo/ssh_centos/ [root@localhost ~]# cd docker_demo/ssh_centos/ [root@localhost ssh_centos]# touch Dockerfile [root@localhost ssh_centos]# pwd /root/docker_demo/ssh_centos
2.以下是编写好的Dockerfile:
FROM centos:7 MAINTAINER saneri 838118461@qq.com # 更新yum源 RUN yum makecache fast && yum -y update glibc # 安装常用软件 RUN yum install -y openssh-server vim tar wget curl rsync bzip2 iptables tcpdump less telnet net-tools lsof # 初始化ssh登陆 RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N '' RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N '' RUN echo '123456' | passwd --stdin root RUN echo "RSAAuthentication yes" >> /etc/ssh/sshd_config RUN echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config # 启动sshd服务并且暴露22端口 RUN mkdir /var/run/sshd EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
3.执行docker build进行构建:
[root@localhost ssh_centos]# docker build -t sshd_centos7 .
构建成功后,查看新构建的镜像:
[root@localhost ssh_centos]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE sshd_centos7 latest 96657c13c530 45 minutes ago 422 MB
4.启动容器,将ssh容器的22端口映射为15000端口.
[root@localhost ~]# docker run -d --name sshd_centos7 --rm -p 15000:22 sshd_centos7 5995979a12e2e408be38fb3dd4c26451219458a6b583f056449bc29767ff3023
查看容器启动情况
[root@localhost ssh_centos]# docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5995979a12e2 sshd_centos7 "/usr/sbin/sshd -D" 41 minutes ago Up 41 minutes 0.0.0.0:15000->22/tcp sshd_centos7
5.进入容器并开启ssh连接,回车两次,其中有个警告,可以忽略.
[root@localhost ssh_centos]# docker exec -it sshd_centos7 /bin/bash [root@5995979a12e2 /]# /usr/sbin/sshd -D & [1] 81 [root@5995979a12e2 /]# /etc/ssh/sshd_config line 140: Deprecated option RSAAuthentication [1]+ Exit 255 /usr/sbin/sshd -D [root@5995979a12e2 /]#
6.查看是否已经启动:lsof -i:22,出现如下信息则表示启动成功
[root@5995979a12e2 /]# lsof -i:22 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1 root 3u IPv4 523483 0t0 TCP *:ssh (LISTEN) sshd 1 root 4u IPv6 523489 0t0 TCP *:ssh (LISTEN)
7.进行ssh远程登录测试,输入密码后测试连接成功.

使用dockerfile构建tomcat镜像,并发布war包
1.上传tomcat包和jdk的包至服务器目录,文件目录结构如下.
[root@localhost dockerfile]# tree -L 1 tomcat tomcat ├── apache-tomcat-8.5.51.tar.gz ├── Dockerfile └── jdk-8u65-linux-x64.tar.gz 0 directories, 3 files
2.编写dockerfile文件,内容如下
FROM centos:7 MAINTAINER saneri #将宿主机的jdk目录下的文件拷至镜像的/usr/local目录下 ADD jdk-8u65-linux-x64.tar.gz /usr/local/ #将宿主机的tomcat目录下的文件拷至镜像的/usr/local目录下 ADD apache-tomcat-8.5.51.tar.gz /usr/local/ #设置环境变量 ENV JAVA_HOME=/usr/local/jdk1.8.0_65 ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.51 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin #公开端口 EXPOSE 8080 #设置启动命令 CMD ["/usr/local/apache-tomcat-8.5.51/bin/catalina.sh","run"]
3.构建镜像
[root@localhost tomcat]# docker build -t local/tomcat7-jdk1.8 . -f Dockerfile
镜像生成后,使用 docker images 查看本地镜像,如下
[root@localhost tomcat]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE local/tomcat7-jdk1.8 latest aac779847112 6 hours ago 583 MB
4.创建容器:
[root@localhost tomcat]# docker run -d -p 8080:8080 --name tomcat7-jdk1.8 local/tomcat7-jdk1.8:latest 86aa4f015c436c6b71511638df98d37e23301e877673dc7506334a8e832b57d0
5.查看容器,并验证也可以在浏览器中直接输入ip:port。
[root@localhost tomcat]# docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 86aa4f015c43 local/tomcat7-jdk1.8:latest "/usr/local/apache..." 2 minutes ago Up 2 minutes 0.0.0.0:8080->8080/tcp tomcat7-jdk1.8 [root@localhost tomcat]# [root@localhost tomcat]# curl -I http://192.168.10.20:8080 HTTP/1.1 200 Content-Type: text/html;charset=UTF-8 Transfer-Encoding: chunked Date: Sat, 09 May 2020 15:27:41 GMT
6.下载helloworld.war包,放入容器的webapps目录下即可.
docker cp helloworld.war 86aa4f015c43:/usr/local/apache-tomcat-8.5.51/webapps/
这样所有的java应用都可以用此方法在tomcat中运行了.

浙公网安备 33010602011771号