无法从 docker 容器外部访问 SpringBoot @RestController
SpringBoot @RestController not accessible from outside docker container
tl;dr 一个 RestController 正确回答,另一个不正确,如果 运行 在 Docker 容器内。
该服务有两个 APIs alive
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
public class AliveController {
@RequestMapping(value = "/alive", method = RequestMethod.GET)
public ResponseEntity<?> alive() {
return new ResponseEntity<>(HttpStatus.OK);
}
}
和callcount
.
@CrossOrigin
@RestController
public class CallController {
private static int callCount = 0;
@RequestMapping(value = "/callcount", method = RequestMethod.GET)
public ResponseEntity<?> callCount() {
return new ResponseEntity<>(++callCount, HttpStatus.OK);
}
}
它们都是 运行 到 docker-compose。
version: '2'
services:
service:
image: my/service
ports:
- "4000:4000"
docker-machine ip
returns 192.168.99.100
.
alive
return 一个空的 200 响应。不出所料。
$ curl -i http://192.168.99.100:4000/alive
HTTP/1.1 200
Content-Length: 0
Date: Mon, 22 Aug 2016 17:33:58 GMT
callcount
应该 return 200 响应和每次调用 API 时都会增加的数字。遗憾的是它没有。
$ curl -i http://192.168.99.100:4000/callcount
HTTP/1.1 404
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 22 Aug 2016 17:37:26 GMT
{"timestamp":1471887446871,"status":404,"error":"Not Found","message":"No message available","path":"/callcount"}
运行本地服务提供了预期的结果。
$ curl -i http://localhost:4000/callcount
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 22 Aug 2016 17:43:40 GMT
1
maven-spotify 插件用于从以下 Dockerfile
.
创建图像
FROM java:8
EXPOSE 4000
VOLUME /tmp
ADD service*.jar app.jar
#
# Without this, Java uses /dev/random to seed its SecureRandom class, which can cause Java code to block unexpectedly.
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]
我正在使用最新的 Docker 和 Docker-Compose 版本(2016 年 8 月 22 日下载)。
已解决!请参阅下面的更新部分。找到最终答案后将确定问题。 - 问题:为什么无法从 Docker 容器外部访问 callcount
?
进一步尝试:
@CrossOrigin(origins = "*", maxAge = 3600)
- 结果相同
- 来自 the spring docs 的全局 CORS 配置。
- 将这两个方法合并到 AliveController 中。
- 删除了所有容器和镜像,docker 从头开始构建。
更新日期:
callcount
API 未被 Spring 注册。我添加了另一个 test
API 来验证这一点,这也无法通过 curl 访问。 alive
仍然工作正常并显示在日志中。
bash-3.2$ docker logs asmstack_service_1 | grep callcount
bash-3.2$ docker logs asmstack_service_1 | grep test
bash-3.2$ docker logs asmstack_service_1 | grep alive
2016-08-23 08:42:06.530 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/alive],methods=[GET]}" onto public org.springframework.http.ResponseEntity<?> de.bahr.asmstack.AliveController.alive()
我在本地使用 JDK 1.8 (java.vm.vendor = Oracle Corporation)。
$ java -version
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)
启动方式的区别
当 运行将应用程序从 IntelliJ 中退出并使用 mvn spring-boot:run
时,callcount
已正确注册。如果 运行 和
则不会注册
java -Djava.security.egd=file:/dev/./urandom -jar my-service.jar
或
java -jar my-service.jar
。这应该是无法从 Docker 容器中访问它的原因。
知道为什么会这样吗?它在 2015 年底的另一个项目中是这样工作的。
我在@daniel.eichten 和@ShawnClark 的帮助下解决了这个问题,但我不明白为什么 这个fails/works。 T
这不是 Docker 问题,而是 Spring。
正如所见 (问题可能无关),我将 Spring-Application 从
更改为
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
到
@EnableAutoConfiguration
@EnableWebMvc
@Configuration
@ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
现在所有 API 都可以按预期访问,即使 运行 在 Docker 容器中也是如此。
tl;dr 一个 RestController 正确回答,另一个不正确,如果 运行 在 Docker 容器内。
该服务有两个 APIs alive
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
public class AliveController {
@RequestMapping(value = "/alive", method = RequestMethod.GET)
public ResponseEntity<?> alive() {
return new ResponseEntity<>(HttpStatus.OK);
}
}
和callcount
.
@CrossOrigin
@RestController
public class CallController {
private static int callCount = 0;
@RequestMapping(value = "/callcount", method = RequestMethod.GET)
public ResponseEntity<?> callCount() {
return new ResponseEntity<>(++callCount, HttpStatus.OK);
}
}
它们都是 运行 到 docker-compose。
version: '2'
services:
service:
image: my/service
ports:
- "4000:4000"
docker-machine ip
returns 192.168.99.100
.
alive
return 一个空的 200 响应。不出所料。
$ curl -i http://192.168.99.100:4000/alive
HTTP/1.1 200
Content-Length: 0
Date: Mon, 22 Aug 2016 17:33:58 GMT
callcount
应该 return 200 响应和每次调用 API 时都会增加的数字。遗憾的是它没有。
$ curl -i http://192.168.99.100:4000/callcount
HTTP/1.1 404
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 22 Aug 2016 17:37:26 GMT
{"timestamp":1471887446871,"status":404,"error":"Not Found","message":"No message available","path":"/callcount"}
运行本地服务提供了预期的结果。
$ curl -i http://localhost:4000/callcount
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 22 Aug 2016 17:43:40 GMT
1
maven-spotify 插件用于从以下 Dockerfile
.
FROM java:8
EXPOSE 4000
VOLUME /tmp
ADD service*.jar app.jar
#
# Without this, Java uses /dev/random to seed its SecureRandom class, which can cause Java code to block unexpectedly.
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]
我正在使用最新的 Docker 和 Docker-Compose 版本(2016 年 8 月 22 日下载)。
已解决!请参阅下面的更新部分。找到最终答案后将确定问题。 - 问题:为什么无法从 Docker 容器外部访问 callcount
?
进一步尝试:
@CrossOrigin(origins = "*", maxAge = 3600)
- 结果相同- 来自 the spring docs 的全局 CORS 配置。
- 将这两个方法合并到 AliveController 中。
- 删除了所有容器和镜像,docker 从头开始构建。
更新日期:
callcount
API 未被 Spring 注册。我添加了另一个 test
API 来验证这一点,这也无法通过 curl 访问。 alive
仍然工作正常并显示在日志中。
bash-3.2$ docker logs asmstack_service_1 | grep callcount
bash-3.2$ docker logs asmstack_service_1 | grep test
bash-3.2$ docker logs asmstack_service_1 | grep alive
2016-08-23 08:42:06.530 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/alive],methods=[GET]}" onto public org.springframework.http.ResponseEntity<?> de.bahr.asmstack.AliveController.alive()
我在本地使用 JDK 1.8 (java.vm.vendor = Oracle Corporation)。
$ java -version
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)
启动方式的区别
当 运行将应用程序从 IntelliJ 中退出并使用 mvn spring-boot:run
时,callcount
已正确注册。如果 运行 和
java -Djava.security.egd=file:/dev/./urandom -jar my-service.jar
或
java -jar my-service.jar
。这应该是无法从 Docker 容器中访问它的原因。
知道为什么会这样吗?它在 2015 年底的另一个项目中是这样工作的。
我在@daniel.eichten 和@ShawnClark 的帮助下解决了这个问题,但我不明白为什么 这个fails/works。 T
这不是 Docker 问题,而是 Spring。
正如所见
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
到
@EnableAutoConfiguration
@EnableWebMvc
@Configuration
@ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
现在所有 API 都可以按预期访问,即使 运行 在 Docker 容器中也是如此。