Docker 编写缓存依赖项而不是代码
Docker compose cache dependensies but not the code
我是一名 Java 后端开发人员,我想 docker 化后端部分,以便我的前端学院能够轻松 运行 在他的本地计算机上。我将根据演示项目描述我的问题。因此,演示项目由 mysql 和一个 spring 引导 Web 应用程序组成。当我使用 docker-compose 时,该应用程序运行良好,所有依赖项都在开始前下载,端点“测试”返回“一些消息”。当我更改代码并 docker-compose down 和 docker-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。
- 在您的 docker 文件中,您必须指定 jar 文件。
- 在您的 docker 撰写中还指定 jar,jar 在哪里、jar 文件名、端口等。这将为您的应用程序创建容器。
4.Inorder 到 运行 使用更新的代码,您必须将此命令用于 docker docker-compose -f dockercomposeYourFile.yaml up --build
.
- 如果你有其他容器 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
我是一名 Java 后端开发人员,我想 docker 化后端部分,以便我的前端学院能够轻松 运行 在他的本地计算机上。我将根据演示项目描述我的问题。因此,演示项目由 mysql 和一个 spring 引导 Web 应用程序组成。当我使用 docker-compose 时,该应用程序运行良好,所有依赖项都在开始前下载,端点“测试”返回“一些消息”。当我更改代码并 docker-compose down 和 docker-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。
- 在您的 docker 文件中,您必须指定 jar 文件。
- 在您的 docker 撰写中还指定 jar,jar 在哪里、jar 文件名、端口等。这将为您的应用程序创建容器。
4.Inorder 到 运行 使用更新的代码,您必须将此命令用于 docker docker-compose -f dockercomposeYourFile.yaml up --build
.
- 如果你有其他容器 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