개발 노트

Railway Spring Boot PORT 설정 — server.port=${PORT:8080}를 쓴 이유

nocklock 2026. 9. 30. 08:30

PORT 설정

 

Spring Boot 프로젝트를 로컬에서 실행할 때는 포트에 대해 크게 생각해본 적이 없었다.

보통은 그냥 실행하고,

http://localhost:8080
 

으로 접속하면 됐다.

그런데 Security Lens를 Railway에 배포하면서 application.properties에 이런 설정을 넣었다.

 
server.port=${PORT:8080}
 

처음에는 그냥 배포할 때 필요한 설정 정도로 생각했다.

그런데 Docker의 8081:8080 포트 매핑을 다시 공부하고 Railway 배포까지 해보면서 이 한 줄이 무슨 의미인지 조금 더 명확하게 보이기 시작했다.

로컬에서는 왜 그냥 8080이었을까

Spring Boot의 기본 HTTP 포트는 8080이다.

그래서 별도로 설정하지 않아도 로컬에서는 보통

localhost:8080
 

으로 애플리케이션에 접근할 수 있다.

물론 이미 다른 프로그램이 8080 포트를 사용하고 있다면 이야기가 달라진다.

나도 개발하면서 8080 포트 충돌을 따로 확인하게 됐고, 이건 별도의 글로 정리했다.

관련 글
Spring Boot 8080 포트 충돌 해결 — Port 8080 was already in use 오류


그런데 Railway에서는 포트를 내가 정하는 게 아니었다

로컬 환경과 Railway 같은 배포 환경의 차이가 여기서 나온다.

Railway는 애플리케이션이 실행될 때 PORT라는 환경변수를 제공한다.

그리고 웹 애플리케이션은 Railway가 전달한 그 포트에서 요청을 받을 수 있어야 한다.

Railway 공식 문서에서도 애플리케이션이 플랫폼에서 주입한 PORT 환경변수를 사용하도록 안내하고 있다.

즉 로컬에서처럼 무조건

server.port=8080
 

으로 고정해서 생각하는 것보다 배포 환경에서 전달되는 값을 받아서 사용하는 편이 자연스럽다.

그래서 사용한 설정이 이거였다.

server.port=${PORT:8080}
 

Railway 공식 Healthchecks / PORT 환경변수
Railway Healthchecks 문서


Railway Application Failed to Respond 문서


${PORT:8080}는 무슨 뜻일까

처음 보면 문법이 조금 이상해 보인다.

하나씩 보면 어렵지 않다.

${PORT:8080}
 

여기에서

PORT
 

는 환경변수 이름이고,

8080
 

은 PORT 값이 없을 때 사용할 기본값이다.

그래서 결과적으로는 이렇게 동작한다.

Railway
PORT 환경변수가 있음
↓
Railway가 전달한 PORT 사용


로컬 개발환경
PORT 환경변수가 없음
↓
8080 사용
 

같은 코드인데 실행되는 환경에 따라 포트를 다르게 사용할 수 있다.

이게 내가 이 설정을 그대로 두는 이유다.


로컬에서는 8080, Railway에서는 PORT

예를 들어 Railway가 실행 환경에서 다음 값을 제공했다고 해보자.

PORT=12345
 

그러면

 
server.port=${PORT:8080}
 

은 실행 시 사실상

 
server.port=12345
 

처럼 동작한다.

반대로 내 PC에서 실행했는데 PORT라는 환경변수가 없다면 기본값인

 
server.port=8080
 

을 사용한다.

그래서 굳이 개발용 설정과 Railway용 설정을 따로 바꿔가며 사용할 필요가 없다.

로컬
→ localhost:8080

Railway
→ Railway가 지정한 PORT
 

이 구조다.


Docker 포트와 헷갈렸던 이유

이 부분을 이해하면서 얼마 전에 정리했던 Docker 포트도 다시 생각났다.

Docker에서는 이런 형태를 사용했다.

 
docker run -p 8081:8080 my-spring-app
 

여기서 의미는

내 컴퓨터 8081
        ↓
컨테이너 8080
 

이었다.

반면 Railway의 PORT는 조금 다르다.

Railway
        ↓
PORT 환경변수 전달
        ↓
Spring Boot
        ↓
해당 PORT에서 서버 실행
 

Docker의 8081:8080이 외부와 컨테이너 사이의 포트 연결을 이야기한다면,

 
server.port=${PORT:8080}
 

은 Spring Boot 자체가 어느 포트에서 실행될지를 정하는 설정이다.

둘 다 포트 이야기라 처음에는 비슷해 보였는데 실제 역할은 다르다.

관련 글
Docker localhost 연결 안 될 때 — 8081:8080 포트 매핑부터 확인했다


빌드가 성공했다고 접속까지 되는 건 아니다

Railway에서 코드를 빌드하는 것과 실제 애플리케이션이 요청을 받을 수 있는 것은 별개의 문제다.

코드가 정상적으로 빌드됐더라도 애플리케이션이 Railway가 기대하는 포트에서 실행되고 있지 않다면 외부 요청을 정상적으로 받을 수 없다.

Railway의 공식 트러블슈팅 문서에서도 애플리케이션이 PORT 환경변수에 지정된 포트를 사용하지 않는 경우 서비스가 응답하지 않을 수 있다고 안내한다.

그래서 배포 로그만 보고

Build 성공했네. 끝.

 

이라고 보기보다 실제 애플리케이션이 어느 포트에서 실행되고 있는지도 같이 보는 게 좋다.


결국 이 한 줄이었다

Security Lens를 Railway에 올리면서 사용한 설정은 아주 짧았다.

 
server.port=${PORT:8080}
 

그런데 이 한 줄 안에 로컬과 배포 환경의 차이가 들어 있었다.

예전에는 그냥

Railway 배포하려면 이렇게 써야 하나 보다.

정도로 생각했다.

지금은 이렇게 이해한다.

PORT가 있으면
→ 배포 환경이 준 포트를 사용

PORT가 없으면
→ 내가 익숙한 8080 사용
 

결국 중요한 건 8080이라는 숫자를 외우는 게 아니라 애플리케이션이 실행되는 환경에서 포트를 누가 결정하는지 이해하는 것이었다.

Docker의 8081:8080도 그랬고 Railway의 PORT도 비슷했다.

포트는 계속 숫자로 보이는데, 어느 쪽의 포트인지 알기 시작하니 조금 덜 헷갈린다.