Docker 编写缓存依赖项而不是代码

Docker compose cache dependensies but not the code

我是一名 Java 后端开发人员,我想 docker 化后端部分,以便我的前端学院能够轻松 运行 在他的本地计算机上。我将根据演示项目描述我的问题。因此,演示项目由 mysql 和一个 spring 引导 Web 应用程序组成。当我使用 docker-compose 时,该应用程序运行良好,所有依赖项都在开始前下载,端点“测试”返回“一些消息”。当我更改代码并 docker-compose downdocker-compose up 应用程序时出现问题,代码没有改变。我可以做的来解决这个问题是在本地机器上打包应用程序,然后将其交付给 docker,但是本地机器必须有 maven 才能编译它,我不想那样,我想要我的大学只是为了使用 docker,并不关心这一切是如何运作的。另一种解决方案可能是不缓存,但每次我们重新启动应用程序时都必须下载依赖项,这也是不可接受的。所以我的问题是“有没有办法缓存依赖项(下载一次)而不是代码,这样当我启动应用程序时,一个带有更新代码的新应用程序会编译?"(对不起我的英语)。这是我正在测试的演示项目:

控制器:

@RestController
@RequestMapping("message")
@RequiredArgsConstructor
public class Controller {

    private final MessageRepository messageRepository;


    @GetMapping("/{id}")
    public Message getById(@PathVariable Long id) {
        return messageRepository.findById(id).get();
    }

    @PostMapping
    public Message save(@RequestBody Message message){
        return messageRepository.save(message);
    }

    @GetMapping("/test")
    public String ss(){
        return "Some message";
    }

}

型号:

@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "messages")
public class Message {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    private Long id;
    @Column(name = "text")
    private String text;
}

存储库:

@Repository
public interface MessageRepository extends JpaRepository<Message,Long> {}

属性 文件:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
    username: root
    password: 123456789
    driver-class-name: com.mysql.cj.jdbc.Driver
    sql-script-encoding: UTF-8
  jpa:
    database-platform: org.hibernate.dialect.MySQL8Dialect
    hibernate:
      ddl-auto: create-drop

Docker 文件位于 spring 项目的根目录中:

FROM maven:3.8.4-jdk-11
WORKDIR /demo
COPY . .
RUN mvn clean install package -Dmaven.test.skip
CMD mvn spring-boot:run

Docker 撰写文件:

version: "3.8"

services:
  mysqldb:
    image: mysql:8.0.27
    restart: unless-stopped
    environment:
      - MYSQL_DATABASE=db
      - MYSQL_ROOT_PASSWORD=123456789
    ports:
      - 3307:3306
    volumes:
      - db:/var/lib/mysql
  app:
    depends_on:
      - mysqldb
    build: ./demo
    ports:
      - 8080:8080
    environment:
      SPRING_APPLICATION_JSON: '{
        "spring.datasource.url"  : "jdbc:mysql://mysqldb:3306/db?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true",
        "spring.datasource.username" : "root",
        "spring.datasource.password" : "123456789",
        "spring.jpa.database-platform" : "org.hibernate.dialect.MySQL8Dialect",
        "spring.jpa.hibernate.ddl-auto" : "update"
      }'
    volumes:
      - .:/root
    stdin_open: true
    tty: true

volumes:
  db:

您的应用程序的图像已构建,并且它会为每个下一个 docker-compose up 重复使用相同的图像。

如果你想强制重建,你可以使用 docker-compose up --build。或者,您可以手动删除图像。但首先,您应该使用 属性:

命名您的图像
services:
  #...
  app:
    #...
    build: ./demo
    image: my_app

然后使用 docker image rm my_app 您可以删除它。之后,docker-compose up 应该重建您的应用程序。 所以你可以给你的前端同事以下 one-liner:

docker image rm my_app && docker-compose up -d

请注意 -d 运行与终端分离的 docker-compose。

1.In 您的项目创建一个 jar。因为我使用 eclipse,所以我只需单击 maven install 或 maven build 来创建 jar。

  1. 在您的 docker 文件中,您必须指定 jar 文件。
  2. 在您的 docker 撰写中还指定 jar,jar 在哪里、jar 文件名、端口等。这将为您的应用程序创建容器。

4.Inorder 到 运行 使用更新的代码,您必须将此命令用于 docker docker-compose -f dockercomposeYourFile.yaml up --build.

  1. 如果你有其他容器 docker compose 只需使用 depends_on 然后如果容器需要等待并导致停止你需要 restart: always 或任何关于 restart

我找到了解决方案。为了不下载依赖项,我需要将它们缓存在上层并将代码缓存在下层,这样当我更改代码时,我不必重新下载依赖项。 docker 文件如下所示。

FROM maven:3.8.4-jdk-11-slim
WORKDIR /opt/app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src/ src/
RUN mvn clean install -Dmaven.test.skip=true
ENTRYPOINT ["java", "-jar", "/opt/app/target/demo-0.0.1-SNAPSHOT.jar"]

正如@valerij-dobler所说,我需要删除我的容器以使我的代码更改生效

docker-compose down && docker image rm -f myapp && docker-compose up -d