【Docker】Dockerfile 和 发布制作镜像

6 Dockerfile

6.1 Dockerfile 介绍

Dockerfile 是用来构建 Docker 镜像的文件!命令参数脚本!

构建步骤:

  1. 编写一个 Dockerfile 文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. 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 构建过程

基础知识:

  1. 每个保留关键字(指令)都是必须是大写字母
  2. 执行从上到下顺序执行
  3. #表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交!

Dockerfile 是面向开发的,以后要发布项目,做镜像,就需要编写 Dockerfile 文件,这个文件十分简单!

Docker 镜像 --> SpringBoot 。镜像逐渐成为企业交付的标准,必须掌握。

步骤:开发,部署,上线运维 … 缺一不可!

  • Dockerfile:构建文件,定义了一切的步骤,源代码。
  • DockerImage:是通过 Dockerfile 构建生成的镜像,最终发布和运行的产品。
  • Docker Container:容器就是镜像运行起来提供服务。

img

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 # 指定这个容器启动的时候要运行的命令,可以追加命令

img

6.3.13 小总结

img

img

img

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)

我们可以列出本地镜像的变更历史

img

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 镜像

  1. 准备镜像文件 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
  1. 编写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
  1. 构建镜像
$ 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
  1. 访问测试
$ curl localhost:8080

img

  1. 发布项目(由于做了卷挂载,我们直接在本地编写项目)
$ 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>

img

发现,项目部署完成,可以直接访问OK!

以后开发的步骤,需要掌握 Dockerfile 的编写!我们之前的一切都是使用 Docker 镜像来发布运行的!

7 发布自己的镜像

7.1 发布镜像到 Dockerhub

DockerHub

  1. DockerHub 地址 https://hub.docker.com/ 注册自己的账号
  2. 确定这个账号可以登录
  3. 在我们服务器上提交自己的镜像
$ 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
  1. 登录完毕后就可以提交镜像了,就是一步 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

img

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 的镜像版本。

img

阿里云容器镜像就可以参考阿里云官方文档即可。

7.3 小结

img

猜你喜欢

转载自blog.csdn.net/weixin_40274679/article/details/131736988