6 Dockerfile
6.1 Dockerfile 介绍
Dockerfile 是用来构建 Docker 镜像的文件!命令参数脚本!
构建步骤:
- 编写一个 Dockerfile 文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub、阿里云镜像仓库、本地镜像仓库)
查看官方 CentOS Dockerfile 镜像文件
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20201113" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-11-13 00:00:00+00:00"
CMD ["/bin/bash"]
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!
6.2 Dockerfile 构建过程
基础知识:
- 每个保留关键字(指令)都是必须是大写字母
- 执行从上到下顺序执行
- #表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交!
Dockerfile 是面向开发的,以后要发布项目,做镜像,就需要编写 Dockerfile 文件,这个文件十分简单!
Docker 镜像 --> SpringBoot 。镜像逐渐成为企业交付的标准,必须掌握。
步骤:开发,部署,上线运维 … 缺一不可!
- Dockerfile:构建文件,定义了一切的步骤,源代码。
- DockerImage:是通过 Dockerfile 构建生成的镜像,最终发布和运行的产品。
- Docker Container:容器就是镜像运行起来提供服务。
6.3 Dockerfile 的指令
FROM | #基础镜镜像,一切从这里开始构建 |
---|---|
MAINTAINER | #镜像是谁写的,姓名+邮箱 |
RUN | #镜像构建的时候需要运行的命令 |
ADD | #步骤: tomcat镜像,这个tomcat压缩包!添加内容 |
WORKDIR | #镜像的工作目录 |
VOLUME | #挂载的目录 |
EXPOSE | #保留端口配置 |
CMD | #指定这个容器的时候要运行的要求,只有最后一个会生效,可被替代 |
ENTRYPOINT | #指定这个容器的时候要运行的要求,ENTRYPOINT 后的指令会作为参数进行传入 |
ONBUILD | #当构建一个被继承 Dockerfile 这个时候就会运行 ONBUILD 的指令,才会触发指令 |
COPY | # 类似 ADD,将文件拷贝到镜像中 |
ENV | #构建的时候设置环境变量 |
参考 tomcat 8 的 dockerfile 入门 --> https://github.com/docker-library/tomcat
DockerHub 使用 docker run 运行的镜像,进行反解析之后就是 Dockerfile
# https://github.com/docker-library/tomcat/blob/master/10.0/jdk8/corretto-al2/Dockerfile
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM amazoncorretto:8-al2-jdk
ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME
# let "Tomcat Native" live somewhere isolated
ENV TOMCAT_NATIVE_LIBDIR $CATALINA_HOME/native-jni-lib
ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOMCAT_NATIVE_LIBDIR
# see https://www.apache.org/dist/tomcat/tomcat-10/KEYS
# see also "versions.sh" (https://github.com/docker-library/tomcat/blob/master/versions.sh)
ENV GPG_KEYS A9C5DF4D22E99998D9875A5110C01C5A2F6059E7
ENV TOMCAT_MAJOR 10
ENV TOMCAT_VERSION 10.0.23
ENV TOMCAT_SHA512 0e0263e8280f2ccfb4bef916444a6105fef689a3d95c334c8a7bfe59f1e3966d48ea624727f1818a4df331a603f1ac5e21b908dda3cae676ddc1aef90c2d12ab
RUN set -eux; \
\
# http://yum.baseurl.org/wiki/YumDB.html
if ! command -v yumdb > /dev/null; then \
yum install -y --setopt=skip_missing_names_on_install=False yum-utils; \
yumdb set reason dep yum-utils; \
fi; \
# a helper function to "yum install" things, but only if they aren't installed (and to set their "reason" to "dep" so "yum autoremove" can purge them for us)
_yum_install_temporary() { ( set -eu +x; \
local pkg todo=''; \
for pkg; do \
if ! rpm --query "$pkg" > /dev/null 2>&1; then \
todo="$todo $pkg"; \
fi; \
done; \
if [ -n "$todo" ]; then \
set -x; \
yum install -y --setopt=skip_missing_names_on_install=False $todo; \
yumdb set reason dep $todo; \
fi; \
) }; \
_yum_install_temporary gzip tar; \
\
ddist() { \
local f="$1"; shift; \
local distFile="$1"; shift; \
local mvnFile="${1:-}"; \
local success=; \
local distUrl=; \
for distUrl in \
# https://issues.apache.org/jira/browse/INFRA-8753?focusedCommentId=14735394#comment-14735394
"https://www.apache.org/dyn/closer.cgi?action=download&filename=$distFile" \
# if the version is outdated (or we're grabbing the .asc file), we might have to pull from the dist/archive :/
"https://downloads.apache.org/$distFile" \
"https://www-us.apache.org/dist/$distFile" \
"https://www.apache.org/dist/$distFile" \
"https://archive.apache.org/dist/$distFile" \
# if all else fails, let's try Maven (https://www.mail-archive.com/[email protected]/msg134940.html; https://mvnrepository.com/artifact/org.apache.tomcat/tomcat; https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/)
${mvnFile:+"https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/$mvnFile"} \
; do \
if curl -fL -o "$f" "$distUrl" && [ -s "$f" ]; then \
success=1; \
break; \
fi; \
done; \
[ -n "$success" ]; \
}; \
\
ddist 'tomcat.tar.gz' "tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz" "$TOMCAT_VERSION/tomcat-$TOMCAT_VERSION.tar.gz"; \
echo "$TOMCAT_SHA512 *tomcat.tar.gz" | sha512sum --strict --check -; \
ddist 'tomcat.tar.gz.asc' "tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz.asc" "$TOMCAT_VERSION/tomcat-$TOMCAT_VERSION.tar.gz.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
for key in $GPG_KEYS; do \
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
done; \
gpg --batch --verify tomcat.tar.gz.asc tomcat.tar.gz; \
tar -xf tomcat.tar.gz --strip-components=1; \
rm bin/*.bat; \
rm tomcat.tar.gz*; \
command -v gpgconf && gpgconf --kill all || :; \
rm -rf "$GNUPGHOME"; \
\
# https://tomcat.apache.org/tomcat-9.0-doc/security-howto.html#Default_web_applications
mv webapps webapps.dist; \
mkdir webapps; \
# we don't delete them completely because they're frankly a pain to get back for users who do want them, and they're generally tiny (~7MB)
\
nativeBuildDir="$(mktemp -d)"; \
tar -xf bin/tomcat-native.tar.gz -C "$nativeBuildDir" --strip-components=1; \
_yum_install_temporary \
apr-devel \
gcc \
make \
openssl11-devel \
; \
( \
export CATALINA_HOME="$PWD"; \
cd "$nativeBuildDir/native"; \
aprConfig="$(command -v apr-1-config)"; \
./configure \
--libdir="$TOMCAT_NATIVE_LIBDIR" \
--prefix="$CATALINA_HOME" \
--with-apr="$aprConfig" \
--with-java-home="$JAVA_HOME" \
--with-ssl \
; \
nproc="$(nproc)"; \
make -j "$nproc"; \
make install; \
); \
rm -rf "$nativeBuildDir"; \
rm bin/tomcat-native.tar.gz; \
\
# mark any explicit dependencies as manually installed
find "$TOMCAT_NATIVE_LIBDIR" -type f -executable -exec ldd '{}' ';' \
| awk '/=>/ && $(NF-1) != "=>" { print $(NF-1) }' \
| xargs -rt readlink -e \
| sort -u \
| xargs -rt rpm --query --whatprovides \
| sort -u \
| tee "$TOMCAT_NATIVE_LIBDIR/.dependencies.txt" \
| xargs -r yumdb set reason user \
; \
\
# clean up anything added temporarily and not later marked as necessary
yum autoremove -y; \
yum clean all; \
rm -rf /var/cache/yum; \
\
# sh removes env vars it doesn't support (ones with periods)
# https://github.com/docker-library/tomcat/issues/77
find ./bin/ -name '*.sh' -exec sed -ri 's|^#!/bin/sh$|#!/usr/bin/env bash|' '{}' +; \
\
# fix permissions (especially for running as non-root)
# https://github.com/docker-library/tomcat/issues/35
chmod -R +rX .; \
chmod 777 logs temp work; \
\
# smoke test
catalina.sh version
# verify Tomcat Native is working properly
RUN set -eux; \
nativeLines="$(catalina.sh configtest 2>&1)"; \
nativeLines="$(echo "$nativeLines" | grep 'Apache Tomcat Native')"; \
nativeLines="$(echo "$nativeLines" | sort -u)"; \
if ! echo "$nativeLines" | grep -E 'INFO: Loaded( APR based)? Apache Tomcat Native library' >&2; then \
echo >&2 "$nativeLines"; \
exit 1; \
fi
EXPOSE 8080
CMD ["catalina.sh", "run"]
6.3.1 FROM
基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是 from
6.3.2 MAINTAINER
镜像维护者的姓名和邮箱地址
6.3.3 RUN
容器构建时需要运行的命令(容器启动前做的一下预操作
),在 docker build 命令构建镜像的时候,就会执行RUN的部分
两种格式
- Shell 格式
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 指令
# 例如:
RUN yum install -y vim
- exec 格式
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
RUN 是在 docker build 时运行
6.3.4 EXPOSE
EXPOSE [/…]
EXPOSE 定义说明里面的服务端口。
该指令通知 Docker 容器在运行时侦听指定的网络端口。您可以指定端口是在 TCP 还是 UDP 上侦听,如果未指定协议,则默认值为 TCP。EXPOSE。
该指令实际上并不发布端口。它充当构建映像的人员和运行容器的人员之间的一种文档类型,有关要发布哪些端口。若要在运行容器时实际发布端口,请使用 标志 on 发布和映射一个或多个端口,或使用标志发布所有公开的端口并将其映射到高阶端口。EXPOSE-pdocker run-P
6.3.5 WORKDIR
WORKDIR /path/to/workdir
指定在创建容器后,终端默认登录的进来工作目录,一个落脚点
6.3.6 USER
指定该镜像以什么样的用户去执行,如果都不指定,默认是 root
6.3.7 ENV
用来在构建镜像过程中设置环境变量
ENV MY_PATH /usr/mytest
这个环境变量可以在后续的任何 RUN 指令中使用,这就如同在命令前面指定了环境变量前缀一样;
也可以在其他指令中直接使用这些环境变量
比如:WORKDIR $MY_PATH
6.3.8 ADD
ADD [–chown=:] …
ADD [–chown=:] [“”,… “”]
将宿主机目录下的文件拷贝进镜像并且会自动处理 URL 和解压 tar 压缩包。该功能仅在用于构建 Linux 容器的 Dockerfiles 上受支持,在 Windows 容器上不起作用。由于用户和组所有权概念不会在 Linux 和 Windows 之间转换,因此使用 和 用于将用户和组名称转换为 ID 会将此功能限制为仅适用于基于 Linux 操作系统的容器。
如果 是可识别的压缩格式(标识、gzip、bzip2 或 xz)的本地 tar 存档,则将其解压缩为目录。来自远程 URL 的资源不会解压缩。当复制或解压缩目录时,它的行为与 相同,结果是:tar -x
ADD 命令支持将远程URL的资源,但是 Docker 官方不建议直接用远程url,所以还是先下载到主机
是 COPY 的升级版。
6.3.9 COPY
类似 ADD,拷贝文件和目录到镜像中
将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的<目标路径>位置
COPY src dest
COPY [“src”, “dest”]
<src源路径>:源文件或者源目录
<dest目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建
6.3.10 VOLUME
VOLUME [“/data”]
容器数据卷,用于数据保存和持久化工作
该指令创建具有指定名称的装入点,并将其标记为保存来自本机主机或其他容器的外部装入卷。该值可以是 JSON 数组,也可以是具有多个参数(如 或 )的纯字符串。有关通过 Docker 客户端的更多信息/示例和挂载说明,请参阅通过卷共享目录文档。
VOLUMEVOLUME [“/var/log/”]VOLUME /var/logVOLUME /var/log /var/db
6.3.11 CMD
**指定容器启动(docker run)后的要干的事情**
CMD 容器启动命令
CMD 指令的格式和 RUN 相似,也是两种格式:
- shell 格式:CMD <命令>
- exec 格式:CMD [“可执行文件”, “参数1”, “参数2”, …]
- 参数列表格式:CMD[“参数1”, “参数2” …]。在指定了 ENTRYPOINT 指定后,用 CMD 指定具体的参数
注意
Dockerfile 中可以有很多个 CMD 指令,但是只有最后一个生效,CMD会被docker run 之后的参数替换
参考官网Tomcat 的 dockerfile 演示介绍
# 官网Dockerfile文件内容
......
EXPOSE 8080
CMD ["catalina.sh", "run"]
演示覆盖操作
$ docker run -it -p 8080:8080 -d billygoo/tomcat8-jdk8:latest /bin/bash
# 浏览器将无法访问8080 Tomcat 默认网页
它和前面 RUN 命令的区别
**CMD 是在 docker run 时运行**
**RUN 是在 docker build 时运行**
6.3.12 ENTRYPOINT
也是用来指定一个容器启动时要运行的命令
类似于 CMD 指令,但是 ENTRYPOINT 不会被 docker run 后面的命令覆盖,而且这些命令行参数会被当做参数送给 ENTRYPOINT 指令指定的程序
命令格式和案例说明
命令格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT 可以和 CMD 一起使用,一般是"变参"才会使用 CMD,这里的 CMD 等于是在给 ENTRYPOINT 传参
当指定了 ENTRYPOINT 后,CMD 的含义就发生了变化,
不再是直接运行其命令而是将 CMD 的内容作为参数传递给 ENTRYPOINT 指令,它两个组合会变成 <ENTRYPOINT> "<CMD>"
案例如下:假设已通过Dockerfile 构建了 "nginx:test 镜像"
FROM nginx
EXPOSE 80
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
是否传参 | 按照dockerfile编写执行 | 传参运行 |
---|---|---|
Docker命令 | docker run nginx:test | docker run nginx:test /etc/nginx/new.conf |
衍生出的实际命令 | nginx -c /etc/nginx/nginx.conf | nginx -c /etc/nginx/new.conf |
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
CMD 和 ENTRYPOINT 区别
CMD # 指定这个容器启动的时候要运行的命令,不可以追加命令
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
6.3.13 小总结
6.4 实战测试
Docker Hub 中 99% 镜像都是从这个基础镜像过来的 FROM scratch ,然后配置需要的软件和配置来进行的构建
6.4.1 创建自己的CentOS镜像
$ mdkir -pv /root/docker/mycentos01 && cd /root/docker/mycentos01
#1.编写Dockerfile的文件
$ vim Dockerfile
#设置基础镜像
FROM centos:centos7.9.2009
#设置镜像作者
MAINTAINER zhongzhiwei <[email protected]>
#配置环境变量
ENV MYPATH="/data"
#设置工作目录
WORKDIR $MYPATH
#安装 vim net-tools 软件
RUN yum makecache fast && \
yum install -y vim net-tools
#清空yum缓存
RUN yum clean all
#提示暴露端口
EXPOSE 80
#docker build运行的提示
RUN echo MYPATH is $MYPATH
RUN echo "---> Success ......"
#挂载卷
VOLUME /data
#设置容器启动的命令
CMD /bin/bash
#2.通过这个文件构建镜像
#命令:docker build -f Dockerfile <文件路径> -t 镜像名:[TAG]
$ docker build -t kube-centos:2.0 -f Dockerfile .
#3.测试运行
$ docker run -it --rm kube-centos:2.0 /bin/bash
[root@3fe81eda9f21 data]# pwd
/data
[root@3fe81eda9f21 data]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.11 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:0b txqueuelen 0 (Ethernet)
RX packets 6 bytes 516 (516.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@3fe81eda9f21 data]# vim --version | head -n 1
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Dec 15 2020 16:44:08)
我们可以列出本地镜像的变更历史
6.4.2 CMD 和 ENTRYPOINT 区别
测试 CMD
#编写Dockerfile文件
$ cat dockerfile1
FROM centos:centos7.9.2009
CMD ls -al
#构建镜像
$ docker build -t cmdtest:1.0 -f dockerfile1 .
#docker run 运行,发现我们的 ls -al 命令生效
$ docker run cmdtest:1.0
total 12
drwxr-xr-x 1 root root 6 Aug 26 03:07 .
drwxr-xr-x 1 root root 6 Aug 26 03:07 ..
-rwxr-xr-x 1 root root 0 Aug 26 03:07 .dockerenv
-rw-r--r-- 1 root root 12114 Nov 13 2020 anaconda-post.log
lrwxrwxrwx 1 root root 7 Nov 13 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Aug 26 03:07 dev
drwxr-xr-x 1 root root 66 Aug 26 03:07 etc
drwxr-xr-x 2 root root 6 Apr 11 2018 home
lrwxrwxrwx 1 root root 7 Nov 13 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 13 2020 lib64 -> usr/lib64
...省略部分输出...
#想追加一个命令参数 -h 使其想变成 ls -alh
$ docker run -it cmdtest:1.0 -h
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-h": executable file not found in $PATH: unknown.
#docker run 后的cmd 中的-h 会完全替换掉 CMD ls -al 命令,-h不是命令所以报错
测试 ENTRYPOINT
$ cat dockerfile2
FROM centos:centos7.9.2009
ENTRYPOINT ls -al
#构建镜像
$ docker build -t cmdtest:2.0 -f dockerfile2 .
#docker run 运行,发现我们的 ls -al 命令生效
$ docker run -it cmdtest:2.0
total 12
drwxr-xr-x 1 root root 6 Aug 26 03:14 .
drwxr-xr-x 1 root root 6 Aug 26 03:14 ..
-rwxr-xr-x 1 root root 0 Aug 26 03:14 .dockerenv
-rw-r--r-- 1 root root 12114 Nov 13 2020 anaconda-post.log
lrwxrwxrwx 1 root root 7 Nov 13 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Aug 26 03:14 dev
drwxr-xr-x 1 root root 66 Aug 26 03:14 etc
drwxr-xr-x 2 root root 6 Apr 11 2018 home
lrwxrwxrwx 1 root root 7 Nov 13 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 13 2020 lib64 -> usr/lib64
...省略部分输出...
#想追加一个命令参数 -h 使其想变成 ls -alh
#可以正常使用
#追加的命令,是直接拼接在我们的 ENTRYPOINT 命令的后缀
$ docker run -it cmdtest:2.0 -h
total 12
drwxr-xr-x 1 root root 6 Aug 26 03:15 .
drwxr-xr-x 1 root root 6 Aug 26 03:15 ..
-rwxr-xr-x 1 root root 0 Aug 26 03:15 .dockerenv
-rw-r--r-- 1 root root 12114 Nov 13 2020 anaconda-post.log
lrwxrwxrwx 1 root root 7 Nov 13 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Aug 26 03:15 dev
drwxr-xr-x 1 root root 66 Aug 26 03:15 etc
drwxr-xr-x 2 root root 6 Apr 11 2018 home
lrwxrwxrwx 1 root root 7 Nov 13 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 13 2020 lib64 -> usr/lib64
Dockerfile 中很多命令都十分的相似,我们需要了解它们的区别,对比他们测试效果。
6.4.3 实战:Tomcat 镜像
- 准备镜像文件 Tomcat 镜像,JDK 压缩包
$ mkdir -pv /root/dockerfile/mytomcat01 && cd /root/dockerfile/mytomcat01
$ wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.22/bin/apache-tomcat-9.0.22.tar.gz
#上传相应的JDK包
$ ls /root/dockerfile/mytomcat01/
apache-tomcat-9.0.22.tar.gz jdk-8u11-linux-x64.tar.gz
- 编写Dockerfile文件
#官方命名为 Dockerfile,docker build 会自动寻找这个文件,就不需要 -f 指定dockerfile文件了
$ vim /root/dockerfile/mytomcat01/Dockerfile
$ cat /root/dockerfile/mytomcat01/readme.txt <<EOF
#构建 tomcat 镜像
docker build -t mytomcat:1.0 -f Dockerfile .
EOF
$ vim Dockerfile
#设置基础镜像
FROM centos:centos7.9.2009
#设置镜像作者
MAINTAINER zhongzhiwei <[email protected]>
#配置环境变量
ENV MYPATH="/usr/local/"
#设置工作目录
WORKDIR $MYPATH
#拷贝 & 压缩文件
COPY readme.txt $MYPATH
ADD apache-tomcat-9.0.22.tar.gz $MYPATH
ADD jdk-8u11-linux-x64.tar.gz $MYPATH
#设置环境变量
ENV JAVA_HOME="/usr/local/jdk1.8.0_11"
ENV JRE_HOME="/usr/local/jdk1.8.0_11/jre"
ENV CLASSPATH="$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar"
ENV CATALINA_HOME="/usr/local/apache-tomcat-9.0.22"
ENV CATALINA_BASE="/usr/local/apache-tomcat-9.0.22"
ENV PATH="$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$CATALINA_BASE/bin:$PATH"
#设置成阿里云源
RUN rm -f /etc/yum.repos.d/* && \
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
#提示暴露端口
EXPOSE 8080
#docker build运行的提示
RUN echo MYPATH is $MYPATH
RUN echo "---> Success ......"
#挂载卷
VOLUME /data
#设置容器启动的命令
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/logs/catalina.out
- 构建镜像
$ docker build -t mytomcat:1.0 .
$ docker run -it -d \
--name tomcat01 -p 8080:8080 \
-v /data/docker/mytomcat01/test:/usr/local/apache-tomcat-9.0.22/webapps/test \
-v /data/docker/mytomcat01/logs:/usr/local/apache-tomcat-9.0.22/logs \
mytomcat:1.0
- 访问测试
$ curl localhost:8080
- 发布项目(由于做了卷挂载,我们直接在本地编写项目)
$ mkdir -p /data/docker/mytomcat01/test/WEB-INFO
$ vim /data/docker/mytomcat01/test/WEB-INFO/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
</web-app>
#WEB-INFO需要和index.jsp在同一级目录。
$ cat > /data/docker/mytomcat01/test/index.jsp <<EOF
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QingCloud (www.kubesphere.com)</title>
</head>
<body>
<%-- 该部分注释在网页中不会被显示--%>
<p>
Hello , World
</p>
</body>
</html>
EOF
$ curl 10.0.0.101:8080/test/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QingCloud (www.kubesphere.com)</title>
</head>
<body>
<p>
Hello , World
</p>
</body>
</html>
发现,项目部署完成,可以直接访问OK!
以后开发的步骤,需要掌握 Dockerfile 的编写!我们之前的一切都是使用 Docker 镜像来发布运行的!
7 发布自己的镜像
7.1 发布镜像到 Dockerhub
DockerHub
- DockerHub 地址 https://hub.docker.com/ 注册自己的账号
- 确定这个账号可以登录
- 在我们服务器上提交自己的镜像
$ 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
- 登录完毕后就可以提交镜像了,就是一步 docker push 镜像名:[TAG]
范例:
$ docker login -u "dragonzw" -p "......"
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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
#设置镜像的标签
$ docker tag mytomcat:1.0 dragonzw/tomcat:1.0
#推送镜像到DockerHub
$ docker push dragonzw/tomcat:1.0
7.2 发布镜像到 阿里云
$ sudo docker login --username=dragon志伟 registry.cn-shenzhen.aliyuncs.com
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
#重新镜像打标签
#$ docker tag tomcat:[镜像版本号] registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:[镜像版本号]
$ docker tag mytomcat:1.0 registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:1.0
#推送镜像
#$ docker push registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:[镜像版本号]
$ docker push registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:1.0
#$ docker pull registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:[镜像版本号]
$ docker pull registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:1.0$ sudo docker login --username=dragon志伟 registry.cn-shenzhen.aliyuncs.com
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
#重新镜像打标签
#$ docker tag tomcat:[镜像版本号] registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:[镜像版本号]
$ docker tag mytomcat:1.0 registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:1.0
#推送镜像
#$ docker push registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:[镜像版本号]
$ docker push registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:1.0
#$ docker pull registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:[镜像版本号]
$ docker pull registry.cn-shenzhen.aliyuncs.com/dragonzw_personal_images/tomcat:1.0
#在阿里云个人的镜像仓库就可以查看到 tomcat 的镜像版本。
阿里云容器镜像就可以参考阿里云官方文档即可。