Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)

文章目录

    • 1. Dockerfile介绍
    • 2. Dockerfile指令说明
    • 3. 制作Centos镜像
        • 3.1 编写Dockerfile的文件
        • 3.2 通过这个文件构建镜像(注意最后加个点!!!)
        • 3.3 测试运行
    • 4. RUN,CMD和ENTRYPOINT的区别
        • RUN命令与CMD命令的区别在哪里?
    • 5. 实战:制作Tomcat镜像并发布镜像
      • 5.1 制作Tomcat镜像
      • 5.2 发布镜像到DockerHub
        • 5.3 发布镜像到阿里云容器服务
    • 6.Docker全流程总结小结
    • 7.常用命令整理
    • 8.不懂就搜
        • Docker学习笔记合集(持续更新)

1. Dockerfile介绍

​ Dockerfile是用来构建Docker镜像的文本文件,也可以说是命令参数脚本。docker build命令用于从Dockerfile构建镜像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile。

Docker镜像发布的步骤:

1、编写一个dockerfile文件

2、docker build 构建成为一个镜像

3、docker run 镜像

4、docker push 镜像(发布镜像到DockerHub、阿里云镜像仓库)

先从Docker官网进来CentOS里面看看:

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第1张图片

很多官方镜像都是基础包,很多功能都没有,我们通常会主机搭建自己的镜像!

官方既然可以制作镜像,那我们也可以!

示例一个镜像的结构图:

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第2张图片

Dockerfile 是面向开发的,以后发布项目,做镜像,就要编写dockerfile文件,这个文件非常简单!Docker镜像逐渐成为企业交付的标准,必须要掌握!

三步走:开发、部署、运维 缺一不可

DockerFile:构建文件,定义了一切的步骤,源代码

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品

Docker容器:容器就是镜像运行起来提供服务器

2. Dockerfile指令说明

关于DockerFile文件的脚本注意点有:

1、每个保留关键字(指令)都必须是大写字母

2、文件中的指令从上到下顺序执行,第一个指令必须是FROM

3、# 号表示注释

4、每一个指令都会创建提交一个新的镜像层,并提交!

指令 说明
FROM 指定基础镜像
MAINTAINER 镜像是谁写的,姓名+邮箱
RUN 镜像构建的时候需要运行的命令
ADD 将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
WORKDIR 镜像的工作目录
VOLUME 挂载的目录
EXPOSE 保留端口配置
CMD 指定这个容器启动的时候要运行的命令(只有最后一个会生效),可悲替代
EMTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD 当构建一个被继承DockerFile,这个时候就会运行ONBUILD的指令,触发指令
COPY 功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
ENV 构建的时候设置环境变量

一个形象的解释各个指令作用的图:

img

以前的话大部分是用别人的,现在就是用自己的!

Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。

关于Dockerfile指令的详细语法解释:Dockerfile文件详解

Dockerfile指令介绍的官方文档:https://docs.docker.com/engine/reference/builder/

3. 制作Centos镜像

Docker Hub中99%镜像都是从这个基础镜像过来的 FROM scratch

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第3张图片

3.1 编写Dockerfile的文件

​ 下面通过编写Dockerfile文件来制作Centos镜像,并在官方镜像的基础上添加vim和net-tools工具。首先在/home/dockfile 目录下新建文件mydockerfile-centos。然后使用上述指令编写该文件。

[root@zecan dockerfile]# cat mydockerfile-centos
FROM centos
MAINTAINER zecan<861328011@qq.com>

ENV MYPATH /user/local
WORKDIE $MYPATH

RUN yum -y install vim 
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash 

逐行解释该Dockerfile文件的指令:

FROM centos:该image文件继承官方的centos,后面加冒号如centos:7,用于指定镜像的版本

ENV MYPATH /usr/local:设置环境变量MYPATH ,后面有用到

WORKDIR $MYPATH:直接使用上面设置的环境变量,指定/usr/local为工作目录

RUN yum -y install vim和RUN yum -y install net-tools:在/usr/local目录下,运行yum -y install vim和yum -y install net-tools命令安装工具,注意安装后的所有依赖和工具都会打包到image文件中

EXPOSE 80:将容器80端口暴露出来,允许外部连接这个端口

CMD:指定容器启动的时候运行命令

通过这个dockerfile构建镜像,构建镜像命令:docker build -f dockerfile文件路径 -t 镜像名[:版本号] .(这里有个小点.)

上面命令中,-t参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。最后的那个点表示 Dockerfile 文件所在的路径,上例是当前路径,所以是一个点。

3.2 通过这个文件构建镜像(注意最后加个点!!!)

命令 dockers build -f 文件路径 -t 镜像名:[tag]

下面执行build命令生成image文件,如果执行成功,可以通过docker images来查看新生成的镜像文件。

[root@zecan dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
Sending build context to Docker daemon  2.048kB
Step 1/10 : FROM centos
 ---> 5d0da3dc9764
Step 2/10 : MAINTAINER zecan<861328011@qq.com>
 ---> Running in 5e2618d4c008
Removing intermediate container 5e2618d4c008
 ---> 3985b063c6a9
Step 3/10 : ENV MYPATH /user/local
 ---> Running in 7350d83ea95d
Removing intermediate container 7350d83ea95d
 ---> ff03b3e8018e
Step 4/10 : WORKDIR $MYPATH
 ---> Running in a12b974d4efb
Removing intermediate container a12b974d4efb
 ---> 700d6cec9746
Step 5/10 : RUN yum -y install vim
 ---> Running in 75a41969f718
Step 6/10 : RUN yum -y install net-tools
 ---> Running in ddc31e95af13
Last metadata expiration check: 0:00:14 ago on Wed Nov 17 03:33:49 2021.
Step 7/10 : EXPOSE 80
 ---> Running in 06fe5019fcbc
Removing intermediate container 06fe5019fcbc
 ---> 7df6436b8a38
Step 8/10 : CMD echo $MYPATH
 ---> Running in f40d2f06684a
Removing intermediate container f40d2f06684a
 ---> cffcdc10c516
Step 9/10 : CMD echo "----end----"
 ---> Running in bba0960d3417
Removing intermediate container bba0960d3417
 ---> 5f734cfc501d
Step 10/10 : CMD /bin/bash
 ---> Running in e085899c8b6e
Removing intermediate container e085899c8b6e
 ---> c4b84a15aefb
Successfully built c4b84a15aefb
Successfully tagged mycentos:0.1

3.3 测试运行

下面生成容器,测试相关命令,查看默认工作目录是否设置成功,vim和net-tools工具是否下载成功。

对比:原生的CentOS

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第4张图片

我们增加之后的镜像:

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第5张图片

另外,我们通过docker history 容器id命令来查看镜像的构建步骤。

可以列出本地镜像的变更历史 **docker history 镜像ID**,看一下mysql的

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第6张图片

4. RUN,CMD和ENTRYPOINT的区别

RUN命令与CMD命令的区别在哪里?

​ 简单说,RUN命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD命令则是在容器启动后执行。另外,一个 Dockerfile 可以包含多个RUN命令,但是只能有一个CMD命令。

​ 注意,指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否则它会覆盖CMD命令。

CMD和ENTRYPOINT的区别在哪里?

  • CMD :指定容器启动的时候要运行的命令,只有最后一个会生效

  • ENTRYPOINT :指定容器启动的时候要运行的命令,命令可以追加

首先是使用CMD指令

[root@zecan dockerfile]# vim dockerfile-CMD-test 
[root@zecan dockerfile]# cat dockerfile-CMD-test
FROM centos
CMD ["ls","-a"]
[root@zecan dockerfile]# docker build -f dockerfile-CMD-test -t cmdtest .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : CMD ["ls","-a"]
 ---> Running in 5c297beafad3
Removing intermediate container 5c297beafad3
 ---> ca06229997a1
Successfully built ca06229997a1
Successfully tagged cmdtest:latest
[root@zecan dockerfile]# docker run -it ca06229997a1
.   .dockerenv	dev  home  lib64       media  opt   root  sbin	sys  usr
..  bin		etc  lib   lost+found  mnt    proc  run   srv	tmp  var

#由于使用的是 CMD指令,命令无追加,-l取代了原本的ls -a,而-l命令不存在所以报错。
如果需要用,只能加完整命令
[root@zecan dockerfile]# docker run -it cmdtest -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.

可以看到追加命令-l 出现了报错。

下面使用更高级的命令:ENTRYPOINT来构建一个镜像

[root@zecan dockerfile]# vim dorkerfile-cmd-entrypoint
[root@zecan dockerfile]# cat dorkerfile-cmd-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]

[root@zecan dockerfile]# docker build -f dorkerfile-cmd-entrypoint -t entrypoint-test .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["ls","-a"]
 ---> Running in 2cad1d3c0bfa
Removing intermediate container 2cad1d3c0bfa
 ---> 5ef9eae1f783
Successfully built 5ef9eae1f783
Successfully tagged entrypoint-test:latest
[root@zecan dockerfile]# docker run 5ef9eae1f783

.dockerenv
bin
dev

# 可以追加命令 
[root@zecan dockerfile]# docker run 5ef9eae1f783 -l
total 56
drwxr-xr-x   1 root root 4096 Nov 17 04:50 .
drwxr-xr-x   1 root root 4096 Nov 17 04:50 ..
-rwxr-xr-x   1 root root    0 Nov 17 04:50 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  340 Nov 17 04:50 dev

[root@zecan dockerfile]# 

Dockerfile的很多命令都很相似,最高效的学习方式就是对比测试。

5. 实战:制作Tomcat镜像并发布镜像

5.1 制作Tomcat镜像

1.准备镜像文件tomcat、jdk压缩包

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第7张图片

(到官网下载,然后通过Xftp上传即可)

2.编写dockerfile文件,文件名使用官方命名:Dockerfile ,build的时候会默认寻找当前目录下的文件,不需要使用-f参数指定

[root@zecan tomcat]# vim Dockerfile
[root@zecan tomcat]# cat Dockerfile
FROM centos
MAINTAINER zecan<861328011@qq.com>

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u211-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.55.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_211
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.55
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.55
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_BASH/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.55/bin/logs/catalina.out 

3.使用该Dockerfile构建镜像

[root@zecan tomcat]# docker build -t diytomat .
Sending build context to Docker daemon  206.6MB
Step 1/15 : FROM centos
 ---> 5d0da3dc9764
Step 2/15 : MAINTAINER zecan<861328011@qq.com>
 ---> Using cache
 ---> 3985b063c6a9
Step 3/15 : COPY readme.txt /usr/local/readme.txt
 ---> 2155cd044ee3
Step 4/15 : ADD jdk-8u211-linux-x64.tar.gz /usr/local/
 ---> 6f01d4822e24
Step 5/15 : ADD apache-tomcat-9.0.55.tar.gz /usr/local/
 ---> 11851969fa84
Step 6/15 : RUN yum -y install vim
 ---> Running in 839a4868c4f1
(这里会卡比较久)
Complete!
Removing intermediate container 839a4868c4f1
 ---> 2f536132ffa0
Step 7/15 : ENV MYPATH /usr/local
 ---> Running in b255d9684079
Removing intermediate container b255d9684079
 ---> 8041894b3554
Step 8/15 : WORKDIR $MYPATH
 ---> Running in ef30711e32c4
Removing intermediate container ef30711e32c4
 ---> 8d81646632b1
Step 9/15 : ENV JAVA_HOME /usr/local/jdk1.8.0_251
 ---> Running in db9ba64f3d66
Removing intermediate container db9ba64f3d66
 ---> 645c12997ae2
Step 10/15 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
 ---> Running in 772fbf67d0c8
Removing intermediate container 772fbf67d0c8
 ---> cf882ea0ecce
Step 11/15 : ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.55
 ---> Running in 8f4be02d8973
Removing intermediate container 8f4be02d8973
 ---> ddab1e64171a
Step 12/15 : ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.55
 ---> Running in 451db0a33dcb
Removing intermediate container 451db0a33dcb
 ---> 86071d4b4b43
Step 13/15 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_BASH/bin
 ---> Running in 43d24ca9dfbf
Removing intermediate container 43d24ca9dfbf
 ---> 09b3687a9254
Step 14/15 : EXPOSE 8080
 ---> Running in 154d2460fa53
Removing intermediate container 154d2460fa53
 ---> 101adc79334d
Step 15/15 : CMD /usr/local/apache-tomcat-9.0.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.55/bin/logs/catalina.out
 ---> Running in c449e423132c
Removing intermediate container c449e423132c
 ---> bb6e73fa1192
Successfully built bb6e73fa1192
Successfully tagged diytomat:latest

4.启动生成的镜像,构建Tomcat容器.

这里设置了数据卷,宿主机的/home/dockerfile/tomcat/test对应该容器的/usr/local/apache-tomcat-8.5.55/webapps/test。这样关于test项目的修复只需要在宿主机上修改就可以了,不需要进入到容器中修改。

[root@zecan tomcat]# docker run -d -p 8088:8080 --name zecantomcat 
-v /home/zecan/build/tomcat/test:/usr/local/apache-tomcat-9.0.55/webapps/test 
-v /home/zecan/build/tomcat/tomcatlogs/:/url/local/apache-tomcat-9.0.55/logs diytomcat
a9411141240a39bbee678e4ab81f80446be6ee3f7aca8c27b8104382b0fca255

# 可测试
[root@zecan tomcat]# curl localhost:8088

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第8张图片

5.在/home/dockerfile/tomcat/test的目录下,新建web.xml和index.jsp 测试Tomcat是否能正常使用。

因为设置了卷挂载所以可以直接在宿主机中进行操作。

[root@zecan WEB-INF]# vim web.xml
[root@zecan WEB-INF]# cat web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
          
web-app>
[root@zecan WEB-INF]# vim index.jsp
[root@zecan WEB-INF]# cat index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello,Zack!title>
head>
<body>
Hello World!<br/>
<%
System.out.println("-----my text web logs----");
%>
body>
html>

方法二是在test文件后面新建一个index.html

DOCTYPE html>
<html>
    <head>
         <meta charset="UTF-8"/>
        <title>这是个标题title>
    head>
    <body>
        <h1>这是一个一个简单的HTMLh1>
        <p>Hello World!p>
    body>
html>

6.访问测试,浏览器访问查看是否能正常访问

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第9张图片

之前出现过下面这个问题,主要是路径错误,找不到该文件!

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第10张图片

如果页面显示乱码,就需要修改tomcat的server.xml文件

  <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="UTF-8" />

这里是添加了一个属性:URIEncoding,将该属性值设置为UTF-8,即可让Tomcat(默认ISO-8859-1编码)以UTF-8的编码处理get请求。

5.2 发布镜像到DockerHub

1.登录https://hub.docker.com/ DockerHub官网进行注册

2.进行登录,docker login -u 用户名

登录命令

[root@zecan tomcat]# docker login --help

Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username

[root@zecan tomcat]# docker login -u zackliu123
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

3.使用docker push命令推送镜像到DockerHub上的仓库

[root@zecan tomcat]# docker push diytomcat
Using default tag: latest
The push refers to repository [docker.io/library/diytomcat]
067e3a36b33e: Preparing 
a156f0e946d1: Preparing 
cfbcf4623ab9: Preparing 
6ab15adb2ef5: Preparing 
74ddd0ec08fa: Preparing 
denied: requested access to the resource is denied  #拒绝

# 解决:增加tag
[root@zecan tomcat]# docker tag e323f58e6fba zecan/tomcat:1.0
[root@zecan tomcat]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED             SIZE
diytomcat             latest    e323f58e6fba   About an hour ago   716MB
zecan/tomcat          1.0       e323f58e6fba   About an hour ago   716MB

# 尽量带上版本号
[root@zecan tomcat]# docker push zecan/tomcat:1.0
The push refers to repository [docker.io/zecan/tomcat]
067e3a36b33e: Preparing 
a156f0e946d1: Preparing 
cfbcf4623ab9: Preparing 
6ab15adb2ef5: Preparing 
74ddd0ec08fa: Preparing 
denied: requested access to the resource is denied
# 也是按镜像的层级来上传的,虚拟机网络限制是基本无法push成功的

因为push的时候,镜像名前面需要加上用户名(zackliu123是我的用户名。如果用户名不是当前登录用户则会拒绝push请求),所以需要使用命令docker tag 镜像名 新的镜像名复制出一份镜像重新打个Tag。

5.3 发布镜像到阿里云容器服务

1.登录阿里云,找到容器镜像服务

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第11张图片

2.创建命名空间

  • 登录容器镜像服务控制台,在左侧导航栏选择实例列表,在实例列表页面单击个人版,在个人版管理页面左侧导航栏中选择仓库管理 > 命名空间。在命名空间页面左上角单击创建命名空间,输入命名空间名称,然后单击确定说明
  • 目前一个账号可以创建3个命名空间。

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第12张图片

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第13张图片

3.与上面DockerHub的操作类似,按官方提供的操作指南操作即可。

[root@zecan tomcat]# docker login --username=小灿zack registry.cn-shenzhen.aliyuncs.com
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[root@zecan tomcat]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
diytomcat             latest    e323f58e6fba   2 hours ago     716MB
zecan/tomcat          1.0       e323f58e6fba   2 hours ago     716MB
[root@zecan tomcat]# docker push zecan/tomcat:1.0
The push refers to repository [docker.io/zecan/tomcat]
067e3a36b33e: Preparing 
a156f0e946d1: Preparing 
cfbcf4623ab9: Preparing 
6ab15adb2ef5: Preparing 
74ddd0ec08fa: Preparing 
denied: requested access to the resource is denied

遇到过问题:上传自己的镜像被拒绝denied: requested access to the resource is denied

解决:根本就是tag重命名的镜像你要结合阿里云的路径,总之按指引说的三条命令严格执行即可!

Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)_第14张图片

最后可以在这里看到自己的镜像以及层信息等等。

6.Docker全流程总结小结

img

img

7.常用命令整理

8.不懂就搜

Docker删除容器与镜像

要删除全部image(镜像)的话

docker rmi $(docker images -q) 1

强制删除全部image的话

docker rmi -f $(docker images -q)

问题:curl(56) Recv failure: Connection reset by peer以及解决方案

  • linux下ps ef命令详解,linux命令中ps -ef详解

实测确实是路径问题

[

](https://blog.csdn.net/weixin_39621488/article/details/116554036)

Linux删除文件命令

  • 单个删除:rm -f + 文件名

    • eg:rm -f 2018_12_26.stderrout.log.060121612 --执行完成即将这个文件删除
  • 批量删除:rm -f + *文件关键字*

Docker学习笔记合集(持续更新)

linux入门–服务器购买—宝塔部署环境说明
Nginx简单入门–学习笔记狂神说
Docker基础01–入门总结–(狂神说docker学习笔记)
Docker基础02–Docker容器数据卷详解–(狂神说docker学习笔记)
Docker基础03–Dockerfile详解与镜像发布–(狂神说docker学习笔记)
Docker基础04–Docker网络–(狂神说docker学习笔记)
Docker进阶01–Docker Compose–(狂神说docker学习笔记)

Docker知识点翻阅手册–Docker常用命令、Dockererfile、Compose、网络等整理合集
Docker实战:Mysql、Nginx、web的Docker化部署(安装、自定义镜像、compose管理容器、自定义网络、部署问题及解决)

你可能感兴趣的