DockerFile
  VxbKCNpUI3P6 2023年11月30日 26 0

一、DockerFile是什么?

DockerFile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本,构建三步骤:

  1. 编写Dockerfile文件
  2. docker build
  3. docker run

那么DockerFile文件案例如下:

FROM scratch
ADD centos-7-x86_64-docker.tar.xz /

LABEL \
    org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20201113" \
    org.opencontainers.image.title="CentOS Base Image" \
    org.opencontainers.image.vendor="CentOS" \
    org.opencontainers.image.licenses="GPL-2.0-only" \
    org.opencontainers.image.created="2020-11-13 00:00:00+00:00"

CMD ["/bin/bash"]

二、DockerFile构建过程解析

2.1.DockerFile内容基础

Dockerfile中的指令需要满足如下的规则:

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  2. 指令按照从上到下,顺序执行
  3. #表示注释
  4. 每条指令都会创建一个新的镜像,并对镜像镜像提交

2.2.docker 执行Dockerfile的流程

docker执行一个Dockerfile脚本的流程大致如下:

  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器做出修改
  3. 执行类似docker commit的操作提交一个新的镜像层
  4. docker在基于刚提交的镜像运行一个新容器
  5. 执行dockerfile中的下一条指令直到所有指令都执行完成

2.3.说明

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,

  • Dockerfile是软件的原材料
  • Docker镜像是软件的交付品
  • Docker容器则可以认为是软件的运行态。

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

DockerFile_tomcat

  1. Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
  2. Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;
  3. Docker容器,容器是直接提供服务的。

三、DockerFile体系结构(保留字指令)

指令

说明

FROM

基础镜像,当前新镜像是基于哪个镜像的,有继承的意味

MAINTAINER

镜像维护者的姓名和邮箱地址

RUN

容器构建时需要运行的命令

EXPOSE

当前容器对外暴露的端口

WORKDIR

指定在创建容器后,终端默认登录的进来工作目录,一个落脚点

ENV

用来在构建镜像过程中设置环境变量

ADD

将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包

COPY

类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置 COPY ["src","dest"]

VOLUME

容器数据卷,用于数据保存和持久化工作

CMD

指定一个容器启动时要运行的命令Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换

ENTRYPOINT

指定一个容器启动时要运行的命令ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数

ONBUILD

当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发

DockerFile命令

BUILD

BOTH

RUN

FROM

WORKDIR

CMD

MAINTAINER

USER

ENV

COPY

 

EXPOSE

ADD

 

VOLUME

RUN

 

ENTRYPOINT

ONBUILD

 

 

.dockerignore

 

 

四、案例演示

4.1.Base镜像(scratch)

Docker Hub 中99%的镜像都是通过在base镜像中安装和配置需要的软件构建处理的,

在dockerhub中搜索Tomcat,地址如下:https://hub.docker.com/,

DockerFile_docker_02

点击查看镜像构成:

DockerFile_docker_03

4.2.自定义镜像mycentos

我们从官方pull下来的centos镜像是mini版的,所以不带有vim、ifconfig这些基础命令,那我们就来自定义一个镜像,功能比官方下载的强大点,同时运用下各个指令。

4.2.1.编写dockerfile

Hub默认Centos镜像什么情况?

DockerFile_Dockerfile_04

自定义mycentos目的使我们自己的镜像具备如下:

  • 登陆后的默认路径
  • vim编辑器
  • 查看网络配置ifconfig支持

首先我们来编写对应的Dockerfile文件。内容如下:

# 指定基础镜像
FROM centos:7
# 镜像维护者的姓名和邮箱地址
MAINTAINER augus<11200297@qq.com>

# 在构建镜像过程中设置环境变量
ENV MYPATH /usr/local
# 指定在创建容器后,终端默认登录的进来工作目录
WORKDIR $MYPATH

# 镜像构建时需要运行的命令
RUN yum -y install vim
RUN yum -y install net-tools

# 当前容器对外露出的端口
EXPOSE 80

# 指定一个容器启动时要运行的命令
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash

操作如下:

DockerFile_docker_05

4.2.2.构建

语法如下:

docker build -f dockerfile名称 -t 新建的镜像名:TAG .

注意:

  • docker build 命令最后有一个 .                                 
  •  . 表示当前目录,

案例如下:

docker build -f dockerfile2 -t mycentos:100 .

执行后结果

DockerFile_docker_06

4.2.3.运行

根据之前构建的镜像生成容器,语法如下:

docker run -it 新镜像名字:TAG

执行命令如下:

DockerFile_tomcat_07

4.2.4.列出镜像的变更历史

语法如下:

docker history 镜像名

执行如下:

DockerFile_Dockerfile_08

在本例中我们用到了 FROMMAINTAINERRUNEXPOSEENVWORKDIR 命令

4.3.CMD/ENTRYPOINT镜像案例

接下来我们通过案例来看看CMDENTRYPOINT两个命令的区别,这两个命令的作用都是指定一个容器启动时要运行的命令

4.3.1.CMD

Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换掉,我们通过tomcat的案例来介绍。正常情况如下

docker run -it -p 8888:8080 tomcat

执行后,可以成功运行Tomcat

DockerFile_tomcat_09

但是当我们在 执行命令后添加参数的话,如下

DockerFile_docker_10

原因是我们先看Tomact对应的 Dockerfile文件,最后面是启动Tomcat的,而我们添加参数后,就将下面的命令给覆盖了,所以容器无法运行(就相当于有了多个CMD)。

DockerFile_Dockerfile_11

4.3.2.ENTRYPOINT

有别于CMD命令,ENTRYPOINT命令是在 docker runcurl指令来介绍这个案例。Dockerfile文件如下:

FROM centos:7
MAINTAINER Augus<Auguses@126.com>

ENV MY_PATH /usr/local/
WORKDIR $MY_PATH

RUN yum install -y curl

EXPOSE 80

ENTRYPOINT [ "curl", "-s", "http://www.baidu.com" ]

构建镜像,如下:

docker build -f dockerfile3 -t myapp .

DockerFile_Dockerfile_12

正常执行run命令,创建容器,如下:

DockerFile_tomcat_13

-i参数 查看响应报文头

DockerFile_Dockerfile_14

通过这个例子 可以看到ENTRYPOINT不会覆盖,而是组合成了一个新的命令。

4.4.自定义镜像Tomcat

最后我们通过自定义一个tomcat镜像来介绍下ADDCOPY这两个命令的区别。

4.4.1.创建个tomcat目录

在dockerfile下创建tomcat目录

DockerFile_Dockerfile_15

4.4.2 添加一个文件

在当前目录下创建一个 hello.txt文件,作用是COPY到容器中

DockerFile_tomcat_16

4.4.3.拷贝相关软件

准备对应的jdktomcat的压缩文件。上传到tomcat目录:

DockerFile_docker_17

4.4.4.创建Dockerfile文件

创建文件tomcatfile,内容如下:

FROM centos
MAINTAINER Augus<Auguses@126.com>

# 把主机的hello.txt 拷贝到容器的/usr/local/路径下
COPY hello.txt /usr/local/helloincontainer.txt
# 把jdk和tomcat添加到容器中/usr/local
ADD jdk-8u172-linux-x64.tar.gz /usr/local
ADD apache-tomcat-8.5.43.tar.gz /usr/local

# 设置工作访问时候的WORKDIR路径,进入容器的落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH

# 配置tomcat和java的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_172
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.43
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.43
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

# 容器运行暴露的端口
EXPOSE 8080

# 启动tomcat
CMD /usr/local/apache-tomcat-8.5.43/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.43/logs/catalina.out

4.4.5.构建镜像

执行命令:

docker build -f tomcatfile -t java8/tomcat:8 .

DockerFile_Dockerfile_18

4.4.6.生成容器

构建成功后,我们就可以运行了,命令如下:

docker run -d -it -p 8082:8080 --name mytomcat8.5 -v /mydockerfile/tomcat/test:/usr/local/apache-tomcat-8.5.43/webapps/ -v /mydockerfile/tomcat/tomcatlogs/:/usr/local/apache-tomcat-8.5.43/logs --privileged=true 镜像ID

执行后如下:

DockerFile_tomcat_19

4.4.7.生成容器测试访问:

在浏览器输入:http://192.168.42.131:8082,访问如下:这里访问没有内容是因为webappes目录下是空的,但是不影响使用

DockerFile_tomcat_20

我们在test目录放入war包,如下:

DockerFile_tomcat_21

然后在浏览器访问,如下:

DockerFile_tomcat_22

五、虚悬镜像

虚悬镜像:仓库名、标签名都是 <none>的镜像,称为 dangling images(虚悬镜像)。

在构建或者删除镜像时可能由于一些错误导致出现虚悬镜像。例如:

1)在myfile目录下创建Dockerfile内容如下:

FROM centos
CMD echo "action is success"

2)构建镜像

# 构建时候没有镜像名、tag
docker build .

3)列出docker中的虚悬镜像:

docker image ls -f dangling=true

4)虚悬镜像一般是因为一些错误而出现的,没有存在价值,可以删除:

# 删除所有的虚悬镜像
docker image prune

DockerFile_Dockerfile_23

六、Dockerfile基于centos7定制java8容器

需要在容器中安装java8,同时安装vim,在myfile中上传文件如下:

DockerFile_Dockerfile_24

编写dockerfile如下:

FROM centos:7
MAINTAINER Augus<Auguses@126.com>

# 设置工作访问时候的WORKDIR路径,进入容器的落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH

# 安装vim编辑器
RUN yum -y install vim
# 安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
# 把jdk和tomcat添加到容器中/usr/local/java,注意Dockerfile和安装包必须在同一个位置
ADD jdk-8u172-linux-x64.tar.gz /usr/local/java

# 配置tomcat和java的环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_172
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

EXPOSE 80

CMD echo $MYPATH
CMD echo "success------------ok"
CMD /bin/bash

构建镜像如下:

docker build -f Dockerfile1 -t openjdk:8-oracle .

七、Docker发布微服务

7.1.创建springboot项目

搭建一个简单的SpringBoot项目,在pom.xml中导入依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.augus</groupId>
    <artifactId>springboot_docker</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>springboot_docker</name>
    <description>springboot_docker</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.12.RELEASE</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.augus.SpringbootDockerApplication</mainClass>
                    <fork>true</fork>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

在application.yaml中指定端口

server:
  port: 6001

在controller包中创建OrderController,如下:

@RestController
public class OrderController {
    @Value("${server.port}")
    private String port;

    @RequestMapping("/order/docker")
    public String helloDocker(){
        return "hello world \t" + port + "\t" + UUID.randomUUID().toString();
    }

    @RequestMapping("/order/index")
    public String index(){
        return "服务端口号:" + "\t" + port + "\t" + UUID.randomUUID().toString();
    }
}

启动项目,然后在浏览器访问

DockerFile_tomcat_25

在Idea中运行没有问题时,将其使用maven的package打成jar包。操作如下:

DockerFile_tomcat_26

7.2.发布微服务项目到Docker容器

7.2.1.将jdk和jar上传到Linux服务器的myfile目录

上传后结果如下:

DockerFile_Dockerfile_27

7.2.2.编写dockerfile

利用基础镜像java:8构建,在Dockerfile内容如下:

# 基础镜像利用java:8完成
FROM java:8
# 作者
MAINTAINER Augus<Auguses@126.com>

#VoLUME指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp

#将jar包添加到容器中并更名为augus_docker.jar
ADD springboot_docker-0.0.1-SNAPSHOT.jar augus_docker.jar

#运行jar包
RUN bash -c 'touch /augus_docker.jar'
ENTRYPOINT ["java","-jar", "/augus_docker.jar"]
#暴露6001端口作为微服务
EXPOSE 6001

7.2.3.构建镜像

执行如下命令

docker build -f Dockerfile -t springboot_docker:1.0 .

执行如下:

DockerFile_Dockerfile_28

7.2.4.利用镜像创建容器

docker run -d -p 6001:6001 --name springboot springboot_docker:1.0

执行后如下:

DockerFile_tomcat_29

7.2.5.测试

在浏览器访问:使用主机ip和端口6001访问:

DockerFile_Dockerfile_30



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

上一篇: docker镜像文件 下一篇: Halo2简单示例
  1. 分享:
最后一次编辑于 2023年11月30日 0

暂无评论

推荐阅读
VxbKCNpUI3P6