说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!
文章目录
- 一、Dockerfile语法
- 1.前言
- 2.FROM关键字
- 3.LABEL关键字
- 4.RUN关键字
- 5.WORKDIR关键字
- 6.ADD和COPY关键字
- 7.ENV关键字
- 8.VOLUME(存储)和EXPOSE(网络)关键字
- 9.RUN 和 CMD 和 ENTRYPOINT
- 二、Docker Image发布
一、Dockerfile语法
1.前言
这里只是简单的描述Dockerfile关键字,具体的详解可以查阅官方文档
在github有一个group,里面有很多官方提供的docker image并提供了Dockerfile构建文件,可以查看这些Dockerfile,从中学习,也可以通过download Dockerfile文件,通过这个Dockerfile文件就可以build一个跟官方一样的image,如下查看mysql5.7版本的Dockerfile
2.FROM关键字
定义:基础镜像,当前新镜像是基于哪个镜像的
尽量使用官方的image作为base image,这样安全
3.LABEL关键字
定义:为镜像指定标签
Metadata不可少
4.RUN关键字
定义:在镜像中要执行的命令
为了美观,复杂的RUN请用反斜线换行!避免无用分层,合并多条命令成一行!
5.WORKDIR关键字
定义:指定当前工作目录,相当于 cd
用WORKDIR,不要用RUN cd!尽量使用绝对目录!
6.ADD和COPY关键字
COPY定义:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
ADD定义:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
大部分情况,COPY优于ADD!ADD除了COPY还有额外功能(解压)!添加远程文件/目录请使用curl或者wget
7.ENV关键字
定义:用来在构建镜像过程中设置环境变量,指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持,如ENV MY_PATH /usr/local/bin,这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量,比如:WORKDIR $MY_PATH
尽量使用ENV增加可维护性
8.VOLUME(存储)和EXPOSE(网络)关键字
VOLUME定义:容器数据卷,用于数据存储和持久化工作,创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等
EXPOSE定义:告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口
关于VOLUME和EXPOSE会在之后的文章中进行使用介绍
9.RUN 和 CMD 和 ENTRYPOINT
RUN:执行命令并创建新的Image Layer
CMD:设置容器启动后默认执行的命令和参数
ENTRYPOINT:设置容器启动时运行的命令
9.1 Shell和Exec格式
Shell格式 把要运行的命令当成shell命令去执行
Exec格式 通过特定的格式去指明要运行的命令以及命令参数
9.2 ENTRYPOINT关键字
- 让容器以应用程序或者服务的形式运行
- 不会被忽略,一定会执行
- 最佳实践:写一个shell脚本作为entrypoint
Dockerfile(Shell格式)
Dockerfile(Exec格式)
- 查看以上两个Dockerfile build出来的image,通过docker run运行容器,查看区别,首先创建Shell格式的Dockerfile使用ENTRYPOINT关键字,运行容器成功打印出hello Docker
- 修改Dockerfile文件,使用Exec格式,运行结果并没有替换定义的name常量的值,原因很简单,因为数据格式是shell,容器是基于centos(linux)系统,所以直接是在bash里面,就能通过shell去执行这个命令,而使用Exec格式只会单纯的执行echo命令并不会将其看做成shell命令,所以后面的$name不会识别替换
- 解决方法就是,指明要运行的命令是通过shell去运行的,也就是在/bin/bash里面执行命令,通过-c 指明后面的为命令字符串
9.3 CMD关键字
- 容器启动时默认执行的命令
- 如果docker run指定了其它命令,CMD命令被忽略
- 如果定义了多个CMD,只有最后一个会被执行
- 现在将Dockerfile文件中ENTRYPOINT关键字换成CMD关键字,并创建image,创建并运行容器,成功打印出hello Docker
- 现在使用docker run指定了其它命令,验证CMD命令被忽略,并没有打印hello Docker
- 而使用docker run 指定其他命令,运行Dockerfile文件使用ENTRYPOINT关键字构建出来的image,验证ENTRYPOINT不会被忽略,一定会执行成功打印出
二、Docker Image发布
说明: 之前文章有详细实操演示从Docker Hub(类似GitHub)上去pull拉取个人或官方build好的image,对于个人来讲,自己build的image也可以分享出来,将自己的image贡献出来,让他人可以使用,就跟在github一样提倡OpenSource精神
1.第一种方式(推送到Docker Hub)
1.1 Push Image to Docker Hub
- 首先注册账户登录Docker hub,点击Repositories就可以到目前账户下的仓库,博主这里没有
- 现在就将之前创建的cdtaogang/hello-world镜像,push到Docker hub上,需要说明的是push的镜像名的格式应该是你docker hub的用户名/镜像名,不然push的时候会提示权限问题,在执行docker push命令之前,需要执行docker login输入用户名密码进行登录
- 刷新仓库页面,就能看到刚刚push到仓库的image了
1.2 Pull Image from Docker Hub
- 点击镜像进入概括,可以看到镜像的描述、标签、自述以及push新版本,因为构建image时并没有添加描述,所以肯定是空的
- 切换到Tags标签,可以看到拉取该镜像的命令
- 现在博主将本地的cdtaogang/hello-world镜像进行删除,执行docker rmi删除镜像命令提示,该镜像创建的容器正在使用,所以博主将所有的容器进行删除后,再删除该镜像
- 删除后,pull拉取我们push的image
2.第二种方式(关联Github自动构建)
说明: 将Docker Hub链接到Github上(请注意:一个Github / Bitbucket帐户一次只能连接到一个Docker Hub帐户),在GIthub上创建一个代码仓库,将本地build image的Dockerfile文件push到代码仓库上,并让Docker Hub仓库与Github代码仓库进行关联,只要这个代码仓库中存在Dockerfile文件,Docker Hub就会自动去克隆这个代码仓库获取到Dockerfile,然后Docker Hub服务器就会自动帮我们去build image,这样的话,我们既提供了image的Dockerfile,又使Docker Hub 服务器自动帮我们build image,安全性就比较高了
2.1 链接到Github
- 首先将Docker Hub链接到Github上,点击如下账户设置
- 点击关联账号,就可以看到可以关联Github和Bitbucket账户
- 点击Connect进行授权
- 链接成功,显示github账户
2.2 将Dockerfile文件git到GitHub仓库
- 通过git工具将本地Dockerfile文件上传到github test仓库
- 刷新github上的test仓库,成功上传Dockerfile
- 为了给大家演示支持多分支多版本,所以博主又在github test仓库创建一个font分支
– 查看Dockerfile文件内容
2.3 Docker Hub Repositories关联Github Repositories并进行自动构建
- 紧接着回到Docker Hub上,页面定位到Repositories存储库,点击Create Repositories创建一个存储库,点击已之前已链接的Github,选择用户及对应的仓库,点击BUILD RULES添加构建规则,选择Github上的分支,以及设置Tag和Dockerfile路径,最后点击创建仓库并进行构建
- 点击创建并构建后,会跳转到仓库常规界面,可以看到正在加载两个build构建
- 切换到Builds页签,现在构建的状态为正在进行和挂起等待
- 构建成功如下
- 点击Recent Builds最近构建,可以查看构建时的日志
- 回到仓库基本页面,可以对这两个自动构建的image,选择Tag进行pull拉取
2.4 更新提交Dockerfile测试Docker Hub自动构建
- 首先修改本地的Dockerfile,这里博主就只提交到master分支进行演示,将端口号修改为6380,重新提交到Github上
- 回到Docker Hub上刷新页面,自动检测关联的Github test仓库中的Dockerfile文件,实现自动构建,因为博主只更新了master分支,所以font分支则不会被检测到形成自动构建,顺便说一下更新font分支,则只需要指定分支进行push即可git push origin master:font
3.第三种方式(搭建个人的Docker Hub)
说明: 对于公司或者说个人比较重要的image不想放在官方Docker Hub上,公开的都能访问,私有的需要花钱并且有些公司级的image即使放在私有仓库也有可能被泄露,所以这里搭建一个私有的Docker Hub自己可以去进行维护,这个私有的Docker Hub没有web界面只供我们个人或者公司使用,Docker Hub官网为我们提供了一个名叫registry的image,通过这个image就可以在本地或者其他服务器机器上搭建一个私人的Docker Hub
3.1 在服务器上搭建Docker Hub(Docker Registry)
- 首先在Dokcer Hub官网上,搜索registry这个image,点击进入该image,可以看到官方提供的使用文档
- 需要准备一台linux机器,并且安装了docker,博主这里再搭建一个centos7的机器命名为centos7_2(当作一个服务器)并已安装了docker
- 回到centos7中,需要ping通centos7_2服务器
- 在centos7_2中,需要执行官方提供的在本地快速运行registry镜像
docker run -d -p 5000:5000 --restart always --name registry registry:2
- 安装并运行registry镜像成功
3.2 Push Image to My Docker Hub
- 首先需要保证在centos7中,telnet 服务器5000端口成功,出现以下提示表示成功
- 然后需要将要push的image的tag需要命名为服务器(centos7_2)IP加上端口号,首先将之前的cdtaogang/hello-world镜像删除,重新构建
- 重新构建一个tag为服务器IP加端口的image
- 此时在进行push image之前需要配置,在/etc/docker目录下创建一个名为daemon.json文件(有就不需要创建了),进行如下配置添加信任,不然会任务我们创建的Docker Hub(192.168.88.211:5000)是不可信任的
- 以上配置了daemon.json文件,需要到/lib/systemd/system/docker.service配置文件中添加EnvironmentFile=-/etc/docker/daemon.json,让启动dockerd进程时读取daemon.json环境的文件,配置就会被加载
- 重启docker服务
- 然后就可以push到个人的docker hub上了
3.3 验证Push Image to My Docker Hub成功
- 因为私有的Docker Registry没有web界面,需要在官方提供的API接口来查询验证是否push成功,查看Listing Repositories列表库接口文档
- 输入服务器IP加上端口号/v2/_catalog请求地址,根据返回的json数据来验证是否push image到私人docker registry成功,如果返回的json数据显示我们push的image名称,则表示成功将image push到私人Docker Hub(Docker Registry)上
评论前必须登录!
注册