개발 노트

Spring Boot 환경변수 설정 — application.properties에 API Key를 직접 넣으면 안 되는 이유

nocklock 2026. 10. 2. 08:20

Spring Boot 프로젝트를 만들다 보면 처음에는 설정값을 application.properties에 그냥 적게 된다.

나도 로컬에서 개발할 때는 이런 방식이 가장 간단해 보였다.

openai.api.key=sk-xxxxxxxxxxxxxxxx

 

실행도 잘 되고 코드에서 값을 가져오는 것도 어렵지 않다.

문제는 프로젝트를 GitHub에 올리거나 실제 서버에 배포하기 시작할 때 생긴다.

로컬에서만 사용하던 설정 파일이 더 이상 단순한 설정 파일이 아니게 된다.

API Key, DB 비밀번호 같은 민감한 정보가 같이 들어 있기 때문이다.

이번에 Spring Boot 프로젝트를 배포하면서 이 부분을 다시 정리해봤다.

application.properties에 API Key를 직접 넣으면 왜 문제일까?

가장 큰 이유는 단순하다.

소스코드와 비밀정보가 같이 움직이게 되기 때문이다.

예를 들어 이런 설정이 있다고 해보자.

openai.api.key=sk-xxxxxxxxxxxxxxxx

 

이 상태로 프로젝트를 GitHub에 push하면 API Key 역시 Git 기록에 남을 수 있다.

나중에 해당 줄을 삭제하더라도 이미 이전 commit에 값이 포함되어 있다면 문제가 끝난 것이 아니다.

API Key는 코드와 달리 공개되어서는 안 되는 값이다.

비밀번호, DB 접속정보, 외부 서비스 토큰도 마찬가지다.

그래서 실제 배포 환경에서는 이런 값을 코드와 분리하는 것이 좋다.

Spring Boot에서는 환경변수를 사용할 수 있다

내가 사용한 방식은 application.properties에는 실제 값을 넣지 않고 환경변수 이름만 지정하는 것이다.

openai.api.key=${OPENAI_API_KEY}

 

그리고 Java 코드에서는 기존처럼 해당 설정값을 사용한다.

예를 들어:

@Value("${openai.api.key}")
private String apiKey;

 

Spring Boot가 실행될 때 OPENAI_API_KEY라는 환경변수를 찾아 실제 값을 넣어준다.

즉 구조가 이렇게 바뀐다.

application.properties
        ↓
${OPENAI_API_KEY}
        ↓
운영체제 또는 배포 플랫폼의 환경변수
        ↓
실제 API Key

 

소스코드에는 API Key 자체가 존재하지 않는다.

로컬에서는 어떻게 설정할까?

Windows라면 환경변수를 운영체제에 등록해서 사용할 수 있다.

PowerShell에서 현재 세션에만 사용할 경우 예를 들면:

$env:OPENAI_API_KEY="실제_API_KEY"

 

그 상태에서 Spring Boot 애플리케이션을 실행하면 된다.

IntelliJ를 사용하고 있다면 Run Configuration의 Environment variables에 등록하는 방법도 있다.

중요한 건 어디에 저장하든 Git에 올라가는 파일 안에 실제 Key를 넣지 않는 것이다.

Railway에서는 더 명확했다

로컬에서는 환경변수 없이도 어떻게든 프로젝트를 실행할 수 있다.

하지만 Railway 같은 배포 환경으로 넘어가면 이야기가 달라졌다.

내 컴퓨터에 존재하는 설정은 Railway 서버에는 존재하지 않는다.

그래서 Railway 프로젝트의 Variables에 직접 환경변수를 등록해야 했다.

예를 들어:

OPENAI_API_KEY=실제_API_KEY

 

Spring Boot 쪽에서는 그대로:

openai.api.key=${OPENAI_API_KEY}

 

이렇게 사용한다.

이 구조를 이해하고 나니 Railway의 PORT 환경변수도 비슷하게 보이기 시작했다.

server.port=${PORT:8080}

 

Railway에서 PORT 값을 제공하면 그 값을 사용하고,

로컬에서는 환경변수가 없기 때문에 기본값인 8080을 사용한다.

 

이 부분은 실제 Railway에 Spring Boot를 배포하면서 따로 정리해두었다.

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

 

처음에는 환경변수를 단순히 "설정값을 밖으로 빼는 것" 정도로 생각했는데, 실제로 배포해보니 로컬 환경과 운영 환경을 분리하는 기본적인 방법에 가까웠다.

기본값을 넣을 수도 있다

Spring Boot에서는 환경변수가 없을 때 사용할 기본값도 지정할 수 있다.

server.port=${PORT:8080}

 

여기서 8080이 기본값이다.

하지만 API Key나 비밀번호 같은 값은 기본값을 코드에 넣지 않는 편이 낫다.

예를 들어 이런 식으로 작성하면:

openai.api.key=${OPENAI_API_KEY:sk-xxxxxxxx}

 

결국 비밀정보를 다시 코드에 넣는 것과 다르지 않다.

민감한 값이라면:

openai.api.key=${OPENAI_API_KEY}

 

처럼 환경변수가 없을 경우 애플리케이션이 실행되지 않게 두는 편이 오히려 문제를 빨리 발견하기 좋다.

.gitignore만 믿으면 될까?

처음에는 설정 파일을 .gitignore에 넣으면 되는 것 아닌가 생각할 수도 있다.

물론 로컬 전용 설정 파일을 제외하는 것도 하나의 방법이다.

하지만 프로젝트를 배포하거나 여러 환경에서 실행하게 되면 환경별 설정을 관리해야 한다.

내 PC
개발 서버
운영 서버
CI/CD
Docker
Railway

 

각 환경마다 API Key나 DB 정보가 다를 수 있다.

이 값을 하나의 파일에 넣고 복사하는 방식보다 환경변수로 분리해두는 것이 관리하기 편하다.

특히 배포 플랫폼에서는 대부분 환경변수를 별도로 관리할 수 있는 기능을 제공한다.

이미 GitHub에 API Key를 올렸다면?

이 경우에는 단순히 코드에서 삭제하는 것만으로 끝내면 안 된다.

가장 먼저 해야 할 일은 해당 API Key를 폐기하고 새로 발급하는 것이다.

이미 외부에 노출되었을 가능성이 있기 때문이다.

그 다음에 Git 기록에 민감한 정보가 남아 있는지도 확인해야 한다.

개인적으로는 API Key를 한 번이라도 공개 저장소에 올렸다면 "아직 아무도 못 봤겠지"라고 생각하기보다 이미 노출되었다고 가정하고 교체하는 편이 안전하다고 생각한다.

내가 배포하면서 바뀐 생각

로컬에서만 개발할 때는 이런 설정이 조금 번거롭게 느껴졌다.

openai.api.key=${OPENAI_API_KEY}

 

그냥 실제 값을 적으면 바로 실행되기 때문이다.

그런데 프로젝트를 GitHub에 올리고 Railway에 배포하면서 생각이 바뀌었다.

로컬에서 실행되는 프로젝트와 실제로 배포할 수 있는 프로젝트는 조금 다른 문제였다.

API Key뿐 아니라 포트, DB 접속정보, 외부 서비스 주소 같은 값들도 결국 실행 환경에 따라 달라진다.

그래서 지금은 Spring Boot 프로젝트를 만들 때 설정값을 보면서 먼저 구분하려고 한다.

코드에 있어도 되는 값인가?

환경에 따라 달라지는 값인가?

외부에 공개되면 안 되는 값인가?

 

마지막 두 가지에 해당한다면 환경변수로 빼는 것을 먼저 생각한다.

처음에는 작은 설정 하나처럼 보였지만, 실제 배포를 해보니 이런 부분들이 프로젝트가 localhost를 떠나기 위한 준비라는 걸 조금씩 알게 됐다.


Spring Boot 프로젝트를 실제로 배포하고 있다면

내가 MVP를 직접 배포하면서 계속 놓쳤던 항목들을 따로 체크리스트로 정리해두었다.

 

먼저 무료 버전부터 확인해볼 수 있다.

- Ship Your Spring Boot MVP — 무료 배포 체크리스트 GitHub

 

환경변수, 포트, 빌드, 배포 전 확인사항처럼 localhost에서는 잘 보이지 않던 문제들을 실제 배포 기준으로 정리했다.

 

조금 더 자세한 설명과 전체 체크리스트가 필요하다면 완성판도 따로 만들어두었다.

- Ship Your Spring Boot MVP — Complete Guide