Docker-Dockerfile构建学习
本文最后更新于 1730 天前,其中的信息可能已经有所发展或是发生改变。

Docker-Dockerfile构建学习

Dockerfile介绍

Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

构建步骤分为:

  1. 编写一个dockerfile文件
  2. docker build构建成为一个镜像
  3. docker run 运行镜像
  4. docker pull 发布镜像(docker hub,阿里云镜像仓库等..)

Dockerfile 指令说明

images_6567790-fff25499e56d7295

指令 含义
FROM 镜像 指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令
MAINTAINER 名字 说明新镜像的维护人信息,姓名+邮箱–>gljadmin@199604.com
RUN 命令 镜像构建时,执行的命令
CMD [“要运行的程序”,”参数1”,”参数2”] 指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能最后一条被执行
ENTRYPOINT 类似CMD命令,指定容器启动时候,需要运行的命令,可追加
EXPOSE 端口号 容器需要暴露的端口号,docker run -P 时,会自动随机映射 EXPOSE 的端口
ENV 环境变量 变量值 设置一个环境变量的值,会被后面的RUN使用
ADD 源文件/目录 目标文件/目录 将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中, 或者是一个URL
COPY 源文件/目录 目标文件/目录 将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中
VOLUME [“目录”] 在容器中创建一个挂载点
USER 用户名/UID 指定运行容器时的用户
WORKDIR 路径 为后续的RUN、CMD、ENTRYPOINT指定 镜像工作目录路径
ONBUILD 命令 指定所生成的镜像作为一个基础镜像时所要运行的命令(是一个特殊的触发指令)
HEALTHCHECK 健康检查
SHELL SHELL 指令可以指定 RUN ENTRYPOINT CMD 指令的 shell,Linux 中默认为 ["/bin/sh", "-c"]

FROM 指定基础镜像

如:FROM nginx,就以nginx为基础构建.

Docker 还存在一个特殊的镜像,名为 scratch。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。FROM scratch.

如果你以 scratch 为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。

MAINTAINER 指定维护者的信息

例子:

MAINTAINER glj<admin@199604.com>

RUN 镜像构建时的执行命令

RUN 指令用于制定docker build 过程中要运行的命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:

shell 格式:

RUN <命令>,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式。

例子:

RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

exec 格式:

RUN ["可执行文件", "参数1", "参数2"],这更像是函数调用中的格式。

例子:

RUN yum -y install vim

ENV 设置环境变量

格式有两种:

  • ENV <key> <value>

例子:

ENV JAVA_VERSION 1.8.0

  • ENV <key1>=<value1> <key2>=<value2>...

例子:

ENV JAVA_VERSION=1.8.0 DEBUG=on NAME="GLJ"

这个指令很简单,就是设置环境变量而已

WORKDIR 指定工作目录

格式为 WORKDIR <工作目录路径>

例子:

WORKDIR /usr/local

COPY 复制文件

格式:

  • COPY [--chown=<user>:<group>] <源路径>... <目标路径>
  • COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]

RUN 指令一样,也有两种格式,一种类似于命令行,一种类似于函数调用。

COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。

例子:

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

ADD 扩展了的复制文件

ADD 指令和 COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能。

比如:如果 <源路径> 为一个 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令将会自动解压缩这个压缩文件到 <目标路径> 去。

如Centos 官网的Dockerfile就是如此:

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

Docker 官方要求,尽可能的使用 COPY,因为 COPY 的语义很明确

另外需要注意的是,ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。

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

CMD 容器启动需要运行的命令

CMD 指令的格式和 RUN 相似,也是两种格式,推荐使用第二种格式:

  • shell 格式:CMD <命令>

例子:

CMD echo $JAVA_VERSION

CMD echo "----end----"

  • exec 格式:CMD ["可执行文件", "参数1", "参数2"...]

例子:

CMD ["/bin/echo", "this is a echo docker"]

CMD 指令指定的程序可被 docker run命令行参数中指定要运行的程序所覆盖。

如你指定:

CMD ["/bin/echo", "this is a echo docker"]

build后运行(假设镜像名为mycentos):

docker run mycentos就会输出: this is a echo docker

但是,如; docker run -it mycentos /bin/bash,不再输出:this is a echo docker,因为CMD命令被/bin/bash覆盖了

注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

ENTRYPOINT 容器启动需要运行的命令(入口点)

ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。

可以搭配 CMD命令使用:一般是变参才会使用CMD ,这里的 CMD 等于是在给ENTRYPOINT 传参,换句话说实际执行时,将变为:

<ENTRYPOINT> "<CMD>"

CMD+ENTRYPOINT的实例:

假设我们需要一个得知自己当前公网 IP 的镜像,那么可以先用 CMD 来实现:

FROM centos:7.9.2009
MAINTAINER glj<admin@199604.com>

ENV TARPATH /home
WORKDIR $TARPATH

RUN yum -y install curl

CMD [ "curl", "-s", "http://myip.ipip.net" ]

假如我们使用 docker build -t checkip:v1 . 来构建镜像的话,如果我们需要查询当前公网 IP.

只需要执行:

[root@gzbsc001 mycentos]# docker run -it checkip:v1
当前 IP:120.235.165.226  来自于:中国 广东 广州  移动

如果需要追加参数怎么办?那么只能CMD+ENTRYPOINT配合即可:

FROM centos:7.9.2009
MAINTAINER glj<admin@199604.com>

ENV TARPATH /home
WORKDIR $TARPATH

RUN yum -y install curl

CMD [ "-i" ]
ENTRYPOINT [ "curl", "-s", "http://myip.ipip.net" ]

我们使用 docker build -t checkip:v2 . 来构建镜像.这次我们再来执行:

[root@gzbsc001 mycentos]# docker images
REPOSITORY            TAG        IMAGE ID       CREATED         SIZE
checkip               v2         9c528482c01a   7 seconds ago   348MB
checkip               v1         b95f6f873e5c   7 minutes ago   348MB
nginx                 latest     04661cdce581   7 days ago      141MB
tomcat                9.0        43e421a14aec   3 weeks ago     680MB
mysql                 5.7        938b57d64674   4 weeks ago     448MB
centos                7.9.2009   eeb6ee3f44bd   2 months ago    204MB
portainer/portainer   latest     580c0e4e98b0   8 months ago    79.1MB
java                  8          d23bdf5b1b1b   4 years ago     643MB
[root@gzbsc001 mycentos]# 
[root@gzbsc001 mycentos]# 
[root@gzbsc001 mycentos]# docker run checkip:v2
HTTP/1.1 200 OK
Date: Wed, 17 Nov 2021 09:11:51 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 70
Connection: keep-alive
X-Shadow-Status: 200
X-Via-JSL: 1cf16e4,4f293cc,-
Set-Cookie: __jsluid_h=2144db3d81319385679383be3efd7fcd; max-age=31536000; path=/; HttpOnly
X-Cache: bypass

当前 IP:120.235.165.226  来自于:中国 广东 广州  移动

最最最简单的CMD+ENTRYPOINT 实例:

FROM centos

CMD ["p in cmd"]
ENTRYPOINT ["echo"]

注意:如果 Dockerfile 中如果存在多个ENTRYPOINT 指令,仅最后一个生效。

VOLUME 定义匿名卷

格式为:

  • VOLUME ["<路径1>", "<路径2>"...]

例子:VOLUME [''/data1","/data2"]

  • VOLUME <路径>

例子:VOLUME /data1

在docker运行时,docker会创建一个匿名的volume,并将此volume绑定到容器的data1目录中,如果容器的/data1目录下已经有内容,则会将内容拷贝的volume中。也就是,Dockerfile中的VOLUME /data1docker run -v /data1 checkip的匿名挂载效果一样。

在启动容器 docker run 的时候,我们也可以通过 -v 参数修改挂载点。

EXPOSE 暴露端口

仅仅只是声明端口。

格式为 EXPOSE <端口1> [<端口2>...]

在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

USER 指定当前用户

用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

格式:USER <用户名>[:<用户组>]

例子:

RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN [ "redis-server" ]

HEALTHCHECK 健康检查

HEALTHCHECK 指令是告诉 Docker 应该如何进行判断容器的状态是否正常,这是 Docker 1.12 引入的新指令。

格式:

  • HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令

HEALTHCHECK 支持下列选项:

  1. --interval=<间隔>:两次健康检查的间隔,默认为 30 秒;
  2. --timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
  3. --retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。
  • HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK --interval=60s --timeout=40s --retries=5

HEALTHCHECKCMD, ENTRYPOINT 一样,HEALTHCHECK 只可以出现一次,如果写了多个,只有最后一个生效。

SHELL 指令

格式:SHELL ["executable", "parameters"]

SHELL 指令可以指定 RUN ENTRYPOINT CMD 指令的 shell,Linux 中默认为 ["/bin/sh", "-c"]

例子:

SHELL ["/bin/sh", "-cex"]
# /bin/sh -cex "nginx"
ENTRYPOINT nginx

SHELL ["/bin/sh", "-cex"]
# /bin/sh -cex "nginx"
CMD nginx

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

可到Dockerfile 最佳实践文档:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ 练手实践…

发布自己的镜像到仓库中

DockerHub

1.登录docker login

[root@gzbsc001 mytomcat]# docker login --help

Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username

[root@gzbsc001 mytomcat]# docker login -u glj17
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded


2.提交镜像

docker push :将本地的镜像上传到镜像仓库,要先登陆到镜像仓库

推送镜像的规范是: docker push 注册用户名/镜像名:[tag]

tag命令修改为规范的镜像:

docker tag dec02f4c1226 glj17/mynginx:1.21.4

[root@gzbsc001 mytomcat]# docker tag dec02f4c1226 glj17/mynginx:1.21.4 

[root@gzbsc001 mytomcat]# docker push glj17/mynginx:1.21.4
The push refers to repository [docker.io/glj17/mynginx]
eac18618a1e0: Pushed 
3f9029f7aeb1: Pushed 
36fdbc2fc6f3: Pushed 
663de1ca3bab: Pushed 
40c95c921670: Pushed 
b4e84b4eb3f3: Pushed 
394d004881a3: Pushed 
174f56854903: Mounted from library/centos 
1.21.4: digest: sha256:fc510ef8eb9483255386f2da07e4ddba04630ed2de85d9c8a39d4e0556b8b5b8 size: 1992

image-20211117192438184

Dockerfile实战

构建sshd镜像

[root@gzbsc001 tmp]# mkdir mysshd
[root@gzbsc001 tmp]# cd mysshd/
[root@gzbsc001 mysshd]# vim Dockerfile # 编写dockerfile文件

FROM centos:7.9.2009
MAINTAINER this is mysshd glj<admin@199604.com>
RUN yum -y update
RUN yum -y install openssh* net-tools lsof telnet passwd
RUN echo '123456!@#' | passwd --stdin root
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd
RUN mkdir -p /root/.ssh && chown root:root /root && chmod 700 /root/.ssh
EXPOSE 22
CMD ["/usr/sbin/sshd" , "-D"]

[root@gzbsc001 mysshd]# docker build -t mysshd:v1 .
[root@gzbsc001 mysshd]# docker images
REPOSITORY            TAG        IMAGE ID       CREATED             SIZE
mysshd                v1         677eca2f9c45   34 seconds ago      719MB

[root@gzbsc001 mysshd]# docker run -d -P mysshd:v1
724dcf29adba83c32add89b3f42a4287006900ec0540b52061eaa24fddcc1e75

[root@gzbsc001 mysshd]#  docker ps -a
CONTAINER ID   IMAGE             COMMAND                  CREATED             STATUS                         PORTS                                     NAMES
724dcf29adba   mysshd:v1         "/usr/sbin/sshd -D"      24 seconds ago      Up 24 seconds                  0.0.0.0:49156->22/tcp, :::49156->22/tcp   priceless_elbakyan


[root@gzbsc001 mysshd]# ssh 127.0.0.1 -p49156
The authenticity of host '[127.0.0.1]:49156 ([127.0.0.1]:49156)' can't be established.
RSA key fingerprint is SHA256:WfwbFngOT9C5dDkPhMTFUNZnuLiSuhf2qZI7hZlOU+M.
RSA key fingerprint is MD5:e5:17:10:32:8b:cb:8a:17:ca:18:2a:6a:93:4f:22:ad.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:49156' (RSA) to the list of known hosts.
root@127.0.0.1's password: 
[root@724dcf29adba ~]# pwd
/root

构建Nginx镜像

[root@gzbsc001 tmp]# mkdir mynginx
[root@gzbsc001 tmp]# cd mynginx/

[root@gzbsc001 mynginx]# vim Dockerfile # 编写dockerfile文件
FROM centos:7.9.2009
MAINTAINER this is mynginx glj<admin@199604.com>
RUN yum install -y proc-devel gcc gcc-c++ zlib zlib-devel make openssl-devel wget
ADD nginx-1.21.4.tar.gz /usr/local/
WORKDIR /usr/local/nginx-1.21.4/
RUN ./configure --prefix=/usr/local/nginx && make && make install
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
WORKDIR /root/nginx
COPY run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]

[root@gzbsc001 mynginx]# vim run.sh
#!/bin/bash
/usr/local/nginx/sbin/nginx   ##开启Nginx服务

[root@gzbsc001 mynginx]# wget http://nginx.org/download/nginx-1.21.4.tar.gz #下载nginx包

[root@gzbsc001 mynginx]# docker build -t mynginx:1.21.4 .   ##创建镜像
Successfully built dec02f4c1226
Successfully tagged mynginx:1.21.4

[root@gzbsc001 mynginx]# docker images
REPOSITORY            TAG        IMAGE ID       CREATED          SIZE
mynginx               1.21.4     dec02f4c1226   12 minutes ago   475MB

[root@gzbsc001 mynginx]# docker run -d -P mynginx:1.21.4
b84a7cb5893729971b4685edec75300a98e640b60853f4443db4acb37181228c

[root@gzbsc001 mynginx]# docker ps 
CONTAINER ID   IMAGE            COMMAND     CREATED         STATUS         PORTS                                                                                NAMES
b84a7cb58937   mynginx:1.21.4   "/run.sh"   5 seconds ago   Up 4 seconds   0.0.0.0:49158->80/tcp, :::49158->80/tcp, 0.0.0.0:49157->443/tcp, :::49157->443/tcp   gallant_matsumoto


image-20211117185139231

构建Tomcat镜像

[root@gzbsc001 tmp]# mkdir mytomcat
[root@gzbsc001 tmp]# cd mytomcat/

[root@gzbsc001 mytomcat]# vim Dockerfile # 编写dockerfile文件
FROM centos:7.9.2009
MAINTAINER this is mytomcat glj<admin@199604.com>
ADD jdk-8u301-linux-x64.tar.gz /usr/local
WORKDIR /usr/local
RUN mv jdk1.8.0_301 /usr/local/java
ENV JAVA_HOME /usr/local/java     ##设置环境变量
ENV JAVA_BIN /usr/local/java/bin
ENV JRE_HOME /usr/local/java/jre
ENV PATH $PATH:/usr/local/java/bin:/usr/local/java/jre/bin
ENV CLASSPATH /usr/local/java/jre/bin:/usr/local/java/lib:/usr/local/java/jre/lib/charsets.jar

ADD apache-tomcat-8.5.72.tar.gz /usr/local
WORKDIR /usr/local
RUN mv apache-tomcat-8.5.72 /usr/local/tomcat8

EXPOSE 8080
ENTRYPOINT ["/usr/local/tomcat8/bin/catalina.sh","run"]

#自行上传或者wget下载对应的包
[root@gzbsc001 mytomcat]# wget https://d6.injdk.cn/oraclejdk/8/jdk-8u301-linux-x64.tar.gz
[root@gzbsc001 mytomcat]# wget dlcdn.apache.org/tomcat/tomcat-8/v8.5.72/bin/apache-tomcat-8.5.72.tar.gz

[root@gzbsc001 mytomcat]# docker build -t mytomcat:8.5.72 . ##创建镜像
Successfully built 25102a5b9a73
Successfully tagged mytomcat:8.5.72

[root@gzbsc001 mytomcat]# docker images
REPOSITORY            TAG        IMAGE ID       CREATED             SIZE
mytomcat              8.5.72     25102a5b9a73   38 seconds ago      956MB

[root@gzbsc001 mytomcat]# docker run -P -it mytomcat:8.5.72 /bin/bash 

[root@gzbsc001 mynginx]# docker ps 
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                                         NAMES
7ec02971fd62   mytomcat:8.5.72   "/usr/local/tomcat8/…"   18 seconds ago   Up 17 seconds   0.0.0.0:49159->8080/tcp, :::49159->8080/tcp   reverent_franklin

image-20211117190932362

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇