Dockerfile的使用以及docker部署java项目
DockerFile定制一切
docker可以利用简单的编写程序构建出任何你想要的环境,同时可以跟业务代码相结合,快速构建和生成所需要的应用。
Dockerfile用来创建一个自定义的Image,包含了用户指定的软件依赖等。使用Docker的build命令可以直接构建新的Image。它简化了从头到尾的流程并极大地简化了部署工作。
一、Dockerfile语法
Dockerfile语法由两部分构成:注释和命令+参数
简单示例:构建一个简单的镜像
Dockerfile可以将文件名字设置为Dockerfile,若是别的文件名需结合-f指令,指定Dockerfile的文件名
在/gangye/dockerImageTestFile目录下编写两个Dockerfile文件,一个就为Dockerfile,另一个命名为helloDockerFile,里面的内容一致,皆为:
FROM centos
#只是单纯的打印"hello world"
RUN echo "hello world"
根据之前的Dockerfile创建镜像
docker build -t my_first_docker_image /gangye/dockerImageTestFile/
二、Dockerfile命令
Dockerfile 的指令如下。
FROM
FROM命令可能是最重要的Dockerfile命令。此命令定义了使用哪个基础镜像启动构建流程。基础镜像可以为任意镜像。如果基础镜像没有被发现,则Docker将试图从Docker image index来查找该镜像。
格式为FROM
第一条指令必须为FROM指令(虽然目前最新的docker版本支持第一条不一定是FROM指令,但是为避免后续出错,最好第一条指令就是FROM)。并且,在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。
MAINTAINER
格式为MAINTAINER
RUN
从名称上就可以看出,RUN是执行或运行的意思。
格式为RUN
前者将在Shell终端中运行命令,即/bin/sh -c;后者则使用exec执行。指定使用其他终端可以通过第二种方式实现,例如,RUN["/bin/bash","-c","echo hello"]。
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用"\"来换行。
EXPOSE
格式为EXPOSE
告诉Docker服务端容器暴露的端口号,供互联系统使用。
CMD
支持三种格式:
CMD ["executable","paraml","param2"]使用exec执行,推荐方式;
CMD command paraml param2在/bin/sh中执行,提供给需要交互的应用;
CMD ["paraml","param2"]提供给ENTRYPOINT的默认参数。
指定启动容器时执行的命令,每个Dockerfile只能有一条CMD命令。如果指定了多条命令,则只有最后一条会被执行。
如果用户启动容器时指定了运行的命令,则会覆盖CMD指定的命令。
ENTRYPOINT
两种格式:
1.ENTRYPOINT["executable","paraml","param2"]
2.ENTRYPOINT command paraml param2(Shell中执行)。
配置容器启动后执行的命令,并且不可被Docker RUN叫提供的参数覆盖。
每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个生效。
ENV
格式为ENV
例如 :
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl - SL http://example.com/postgres-$PG_VERSION.tar.xz | tar-xJC/usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
ADD
格式为ADD
该命令将复制指定的
COPY
格式为 COPY
复制本地主机的
当使用本地目录为源目录时,推荐使用COPY。
VOLUME
格式为VOLUME ["/data"]。
创建一个可以从本地主机或其他容器挂载的挂载点 , 一般用来存放数据库和需要保持的数据等。
WORKDIR
格式为WORKDIR /path/to/workdir。
为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。
可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
最终路径为/a/b/c 。
USER
格式为USER daemon。
指定运行容器时的用户名或UID,后续的RUN也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如,RUN groupadd -r postgres && useradd -r -g postgres postgres。要临时获取管理员权限可以使用go钮,而不推荐使用sudo。
ONBUILD
格式为ONBUILD [INSTRUCTION]。
配置当创建的镜像作为其他新创建镜像的基础镜像时,所执行的操作指令。
例如,Dockerfile使用如下内容创建了镜像image-A 。
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
如果基于A创建新的镜像,新的Dockerfile中使用FROM image-A指定基础镜像,则会自动执行ONBUILD指令内容,等价于在后面添加了两条指令。
FROM image-A
#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src
使用ONBUILD指令的镜像,推荐在标签中注明,例如,ruby:1.9-onbuild。
三、Dockerfile构建过程
Dockerfile其实可以看作一个命令集,每行均为一条命令,每行的第一个单词就是命令command,后面的字符串是该命令所要接收的参数。比如ENTRYPOINT /bin/bash。ENTRYPOINT命令的作用就是将后面的参数设置为镜像的entrypoint。
docker build的流程
(1)提取Dockerfile(evaluator.go/RUN)。
(2)将Dockerfile按行进行分析(parser/parser.go/Parse),每行第一个单词(如CMD、FROM等)叫作command。根据command,将之后的字符串用对应的数据结构进行接收。
(3)根据分析的command,在dispatchers.go中选择对应的函数进行处理(dispatchers.go)。
(4)处理完所有的命令,如果需要打标签,则给最后的镜像打上tag,结束。
Dockerfile逆向
通过docker history image可以看到该镜像的历史来源。即使没有Dockerfile,也可以通过history来逆向产生Dockerfile。
四、构建Java环境
- 首先做好准备工作,创建一个目录,在目录下,创建Dockerfile文件,以及准备好jdk以及一个可运行的jar文件
- 在Dockerfile中编写内容
# Set the base image
#FROM alpine:3.11
#FROM centos:7
#FROM debian:9
FROM alpine
###############################################################
# Dockerfile to build java container images
# Based on CentOS
# File Author / Maintainer
###############################################################
MAINTAINER bob 115765728@qq.com
#################################
#设置系统编码cenos
#RUN yum install kde-l10n-Chinese -y
#RUN yum install glibc-common -y
#RUN localedef -c -f UTF-8 -i zh_CN zh_CN.utf8
##RUN export LANG=zh_CN.UTF-8
##RUN echo "export LANG=zh_CN.UTF-8" >> /etc/locale.conf
##ENV LANG zh_CN.UTF-8
#ENV LC_ALL zh_CN.UTF-8
#################################
#设置系统编码debian
#dpkg-reconfigure locales
#RUN apt-get update
#RUN apt-get install locales vim -y
#RUN export LANG=zh_CN.UTF-8
#RUN echo "export LANG=zh_CN.UTF-8" >> /etc/locale.conf
#RUN echo "zh_CN.UTF-8 UTF-8" >> /etc/locale.gen
#RUN locale-gen
##################################
#设置系统编码apine
#mirrons aliun
RUN echo http://mirrors.aliyun.com/alpine/v3.10/main/ > /etc/apk/repositories && \
echo http://mirrors.aliyun.com/alpine/v3.10/community/ >> /etc/apk/repositories
# 更新最新镜像源列表
RUN apk update && apk upgrade
# 设置Docker 时间为上海时区
RUN apk add -U tzdata
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/shanghai" >> /etc/timezone
RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime && \
echo ${TZ} > /etc/timezone
# 依次安装命令:curl、scp、telnet
#RUN apk add curl
#RUN apk add openssh-client
#RUN apk add busybox-extras
# 添加glibc依赖
#RUN apk --no-cache add ca-certificates && \
#wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
#wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.29-r0/glibc-2.29-r0.apk && \
#apk add glibc-2.29-r0.apk
#install glibc
RUN apk --no-cache add libstdc++ ca-certificates bash wget curl && \
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
#wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-2.30-r0.apk && \
#wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-bin-2.30-r0.apk && \
#wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-i18n-2.30-r0.apk && \
wget http://192.168.10.21/file/1/buildsrc/glibc-2.30-r0.apk && \
wget http://192.168.10.21/file/1/buildsrc/glibc-bin-2.30-r0.apk && \
wget http://192.168.10.21/file/1/buildsrc/glibc-i18n-2.30-r0.apk && \
apk add glibc-2.30-r0.apk && apk add glibc-bin-2.30-r0.apk && apk add glibc-i18n-2.30-r0.apk && \
curl -Ls https://archive.archlinux.org/packages/z/zlib/zlib-1%3A1.2.9-1-x86_64.pkg.tar.xz -o libz.tar.xz && mkdir -p libz && tar -xf libz.tar.xz -C libz && \
mv libz/usr/lib/libz.so* /usr/glibc-compat/lib && \
rm glibc-2.30-r0.apk && rm glibc-bin-2.30-r0.apk && rm glibc-i18n-2.30-r0.apk && rm -rf /var/cache/apk/* && rm -rf libz/* && rm -rf libz.tar.xz
RUN apk add --update font-adobe-100dpi ttf-dejavu fontconfig && \
/usr/glibc-compat/bin/localedef -i zh_CN -f UTF-8 zh_CN.UTF-8 && \
echo export LANG=zh_CN.utf8 > /etc/profile.d/locale.sh
#################################
#设置语言
ENV LANG=zh_CN.UTF-8 \
LANGUAGE=zh_CN.UTF-8
ENV TZ=Asia/Shanghai
#添加java8环境
RUN mkdir /opt/jdk
COPY jdk-8u221-linux-x64.tar.gz /opt/jdk
RUN tar xzf /opt/jdk/jdk-8u221-linux-x64.tar.gz -C /opt/jdk
RUN rm -rf /opt/jdk/jdk-8u221-linux-x64.tar.gz
# 将目录中的zfile-release.jar复制到容器中
ADD zfile-release.jar app.jar
ENV JAVA_HOME=/opt/jdk/jdk1.8.0_221
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tool.jar
EXPOSE 80
ENTRYPOINT ["java","-Dfile.encoding=utf-8","-jar","-Dserver.port=80","/app.jar"]
-
在目录下执行docker build
sudo docker build -t bob/zfile .
-
查看所有镜像
sudo docker images
-
执行镜像,并查看当前启动的容器以及所有容器
sudo docker run -itd \
-v /mnt/disk0/zfile:/zfile:rw \
-v /mnt/appdata/zfile/.zfile:/root/.zfile:rw \
-e TZ=Asia/Shanghai \
-e PUID=1000 \
-e PGID=1000 \
--name=zfile \
--net=macnet \
--ip=192.168.10.21 \
--restart=unless-stopped \
bob/zfile
//-v /mnt/nfs/disk0/appdata/zfile/zfile-2.6.jar:/app.jar:rw \
//-v /mnt/nfs/disk0/appdata/zfile/.zfile-new:/root/.zfile-new:rw \
//--entrypoint=/bin/sh -c java -Xms10m -Xmx300m -Djava.security.egd=file:/dev/./urandom -jar zfile.jar \
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。