웹챗 SDK를 운영계에 배포하기 위해 nginx로 reverse proxy 설정을 해야할 필요가 생겼다.
클라우드 디스크 교체 작업 동안 운영계 서버를 쓸 수 없으니 일단 개인 ec2에서 하나의 서버에서 reverse proxy 설정을 해보고 운영계에 도전하기로 했다.
대략적인 구성은 다음과 같다.
외부에서는 http://my_ec2_host/sdk 로 접근하면 nginx는 reverse proxy로 도커로 띄운 http://my_ec2_host:4001/로 프록시 패스해준다.
1. nginx.conf
RHEL7 기준 default로 /etc/nginx 내에 위치한 nginx.conf를 다음과 같이 수정했다.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
# 번들링된 정적 파일 프록시
location /_next/static {
proxy_pass http://my_next_js_app:4001/_next/static;
}
# api route 프록시
location /api {
proxy_pass http://my_next_js_app:4001/api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location / {
# 이미지 프록시
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|woff2)$ {
proxy_pass http://my_next_js_app:4001;
}
# cors 해제
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://my_next_js_app:4001';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' 'http://my_next_js_app:4001';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' 'http://my_next_js_app:4001';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
# 페이지 프록시
location /sdk {
proxy_pass http://my_next_js_app:4001/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
# Next.js 자체에서 404 에러를 띄우므로 주석처리
# error_page 404 /404.html;
# location = /40x.html {
# }
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
}
번들링된 /_next/static과 api route를 신경써줘야 한다! 같은 서버에서 띄웠으므로 cors를 해제해주었다.
2. Next.js configuration
nginx에서 api route또한 proxy pass 해주었으므로 config에서 api route또한 http://my_ec2_host/api로 접근할 수 있게끔 해준다.
/* /config/env/production.js */
module.exports = {
// ...
api_domain: "http://my_ec2_host/api"
};
아주 초보적인 방법으로 기존의 docker로만 띄워서 4001번으로 접근했던 것을 서브 도메인으로 접근할 수 있도록 변경 끝!
3. Improvement
위에서는 하나의 컨테이너만 띄워져 있어서 Next.js 내 이미지를 받아오는 데 크게 문제가 없지만 만약 여러 개의 웹 서비스를 nginx가 동시에 처리하고 있다면 이미지 path 또한 nginx 에서 proxy pass 해주면 좋을 거 같다!
혹은 싱글 페이지가 아닌 link로 연결된 다수의 페이지가 있을 경우 또한 next.js의 assetPrefix를 활용하여 효율적으로 관리할 수 있다.
지금은 아주 초보적인 방법으로 접근했는데 실제 운영계에서는 다수의 컨테이너와 서비스들을 nginx가 처리하고 있어서 이를 처리하려면 모두 나눠야 할거 같다.
그건 다음에 성공하고 나서 기록해둬야지 ㅇ<-<
참고했던 URL들
'Today I Learn > 인프라' 카테고리의 다른 글
Jenkins, Github Action으로 CI 환경 구축 경험기 (0) | 2021.11.13 |
---|---|
[NGINX] Basic Authentication와 IP Address (0) | 2021.07.01 |
macOS iTerm2 zsh 설정하기 (0) | 2020.07.23 |
[2020-01-07] ec2 Next.js Docker 배포 이슈 (0) | 2020.01.07 |