개발을 하다보면 환경 변수를 많이 사용하게 된다.
이는 주로, 기밀성 유지 혹은 컴포넌트가 의존성 제거를 통해 결합도를 낮추기 위해 사용된다.
특히 배포 시 필요한, API 키값이나, 다른 API의 주소 등의 값들을 환경 변수로 저장하고 사용하게 된다. 별도의 파일로 관리해서, 배포 환경이나 운영자가 바뀌더라도, 코드를 수정하지 않고 바로 사용하기 위해서이다.
즉, 환경 설정 값을 별도의 파일로 저장하고, 어플리케이션은 런타임에서 이 파일을 읽고, 값들을 대입하게끔 설계한다.
환경 변수를 관리하는 방식은 여러가지가 있다. 시스템 환경 변수에 저장하는 방식이 있고, .yml .properties .env 등의 파일에 별도로 저장하는 방식이 있다.
사실 시스템 환경 변수에 저장하는 방식 외에는 전부 텍스트 파일에 불과하다. 다만 응용프로그램이 각 파일을 다루는 일반적인 방식에 차이가 있다.
윈도우의 경우 주로 시스템 환경 변수 편집 혹은 set 명령어를 사용해서 설정하고, 리눅스의 경우 export 명령어를 통해 설정할 수 있다.
# 환경 변수 설정
export DB_USER=root
# 확인
echo $DB_USER
이렇게 설정한 값들은 어디에 저장되는 걸까? 놀랍게도 OS 자체에는 환경 변수가 없다. 환경 변수는 각 프로세스가 가지고 있다. OS는 부팅이 완료되면 유저 프로세스인 systemd(혹은 init) 실행한다. 이 systemd는 부팅 후, 가장 처음 실행 되는 유저 프로세스이며, PID로 1을 갖는다. 이후 모든 유저 프로세스의 조상이 된다.(fork 형식으로 프로세스를 생성하기 때문) 이 systemd에 모든 시스템 환경 변수를 적재하게 된다.
각 프로세스는 환경 변수 테이블이라는 형태로 각자 자신만의 환경 변수를 저장하고 관리하는데, 프로세스가 생성될 때, 부모의 모든 환경 변수를 복사한다.
위의 과정을 통해 모든 유저 프로세스가 시스템 환경 변수를 각자 가지게 되고, 이 결과가 마치 모든 프로세스가 하나의 값을 공유하는 것처럼 보이는 것이다.

.yml과 .properties은 일반적으로 텍스트 파일과 동일한 방식으로 사용된다. 단순 문자열로 읽어지고, key=value 값을 단순 문자열 파싱을 통해, 런타임에서 어플리케이션의 특정 변수에 value를 바로 대입한다. 텍스트 파일과 동일하게 직접 파싱을 해주거나, 별도의 파싱 라이브러리를 사용한다.
이러한 방식으로 인해 어플리케이션의 환경 변수 테이블에 적재되지도 않는다. 고로 정확히 얘기하면 환경 변수는 아니다. 외부 파일에 저장된 단순 문자열에 가깝다.
환경 변수 테이블에 적재되지 않기 때문에, 값을 읽을 때마다, .yml(혹은 .properties) 파일에 직접 접근해야 한다. File IO를 줄이려면, 최초에 읽고 난뒤 별도의, 변수에 저장해서 직접 관리해야 한다.
.env는 다른 형식과는 조금 다르다. 어플리케이션이 실행되면, .env 파일을 읽고 .env에 기록된 key, value 값들을 복사해서 자신의 환경 변수 테이블에 적재한다.
이후에는 시스템 환경 변수들과 같은 방식으로 접근하고 사용한다. 따라서 값을 읽을 때마다 .env 파일에 접근하지 않고도, 별도의 변수 관리 없이, 코드의 모든 구간에서 접근 가능하다.