왜 Docker + Docker Compose를 사용하려고 했나?
개발 및 배포 환경을 통합하고, 프론트엔드와 백엔드를 컨테이너화하여 쉽게 관리하기 위해 Docker와 Docker Compose를 사용했다.
프로젝트 구조
- 백엔드 (Node.js + Express): API 제공
- 프론트엔드 (HTML + EJS + Express 기반 정적 파일 제공): UI
- DB (MySQL): 데이터 저장소
🎯 목표
- 백엔드, 프론트엔드, 데이터베이스를 컨테이너로 띄우기
- docker-compose.yml을 이용해 한 번에 컨테이너 관리
- 배포 환경과 로컬 개발 환경을 통일
Dockerfile 초안
FROM node:16 AS build
WORKDIR /app
# 패키지 파일 복사
COPY package.json package-lock.json ./
RUN npm install
# 전체 코드 복사
COPY . .
# Nginx로 정적 파일 서빙
FROM nginx:latest
COPY ./resources /usr/share/nginx/html/resources
COPY ./views /usr/share/nginx/html/views
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Docker Compose yml파일 초안
frontend:
build:
context: ./frontend
container_name: frontend
restart: always
ports:
- "8081:80"
volumes:
- ./frontend:/usr/share/nginx/html
depends_on:
- backend
실행했더니 package.json not found 오류 발생
- COPY frontend/package.json ./ → frontend 경로를 못 찾음
- COPY frontend . → frontend 폴더가 복사되지 않음
- context: ./frontend을 제대로 설정하지 않아서 생긴 문제
- 경로 문제 해결: COPY frontend/package.json ./ → COPY package.json ./
- context: ./frontend 설정하여 Dockerfile이 frontend 폴더 내부에서 실행되도록 변경
- npm run build가 필요하지 않으므로 삭제하고 리소스 폴더만 복사하도록 변경
- COPY ./resources /usr/share/nginx/html/resources
COPY ./frontend /usr/share/nginx/html 설명
이 명령어는 GCP 서버의 frontend 폴더를 컨테이너 내부의 /usr/share/nginx/html로 복사하는 것.
즉:
- 호스트 머신(GCP 인스턴스)에서 frontend 폴더를
- 컨테이너 내부의 /usr/share/nginx/html로 복사하는 것
왜 /usr/share/nginx/html로 복사하냐?
- Nginx 기본 루트 디렉토리가 /usr/share/nginx/html
- nginx는 이 경로에 있는 파일을 정적 파일(HTML, CSS, JS 등)로 제공한다.
즉, frontend 폴더 안의 내용을 /usr/share/nginx/html에 넣으면,
👉 Nginx가 index.html이나 index.ejs 같은 파일을 바로 제공할 수 있게 됨.
하지만 문제가 있음!
지금 frontend 폴더에는 index.html이 없고 views/*.ejs만 있다
- Nginx는 .ejs 파일을 직접 해석할 수 없다
- ejs는 Node.js 서버에서 해석해서 HTML로 변환해야 하는 템플릿 엔진
해결 방법: Express + Nginx 조합
📌 1️⃣ frontend가 정적 파일이면 그대로 둠
frontend에 .html 파일이 있다면 Nginx만으로 해결됨.
하지만 .ejs가 있는 경우 Node.js(Express) 서버에서 렌더링해야 함.
📌 2️⃣ views/ 폴더를 백엔드 서버로 옮겨야 함
현재 views/*.ejs 파일이 있는데, 이건 백엔드에서 렌더링해야 하는 파일.
즉, 백엔드(Node.js)에서 처리해야 함.
📌 3️⃣ resources/만 Nginx로 복사! 지금 frontend/resources/ 안에 있는 파일들은 정적 파일(CSS, JS, 이미지 등)이므로,
이것만 Nginx에 올려서 서빙하고, .ejs는 백엔드에서 렌더링해야 함.
수정해야할 점
1️⃣ Dockerfile 수정
💡 views/ 폴더는 복사하지 않고 resources/만 Nginx로 복사하도록 수정
# 2. Nginx로 정적 파일 서빙
FROM nginx:latest
COPY ./frontend/resources /usr/share/nginx/html/resources
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
2️⃣ docker-compose.yml 수정
💡 views/ 폴더는 백엔드에서 처리해야 하므로 백엔드 컨테이너에 마운트해야 함.
services:
backend:
~~~~~~~~~~~~~~~
volumes:
- ./backend/uploads:/app/uploads
- ./frontend/views:/app/views # 📌 views 폴더를 백엔드에 마운트
~~~~~~~~~~~~~~
frontend:
~~~~~~~~~~~~~~~~~
volumes:
- ./frontend/resources:/usr/share/nginx/html/resources # 📌 resources 폴더만 마운트
~~~~~~~~~~~~~~~~