4편에서 만든 정적 산출물을 이제 실제로 웹에서 보여 주어야 합니다. 이번 글은 가장 흔한 조합인 "정적 파일 + nginx"를 Docker로 묶는 기본기를 다룹니다. 모든 예시는 고등학생도 따라 할 수 있는 단일 Dockerfile과 짧은 nginx.conf를 기준으로 설명합니다.
이 글의 흐름
- 정적 사이트를 컨테이너에 담는 머릿속 그림
- nginx 이용해 이미지를 만드는 기본
Dockerfile - 꼭 알아야 할
nginx.conf최소 설정 - 터미널에서 따라 하는 10분 실습
- 정적 사이트 배포에서 자주 만나는 확장 포인트
읽기 카드
- 예상 소요 시간: 15분
- 사전 준비:
docker build,docker run명령을 한 번이라도 실행해 본 경험- 읽고 나면: "정적 폴더 → nginx 이미지 → 실행" 과정을 스스로 설명할 수 있습니다.
머릿속 그림: 파일 상자 + 배달 트럭
정적 웹사이트를 컨테이너에 올리는 과정을 아래처럼 상상해 보세요.
1. build/ 폴더: 완성된 HTML/CSS/JS 상자
2. nginx 이미지: 상자를 싣고 배달하는 트럭
3. Docker 컨테이너: 트럭이 실제로 달리는 공간
트럭(nginx)은 상자 안에 어떤 프레임워크가 있었는지 관심이 없습니다. 단지 /usr/share/nginx/html 안의 파일을 그대로 내보낼 뿐입니다. 우리는 정적 파일을 그 위치로 복사하고, 트럭이 도착할 주소(포트 80)를 외부로 연결해 주면 됩니다.
기본 Dockerfile 살펴보기
가장 단순한 Dockerfile은 아래와 같습니다. 빌드 결과물이 build/ 폴더에 있다고 가정합니다.
FROM nginx:alpine
WORKDIR /usr/share/nginx/html
RUN rm -rf /usr/share/nginx/html/*
COPY build/ .
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
HEALTHCHECK CMD wget -qO- http://127.0.0.1/ >/dev/null || exit 1
RUN rm -rf ...는 기본으로 들어 있는Welcome to nginx!페이지를 비움으로써 실수로 노출되는 일을 막습니다.COPY build/ .는 빌드 산출물을 문서 루트에 그대로 옮깁니다.COPY nginx.conf ...는 우리가 준비한 설정을 덮어씌웁니다.HEALTHCHECK는 30초마다 "응답이 오는지"를 확인하는 체온계 역할을 합니다. 정확한 간격을 추가하려면--interval,--timeout옵션을 붙이면 됩니다.
nginx.conf는 최소 네 줄만 이해해도 된다
처음부터 거대한 설정을 외울 필요는 없습니다. 아래 네 줄 정도면 정적 사이트를 안전하게 서빙할 수 있습니다.
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
location / { try_files $uri $uri/ /index.html; }
}
listen 80;과server_name _;은 "80번 포트를 열고, 어떤 도메인이 와도 응답한다"는 뜻입니다.root는 방금 복사한 정적 파일의 위치를 가리킵니다.try_files규칙은 "정확한 파일 → 폴더 인덱스 →index.html" 순서로 찾습니다. SPA를 배포한다면 마지막/index.html덕분에 클라이언트 라우팅이 깨지지 않습니다.
여기에 캐시 정책, gzip, 보안 헤더 등을 하나씩 추가해 나가면 됩니다. 중요한 것은 "root와 location만 이해해도 나머지는 확장"된다는 사실입니다.
작은 실습: 이미지를 만들고 컨테이너 확인하기
npm run build같은 명령으로 정적 사이트를 만들어build/폴더를 확인합니다.- 위 예시와 같은
Dockerfile,nginx.conf를 같은 폴더에 둡니다. - 터미널에서 아래 명령을 실행합니다.
docker build -t my-static-site .
docker run -d --name my-static -p 8080:80 my-static-site
- 브라우저에서
http://localhost:8080을 열고 화면이 뜨는지 확인합니다. - 상태를 점검하려면
docker ps,docker logs my-static,curl -I localhost:8080정도만 실행해도 충분합니다.
Tip: 컨테이너가 마음에 들지 않으면
docker rm -f my-static으로 지우고 Dockerfile을 수정한 뒤 다시 빌드하면 됩니다. 실습에서는 "빠르게 고치고 재시도"하는 습관이 가장 중요합니다.
흔한 실수와 해결법
- 빌드 폴더 경로를 잘못 복사:
COPY build/ .앞에 빌드 명령을 넣거나,COPY --from=builder구문으로 멀티 스테이지 빌드에서 직접 가져오면 해결됩니다. - 포트 충돌:
-p 8080:80에서 앞쪽 숫자만 바꿔도 됩니다. 8787, 3000 등 빈 포트를 찾아 사용하세요. - 헬스체크 실패:
wget이 없다면apk add --no-cache wget을Dockerfile에 추가하거나curl버전을 사용하세요.
정적 사이트 배포에서 자주 만나는 확장 포인트
기본 배포가 끝나면 보통 아래 기능을 하나씩 추가하게 됩니다.
- gzip과 캐시 헤더로 정적 파일 전송을 최적화하기
/ko,/en같은 경로 리다이렉트 붙이기/api요청만 별도 백엔드로 프록시하기docker compose로 데이터베이스나 API와 함께 관리하기
하지만 핵심은 같습니다. 정적 파일을 /usr/share/nginx/html로 옮기고, 80번 포트를 외부에 연결한다. 이 기본 흐름을 확실히 이해했다면 어떤 정적 사이트라도 쉽게 도커라이즈할 수 있습니다.
다음 글 예고: Docker Compose로 실행 환경 묶기
이미지 하나만으로는 서비스 전체를 설명할 수 없습니다. 6편에서는 여러 컨테이너를 한 번에 정의하는 Docker Compose 기본기를 다루고, 웹+DB 같은 가장 흔한 조합부터 실습해 보겠습니다.
💬 댓글
이 글에 대한 의견을 남겨주세요