在 docker hub 有成千上万的 docker 镜像,我们可以轻松的使用这些镜像构建容器。但在某些情况和用例中,我们希望在 docker 镜像中进行一些配置或更改,而这些更改应该在我们运行容器时出现。这可以通过使用 Dockerfile 构建 docker 镜像来实现。
Dockerfile 是一个文本文件,其中包含关键字和一组 Linux 命令,当我们构建 Docker Image 时,这些命令会自动执行。使用 Dockerfile 创建 docker 镜像类似于虚拟化世界的模板概念。
在这篇文章中,我们将介绍如何从 Dockerfile 逐步构建 docker 镜像。让我们假设我们想要构建 Jboss EAP docker 镜像。下面列出了一些通常在 Dockerfile 中使用的关键字
FROM 关键字指定将用于构建 Docker 镜像的基础镜像名称,Docker 命令将在本地搜索该映像,如果在本地注册表中没有找到,那么它将尝试从 Docker hub 注册表中获取它。
Example:
FROM jboss-eap:7
MAINTAINER 关键字指定了维护 Docker 镜像的社区或所有者的名称。
Example:
MAINTAINER Linuxtechi Team
在创建 Docker 镜像时,将执行 RUN 关键字后面提到的命令
Example :
RUN apt-get update
RUN apt-get install apache2 -y
RUN echo 'Web site Hosted inside a container' > /var/ww/html/index.html
RUN echo 'apache2ctl start' >> /root/.bashrc
WORKDIR 用于定义容器的工作目录,用于执行 COPY、ADD、RUN、CMD 和 ENTRYPOINT 指令。
Example:
WORKDIR /opt
当容器从 docker 镜像启动时,CMD 关键字后面提到的命令将被执行
Example:
CMD /bin/bash
CMD wget {url}
每当我们使用多个 CMD 关键字时,最新的关键字会获得首选项。如果您注意到运行容器时,我们会因 CMD 关键字(CMD /bin /bash)而获得 bash shell。
ENTRYPOINT 类似于 CMD, ENTRYPOINT 之后的命令将接受来自 CMD 的参数,或者换句话说,我们可以说 CMD 是 ENTRYPOINT 的参数。ENTRYPOINT 中的命令将始终被执行。
Example:
ENTRYPIONT ["curl"]
CMD ["www.google.com"]
使用 ENV 关键字,我们可以根据需求设置环境或 shell 变量,假设我想构建 Docker 映像,我将安装 java,并需要设置 java 路径,这可以通过使用 ENV 关键字来实现。
Example:
ENV JAVA_HOME= /usr/jdk/jdk{version}
通过 VOLUME 关键字,我们可以将 Docker 主机上的文件夹附加到容器上。
Example:
VOLUME /opt/storage /data
通过 EXPOSE 关键字,我们可以从容器中公开应用程序端口
Example:
EXPOSE 8080
使用 COPY 关键字,我们可以将文件从 docker dost 复制到容器中
Example:
COPY jboss-eap-7.2.0.zip /opt
ADD 关键字的功能几乎类似于 COPY。ADD 支持两个附加特性,比如我们可以使用 URL 而不是本地文件或目录,以及 tar 文件可以直接从源文件提取到目标文件。
Example :
ADD ./jdk-10.0.2.1-linux-x64_bin.tar.gz /usr/local/
Note: To view the keywords and command that are being used for building docker image use “docker history” command. Let’s see the keywords and commands of a docker image mariadb:latest
注意: 要查看用于构建 docker 映像的关键字和命令,请使用 docker history 命令。让我们看看 docker 映像 mariadb:latest 的关键字和命令
$ docker history mariadb:latest
在上面的输出中,如果命令中没有提到关键字,那么这些命令将以 RUN 关键字执行。
让我们开始使用 Dockerfile 构建 docker 映像的步骤。
首先在用户的主目录下创建一个名为 mycode 的文件夹,然后创建 Dockerfile
$ mkdir mycode
$ cd mycode/
$ touch Dockerfile
注意: docker 文件的名称必须是 Dockerfile,如果我们不遵循这个约定,我们的 docker 构建命令将不起作用。
用 vi 编辑器打开 Dockerfile 并添加以下关键字
$ vi Dockerfile
FROM jboss-eap:7
RUN mkdir -p /opt/jboss
COPY ./jboss-eap-7.2.0.zip /opt/jboss/
ENV JBOSS_HOME=/opt/jboss/jboss-eap-7.2
WORKDIR /opt/jboss/
RUN unzip -qq jboss-eap-7.2.0.zip
RUN $JBOSS_HOME/bin/add-user.sh admin Jobss@123# --silent
EXPOSE 8080 9990 9999
ENTRYPOINT ["/opt/jboss/jboss-eap-7.2/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0"]
存并退出文件
注意: 不要忘记将 jboss-eap-7.2.0.zip 放在 mycode 目录中,这个压缩包可以从下面的 url 下载
https://developers.redhat.com/content-gateway/file/jboss-eap-7.2.0.zip
From mycode folder, run the beneath docker build command, -t option is used to set tag name of docker image. In example below,I am setting tag as “ jboss-eap:v1 ”
在 mycode 文件夹下运行 docker build 命令,-t 选项用于设置镜像的标签名称。
$ docker build -t jboss-eap:v1 .
上面的输出确认映像已经成功构建。下一步,尝试使用新建的映像运行 jboss 容器。
让我们看看新建的 docker 映像在本地映像库中是否可用,运行以下命令
$ docker images
现在使用 docker 映像 jboss-eap:v1 运行一个容器
$ docker run -d -it --name=jboss-eap -P jboss-eap:v1
$ docker ps
现在使用下面的 url 访问 jboss 应用程序
http://:49154
使用我们在 Dockerfile 中定义的相同用户名和用户名