docker镜像的三种创建方式
一、创建镜像的方式
创建镜像有三种方法,分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。
1、基于现有基础镜像创建
先使用基础镜像创建一个容器,然后对容器进行修改,最后使用commit命令提交为一个新的镜像
第一步,启动一个基础镜像,在容器里修改
#根据基础镜像,创建容器 docker run --name mytomcat -p 8080:8080 -d tomcat #修改容器 docker exec -it bcd08edac78d /bin/bash cd webapps/ROOT rm -f index.jsp echo welcome to tomcat > index.html exit
第二步,将容器里面运行的程序及运行环境打包生成新的镜像
#提交为新镜像,语法:docker commit -m="描述消息" -a="作者" 容器id或容器名 镜像名:tag
docker commit -m="修改默认索引页" -a="小洋" bcd08edac78d itany/tomcat:v1 说明: -m:说明信息 -a:作者信息 -p:生成过程中停止容器的运行 docker images 或docker inspect 新镜像名 #查看镜像信息
第三步,测试新镜像
#使用新镜像运行容器
docker run --name tomcat_v1 -p:8080:8080 -d itany/tomcat:v1
访问默认页:
http://ip:8080/index.html
2、基于本地模板创建
(1)使用wget命令导入镜像包
通过导入操作系统模板文件生成新的镜像 wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz
(2)导入镜像
cat debian-7.0-x86-minimal.tar.gz | docker import - debian:yhw docker images
(3)把镜像导入到容器中
docker run -it --name jc2 debian:yhw bash
ls
3、基于dockerfile创建
(1)联合文件系统(UnionFS)
• UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。AUES、OverlayES及Devicemapper都是一种UnionFS
• Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
• 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加教会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
• 我们下载的时候看到的一层层的就是联合文件系统
(2)镜像加载原理(bootfs、rootfs)
• Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统是UnionES
• bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统
• 在Docker镜像的最底层是bootfs,这一层与我们典型的Linux./tTnix系统是一样的,包含boot加载器和内核。当iboot加u载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs
• rootfs,在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu, centos等等
• 我们可以理解成一开始内核里什么都没有,操作一个命令下载debian,这时就会在内核上面加了一层基础镜像;再安装一个emacs,会在基础镜像上叠加一层image;接着再安装一个apache,又会在images上面再叠加一层image。最后它们看起来就像一个文件系统即容器的rootfs。在Docker的体系里把这些rootfs叫做Docker的镜像。但是,此时的每一层rootfs都是read-only的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs
(3)为什么Docker里的centos的大小才200M?
因为对于精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用宿主机的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
二、Dockerfile
1.Dockerfile 简介
1.1概述
• Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如核名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变
• 镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是Dockerfile
• Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了pockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成image即可,省去了敲命令的麻烦
• 除了手动生成Docker镜像之外,可以使用dockerfile自动生成镜像。Dockerfile是由多条的指令组成的文件,其中每条指令对应Linux中的一条命令,Docker程序将读取Dockerfile中的指令生成指定镜像
1.2Dockerfile结构
Dockerfile结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
Dockerfile每天支持一条指令,每条指令可携带多个参数,支持使用“#”号开头的注释
Dockerfile是用来构建Docker镜像的文件,是由一系列命令和参数构成的脚本
Dockerfile从FROM命令开始,紧接着各种命令、参数等,最终会生成一个新的镜像
1.3Dockerfile镜像结构的分层
镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。
如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层
(1)Dockerfile中的每个指令都会创建一个新的镜像层
(2)镜像层将被缓存和复用
(3)当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效
(4)某一层的镜像缓存失效,它之后的镜像层缓存都会失效
(5)镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在Docker容器中不可见了
(6)分层结构:共享资源、便于复用(许多镜像都是从相同的Base基础镜像构建而来的,基础镜像只需要保存一份)
(7)镜像都是只读的,而由镜像生成的容器是可修改的
1.4使用Dockerfile构建镜像的步骤:
- 编写Dockerfile文件
- 使用docker build构建镜像
- 使用docker run运行容器
2. 用法
2.1 语法规则
- 指令必须要大写,且后面必须跟参数
- 第一条指令必须是FROM,指定Base Image 基础镜像
- 指令按从上往下的顺序,依次执行
- 每条指定都会创建一个新的镜像层并提交
#
表示注释
2.2 docker执行dockerfile的流程
- docekr从基础镜像运行一个容器
- 执行一条指令并对容器做出修改
- 执行类似docker commint的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有指令都执行完
2.3 常用指令
指令 | 解释 | |
---|---|---|
FROM | 指定基础镜像,即当前新镜像是基于哪个镜像的 |
格式: FROM <image> FROM <image>:<tag> FROM <image>@<digest> 描述: tag和digest可选,不指定时,则使用latest版本基础镜像,digest表示V2 |
MAINTAINER | 指定镜像作者命名和邮箱地址 |
格式: MAINTAINER <name> 描述: name即为维护者信息,可自定义为姓名、邮箱地址等 示例: MAINTAINER andya MAINTAINER andya@163.com MAINTAINER andya <andya@163.com> |
RUN | 指定构建过程中要执行的命令 | 格式:
# shell执行 RUN <command> # exec执行 RUN ["executable", "param1", "param2"] 描述: 1)Dockerfile的指令每执行一次都会在docker上新建一层,所以尽量合并RUN。 2)exec执行格式是JSON数组,必须使用双引号描述。 3)exec格式不调用命令行shell,需要使用shell格式或者路径。 |
ENV | 用来在构建镜像过程中设置环境变量 |
格式: ENV <key> <value> ENV <key>=<value> ... 描述: 1)ENV <key> <value> 中的<key>后面内容都作为<value>的内容,
|
WORKDIR | 指定默认的工作目录,即进入容器后默认进入的目录,一个落脚点,默认不设置即为容器根目录/ |
格式: WROKDIR <dir> 描述: 1)设置工作目录后,Dockerfile后的命令RUN, CMD, ENTRYPOINT, |
VOLUME | 创建挂载点,也称容器数据卷,用于数据共享和持久化 |
格式: VOLUME ["<dir01>", "<dir02>", ...] VOLUME <dir> 描述: 指定持久化目录,卷可以存在于一个或多个容器的指定目录 示例: VOLUME ["/data/data01", "/data/data02"] VOLUME /data |
CMD |
指定容器启动时要运行的命令,与RUN不同的是,这些命令不是在镜像构建过程中执行的 Dockerfile中可以又多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换 |
格式: # exec form, this is the preferred form CMD ["executable","param1","param2"] # shell form CMD command param1 param2 # as default parameters to ENTRYPOINT CMD ["param1","param2"] 描述: 1)Dockerfile中若有多个CMD,则只有最后一个CMD有效。 2)当CMD为ENTRYPOINT提供默认参数时,CMD和ENTRYPOINT都需要以JSON数组格式进行声明。 3)同ENTRYPOINT,exec格式中CMD [ "echo", "$HOME" ]无效,需要指定sh -c,
|
ENTRYPOINT |
指定一个容器启动时要运行的命令 ENTRYPOINT和CMD一样,都是指定容器启动程序和参数 |
格式: # exec格式 ENTRYPOINT ["executable", "param1", "param2"] # shell格式 ENTRYPOINT command param1 param2 描述: 1)shell格式的将会拒绝任何CMD或者run命令行的参数,将以/bin/sh -c开头, |
COPY |
类似ADD 拷贝文件和目录到镜像中,但不可以自动解压文件,且不能访问网络资源 将从构建上下文目录中<源文件>的文件/目录复制到新的一层镜像内的<目标路径>位置 COPY src dest 或COPY [“src”,“dest”] |
格式: COPY [--chown=<user>:<group>] <src>... <dest> COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] 描述: 1)[--chown=<user>:<group>]为可选参数,改变文件的所属者和属组。 2)目标路径不存在时,会自动创建。 示例: COPY demo.tar demo01.tar COPY --chown=user01:group01 demo.tar demo02.tar
|
ADD | 将宿主机目录下的文件拷贝文件到镜像中,且ADD命令会自动处理URL和自动解压tar压缩包 |
格式: ADD <sourceDir1>... <dest> ADD ["<sourceDir1>", ... "<targetDir>"] 描述: 1)用[],可以支持包含空格的路径。 2)基本功能和格式同COPY。 示例: ADD demo.jar /app.jar ADD *.sh /shell ADD dir01 relativeDir/ ADD dir02 /absoluteDir
|
EXPOSE | 指定对外暴露的端口 |
格式: EXPOSE <port> [<port>/<protocol>...] 描述: 1)默认TCP协议。 2)EXPOSE不是真正的发布该端口,需要在docker run中使用-p进行发布, |
ONBUILD | 当构建一个被继承的dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发 | |
HEALTHCHECK |
健康检查 |
2.4RUN、ENTRYPOINT和CMD区别
- RUN是docker build构建docker镜像时执行的命令,真正运行一个命令并提交运行结果。
- CMD在docker build时期不执行任何东西,在docker run执行docker镜像构建容器时,为镜像声明了预期的命令。存在多条CMD时,只会执行最后一条,当同时存在ENTRYPOINT时,CMD命令将充当参数(exec格式提供默认值)或者被覆盖。若不存在ENTRYPOINT时,则可以动态覆盖或执行命令。
- ENTRYPOINT命令一定会执行,一般用于执行脚本。shell格式的ENTRYPOINT命令,都不会执行在Dockerfile中存在CMD命令还是在docker run添加的命令。exec格式的ENTRYPOINT命令,CMD命令或docker run添加的命令,会被当做ENTRYPOINT命令的参数执行。
-
CMD
在Dockerfile中可以有多个CMD指令,但只有最后一条指令生效,所以一般只有一条CMD指令
CMD指令在被docker run之后的参数覆盖
vi aaa FROM centos CMD ["/bin/ls"] CMD ["/bin/bash"] docker build -f aaa -t itany/aaa . docker run -it itany/aaa docker run -it itany/aaa /bin/pwd
-
ENTRYPOINT
docker run之后的参数会被作为ENTRYPOINT指令的参数,组合形成新的命令
vi bbb FROM centos ENTRYPOINT ["/bin/ls","/usr/local"] docker build -f bbb -t itany/bbb . docker run -it itany/bbb docker run -it itany/bbb -l # ls /usr/local -l
2.5案例:
FROM cenos
RUN yum install -y curl
CMD [ "curl", "-s", "http://ip.cn" ]
命令:docker build -f Dockerfile -t myip .
FROM cenos
RUN yum install -y curl
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
命令:docker build -f Dockerfile -t myip .
ONBUILD应用

2.6构建新镜像语法
语法:
docker build -f Dockerfile文件的路径 -t 镜像名:tag 命令执行的上下文
2.7在编写Dockerfile时,要遵循的格式
(2)之后使用MAINTAINER指令说明维护该镜像的用户信息
(3)然后是镜像操作相关指令,如RUN指令。每运行一条指令,都会给基础镜像添加新的一层
(4)最后使用CMD指令指定启动容器时要运行的命令操作
三、案例
1 自定义centos镜像
# 1.编写Dockerfile文件 vi Dockerfile2 FROM centos MAINTAINER tangxiaoyang@itany.com ENV MYPATH /usr/local/centos RUN mkdir -p $MYPATH WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install wget # 创建挂载点,无法指定宿主机上对应的目录,是自动生成的 VOLUME ["/data1","/data2"] CMD ["/bin/bash"] # 2.使用docker build构建镜像 docker build -f Dockerfile2 -t itany/centos:v1 . # 3.使用docker run运行容器 docker run -it b25b1dad795c # 查看镜像的变更历史 docker history b25b1dad795c # 验证挂载点: /var/lib/docker/volumes/0b001b4cc8db1ebbbb4c537c17a5c44adb700fb0e1b941bc82cc717c4ae196f6/_data /var/lib/docker/volumes/f020f5a5664bf68312be9f49a640f27ecfb49990b231aaf3d0eb7cb723fa0ddd/_data
2 自定义tomcat镜像
# 准备工作 # 1.编写Dockerfile文件 vi Dockerfile #base images: 基础镜像
FROM centos
#维护者信息 MAINTAINER tangxiaoyang@itany.com # 把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下 # 拷贝文件,文件必须与Dockerfile在同一目录下 COPY teacher.txt /usr/local #把java与tomcat添加到容器中 ADD jdk-8u171-linux-x64.tar.gz /usr/local ADD apache-tomcat-8.5.30.tar.gz /usr/local # 配置java和tomcat环境变量 ENV JAVA_HOME /usr/local/jdk1.8.0_171 ENV CLASSPATH .:$JAVA_HOME/lib ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.30 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin ##设置工作访问时候的WORKDIR路径,登录落脚点 ENV MYPATH /usr/local #工作目录,类似cd进入工作目录
WORKDIR $MYPATH #WORKDIR $CATALINA_HOME #执行命令 RUN yum -y install vim #容器运行时监听的端口 EXPOSE 8080 #启动时运行tomcat
#设定容器启动时第一个运行的命令及参数 # ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ] # CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"] #CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache CMD ["catalina.sh", "run"]
# 2.使用docker build构建镜像 docker build -t itany/tomcat:1.0 . #末尾有“.”代表当前目录
# 3.使用docker run新镜像运行容器 docker run \ --name mytomcat \ -p 8080:8080 \ -v /my/tomcat/webapps/spring-web.war:/usr/local/apache-tomcat-8.5.30/webapps/spring-web.war \ -d itany/tomcat:1.0
3、DOCKERFILE构建简单的微服务镜像
3.1拉取CONTOS7镜像
docker pull centos:7
3.2制作jdk镜像
1)新建一个空文件夹jdk1.8,将jdk-8u211-linux-x64.tar.gz、Dockerfile上传到该目录
2)编写vi Dockerfile
#依赖镜像名称和ID(切记,跟你宿主机上centos镜像的名称一样,不要复制我的) FROM /centos:7 #指定镜像创建者信息(随便写) MAINTAINER IMMORT #切换工作目录 WORKDIR /usr RUN mkdir /usr/local/java #ADD 是相对路径jar,把java添加到容器中 #(切记第一个jdk... 是你jdk文件的名字。不要复制我的,根据实际情况) ADD jdk-8u211-linux-x64.tar.gz /usr/local/java/ #配置java环境变量 ENV JAVA_HOME /usr/local/java/jdk1.8.0_211 ENV JRE_HOME $JAVA_HOME/jre ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH ENV PATH $JAVA_HOME/bin:$PATH
3)使用命令制作JDK1.8镜像
docker build -t='jdk1.8' . -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。 注意: 后面有一个点。此命令在dockerfile所在文件目录下运行。jdk1.8文件也放在此目录下。
4)制作微服务
# 依赖镜像名称和ID FROM jdk1.8 ADD app.jar /app.jar # 暴露的端口 EXPOSE 1300 # RUN:用于执行后面跟着的命令行命令。 RUN bash -c 'touch /app.jar' # CMD 指令允许用户指定容器的默认执行的命令。此命令会在容器启动且 docker run 没有指定其他命令时运行。 # 那么说白了,就是容器一启动,那么会自动使用java -jar 命令启动项目。 CMD ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
上传后的目录结构如下(与上面的jdk1.8的结构一样):
使用DOCKER命令创建镜像
docker build -t='web1.1' .
4、基于Ubuntu/centos构建Java项目
1)建一个空文件夹docker-demo:
2)将docker-demo.jar、jdk-8u171-linux-x64.tar.gz、Dockerfile上传到该目录
3)其中Dockerfile的内容如下:
# 指定基础镜像 FROM jdk1.8 # 拷贝java项目的包 ADD conf /opt/box-manage/conf ADD bin/ /opt/box-manage/bin ADD logs/ /opt/box-manage/logs ADD lib/ /opt/box-manage/lib #执行命令 #RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone RUN chmod +x /opt/safebox-manage/bin/start.sh # 暴露的端口 EXPOSE 8080 #指定工作目录 WORKDIR /opt/box-manage # CMD 指令允许用户指定容器的默认执行的命令。此命令会在容器启动且 docker run 没有指定其他命令时运行。 # 那么说白了,就是容器一启动,那么会自动使用java -jar 命令启动项目。 #CMD ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/opt/box-manage/lib/app.jar"] #带参数启动 #ENTRYPOINT java -server -Xmx512m -Xms512m -Xmn256m -Xss256k -XX:MetaspaceSize=96m -jar /opt/box-manage/lib/app.jar --spring.profiles.active=prod #执行脚本启动 CMD ["bash","/opt/box-manage/bin/start.sh"]
# 或者这样写 配置容器启动后执行的命令 ${JAVA_OPTS}:这样写,启动容器时可以添加JVM参数 ENTRYPOINT java ${JAVA_OPTS} -jar /app.jar #启动时也可以加JVM参数:# --cap-add=SYS_PTRACE 这个参数是让docker能支持在容器里能执行jdk自带类似jinfo,jmap这些命令,如果不需要在容器里执行这些命令可以不加 docker run -e JAVA_OPTS='-Xms1028M -Xmx1028M -Xmn512M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M' --cap-add=SYS_PTRACE -d -p 8761:8761 javaweb1.0 注意:docker-demo.jar为maven打包后的jar包jdk-8u171-linux-x64.tar.gz为JDK的Linux版本,版本号为jdk1.8.0_171注意JDK版本之间要对应
============================================
#将启动命令写入启动脚本start.sh。
RUN mkdir -p /home/admin
RUN echo 'eval exec java -jar $CATALINA_OPTS /home/admin/app/app.jar'> /home/admin/start.sh && chmod +x /home/admin/start.sh
WORKDIR $ADMIN_HOME
CMD ["/bin/bash", "/home/admin/start.sh"]
启动脚本:
vi start.sh
#!/usr/bin/env bash baseDir=$(cd "$(dirname "$0")"; pwd) ROOT_DIR="${baseDir}/.." export JAVA_HOME=$JAVA_HOME export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export LOG_HOME="${ROOT_DIR}/logs" PIDFILE="${ROOT_DIR}/bin/service.pid" #app name APP_NAME=`ls ${ROOT_DIR}/lib/safebox-manage-biz-*.jar` APP_CONF="${ROOT_DIR}/conf/application.yml" #设置需要加载的包的目录 最后加上项目主包 CLASSPATH=".:${ROOT_DIR}/lib/*:${ROOT_DIR}/conf/*" #这里可替换为你自己的执行程序,其他代码无需更改 ENV=pord #设置虚拟机参数 JAVA_OPTS="-server -Xmx512m -Xms512m -Xmn256m -Xss256k -XX:MetaspaceSize=96m" JAVA_OPTS="$JAVA_OPTS -XX:+DisableExplicitGC" JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC" JAVA_OPTS="$JAVA_OPTS -XX:CMSMaxAbortablePrecleanTime=5000" JAVA_OPTS="$JAVA_OPTS -XX:+CMSClassUnloadingEnabled " JAVA_OPTS="$JAVA_OPTS -XX:+CMSParallelRemarkEnabled" JAVA_OPTS="$JAVA_OPTS -XX:+UseFastAccessorMethods" JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSInitiatingOccupancyOnly" JAVA_OPTS="$JAVA_OPTS -XX:+ExplicitGCInvokesConcurrent" JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=80" JAVA_OPTS="$JAVA_OPTS -XX:SurvivorRatio=10" JAVA_OPTS="$JAVA_OPTS -XX:MaxDirectMemorySize=1g" JAVA_OPTS="$JAVA_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$LOG_HOME/java.hprof" JAVA_OPTS="$JAVA_OPTS -Xloggc:$LOG_HOME/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps" JAVA_OPTS="$JAVA_OPTS -Dlog_path=$LOG_HOME" #PARAM="--spring.config.location=${APP_CONF} --spring.profiles.active=${ENV}" PARAM="--spring.profiles.active=${ENV}" #采用加载所有jar 和指定 main class 启动方式
#该条shell命令将不会输出任何信息到控制台,也不会有任何信息输出到文件中
>/dev/null 2>&1 &
#nohup exec java ${JAVA_OPTS} -classpath ${CLASSPATH} -jar $APP_NAME ${PARAM} >/dev/null 2>&1 & #nohup java ${JAVA_OPTS} -classpath ${CLASSPATH} -jar $APP_NAME ${PARAM} & exec java ${JAVA_OPTS} -classpath ${CLASSPATH} -jar $APP_NAME ${PARAM}
4)构建镜像
docker build -t javaweb:1.0 .
5、基于java8构建Java项目
构建java项目的镜像,可以在已经准备了JDK的基础镜像基础上构建。
需求:基于java:8-alpine镜像,将一个Java项目构建为镜像
1)修改Dockfile的内容如下:
# 指定基础镜像 FROM java:8-alpine # 拷贝Java项目的包 COPY ./docker-demo.jar /opt/app.jar ADD config /opt/config #设置运行时工作目录 WORKDIR /opt # 暴露端口 EXPOSE 8090 # 入口,java项目的启动命令 ENTRYPOINT java -jar /tmp/app.jar
2)构建镜像
docker build -t javaweb:2.0 .
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
2021-03-30 vmstat命令
2021-03-30 grep命令