docker部署java项目(使用Docker部署Java应用)

 分类:IT知识时间:2022-07-16点击:

创建Java应用

这里我们使用SpringBoot创建一个提供HTTP访问能力的Java应用,以便于我们验证部署结果。

我们可以使用spring initializer来创建,如果是使用的是IntelliJ IDEA的社区版,可以在spring官网来配置一个SpringBoot项目并下载到本地。

在浏览器中打开网址:https://start.spring.io/
在这个界面中,我们可以对项目进行初始的配置。因为这个项目当前仅做演示用,因此我们暂时先不进行额外的修改。但是需要注意的是,我们需要将Java的版本选为“11”,同时添加“Spring Web”依赖。然后点击下方的“GENERATE”按钮,将生成Maven项目并下载。

使用Docker部署Java应用

生成SpringBoot项目

为了避免有小伙伴因为网络等原因无法生成初始项目,此处我们贴出两个关键文件的代码(其他文件即使没有也不影响)。

/pom.xml:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </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>
        </plugins>
    </build></project>

/src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class DemoApplication {    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

然后,我们修改DemoApplication.java文件,增加一个RESTful接口用以后续测试,此时我们仅简单地输出一个字符串即可。修改后的文件内容如下:

package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;@RestController@SpringBootApplicationpublic class DemoApplication {    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }    @RequestMapping(method = RequestMethod.GET)
    String hello() {        return "Hello Docker";
    }
}

然后,我们打开一个控制台,进入到项目目录(包含pom.xml的目录)中,执行以下命令对项目进行编译打包:

mvn clean package

打包成功后,我们进入到“target”目录中运行应用:

cd targetjava -jar demo-0.0.1-SNAPSHOT.jar

其输出如下:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.3)2022-01-27 01:22:28.696  INFO 3540 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication v0.0.1-SNAPSHOT using Java 17.0.1 on talefox with PID 3540 (E:\source-code\docker\demo\target\demo-0.0.1-SNAPSHOT.jar started by talefox in E:\source-code\docker\demo\target)2022-01-27 01:22:28.699  INFO 3540 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default2022-01-27 01:22:29.431  INFO 3540 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)2022-01-27 01:22:29.440  INFO 3540 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]2022-01-27 01:22:29.440  INFO 3540 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.56]2022-01-27 01:22:29.499  INFO 3540 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext2022-01-27 01:22:29.499  INFO 3540 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 755 ms2022-01-27 01:22:29.776  INFO 3540 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''2022-01-27 01:22:29.783  INFO 3540 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.41 seconds (JVM running for 1.714)

此时应用已顺利启动,我们可以在浏览器中访问这个API:



访问本地应用

此时,我们已经准备好了一个Java应用,下面我们将其部署到Docker容器中。

部署应用

首先,我们在项目的根目录中创建“Dockerfile”文件,并将以下内容保存到文件中:

FROM openjdk:11COPY ./target/demo-0.0.1-SNAPSHOT.jar /opt/demo/WORKDIR /opt/demo

此处我们再啰嗦一次这个Dockerfile文件内容的含义:

  • 步骤一,FROM openjdk:11,使用openjdk:11镜像作为我们待部署应用的容器的父镜像,这个镜像是我们在《使用Docker制作OpenJDK镜像》章节中制作的镜像

  • 步骤二,COPY ./target/demo-0.0.1-SNAPSHOT.jar /opt/demo/,将“target”目录下的“demo-0.0.1-SNAPSHOT.jar”文件拷贝到容器的“/opt/demo/”目录中

  • 步骤三:WORKDIR /opt/demo,将“/opt/demo”设置为工作目录,即在容器中进行操作的初始目录

然后,我们将项目目录作为共享目录挂载到虚拟机中:

使用Docker部署Java应用

将项目目录挂载到虚拟机

之后,我们启动虚拟机,并通过SSH连接到虚拟机进行操作,继续制作镜像。

首先,我们进入到项目目录(挂载共享目录时指定的目录):

cd /root/demo

然后,我们执行以下命令,制作Docker镜像:

docker image build -t demo:0.0.1 .

需要注意的是,这行命令的最后有一个点,表示在当前目录中寻找Dockerfile文件以制作命令。其中“-t”用来指定镜像的标签,这个镜像的标签即为“demo:0.0.1”。

镜像制作完成后,其输出结果如下:

Sending build context to Docker daemon  17.71MBStep 1/3 : FROM openjdk:11
 ---> de5d1368d569Step 2/3 : COPY ./target/demo-0.0.1-SNAPSHOT.jar /opt/demo/
 ---> 83f24fbed424Step 3/3 : WORKDIR /opt/demo
 ---> Running in b683a2804786Removing intermediate container b683a2804786
 ---> 9c07fc5eb13fSuccessfully built 9c07fc5eb13fSuccessfully tagged demo:0.0.1

现在,我们可以在本地看到刚刚制作的“demo:0.0.1”镜像了:

docker image ls

其输出结果为:

REPOSITORY   TAG       IMAGE ID       CREATED              SIZEdemo         0.0.1     9c07fc5eb13f   About a minute ago   532MBopenjdk      11        de5d1368d569   26 hours ago         514MBmysql        8.0.28    5b4c624c7fe1   6 days ago           519MBcentos       7         eeb6ee3f44bd   4 months ago         204MB

验证镜像

首先,我们使用新创建的镜像来创建一个容器并运行,将本机的8080端口绑定到容器的8080端口,并在容器中运行Java应用:

docker run --name demo -p 8080:8080 -d demo:0.0.1 java -jar demo-0.0.1-SNAPSHOT.jar

其中参数的含义如下:

  • --name,指示新创建的容器的名称为“demo”

  • -p,等同于“--publish”,指示在本机的8080端口发布容器的8080端口,需要注意的是冒号前是本机端口,后面是容器的端口

  • -d,等同于“--detach”,表示后台运行,并输出容器的唯一标识

之后便是使用的镜像名称,及在容器中执行的命令。因为之前在Dockerfile中,我们已经指定了容器的工作目录为“/opt/demo”,因此此时我们直接执行java命令即可,此时便是在该工作目录下执行命令。

现在我们来通过浏览器验证一下部署的结果:

使用Docker部署Java应用

访问Docker中的应用

到这里,我们已经成功地将自己编写的Java应用在Docker中运行起来。


除注明外的文章,均为来源:老汤博客,转载请保留本文地址!
原文地址: