当前位置: 首页 > 知识库问答 >
问题:

Docker上的Spring开发

廖夜洛
2023-03-14

我对Java和Spring很陌生。我正在寻找一个容器化的解决方案,它可以监视src文件夹,重新构建项目,并利用Spring devols热交换重新加载更改的类。

我进行了搜索,但我一直在寻找生产就绪容器,构建和运行的步骤是分开的。我尝试使用两个不同的容器,一个带有Gradle的容器保持构建(Gradle build--continuous),另一个容器执行构建结果:

version: '3.7'
services:

  builder:
    image: gradle:jdk11
    working_dir: /home/gradle/project
    volumes:
      - ./:/home/gradle/project
    command: gradle build --continuous

  api:
    image: openjdk:11-slim
    volumes:
    - ./build/classes:/app
    command: java -classpath /app/java/main com.example.Application

它失败了,因为Java在api容器中找不到依赖项(Spring、devtools、h2等),而且我不知道如何让Gradle在构建文件夹中包含外部JAR。我想这样做,只是这个例子已经过时了。

尽管如此,我还是一直在想可能有一个更优雅、更简单的解决方案。它不一定要与Gradle,它可以是Maven,如果它的作品!:)

我知道很多IDE都支持自动构建和开发工具,我只是想在Docker上实现它。这样,我将拥有一个在存储库上的开发工作流,而不是在IDE的配置上,并且实际上与任何开发环境都兼容。这是个坏主意吗?

共有1个答案

杜砚
2023-03-14

最后,我找到了一个非常有效的解决方案,只有一个警告。这当然是一个开发环境,旨在快速更改文件、自动构建和刷新Spring应用程序。它不是为了生产。

构建过程被委托给一个Gradle容器来监视更改。由于Gradle具有增量编译功能,因此即使对于大型项目,它也可以很好地扩展。

应用程序本身是在openjdk:11 slim上执行的。因为它运行.class文件,所以SpringBoot得到它的dev env并激活它的devtools

这是我的docker-compose.yml

version: '3.7'
services:

  builder:
    image: gradle:jdk11
    working_dir: /home/gradle/project
    volumes:
      - ./build:/home/gradle/project/build
      - ./src:/home/gradle/project/src
      - ./build.gradle:/home/gradle/project/build.gradle
    command: gradle build --continuous -x test -x testClasses

  api:
    image: openjdk:13-alpine
    volumes:
    - ./build:/app
    depends_on:
      - builder
    command: java -cp "/app/classes/java/main:/app/dependencies/*:/app/resources/main" com.example.Application

这是我的构建。gradle

plugins {
    id 'org.springframework.boot' version '2.2.1.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.1.0-SNAPSHOT'
sourceCompatibility = '11'

configurations {
    developmentOnly
    runtimeClasspath {
        extendsFrom developmentOnly
    }
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

task copyLibs(type: Copy) {
    from configurations.runtimeClasspath
    into "${buildDir}/dependencies"
}

build.dependsOn(copyLibs)

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.h2database:h2'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

test {
    useJUnitPlatform()
}

总而言之,整个重建和热交换源代码的更改需要5s。不是webpack一样快,但仍然可以接受。以这种方式使用它的最大好处是它驻留在代码上,每个人都可以让它工作,不管他们的工作站是什么。

警告?在第一次运行时,生成文件夹为空,并且api容器无法启动。您必须等待builder完成其工作,然后重新启动api

我仍然希望有一个更好的解决方案,我鼓励你发布比这更流畅的东西。

 类似资料:
  • 在这些日子里,我正在尝试部署我的Spring Boot OAuth2项目。它有3个不同的模块。(身份验证服务器,资源服务器和前端)身份验证和资源服务器有自己的*.yml文件配置,如mongodb名称-端口,服务器配置文件-IP等。我正在尝试做什么?我想在docker上部署Spring Boot应用程序,但我不想把我的数据库(mongodb)作为容器放在docker上。我不确定这种结构是否可行?因为

  • 编辑/解决方案: 我明白了,部分归功于@anemyte的评论。尽管属性不是问题所在(尽管它确实需要更正),但仔细观察后,我发现了问题的真正原因:正在使用的网络接口、端口转发和(糟糕的)运气。 不幸的是,客户机服务选择用它们的桥接接口IP向Eureka注册作为广告IP而不是内部swarm IP--可能是因为在这种情况下(Spring Cloud在内部使用)将返回该IP。 这导致我错误地认为Sprin

  • 问题内容: 我正在尝试为ZooKeeper创建docker容器并在集群模式下对其进行配置(完整的代码在此处和此处)。 容器基于Alpine Linux(Docker Hub上为alpine:3.2),但是我要描述的问题也出现在官方Java容器(java:7)上。 我使用以下命令来启动集群: (它们在docker hub上可用,您可以尝试)。 如果我等待一段时间开始的第二和第三个容器,那么主机名之前

  • 问题内容: 我正在尝试创建一个行为像完整虚拟机的Docker容器。我知道我可以在Dockerfile中使用EXPOSE指令公开端口,并且可以使用标志来分配端口,但是一旦容器实际运行,是否有命令打开/映射其他端口? 例如,假设我有一个运行sshd的Docker容器。有人使用ssh容器安装了httpd。有没有办法公开容器上的端口80并将其映射到主机上的端口8080,以便人们可以访问容器中运行的Web服

  • 用 PHP 作为我们「Docker 开发大礼包」开篇是带着一些朝圣的心情的。这是一门堪称「古老」的语言,也是一门争议最多的语言,更是一门不断涅槃的语言。「PHP 是最好的语言」这个流传已久的梗,或许正是对我国最有群众基础的编程语言描述里,最经典的注解。 就让我们一起回顾一下 PHP 的发展历程作为此系列文章的开篇。历史是最好的老师,他给每个未来提供启示。 谁创造了 PHP? Rasmus Lerd

  • 我最近几天的问题是,我正在尝试加密我的一些项目,我正在工作。由于Docker对我来说是一个很好的解决方案(如果它在本地运行,它将在远程运行),据我所知,我得到了3层可以实现我的ssl证书。第一层是实例或虚拟机(在我的例子中是本地的,aws或Google)。第二层是Docker守护进程(充当服务器或所有运行容器的管理器),最后一层是运行在jdk-alpine环境(可能是tomcat服务器)上的spr