안녕하세요! 지난번 사파리 브라우저의 화면 깨짐 지옥에서는 무사히 빠져나오셨나요? 호환성 대응 코드로 단단해진 UI를 완성하셨길 바랍니다! 자, 오늘은 개발자라면 누구나 한 번쯤 외쳐봤을 그 마법의 주문, "어? 내 컴퓨터(로컬)에서는 분명히 잘 됐는데?"의 가장 대표적인 원흉에 대해 이야기해 볼까 합니다.
로컬 개발 환경(localhost:3000)에서는 로그인 API도 척척 붙고, 외부 데이터도 예쁘게 잘 불러와집니다. 이제 세상에 내 코드를 자랑할 시간이라며 Vercel이나 AWS, Netlify 같은 호스팅 서버에 기분 좋게 배포(Deploy)를 마쳤죠. 그런데 배포된 진짜 URL로 접속해 보니 화면이 새하얗게 비어있거나, 콘솔창에 API URL is undefined, 404 Not Found 같은 시뻘건 에러가 비 오듯 쏟아집니다. (웃음)
대체 로컬에서는 멀쩡하던 코드가 왜 배포만 하면 바보가 되는 걸까요? 오늘은 프론트엔드 개발자들의 멘탈을 붕괴시키는 '환경변수(.env)의 3가지 함정'과 그 완벽한 해결책을 속 시원히 파헤쳐 보겠습니다.

1. 첫 번째 함정: 당신의 .env는 깃허브에 올라가지 않았습니다!
가장 먼저 짚고 넘어가야 할 아주 기본적이고 치명적인 원인입니다. 우리는 API 키나 데이터베이스 비밀번호 같은 민감한 정보를 숨기기 위해 .env 파일에 값을 저장합니다. 그리고 보안을 위해 .gitignore 파일에 .env를 등록해서 깃허브(GitHub)에 절대 올라가지 않도록 막아두죠. 이것은 아주 훌륭한 보안 습관입니다!
그런데 Vercel이나 AWS 같은 배포 서버는 어디서 여러분의 코드를 가져올까요? 바로 깃허브입니다. 깃허브에는 .env 파일이 없으니, 배포 서버 입장에서는 환경변수가 텅 비어있는 상태로 빌드를 돌리게 되는 것입니다. 로컬에는 파일이 있지만, 배포 서버에는 파일이 없어서 생기는 아주 단순하지만 치명적인 미스매치입니다.
2. 두 번째 함정: 프론트엔드 환경변수만의 까다로운 '접두사(Prefix)' 규칙
"어? 저는 호스팅 서버 세팅에 환경변수 확실하게 다 입력했는데요?"라고 억울해하시는 분들도 계실 겁니다. 그렇다면 두 번째 함정인 '프론트엔드 프레임워크의 접두사 규칙'을 확인해 보셔야 합니다.
Node.js 같은 백엔드 환경에서는 .env에 SECRET_KEY=1234라고 적으면 process.env.SECRET_KEY로 바로 꺼내 쓸 수 있습니다. 하지만 브라우저에서 동작하는 프론트엔드는 보안상 모든 환경변수를 기본적으로 차단합니다. 허락된 변수만 브라우저로 내보내기 위해, 프레임워크마다 정해진 '접두사(Prefix)'를 변수명 앞에 반드시 붙여야만 합니다.
- React (CRA): REACT_APP_을 붙여야 합니다. (예: REACT_APP_API_URL)
- Next.js: NEXT_PUBLIC_을 붙여야 합니다. (예: NEXT_PUBLIC_API_URL)
- Vite: VITE_를 붙여야 합니다. (예: VITE_API_URL)
이 접두사를 빼먹고 그냥 API_URL이라고 지어버리면, 브라우저에서는 해당 값을 절대 읽을 수 없고 자비 없이 undefined를 뱉어내게 됩니다.

3. 세 번째 함정: 환경변수는 '빌드 타임(Build Time)'에 주입됩니다
마지막으로 프론트엔드 개발자들이 가장 헷갈려하는 개념입니다. "배포 완료 후에 Vercel 설정창에서 환경변수를 수정했는데 왜 여전히 안 되죠?"
프론트엔드의 환경변수는 사용자가 사이트에 접속할 때마다 실시간으로 읽어오는 것(Runtime)이 아닙니다. 코드를 HTML/CSS/JS로 변환하는 '빌드(Build)' 과정에서 글자가 아예 치환(Replace) 되어버립니다. 즉, 웹팩(Webpack)이나 비트(Vite)가 소스 코드 안의 process.env.REACT_APP_API_URL이라는 글자를 통째로 찾아내어 진짜 문자열로 하드코딩하듯 박아버리는 원리죠.
따라서 배포 서버 설정창에서 환경변수의 값을 추가하거나 수정했다면, 반드시 프로젝트를 '재빌드(Redeploy)' 해야만 그 변경된 값이 새로운 코드에 정상적으로 반영됩니다.
마무리하며
오늘은 "로컬에선 되는데 배포하면 터져요!"의 1등 공신, 환경변수(.env)의 비밀에 대해 알아보았습니다. 배포 서버의 대시보드(Settings - Environment Variables)에 환경변수를 꼼꼼히 복사해 넣었는지 확인하고, 프레임워크에 맞는 접두사(NEXT_PUBLIC_ 등)를 잘 붙였는지 점검해 보세요. 그리고 값을 수정했다면 잊지 말고 꼭 재빌드(Redeploy) 버튼을 눌러주셔야 합니다. 이 세 가지만 기억하시면 더 이상 배포 환경에서 API 주소를 찾지 못해 헤매는 일은 없으실 겁니다!
[다음 포스팅 예고] 배포 환경의 미스터리를 무사히 해결하셨나요? 다음 글에서는 프론트엔드와 백엔드가 처음으로 데이터를 주고받을 때 100% 확률로 마주치는, 붉은색 에러의 대명사를 만나보겠습니다. 바로 "프론트엔드/백엔드 모두 알아야 할 CORS 에러의 완벽한 원인과 해결법" 편으로 돌아오겠습니다. 내 도메인과 서버 도메인이 달라서 브라우저가 통신을 콱 막아버리는 끔찍한 CORS 정책 때문에 며칠 밤을 지새워보셨다면, 다음 글도 절대 놓치지 마세요! 오늘도 버그 없는 평온한 하루 보내시길 응원합니다!
[실무에서 복붙해 쓰는 에러 해결 및 트러블슈팅 가이드 #12] 포스트맨에선 되는데 왜 안돼? 지긋
안녕하세요! 지난번 배포 환경의 미스터리, 환경변수(.env)의 함정에서는 무사히 탈출하셨나요? 드디어 서버에 내 코드를 띄우셨다니 정말 축하드립니다! 자, 오늘은 프론트엔드와 백엔드가 처음
code-bricks.tistory.com