dockerfile基础篇-基本语法

dockerfile基础篇-基本语法

Dockerfile是用于构建Docker镜像的文本文件,其中包含了一系列的指令和配置,用于定义镜像的构建过程。通过编写Dockerfile,开发者可以定义镜像中应该包含哪些文件、环境变量、依赖关系和运行命令等信息。

Dockerfile通常包含了以下几个主要部分:

  1. 基础镜像指令(FROM):指定基础镜像,新镜像将基于该镜像构建。例如:

    FROM centos
  2. 维护者信息(MAINTAINER):指定镜像的维护者信息,通常是镜像的作者或团队名称。

    MAINTAINER JX Cai 
  3. 镜像构建指令:一系列的指令,用于构建镜像。

    • 运行命令指令(RUN):运行命令来安装软件包、配置环境等。例如:

      RUN rm -rf /etc/yum.repos.d/*
    • 复制文件指令(COPY、ADD):复制本地文件到镜像中。例如:

      COPY index.html /usr/share/nginx/html/
    • 设置工作目录指令(WORKDIR):设置镜像中命令的执行目录。

      WORKDIR /app
    • 设置环境变量指令(ENV):设置环境变量。例如:

      ENV ENVIRONMENT=production
    • 暴露端口指令(EXPOSE):声明容器运行时的端口。

      EXPOSE 80
    • 执行命令指令(CMD、ENTRYPOINT):设置容器启动时执行的命令。

      CMD ["nginx", "-g", "daemon off;"]
  4. 注释:可以添加注释来提高代码的可读性。

    # This is a Dockerfile for building a web server image

编写Dockerfile的过程是根据应用程序的需求和容器环境的配置来定义镜像构建过程,使得镜像可以快速、自动地构建出来,方便地部署和分享。Dockerfile提供了一种标准化、可重复的镜像构建方法,使得Docker容器的构建更加简单和可控。

1、FROM

基础镜像,必须是可以下载下来的,定制的镜像都是基于 FROM 的镜像,这里的 centos 就是定制需要的基础镜像。后续的操作都是基于 centos 镜像。

2、MAINTAINER

指定镜像的作者信息

3、RUN

指定在当前镜像构建过程中要运行的命令

包含两种模式

(1)Shell

RUN \ (shell 模式,这个是最常用的,需要记住)

RUN echo hello

(2)exec 模式

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

RUN ["/bin/bash","-c","echo hello"]

等价于/bin/bash -c echo hello

4、EXPOSE 指令

仅仅只是声明端口。

作用:

1、帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。

2、在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

3、可以是一个或者多个端口,也可以指定多个 EXPOSE

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

5、CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

1、CMD 在 docker run 时运行。

2、RUN 是在 docker build 构建镜像时运行的

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被docker run 命令行参数中指定要运行的程序所覆盖。

CMD["executable","param1","param2"](exec 模式)

CMD command (shell 模式)

CMD ["param1","param2"](作为 ENTRYPOINT 指令的默认参数)

例如:构建dockerfile,此时加上CMD命令,构建镜像,启动容器后不需要进入容器内,nginx服务就已经启动,不需要在终端键入其他参数了,如nginx -g "daemon off"。

在目录[test-cmd]下编写dockerfile

[root@docker-master test-cmd]# cat dockerfile 
FROM centos
MAINTAINER Caijx
RUN rm -rf /etc/yum.repos.d/*
COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/
RUN yum clean all
RUN yum install nginx -y
EXPOSE 80
CMD ["/usr/sbin/nginx","-g","daemon off;"]

将Centos-vault-8.5.2111.repo文件传入当前目录[test-cmd]

[root@docker-master test-cmd]# ls
Centos-vault-8.5.2111.repo  dockerfile

构建镜像

[root@docker-master test-cmd]# docker build -t="dockerfile/test-cmd:v1" .
[+] Building 39.0s (8/9)                                                                                                                                                                                                     docker:default
 => [internal] load build definition from dockerfile                                     
 => => transferring dockerfile: 304B                                                     
 => [internal] load metadata for docker.io/library/centos:latest                         
 => [internal] load .dockerignore                                                         
 => => transferring context: 2B                                                           
 => CACHED [1/5] FROM docker.io/library/centos:latest                                     
 => [internal] load build context                                                         
 => => transferring context: 2.61kB                                                       
 => [2/5] RUN rm -rf /etc/yum.repos.d/*                                                   
 => [3/5] COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/                               
 => [4/5] RUN yum clean all                                                               
 => [5/5] RUN yum install nginx -y 
 ....省略部分输出...
参数 解释
-t 给镜像指定一个标签为 dockerfile/test-cmd:v1
. 表示 Dockerfile 文件位于当前目录。如果 Dockerfile 在其他路径下,需要提供相应的路径

基于构建的镜像运行容器

[root@docker-master test-cmd]# docker run -p 80 --name=test-cmd -d dockerfile/test-cmd:v1 
f05fc8f5128b6e34979e7f6e606ebb9e7e598890c006c0136dce061aaf163d2a

查看容器内nginx服务是否已正常启动

[root@docker-master test-cmd]# docker ps | grep test-cmd
f05fc8f5128b   dockerfile/test-cmd:v1   "/usr/sbin/nginx -g …"   16 seconds ago   Up 16 seconds   0.0.0.0:32769->80/tcp, :::32769->80/tcp   test-cmd
[root@docker-master test-cmd]# curl 192.168.132.167:32769
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <title>Test Page for the Nginx HTTP Server on Red Hat Enterprise Linux</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <style type="text/css">
 ....省略部分输出...
6、ENTERYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 entrypoint 指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

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

格式:

ENTERYPOINT ["executable","param1","param2"](exec 模式)

ENTERYPOINT command (shell 模式)

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下 示例会提到。

示例:

假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参

CMD ["/etc/nginx/nginx.conf"] # 变参

(1)不传参运行:在终端运行[docker run nginx:test],容器内默认运行[nginx -c /etc/nginx/nginx.conf]命令,启动主进程。

(2)传参运行:在终端运行[docker run nginx:test -c /etc/nginx/new.conf],容器会默认运行[nginx -c /etc/nginx/new.conf],启动主进程。(假设容器内已有new.conf文件)

7、COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

格式:

COPY [--chown=\:\] <源路径 1>... <目标路径>

下面这种格式有时候更加灵活,特别是当源路径包含空格或特殊字符时。

COPY ["<源路径1>", "<源路径2>", "<目标路径>"]

(1)将 file1.txt 和 file2.txt 复制到镜像中的 /app/ 目录下。

COPY ["file1.txt", "file2.txt", "/app/"]

(2)将当前目录下所有的 .html文件复制到镜像中的 /var/www/html/ 目录下。

COPY ["*.html", "/var/www/html/"]

[--chown=\:\]:可选参数,用户改变复制到容器内文件的拥有者和属组。

<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:

COPY hom* /mydir/

COPY hom?.txt /mydir/

<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

8、ADD

ADD \...\

ADD ["\"..."\"]

ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下, 会自动复制并解压到 <目标路径>。

ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像 构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。

ADD包含类似tar的解压功能,如果是单纯复制文件,dockerfile推荐使用COPY。

例子如下:

替换nginx容器内部的index.html页面。

创建test-copy目录,编写index.html文件

[root@docker-master test-copy]# ls
Centos-vault-8.5.2111.repo  dockerfile  index.html
[root@docker-master test-copy]# cat index.html 
This is replace page.

编写dockerfile文件

[root@docker-master test-copy]# vim dockerfile                                           FROM centos
MAINTAINER Caijx
RUN rm -rf /etc/yum.repos.d/*
COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/
RUN yum clean all
RUN yum install nginx -y
COPY index.html /usr/share/nginx/html/
EXPOSE 80
CMD ["/usr/sbin/nginx","-g","daemon off;"]

构建镜像和运行容器

[root@docker-master test-copy]# docker build -t="dockerfile/test-copy:v1" .
[+] Building 0.1s (11/11) FINISHED                                                                                                                                                                                           docker:default
 => [internal] load build definition from dockerfile                                     
 => => transferring dockerfile: 340B                                                     
 => [internal] load metadata for docker.io/library/centos:latest                         
 => [internal] load .dockerignore                                                         
 => => transferring context: 2B                                                           
 => [1/6] FROM docker.io/library/centos:latest                                           
 => [internal] load build context                                                         
 => => transferring context: 191B                                                         
 => CACHED [2/6] RUN rm -rf /etc/yum.repos.d/*                                           
 => CACHED [3/6] COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/                       
 => CACHED [4/6] RUN yum clean all                                                       
 => CACHED [5/6] RUN yum install nginx -y                                                 
 => [6/6] COPY index.html /usr/share/nginx/html/                                         
 => exporting to image                                                                   
 => => exporting layers                                                                   
 => => writing image sha256:a9f7423105db26cf3c375ee9e26e49c7d238d734987695fa7e0cc718318f7b14                   
 => => naming to docker.io/dockerfile/test-copy:v1                                       
[root@docker-master test-copy]# docker run -d -p 80 --name=test-copy dockerfile/test-copy:v1 
d3df507b53995386b3b0d81046562d26188462e3ea674c527e0dd9b83aa3439b

查看容器运行状态和映射端口

[root@docker-master test-copy]# docker ps 
CONTAINER ID   IMAGE                     COMMAND                  CREATED         STATUS         PORTS                                     NAMES
d3df507b5399   dockerfile/test-copy:v1   "/usr/sbin/nginx -g …"   5 seconds ago   Up 4 seconds   0.0.0.0:32778->80/tcp, :::32778->80/tcp   test-copy

查看容器内部的nginx界面是否被替换

[root@docker-master test-copy]# curl 192.168.132.167:32778
This is replace page.
9、VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

作用:

1、避免重要的数据,因容器重启而丢失,这是非常致命的。

2、避免容器不断变大。

格式:

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

VOLUME <路径>

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

dockerfile写法如下:

VOLUME ["/data"]
10、WORKDIR

指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作 目录,必须是提前创建好的)。

docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才 会一直存在。

格式:

WORKDIR <工作目录路径>

WORKDIR /path/to/workdir(填写绝对路径)

11、ENV

设置环境变量

ENV \ \

ENV \=\...

以下示例设置 NODE_VERSION =6.6.6, 在后续的指令中可以通过 $NODE_VERSION 引用:

ENV NODE_VERSION 6.6.6
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz"
\
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
12、USER

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

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

USER daemon

USER nginx

USER user

USER uid

USER user:group

USER uid:gid

USER user:gid

USER uid:group

13、ONBUILD

用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜 像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的ONBUILD 指定的命令。

格式:

ONBUILD <其它指令>

为镜像添加触发器,当一个镜像被其他镜像作为基础镜像时需要写上 OBNBUILD会在构建时插入触发器指令

例如:

创建test-onbuild目录,在该目录下创建dockefile、index.html和仓库文件

[root@docker-master ~]# mkdir test-onbuild
[root@docker-master ~]# cd test-onbuild/
[root@docker-master test-onbuild]# vim dockerfile 
FROM centos
MAINTAINER Caijx
RUN rm -rf /etc/yum.repos.d/*
COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/
RUN yum install wget -y
RUN yum install nginx -y
ONBUILD COPY index.html /usr/share/nginx/html/
EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
[root@docker-master test-onbuild]# cp /test-copy/{Centos-vault-8.5.2111.repo,index.html} ./ 
[root@docker-master test-onbuild]# ls
Centos-vault-8.5.2111.repo  dockerfile  index.html

构建镜像并创建容器,查看物理机的映射端口

[root@docker-master test-onbuild]# docker build -t="dockerfile/test-onbuild:v1" ./
[+] Building 52.3s (10/10) FINISHED                                                     docker:default
 => [internal] load build definition from dockerfile   
 ...省略部分输出...
 [root@docker-master test-onbuild]# docker run -d -p 80 --name=nginx-nochange dockerfile/test-onbuild:v1 
78d7b1624efc81734c0f43f4de21938d395d5ba78daa4c43d2cc76185e069335                         
[root@docker-master test-onbuild]# docker ps | grep onbuild
78d7b1624efc   dockerfile/test-onbuild:v1   "/usr/sbin/nginx -g …"   13 seconds ago   Up 12 seconds   0.0.0.0:32779->80/tcp, :::32779->80/tcp   nginx-nochange

发现访问的界面还是nginx初始内容,表明onbuild指令后的copy命令并没有生效

[root@docker-master test-onbuild]# curl 192.168.132.167:32779
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 ...省略部分输出...

修改当前路径下的dockerfile文件,引用的镜像修改为刚才创建的dockerfile/test-onbuild:v1

[root@docker-master test-onbuild]# vim dockerfile 
FROM dockerfile/test-onbuild:v1
MAINTAINER Caijx
EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]

重新构建镜像和运行容器,查看物理机映射的端口

[root@docker-master test-onbuild]# docker build -t="dockerfile/test-onbuild:v2" ./
[+] Building 0.1s (7/7) FINISHED                                                     docker:default
 => [internal] load build definition from dockerfile   
 ...省略部分输出...
 [root@docker-master test-onbuild]# docker run -d -p 80 --name=nginx-change dockerfile/test-onbuild:v2
34dd6d6d17bec36f2a566c3e0cf0a93c04914d50250ee1eef7c9cc6f196b857f
[root@docker-master test-onbuild]# docker ps | grep v2
34dd6d6d17be   dockerfile/test-onbuild:v2   "/usr/sbin/nginx -g …"   16 seconds ago   Up 15 seconds   0.0.0.0:32780->80/tcp, :::32780->80/tcp   nginx-change

访问界面可以观察到index.html文件已经被修改了,得出onbuild指令已经被执行的结论

[root@docker-master test-onbuild]# curl 192.168.132.167:32780
This is replace page.
14、LABEL

LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:

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

比如可以添加镜像的作者:

LABEL org.opencontainers.image.authors="Caijx"

15、HEALTHCHECK

HEALTHCHECK 指令用于指定容器的健康检查命令,用于检查容器内应用程序的运行状态。当健康检查命令返回非零退出码时,Docker 将认为容器不健康,并可能触发一些相应的操作,比如重新启动容器。

HEALTHCHECK 指令有两种格式:

  1. 格式一:HEALTHCHECK [选项] CMD <命令>

    在这种格式中,<命令>可以是任何可以在容器内部执行的 Shell 命令或者可执行文件。比如:

    HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1

    这个命令每隔 5 分钟(--interval=5m)执行一次,超时时间设置为 3 秒(--timeout=3s)。如果 curl 请求返回状态码非 2xx,就会使容器变为不健康状态。

  2. 格式二:HEALTHCHECK NONE

    表示关闭健康检查功能,也就是不进行任何健康检查。这在某些情况下可能会有用,比如你的容器运行的是一个守护进程,它自己有健康检查机制。

下面是一个使用 HEALTHCHECK的示例 Dockerfile:

FROM nginx:alpine

# 复制健康检查脚本到镜像中
COPY healthcheck.sh /usr/local/bin/healthcheck.sh

# 设置健康检查命令
HEALTHCHECK --interval=30s --timeout=3s CMD /usr/local/bin/healthcheck.sh

# 复制网站文件到Nginx默认目录
COPY index.html /usr/share/nginx/html/

# 暴露80端口
EXPOSE 80

健康检查脚本 healthcheck.sh 可以是一个简单的 Shell 脚本,例如:

#!/bin/sh

# 检查Nginx是否正常运行
if nginx -t > /dev/null; then
  exit 0
else
  exit 1
fi

这个脚本检查 Nginx 是否能够正常运行,如果正常则返回 0,否则返回 1。

在实际使用中,可以根据应用程序的特性编写不同的健康检查命令,以确保容器内的应用程序处于健康状态。

16、ARG

ARG 指令用于定义构建时的变量,这些变量可以在 Dockerfile 中使用,并且可以在构建时通过 --build-arg 参数传递给 docker build 命令。ARG 变量可以在 Dockerfile 中使用,并且在构建过程中的任意位置进行定义。

ARG 指令有两种形式:

  1. ARG <变量名>:定义一个只读的构建参数,可以在 Dockerfile 中使用。

    ARG VERSION
    RUN echo "Version is $VERSION"

    在构建时,你可以通过 --build-arg参数传递这个变量的值:

    docker build --build-arg VERSION=1.0 .

    注意:这种形式定义的变量只在构建过程中有效,不会传递到运行时的容器中。

  2. ARG <变量名>=<默认值>:定义一个带默认值的构建参数,如果构建时未提供这个参数的值,则使用默认值。

    ARG VERSION=1.0
    RUN echo "Version is $VERSION"

    如果在构建时没有传递 VERSION 参数,则会使用默认值 1.0。

ARG 指令的变量可以在 Dockerfile 的任意位置使用,包括 FROM、RUN、COPY、CMD 等指令中。

以下是一个使用 ARG 的示例 Dockerfile:

ARG BASE_IMAGE=ubuntu:latest
FROM $BASE_IMAGE

ARG APP_DIR=/app
RUN mkdir -p $APP_DIR
WORKDIR $APP_DIR

ARG APP_VERSION
RUN echo "Building version $APP_VERSION"

在构建时,你可以通过 --build-arg 参数传递这些变量的值:

docker build --build-arg BASE_IMAGE=debian:latest --build-arg APP_VERSION=1.0 .

这个命令会使用debian:latest 作为基础镜像,并且设置 APP_VERSION 为 1.0。

构建Tomcat环境

创建build-tomcat目录,上传tomcat、jdk软件包和仓库文件到目录内

[root@docker-master test-onbuild]# mkdir /build-tomcat
[root@docker-master test-onbuild]# cd /build-tomcat/
[root@docker-master build-tomcat]# cp /test-copy/Centos-vault-8.5.2111.repo ./
[root@docker-master build-tomcat]# ls
apache-tomcat-8.0.26.tar.gz  Centos-vault-8.5.2111.repo  jdk-8u45-linux-x64.rpm

编写dockerfile

[root@docker-master build-tomcat]# vim dockerfile 
FROM centos
MAINTAINER Caijx
RUN rm -rf /etc/yum.repos.d/*
COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/
RUN yum install wget -y
ADD jdk-8u45-linux-x64.rpm /usr/local/
ADD apache-tomcat-8.0.26.tar.gz /usr/local/
RUN cd /usr/local && rpm -ivh jdk-8u45-linux-x64.rpm
RUN mv /usr/local/apache-tomcat-8.0.26 /usr/local/tomcat8
EXPOSE 8080

构建镜像并启动容器

[root@docker-master build-tomcat]# docker build -t="tomcat8:v1" .
[+] Building 13.1s (10/12)                                                                docker:default
 => [internal] load build definition from dockerfile  
 ...省略部分代码...
 [root@docker-master build-tomcat]# docker run -itd -p 8080 --name=tomcat-manual tomcat8:v1 
3741f67b9a1236888ae6fedb043190c9daef69cd6c1b4cfb58b32fb9f4598df7

进入容器内部,启动tomcat

[root@docker-master build-tomcat]# docker exec -it tomcat-manual /bin/bash
[root@3741f67b9a12 /]# /usr/local/tomcat8/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat8
Using CATALINA_HOME:   /usr/local/tomcat8
Using CATALINA_TMPDIR: /usr/local/tomcat8/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat8/bin/bootstrap.jar:/usr/local/tomcat8/bin/tomcat-juli.jar
Tomcat started.

查看tomcat进程是否成功启动

[root@3741f67b9a12 /]# ps -ef | grep tomcat 
root         38      0 14 08:38 pts/1    00:00:03 /usr/bin/java -Djava.util.logging.config.file=/usr/local/tomcat8/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/local/tomcat8/endorsed -classpath /usr/local/tomcat8/bin/bootstrap.jar:/usr/local/tomcat8/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat8 -Dcatalina.home=/usr/local/tomcat8 -Djava.io.tmpdir=/usr/local/tomcat8/temp org.apache.catalina.startup.Bootstrap start
root         66     15  0 08:38 pts/1    00:00:00 grep --color=auto tomcat
[root@3741f67b9a12 /]# ss -lntp | grep 8080  
LISTEN 0      100                     *:8080            *:*    users:(("java",pid=38,fd=48))

打开新终端,查看物理机映射的网页端口

[root@docker-master build-tomcat]# docker ps | grep tomcat
3741f67b9a12   tomcat8:v1                   "/bin/bash"              39 seconds ago      Up 37 seconds      0.0.0.0:32781->8080/tcp, :::32781->8080/tcp   tomcat-manual

访问tomcat网页,查看内容

[root@docker-master /]# curl 192.168.132.167:32781
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.0.26</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
...省略部分输出...

在构建 tomcat 镜像时候,基于镜像运行容器,但是需要进入到容器,手动启动 tomcat 服务, 那如果想要启动容器,tomcat 也自动启动,需要按照如下方法修改dockerfile。

[root@docker-master build-tomcat]# vim dockerfile 
FROM centos
MAINTAINER Caijx
RUN rm -rf /etc/yum.repos.d/*
COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/
RUN yum install wget -y
ADD jdk-8u45-linux-x64.rpm /usr/local/
ADD apache-tomcat-8.0.26.tar.gz /usr/local/
RUN cd /usr/local && rpm -ivh jdk-8u45-linux-x64.rpm
RUN mv /usr/local/apache-tomcat-8.0.26 /usr/local/tomcat8
ENTRYPOINT /usr/local/tomcat8/bin/startup.sh && tail -F /usr/local/tomcat8/logs/catalina.out