이전 포스팅에서 예고했던대로 이번엔 'Railway'를 이용한 백엔드 서버 배포 과정을 포스팅할것이다.
이 과정에서 시행착오가 꽤 많았기 때문에 생각보다 시간이 오래 걸렸다.
Railway란?
Railway는 개발자들이 코드를 간편하게 배포할 수 있도록 지원하는 클라우드 플랫폼으로, 자동 배포, 다양한 서비스 관리, 사용자 친화적인 인터페이스를 제공한다.
팀 협업이 가능하고 컨테이너 기반의 인프라 사용하여 스케일링이 용이해 안정적인 앱 운영을 돕는다.
Railway
Railway is an infrastructure platform where you can provision infrastructure, develop with that infrastructure locally, and then deploy to the cloud.
railway.com
가입 방법도 여느 사이트와 크게 다르지 않다.
GitHub 계정과 연동하면 가입도 편해지고 추후 저장소를 연결해 새로운 push가 생길 때 마다 자동으로 재배포가 가능하다.
Railway CLI 사용
Railway는 기본적으로 GUI 인터페이스를 제공하고, GitHub 저장소와 연동해서 쓸 수 있기 때문에 웬만하면 CLI를 쓸 일이 없을 것이다.
하지만 나는 프로젝트 구조 상 GitHub과 연동하지 않고 서버 코드를 따로 업로드했기 때문에 CLI를 통해 코드를 업로드 했다.
# Railway 설치
npm i -g railway
# Railway 버전 확인(설치 확인)
railway --version
# 로그인
railway login
CLI를 사용하기 위해 npm으로 railway를 전역 설치해준 뒤 설치가 제대로 되었다면 로그인을 진행한다.
Railway 프로젝트 생성
방법 1. CLI 사용
# 프로젝트 생성
railway init
# → 이후 대시보드 선택 (ex. 본인 계정 ID's Projects)
# → 원하는 프로젝트 이름 입력. 공백으로 둘 시 임의의 이름으로 자동 생성
방법 2. 홈페이지 대시보드 활용
프로젝트는 railway init 명령어로 생성할 수 있고, Railway 홈페이지의 대시보드에서도 생성할 수 있다.
아무래도 후자가 직관적이고 진행 상황을 확인하기도 좋으니 특별한 이유가 있는게 아니라면 CLI로 프로젝트를 생성할 필요는 없어보이는데, 아무튼 각자가 편한 방식으로 생성하면 된다.
이제 만들어둔 new project를 클릭해 서버를 생성해야 한다.
Add a Service 버튼을 누르면 여러가지 항목이 나오는데 나는 로컬에 있는 소스코드를 그대로 올릴 예정이라 마지막 항목인 Empty Service를 선택했다.
그러면 비어있는 서비스 하나가 생성된 것을 확인할 수 있다.
Railway 프로젝트 배포하기
Empty Service 생성이 완료되면 해당 서비스에 그동안 만들어둔 서버와 관련 파일들을 업로드해야한다.
이 과정은 홈페이지에서는 불가능한것 같으니 다시 CLI로 돌아와서 서버 폴더로 경로를 옮긴 다음 그 안의 파일들을 모두 업로드(배포)해야 한다.
# 경로 먼저 지정
cd <배포할 소스파일이 있는 폴더 위치>
# Railway 프로젝트와 연동
railway link
폴더 경로를 잡은 다음엔 railway link 명령어를 입력하고 서버를 업로드하기 위한 대시보드와 프로젝트, 서비스를 차례로 선택해준다.
# Railway 서비스에 파일 업로드
railway up
이제 마지막으로 railway up 명령어를 입력하면 만들어둔 서비스에 파일이 올라가게 되며, 홈페이지의 대시보드에서도 배포중임을 확인할 수 있다.
배포가 완료되면 대시보드에서 해당 서비스를 클릭하고 배포 상태를 확인할 수 있다.
ACTIVE 상태일 경우 서비스가 정상적으로 작동하는 상태이며, 만약 소스코드에 오류가 있거나 다른 문제가 있을 경우 Fail 메시지와 함께 로그 확인이 가능하다.
Public 도메인 생성
서비스가 배포되었다면 이제 외부에서 접근 가능한 도메인을 생성해야 한다.
Vercel에서 배포한 리액트 앱과 통신하며 api를 제공할 서버이기 때문에 외부에서 접근 가능한 상태로 만들어주어야 한다.
Settings 메뉴에서 Networking 설정으로 이동해 Public Networking 아래 Generate Domain 버튼을 클릭해주면 도메인이 하나 생성된다.
이제 클라이언트의 proxy 설정에서 api 요청 경로를 이 도메인으로 맵핑해주면 된다.
환경변수 추가
마지막으로 서버에서 사용할 환경변수를 추가해주어야 한다.
로컬에서는 .env 파일을 통해 환경변수를 참조했지만, 해당 파일은 웹에 업로드하지 않기 때문에 배포된 서버가 참조할 수 있도록 추가로 입력해주어야 한다.
업로드한 소스코드에서 참조할 수 있도록 .env 파일에서 사용했던 변수명을 똑같이 사용하면 된다.
소스코드 수정 반영
# 수정사항 반영
railway up
로컬에서 소스코드를 수정했다면 다시 CLI에 railway up 명령어를 입력해 재배포하면 된다.
비하인드
비하인드의 내용은 주의사항 정도라고 이해하면 좋을것 같다.
지금 생각해보면 좀 부끄러운 얘기지만 처음 프로젝트 폴더 구조를 짰을 때 클라이언트(FE) 폴더와 서버(BE) 폴더를 분리하지 않고 작업을 해왔다. (즉, FE 폴더 안에 서버 폴더를 구축하는 만행을 저질렀다.)
'어차피 React와 Node.js 둘 다 JS 기반이니까 괜히 node 모듈을 여러군데 나누지 말고 한꺼번에 쓰자!' 라는 생각과 '프론트엔드 포트폴리오니까 서버 위치가 얼마나 중요하겠어?' 라는 안일한 결정이 화를 부른 것이다.
처음엔 원래 GitHub 저장소와 연동하고 환경변수 정도만 수정할 생각으로 서비스를 배포했는데 게시판 페이지에서 계속 에러가 났다.
클라이언트에서 api를 호출하면 계속 index.html이 반환되었다.
로컬 작업 중에는 전혀 경험하지 못한 에러다보니 이게 무슨 상황인가 싶어 이것저것 검색해봤지만 확실한 답을 찾지 못하고 하루를 다 보내버리고 나서야 원인을 찾았다.
문제는 생각보다 간단했는데 프론트엔드 코드와 백엔드 코드가 같은 포트에서 작동하다보니 리액트 라우터와 api 요청 경로의 충돌이 일어난 것이다.
axios에서 요청한 api 주소가 클라이언트 페이지 url로 인식되어 계속 index.html이 반환되는 상황이었다.
로컬에선 클라이언트와 서버가 각자 다른 포트에서 실행됐기 때문에 문제가 없었지만, Railway 배포 후에는 한 포트에서 동시에 실행되다보니 이런 상황이 벌어졌다.
처음엔 문제를 해결하기 위해 서버 코드를 수정해 api 요청 경로에 따른 예외처리도 해보았지만, 결국 근본적으로 클라이언트와 서버가 분리되지 않으면 서로 요청을 보내고 받는 것 자체가 불가능하다 판단했다. (방법이 있을 수도 있으나 본인은 찾지 못했다. 😥)
그래서 지금처럼 서버만 Railway에서 배포하고, Vercel에 배포된 리액트 앱에서 Railway의 서버에 api를 요청하도록 했다.
DB 생성과 관련해서도 시행착오가 좀 있었는데 이는 다음 포스팅에서 다뤄보려 한다.
https://duski96.tistory.com/24
[MySQL] Railway에서 DB 생성하기
백엔드 서버 패포용으로 Railway를 선택한 이유 중 하나는 MySQL DB를 지원하기 때문이다.원래는 로컬에서 직접 만든 DB와 똑같은 속성을 갖도록 만들고 싶었는데 아무래도 무료 서비스라 그런지 기
duski96.tistory.com
'Node.js' 카테고리의 다른 글
[Node.js] DB에 입력 값 추가하기 (0) | 2025.03.06 |
---|---|
[Node.js] Promise.all() 매서드 사용하기 (0) | 2025.03.06 |
[Node.js] 로그인 api 만들기 + JWT 활용 (0) | 2025.03.04 |
[Node.js] React에 MySQL 연동을 위한 Server 생성 (0) | 2025.02.28 |