2024. 8. 4. 01:17ㆍBE/Nginx
1. 리버스 프록시 설정법
위와 같이 path가 /
일 경우는 react를 빌드한 정적인 파일을 주고 path가 /api/v1
인 경우 8080 포트의 Spring-Boot 백엔드 서버로 요청을 전달한다.
#example.conf
server {
listen 80; # IPv4
listen [::]:80; # IPv6
server_name example.com;
location / {
root /app/build;
try_files $uri /index.html;
}
location /api/v1/ {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /robots.txt {
return 200 "User-agent: *\nDisallow: /";
}
}
2. server block
server {
listen 80; # IPv4
listen [::]:80; # IPv6
server_name example.com;
...
}
listen 80; # IPv4
: IPv4를 통해 포트 80에서 요청을 수신합니다.listen [::]:80; # IPv6
: IPv6를 통해 포트 80에서 요청을 수신합니다.server_name example.com;
: 서버의 도메인 이름을 설정합니다.
:example.com
의 도메인을 가진 경우에 대하여 실행한다.
3. 정적 파일 처리
location / {
root /app/build;
try_files $uri /index.html;
}
location / {
: 루트 경로에 대한 설정을 정의합니다.root /app/build;
: 정적 파일의 루트 디렉터리를/app/build
로 설정.try_files $uri /index.html;
: 요청된 파일이 없으면/index.html
을 반환합니다.
4. 프록시 설정
location /api/v1/ {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/v1/ {...}
:/api/v1
의 경로를 가진 요청에 대하여 작업을 수행.proxy_pass http://backend:8080;
: 포트 번호 80번으로 들어온/api/v1
요청을 8080번http://backend:8080
으로 보낸다.
: 8080번 스프링부트는http
프로토콜로/api/v1 + 나머지 url
로 요청을 받는다.
:backend
는 docker network 내부에서 통신할 때 사용되는 이름이다. (아래docker-compose.yml
참고)
:http://example.com
과 같은 url이나 특정 named group도 위치할 수 있다.proxy_pass <http://backend:8080>;
: 요청을http://backend:8080
으로 전달합니다.proxy_set_header Host $host;
: proxy 요청에 원래 호스트 헤더를 설정.proxy_set_header X-Real-IP $remote_addr;
: 클라이언트의 실제 IP를 X-Real-IP 헤더에 설정.
: 백엔드 서버가 실제 클라이언트의 IP를 알기 위함.
: 로깅, IP 제한, 지리적 위치 서비스 등에 사용.proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
: 클라이언트의 IP와 경유한 프록시 서버의 IP 목록을 전달.
: 백엔드 서버가 전체 경로를 추적할 수 있게 함.proxy_set_header X-Forwarded-Proto $scheme;
: 프로토콜을 X-Forwarded-Proto 헤더에 설정.
: 프로토콜이 http인지 https인지 알기 위함.
: 보안 분석, 트래픽 분석 등에 사용.
5. 로봇 접근 제한
# Disallow all bots
location /robots.txt {
return 200 "User-agent: *\nDisallow: /";
}
location /robots.txt {return 200 "User-agent: *\\nDisallow: /"; }
: 모든 봇의 접근을 차단.
여기서 말하는 로봇이란 웹 크롤러나 스크래퍼와 같은 자동화된 봇을 의미한다.
웹사이트를 방문하여 정보를 수집하거나 인덱싱을 수행한다.
6. Buffer 설정
예시에는 없지만 Buffer에 대한 설정도 추가할 수 있다.
기본적으로 Nginx는 프록시된 서버의 응답을 버퍼링 한다.
응답은 내부 버퍼에 저장되며 전체 응답을 받을 때까지 클라이언트로 전송되지 않는다.
버퍼링은 비교적 처리 속도가 느린 클라이언트와의 통신에서 성능 최적화에 도움이 된다.
응답이 Nginx에서 클라이언트로 동기적으로 전달될 경우 프록시된 서버(보통 WAS)가 클라이언트의 처리속도에 맞춰야 하기에 시간이 낭비될 수 있다.
버퍼링이 활성화되면 프록시된 서버는 응답을 Nginx에게 주고, NGINX는 클라이언트가 다운로드하는 데 필요한 시간 동안 응답을 저장한다.
proxy_buffering
이란 지시어로 버퍼링을 활성화 및 비활성화할 수 있다.
location /some/path/ {
proxy_buffers 16 4k;
proxy_buffer_size 2k;
proxy_pass http://localhost:8000;
}
proxy_buffers
: 요청에 할당된 버퍼의 크기와 수를 제어.proxy_buffer_size
: 프록시된 서버(WAS)에서 오는 응답의 첫 번째 부분은 별도의 버퍼에 저장된다.
: 응답의 첫 번째 부분은 보통 이후의 응답과 비교해 응답 헤더의 크기가 작아서 나머지 응답을 위한 버퍼보다 작게 설정할 수 있다.
location /some/path/ {
proxy_buffering off;
proxy_pass http://localhost:8000;
}
버퍼링이 비활성화되면 응답이 프록시된 서버로부터 수신되는 동안 클라이언트에게 동기식으로 전송된다.
가능한 한 빨리 응답을 받아야 하는 경우 사용한다.
예를 들어 빠릿빠릿하게 반응해야 하는 대화형 클라이언트에게 바람직할 수 있겠다.
이 경우 Nginx는 당장 전달할 부분만 proxy_buffer_size
크기의 버퍼에 저장한다.
7. Outgoing IP 주소 설정
예를 들어 로드 밸런싱 같은 경우, 같은 요청을 여러 곳에서 처리하고 있다.
만약 특정한 요청만 특정한 곳에서 처리하게 만들고 싶다면 proxy_bind
를 사용하면 된다.
location /app1/ {
proxy_bind 127.0.0.1;
proxy_pass <http://example.com/app1/>;
}
location /app2/ {
proxy_bind 127.0.0.2;
proxy_pass <http://example.com/app2/>;
}
/app1/
경로로 들어오는 요청은 로컬 IP127.0.0.1
을 사용하여http://example.com/app1/
로 전달./app2/
경로로 들어오는 요청은 로컬 IP127.0.0.2
을 사용하여http://example.com/app2/
로 전달.
proxy_bind
지시어로 IP 주소를 지정한다.
location /app3/ {
proxy_bind $server_addr;
proxy_pass <http://example.com/app3/>;
}
$server_addr
변수는 해당 요청을 수락하는 네트워크 인터페이스의 IP 주소를 의미한다.
이해를 돕기 위한 docker-compose.yml
:
services:
db:
image: mysql:8.4.1
volumes:
- 'mysql_data:/var/lib/mysql'
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DB}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
TZ: Asia/Seoul
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
timeout: 20s
retries: 10
expose:
- "3306"
networks:
- myNetwork
container_name: db
backend:
depends_on:
db:
condition: service_healthy
build:
context: ./backend
dockerfile: Dockerfile
image: backend
env_file: '.env'
restart: 'always'
environment:
SPRING_PROFILES_ACTIVE: ${PROFILE}
MYSQL_HOST: ${MYSQL_HOST}
MYSQL_PORT: ${MYSQL_PORT}
MYSQL_DB: ${MYSQL_DB}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
JWT_SECRET_KEY: ${JWT_SECRET_KEY}
DDL_AUTO_OPTION: ${DDL_AUTO_OPTION}
GOOGLE_CLIENT_NAME: ${GOOGLE_CLIENT_NAME}
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI}
GOOGLE_AUTHORIZATION_GRANT_TYPE: ${GOOGLE_AUTHORIZATION_GRANT_TYPE}
GOOGLE_SCOPE: ${GOOGLE_SCOPE}
LIVEKIT_API_KEY: ${LIVEKIT_API_KEY}
LIVEKIT_API_SECRET: ${LIVEKIT_API_SECRET}
REDIRECT_URI: ${REDIRECT_URI}
expose:
- "8080"
networks:
- myNetwork
container_name: backend
frontend:
depends_on:
- backend
build:
context: ./frontend
dockerfile: Dockerfile
args:
PROFILE: ${PROFILE}
image: frontend
volumes:
- "/etc/nginx/:/etc/nginx/"
restart: 'always'
ports:
- "80:80"
container_name: frontend
networks:
- myNetwork
volumes:
mysql_data:
networks:
myNetwork:
driver: bridge
'BE > Nginx' 카테고리의 다른 글
[Nginx] HTTPS 적용 (5) | 2024.08.04 |
---|---|
[Nginx] Nginx란? (0) | 2024.08.03 |