docker之Dockerfile实践

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:
  用来创建一个在image之外的mount point,用来在多个container之间实现数据共享
  运行使用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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值