Next.js 기초 입문 24회차: 환경 변수 (Environment Variables) 심층 분석

🔢
제24주차 학습 목표

환경 변수 (Environment Variables)

개발 및 배포 환경에 따라 다른 값을 사용하는 환경 변수를 관리합니다.

Next.js 기초 입문 24회차: 환경 변수 (Environment Variables)

Next.js 기초 입문 과정의 24번째 챕터에 오신 것을 환영합니다. 이번 회차에서는 애플리케이션의 동작을 유연하게 제어하고 중요한 정보를 안전하게 관리하는 데 필수적인 환경 변수(Environment Variables)에 대해 심층적으로 학습하겠습니다. 개발, 스테이징, 프로덕션 등 다양한 환경에서 애플리케이션이 다르게 동작해야 할 때 환경 변수는 매우 중요한 역할을 수행합니다.

📌 이번 회차 학습 목표

  • Next.js 프로젝트에서 환경 변수를 설정하고 관리하는 방법을 이해합니다.
  • 클라이언트 측과 서버 측 환경 변수의 차이점 및 보안 고려사항을 파악합니다.
  • .env 파일을 활용하여 환경 변수를 효과적으로 정의하고 사용합니다.
  • 다양한 배포 환경에 맞는 환경 변수 설정 전략을 수립할 수 있습니다.

📝 개념 설명

1. 환경 변수란 무엇인가?

환경 변수(Environment Variables)는 애플리케이션의 코드 외부에 존재하는 변수들로, 애플리케이션이 실행되는 환경에 따라 다른 값을 가질 수 있습니다. 예를 들어, 개발 환경에서는 로컬 데이터베이스 연결 문자열을 사용하고, 프로덕션 환경에서는 실제 운영 데이터베이스 연결 문자열을 사용해야 할 때 환경 변수를 활용합니다. 이는 코드의 변경 없이 환경 설정만으로 애플리케이션의 동작을 변경할 수 있게 하여 유연성과 유지보수성을 높입니다.

2. Next.js에서의 환경 변수

Next.js는 기본적으로 환경 변수를 지원하며, .env 파일을 통해 쉽게 관리할 수 있습니다. Next.js는 빌드 시점에 환경 변수를 주입하며, 클라이언트 측 코드와 서버 측 코드에서 접근 가능한 변수를 명확히 구분합니다. 이는 보안 측면에서 매우 중요합니다.

3. .env 파일 사용법

Next.js 프로젝트의 루트 디렉토리에 .env 파일을 생성하여 환경 변수를 정의합니다. 파일명은 .env.local, .env.development, .env.production 등 다양하게 사용될 수 있으며, Next.js는 특정 환경에 맞는 파일을 자동으로 로드합니다.

  • .env: 모든 환경에서 기본적으로 로드됩니다.
  • .env.local: 로컬 환경에서만 로드되며, .env 파일을 덮어씁니다. 이 파일은 Git에 커밋하지 않는 것이 일반적입니다.
  • .env.development: 개발 환경(next dev)에서 로드됩니다.
  • .env.production: 프로덕션 환경(next start)에서 로드됩니다.
  • .env.test: 테스트 환경에서 로드됩니다.
팁: .env.local 파일은 민감한 정보를 포함할 수 있으므로, .gitignore 파일에 추가하여 Git 저장소에 포함되지 않도록 관리해야 합니다.

4. 클라이언트 측 환경 변수와 서버 측 환경 변수

Next.js에서 환경 변수는 접근 가능한 위치에 따라 두 가지로 구분됩니다.

  • 클라이언트 측 환경 변수 (Public Environment Variables):
    • 변수 이름 앞에 NEXT_PUBLIC_ 접두사를 붙여야 합니다.
    • 이 변수들은 브라우저에서 실행되는 클라이언트 측 코드(예: React 컴포넌트)에서도 접근 가능합니다.
    • 빌드 시점에 클라이언트 측 JavaScript 번들에 포함되므로, 절대 민감한 정보(API 키, 데이터베이스 비밀번호 등)를 포함해서는 안 됩니다.
  • 서버 측 환경 변수 (Private Environment Variables):
    • NEXT_PUBLIC_ 접두사가 없는 모든 환경 변수입니다.
    • 이 변수들은 서버 측 코드(예: getServerSideProps, API 라우트)에서만 접근 가능합니다.
    • 클라이언트 측 번들에 포함되지 않으므로, 민감한 정보를 안전하게 저장하고 사용할 수 있습니다.
⚖️ Next.js 환경 변수 비교
항목클라이언트 측 변수서버 측 변수
접두사NEXT_PUBLIC_ 필수접두사 없음
접근 가능 위치클라이언트(브라우저), 서버서버만
보안낮음 (클라이언트 번들에 포함)높음 (클라이언트 번들에 미포함)
사용 예시공개 API 키, 분석 ID데이터베이스 비밀번호, 비공개 API 키

💡 예제 & 실습

이제 실제 Next.js 프로젝트에서 환경 변수를 설정하고 사용하는 방법을 단계별로 살펴보겠습니다.

1. 프로젝트 설정

새 Next.js 프로젝트를 생성하거나 기존 프로젝트를 사용합니다.

npx create-next-app@latest nextjs-env-example
cd nextjs-env-example

2. .env.local 파일 생성

프로젝트 루트 디렉토리에 .env.local 파일을 생성하고 다음과 같이 내용을 작성합니다.

# .env.local

# 클라이언트 측에서 접근 가능한 공개 환경 변수
NEXT_PUBLIC_ANALYTICS_ID='UA-XXXXX-Y'
NEXT_PUBLIC_API_URL='https://api.example.com/public'

# 서버 측에서만 접근 가능한 비공개 환경 변수
DB_CONNECTION_STRING='mongodb://localhost:27017/mydb'
SECRET_API_KEY='super_secret_key_12345'
주의: .env.local 파일은 Git에 커밋되지 않도록 .gitignore 파일에 추가하는 것을 잊지 마세요.

3. .gitignore 파일 확인

.gitignore 파일에 .env.local이 포함되어 있는지 확인합니다. 일반적으로 create-next-app으로 생성 시 기본적으로 포함되어 있습니다.

# .gitignore

# ... (생략)

.env.local
.env.*.local

# ... (생략)

4. 환경 변수 사용하기

이제 애플리케이션 코드에서 이 환경 변수들을 사용해 보겠습니다.

a. 클라이언트 측에서 환경 변수 사용 (NEXT_PUBLIC_ 접두사)

pages/index.js 파일을 다음과 같이 수정하여 클라이언트 측 환경 변수에 접근합니다.

// pages/index.js

import Head from 'next/head';

export default function Home() {
  // 클라이언트 측에서 접근 가능한 환경 변수
  const analyticsId = process.env.NEXT_PUBLIC_ANALYTICS_ID;
  const publicApiUrl = process.env.NEXT_PUBLIC_API_URL;

  return (
    <div>
      <Head>
        <title>환경 변수 예제</title>
      </Head>

      <main>
        <h1>환경 변수 테스트</h1>
        <p><strong>Analytics ID (Public):</strong> {analyticsId}</p>
        <p><strong>Public API URL (Public):</strong> {publicApiUrl}</p>
        <p>이 값들은 브라우저 개발자 도구에서도 확인 가능합니다.</p>
      </main>
    </div>
  );
}

애플리케이션을 실행하고(npm run dev 또는 yarn dev) 브라우저에서 페이지를 확인한 후, 개발자 도구(Sources 탭 등)를 통해 번들된 JavaScript 파일에서 NEXT_PUBLIC_ANALYTICS_IDNEXT_PUBLIC_API_URL 값이 포함되어 있는지 확인해 보세요.

b. 서버 측에서 환경 변수 사용 (접두사 없음)

pages/api/hello.js 파일을 수정하여 서버 측 환경 변수에 접근해 보겠습니다. API 라우트는 항상 서버에서 실행됩니다.

// pages/api/hello.js

export default function handler(req, res) {
  // 서버 측에서만 접근 가능한 환경 변수
  const dbConnectionString = process.env.DB_CONNECTION_STRING;
  const secretApiKey = process.env.SECRET_API_KEY;

  // 클라이언트 측 변수도 서버에서 접근 가능합니다.
  const publicApiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!dbConnectionString || !secretApiKey) {
    console.error('DB_CONNECTION_STRING or SECRET_API_KEY is not set!');
    return res.status(500).json({ message: 'Server configuration error' });
  }

  res.status(200).json({
    name: 'John Doe',
    dbInfo: `Connected to: ${dbConnectionString ? 'DB is configured' : 'DB not configured'}`,
    apiKeyStatus: `Secret API Key: ${secretApiKey ? 'Set' : 'Not Set'}`,
    publicApiUrlFromApi: publicApiUrl // 클라이언트 변수도 서버에서 접근 가능
  });
}

브라우저에서 http://localhost:3000/api/hello로 접속하여 결과를 확인합니다. 서버 측 변수들이 정상적으로 로드되었는지 확인하고, 이 값들이 클라이언트 측 번들에는 노출되지 않는다는 점을 기억하세요.

c. getServerSideProps에서 환경 변수 사용

getServerSideProps 함수는 서버에서 실행되므로, 서버 측 환경 변수에 접근할 수 있습니다. pages/server-data.js 파일을 생성하고 다음과 같이 작성합니다.

// pages/server-data.js

import Head from 'next/head';

export default function ServerData({ dbInfo, secretStatus, publicApiUrl }) {
  return (
    <div>
      <Head>
        <title>서버 데이터 예제</title>
      </Head>

      <main>
        <h1>getServerSideProps에서 환경 변수 사용</h1>
        <p><strong>DB Connection Status:</strong> {dbInfo}</p>
        <p><strong>Secret API Key Status:</strong> {secretStatus}</p>
        <p><strong>Public API URL (from server):</strong> {publicApiUrl}</p>
        <p>이 값들은 서버에서만 로드되어 클라이언트로 전달됩니다.</p>
      </main>
    </div>
  );
}

export async function getServerSideProps() {
  // 서버 측에서만 접근 가능한 환경 변수
  const dbConnectionString = process.env.DB_CONNECTION_STRING;
  const secretApiKey = process.env.SECRET_API_KEY;
  const publicApiUrl = process.env.NEXT_PUBLIC_API_URL; // 클라이언트 변수도 서버에서 접근 가능

  return {
    props: {
      dbInfo: dbConnectionString ? 'DB is configured' : 'DB not configured',
      secretStatus: secretApiKey ? 'Secret API Key is set' : 'Secret API Key is NOT set',
      publicApiUrl: publicApiUrl
    },
  };
}

http://localhost:3000/server-data로 접속하여 결과를 확인합니다. getServerSideProps는 서버에서 실행되므로, 여기서 사용된 서버 측 환경 변수들은 클라이언트로 직접 노출되지 않고, 오직 props를 통해 전달된 데이터만 클라이언트에 표시됩니다.

🔄 환경 변수 접근 흐름
.env 파일 정의
Next.js 빌드/실행
NEXT_PUBLIC_ 변수: 클라이언트 번들 포함
일반 변수: 서버 환경에만 주입

⚠️ 자주 틀리는 것 / 주의사항

  • NEXT_PUBLIC_ 접두사 누락: 클라이언트 측에서 환경 변수에 접근하려면 반드시 NEXT_PUBLIC_ 접두사를 붙여야 합니다. 이를 누락하면 클라이언트 측에서 undefined로 나타납니다.
  • 민감 정보 노출: NEXT_PUBLIC_ 접두사가 붙은 변수는 브라우저 개발자 도구에서 쉽게 확인할 수 있습니다. 절대 데이터베이스 비밀번호, 관리자 API 키 등 민감한 정보를 이 방식으로 노출해서는 안 됩니다.
  • .env.local Git 커밋: .env.local 파일은 로컬 개발 환경에 특화된 설정이나 민감한 정보를 포함할 수 있으므로, Git 저장소에 커밋되지 않도록 .gitignore에 반드시 추가해야 합니다.
  • 빌드 후 변경 불가: Next.js는 빌드 시점에 환경 변수를 주입합니다. 따라서 애플리케이션이 빌드된 후에는 .env 파일을 수정해도 변경 사항이 반영되지 않습니다. 환경 변수를 변경하려면 애플리케이션을 다시 빌드해야 합니다. (단, 런타임 환경 변수는 예외)
  • 런타임 환경 변수 (Runtime Environment Variables): Next.js 12부터는 next.config.jsenv 설정을 통해 런타임에 환경 변수를 주입하는 기능도 제공하지만, 이는 고급 주제이므로 본 과정에서는 .env 파일 방식에 집중합니다.
✅ 이번 회차 핵심 정리
  • 환경 변수는 개발 및 배포 환경에 따라 애플리케이션 동작을 유연하게 제어하는 데 사용됩니다.
  • Next.js는 .env 파일을 통해 환경 변수를 관리하며, .env.local, .env.development, .env.production 등의 파일명을 지원합니다.
  • NEXT_PUBLIC_ 접두사가 붙은 변수는 클라이언트 측에서도 접근 가능하며, 빌드 시점에 번들에 포함되므로 보안에 유의해야 합니다.
  • 접두사가 없는 변수는 서버 측에서만 접근 가능하며, 민감한 정보를 안전하게 보관하는 데 사용됩니다.
  • .env.local 파일은 .gitignore에 추가하여 Git 저장소에서 제외해야 합니다.
  • 환경 변수 변경 시에는 애플리케이션을 다시 빌드해야 적용됩니다.

🔗 다음 회차 예고

이번 회차에서는 환경 변수를 통해 애플리케이션의 유연성과 보안을 강화하는 방법을 학습했습니다. 다음 25회차에서는 Next.js 애플리케이션의 성능을 최적화하는 핵심 기법 중 하나인 이미지 최적화 (Image Optimization)에 대해 다룰 예정입니다. next/image 컴포넌트를 활용하여 웹 페이지 로딩 속도를 향상시키고 사용자 경험을 개선하는 방법을 함께 알아보겠습니다.

댓글 남기기

Wordpress Social Share Plugin powered by Ultimatelysocial
Copy link
URL has been copied successfully!
THREADS
RSS
error: 저작권 콘텐츠보호를 부탁드립니다.