将Spring Boot项目运行在Docker上

一、使用Dockerfile构建Docker镜像

Dockerfile是一个文本文件,其中包含了若干条指令,指令描述了构建镜像的细节。

先来编写一个最简单的Dockerfile,编写一个Dockerfile修改该镜像的首页。

1:准备一个文件,名为Dockerfile:

> FROM nginx
> RUN echo '<h1>测试Dockerfile文件</h1>' > /user/share/nginx/html/index.html

FROM指令用语指定基础镜像,RUN指令用于执行命令。

2:在Dockerfile所在路径执行以下命令构建镜像:

docker build -t nginx:my .

其中,命令最后的(.)用于路径参数传递,表示当前路径。

3:执行以下命令,即可使用该镜像启动一个Docker容器。

docker run -d -p 92:80 nginx:my

4:访问http://Docker宿主机IP:92/,即可看到刚才修改的主页面。

Demo:使用Dockerfile构建Docker镜像

  1. 首先执行mvn clean package # 使用Maven打包项目
  2. 将项目构建成jar包:microservice-discovery-eureka-0.0.1-SNAPSHOT.jar ,那么如果我们想要启动项目则只需要在microservice-discovery-eureka-0.0.1-SNAPSHOT.jar所在的目录(即项目的target目录)执行:java -jar microservice-discovery-eureka-0.0.1-SNAPSHOT.jar
  3. 使用Dockerfile构建Docker镜像:

    microservice-discovery-eureka-0.0.1-SNAPSHOT.jar所在目录(默认即:项目构建后的target目录,当然也可以将jar文件拷贝到其他任意路径),创建文件,命名为Dockerfile。

    构建docker镜像,执行:docker build -t eacdy/test1 . # 格式:docker build -t 标签名称 Dockerfile的相对位置

    启动镜像:docker run -p 8761:8761 eacdy/test1
# 基于哪个镜像
FROM java:8
# 将本地文件夹挂载到当前容器
VOLUME /tmp
# 拷贝文件到容器,也可以直接写成ADD microservice-discovery-eureka-0.0.1-SNAPSHOT.jar /app.jar
ADD microservice-discovery-eureka-0.0.1-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
# 开放8761端口
EXPOSE 8761
# 配置容器启动后执行的命令
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

1.1Dockerfile常用指令

指令的一般格式为:指令名称参数。

1.1.1ADD复制文件

ADD用于复制文科,格式为:

 - ADD<src> .... <dest>
- ADD["<src>",..."<dest>"]

从src目录复制文件到容器的dest,其中src可以是Dockerfile所在目录的相对路径,也可以是一个URL,还可以是一个压缩包。

  • src必须构建在上下文内,不能使用例如 ADD …/somethine/something这样的命令,因为docker build命令首先会将上下文路径和其子目录发送到docker daemon。
  • 如果src是一个URL,同时dest不以斜杠结尾,dest将被视为文件,src对应的内容文件将被下载到dest。
  • 如果src是一个URL,同时dest一些刚结尾,dest将被视为目录,src对于内容将被下载到dest目录,
  • 如果src是一个目录,那么正规目录下的内容将被复制,包括文件系统元数据。
  • 如果文件是可识别的压缩包格式,则docker会自动解压。

示例:

ADD microservice-discovery-eureka-0.0.1-SNAPSHOT.jar app.jar

1.1.2ARG设置构建参数

ARG指令用于设置构建参数,类似于ENV。ARG设置的是构建时的环境变量,在容器运行时是不会存在这些变量的。

格式为:ARG [name][=< default value>]

示例:

ARG user1=someuser

1.1.3CMD容器启动命令

CMD指令用于为执行容器提供默认值。每个Dockerfile只有一个CMD命令,如果指定了多个CMD命令,那么只有最后一条会被执行,如果启动容器时指定了运行的命令,则会覆盖CMD指定的命令。

支持3种格式:

CMD ["executable","parama","param2"]  (推荐使用)
CMD["param1","param2"] (为EMTRYPOINT指令提供预设参数)
CMD command param1 param2 (在shell中执行)

示例:

CMD echo "test." | wc -

1.1.4COPY复制文件

复制文件,格式为:

 - COPY <src> ... <dest>
- COPY ["<src>",..."<dest>"]

复制本地端的src到容器的dest。COPY不支持URL和压缩包。

1.1.5ENTRYPOINT入口点

格式为:

ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1 param2

ENTRYPOINT和CMD指令的目的一样,都是指定Docker容器启动时执行的命令,可多次设置,但只有最后一个有效。

1.1.6ENV设置环境变量

ENV指令用语设置环境变量,格式为:

ENV <key> <value>
ENV <key>=<value> ...

示例:

ENV JAVA_HOME /path/to/java

1.1.7EXPOSE声明暴露的端口

EXPOSE指令用语声明在运行时容器提供服务的端口,格式为:

EXPOSE <port> [<port>...]

这只是一个声明,运行时并不会因为该声明就打开相应的端口。该指令的作用主要是帮助镜像使用者理解该镜像服务的守护端口;其次是运行时使用随机映射时,会自动映射EXPOSE的端口。

示例:

声明暴露一个端口示例
EXPOSE port1
相应的运行容器使用的命令
docker run -p port1 image
也可使用-p选项启动
docker run -p image 声明暴露多个端口示例
EXPOSE port1 port2 port3
相应的运行容器使用的命令
docker run -p port1 -p port2 -p port3 image
也可指定需要映射到宿主机器的端口号
docker run -p host_port1 -p host_port2:port2 -p host_port3:port3 image

1.1.8FROM指定基础镜像

使用FROM指令指定基础镜像,FROM指令类似Java中的extends关键字。FROM指令必须指定且需要写在其他指令之前。FROM指令后的所有指令都依赖与该指令指定的镜像。

支持3种格式:

FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>

1.1.9LABEL为镜像添加元数据

LABEL指令用于为镜像添加元数据。

格式为:

LABEL <key>=<value> <key>=<value> <key>=<value> ...
使用" 和 \ 转换命令行;

示例:

LABEL "com.example.vendor"=" ACME Incorporated"
LABEL com.example.label-width-value="foo"
LABEL version="1.0"
LABEL description = "this test illustrates \
that label-values can span multiple lines."

1.1.10MAINTAINER 指定维护者的信息

MAINTAINER 指令用于指定维护者的信息,用于为Dockerfile署名。

格式为:

MAINTAINER  <name>

示例:

MAINTAINER  测试<eacdy000@qq.com>

1.1.11RUN执行命令

支持两种格式:

RUN <command>
RUN ["executable","param1","param2"]
RUN<command>在shell终端运行,在Windows中式cmd /s/c。
RUN ["executable","param1","param2"]使用exec执行,类似于函数调用。指定其他终端可以通过该方式操作,例如
RUN["/bin/bash","c","echo hello"],该方式必须使用双引号而不能使用单引号,因为该方式会被转换成一个JSON数组。

1.1.12USER设置用户

该指令用于设置启动镜像时的用户或者UID,写在该指令后的RUN、CMD以及ENTRYPOINT指令都将使用该用户执行命令。

格式为:USER 用户名

示例:

USER demo

1.1.13VOLUME指定挂载点

该指令使容器中的一个目录具有持久化存储的功能,该目录可被容器本身使用,也可共享给其他容器。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该命令。

格式为:VOLUME ["/data"]

示例:VOLUME /data

1.1.14WORKDIR 指定工作目录

格式为:WORKDIR /path/to/workdir

切换目录指令,类似cd,写在该指令后的RUN、CMD及ENTRYPOINT都将该目录作为当前目录,并执行相应的命令。

二、使用Maven插件构建Docker镜像

2.1使用插件构建Docker镜像

  • 在pom.xml中添加下面这段
    <build>
<plugins>
<!-- docker的maven插件,官网:https://github.com/spotify/docker-maven-plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.12</version>
<configuration>
<!-- 注意imageName一定要是符合正则[a-z0-9-_.]的,否则构建不会成功 -->
<!-- 详见:https://github.com/spotify/docker-maven-plugin Invalid repository name ... only [a-z0-9-_.] are allowed-->
<imageName>microservice-discovery-eureka</imageName>
<baseImage>java</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
  • 执行命令:
mvn clean package docker:build
  • 发现控制台有类似如下内容:
[INFO] Building image microservice-discovery-eureka
Step 1 : FROM java
Pulling from library/java
Digest: sha256:581a4afcbbedd8fdf194d597cb5106c1f91463024fb3a49a2d9f025165eb675f
Status: Downloaded newer image for java:latest
---> ea40c858f006
Step 2 : ADD /microservice-discovery-eureka-0.0.1-SNAPSHOT.jar //
---> d1c174083bca
Removing intermediate container 91913d847c20
Step 3 : ENTRYPOINT java -jar /microservice-discovery-eureka-0.0.1-SNAPSHOT.jar
---> Running in 0f2aeccdfd46
---> d57b027ca65a
Removing intermediate container 0f2aeccdfd46
Successfully built d57b027ca65a
[INFO] Built microservice-discovery-eureka
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:38 min
[INFO] Finished at: 2016-09-18T01:05:05-07:00
[INFO] Final Memory: 40M/198M
  • 执行docker images 会发现该镜像已经被构建成功:

REPOSITORY TAG IMAGE ID CREATED SIZE

microservice-discovery-eureka latest d57b027ca65a About a minute ago 681.5 MB

  • 启动镜像
docker run -p 8761:8761 microservice-discovery-eureka
  • 访问测试
访问http://Docker宿主机IP:8761 ,能够正常看到Eureka界面。

2.2docker部署spring boot服务 选择配置文件启动

默认启动命令:

docker run --name swapping -itd --net=host -v /etc/localtime:/etc/localtime:ro  -v /etc/timezone:/etc/timezone:ro  swapping

则 默认启动的配置文件是application.yml或者application.properties文件

如果要选择以开发配置文件启动则:

docker run --name swapping -itd --net=host -v /etc/localtime:/etc/localtime:ro  -v /etc/timezone:/etc/timezone:ro  swapping  --spring.profiles.active=test

加上参数,则启动的配置文件就是application-pro.yml或者application-pro.properties文件。

2.3向Docker容器传递参数


原文地址:CSDN:chenxing109:如何向Docker容器传递参数


2.3.1未定义 ENTRYPOINT, 定义了 CMD

没有定义 ENTRYPOINT 的镜像想怎么来就怎么来,docker run <image> 后面的输入你自己作主。

#ENTRYPOINT []
CMD ["echo", "hello"]

实际入口是它们拼接后还是 CMD 本身,[“echo”, “hello”]

2.3.2定义了 ENTRYPOINT 和 CMD

ENTRYPOINT ["echo", "hello"]
CMD ["echo", "world"]

实际入口是它们拼接起来,形成 [“echo”, “hello”, “echo”, “world”], 执行 docker run test 显示为 hello echo world.

2.3.3定义了 ENTRYPOINT, CMD 由 docker run 提供

ENTRYPOINT  ["echo", "hello"]

执行命令 docker run rm -rf /, 实际入口是由 [“echo”, “hello”] 与 [“rm”, “-rf”, “/”] 拼接而成的 [“echo”, “hello”, “rm”, “-rf”, “/”], 输出为 hello rm -rf /。看到 rm -rf / 也不用担心,用 ENTRYPOINT 就是让人放心

注:ENTRYPOINT 同样可以被覆盖,如 docker run --entrypoint ls test -l /,将会执行 ls -l / 命令。

2.3.4如果 ENTRYPOINT 用 shell 格式定义的

ENTRYPOINT java -jar /app.jar
CMD ["hello", "world"]

通过 docker inspect 命令看到镜像中实际的 ENTRYPOINT 是:

ENTRYPOINT ["/bin/sh", "-c", "java -jar /app.jar"]

所以与 CMD 连接起来的入口就是 ["/bin/sh", “-c”, “java -jar /app.jar”, “hello”, “world”],“bin/sh” 直接忽略掉后面的 “hello” 与 “world”,这就是为什么shell 命令方式无法获取参数。

2.3.5环境变量方式

对于 shell 格式的 ENTRYPOINT, 或者显式由 “/bin/sh -c” 来启动的命令,可以通过环境变量传入参数.

ENTRYPOINT java $JAVA_OPTS -jar app.jar $0 $@
#或显式的 ENTRYPOINT ["/bin/sh", "-c", "java $JAVA_OPTS -jar /app.jar $0 $@"]

启动容器时的命令用:

docker run -e JAVA_OPTS="-Xmx5G -Xms2G" <image-name> aa bb

那么实际执行 java 的完整命令就是:

java -Xmx5G -Xms2G -jar /app.jar aa bb

2.3.6总结

  1. 容器运行的最终入口由 ENTRYPOINT 和实际的 CMD 拼接而成。
  2. ENTRYPOINT 和 CMD 合并前需转换为 exec 格式(用 docker inspect <image> 查看),合并后(相当于数组) 第一个元素是命令,其他都为参数
  3. CMD 可在 Dockerfile 中配置,在启动容器时会被 docker run <image> 后的参数覆盖
  4. CMD 的 exec 格式中,第一个元素是 shell 的 $0, 其余元素是 shell 的 $@。当 ENTRYPOINT 中用

    shell 格式或显式的 sh(bash等)就可以引用 $0, $@
  5. 环境变量的解析是通过 sh(bash 等) 来解析的,所以 ENTRYPOINT [“echo”, “$name”] 中的 $name 是不被解析的
  6. 最能说明问题的是 docker inspect 看个究竟,Path 和 Args 说明了一切.

将Spring Boot项目运行在Docker上的更多相关文章

  1. 从零开始通过idea插件将一个spring boot项目部署到docker容器里运行

    实操:将一个spring boot项目部署到docker容器里运行 实验需要的环境: 腾讯云+Ubuntu 16.04 x64+idea+插件docker integration+daocloud 第 ...

  2. VS Code打开使用IDEA搭建的Spring Boot项目运行提示"snakeyaml was not found on the classpath"错误

    今天用VS Code打开之前基于IDEA搭建并开发的Spring Boot项目,启动调试后出现如下错误: 17:43:05.214 [restartedMain] ERROR org.springfr ...

  3. 使用jib-maven-plugin将Spring Boot项目发布为Docker镜像

    目录 介绍 使用 总结 介绍 将spring boot(cloud)项目发布到docker环境作为镜像,一般常用的一个是com.spotify的docker-maven-plugin这个maven插件 ...

  4. PM2 监控 Spring Boot 项目运行

    更多 PM2 的用法介绍请参考: PM2简易使用手册 - 掘金 由于 PM2 通常都用于 node 应用, 所以 exec_mode 应写为 fork, 其中最重要的是 args, -jar 和 ja ...

  5. 使用Docker部署Spring boot项目

    Docker是一个使用广泛的Linux容器管理工具包,它允许用户创建镜像,并将其容器实例化.通过本指南,我们可以学习到如何使用Docker部署Spring Boot项目. 先决条件 开发之前,你必须具 ...

  6. 在Docker中部署Spring Boot项目

    想要获取更多文章可以访问我的博客 - 代码无止境. 微服务现在在互联网公司可谓非常流行了,之前找工作的的时候很多HR电话约面试的时候都会问对微服务是否有过接触.而微服务和Docker可以非常完美的结合 ...

  7. Spring Boot项目微信云托管入门部署

    微信云托管本身是一个服务器,里面的软件都已经配置好了,直接使用即可,适用于一些简单部署的项目.直接把项目直接上传到服务器即可.无需各种繁琐的软件配置和打包,微信云托管统统给你搞定.而且系统会根据使用量 ...

  8. Eclipse创建第一个Spring Boot项目

    一.安装SpringBoot插件 安装过程需要联网下载插件,属于在线安装,请耐心等待安装完成,下载安装完成以后,需要重启Eclipse 二.创建Spring Boot项目 如下图所示new-other ...

  9. 【docker】docker部署spring boot项目在服务器上

    IDE:idea 工具:docker spring boot:2.0.1 ======================================== 简单记录一下流程,以供参考: 第一步:首先得 ...

随机推荐

  1. lambda表达式之方法引用

    /** * 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器.<br> * 与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码. ...

  2. 浅谈Java并发编程系列(八)—— LockSupport原理剖析

    LockSupport 用法简介 LockSupport 和 CAS 是Java并发包中很多并发工具控制机制的基础,它们底层其实都是依赖Unsafe实现. LockSupport是用来创建锁和其他同步 ...

  3. CentOS7搭建svn部署项目

    一.安装SVN[root@client ~]# yum install -y subversion查看安装了哪些文件[root@client ~]# rpm -ql subversion/etc/su ...

  4. G客短信平台开发,资源短信功能使用说明

    短信平台使用资源短信操作顺序  联系微信:290615413 1:登录客户端 2:点击左侧 发送短信中的,资源短信 3:资源短信申请操作 3.1:选择相应的省市 会显示资源数量. 3.2:然后输入申请 ...

  5. Head First 设计模式 —— 05. 单例模式

    全局变量的缺点 如果将对象赋值给一个全局变量,那么必须在程序一开始就创建好对象 P170 和 JVM 实现有关,有些 JVM 的实现是:在用到的时候才创建对象 思考题 Choc-O-Holic 公司使 ...

  6. Java并发编程实战(3)- 互斥锁

    我们在这篇文章中主要讨论如何使用互斥锁来解决并发编程中的原子性问题. 目录 概述 互斥锁模型 互斥锁简易模型 互斥锁改进模型 Java世界中的互斥锁 synchronized中的锁和锁对象 synch ...

  7. Netty学习之IO模型

    目录 1.1 同步.异步.阻塞.非阻塞     同步 VS 异步         同步         异步     阻塞 VS 非阻塞         阻塞         非阻塞     举例   ...

  8. .Net微服务实战之负载均衡(下)

    系列文章 .Net微服务实战之技术选型篇 .Net微服务实战之技术架构分层篇 .Net微服务实战之DevOps篇 .Net微服务实战之负载均衡(上) .Net微服务实战之CI/CD .Net微服务实战 ...

  9. 500 份源码合集——GitHub 热点速览 v.21.02

    作者:HelloGitHub-小鱼干 GitHub 项目名,如同变量命名,一个好的项目名能让你一眼就知道它是什么.500-AI-Machine-learning-Deep-learning-Compu ...

  10. 查找linux系统下的端口被占用进程的两种方法 【转】

    在linux下开发时,你的软件可能要使用某一个端口,或者想查找某一个端口是否被占用.需要怎么做呢??这的确是一个比较烦恼的问题,我也此为这个苦恼过.但是通过查找man手册,还是同事的交流.总结出来两种 ...