똑같은 문제를 새로운 프로젝트를 하면서 겪었는데, 해결법을 확인하러 블로그에 들어왔다. 예전에 블로그에 적은 줄 알았는데 안 적혀 있더라. 이 문제는 항상 자주 발생하는 문제인거 같다.
현재 도커를 활용하여 Spring Server Container 2개, Nginx 컨테이너를 사용하여 서버를 구축하고 있다.
하지만, Swagger에 접속하고 요청을 보내는 경우 endpoint가 http://3.xx.xx.xx/와 같이 우리 서버로 요청이 들어가야 하는데, 이상하게 http://backend로 요청이 가게 되었다. 이를 해결하기 위해 쉽게 Swagger의 설정을 바꾸면 되긴 했지만, 근본적으로 왜 이런 현상이 일어나는지 궁금해졌다.
문제가 생겼을 시점의 Nginx conf 파일이다.
upstream backend {
server api-server1:8080 weight=2;
server api-server2:8080 weight=2;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://backend;
}
ServletUriComponetsBuilders의 메소드의 host를 가져오는 부분을 잘 보자.
private static ServletUriComponentsBuilder initFromRequest(HttpServletRequest request) {
String scheme = request.getScheme();
String host = request.getServerName();
int port = request.getServerPort();
ServletUriComponentsBuilder builder = new ServletUriComponentsBuilder();
builder.scheme(scheme);
builder.host(host);
if (("http".equals(scheme) && port != 80) || ("https".equals(scheme) && port != 443)) {
builder.port(port);
}
return builder;
}
HttpServletRequest에서 getServerName의 설명을 보면, 요청이 보내진 서버의 호스트 이름을 리턴한다고 한다.
Host
값은 클라이언트가 전송한 요청 헤더의 Host
필드 값으로 당연하게 자동으로 설정되게 된다. upstream backend {
server api-server1:8080 weight=2;
server api-server2:8080 weight=2;
}
server {
listen 80;
listen [::]:80;
server_name example.com;
#access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://backend;
proxy_set_header Host $server_name;
}
}
@Bean
public Docket swaggerApi() {
return new Docket(DocumentationType.SWAGGER_2)
.host(hostUrl)
...
}
@OpenAPIDefinition(
servers = {
@Server(url = "/", description = "Default Server URL")
}
)
@SpringBootApplication
public class App {
// ...
}
혹은
@Bean
public OpenAPI customOpenAPI() {
Server server = new Server();
server.setUrl("https://example.com/api");
return new OpenAPI().servers(List.of(server));
}
출저 : https://www.vompressor.com/nginx-reverse-proxy/
https://developer88.tistory.com/299