0
点赞
收藏
分享

微信扫一扫

微信小程序 picker-view 组件构建一个上下拖动选择器

醉东枫 2023-10-24 阅读 38

参考官方文档:https://docs.docker.com/engine/reference/builder/

Dockerfile常用指令

指令说明
from基础镜像,当前镜像基于(依赖)哪个镜像
maintainer镜像的维护者和邮箱
run镜像构建时需要执行的命令
workdir镜像的工作目录
expose对外暴露的端口
env设置环境变量
add将宿主机的文件复制到镜像中,并自动解压
copy将宿主机的文件复制到镜像中
volume容器数据卷,用于数据的保存和持久化
cmd运行命令,多条CMD只会执行最后一条,参数会被RUN的参数覆盖
entrypoint运行命令,会把RUN的参数追加到后面
volume容器数据卷,用于数据的保存和持久化
cmd运行命令,多条CMD只会执行最后一条,参数会被RUN的参数覆盖
entrypoint运行命令,会把RUN的参数追加到后面

在这里插入图片描述

Dockerfile指令的使用

FROM

FROM [--platform=<platform>] <image> [AS <name>]

FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]

FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

FROM指令初始化了一个新的构建阶段,并指定了这个构建阶段的基础镜像,每一个Dockerfile都要以FROM指令开始。

例如:

FROM centos:7

MAINTAINER

MAINTAINER用来指定Dockerfile的作者,官方已不推荐使用,推荐使用LABEL

maintainer morris131<morris131@163.com>

LABEL

LABEL <key>=<value> <key>=<value> <key>=<value> ...

LABEL用来为镜像添加元数据,是一个key-value结构。

例如:

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."

一个镜像可以指定多个label,可以指定在一行指定多个label。

LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"

父镜像的label会被继承。

可以使用docker image inspect来查看镜像的label。

$ docker image inspect --format='{{json .Config.Labels}}' centos:7
{"org.label-schema.build-date":"20201113","org.label-schema.license":"GPLv2","org.label-schema.name":"CentOS Base Image","org.label-schema.schema-version":"1.0","org.label-schema.vendor":"CentOS","org.opencontainers.image.created":"2020-11-13 00:00:00+00:00","org.opencontainers.image.licenses":"GPL-2.0-only","org.opencontainers.image.title":"CentOS Base Image","org.opencontainers.image.vendor":"CentOS"}

RUN

RUN <command>

RUN ["executable", "param1", "param2"]

RUN主要用于在镜像里执行指令,比如安装软件,下载文件等。在Linux下默认的shell是/bin/sh -c,在windows下默认的shell是cmd /S /C

例如:

run yum install -y wget gcc gcc-c++ automake autoconf libtool make

run wget https://download.redis.io/releases/redis-6.2.5.tar.gz

run tar xzf redis-6.2.5.tar.gz && cd redis-6.2.5 && make

WORKDIR

WORKDIR /path/to/workdir

WORKDIR指定运行RUN, CMD, ENTRYPOINT, COPYADD等指令的工作目录。

WORKDIR可以使用多次,如果指定的是一个相对路径,那么会自动拼接上前面的WORKDIR指令指定的路径。

WORKDIR /a
WORKDIR b
WORKDIR c

最终的工作路径将变为/a/b/c

COPY

COPY [--chown=<user>:<group>] [--chmod=<perms>] <src>... <dest>
COPY [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]

COPY指令可以把本地的文件复制到镜像里,如果目标目录不存在,则会自动创建。

例如:

COPY /foo /bar
COPY hom* /mydir/
COPY hom?.txt /mydir/
COPY test.txt relativeDir/

ADD

ADD [--chown=<user>:<group>] [--chmod=<perms>] [--checksum=<checksum>] <src>... <dest>
ADD [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]

ADDCOPY的功能类似,唯一的区别在于如果复制的是一个gzip等压缩文件时,ADD会帮助我们自动去解压缩文件。

因此在COPYADD指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用COPY指令,仅在需要自动解压缩的场合使用ADD

如果要在容器内部复制文件,可以使用run copy xx oo

ARG

ARG <name>[=<default value>]

ARG用于定义一个变量,可以在Dockerfile中使用,可以在构建时指定构建参数来覆盖这个变量的值。

FROM busybox
ARG username
USER $username

在构建时修改这个变量:

$ docker build --build-arg username=what_user .

ENV

ENV <key>=<value> ...

ENV设置的变量不仅可可以在镜像的构建阶段使用,还会出现在容器中的环境变量里。

例如:

ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy

ENV设置的变量可以通过docker image inspect命令来查看:

$ docker image inspect --format='{{json .Config.Env}}' openjdk:8-jre-alpine
["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin","LANG=C.UTF-8","JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk/jre","JAVA_VERSION=8u212","JAVA_ALPINE_VERSION=8.212.04-r0"]

可以在运行时使用run --env <key>=<value>来改变环境变量的值。

CMD

CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)

CMD可以用来设置容器启动时默认会执行的命令。

如果docker container run启动容器时指定了其它命令,则CMD命令会被忽略。

如果定义了多个CMD,只有最后一个会被执行。

例如:

CMD echo "This is a test." | wc -

CMD ["/usr/bin/wc","--help"]

默认进入到shell是因为在ubuntu的基础镜像里有定义CMD

$ docker container run -it centos:7
[root@ea4a8eb97765 /]# exit
exit

$ docker history centos:7
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
eeb6ee3f44bd   24 months ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>      24 months ago   /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
<missing>      24 months ago   /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB

ENTRYPOINT

ENTRYPOINT ["executable", "param1", "param2"]

ENTRYPOINT command param1 param2

ENTRYPOINT也可以设置容器启动时要执行的命令,但是和CMD是有区别的。

CMD设置的命令,可以在docker container run时传入其它命令,覆盖掉CMD的命令,但是ENTRYPOINT所设置的命令是一定会被执行的。

ENTRYPOINTCMD可以联合使用,ENTRYPOINT设置执行的命令,CMD传递参数。

CMD测试

cmd.Dockerfile

FROM centos:7
CMD ["echo", "hello cmd"]

把上面的Dockerfile构建成一个叫cmd的镜象:

$ docker build -f cmd.Dockerfile -t cmd .
Sending build context to Docker daemon  327.2MB
Step 1/2 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/2 : CMD ["echo", "hello cmd"]
 ---> Running in 4bddfcb6153c
Removing intermediate container 4bddfcb6153c
 ---> c92160d2a1d6
Successfully built c92160d2a1d6
Successfully tagged cmd:latest

运行容器时如果不指定运行时的命令,则会默认执行CMD所定义的命令,打印出hello cmd

$ docker run --rm -it cmd
hello cmd

如果运行容器的时候指定命令,则该命令会覆盖掉CMD的命令,如:

$ docker run --rm -it cmd echo hello docker
hello docker

ENTRYPOINT测试

entrypoint.Dockerfile

FROM centos:7
ENTRYPOINT ["echo", "hello entrypoint"]

把上面的Dockerfile构建成一个叫entrypoint的镜象:

$ docker build -f entrypoint.Dockerfile -t entrypoint .
Sending build context to Docker daemon  327.2MB
Step 1/2 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/2 : ENTRYPOINT ["echo", "hello entrypoint"]
 ---> Running in b74fa51c63a8
Removing intermediate container b74fa51c63a8
 ---> b3f6c3c624e0
Successfully built b3f6c3c624e0
Successfully tagged entrypoint:latest

运行容器时如果不指定运行时的命令,则会默认执行ENTRYPOINT所定义的命令,打印出hello entrypoint

$ docker run --rm -it entrypoint
hello entrypoint

但是容器里ENTRYPOINT所定义的命令则无法覆盖,一定会执行,如:

$ docker run --rm -it entrypoint echo hello docker
hello entrypoint echo hello docker

实战构建redis

$ cat redis.dockerfile
from centos

maintainer morris131<morris131@163.com>

env WORK_DIR /usr/local

workdir $WORK_DIR

run yum install -y wget gcc gcc-c++ automake autoconf libtool make

run wget https://download.redis.io/releases/redis-6.2.5.tar.gz

run tar xzf redis-6.2.5.tar.gz && cd redis-6.2.5 && make

expose 6379

env REDIS_HOME $WORK_DIR/redis-6.2.5

env PATH $PATH:$REDIS_HOME/src

entrypoint ["redis-server"]
举报

相关推荐

0 条评论