이번 글은 CICD 배포의 마지막으로 Nginx와 EC2 설정에 대해 알아보겠다.
Amazon EC2 인스턴스에 Nginx를 설치하고 설정하는 과정과 함께,
서버 로그를 확인하는 방법에 대해 자세히 다뤄보려 한다.
Nginx
Nginx는 비동기 이벤트 기반 구조를 가진 고성능 웹 서버이다.
단순히 클라이언트 요청을 처리하는 정적 서버의 역할뿐 아니라,
리버스 프록시, 로드 밸런서, SSL 암호화 처리기, 정적 파일 서버로서의 기능을 수행한다.
이번 프로젝트에서는 Spring Boot API 서버와 React 프론트엔드 정적 파일을 분리 배포하고, 이 둘을 도메인 하나(api.gasdg.store) 아래에서 통합 처리하기 위해 Nginx를 사용했다.
왜 리버스 프록시구조 사용?
Nginx는 백엔드(Spring 서버) 앞단에 위치해,
모든 HTTP 요청을 대신 수신하고 필요한 서버에 전달하는 리버스 프록시 구조로 동작한다.
1. 보안 강화
- 클라이언트는 Nginx에만 접근하고, Spring 서버는 외부에 노출되지 않는다.
- 이를 통해 직접적인 공격을 방지할 수 있고, IP 주소나 포트 정보도 외부에 공개되지 않는다.
- 예시: 사용자는 https://api.gasdg.store 로 요청하지만, 내부에서는 http://localhost:8080 으로 API 요청이 전달된다.
2. HTTPS(SSL/TLS) 인증서 적용
- Nginx는 SSL 인증서를 중앙에서 관리하고, 모든 트래픽을 HTTPS(SSL/TLS)로 암호화하여 전송할 수 있다.
- 이는 민감한 정보(예: 로그인 정보, 토큰 등)를 네트워크 상에서 도청당하지 않도록 보호한다.
3. 정적 리소스 서빙
- React로 빌드된 프론트엔드 정적 파일은 /var/www/html에 배포하고, Nginx가 이를 클라이언트에 서빙한다.
- 이로써 Spring 서버는 API 처리에만 집중할 수 있게 된다.
뿐만 아니라 로드 밸런싱 기능도 있는데 프로젝트에 적용하지는 않았지만 다음과 같은 역할을 한다.
- Nginx는 여러 개의 백엔드(서버)에 트래픽을 분산할 수 있다.
- 이를 통해 부하 분산, 고가용성, 무중단 배포 등을 지원한다.
HTTP가 아닌 HTTPS를 사용하는 이유
HTTP는 데이터를 암호화하지 않고 전송한다.
즉, 사용자 인증 정보나 토큰, 개인정보 등 모든 데이터가 평문(Plain Text) 상태로 전달된다.
이로 인해 중간자 공격(Man-in-the-Middle), 도청 등의 보안 위협에 매우 취약하다.
반면, HTTPS(Hypertext Transfer Protocol Secure)는 SSL/TLS 프로토콜을 기반으로 데이터를 암호화한다.
데이터가 클라이언트와 서버 사이에서 암호화된 형태로 전송되므로 도청, 위변조, 피싱 위험으로부터 안전하다.
HTTPS는 보안뿐 아니라 SEO와 사용자 신뢰도 측면에서도 필수가 되었다.
SSL/TLS는 어떻게 암호화를 수행하는가?
SSL/TLS는 크게 두 가지 방식을 결합하여 암호화를 수행한다.
- 비대칭키 암호화 (공개키/개인키): 최초 연결 시 클라이언트가 서버의 공개키를 이용해 데이터를 암호화하면, 서버는 자신의 개인키로 이를 복호화한다. 이를 통해 안전한 세션키를 공유한다.
- 대칭키 암호화: 이후 데이터 전송은 속도 때문에 대칭키 방식으로 수행되며, 양측이 공유한 세션키로 데이터를 암호화/복호화한다.
👉 Let's Encrypt 인증서 기반 SSL 설정을 통해 이 암호화 통신을 손쉽게 적용할 수 있다.
Let's Encrypt와 Certbot으로 SSL 인증서 발급 및 적용
이번 프로젝트에서는 무료로 SSL 인증서를 발급해주는 Let's Encrypt와, 이를 간단히 설정할 수 있도록 도와주는 Certbot을 이용해 SSL을 구성하였다.
1. Cerbot 설치
sudo apt install -y certbot python3-certbot-nginx
2. 인증서 발급
sudo certbot --nginx -d gasdg.store -d www.gasdg.store -d api.gasdg.store
- --nginx: Nginx 설정 파일을 자동으로 읽고 SSL 설정을 삽입한다.
- -d: 인증서를 적용할 도메인을 명시한다.
3. 인증서 자동 갱신 설정
Let's Encrypt 인증서는 90일 유효 기간을 갖기 때문에 자동 갱신이 필요하다. 다음 명령어로 자동 갱신을 등록하였다.
echo "0 0 1 * * certbot renew --quiet" | sudo tee -a /etc/crontab
Nginx 설치 및 설정 파일 작성
Nginx 서비스 시작 및 부팅 시 자동 실행 설정하는 코드이다.
sudo systemctl start nginx
sudo systemctl enable nginx
그리고 Nginx 설정 파일 수정 하여
sudo nano /etc/nginx/sites-available/default
아래와 같이 설정해 HTTP요청을 HTTPS로 리다이렉트하고 SSL을 적용한다.
server {
listen 80;
server_name gasdg.store www.gasdg.store;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name gasdg.store www.gasdg.store;
ssl_certificate /etc/letsencrypt/live/gasdg.store/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gasdg.store/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://localhost: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;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
- 80번 포트 요청은 HTTPS(443번) 로 리다이렉트된다.
- SSL 인증서 경로는 Certbot에서 자동으로 설정한 Let’s Encrypt 인증서를 참조한다.
- proxy_pass는 클라이언트 요청을 로컬 8080 포트(Spring 서버)로 전달한다.
EC2 서버 로그 및 동작 확인 방법
1. 서버 로그 확인
tail -f output.log
Spring Boot 서버에서 출력되는 로그를 실시간으로 모니터링한다.
2. 실행 중인 서버 확인
ps aux | grep java
sudo lsof -i :8080
현재 Java 프로세스가 실행 중인지, 8080 포트에서 서버가 동작 중인지 확인한다.
3. API 응답 테스트 (백엔드)
curl https://api.gasdg.store/api/health-check
4. 프론트엔드 연결 테스트
curl -I https://gasdg.store
마무리
Nginx는 단순 웹 서버 그 이상이다. 이번 프로젝트에서는 리버스 프록시, 정적 파일 서빙, SSL 인증서 관리, API 라우팅이라는 역할을 모두 수행하며 EC2 기반의 배포 아키텍처를 단순하고 효율적으로 만들어주었다.
특히 Let's Encrypt + Certbot 조합을 사용하면 비용 없이 HTTPS 보안 환경을 구축할 수 있어 실무나 개인 프로젝트 모두에서 유용하게 활용 가능하다.
지금까지 CI/CD, AWS, Nginx, SSL 구성까지 전반적인 백엔드 배포의 기초를 다져보았다.
'프로젝트 > 기업 일정 관리 웹' 카테고리의 다른 글
GitHub Actions EC2 배포 실패: SSH 키 인증 실패 문제 해결 (0) | 2025.04.09 |
---|---|
CICD 2 - 가비아 도메인 + Route 53 + EC2 + RDS (0) | 2025.04.05 |
CI/CD 1 : GithubActions (0) | 2025.04.03 |
REST API 에서 Enum 직렬화 문제 (0) | 2025.04.02 |
Redis 적용하기 (0) | 2025.04.02 |