IT 기술/기타

[NGINX] SPA 배포 간 문제

to,min 2024. 10. 18. 10:46

 

Docker로 React를 Nginx 와 함께 배포하였는데, 도커로 배포한 환경에서만 타 페이지로 redirect가 되지 않는 문제가 발생했다.

 

당시 frontend Dockerfile은 아래와 같았다.

 

# 1단계: Node.js를 사용하여 빌드
FROM node:16-alpine as build

# 환경 변수 설정 (default는 dev)
ARG NODE_ENV=dev
ENV NODE_ENV=$NODE_ENV
ARG REACT_APP_API_BASE_URL
ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL

# 작업 디렉토리 설정
WORKDIR /usr/src/app

# 종속성 설치
COPY package*.json ./
RUN npm install

# 애플리케이션 빌드
COPY . ./
RUN npm run build:${NODE_ENV}

# 2단계: NGINX를 사용하여 빌드된 애플리케이션 제공
FROM nginx:alpine

# 빌드된 파일을 NGINX HTML 디렉토리로 복사
COPY --from=build /usr/src/app/build /usr/share/nginx/html

# 포트 노출
EXPOSE 80

# NGINX 실행 명령
CMD ["nginx", "-g", "daemon off;"]

 

 

별날 것 없다고 생각했는데 react는 SPA 로 동작하다 보니, 여러 호출url 을 index.html 한곳 에서 모두 수신하여 필요한 부분을 클라이언트 측에서 랜더링 하는 구조인데, Nginx 로 연동하다 보니 다른 호출 Url 을 index.html 로 리다이렉팅 하지 않아 나오는 문제였다.

 

그래서 nginx.conf 를 생성하여 다른 호출 url 을 index.html 로 연결하도록 설정하여 해결했다.

(아래 코드는 다른 설정 확인차 굳이 docker-entrypoint.sh 로 나눈것이고 그냥 해당 파일 없이 Dockerfile 내에서 CMD로 nginx 실행해도 된다)

 

Dockerfile

# 1단계: Node.js를 사용하여 빌드
FROM node:16-alpine as build

# 환경 변수 설정 (default는 dev)
ARG NODE_ENV=dev
ENV NODE_ENV=$NODE_ENV
ARG REACT_APP_API_BASE_URL
ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL

# 작업 디렉토리 설정
WORKDIR /usr/src/app

# 종속성 설치
COPY package*.json ./
RUN npm install

# 애플리케이션 빌드
COPY . ./
RUN npm run build:${NODE_ENV}

# 2단계: NGINX를 사용하여 빌드된 애플리케이션 제공
FROM nginx:alpine

# 빌드된 파일을 NGINX HTML 디렉토리로 복사
COPY --from=build /usr/src/app/build /usr/share/nginx/html

# Nginx 설정 파일 템플릿 복사
COPY nginx.conf.template /etc/nginx/templates/nginx.conf.template

# 엔트리포인트 스크립트 복사
COPY docker-entrypoint.sh /usr/bin/docker-entrypoint.sh
RUN chmod +x /usr/bin/docker-entrypoint.sh

# 포트 노출
EXPOSE 80

# Nginx 실행 명령 (EntryPoint에서 실행)
CMD ["/usr/bin/docker-entrypoint.sh"]

 

nginx.conf.template

server {
    listen 80;

    root /usr/share/nginx/html;
    index index.html index.htm;

    # 모든 요청을 index.html로 리다이렉트
    location / {
        try_files $uri /index.html;
    }

    # API 요청을 환경 변수로 설정된 백엔드 서버로 프록시
    # location /api/ {
    #     proxy_pass http://${REACT_APP_API_BASE_URL};  # 환경 변수로 설정된 백엔드 주소
    #     # proxy_pass http://localhost;  # 환경 변수로 설정된 백엔드 주소
    #     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;
    # }
}

 

docker-entrypoint.sh

#!/bin/sh

# 환경 변수를 사용하여 Nginx 설정 파일 생성
# envsubst '$REACT_APP_API_BASE_URL' < /etc/nginx/templates/nginx.conf.template > /etc/nginx/conf.d/default.conf

# Nginx 시작
exec nginx -g 'daemon off;'