환경 변수

Environment Variable

개념

같은 코드가 실행되는 자리마다 다른 값을 쓰도록 바깥에서 꽂아 주는 설정으로, 주소나 키처럼 자리마다 달라지는 것을 담습니다.

등장 배경

예전에는 이런 값을 코드 안에 그냥 적었습니다. 데이터베이스 주소도, 결제 회사에서 받은 키도 파일 어딘가에 문자열로 박혀 있었습니다. 혼자 만드는 프로그램이 한 대의 서버에서만 돌 때는 아무 문제가 없었습니다.

개발자 컴퓨터와 시험용 서버와 실제 서버가 나뉘면서 문제가 드러났습니다. 셋은 같은 코드를 돌리지만 봐야 할 데이터베이스가 다릅니다. 그래서 배포할 때마다 파일을 열어 주소를 고치고, 되돌아올 때 다시 고치는 일이 생겼습니다. 한 번 빠뜨리면 시험용 서버가 실제 고객 데이터를 건드립니다. 실제로 테스트 계정을 만드는 코드가 운영 데이터베이스를 바라보고 있어 고객 목록에 더미 계정 수천 개가 들어간 사고는 어느 회사에나 하나씩 있습니다.

더 곤란한 건 키였습니다. 결제 키를 코드에 적어 저장소에 올리면 그 저장소를 볼 수 있는 사람 전부가 그 키를 갖게 됩니다. 퇴사자의 노트북에도 남고, 실수로 공개 저장소에 올라가면 몇 분 만에 남이 가져다 씁니다. 환경 변수는 이 두 문제를 같은 방법으로 풀었습니다. 달라지는 값을 코드 바깥으로 빼내고, 실행하는 쪽이 그때그때 넣어 주게 한 것입니다.

작동 방식

프로그램이 시작될 때 운영체제가 들고 있는 이름과 값의 쌍을 읽어 오는 구조입니다. 코드에는 "DATABASE_URL 이라는 이름의 값을 가져와라" 라고만 적혀 있고, 그 이름에 무엇이 들었는지는 실행하는 쪽이 정합니다.

흐름은 세 단계입니다.

  1. 코드가 값을 이름으로 부릅니다. 주소를 직접 적는 대신 DATABASE_URL 을 읽어 쓰도록 짭니다.
  2. 실행하는 쪽이 그 이름에 값을 채웁니다. 개발자 컴퓨터에서는 로컬 데이터베이스 주소가, 운영 서버에서는 진짜 주소가 들어갑니다. 채우는 자리는 배포 도구의 설정 화면이거나 서버의 실행 명령입니다.
  3. 프로그램이 뜰 때 그 값을 읽어 들고 시작합니다. 대부분 실행 중에는 바뀌지 않으므로 값을 고치면 다시 띄워야 반영됩니다.

이 구조 덕분에 아티팩트, 즉 빌드가 뱉어 낸 실행 파일 한 벌을 시험용 서버와 운영 서버에 그대로 올릴 수 있습니다. 검사한 물건과 고객에게 가는 물건이 같아지는 것이 여기서 얻는 가장 큰 이득입니다. 환경마다 따로 빌드하면 시험을 통과한 것과 다른 물건이 올라갈 여지가 생깁니다.

이름은 대문자와 밑줄로 씁니다. DATABASE_URL 처럼 적는 관행이 굳어져 있어서, 소문자로 적어 두면 다른 사람이 설정 값인 줄 모르고 지나칩니다.

값은 전부 문자열입니다. 숫자 3000 을 넣어도 프로그램은 글자 3000 으로 받으므로 코드에서 숫자로 바꿔 씁니다. 참·거짓도 마찬가지라 false 라는 글자가 참으로 읽히는 실수가 흔합니다.

키처럼 새면 안 되는 값은 같은 통로로 들어오되 보관하는 곳이 다릅니다. 이것을 따로 시크릿 관리라고 부르고, 금고 역할을 하는 도구에 넣어 두었다가 실행하는 순간에만 꺼내 꽂습니다. 설정 화면에서도 한 번 저장한 뒤에는 다시 보이지 않게 가려 둡니다.

쓰이는 곳

가장 흔한 자리는 외부 서비스 주소입니다. 결제, 메일 발송, 파일 저장처럼 남의 서비스를 쓰는 부분마다 시험용 주소와 실제 주소가 따로 있고, 그 선택을 환경 변수가 합니다. 시험용 결제 서버를 보는 동안에는 카드 번호를 넣어도 돈이 빠져나가지 않습니다. 주소 하나가 잘못 들어가면 개발 중에 낸 테스트 결제가 고객 명세서에 찍힙니다.

기능을 켜고 끄는 스위치로도 씁니다. 아직 공개하지 않은 화면을 개발 환경에서만 보이게 하려면 값 하나를 다르게 주면 됩니다. 다만 사용자마다 다르게 켜야 하는 수준이 되면 환경 변수로는 부족하고 피처 플래그를 씁니다.

자동 배포 흐름 안에서는 파이프라인이 이 값을 나눠 주는 역할을 합니다. 같은 코드가 검사 단계에서는 시험용 값으로 돌고, 운영 배포 단계에서는 운영 값으로 도는 식입니다. 어느 값이 어느 단계에 들어가는지를 한곳에서 관리하게 되는 셈입니다.

새 사람이 들어왔을 때 필요한 이름 목록도 여기 붙습니다. 값이 빠진 채 띄우면 프로그램이 이유 없이 죽기 때문에, 이름만 적고 값은 비워 둔 예시 파일을 저장소에 함께 둡니다. 새로 합류한 사람은 그 파일을 복사해 자기 값을 채웁니다.

실무 용례

"로컬에서는 되는데 배포하면 죽어요. 환경 변수 빠진 것 같은데요."

코드가 아니라 서버 쪽 설정에 값이 안 들어갔을 가능성부터 보자는 말입니다.

"그 키는 코드에 적지 말고 환경 변수로 빼 주세요."

저장소에 비밀 값이 남는 것을 막자는 요청입니다.

"값은 바꿨는데 반영이 안 돼요. 재시작하셨어요?"

환경 변수는 뜰 때 한 번 읽는다는 사실을 짚는 말입니다.

페이지덱에서 태오가 신입 개발자와 반나절을 보낸 적이 있습니다. 문서 미리보기 기능이 자기 컴퓨터에서만 안 되는데 이유를 못 찾겠다는 것이었습니다. 태오가 예시 파일과 신입의 설정 파일을 나란히 놓고 보니 이름이 하나 빠져 있었습니다. 두 달 전에 새로 추가된 값인데 예시 파일에는 올리지 않은 것이었습니다.

그날 이후 페이지덱은 새 환경 변수를 추가하는 변경에는 예시 파일도 함께 고쳤는지 확인하는 항목을 코드 리뷰 목록에 넣었습니다. 빠진 값 하나가 새로 온 사람의 첫날을 통째로 먹는 일이 그 전까지 서너 번 있었습니다.

흔한 오해

환경 변수에 넣으면 비밀이 지켜진다고 읽는 경우가 많습니다. 코드에서 빼냈으니 안전해졌다고 느끼기 쉽습니다. 하지만 이 값은 실행 중인 프로그램이 언제든 읽을 수 있는 자리에 있어서, 서버에 들어갈 수 있는 사람이나 그 서버에서 도는 다른 프로그램에게는 그대로 보입니다. 오류가 났을 때 설정 전체를 로그에 찍는 코드가 섞여 있으면 키가 로그 파일에 남고, 그 로그는 대개 여러 사람이 봅니다. 저장소에 적는 것보다 나아진 것이지 금고에 넣은 것이 아닙니다.

파일 하나에 값을 모아 두면 그 파일을 저장소에 올리지 않도록 막아 두는 일도 함께 해야 합니다. 이름이 점으로 시작해 눈에 잘 띄지 않는 파일이라 실수로 올라가는 일이 잦습니다. 한 번 올라가면 나중에 지워도 이력에 남기 때문에 키 자체를 새로 발급받아야 합니다. 발급을 다시 받는 동안 그 키를 쓰던 기능이 멈추는 것까지가 이 실수의 값입니다.

자주 헷갈리는 용어

용어무엇을 가리키는가환경 변수와의 차이
환경개발·스테이징·운영처럼 목적이 다른 실행 공간환경은 공간이고 환경 변수는 그 공간에 꽂는 값입니다. 환경이 셋이면 같은 이름의 변수가 셋 있고 값만 다릅니다

같이 보면 좋은 페이지

  • CI/CD

    이 값들이 어느 흐름 안에서 주입되는지 봅니다

  • 파이프라인

    단계마다 다른 값을 넣는 구조를 확인합니다

마지막 업데이트 2026-09-16