文章目录
Dockerfile中的一系列指令
首先熟悉下配置信息
Docker通过对于在Dockerfile中的一系列指令的顺序解析实现自动的image的构建
通过使用build命令,根据Dockerfiel的描述来构建镜像
通过源代码路径的方式
通过标准输入流的方式
通过源代码路径
Dockerfile需要放置在项目的根目录位置
在构建的时候,Dockerfile client会把整个context打包发送到Docker Server端,然后由server端负责build镜像,在构建成功后,会删除context目录
docker build -t {镜像名字} {项目路径可以是相对路径}
docker利用Dockerfile来构建新镜像之前,先来了解一下Dockerfile创建中使用到的指令
通过标准输入流:
通过标准输入流的方式获取Dockerfile的内容
client不会打包上传context目录,因此对于一些ADD、COPY等涉及host本地文件复制的操作不能够支持
docker build -t {镜像名字} - < Dockerfile路径
build cache:
Dockerfile中的每一个指令执行完毕后,都会提交为一个image,这样保证了指令之间不会有影响
Dockerfile会尽可能尝试重用之前已经构建的镜像
可以通过在build命令中增加–no-cache的方式来禁用这个cache
Dockerfile指令:
只支持Docker自己定义的一套指令,不支持自定义
大小写不敏感,但是建议全部使用大写
根据Dockerfile的内容顺序执行
FROM:
FROM {base镜像}
必须放在DOckerfile的第一行,表示从哪个baseimage开始构建
MAINTAINER:
可选的,用来标识image作者的地方
RUN:
每一个RUN指令都会是在一个新的container里面运行,并提交为一个image作为下一个RUN的base
一个Dockerfile中可以包含多个RUN,按定义顺序执行
RUN支持两种运行方式:
RUN 这个会当作/bin/sh -c “cmd” 运行
RUN [“executable”,“arg1”,。。],Docker把他当作json的顺序来解析,因此必须使用双引号,而且executable需要是完整路径
RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 RUN command1 的执行仅仅是当前进程,一个内存上的变化而已,其结果不会造成任何文件。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。而如果需要将两条命令或者多条命令联合起来执行需要加上&&。如:cd /usr/local/src && wget xxxxxxx
CMD:
CMD的作用是作为执行container时候的默认行为(容器默认的启动命令)
当运行container的时候声明了command,则不再用image中的CMD默认所定义的命令
一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用
CMD定义的三种方式:
CMD 这个会当作/bin/sh -c "cmd"来执行
CMD [“executable”,“arg1”,…]
CMD [“arg1”,“arg2”],这个时候CMD作为ENTRYPOINT的参数
EXPOSE 声明端口
格式为 EXPOSE <端口1> [<端口2>…]。
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
entrypoint:
entrypoint的作用是,把整个container变成了一个可执行的文件,这样不能够通过替换CMD的方法来改变创建container的方式。但是可以通过参数传递的方法影响到container内部
每个Dockerfile只能够包含一个entrypoint,多个entrypoint只有最后一个有效
当定义了entrypoint以后,CMD只能够作为参数进行传递
entrypoint定义方式:
entrypoint [“executable”,“arg1”,“arg2”],这种定义方式下,CMD可以通过json的方式来定义entrypoint的参数,可以通过在运行container的时候通过指定command的方式传递参数
entrypoint ,当作/bin/bash -c "cmd"运行命令
ADD & COPY:
当在源代码构建的方式下,可以通过ADD和COPY的方式,把host上的文件或者目录复制到image中
ADD和COPY的源必须在context路径下
当src为网络URL的情况下,ADD指令可以把它下载到dest的指定位置,这个在任何build的方式下都可以work
ADD相对COPY还有一个多的功能,能够进行自动解压压缩包
ENV:
ENV key value
用来设置环境变量,后续的RUN可以使用它所创建的环境变量
当创建基于该镜像的container的时候,会自动拥有设置的环境变量
WORKDIR:
用来指定当前工作目录(或者称为当前目录)
当使用相对目录的情况下,采用上一个WORKDIR指定的目录作为基准
USER:
指定UID或者username,来决定运行RUN指令的用户
ONBUILD:
ONBUILD作为一个trigger的标记,可以用来trigger任何Dockerfile中的指令
可以定义多个ONBUILD指令
当下一个镜像B使用镜像A作为base的时候,在FROM A指令前,会先按照顺序执行在构建A时候定义的ONBUILD指令
ONBUILD <DOCKERFILE 指令>
VOLUME:
用来创建一个在容器和主机之间的共享文件夹;因为容器内的文件再关闭和销毁后就不存在了,因此文件数据持久化就需要把数据保存到容器外的主机磁盘上;
运行使用json array的方式定义多个volume
VOLUME [“/var/data1”,“/var/data2”]
或者plain text的情况下定义多个VOLUME指令
使用dockerfile构建springboot-demo
Dockerfile
FROM openjdk:8-jdk-alpine
MAINTAINER bamoo
ADD springboot-demo.jar springboot-demo.jar
RUN echo "Asia/Shanghai" >/etc/timezone
RUN sh -c 'touch /springboot-demo.jar'
ENV JAVA_OPTS=""
CMD exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /springboot-demo.jar
EXPOSE 8000
#构建镜像
docker build . -t springboot-demo:v1 -f Dockerfile
#查看镜像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
springboot-demo v1 3ed4b8bc215f 26 minutes ago 140MB
这样我们就构建好了一个springboot的简单镜像
运行这个镜像到容器中
docker run -d -p 8000:8000 --name demo-test springboot-demo:v1
#查看镜像容器进程是否启动
docker ps -a
#直接本地访问,返回数据运行正常
curl localhost:8000
hallo springboot
Dockerfile使用教程:实现nginx镜像和启动容器
[root@docker ~]# mkdir docker_demo
[root@docker ~]# cd docker_demo/
[root@docker docker_demo]# touch Dockerfile
[root@docker docker_demo]# pwd
/root/docker_demo
开始编写Dockerfile文件了(注意Dockerfile的D需要大写)
# base image
FROM centos
# MAINTAINER
MAINTAINER zjcjava@163.com
# put nginx-1.12.2.tar.gz into /usr/local/src and unpack nginx
ADD nginx-1.12.2.tar.gz /usr/local/src
# running required command
RUN yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel
RUN yum install -y libxslt-devel -y gd gd-devel GeoIP GeoIP-devel pcre pcre-devel
RUN useradd -M -s /sbin/nologin nginx
# change dir to /usr/local/src/nginx-1.12.2
WORKDIR /usr/local/src/nginx-1.12.2
# execute command to compile nginx
RUN ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-file-aio --with-http_ssl_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
ENV PATH /usr/local/nginx/sbin:$PATH
EXPOSE 80
执行docker build进行构建:
docker build -t centos_nginx:v1 .
后面的.代表的是相对路径的当前目录,如果需要全路径则为/root/docker_demo(就是找到Dockerfile文件)
查看新构建的镜像:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_nginx v1 78d18f16e757 4 hours ago 464MB
然后使用构建的镜像启动一个container并开启nginx服务:
docker run -d -p80:80 centos_nginx:v1 /usr/local/nginx/sbin/nginx -g "daemon off;"
如果设置了ENV环境变量指令ENV PATH /usr/local/nginx/sbin:$PATH,则可以缩写成下面的启动方式
docker run -d -p81:80 centos_nginx:v1 nginx -g "daemon off;"
查看端口映射信息:
[root@docker docker_demo]# docker port e4b6e4846ded
80/tcp -> 0.0.0.0:80
CMD指令
EXPOSE 80下面一行添加如下指令则 启动命令则省略了bath命令
CMD /bin/sh -c 'nginx -g "daemon off;"'
然后进行构建:
[root@docker docker_demo]# docker build -t centos_nginx:v3 .
基于v3版本的镜像启动一个container,则可以看到省略了bath相关的参数指令
docker run -d -p82:80 centos_nginx:v3
ocker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d988c04d04f4 centos_nginx:v3 "/bin/sh -c '/bin/..." 6 seconds ago Up 5 seconds 0.0.0.0:82->80/tcp optimistic_saha
CMD表示当启动一个container时默认运行的命令,如果在启动container时赋予了command的参数的话,那么
定义的CMD中的命令将不会被执行,而会去执行command的命令;如果省略了的话则直接执行CMD指令
当ENTRYPOINT和CMD连用
修改指令CMD如下
ENTRYPOINT ["nginx"]
CMD ["-g","daemon off;"]
CMD的命令是ENTRYPOINT命令的参数,两者连用相当于nginx -g “daemon off;”
而当一起连用的时候命令格式最好一致(这里选择的都是json格式的是成功的,如果都是sh模式可以试一下)
构建v4版本
docker build -t centos_nginx:v4 .
为v4版本的镜像启动一个container:
docker run -d -p83:80 centos_nginx:v4
VOLUME指令:
给容器添加磁盘卷,容器和主机之间共用file目录,方便文件存放
完整版如下:
[root@docker docker_demo]# cat Dockerfile
# base image
FROM centos
# MAINTAINER
MAINTAINER zjcjava@163.com
# put nginx-1.12.2.tar.gz into /usr/local/src and unpack nginx
ADD nginx-1.12.2.tar.gz /usr/local/src
# running required command
RUN yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel
RUN yum install -y libxslt-devel -y gd gd-devel GeoIP GeoIP-devel pcre pcre-devel
RUN useradd -M -s /sbin/nologin nginx
# mount a dir to container
VOLUME ["/data"]
# change dir to /usr/local/src/nginx-1.12.2
WORKDIR /usr/local/src/nginx-1.12.2
# execute command to compile nginx
RUN ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-file-aio --with-http_ssl_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
# setup PATH
ENV PATH /usr/local/nginx/sbin:$PATH
# EXPOSE
EXPOSE 80
# the command of entrypoint
ENTRYPOINT ["nginx"]
CMD ["-g"]
重新构建并启动容器
docker build -t centos_nginx:v6 .
docker run -d -p 86:80 --name=nginx6 centos_nginx:v6 -g "daemon off;"
利用docker exec进入到container中,查看是否存在卷/data:这个/data挂载的目录对应本机host的这个目录
Dockerfile之mysql
方式1:直接使用docker镜像
docker 安装 mysql 8 版本
# docker 中下载 mysql
docker pull mysql
#启动
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=Lzslov123! -d mysql
#进入容器
docker exec -it mysql bash
#登录mysql
mysql -u root -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Lzslov123!';
#添加远程登录用户
CREATE USER 'liaozesong'@'%' IDENTIFIED WITH mysql_native_password BY 'Lzslov123!';
GRANT ALL PRIVILEGES ON *.* TO 'liaozesong'@'%';
方法2使用dockerfile安装
[root@docker mysql]# cat Dockerfile
FROM centos
MAINTAINER json_hc@163.com
COPY MariaDB-10.0.33-centos7-x86_64-client.rpm /root/MariaDB-10.0.33-centos7-x86_64-client.rpm
COPY MariaDB-10.0.33-centos7-x86_64-common.rpm /root/MariaDB-10.0.33-centos7-x86_64-common.rpm
COPY MariaDB-10.0.33-centos7-x86_64-compat.rpm /root/MariaDB-10.0.33-centos7-x86_64-compat.rpm
COPY MariaDB-10.0.33-centos7-x86_64-server.rpm /root/MariaDB-10.0.33-centos7-x86_64-server.rpm
WORKDIR /root
RUN yum remove mysql-libs -y
RUN yum -y install *.rpm
ADD business.sql /root/business.sql
ADD server.cnf /etc/my.cnf.d/server.cnf
ADD setup.sh /root/setup.sh
RUN yum clean all
RUN chmod +x /root/setup.sh
EXPOSE 3306
CMD ["/root/setup.sh"]
参考资料
docker之Dockerfile实践
https://www.cnblogs.com/jsonhc/p/7767669.html