1. 개요
| 항목 | 내용 |
|---|---|
| 발생일 | 2026-06-18 |
| 환경 | AWS App/WAS EC2, HAProxy, MariaDB Galera |
| 대상 서비스 | tripkey-app EC2의 was 컨테이너 |
| 영향 | WAS 컨테이너가 DB 연결에 실패하여 정상 기동하지 못함 |
| 원인 | DB 비밀번호에 포함된 / 문자가 DB 접속 URL에서 경로 구분자로 해석됨 |
| 조치 | DB 비밀번호를 URL 인코딩하여 WRITE_DATABASE_URL, READ_DATABASE_URL에 반영 |
AWS 배포 검증 중 was 컨테이너가 unhealthy 또는 restarting 상태가 되었다.
초기에는 컨테이너 이미지, DB 포트, Security Group, HAProxy 리스닝 포트 문제를 의심했지만, 최종 원인은 DB 접속 문자열에 포함된 비밀번호 특수문자였다.
DB 비밀번호에 포함된 / 문자가 URL 문법에서 경로 구분자로 해석되면서, 애플리케이션이 DB 접속 URL을 정상적으로 파싱하지 못한 것으로 판단했다.
2. 당시 구조
WAS는 SQLAlchemy/asyncmy 형식의 DB 접속 URL을 환경 변수로 전달받는다.
3. 증상
App/WAS EC2에서 Docker Compose 배포 후 was 컨테이너가 정상 상태가 되지 않았다.
확인된 상태는 다음과 같다.
우선 확인해야 하는 로그는 was 컨테이너 로그다.
현재 저장소와 당시 Codex 세션 기록 기준으로는 정확한 WAS 에러 로그 또는 스크린샷은 확인되지 않았다.
다만 당시 대화 기록에 다음 내용이 남아 있었다.
이를 근거로 DB 접속 URL의 비밀번호 파싱 문제를 의심했다.
4. 원인
DB 비밀번호에 /가 포함된 상태에서 해당 값을 DB 접속 URL에 그대로 삽입했다.
예를 들어 비밀번호가 다음과 같다고 가정한다.
이를 인코딩하지 않고 DB URL에 넣으면 다음과 같은 형태가 된다.
URL 문법에서 /는 경로를 구분하는 예약 문자다.
따라서 URL 파서는 abc/def 전체를 비밀번호로 해석하지 못하고, /def@10.250.150.192:3306/integrated 이후 구간을 경로처럼 처리할 수 있다.
결과적으로 애플리케이션은 실제 DB 계정 비밀번호와 다른 값으로 접속을 시도하게 되고, DB 인증 또는 연결 실패가 발생한다.
5. 조치
비밀번호에 포함된 / 문자를 URL 인코딩했다.
예시:
수동으로 URL 인코딩 값을 확인할 때는 다음 명령을 사용할 수 있다.
출력:
.env 또는 User Data 생성 결과에 URL 인코딩된 값이 반영되었는지 확인한 뒤, WAS 컨테이너를 재기동한다.
정상 기준은 다음과 같다.
WAS EC2 내부에서 API 응답을 확인한다.
Web EC2의 Reverse Proxy를 거친 요청까지 확인하려면 다음 명령을 사용한다.
6. 재발 방지
현재 AWS App/WAS EC2 User Data는 SSM Parameter Store에서 DB 계정 정보를 가져온 뒤, URL 인코딩을 수행하여 DB 접속 URL을 생성한다.
이후 인코딩된 값을 사용해 접속 URL을 생성한다.
운영 배포에서는 다음 원칙을 적용한다.
DATABASE_URL에 들어가는 username, password, database name은 URL 인코딩한다.- DB 비밀번호에
/,@,:,#,?,&,%같은 URL 예약 문자가 포함될 수 있다고 가정한다. .env에 평문 비밀번호와 DB URL을 함께 둘 경우, 실제 애플리케이션이 어떤 환경 변수를 읽는지 확인한다.- SSM Parameter Store에는 원본 값을 저장하고, URL 조립 시점에만 인코딩한다.
- 배포 직후
docker compose ps,docker compose logs was, 실제 API 요청을 함께 확인한다. - 문서, 로그, 스크린샷에는 실제 비밀번호를 남기지 않는다.
7. 트러블슈팅 흐름
8. 검증 명령어 예시
8.1 컨테이너 상태 확인
8.2 WAS 로그 확인
8.3 DB URL 환경 변수 확인
실제 비밀번호가 노출되지 않도록 운영 환경에서는 출력 범위에 주의한다.
필요하면 비밀번호 영역은 마스킹해서 확인한다.
8.4 URL 인코딩 확인
8.5 WAS 재기동
8.6 API 응답 확인
9. 근거
당시 Codex 세션 기록에서 사용자가 다음 내용을 언급했다.
이후 / 문자를 %2F로 URL 인코딩해야 한다고 판단했고, 해당 판단은 현재 저장소의 AWS App/WAS EC2 User Data에 반영되어 있다.
관련 파일 및 구현 요소는 다음과 같다.
10. 결론
이번 장애는 DB 서버, HAProxy, Security Group, 컨테이너 이미지 문제가 아니라 DB 접속 URL에 포함된 비밀번호 특수문자 처리 문제였다.
DB 접속 URL처럼 URI 형식을 사용하는 설정에서는 username, password, database name에 URL 예약 문자가 포함될 수 있으므로, URL 조립 전에 반드시 인코딩해야 한다.
만약 App/WAS EC2 User Data에서 SSM Parameter Store 값을 가져온 뒤 URL 인코딩하여 WRITE_DATABASE_URL, READ_DATABASE_URL을 생성하도록 수정한다면, 동일 유형의 문제는 재발 가능성이 낮아질 것으로 판단된다.