1. Railway 배포 후 서버가 Online 상태에서 Crashed 되는 문제
처음 Railway에 Spring Boot 애플리케이션을 배포했을 때 잠시 Online 상태가 되었지만 이후 Crashed 상태로 변경되는 문제가 발생했다.
로컬에서는 Docker로 실행한 MySQL을 사용하고 있었기 때문에, 배포 환경에서도 로컬 DB 설정을 그대로 사용할 수 없었다.
기존 로컬 환경에서는 다음과 같이 localhost의 MySQL을 사용하고 있었다.
spring:
datasource:
url: jdbc:mysql://localhost:3306/gamelog
하지만 Railway에서 실행되는 애플리케이션의 localhost는 로컬 컴퓨터의 MySQL을 의미하지 않는다.
따라서 Railway 프로젝트에 MySQL을 별도의 서비스로 추가하고, 배포 환경에서는 Railway MySQL을 사용하도록 구성했다.
2. 환경별 DB 설정을 위해 prod 프로파일 추가
기존 application.yaml에는 local과 test 프로파일만 존재했다.
local → Docker MySQL
test → H2
Railway 배포를 진행하면서 배포 환경과 로컬 환경의 DB 설정을 분리하기 위해 prod 프로파일을 새로 추가했다.
최종적으로 다음과 같이 환경을 분리했다.
local → Docker MySQL
test → H2
prod → Railway MySQL
Railway MySQL 연결
먼저 Railway 프로젝트에 MySQL 서비스를 추가했다.
MySQL 서비스를 추가하면 Railway의 Variables에 MySQL 접속에 필요한 환경 변수들이 생성된다.
예를 들어:
MYSQLHOST
MYSQLPORT
MYSQLDATABASE
MYSQLUSER
MYSQLPASSWORD
이 변수들을 application.yaml의 prod 프로파일에서 사용하도록 설정했다.
---
# ===== 배포 (Railway) =====
spring:
config:
activate:
on-profile: prod
datasource:
url: jdbc:mysql://${MYSQLHOST}:${MYSQLPORT}/${MYSQLDATABASE}
username: ${MYSQLUSER}
password: ${MYSQLPASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
이렇게 하면 DB 접속 정보를 코드에 직접 작성하지 않고 Railway가 제공하는 환경 변수를 통해 DB에 연결할 수 있다.
3.. ddl-auto 설정 문제
처음 Railway에 배포할 때 prod 환경의 ddl-auto를 validate로 설정했다.
spring:
jpa:
hibernate:
ddl-auto: validate
하지만 당시 Railway MySQL DB가 비어 있는 상태였기 때문에 테이블이 존재하지 않았고, validate는 테이블을 생성하지 않고 스키마가 엔티티와 일치하는지만 검사하기 때문에 애플리케이션이 정상적으로 실행되지 않았다.
이를 해결하기 위해 처음에는 validate를 update로 변경했다.
이 상태로 애플리케이션을 실행하여 Spring Boot가 엔티티를 기반으로 Railway DB에 필요한 테이블을 생성하도록 했다.
테이블이 정상적으로 생성된 것을 확인한 후에는 다시 validate로 변경했다.
최종적으로 배포 환경에서는 Hibernate가 DB 구조를 임의로 변경하지 않고, 현재 DB 스키마가 엔티티 구조와 일치하는지만 검증하도록 validate를 사용했다.
4. Railway에서 prod 프로파일을 사용하도록 설정
application.yaml의 기본 프로파일은 로컬 개발을 위해:
spring:
profiles:
active: local
로 설정되어 있다.
따라서 로컬에서 별도의 설정 없이 실행하면 local 프로파일이 사용된다.
Railway에서는 Variables에:
SPRING_PROFILES_ACTIVE=prod
를 추가하여 배포 환경에서 prod 프로파일을 사용하도록 설정했다.
결과적으로:
로컬 실행
→ local
→ Docker MySQL
Railway 실행
→ prod
→ Railway MySQL
로 실행 환경에 따라 DB 연결이 달라지도록 구성했다.
5. JWT Secret을 환경 변수로 분리
JWT Secret은 배포 환경에서 코드에 직접 작성하지 않고 환경 변수로 관리하도록 변경했다.
prod 프로파일에서는:
jwt:
secret: ${JWT_SECRET}
으로 설정하고, Railway Variables에 JWT_SECRET을 등록했다.
이를 통해 GitHub에 올라가는 코드에 실제 JWT Secret이 포함되지 않도록 했다.
6. IntelliJ의 IGDB import 설정과 Railway 배포 환경의 차이
로컬에서 IGDB 데이터를 import할 때 IntelliJ의 Program Arguments를 사용해 실행 옵션을 전달했었다.
하지만 IntelliJ의 Program Arguments는 IntelliJ에서 로컬로 실행할 때만 적용되는 설정이기 때문에 Railway 배포 환경에는 자동으로 적용되지 않는다.
또한 이미 로컬 DB에 IGDB 데이터를 충분히 저장해 둔 상태였기 때문에 Railway에서 대량의 데이터를 다시 import하는 대신, 기존 데이터를 Railway MySQL로 이전하는 방법을 선택했다.
7. 로컬 MySQL의 IGDB 데이터를 Railway MySQL로 이전
로컬 DB에 이미 저장되어 있던 IGDB 데이터를 DBeaver를 이용해 SQL 파일로 export한 뒤 Railway MySQL에 import했다.
export한 테이블은 다음과 같다.
genres
platforms
game_series
games
game_genres
game_platforms
game_series_games
ERD의 FK 관계를 기준으로 부모 테이블을 먼저 넣어야 했기 때문에 다음 순서로 데이터를 삽입했다.
1. genres
2. platforms
3. game_series
4. games
5. game_genres
6. game_platforms
7. game_series_games
'회고 > GameLog 프로젝트' 카테고리의 다른 글
| 2차 프로젝트: GameLog - 프로필 기능 개선 (0) | 2026.09.23 |
|---|---|
| 2차 프로젝트: GameLog - 프로필 탭 API 구현 (0) | 2026.09.21 |
| 2차 프로젝트: GameLog 3일차 - 403 오류 (0) | 2026.09.16 |
| 2차 프로젝트: GameLog 2일차 (0) | 2026.09.15 |
| 2차 프로젝트: GameLog 1일차 (0) | 2026.09.14 |
댓글