환경별 설정
개발과 운영을 구분합니다.
같은 코드가 자리마다 다르게 돌아야 합니다
4.4에서 설정 파일이 겹쳐 읽힌다고 했습니다. 그 "겹치는 기준" 이 환경 입니다. 개발 기계에서는 자세한 오류를 보고 싶고, 운영에서는 보이면 안 됩니다.
환경은 ASPNETCORE_ENVIRONMENT 환경 변수가 정합니다.
적지 않으면 Production 입니다. 이름은
우리가 정할 수 있지만, 아래 셋이 관례이고 프레임워크가 그 이름을 알고 있습니다.
| 이름 | 어디 |
|---|---|
| Development | 개발 기계입니다. 1.2에서 본 launchSettings.json 이 이 값을 넣어 줍니다. |
| Staging | 운영과 같게 꾸며 두고 마지막으로 확인하는 곳입니다. |
| Production | 실제로 사용하는 곳입니다. 기본값입니다. |
기본값이 Production 인 것은 안전한 쪽이기 때문입니다. 잊고 적지 않았을 때 운영으로 도는 편이, 개발용으로 도는 것보다 낫습니다.
세 환경으로 각각 띄워 보면
app.MapGet("/", (IHostEnvironment env, IConfiguration c) => new { 환경 = env.EnvironmentName, 개발인가 = env.IsDevelopment(), 운영인가 = env.IsProduction(), 이름 = c["Site:Name"] });
이 코드는 호스트가 있어야 하므로 브라우저에서 실행할 수 없습니다.
Staging 은 개발도 운영도 아닙니다. 둘 다
false 입니다.
if (!env.IsDevelopment()) 로 적으면 Staging 도
운영 취급이 되고, if (env.IsProduction()) 로 적으면
Staging 만 빠집니다. 어느 쪽을 뜻하는지 정해서 적어야 합니다.
appsettings.Production.json 은 만들지 않았는데도 목록에 있습니다. 없어도 오류가 나지 않습니다. 있으면 읽고 없으면 넘어갑니다.
같은 예외가 다르게 보입니다
이것이 환경을 나누는 가장 큰 까닭입니다. 연결 문자열이 섞인 예외를 일부러 내 두 환경에서 각각 불러 보았습니다.
app.MapGet("/boom", () => { throw new InvalidOperationException( "연결 문자열 Server=db01;Password=1234 로 접속 실패"); });
{
"title": "System.InvalidOperation…",
"status": 500,
"detail": "연결 문자열 Server=db01;
Password=1234 로 접속 실패",
"exception": { 호출 스택 … },
"traceId": "00-af02d658…"
}
{
"title": "An error occurred while
processing your request.",
"status": 500,
"traceId": "00-3c4d4ce8…"
}
왼쪽에 비밀번호가 그대로 있습니다. 예외 메시지·호출 스택·파일 경로가 모두 나갑니다. 고칠 때는 이만한 것이 없지만, 운영에서 이것이 나가면 그대로 사고입니다.
2.5에서 "500은 예외 메시지를 흘리지 않는다" 고 한 것이 이 오른쪽입니다. 그때 Production 으로 띄웠기 때문이고, 개발에서는 다르게 보입니다.
환경으로 갈라 두는 코드는 이렇게 적습니다.
if (app.Environment.IsDevelopment()) app.UseDeveloperExceptionPage(); else app.UseExceptionHandler();
환경이 바꾸는 것들
직접 적지 않아도 환경에 따라 달라지는 것이 여럿입니다. 앞의 단원에서 하나씩 만난 것들입니다.
| 무엇 | Development | 그 밖 |
|---|---|---|
| 예외 응답 | 메시지·호출 스택이 나갑니다 | 제목과 traceId 만 나갑니다 |
| 범위 검사(4.1) | 켜집니다 — 잘못 등록하면 기동이 막힙니다 | 꺼집니다 — 조용히 잘못 동작합니다 |
| 사용자 비밀(4.4) | 읽습니다 | 읽지 않습니다 |
| 정적 파일 캐시 | 짧게 둡니다 | 길게 둡니다 |
둘째 줄이 4.1의 그 함정입니다. 개발에서 잡히는 것이 운영에서는 잡히지 않습니다. 환경을 나누는 것이 편의만은 아니라는 뜻입니다.
운영에서 환경을 정하는 자리
1.2에서 launchSettings.json 이 배포본에 들어가지 않는다고 했습니다. 그러므로 운영에서는 다른 곳에서 정해야 합니다.
# 리눅스·컨테이너 export ASPNETCORE_ENVIRONMENT=Production # 윈도우 IIS — web.config 의 환경 변수 <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" /> # 그때 한 번만 dotnet Api.dll --environment Staging
적지 않으면 Production 이므로, 운영에서는 사실 적지 않아도 됩니다. 그래도 적어 두는 편이 낫습니다. 무엇으로 도는지 눈에 보이고, Staging 을 늘릴 때 자리가 이미 있습니다.
환경 이름은 우리가 정할 수 있습니다
QA·Demo 처럼 원하는 이름을
둘 수 있습니다. 그러면 appsettings.QA.json 을
읽습니다. 다만 IsDevelopment() 같은 메서드는
정해진 세 이름에만 맞으므로
env.IsEnvironment("QA") 로 봅니다.
대소문자를 가립니다.
development 라고 적으면
IsDevelopment() 는 참이지만
appsettings.development.json 을 찾습니다. 리눅스에서는
파일 이름도 대소문자를 가려 읽히지 않습니다.
직접 해보기
지금 어떤 환경으로 돌고 있는지 화면에 내보내는 주소를 만들어보세요. 그리고 환경 변수를 바꿔 가며 확인해보십시오.
IHostEnvironment 를 받으면 됩니다. 1.2의 프로필을 사용하지 않으려면 --no-launch-profile 입니다.아래 셋을 Staging 에서 어떻게 두어야 할지 정하고 코드를 적어보세요.
① 자세한 예외 화면 ② 검색 로봇에게 색인하지 말라고 알리기 ③ 결제를 실제로 승인하기
운영 사이트에서 오류가 났는데 호출 스택과 연결 문자열이 그대로 보였습니다. 무엇을 살펴야 할지, 그리고 다시 생기지 않게 하려면 어떻게 할지 적어보세요.
- 환경은
ASPNETCORE_ENVIRONMENT가 정하고, 적지 않으면 Production 입니다. - 환경 이름으로 appsettings.{환경}.json 을 찾습니다. 없어도 오류가 나지 않습니다.
- 같은 예외가 개발에서는 호출 스택까지, 운영에서는 제목만 나갑니다.
- Staging 은 개발도 운영도 아닙니다. 어느 쪽 기준으로 갈랐는지 항목마다 확인하십시오.
- 운영에서는 launchSettings.json 이 없으므로 환경 변수나 web.config 로 정합니다.