docker镜像构建
镜像的构建实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的
docker镜像构建
发布时间:2023-10-17 (2023-10-17)

镜像的构建实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

自定义nginx镜像

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自定义Dockerfile</title>
</head>
<body>
自定义Dockerfile
</body>
</html>

FROM nginx:latest

COPY index.html /usr/share/nginx/html/

构建镜像

docker build -t nginx:v3 .

启动容器

docker run --name ng -itd -p 81:80 nginx:v3

指定构建的dockerfile

docker build -t nginx:v4  -f xxx_dockerfile .

Dockerfile相关命令

FROM

FROM指定一个基础镜像, 一般情况下一个可用的 Dockerfile一定是 FROM 为第一个指令。至于image则可以是任何合理存在的image镜像。 FROM 一定是首个非注释指令 Dockerfile. FROM 可以在一个 Dockerfile 中出现多次,以便于创建混合的images。 如果没有指定 tag ,latest 将会被指定为要使用的基础镜像版本。

ENV 设置环境常量

简单的说,它就是一个全局常量,被设置后,进入容器内部,在任意位置都可以访问这个常量的值,比如# echo $var_bl。 好比本地设置了JAVA_HOME环境变量一样,在CMD窗口任意目录,都可以打印/获取该常量。

ENV WORKPATH /tmp
ENV http_proxy ""
ENV JAVA_HOME /usr/local/openjdk8
ENV test=mayun-xiaoma
ENV mycat=mimi
 
RUN $JAVA_HOME/bin/java-jar test.jar

ENV指令可以用于为docker容器设置环境变量 ENV设置的环境变量,可以使用 docker inspect命令来查看。同时还可以使用docker run --env =来修改环境变量。

USER USER

用来切换运行属主身份的。Docker 默认是使用 root,但若不需要,建议切换使用者身分,毕竟 root 权限太大了,使用上有安全的风险。

Dockerfile指定USER用户后, 后续的命令 RUN、CMD、ENTRYPOINT 都将使用该用户

WORKDIR 设置工作目录

WORKDIR 设置的,目录需要是绝对路径,如果不存在,会自动创建。

在Dockerfile最外层首次出现,则是指明通过docker exec -it 进入容器内部后,默认进入的工作目录(无需再用cd命令切换)。

如果Dockerfile中命令比较多,需要来回切换工作目录,则可以随时再次定义新的WORKDIR

WORKDIR /usr/local
WORKDIR /usr/local/newdir #如果不存在会被自动创建,尽量使用绝对路径

ADD & COPY 将宿主机的文件上传到镜像中

add除了复制,还具备添加远程文件功能(文件以http://开头),类似于linux的wget

add是增强版的copy,add自带解压,copy不带解压。两者都支持目录中有空格。

1、ADD指令不支持认证,从远程获取资源如果需要认证(交互),则只能使用RUN wget或RUN curl替代。 2、如果不是需要解压,优先使用COPY命令,效率更高、更节省资源。

ADD hello  /         #把hello从宿主机复制到容器内部的根路径
ADD test.tar.gz  /   #把压缩包从宿主机添加到容器的根目录后,自动解压
ADD hello .          #把hello文件复制到当前workdir工作目录的根目录
COPY test.txt /etc/nginx   #仅从宿主机复制文件到容器内部的指定目录
ADD demo.tar.gz /usr/share/nginx/html   #复制文件,并自动解压到指定目录

RUN & CMD & ENTRYPOINT 运行指令

三者都是执行命令,但是它们的执行时机是不同的

RUN 仅在Build构建时执行的命令
CMD 用来设置容器启动后默认执行的命令(参数),它可被docker run后面的命令参数替换;
ENTRYPOINT 容器run启动时执行的命令

RUN 在生成镜像时需要执行的命令

#示例,演示run命令的两种不同写法
RUN yum install -y vim #Shell命令格式 
RUN ["yum "," install" ,"-y","vim"] #Exec命令格式

Dockerfile中的RUN命令,只有在docker build 命令构建镜像时会自动运行,docker run的时候,并不会运行(注意,部分精简版的镜像,本身只提供最基础的linux命令比如vi,不自带vim)。

CMD用来设置容器启动后默认执行的命令(参数)

作用:可以单独使用,但不一定会被执行,也可作为其他命令的补充参数使用

dockerfile 中如果存在多个CMD指令,仅能保证最后一个生效。

在dockerfile 文件中,RUN后面可以包含CMD命令,此时它前面的CMD可能会被忽略。

ENTRYPOINT 容器启动时需要执行的命令

如果有ENTRYPOINT,则不会执行cmd

命令执行的顺序

FROM nginx:latest

RUN echo "run的命令1"
RUN echo "run的命令2"
CMD ["echo", "cmd命令1"]
CMD ["echo", "cmd命令2"]

构建时,输出结果

run的命令1
run的命令2

docker run 的输出结果

docker run xxx
cmd命令2
docker run xxx echo "xxx"
xxx

EXPOSE 指令指定在docker允许时指定的端口进行转发。

EXPOSE参数在Dockerfile中是可以不写(docker run -p时依然可以指定暴露端口),

为了规范化Dockerfile,让读者对其外暴露的端口一目了然,建议还是要写。

#docker run -d -p 8000:8080   

8080 就是容器内对外暴露的端口,-p 极具灵活性。 

参考文章

https://blog.csdn.net/succing/article/details/122379519