컨텐츠로 건너뛰기

환경 변수 사용

Astro는 Vite의 내장 환경 변수 지원에 접근할 수 있게 해주며, 현재 프로젝트의 구성 값(site, base 등), 프로젝트가 개발 환경인지 프로덕션 환경인지 여부 등을 확인할 수 있는 프로젝트용 기본 환경 변수를 포함합니다.

Astro는 또한 타입 안전성이 보장된 환경 변수를 사용하고 구성할 수 있는 방법을 제공합니다. 이는 Astro 컨텍스트(예: Astro 컴포넌트, 라우트 및 엔드포인트, UI 프레임워크 컴포넌트, 미들웨어)에서 사용할 수 있으며, Astro 구성의 스키마를 통해 관리됩니다.

Astro는 빌드 시 정적으로 교체되는 Vite에 내장된 환경 변수 지원을 사용합니다. 이를 통해 Vite가 제공하는 모든 방법을 사용하여 환경 변수를 관리할 수 있습니다.

모든 환경 변수는 서버 측 코드에서만 사용할 수 있으며, 보안을 위해 오직 PUBLIC_ 접두사를 사용하는 환경 변수만이 클라이언트 측 코드에서 사용될 수 있습니다.

.env
SECRET_PASSWORD=password123
PUBLIC_ANYBODY=there

이 예에서 PUBLIC_ANYBODY(import.meta.env.PUBLIC_ANYBODY를 통해 사용 가능)는 서버 측 코드와 클라이언트 측 코드에서 모두 사용할 수 있는 반면, SECRET_PASSWORD(import.meta.env.SECRET_PASSWORD를 통해 사용 가능)는 서버 측 코드에서만 사용할 수 있습니다.

기본적으로 Astro는 astro/client.d.ts에서 import.meta.env에 대한 타입 정의를 제공합니다.

.env.[mode] 파일에서 더 많은 사용자 정의 환경 변수를 정의할 수 있지만, PUBLIC_ 접두사가 붙은 사용자 정의 환경 변수에 대한 TypeScript 자동 완성을 얻고 싶을 수 있습니다.

이를 위해 src/env.d.ts를 생성하고 다음과 같이 ImportMetaEnv를 구성할 수 있습니다:

src/env.d.ts
interface ImportMetaEnv {
readonly DB_PASSWORD: string;
readonly PUBLIC_POKEAPI: string;
// 더 많은 환경 변수...
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

Astro는 기본적으로 몇 가지 환경 변수를 포함하고 있습니다.

  • import.meta.env.MODE: 사이트가 실행 중인 모드입니다. astro dev 명령을 실행할 때는 development이고 astro build 명령을 실행할 때는 production입니다.
  • import.meta.env.PROD: 사이트가 프로덕션 환경에서 실행 중인 경우 true입니다. 그렇지 않으면 false입니다.
  • import.meta.env.DEV: 사이트가 개발 환경에서 실행 중인 경우 true입니다. 그렇지 않으면 false입니다. 항상 import.meta.env.PROD와 반대입니다.
  • import.meta.env.BASE_URL: 사이트의 기본 URL입니다. 이는 base 구성 옵션에 의해 결정됩니다.
  • import.meta.env.SITE: 프로젝트의 astro.config 파일에 설정된 site 옵션의 값입니다.
  • import.meta.env.ASSETS_PREFIX: build.assetsPrefix 구성 옵션이 설정된 경우 Astro에서 생성된 자산 링크의 접두사입니다. 이는 Astro가 처리하지 않는 자산 링크를 생성하는 데 사용될 수 있습니다.

다른 환경 변수처럼 사용하세요.

const isProd = import.meta.env.PROD;
const isDev = import.meta.env.DEV;

환경 변수는 프로젝트 디렉터리의 .env 파일에서 불러올 수 있습니다.

프로젝트 디렉터리에 .env 파일을 생성하고 몇 가지 변수를 추가하세요.

.env
# 서버에서 실행될 때만 사용할 수 있습니다!
DB_PASSWORD="foobar"
# 어디서나 사용할 수 있습니다!
PUBLIC_POKEAPI="https://pokeapi.co/api/v2"

.env 파일명에 .production, .development 또는 사용자 정의 모드 이름을 추가할 수도 있습니다(예: env.testing, .env.staging). 이를 통해 서로 다른 시점에 서로 다른 환경 변수 세트를 사용할 수 있습니다.

astro devastro build 명령어는 각각 기본적으로 "development""production" 모드를 사용합니다. 이러한 명령어를 --mode 플래그와 함께 실행하여 mode에 다른 값을 전달하고 해당하는 .env 파일을 로드할 수 있습니다.

이를 통해 개발 서버를 실행하거나 서로 다른 API에 연결하여 사이트를 빌드할 수 있습니다:

터미널 창
# "staging" API에 연결된 개발 서버 실행
astro dev --mode staging
# 디버깅 정보가 포함된 "production" API를 연결하는 사이트 빌드
astro build --devOutput
# "testing" API를 연결하는 사이트 빌드
astro build --mode testing

.env 파일에 대한 자세한 내용은 Vite 문서를 참조하세요.

Astro는 다른 파일들을 로드하기 전에 구성 파일을 평가합니다. 이는 .env 파일에 설정된 환경 변수에 접근하기 위해 astro.config.mjs에서 import.meta.env를 사용할 수 없다는 것을 의미합니다.

CLI에 의해 설정된 것들과 같은 다른 환경 변수에 접근하기 위해 구성 파일에서 process.env를 사용할 수 있습니다.

또한 .env 파일을 수동으로 로드하기 위해 Vite의 loadEnv 헬퍼를 사용할 수 있습니다.

astro.config.mjs
import { loadEnv } from "vite";
const { SECRET_PASSWORD } = loadEnv(process.env.NODE_ENV, process.cwd(), "");

프로젝트를 실행할 때 환경 변수를 추가할 수도 있습니다.

터미널 창
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 npm run dev

Astro의 환경 변수는 process.env 대신 ES2020에 추가된 import.meta 기능의 import.meta.env를 통해 사용할 수 있습니다.

예를 들어 import.meta.env.PUBLIC_POKEAPI를 사용하여 PUBLIC_POKEAPI 환경 변수를 가져올 수 있습니다.

// import.meta.env.SSR === true인 경우 사용됨
const data = await db(import.meta.env.DB_PASSWORD);
// import.meta.env.SSR === false인 경우 사용됨
const data = fetch(`${import.meta.env.PUBLIC_POKEAPI}/pokemon/squirtle`);

SSR을 사용하는 경우, 사용 중인 SSR 어댑터를 통해 런타임 시 환경 변수를 사용할 수 있습니다. 대부분의 어댑터는 process.env를 통해 환경 변수를 사용하지만 일부 어댑터는 다르게 동작합니다. Deno 어댑터의 경우 Deno.env.get() 함수를 사용합니다. Cloudflare 런타임 사용에서 Cloudflare 어댑터가 환경 변수를 처리하는 방법을 알아보세요. Astro는 먼저 서버 환경에서 변수를 확인하고 변수가 존재하지 않으면 .env 파일에서 해당 변수를 찾습니다.

astro:env API를 사용하면 설정한 환경 변수에 대한 타입 안전 스키마를 구성할 수 있습니다. 이를 통해 환경 변수가 서버 또는 클라이언트에서 사용 가능한지 여부를 지정하고, 데이터 타입과 추가 속성을 정의할 수 있습니다.

어댑터를 개발하고 계신가요? astro:env와 호환되는 어댑터를 만드는 방법을 확인해보세요.

Astro 구성에 env.schema 옵션을 추가하여 스키마를 구성하세요:

astro.config.mjs
import { defineConfig } from 'astro/config'
export default defineConfig({
env: {
schema: {
// ...
}
}
})

그런 다음 envField 헬퍼를 사용하여 변수를 문자열, 숫자, 열거형, 부울로 등록할 수 있습니다. 각 변수에 대해 context(클라이언트 또는 서버)와 access(비밀 또는 공개)를 제공하여 환경 변수의 종류를 정의하고, optional 또는 default와 같은 추가 속성을 객체로 전달할 수 있습니다:

astro.config.mjs
import { defineConfig, envField } from 'astro/config'
export default defineConfig({
env: {
schema: {
API_URL: envField.string({ context: "client", access: "public", optional: true }),
PORT: envField.number({ context: "server", access: "public", default: 4321 }),
API_SECRET: envField.string({ context: "server", access: "secret" }),
}
}
})

astro dev 또는 astro build를 실행할 때 타입이 자동으로 생성되지만, astro sync를 실행하여 타입만 생성할 수도 있습니다.

스키마로부터 변수 사용

섹션 제목: 스키마로부터 변수 사용

적절한 /client 또는 /server 모듈에서 정의된 변수를 가져와 사용하세요:

---
import { API_URL } from "astro:env/client"
import { API_SECRET_TOKEN } from "astro:env/server"
const data = await fetch(`${API_URL}/users`, {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_SECRET_TOKEN}`
},
})
---
<script>
import { API_URL } from "astro:env/client"
fetch(`${API_URL}/ping`)
</script>

스키마에 정의된 context(클라이언트 또는 서버)와 access(비밀 또는 공개) 설정의 조합에 따라 세 가지 종류의 환경 변수를 사용할 수 있습니다:

  • 공개 클라이언트 변수: 이러한 변수들은 최종 클라이언트와 서버 번들 모두에 포함되며, astro:env/client 모듈을 통해 클라이언트와 서버 모두에서 접근할 수 있습니다:

    import { API_URL } from "astro:env/client"
  • 공개 서버 변수: 이러한 변수들은 최종 서버 번들에 포함되며, astro:env/server 모듈을 통해 서버에서 접근할 수 있습니다:

    import { PORT } from "astro:env/server"
  • 비밀 서버 변수: 이러한 변수들은 최종 번들에 포함되지 않으며, astro:env/server 모듈을 통해 서버에서 접근할 수 있습니다:

    import { API_SECRET } from "astro:env/server"

    기본적으로 비밀은 런타임에만 검증됩니다. validateSecrets: true를 구성하여 시작 시 비공개 변수 검증을 활성화할 수 있습니다.

현재 지원되는 데이터 타입은 문자열, 숫자, 열거형, 부울 네 가지입니다:

import { envField } from "astro/config"
envField.string({
// context & access
optional: true,
default: "foo",
})
envField.number({
// context & access
optional: true,
default: 15,
})
envField.boolean({
// context & access
optional: true,
default: true,
})
envField.enum({
// context & access
values: ['foo', 'bar', 'baz'],
optional: true,
default: 'baz',
})
검증 필드의 전체 목록은 envField API 참조를 확인하세요.

스키마를 정의했더라도 주어진 비밀의 원시 값을 검색하거나 스키마에 정의되지 않은 비밀을 검색하고 싶을 수 있습니다. 이 경우 astro:env/server에서 내보낸 getSecret()을 사용할 수 있습니다:

import {
FOO, // boolean
getSecret
} from 'astro:env/server'
getSecret('FOO') // string | undefined
API 참조에서 자세히 알아보세요.
  1. astro:env는 가상 모듈이므로 Astro 컨텍스트에서만 사용할 수 있습니다. 예를 들어, 다음과 같은 곳에서 사용할 수 있습니다:

    • 미들웨어
    • Astro 라우트 및 엔드포인트
    • Astro 컴포넌트
    • 프레임워크 컴포넌트
    • 모듈

    다음과 같은 곳에서는 사용할 수 없으며 process.env를 사용해야 합니다:

    • astro.config.mjs
    • 스크립트
  2. @astrojs/cloudflare는 다른 어댑터들과 약간 다릅니다. Node.js에서는 전역인 반면, 여기에서는 환경 변수가 요청에 대해 범위가 지정됩니다.

    즉, 항상 요청 범위에서 비밀을 사용해야 합니다:

    src/middleware.ts
    import { defineMiddleware } from "astro:middleware"
    import { FOO, getSecret } from "astro:env"
    console.log(FOO) // undefined
    console.log(getSecret("FOO")) // undefined
    export const onRequest = defineMiddleware((context, next) => {
    console.log(FOO) // boolean
    console.log(getSecret("FOO")) // string
    return next()
    })
기여하기

여러분의 생각을 들려주세요!

GitHub Issue 생성

우리에게 가장 빨리 문제를 알려줄 수 있어요.

커뮤니티