在 IDEA 中将项目部署到 Docker 中运行

此方法无法使用 debug,且启动起来可能会非常缓慢!应当在需要进行远程部署,测试等情况下进行使用。

这几天折腾 Docker 的网络问题弄得心力交瘁,最后发现好像在 Mac 上的确是找不到合适的,客户端无感知的解决方案。今天突然灵机一动,想到我干脆可以把项目作为容器部署到 Docker 里,然后把客户端(消费者)的端口映射到本机。

经测试,该方法确实可行,且实现起来非常容易。网上的教程都要求把项目打成 JAR 包,创建相应镜像并运行,但这是不必要的——IDEA 提供了直接在 container 中运行项目的能力,它会先在本地中构建项目,然后直接将整个项目共享给容器并直接通过 java 运行相应的 class 文件,就和本地运行一样,容器只需要引入 JVM 即可。

但它有一个比较大的问题——无法 debug,可能需要一些麻烦的配置吧,因此该方法显然不适合生产环境,但符合我当前的需求。有点怀疑无法 debug 是 mac 的问题。

材料

  • IDEA(当前版本自带 Docker 插件)
  • Docker
  • ❤️

创建 IDEA 项目

我们直接从 start.spring.io 上创建一个 Spring Boot 项目,为了方便测试,引入 Spring Web。

创建后,在主启动类下写个接口,启动一次项目。

1
2
3
4
5
6
7
8
9
10
11
@SpringBootApplication
@RestController
public class HigherApplication {
@GetMapping("/")
String sayHi(HttpServletRequest request) {
return "Hello, " + request.getRemoteHost() + ", It's there a future?";
}
public static void main(String[] args) {
SpringApplication.run(HigherApplication.class, args);
}
}

编写 Dockerfile

在根目录下创建一个Dockerfile,文件内容如下——

1
2
3
FROM java:8

# 的的确确只需要这一行,引入 Java 的运行时环境即 JVM 即可

配置启动项和 Docker

启动完项目后,IDEA 应该会自动创建一个启动项,我们直接对该启动项进行编辑。

首先点击右上角的启动项菜单,选择Edit Configurations...,然后点击Run on菜单,选择Docker...

在弹出的窗口中选择 Dockerfile 的文件路径,一路 next,finish 即可。第一次创建时会拉取该 image,可能会耗时很久。

在这里也可以配置将要生成的 image 和 container,需注意的是如果配置了 container 中发布特定端口的时候,启动多个 container 会导致失败(因为端口冲突),而它的表现是应用在启动界面直接退出,正常返回 0,这一点非常误导人。

启动,测试

启动该启动项,在 Run 界面 IDEA 应该会提示类似Application port 8080 is bound to local port 53248的信息(端口每次都会改变),通过浏览器检查localhost: 该端口是否能得到结果。

然后再测试一下其它容器能否访问该容器(如果可以,则该容器应当也能够访问其他容器),我们首先获得该容器的 IP,再从其他容器向该 IP 发送请求,如果得到回应说明这些容器是连通的。

1
2
3
4
$ docker ps # 找到该容器的 ID,这里我找到的值是 e116cca34a13
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' e116cca34a13 # 获取容器的 IP,我的是 172.17.0.2
$ docker run -it rancher/curl 172.17.0.2:8080 # 随便拉的 curl 镜像,用来发送请求
# 结果:Hello, 172.17.0.3, It's there a future?