Spring Boot 앱의 정적 HTML 파일 url .html 없애기. (프론트와 백 서버 나누기)
Spring Boot 앱의 정적 HTML 파일(예: login.html)을 URL에서 .html 없이 작동하도록 설정하고 싶었습니다 (예: https://syoo.shop/login 대신 https://syoo.shop/login.html). 이를 위해 서버 사이드 렌더링을 하지 않는 이상, 정적 파일은 프론트엔드와 백엔드가 다른 서버에 있어야 원활하게 가능하다는 것을 알게 되었습니다.
- 방법:
-
- Nginx를 사용해
/var/www/html/
에서 정적 파일을 .html 없이 제공. - Spring Boot는 API (
/api/
)와 WebSocket (/websocket
)용으로 유지, Nginx가 해당 요청을 Spring Boot로 전달. - Spring Boot의
src/main/resources/static/
에 있던 모든 정적 파일(HTML, JS, CSS, 이미지)을/var/www/html/
로 이동. localStorage
를 활용한 리다이렉트를 처리하는index.html
생성.- 사용자 경험 개선을 위해 커스텀 에러 페이지 추가.
- Nginx를 사용해
선택한 방법
- 1. 모든 정적 파일을
/var/www/html/
로 이동 -
- Spring Boot의 정적 폴더에서 Nginx가 제공할 위치로 파일 이동 시작:
- 디렉토리 생성 (없을 경우):
sudo mkdir -p /var/www/html
- Spring Boot 프로젝트에서 모든 정적 파일(HTML, JS, CSS, 이미지 등) 복사:
sudo cp -r /path/to/my/spring-boot-project/src/main/resources/static/* /var/www/html/
- Nginx가 파일을 읽을 수 있도록 권한 설정:
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
- 2. Nginx 설정으로 정적 파일 제공 및 Spring Boot로 프록시
-
- Nginx 설정 파일을 편집해 프론트엔드-백엔드 분리 설정:
- 파일 열기:
sudo vim /etc/nginx/sites-available/default
- Nginx 설정 업데이트:
server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { try_files $uri $uri/ =404; } } server { server_name syoo.shop www.syoo.shop; root /var/www/html; index index.html; location =/ { try_files /index.html =404; } location / { try_files $uri $uri.html =404; } # Proxy API requests to Spring Boot location /api/ { proxy_pass http://127.0.0.1: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; proxy_intercept_errors on; # 백엔드 에러 가로채기 } location /websocket { proxy_pass http://127.0.0.1:8080; # WebSocket 서버 위치 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; } error_page 400 /400.html; error_page 401 /401.html; error_page 403 /403.html; error_page 404 /404.html; error_page 405 /405.html; error_page 500 /500.html; error_page 503 /503.html; listen 443 ssl; # Certbot 관리 listen [::]:443 ssl ipv6only=on; # Certbot 관리 ssl_certificate /etc/letsencrypt/live/syoo.shop/fullchain.pem; # Certbot 관리 ssl_certificate_key /etc/letsencrypt/live/syoo.shop/privkey.pem; # Certbot 관리 include /etc/letsencrypt/options-ssl-nginx.conf; # Certbot 관리 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Certbot 관리 } server { if ($host = www.syoo.shop) { return 301 https://$host$request_uri; } # Certbot 관리 if ($host = syoo.shop) { return 301 https://$host$request_uri; } # Certbot 관리 listen 80; listen [::]:80; server_name syoo.shop www.syoo.shop; return 404; # Certbot 관리 }
/var/www/html
디렉토리의 HTML로 에러 렌더링을 위해 다음 줄을listen 443 ssl;
전에 추가:error_page 400 /400.html; error_page 401 /401.html; error_page 403 /403.html; error_page 404 /404.html; error_page 405 /405.html; error_page 500 /500.html; error_page 503 /503.html;
location /api/
안에 추가:proxy_intercept_errors on;
- Nginx 테스트 및 재로드:
sudo nginx -t
sudo nginx -s reload
- 3. 루트 리다이렉트를 위한
index.html
설정 -
index.html
파일 내용:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Welcome to Let's Chat!</title> </head> <body> <script> // localStorage에서 userId 확인 const userId = localStorage.getItem('userId'); if (userId === null || userId === '') { // userId 없음, 로그인으로 리다이렉트 window.location.href = 'https://syoo.shop/login'; } else { // userId 있음, 채팅 목록으로 리다이렉트 window.location.href = 'https://syoo.shop/chat-list'; } </script> </body> </html>
구현 과정
-
- https://syoo.shop/login 같은 URL이 .html 없이 작동.
- 모든 정적 파일이
/var/www/html/
에서 로드됨. - https://syoo.shop/가
localStorage
를 사용해 리다이렉트. - API와 WebSocket이 Spring Boot와 연동.
- 에러가 커스텀 페이지로 표시됨.
결과 :
Posted on 2025.03.07