SW/TypeScript

Angular에서 환경 변수를 사용하는 방법: 환경 변수로 유연한 배포 환경 구성하기

얇은생각 2024. 10. 23. 07:30
반응형

웹 애플리케이션을 개발하는 과정에서 로컬 환경에서는 대개 localhost URL을 사용하여 서비스를 실행합니다. 하지만 프로덕션 배포다른 환경으로 전환할 때는 해당 URL을 적절한 값으로 변경해야 하는데, 이러한 과정에서 환경 변수를 활용하면 더욱 유연하고 안전하게 프로젝트를 관리할 수 있습니다.

이 글에서는 Angular 프로젝트에서 환경 변수를 이용하여 쉽게 구성 요소를 대체하고, Docker와 함께 환경 변수를 적용하는 방법까지 상세하게 다룹니다.

 

 

Angular에서 환경 변수를 사용하는 방법: 환경 변수로 유연한 배포 환경 구성하기

 

 

환경 변수란?

**환경 변수(Environment Variables)**는 시스템 외부에서 설정할 수 있는 변수로, 애플리케이션이 실행될 때 동적으로 값을 읽어들입니다. 이를 통해 개발, 테스트, 프로덕션 등 다양한 환경에서 같은 코드베이스로도 다른 설정 값을 적용할 수 있게 해줍니다.

 

 

왜 환경 변수를 사용해야 할까?

  1. 유연한 배포: 로컬 개발 환경과 프로덕션 환경은 대개 설정이 다릅니다. 이를 수동으로 변경하는 대신, 환경 변수를 사용하면 애플리케이션을 더 유연하게 구성할 수 있습니다.
  2. 보안: 중요한 정보(: API , 데이터베이스 URL)를 코드에 직접 하드코딩하는 것은 보안에 취약합니다. 환경 변수를 사용하면 중요한 정보를 코드에서 분리할 수 있어 보안성이 향상됩니다.
  3. 프로젝트 유지보수 용이성: 환경 변수를 사용하면 다양한 환경 설정을 쉽게 변경할 수 있습니다. 이를 통해 프로젝트 유지보수가 더 쉬워지고, 새로운 환경에 맞춰 애플리케이션을 손쉽게 조정할 수 있습니다.

 

Angular에서 환경 변수 설정하기

Angular 프로젝트에서 환경 변수를 사용하려면, 먼저 템플릿 파일을 만들어야 합니다. 이를 통해 배포할 환경에 따라 변수를 쉽게 대체할 수 있습니다.

 

 

1. 환경 파일 템플릿 만들기

먼저 src/ 폴더 아래에 environments라는 폴더를 만들고, 그 안에 environment.template.ts라는 파일을 생성합니다. 여기에 환경 변수를 설정할 수 있는 템플릿 변수를 추가합니다. 아래 예시와 같이 필요한 만큼 변수를 정의할 수 있습니다.

export const environment = 
{
    production: '${IS_PRODUCTION}',
    API_URL: '${BACKEND_URL}${BACKEND_PORT}'
};

 

 

위 템플릿에서 ${IS_PRODUCTION}, ${BACKEND_URL}, ${BACKEND_PORT}는 나중에 실제 환경에 맞게 대체될 변수들입니다.

 

 

2. 환경 변수를 대체하는 스크립트 추가

다음으로 환경 변수를 템플릿 파일에 적용하는 JavaScript 파일을 만듭니다. 이 파일은 지정된 환경 변수로 템플릿 파일의 내용을 대체하고 새로운 환경 파일을 생성합니다. 파일명은 replace_environment_variables.js로 하며, 아래 코드를 사용합니다.

const fs = require("fs");

// 명령어에서 전달된 인자를 가져옵니다.
let config = process.argv[2];

// 템플릿 파일을 문자열로 읽습니다.
let template_environment = fs.readFileSync("./src/environments/environment.template.ts").toString();

// 환경 변수를 대체합니다.
Object.keys(process.env).forEach(env_var => {
    template_environment = template_environment.replaceAll(`\${${env_var}}`, process.env[env_var]);
});

// 환경 설정에 따라 파일 이름을 지정합니다.
if(config)
    fs.writeFileSync(`./src/environments/environment.${config}.ts`, template_environment);
else
    fs.writeFileSync("./src/environments/environment.ts", template_environment);

 

이 스크립트는 시스템에 설정된 환경 변수를 템플릿 파일에서 읽어온 후 적절히 대체한 후, 최종적인 환경 파일을 생성합니다.

 

 

3. npm 스크립트 추가

이제 이 스크립트를 Angular의 빌드 과정과 통합합니다. 이를 위해 package.json 파일의 scripts 섹션에 아래와 같은 스크립트를 추가합니다.

"scripts": {
    "ng": "ng",
    "replace-vars": "node ./src/environments/replace_environment_variables.js",
    "start": "npm run replace-vars && ng serve",
    "build": "npm run replace-vars && ng build"
}

 

 

여기서 "replace-vars" 명령어는 환경 변수를 템플릿 파일에 대체하는 역할을 하고, "start""build" 명령어는 각각 Angular 서버를 시작하거나 애플리케이션을 빌드하기 전에 이 스크립트를 실행합니다.

 

 

4. Docker와의 연동

이제 환경 변수를 Docker에서도 사용할 수 있도록 설정해 보겠습니다. 먼저 Dockerfile에서 빌드 시 전달할 변수를 정의합니다.

FROM node:latest as node

ARG BACKEND_API_PORT 
ARG BACKEND_API_URL
WORKDIR /app

ARG BACKEND_URL=$BACKEND_API_URL
ARG BACKEND_PORT=$BACKEND_API_PORT

RUN npm install
RUN npm run build --prod

 

Dockerfile에서는 BACKEND_API_PORTBACKEND_API_URL 등의 환경 변수를 ARG로 정의한 후, 빌드 시 전달받은 값을 대체하여 사용합니다.

다음으로, Docker 빌드 시 환경 변수를 전달하는 방법입니다.

# Linux 예시
docker build --build-arg BACKEND_API_URL=$BACKEND_API_URL --build-arg BACKEND_API_PORT=$BACKEND_API_PORT -t docker-image-name:latest .

# Windows 예시
docker build --build-arg BACKEND_API_URL=$Env:BACKEND_URL --build-arg BACKEND_API_PORT=$Env:BACKEND_PORT -t docker-image-name:latest.

# 수동으로 환경 변수를 전달하는 방법
docker build --build-arg BACKEND_API_URL=http://some-cool-address.com/api --build-arg BACKEND_API_PORT=:8443 -t docker-image-name:latest.

 

 

위 명령어를 통해 Docker 이미지를 빌드할 때 필요한 환경 변수를 전달하여, 환경에 맞는 설정을 적용할 수 있습니다.

 

 

5. 환경 변수 확인하기

Docker 빌드가 완료되면, 환경 변수가 올바르게 대체되었는지 확인할 수 있습니다. 컨테이너를 실행하고 다음 명령어를 통해 environment.ts 파일을 확인합니다.

docker run -it container-id bash
cat src/environments/environment.ts

 

 

여기에서 Docker 빌드 명령에서 전달된 값이 템플릿 파일에 올바르게 대체된 것을 확인할 수 있습니다.

 

 

결론

Angular 프로젝트에서 환경 변수를 활용하면 다양한 환경에 맞게 애플리케이션을 쉽게 구성할 수 있으며, 특히 배포 시 발생할 수 있는 오류를 줄이고, 프로젝트의 유지보수를 더 효율적으로 할 수 있습니다. 또한, Docker와의 연동을 통해 일관된 환경을 제공하며, 코드에서 민감한 정보를 보호할 수 있습니다.

반응형