React.js 언어별 가이드
React.js 언어별 가이드
이 가이드는 Docker로 React.js 어플리케이션을 컨테이너화하는 방법을 알려줘요.
출처: 문서
본문
React.js 언어별 가이드는 Docker를 사용해 React.js 어플리케이션을 컨테이너화하고, 효율적이고 프로덕션 준비가 된 컨테이너를 만드는 모범 사례를 따르는 방법을 보여줘요.
React.js는 인터랙티브한 사용자 인터페이스를 만들기 위해 널리 사용되는 라이브러리예요. 하지만 의존성, 환경, 배포를 효율적으로 관리하는 것은 복잡할 수 있어요. Docker는 일관되고 컨테이너화된 환경을 제공해 이 과정을 단순화해요.
감사의 말 (Acknowledgment)
Docker는 이 가이드를 집필해준 Kristiyan Velkov에게 진심으로 감사를 전해요. Docker Captain이자 경험 많은 Front-end 엔지니어로서, Docker·DevOps·현대 웹 개발에 대한 그의 전문성 덕분에 이 자료가 커뮤니티에 매우 가치 있는 자료가 되어, 개발자들이 자신의 Docker 워크플로를 탐색하고 최적화하는 데 도움을 주고 있어요.
무엇을 배우게 될까요?
이 가이드에서 다음을 배우게 돼요:
- Docker를 사용해 React.js 어플리케이션을 컨테이너화하고 실행하기.
- 컨테이너 안에서 React.js용 로컬 개발 환경 설정하기.
- Docker 컨테이너 안에서 React.js 어플리케이션 테스트 실행하기.
시작하려면 기존 React.js 어플리케이션을 컨테이너화하는 것부터 해볼 거예요.
준비 사항 (Prerequisites)
시작하기 전에 다음에 익숙한지 확인해요:
- JavaScript 또는 TypeScript에 대한 기본 이해.
- 의존성 관리와 스크립트 실행을 위한 Node.js와 npm에 대한 기본 지식.
- React.js 기초에 대한 이해.
- 이미지, 컨테이너, Dockerfile 같은 Docker 개념에 대한 이해. Docker가 처음이라면 Docker basics 가이드부터 시작해요.
React.js getting started 모듈을 완료하면, 이 가이드의 예제와 설명을 바탕으로 자신만의 React.js 어플리케이션을 컨테이너화할 준비가 될 거예요.
React.js 어플리케이션 컨테이너화하기
준비 사항 (Prerequisites)
시작하기 전에 다음 도구가 시스템에 설치·사용 가능한지 확인해요:
- 최신 버전의 Docker Desktop을 설치했어야 해요.
- git 클라이언트가 필요해요. 이 섹션의 예제는 명령줄 기반의 git 클라이언트를 사용하지만, 어떤 클라이언트를 써도 무방해요.
Docker가 처음이라면?
이미지, 컨테이너, Dockerfile 같은 핵심 개념에 익숙해지려면 Docker basics 가이드부터 시작해요.
개요 (Overview)
이 가이드는 Docker로 React.js 어플리케이션을 컨테이너화하는 전체 과정을 안내해요. 성능, 보안, 확장성, 배포 효율성을 높이는 모범 사례를 사용해 프로덕션 준비가 된 Docker 이미지를 만드는 방법을 배우게 돼요.
이 가이드를 끝내면 다음을 할 수 있게 돼요:
- Docker를 사용해 React.js 어플리케이션을 컨테이너화하기.
- 프로덕션 빌드용 Dockerfile을 만들고 최적화하기.
- 다단계 빌드(multi-stage builds)를 사용해 이미지 크기 최소화하기.
- 커스텀 NGINX 구성으로 어플리케이션을 효율적으로 서빙하기.
- 안전하고 유지보수하기 쉬운 Docker 이미지를 만드는 모범 사례 따르기.
샘플 어플리케이션 가져오기
이 가이드에서 사용할 샘플 어플리케이션을 클론해요. 터미널을 열고 작업할 디렉토리로 이동한 다음, 다음 명령을 실행해 git 저장소를 클론해요:
$ git clone https://github.com/kristiyan-velkov/docker-reactjs-sample
Docker 이미지 빌드하기
React.js는 정적 자산으로 컴파일되는 프론트엔드 라이브러리이므로, Dockerfile은 React 어플리케이션이 프로덕션 환경에서 빌드되고 서빙되는 방식을 최적화하도록 맞춰져 있어요.
Tip
Gordon, Docker의 AI 어시스턴트가 프로젝트에 맞는 Docker 자산을 생성해줄 수 있어요. Gordon에게 어플리케이션에 맞춘 Dockerfile, Compose 파일,
.dockerignore를 만들어 달라고 요청해보세요.
1단계: Dockerfile 만들기
Dockerfile을 만들기 전에 베이스 이미지를 선택해야 해요. Node.js Official Image를 사용하거나, Hardened Image catalog의 Docker Hardened Image (DHI)를 사용할 수 있어요.
DHI를 선택하면 가볍고 안전한 프로덕션 준비가 된 이미지라는 이점을 얻을 수 있어요. 자세한 내용은 Docker Hardened Images를 참고해요.
Important
이 가이드는 작성 시점에 안전한 것으로 간주되는 안정적인 Node.js LTS 이미지 태그를 사용해요. 새 릴리스와 보안 패치는 정기적으로 배포되므로, 이 가이드를 따라갈 때 여기 보이는 태그가 더 이상 가장 안전한 옵션이 아닐 수 있어요. 어플리케이션을 빌드·배포하기 전에 항상 최신 사용 가능한 이미지 태그를 검토하고 안전하고 최신 버전을 선택하세요.
공식 Node.js Docker 이미지: https://hub.docker.com/_/node
Docker Hardened Images (DHI)는 Docker Hardened Images catalog의 Node.js용으로 제공돼요. Docker Hardened Images는 구독 없이 누구나 자유롭게 사용할 수 있어요. DHI 레지스트리에 로그인한 뒤 다른 Docker 이미지처럼 pull해서 사용할 수 있어요. 자세한 내용은 DHI quickstart 가이드를 참고해요.
- DHI 레지스트리에 로그인해요:
$ docker login dhi.io
- Node.js DHI를 pull해요 (사용 가능한 버전은 카탈로그에서 확인하세요):
$ docker pull dhi.io/node:24-alpine3.22-dev
- Nginx DHI를 pull해요 (사용 가능한 버전은 카탈로그에서 확인하세요):
$ docker pull dhi.io/nginx:1.28.0-alpine3.21-dev
다음 Dockerfile에서 FROM 지시문은 dhi.io/node:24-alpine3.22-dev와 dhi.io/nginx:1.28.0-alpine3.21-dev를 베이스 이미지로 사용해요.
# =========================================
# Stage 1: Build the React.js Application
# =========================================
# Use a lightweight Node.js image for building (customizable via ARG)
FROM dhi.io/node:24-alpine3.22-dev AS builder
# Set the working directory inside the container
WORKDIR /app
# Copy package-related files first to leverage Docker's caching mechanism
COPY package.json package-lock.json* ./
# Install project dependencies using npm ci (ensures a clean, reproducible install)
RUN --mount=type=cache,target=/root/.npm npm ci
# Copy the rest of the application source code into the container
COPY . .
# Build the React.js application (outputs to /app/dist)
RUN npm run build
# =========================================
# Stage 2: Prepare Nginx to Serve Static Files
# =========================================
FROM dhi.io/nginx:1.28.0-alpine3.21-dev AS runner
# Copy custom Nginx config
COPY nginx.conf /etc/nginx/nginx.conf
# Copy the static build output from the build stage to Nginx's default HTML serving directory
COPY --chown=nginx:nginx --from=builder /app/dist /usr/share/nginx/html
# Use a non-root user for security best practices
USER nginx
# Expose port 8080 to allow HTTP traffic
# Note: The default NGINX container now listens on port 8080 instead of 80
EXPOSE 8080
# Start Nginx directly with custom config
ENTRYPOINT ["nginx", "-c", "/etc/nginx/nginx.conf"]
CMD ["-g", "daemon off;"]
Dockerfile이라는 파일을 다음 내용으로 만들어요:
# =========================================
# Stage 1: Build the React.js Application
# =========================================
ARG NODE_VERSION=24.12.0-alpine
ARG NGINX_VERSION=alpine3.22
# Use a lightweight Node.js image for building (customizable via ARG)
FROM node:${NODE_VERSION} AS builder
# Set the working directory inside the container
WORKDIR /app
# Copy package-related files first to leverage Docker's caching mechanism
COPY package.json package-lock.json* ./
# Install project dependencies using npm ci (ensures a clean, reproducible install)
RUN --mount=type=cache,target=/root/.npm npm ci
# Copy the rest of the application source code into the container
COPY . .
# Build the React.js application (outputs to /app/dist)
RUN npm run build
# =========================================
# Stage 2: Prepare Nginx to Serve Static Files
# =========================================
FROM nginxinc/nginx-unprivileged:${NGINX_VERSION} AS runner
# Copy custom Nginx config
COPY nginx.conf /etc/nginx/nginx.conf
# Copy the static build output from the build stage to Nginx's default HTML serving directory
COPY --chown=nginx:nginx --from=builder /app/dist /usr/share/nginx/html
# Use a built-in non-root user for security best practices
USER nginx
# Expose port 8080 to allow HTTP traffic
# Note: The default NGINX container now listens on port 8080 instead of 80
EXPOSE 8080
# Start Nginx directly with custom config
ENTRYPOINT ["nginx", "-c", "/etc/nginx/nginx.conf"]
CMD ["-g", "daemon off;"]
Note
보안 모범 사례를 따르기 위해 표준 NGINX 이미지 대신 nginx-unprivileged를 사용하고 있어요. 최종 이미지에서 비루트(non-root) 사용자로 실행하는 것은:
- 공격 표면(attack surface)을 줄여주고
- 컨테이너 하드닝에 대한 Docker의 권장사항과 일치하며
- 프로덕션 환경의 더 엄격한 보안 정책을 준수하는 데 도움이 돼요
2단계: compose.yaml 파일 만들기
compose.yaml이라는 파일을 다음 내용으로 만들어요:
services:
server:
build:
context: .
ports:
- 8080:8080
3단계: .dockerignore 파일 만들기
.dockerignore 파일은 이미지를 빌드할 때 어떤 파일과 폴더를 제외할지 Docker에 알려줘요.
Note
이것은 다음과 같은 도움이 돼요:
- 이미지 크기 줄이기
- 빌드 과정 가속화하기
- 민감하거나 불필요한 파일(예:
.env,.git,node_modules)이 최종 이미지에 추가되는 것을 방지하기자세히 알아보려면 .dockerignore reference를 참고해요.
.dockerignore이라는 파일을 다음 내용으로 만들어요:
# Ignore dependencies and build output
node_modules/
dist/
out/
.tmp/
.cache/
# Ignore Vite, Webpack, and React-specific build artifacts
.vite/
.vitepress/
.eslintcache
.npm/
coverage/
jest/
cypress/
cypress/screenshots/
cypress/videos/
reports/
# Ignore environment and config files (sensitive data)
*.env*
*.log
# Ignore TypeScript build artifacts (if using TypeScript)
*.tsbuildinfo
# Ignore lockfiles (optional if using Docker for package installation)
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Ignore local development files
.git/
.gitignore
.vscode/
.idea/
*.swp
.DS_Store
Thumbs.db
# Ignore Docker-related files (to avoid copying unnecessary configs)
Dockerfile
.dockerignore
docker-compose.yml
docker-compose.override.yml
# Ignore build-specific cache files
*.lock
4단계: nginx.conf 파일 만들기
React.js 어플리케이션을 컨테이너 안에서 효율적으로 서빙하기 위해 NGINX를 커스텀 구성으로 설정할 거예요. 이 구성은 성능, 브라우저 캐싱, gzip 압축, 클라이언트 사이드 라우팅 지원에 최적화되어 있어요.
프로젝트 디렉토리 루트에 nginx.conf라는 파일을 만들고 다음 내용을 추가해요:
Note
NGINX 구성에 대해 더 알아보려면 공식 NGINX 문서를 참고해요.
worker_processes auto;
# Store PID in /tmp (always writable)
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Disable logging to avoid permission issues
access_log off;
error_log /dev/stderr warn;
# Optimize static file serving
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
# Gzip compression for optimized delivery
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
gzip_min_length 256;
gzip_vary on;
server {
listen 8080;
server_name localhost;
# Root directory where React.js build files are placed
root /usr/share/nginx/html;
index index.html;
# Serve React.js static files with proper caching
location / {
try_files $uri /index.html;
}
# Serve static assets with long cache expiration
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2?|eot|ttf|svg|map)$ {
expires 1y;
access_log off;
add_header Cache-Control "public, immutable";
}
# Handle React.js client-side routing
location /static/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
}
5단계: React.js 어플리케이션 이미지 빌드하기
커스텀 구성을 준비했으니 이제 React.js 어플리케이션용 Docker 이미지를 빌드할 준비가 됐어요.
업데이트된 구성에는 다음이 포함돼요:
- 브라우저 캐싱과 gzip 압축 최적화
- 권한 문제를 피하기 위한 안전한 비루트 로깅
- 일치하지 않는 라우트를
index.html로 리다이렉트해 React 클라이언트 사이드 라우팅 지원
이전 단계를 완료한 후 프로젝트 디렉토리에는 다음 파일들이 있어야 해요:
├── docker-reactjs-sample/
│ ├── Dockerfile
│ ├── .dockerignore
│ ├── compose.yaml
│ └── nginx.conf
이제 Dockerfile이 구성됐으니 React.js 어플리케이션용 Docker 이미지를 빌드할 수 있어요.
Note
docker build명령은 Dockerfile의 지시사항을 사용해 어플리케이션을 이미지로 패키징해요. 현재 디렉토리(이걸 build context라고 해요)에서 필요한 모든 파일을 포함해요.
프로젝트 루트에서 다음 명령을 실행해요:
$ docker build --tag docker-reactjs-sample .
이 명령이 하는 일:
- 현재 디렉토리(.)의 Dockerfile을 사용해요
- 어플리케이션과 그 의존성을 Docker 이미지로 패키징해요
- 이미지를 docker-reactjs-sample로 태그해서 나중에 참조할 수 있게 해요
6단계: 로컬 이미지 확인하기
Docker 이미지를 빌드한 후 Docker CLI나 Docker Desktop으로 로컬 머신에서 사용 가능한 이미지를 확인할 수 있어요. 이미 터미널에서 작업 중이므로 Docker CLI를 사용해보죠.
로컬에서 사용 가능한 모든 Docker 이미지를 나열하려면 다음 명령을 실행해요:
$ docker images
예시 출력:
REPOSITORY TAG IMAGE ID CREATED SIZE
docker-reactjs-sample latest f39b47a97156 14 seconds ago 75.8MB
이 출력은 이미지에 대한 주요 세부 정보를 제공해요:
- Repository – 이미지에 부여된 이름.
- Tag – 다른 빌드를 식별하는 데 도움을 주는 버전 라벨 (예: latest).
- Image ID – 이미지의 고유 식별자.
- Created – 이미지가 빌드된 시점을 나타내는 타임스탬프.
- Size – 이미지가 사용하는 전체 디스크 공간.
빌드에 성공했다면 docker-reactjs-sample 이미지가 나열된 것을 볼 수 있어요.
컨테이너화한 어플리케이션 실행하기
이전 단계에서 React.js 어플리케이션용 Dockerfile을 만들고 docker build 명령으로 Docker 이미지를 빌드했어요. 이제 그 이미지를 컨테이너에서 실행하고 어플리케이션이 예상대로 동작하는지 확인할 차례예요.
docker-reactjs-sample 디렉토리 안에서 터미널에 다음 명령을 실행해요.
$ docker compose up --build
브라우저를 열고 http://localhost:8080에서 어플리케이션을 확인해요. 간단한 React.js 웹 어플리케이션을 볼 수 있어요.
터미널에서 ctrl+c를 눌러 어플리케이션을 중지해요.
어플리케이션을 백그라운드로 실행하기
-d 옵션을 추가하면 터미널에서 분리된 상태로 어플리케이션을 실행할 수 있어요. docker-reactjs-sample 디렉토리 안에서 터미널에 다음 명령을 실행해요.
$ docker compose up --build -d
브라우저를 열고 http://localhost:8080에서 어플리케이션을 확인해요. 간단한 웹 어플리케이션 미리보기를 볼 수 있어요.
컨테이너가 실행 중인지 확인하려면 docker ps 명령을 사용해요:
$ docker ps
이 명령은 포트, 이름, 상태와 함께 모든 활성 컨테이너를 나열해요. 8080 포트를 노출하는 컨테이너를 찾아보세요.
예시 출력:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
88bced6ade95 docker-reactjs-sample-server "nginx -c /etc/nginx…" About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp docker-reactjs-sample-server-1
어플리케이션을 중지하려면 다음을 실행해요:
$ docker compose down
Note
Compose 명령에 대한 자세한 내용은 Compose CLI reference를 참고해요.
React.js 개발에 컨테이너 사용하기
준비 사항 (Prerequisites)
React.js 어플리케이션 컨테이너화를 완료해요.
개요 (Overview)
이 섹션에서는 Docker Compose를 사용해 컨테이너화한 React.js 어플리케이션을 위한 프로덕션 환경과 개발 환경을 모두 구성하는 방법을 배워요. 이 구성으로 Nginx를 통해 정적 프로덕션 빌드를 서빙하고, Compose Watch와 함께 라이브 리로딩 개발 서버를 사용해 컨테이너 안에서 효율적으로 개발할 수 있어요.
다음을 배우게 돼요:
- 프로덕션용과 개발용으로 별도의 컨테이너 구성하기
- 개발 중 Compose Watch를 사용해 자동 파일 동기화 활성화하기
- 수동 리빌드 없이 실시간으로 변경 사항을 디버그하고 라이브 미리보기하기
서비스 자동 업데이트 (개발 모드)
Compose Watch를 사용하면 소스 파일 변경 사항을 컨테이너화한 개발 환경으로 자동 동기화할 수 있어요. 이렇게 하면 컨테이너를 수동으로 재시작하거나 리빌드할 필요 없이 매끄럽고 효율적인 개발 경험을 제공해요.
1단계: 개발용 Dockerfile 만들기
프로젝트 루트에 Dockerfile.dev라는 파일을 다음 내용으로 만들어요:
# =========================================
# Stage 1: Develop the React.js Application
# =========================================
ARG NODE_VERSION=24.12.0-alpine
# Use a lightweight Node.js image for development
FROM node:${NODE_VERSION} AS dev
# Set the working directory inside the container
WORKDIR /app
# Copy package-related files first to leverage Docker's caching mechanism
COPY package.json package-lock.json* ./
# Install project dependencies
RUN --mount=type=cache,target=/root/.npm npm install
# Copy the rest of the application source code into the container
COPY . .
# Expose the port used by the Vite development server
EXPOSE 5173
# Use a default command, can be overridden in Docker compose.yml file
CMD ["npm", "run", "dev"]
이 파일은 개발 서버를 사용해 React 앱을 위한 가벼운 개발 환경을 구성해요.
2단계: compose.yaml 파일 업데이트하기
compose.yaml 파일을 열고 프로덕션용(react-prod)과 개발용(react-dev) 두 개의 서비스를 정의해요.
React.js 어플리케이션의 구성 예시는 다음과 같아요:
services:
react-prod:
build:
context: .
dockerfile: Dockerfile
image: docker-reactjs-sample
ports:
- "8080:8080"
react-dev:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "5173:5173"
develop:
watch:
- action: sync
path: .
target: /app
react-prod서비스는 Nginx를 사용해 정적 프로덕션 앱을 빌드하고 서빙해요.react-dev서비스는 라이브 리로드와 핫 모듈 교체(hot module replacement)를 갖춘 React 개발 서버를 실행해요.watch는 Compose Watch로 파일 동기화를 트리거해요.
Note
자세한 내용은 공식 가이드인 Use Compose Watch를 참고해요.
3단계: Docker 안에서 제대로 동작하도록 vite.config.ts 업데이트하기
Vite의 개발 서버를 Docker 안에서 안정적으로 동작하게 하려면 올바른 설정으로 vite.config.ts를 업데이트해야 해요.
프로젝트 루트의 vite.config.ts 파일을 열고 다음과 같이 업데이트해요:
/// <reference types="vitest" />
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
base: "/",
plugins: [react()],
server: {
host: true,
port: 5173,
strictPort: true,
},
});
Note
vite.config.ts의server옵션은 Docker 안에서 Vite를 실행하는 데 필수적이에요:
host: true는 개발 서버를 컨테이너 외부에서 접근 가능하게 해줘요.port: 5173은 일관된 개발 포트를 설정해요 (Docker에서 노출된 포트와 일치해야 해요).strictPort: true는 포트를 사용할 수 없을 때 Vite가 조용히 전환하는 대신 명확히 실패하게 해줘요.자세한 내용은 Vite server configuration docs를 참고해요.
이전 단계를 완료한 후 프로젝트 디렉토리에는 다음 파일들이 있어야 해요:
├── docker-reactjs-sample/
│ ├── Dockerfile
│ ├── Dockerfile.dev
│ ├── .dockerignore
│ ├── compose.yaml
│ └── nginx.conf
4단계: Compose Watch 시작하기
프로젝트 루트에서 다음 명령을 실행해 watch 모드로 컨테이너를 시작해요:
$ docker compose watch react-dev
5단계: React로 Compose Watch 테스트하기
Compose Watch가 올바르게 동작하는지 확인하려면:
-
텍스트 편집기에서
src/App.tsx파일을 열어요. -
다음 줄을 찾아요:
<h1>Vite + React</h1>
- 다음으로 바꿔요:
<h1>Hello from Docker Compose Watch</h1>
-
파일을 저장해요.
-
브라우저에서 http://localhost:5173을 열어요.
컨테이너를 수동으로 리빌드할 필요 없이 업데이트된 텍스트가 즉시 나타나는 것을 볼 수 있어요. 이는 파일 감시와 자동 동기화가 예상대로 동작하고 있다는 뜻이에요.
컨테이너에서 React.js 테스트 실행하기
준비 사항 (Prerequisites)
이 가이드의 이전 섹션을 전부 완료해요 — React.js 어플리케이션 컨테이너화부터 시작해서요.
개요 (Overview)
테스트는 개발 과정의 중요한 부분이에요. 이 섹션에서 다음을 배우게 돼요:
- Docker 컨테이너 안에서 Vitest를 사용해 단위 테스트 실행하기.
- Docker Compose를 사용해 격리되고 재현 가능한 환경에서 테스트 실행하기.
Vite용으로 설계된 초고속 테스트 러너인 Vitest와 단언(assertion)용 Testing Library를 사용할 거예요.
개발 중 테스트 실행하기
docker-reactjs-sample 어플리케이션에는 다음 위치에 샘플 테스트 파일이 포함돼 있어요:
$ src/App.test.tsx
이 파일은 Vitest와 React Testing Library를 사용해 App 컴포넌트의 동작을 검증해요.
1단계: Vitest와 React Testing Library 설치하기
필요한 테스트 도구를 아직 추가하지 않았다면 다음을 실행해 설치해요:
$ npm install --save-dev vitest @testing-library/react @testing-library/jest-dom jsdom
그런 다음 package.json 파일의 scripts 섹션을 업데이트해 다음을 포함시켜요:
"scripts": {
"test": "vitest run"
}
2단계: Vitest 구성하기
프로젝트 루트의 vitest.config.ts 파일을 다음 구성으로 업데이트해요:
/// <reference types="vitest" />
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
base: "/",
plugins: [react()],
server: {
host: true,
port: 5173,
strictPort: true,
},
test: {
environment: "jsdom",
setupFiles: "./src/setupTests.ts",
globals: true,
},
});
Note
vitest.config.ts의test옵션은 Docker 안에서 안정적인 테스트에 필수적이에요:
environment: "jsdom"은 렌더링과 DOM 상호작용을 위한 브라우저와 유사한 환경을 시뮬레이션해요.setupFiles: "./src/setupTests.ts"는 각 테스트 파일 전에 전역 구성이나 목(mock)을 로드해요 (선택 사항이지만 권장).globals: true는describe,it,expect같은 전역 테스트 함수를 임포트 없이 사용할 수 있게 해줘요.자세한 내용은 공식 Vitest configuration docs를 참고해요.
3단계: compose.yaml 업데이트하기
compose.yaml 파일에 react-test라는 새 서비스를 추가해요. 이 서비스는 격리된 컨테이너 환경에서 테스트 스위트를 실행할 수 있게 해줘요.
services:
react-dev:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "5173:5173"
develop:
watch:
- action: sync
path: .
target: /app
react-prod:
build:
context: .
dockerfile: Dockerfile
image: docker-reactjs-sample
ports:
- "8080:8080"
react-test:
build:
context: .
dockerfile: Dockerfile.dev
command: ["npm", "run", "test"]
react-test 서비스는 개발에 사용된 것과 같은 Dockerfile.dev를 재사용하고 기본 명령을 npm run test로 테스트 실행하도록 덮어써요. 이 구성으로 로컬 개발 구성과 일치하는 일관된 테스트 환경을 보장해요.
이전 단계를 완료한 후 프로젝트 디렉토리에는 다음 파일들이 있어야 해요:
├── docker-reactjs-sample/
│ ├── Dockerfile
│ ├── Dockerfile.dev
│ ├── .dockerignore
│ ├── compose.yaml
│ └── nginx.conf
4단계: 테스트 실행하기
컨테이너 안에서 테스트 스위트를 실행하려면 프로젝트 루트에서 다음 명령을 실행해요:
$ docker compose run --rm react-test
이 명령은:
compose.yaml파일에 정의된react-test서비스를 시작해요.- 개발과 같은 환경을 사용해
npm run test스크립트를 실행해요. - 테스트가 완료된 후 컨테이너를 자동으로 제거해요 (
docker compose run --rm명령 덕분에).
Note
Compose 명령에 대한 자세한 내용은 Compose CLI reference를 참고해요.
요약 (Summary)
이 섹션에서는 Vitest와 Docker Compose를 사용해 Docker 컨테이너 안에서 React.js 어플리케이션의 단위 테스트를 실행하는 방법을 배웠어요.
달성한 것:
- React 컴포넌트 테스트를 위해 Vitest와 React Testing Library를 설치하고 구성했습니다.
- 테스트 실행을 격리하기 위해
compose.yaml에react-test서비스를 만들었습니다. - dev와 test 환경 간 일관성을 보장하기 위해 개발용
Dockerfile.dev를 재사용했습니다. docker compose run --rm react-test를 사용해 컨테이너 안에서 테스트를 실행했습니다.- 로컬 머신 설정에 의존하지 않고 다양한 환경에서 안정적이고 반복 가능한 테스트를 보장했습니다.
관련 자료 (Related resources)
Docker 테스트 워크플로를 향상시키려면 공식 레퍼런스와 모범 사례를 살펴보세요:
- Dockerfile reference – 모든 Dockerfile 지시문과 문법을 이해하기.
- Best practices for writing Dockerfiles – 효율적이고 유지보수하기 쉬우며 안전한 Dockerfile 작성하기.
- Compose file reference –
compose.yaml에서 서비스 구성에 사용 가능한 전체 문법과 옵션 배우기. docker compose runCLI reference – 서비스 컨테이너에서 일회성 명령 실행하기.