Spring Boot 3으로 작성한 애플리케이션을 AWS Elastic Beanstalk에 배포한 후, Nginx에서 502 Bad Gateway 오류가 발생하며 제대로 포트 포워딩이 되지 않는 상황을 겪었다. 기본적으로 Spring Boot는 8080 포트를 사용하고, Elastic Beanstalk의 Nginx는 5000 포트로 프록시하도록 설정되어 있어 이로 인해 충돌이 발생한 것으로 생각했다. 그러나 서버 포트를 수정했는데도 불구하고 계속 문제가 발생했다. 문제를 정확히 파악하기 위해 EC2 인스턴스에 직접 접근하여 상태를 확인해보기로 했다.
1. 문제 분석
애플리케이션 설정 파일(application.yml)에서 서버 포트를 5000으로 설정했음에도 불구하고 여전히 502 Bad Gateway 오류가 발생했다. 문제의 원인을 파악하기 위해 인스턴스에 직접 접속하여 설정을 확인해보기로 했다.
$ ssh -i "{pemfile}.pem" root@{address}.ap-northeast-2.compute.amazonaws.com
_____ _ _ _ ____ _ _ _
| ____| | __ ___| |_(_) ___| __ ) ___ __ _ _ __ ___| |_ __ _| | | __
| _| | |/ _ \/ __| __| |/ __| _ \ / _ \/ _\ | '_ \/ __| __/ _\ | | |/ /
| |___| | (_| \__ \ |_| | (__| |_) | __/ (_| | | | \__ \ || (_| | | <
|_____|_|\__,_|___/\__|_|\___|____/ \___|\__,_|_| |_|___/\__\__,_|_|_|\_\
Amazon Linux 2023 AMI
This EC2 instance is managed by AWS Elastic Beanstalk. Changes made via SSH
WILL BE LOST if the instance is replaced by auto-scaling. For more information
on customizing your Elastic Beanstalk environment, see our documentation here:
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
2. Nginx 설정 확인
Elastic Beanstalk의 Nginx 설정 파일을 열어 현재 포트 포워딩 설정을 확인했다.
$ cat etc/nginx/nginx.conf
#Elastic Beanstalk Nginx Configuration File
user nginx;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 200000;
events {
worker_connections 1024;
}
http {
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
include conf.d/*.conf;
map $http_upgrade $connection_upgrade {
default "upgrade";
}
server {
listen 80 default_server;
access_log /var/log/nginx/access.log main;
client_header_timeout 60;
client_body_timeout 60;
keepalive_timeout 60;
gzip off;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# Include the Elastic Beanstalk generated locations
include conf.d/elasticbeanstalk/*.conf;
}
Nginx 설정 파일의 내용을 확인해보니, Elastic Beanstalk는 /etc/nginx/conf.d/elasticbeanstalk/*.conf 경로에 위치한 설정 파일을 통해 포트 포워딩을 처리하고 있었다. 이 경로에 위치한 설정 파일(00_application.conf)을 열어 확인했다.
$ cat etc/nginx/conf.d/elasticbeanstalk/00_application.conf
따라서 해당 디렉토리를 확인해 설정파일을 확인해봤다.
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
정상적으로 5000번 포트로 프록시해주는 것을 알 수있다.
3. 포트 상태 확인
문제는 포트 상태에 있었다. netstat 명령어를 통해 현재 열려 있는 포트를 확인해본 결과, 5000 포트가 열려 있지 않았다.
$ netstat -tnlp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:22221 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
이를 통해 Spring이 제대로 실행되지 않은 것을 확인할 수 있었다.
4. 애플리케이션 수동 실행
Spring Boot 애플리케이션이 제대로 실행되지 않은 문제를 확인하기 위해 직접 수동으로 애플리케이션을 실행해보자.
$ java -jar var/app/current/application.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.3.3)
... 중략 ...
2024-10-30T23:40:53.863Z ERROR 578358 --- [shop] [ main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
2024-10-30T23:40:53.866Z WARN 578358 --- [shop] [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
2024-10-30T23:40:53.883Z INFO 578358 --- [shop] [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2024-10-30T23:40:53.930Z INFO 578358 --- [shop] [ main] .s.b.a.l.ConditionEvaluationReportLogger :
2024-10-30T23:40:53.997Z ERROR 578358 --- [shop] [ main] o.s.boot.SpringApplication : Application run failed
로그에 따르면 데이터베이스 연결 정보와 관련된 설정이 올바르게 로드되지 않아 애플리케이션이 실행에 실패한 상태였다. 특히 환경 변수를 github action에서 지정했음에도 불구하고 제대로 설정되지 않아 Hibernate가 데이터베이스 연결에 실패해서 스프링이 구동을 실패했다.
5. 느낀 점
AWS Elastic Beanstalk는 기본적으로 인프라를 자동으로 관리해주지만, 배포 오류가 발생했을 때 직접 인스턴스에 접속해 문제를 확인하는 것이 중요하다는 점을 깨달았다. 특히 애플리케이션 포트 설정과 환경 변수는 작은 차이로도 큰 문제를 일으킬 수 있으며, 이를 디버깅하기 위해 인스턴스를 직접 점검하는 과정이 필요했다.
이번 경험을 통해, 자동화된 배포 환경에서도 직접 인스턴스를 뜯어보는 디버깅의 중요성과 세밀한 설정 관리의 필요성을 다시 한번 실감할 수 있었고, 앞으로도 자동화된 인프라에서 발생할 수 있는 문제를 미리 예측하고 대비하는 자세가 필요하다는 것을 느꼈다.
'WIL > 웹 개발' 카테고리의 다른 글
WAI-ARIA: Role과 Aria-Label이란? (1) | 2024.11.19 |
---|---|
Spring 애플리케이션 배포 시 GitHub Actions 환경 변수 설정법 (1) | 2024.11.04 |
2024년 10월 1일 이후 Github Action과 AWS Beanstalk를 사용한 CI/CD (1) | 2024.10.29 |
JwtFilter는 어디에 배치해야 할까? (0) | 2024.10.19 |
Presigned URL을 사용한 파일 업로드 구현 (0) | 2024.10.15 |