Dockerfile关键字

Dockerfile是用于构建docker镜像的脚本文件,通过编写脚本,可以实现自定义镜像。

Dockerfile关键字

FROM

基础镜像,Dockerfile第一条指令必须是FROM。
例如,下列就表示使用ubuntu的最新版本最为基础镜像。

FROM ubuntu:latest

MAINTAINER

镜像作者,例如:

MAINTAINER lixingwu@aliyun.com

LABEL

LABEL为镜像增加元数据,一个LABEL是键值对,多个键值对之间使用空格分开,命令换行时是使用反斜杠\
建议使用LABEL指令替换MAINTAINER指令,例如:

LABEL author="lixingwu"
LABEL email="lixingwu@aliyun.com"
LABEL version="1.0"
LABEL description="This is my Dockerfile."

添加后可使用 docker inspect指令查看到添加的信息。

image-20220822231204655

RUN

构建容器时运行的shell脚本。

# 运行安装net-tools命令
RUN yum install net-tools

每一行RUN指令会生成一层Layer,所以尽量减少使用使用RUN指令,可以用&&把多个命令写在同一个RUN指令中,以减少Layer的层数。例如:

RUN apt-get update && \
	apt-get install -y wget && \
	mkdir /home/temp && \
	cd /home/temp && \
	touch readme.md

EXPOSE

声明对外暴露的端口,只起到声明作用,告诉使用者,运行该镜像可以映射的端口。只有在使用-p指令映射端口后才能通过端口访问到镜像。

例如,nginx镜像提供80和443端口,就可以在dockerfile文件中使用如下命令声明:

EXPOSE 80
EXPOSE 443

WORKDIR

在进入容器时,默认的目录,起到落脚点的作用。例如:

WORKDIR /home

此时,在进入启动容器后,就会自动定位到指定的目录/home,主要用于快速定位到目标目录。假设是nginx容器,我们希望进入容器后就直接定位到nginx所在的目录,而不是让我们手动切换过去。

USER

指定镜像运行时的用户,通常情况下,为了保证容器的安全性,我们都不会使用直接使用容器里面的root用户。
因为root用户权限太高,容易访问系统文件,失误修改到关键文件,容易导致容器崩溃
我们通常会为容器创建一个非root的用户,然后赋予我们工作目录的操作权限,保证该用户只会操作我们允许操作的目录和文件。

在使用USER指令时,我们需要先保证该用已经存在,如果不存在,可以手动创建用户:

RUN useradd -m -d /home/nginx -s /bin/sh -f -1 -c "this is a nginx" nginx
USER nginx

在构建完成后,我们进入容器,登录的用户就是设置的nginx用户。

docker build -t mynginx:0.0.1 .
docker run -it mynginx:0.0.1

# 使用whoami可查看当前登录用户,
# 因为我们在Dockerfile中使用USER指令指定了,所以登录后就是我们指定的用户
nginx@cd4ee8b6a39a:/$ whoami
nginx

ENV

容器运行时环境变量。

# 定义项目根目录
ENV WORK_PAYH /usr/work

# 使用环境变量
WORKDIR $WORK_PAYH

这些定义的环境变量可在运行时被覆盖,比如,我们在dockerfile文件中定义环境变量。

ENV BASE_URL lhttp://ocalhost:8888

然后我们在启动时覆盖掉,容器里的环境变量就会被覆盖

docker run -it -e BASE_URL=http://localhost:9999 mynginx:0.0.2

# 在容器中输出BASE_URL环境变量,已被覆盖
nginx@1fe788f36758:/$ echo $BASE_URL
http://localhost:9999

ADD

把宿主机下的文件拷贝到容器,如果是tar压缩包会自动解压,url会自动下载

# 把文件 myhostconfig.conf ,加入到容器 /home/nginx/ 目录下
ADD myhostconfig.conf /home/nginx/

# 把文件 myhostconfig.conf ,加入到容器 /home/nginx/ 目录下,并重新命名为 my.conf
ADD myhostconfig.conf /home/nginx/my.conf

# 把 app.tar.gz 解压到容器 /home/app/ 目录下
ADD app.tar.gz /home/app/

# 把网络资源下载到 /home/java/ 目录下
ADD https://files.cnblogs.com/files/lixingwu/app.tar.gz /home/app1/

# 把当前目录所有文件拷贝到容器/home/temp/目录下
ADD . /home/temp/

# 把当前目录下的txt文件,复制到容器/home/txt/目录下
ADD *.txt /home/txt/

# 把文件夹data下的内容拷贝到到/home/mydata/目录下,拷贝的文件不能有反斜杠
ADD data /home/mydata/
# 如果需要复制文件夹,把目标目录也设置为同名文件夹即可
ADD data /home/data/

注意:

  1. 下载网络资源的压缩包不会自动解压,而且还会使镜像文件变大,如果需要解压网络资源,可以使用RUN指令下载、解压、删除操作。

  2. 在复制全部文件时,如果需要忽略其中的一些文件,可以定义.dockerignore文件进行排除,.dockerignore语法和.gitignore语法一致。

  3. 文件名尽量不要出现中文,不然复制时会被转码。

  4. 指令只拷贝目录中的内容而不包含目录自身

COPY

把宿主机下的文件,原封不同的复制到镜像容器下。该指令只能复制本地的文件,而且也不会自动解压压缩包。大多数情况都是使用copy指令,只有需要自动下解压和自动下载url时才需要add指令。

copy指令的规则和add指令一致,复制本地文件、文件夹可平替,而且copy语义上也更符合我们的操作。

COPY app.tar.gz /home/copy/app/
COPY . /home/copy/temp/
COPY *.txt /home/copy/txt/
COPY data /home/copy/mydata/
COPY data /home/copy/data/

VOLUME

挂载容器卷,持久化数据库到宿主机,效果和-v一样。

例如:需把主机的/tmp/nginx挂在到容器的/tmp就可以写成

VOLUME ["/tmp/nginx","/tmp"]

CMD

用于指定默认的容器主进程启动命令。
可以使用 shell 脚本的方式,例如:CMD java -jar app.jar
也可以使用exec的方式:例如:CMD["java", "-jar", "app.jar"]
cmd指令只能写一个,存在多个只有最后一个生效。

如果在run时加入参数,CMD指令会被覆盖,例如:

docker run -it -p 8080:8080 tomcat /bin/bash

此时,/bin/bash参数会把CMD指令覆盖,会导致app没有启动起来。

ENTRYPOINT

用于指定默认的容器主进程启动命令,不会被run时加入参数覆盖,会把参数传递给ENTRYPOINT指令。

例如:ENTRYPOINT["java", "-jar", "app.jar"],在启动时传入参数:

docker run -it -p 8080:8080 tomcat --spring.profiles.active=test

此时,启动参数就会变成:

java -jar app.jar --spring.profiles.active=test

构建镜像

使用build执行构建脚本,命令最后的一个点是表示构建市时的上下文,点表示在执行命令的当前目录。

在构建时,docker会在上下文中找到Dockerfile文件,然后根据文件编写的脚本镜像镜像构建,其中imagename表示镜像的名字,tag表示镜像的版本,镜像名字可用重复,但是标签不可以,如果出现同名同标签时会覆盖存在的镜像文件。

docker build -t [imagename]:[tag] .

文章使用脚本源码:gitee

posted @ 2022-10-07 15:02  喵喵扑  阅读(194)  评论(0编辑  收藏  举报