欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Boot应用发布到Docker的实现

程序员文章站 2023-12-20 12:20:16
spring官网上有一篇getting start,介绍了如何使用docker发布spring boot应用,算是比较详细了,不过有些细节没有提及到,而且官网的入门手册是英...

spring官网上有一篇getting start,介绍了如何使用docker发布spring boot应用,算是比较详细了,不过有些细节没有提及到,而且官网的入门手册是英文版。这里重新整理记录一下,算是给英文不好的小伙伴一个参考,也给自己留个备忘。

准备

需要的工具以及运行环境:

  1. jdk 1.8 or later
  2. maven 3.0 +
  3. 你喜欢的ide或其他文本编辑器

创建工程

首先,你需要创建一个spring boot工程,spring tool suite和intellij idea都自带插件可以创建,还有一种方式是从上创建,推荐使用这种方式。填好表单中的group idartifact id之后,点击generate project按钮就可以生成了,将下载后的工程导入到你喜欢的ide中。

修改pom.xml文件,添加docker-maven-plugin:

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelversion>4.0.0</modelversion>
  <groupid>org.matrixstudio.springboot</groupid>
  <artifactid>docker</artifactid>
  <version>0.0.1-snapshot</version>
  <packaging>jar</packaging>

  <name>docker</name>
  <description>demo project for spring boot</description>

  <parent>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-parent</artifactid>
    <version>1.5.2.release</version>
    <relativepath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceencoding>utf-8</project.build.sourceencoding>
    <project.reporting.outputencoding>utf-8</project.reporting.outputencoding>
    <java.version>1.8</java.version>
    <docker.image.prefix>springio</docker.image.prefix>
  </properties>

  <dependencies>
    <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-web</artifactid>
    </dependency>

    <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-test</artifactid>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-maven-plugin</artifactid>
      </plugin>

      <!-- docker maven plugin -->
      <plugin>
        <groupid>com.spotify</groupid>
        <artifactid>docker-maven-plugin</artifactid>
        <version>0.4.3</version>
        <configuration>
          <imagename>${docker.image.prefix}/${project.artifactid}</imagename>
          <dockerdirectory>src/main/docker</dockerdirectory>
          <resources>
            <resource>
              <targetpath>/</targetpath>
              <directory>${project.build.directory}</directory>
              <include>${project.build.finalname}.jar</include>
            </resource>
          </resources>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

docker-maven-plugin插件用于将spring boot工程构建为docker镜像:

  1. imagename表示docker镜像名称,我们使用docker的命名规范,命名为:springio/docker
  2. dockerdirectory表示dockerfile的路径
  3. resource表示在构建时需要的资源文件,这些文件和dockerfile放在一起,这里只需要spring boot生成的jar文件即可。

打开dockerapplication.java文件,修改成如下内容:

package org.matrixstudio.springboot;

import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

@springbootapplication
@restcontroller
public class dockerapplication {

  @requestmapping("/")
  public string home() {
    return "hello docker world";
  }

  public static void main(string[] args) {
    springapplication.run(dockerapplication.class, args);
  }
}

编译并运行

执行如下命令运行spring boot工程:

mvn package && java -jar target/docker-0.0.1-snapshot.jar

打开浏览器,输入http://localhost:8080,如果出现“hello docker world”说明运行成功。

注:运行上面的命令时,需要从maven官方仓库中下载很多依赖包,国内网络不太稳定,下载速度较慢,可考虑使用第三方提供的镜像站,比如阿里的maven镜像仓库。在pom.xml中加入下面配置:

<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
  xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelversion>4.0.0</modelversion>
  <groupid>org.matrixstudio.springboot</groupid>
  <artifactid>docker</artifactid>
  <version>0.0.1-snapshot</version>
  <packaging>jar</packaging>

  <!-- dependencies -->
  ......

  <!-- build -->
  ......

  <!-- aliyun repository -->
  <repositories>
    <repository>
    <id>central</id>
      <name>aliyun</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <releases>
        <enabled>true</enabled>
      </releases>
    </repository>
  </repositories>
</project>

容器化项目

首先要确保你的机器上安装了docker,如果你的docker安装在一台linux服务器上,你需要将上面的spring boot工程上传到该服务器上,下面的步骤假设你是在linux环境上操作。

创建dockerfile

docker使用一个名为dockerfile的文件来指定image层,所以我们首先需要创建一个dockerfile文件,执行下面的命令创建dockerfile文件:

sudo tee src/main/docker/dockerfile <<-'eof'
from frolvlad/alpine-oraclejdk8:slim
volume /tmp
add docker-0.0.1-snapshot.jar app.jar
run sh -c 'touch /app.jar'
env java_opts=""
entrypoint [ "sh", "-c", "java $java_opts -djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
eof

大概解释一下上面的命令:

  1. volume指向了一个/tmp的目录,由于spring boot使用内置的tomcat容器,tomcat默认使用/tmp作为工作目录。效果就是在主机的/var/lib/docker目录下创建了一个临时文件,并连接到容器的/tmp。
  2. 将项目的jar文件作为app.jar添加到容器
  3. run表示在新创建的镜像中执行一些命令,然后把执行的结果提交到当前镜像。这里使用touch命令来改变文件的修改时间,docker创建的所有容器文件默认状态都是“未修改”。这对于简单应用来说不需要,不过对于一些静态内容(比如:index.html)的文件就需要一个“修改时间”。
  4. 为了缩短tomcat的启动时间,我们添加一个java.security.egd的系统属性指向/dev/urandom作为entrypoint。

构建docker镜像

运行下面的命令构建docker镜像:

mvn package docker:build

构建完成后,运行下面的命令查看:

sudo docker images

结果为: 

repository                   tag                 image id            created             size
springio/docker              latest              7e2ba2f7e81e        2 minutes ago       195 mb
frolvlad/alpine-oraclejdk8   slim                00d8610f052e        4 days ago          167 mb

可以看到我们构建的镜像已经出现了,下一步就是运行该镜像。

运行docker镜像

执行下面的命令来运行上一步构建的docker镜像:

sudo docker run -p 8080:8080 -t springio/docker

如果不出意外,你将看到下面的输出内容:

 .  ____     _      __ _ _
 /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/ ___)| |_)| | | | | || (_| | ) ) ) )
 ' |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: spring boot ::    (v1.5.2.release)

2017-03-08 03:34:59.434 info 6 --- [      main] o.m.springboot.dockerapplication     : starting dockerapplication v0.0.1-snapshot on 00eed53e6928 with pid 6 (/app.jar started by root in /)
2017-03-08 03:34:59.445 info 6 --- [      main] o.m.springboot.dockerapplication     : no active profile set, falling back to default profiles: default
2017-03-08 03:34:59.752 info 6 --- [      main] ationconfigembeddedwebapplicationcontext : refreshing org.springframework.boot.context.embedded.annotationconfigembeddedwebapplicationcontext@4b9af9a9: startup date [wed mar 08 03:34:59 gmt 2017]; root of context hierarchy
2017-03-08 03:35:03.755 info 6 --- [      main] s.b.c.e.t.tomcatembeddedservletcontainer : tomcat initialized with port(s): 8080 (http)
2017-03-08 03:35:03.807 info 6 --- [      main] o.apache.catalina.core.standardservice  : starting service tomcat
2017-03-08 03:35:03.821 info 6 --- [      main] org.apache.catalina.core.standardengine : starting servlet engine: apache tomcat/8.5.11
2017-03-08 03:35:04.042 info 6 --- [ost-startstop-1] o.a.c.c.c.[tomcat].[localhost].[/]    : initializing spring embedded webapplicationcontext
2017-03-08 03:35:04.043 info 6 --- [ost-startstop-1] o.s.web.context.contextloader      : root webapplicationcontext: initialization completed in 4303 ms
2017-03-08 03:35:04.441 info 6 --- [ost-startstop-1] o.s.b.w.servlet.servletregistrationbean : mapping servlet: 'dispatcherservlet' to [/]
2017-03-08 03:35:04.455 info 6 --- [ost-startstop-1] o.s.b.w.servlet.filterregistrationbean  : mapping filter: 'characterencodingfilter' to: [/*]
2017-03-08 03:35:04.457 info 6 --- [ost-startstop-1] o.s.b.w.servlet.filterregistrationbean  : mapping filter: 'hiddenhttpmethodfilter' to: [/*]
2017-03-08 03:35:04.468 info 6 --- [ost-startstop-1] o.s.b.w.servlet.filterregistrationbean  : mapping filter: 'httpputformcontentfilter' to: [/*]
2017-03-08 03:35:04.468 info 6 --- [ost-startstop-1] o.s.b.w.servlet.filterregistrationbean  : mapping filter: 'requestcontextfilter' to: [/*]
2017-03-08 03:35:05.110 info 6 --- [      main] s.w.s.m.m.a.requestmappinghandleradapter : looking for @controlleradvice: org.springframework.boot.context.embedded.annotationconfigembeddedwebapplicationcontext@4b9af9a9: startup date [wed mar 08 03:34:59 gmt 2017]; root of context hierarchy
2017-03-08 03:35:05.390 info 6 --- [      main] s.w.s.m.m.a.requestmappinghandlermapping : mapped "{[/]}" onto public java.lang.string org.matrixstudio.springboot.dockerapplication.home()
2017-03-08 03:35:05.402 info 6 --- [      main] s.w.s.m.m.a.requestmappinghandlermapping : mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.modelandview org.springframework.boot.autoconfigure.web.basicerrorcontroller.errorhtml(javax.servlet.http.httpservletrequest,javax.servlet.http.httpservletresponse)
2017-03-08 03:35:05.404 info 6 --- [      main] s.w.s.m.m.a.requestmappinghandlermapping : mapped "{[/error]}" onto public org.springframework.http.responseentity<java.util.map<java.lang.string, java.lang.object>> org.springframework.boot.autoconfigure.web.basicerrorcontroller.error(javax.servlet.http.httpservletrequest)
2017-03-08 03:35:05.512 info 6 --- [      main] o.s.w.s.handler.simpleurlhandlermapping : mapped url path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.resourcehttprequesthandler]
2017-03-08 03:35:05.512 info 6 --- [      main] o.s.w.s.handler.simpleurlhandlermapping : mapped url path [/**] onto handler of type [class org.springframework.web.servlet.resource.resourcehttprequesthandler]
2017-03-08 03:35:05.639 info 6 --- [      main] o.s.w.s.handler.simpleurlhandlermapping : mapped url path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.resourcehttprequesthandler]
2017-03-08 03:35:06.019 info 6 --- [      main] o.s.j.e.a.annotationmbeanexporter    : registering beans for jmx exposure on startup
2017-03-08 03:35:06.168 info 6 --- [      main] s.b.c.e.t.tomcatembeddedservletcontainer : tomcat started on port(s): 8080 (http)
2017-03-08 03:35:06.183 info 6 --- [      main] o.m.springboot.dockerapplication     : started dockerapplication in 7.893 seconds (jvm running for 8.743)
2017-03-08 03:35:56.728 info 6 --- [nio-8080-exec-1] o.a.c.c.c.[tomcat].[localhost].[/]    : initializing spring frameworkservlet 'dispatcherservlet'
2017-03-08 03:35:56.728 info 6 --- [nio-8080-exec-1] o.s.web.servlet.dispatcherservlet    : frameworkservlet 'dispatcherservlet': initialization started
2017-03-08 03:35:56.774 info 6 --- [nio-8080-exec-1] o.s.web.servlet.dispatcherservlet    : frameworkservlet 'dispatcherservlet': initialization completed in 43 ms

执行以下命令,查看正在运行的docker容器:

sudo docker ps

可以看到已经有一个docker容器在运行了:

 container id    image        command         created       status       ports          names
00eed53e6928    springio/docker   "sh -c 'java $java..."  about a minute ago  up about a minute  0.0.0.0:8080->8080/tcp  fervent_leavitt

现在输入http://localhost:8080可以查看到“hello docker world”结果。

如果要停止容器,可以执行下面的命令:

sudo docker stop 00e

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: