Kubernetes教程(四)Dockerfile构建镜像

发布于:2025-03-06 ⋅ 阅读:(8) ⋅ 点赞:(0)

一、前言

1. Dockerfile是什么?

  • 在 Docker 中,Dockerfile 是一个纯文本文件,包含了一系列指令,用于定义如何构建一个 Docker 镜像
  • Dockerfile的文件名必须为 Dockerfile,没有扩展名。

2. 为什么要用Dockerfile

当我们编写好SpringBoot程序后,要把它运行到Docker容器中,那就得需要该项目的镜像,有镜像才能运行容器。而Dockerfile就可以把Java程序构建成镜像。当然也不止是Java程序,Docker镜像库也包含MySQL、Redis等,所以我们也构建Vue项目、自定义的Redis等镜像。流程为:编写 Dockerfile 文件 -> docker build 命令构建镜像 -> docker run 以镜像运行容器实例。
在这里插入图片描述

二、Dockerfile格式

  • Dockerfile一个名为 Dockerfile纯文本文件(文件名必须为 Dockerfile,没有扩展名)
  • 每条指令都必须为大写字母,且后面要跟随至少一个参数
  • 指令按照从上到下,顺序执行

下面假设一名Java程序员小王🐶,他写好了SpringBoot项目,然后想把该项目部署到Docker容器中,并能在主机访问容器中的项目接口。

FROM

FROM指定基础镜像Dockerfile的第一条指令就是FROM
你用Java写的SpringBoot项目,你要根据Java的版本是什么,来指定Java基础镜像。
如果你写的是Python项目,那就指定Python对应版本的基础镜像。

使用openjdk17轻量版本作为基础镜像(slim表示轻量镜像,去除了不必要的工具)
FROM openjdk:17-jdk-slim

使用openjdk8极简镜像
FROM openjdk:8-alpine

使用官方的 Python 3.9 作为基础镜像
FROM python:3.9-slim

程序员小王🐶使用Java8开发的,所以他的Dockerfile文件内容可以如下:

# 使用openjdk8的slim轻量版
FROM openjdk:8-slim

MAINTAINER

MAINTAINER指令用于标记镜像的作者信息,以便用户在使用镜像时能够找到相关的维护者信息。

MAINTAINER your_name <your_email@example.com>

程序员小王🐶 想把他自己的信息写上,这样别人用这个镜像时,都知道是他这个大佬开发的了😎。于是Dockerfile内容如下:

# 使用openjdk8的slim轻量版
FROM openjdk:8-slim

# 镜像作者信息
MAINTAINER xiao wang <xiao.wang@example.com> 

WORKDIR

WORKDIR是设置工作目录,指定在创建容器后,终端默认登陆进来的目录,一个落脚点。
程序员小王🐶 设置容器内的工作目录为/app,于是Dockerfile内容如下:

# 使用openjdk8的slim轻量版
FROM openjdk:8-slim

# 镜像作者信息
MAINTAINER xiao wang <xiao.wang@example.com> 

# 设置容器工作目录
WORKDIR /app

COPY

COPY是将本机指定的文件或目录复制到镜像中,当通过该镜像生成容器时,容器中的目标路径就会有拷贝的内容。

COPY <源路径> <目标路径>
  • <源路径>:指定要复制的文件或目录在构建上下文内的路径,可以是相对路径或绝对路径。
  • <目标路径>:指定要将文件或目录复制到容器内的路径,必须是容器内的绝对路径。

程序员小王🐶把Dockerfile文件和target目录放同一层,target目录下的my-spring-boot-app.jar就是工程jar包,当容器运行后,要把my-spring-boot-app.jar先拷贝并重命名到容器内/app/app.jar

# 使用openjdk8的slim轻量版
FROM openjdk:8-slim

# 镜像作者信息
MAINTAINER xiao wang <xiao.wang@example.com> 

# 设置容器工作目录
WORKDIR /app

# 将jar包拷贝到容器的/app目录并重命名
COPY target/my-spring-boot-app.jar /app/app.jar 

ADD

ADD 指令的作用是将源文件或目录复制到容器的文件系统中。它可以从 Docker 构建上下文(build context)中的本地文件系统中复制文件,也可以从远程 URL 下载文件并添加到容器中。看到这,感觉和COPY比较类似,但是如果是压缩包,ADD还可以解压,而且ADD的源路径是支持远程的哦。
同样需求下,官方推荐使用 COPY。

ADD <源路径> <目标路径>

将远程文件拷贝到容器/app/目录下
ADD https://example.com/file.txt /app/

# 添加所有以"tes"开头的文件
ADD|COPY tes* /mydir/    

# 添加 "test" 到 WORKDIR/mydir/
ADD|COPY test mydir/     

# 添加 "test" 到 /opt/
ADD|COPY test /opt/      

请注意以下几点:

  • 如果 <目标路径> 是一个以 “/” 结尾的目录路径,那么源路径的基本名称将用作目标路径中的文件或目录名。
  • 如果 <目标路径> 是一个不存在的目录,Docker 将自动创建该目录。
  • 如果 <源路径> 是一个目录,Docker 将递归复制该目录及其内容。
  • 如果 <源路径> 是一个文件或 URL,Docker 将复制该文件或从 URL 下载文件。
  • 如果 <源路径> 是一个通配符表达式,Docker 将复制匹配该表达式的文件或目录

EXPOSE

EXPOSE是声明容器运行时监听的端口,程序员小王🐶想暴露 Spring Boot 应用的端口为8088,于是Dockerfile内容如下:

# 使用openjdk8的slim轻量版
FROM openjdk:8-slim

# 镜像作者信息
MAINTAINER xiao wang <xiao.wang@example.com> 

# 设置容器工作目录
WORKDIR /app

# 将jar包拷贝到容器的/app目录并重命名
COPY target/my-spring-boot-app.jar /app/app.jar

# 设置端口为8088
EXPOSE 8088

ENTRYPOINT

ENTRYPOINT用于配置容器启动时要执行的默认应用程序或命令。

ENTRYPOINT ["可执行文件", "参数1", "参数2", ...]
ENTRYPOINT command param1 param2 ...
ENTRYPOINT ["命令", "参数1 参数2", "参数3"]

程序员小王🐶想到执行app.jar的命令是java -jar app.jar,于是他又在Dockerfile中加了一行:

# 使用openjdk8的slim轻量版
FROM openjdk:8-slim

# 镜像作者信息
MAINTAINER xiao wang <xiao.wang@example.com> 

# 设置容器工作目录
WORKDIR /app

ARG JAR_FILE=my-spring-boot-app.jar

# 将jar包拷贝到容器的/app目录并重命名
COPY target/${JAR_FILE} /app/app.jar

# 设置端口为8088
EXPOSE 8088

# 设置启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]

RUN 和 CMD

  • RUN: 执行命令并创建新的镜像层。当你需要在镜像构建过程中安装软件包或应用程序时,就会用到 RUN。每执行一次 RUN 就会在镜像上添加一个新的层。
  • CMD:设置容器启动后默认执行的命令及其参数。不过,CMD 指定的命令可以通过 docker run 命令行参数来覆盖。它主要用于为容器设定默认启动行为。如果 Dockerfile 中有多个 CMD 指令,只有最后一个生效
RUN apt-get update && apt-get -y install redis-server

CMD格式:
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)

ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

# 格式:
ENV <key> <value>
ENV <key>=<value>
# 示例:
ENV myName John
ENV myCat=tomcat

# 配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk-11
ENV PATH $JAVA_HOME/bin:$PATH

三、构建SpringBoot项目镜像

1. 创建SpringBoot项目

我们使用阿里云的SpringBoot创建地址:https://start.aliyun.com
创建一个最简单的SpringBoot项目,勾选有SpringMVC就可以。
在这里插入图片描述
在pom文件中,加上文件名为my-spring-boot-app,并设置skip为false(为了让jar包能启动)。
在这里插入图片描述

2. 使用Dockerfile构建镜像

打包后将target/my-spring-boot-app.jarDockerfile都传到服务器,执行构建镜像命令:

注意最后的点
docker build -t my-spring-boot-app .

查看镜像,看有没有多一个名为my-spring-boot-app的镜像
docker images
  • -t my-spring-boot-app:指定镜像的名称为 my-spring-boot-app

  • 最后的点.表示当前目录是构建上下文,Docker 会查找当前目录下的 Dockerfile

在这里插入图片描述

3. 启动容器并测试接口

从镜像启动容器
docker run -d --name dockerfile_test_project -p 8088:8088 my-spring-boot-app

查看已经启动的容器,发现多了一个容器
docker ps

在这里插入图片描述
测试下容器中的接口,有返回说明访问容器内接口没有问题

curl http://127.0.0.1:8088/hello?name=lisi

4. 进入容器

进入容器
docker exec -it dockerfile_test_project /bin/bash

发现进入容器后默认目录就是配置的工作目录/app
在这里插入图片描述
参考文档:
https://www.cnblogs.com/miaocbin/p/15245836.html
https://blog.csdn.net/qq_47959003/article/details/142833781


网站公告

今日签到

点亮在社区的每一天
去签到