카테고리 없음

Docker + Docker Compose 개발 환경 구축 삽질기 (feat. 패키지 파일 not found 오류 해결)

meomdms 2025. 2. 18. 14:09

왜 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 설정하여 Dockerfilefrontend 폴더 내부에서 실행되도록 변경
  • 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 폴더만 마운트
~~~~~~~~~~~~~~~~