Study/Docker

[Docker] 로컬 개발 환경 세팅(vscode, IntelliJ) (2)

seomj 2026. 1. 24. 20:00

서론

이전 포스팅에서 로컬 개발 환경 세팅을 진행했다.

하지만 미숙했던 점이 많았고 이로 인해 문제가 발생했다. 이에 대한 내용을 다뤄보도록 할 것이다.

 

이전 포스팅 참고

 

[Docker] 로컬 개발 환경 세팅(vscode, IntelliJ) (1) - 실패

서론SSAFY 2학기를 맞이해서 프로젝트를 진행하고 있다.본인은 인프라를 담당했고, 우선적으로 팀원들의 개발 환경 통일을 위한 세팅을 제공하기 위해 진행한 내용에 대해 정리한다. 필독해당 글

seomj74.tistory.com

 


문제 사항

1. Front 컨테이너 접속

프론트 담당 팀원들은 WebStorm을 통해 진행을 하고자 했다. WebStorm에서 Front 컨테이너에 접속하고자 했으나 프로젝트 열기 버튼이 활성화되지 않았다. vscode 등에서 코드를 수정하면 바로 반영이 되기 때문에 큰 문제는 없었으나, 내가 예상한 구성이 아니라는 것을 알게 되었다.

 

2. Back 빌드

intellij에서 컨테이너를 열어 빌드를 시도했으나 아래와 같은 오류가 발생했다.

즉, 현재 포트 8080이 이미 사용 중이라서 Spring Boot가 뜨지 못한다는 내용이었다.

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2026-01-22T06:25:15.962Z ERROR 6036 --- [roundy] [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:
Web server failed to start. Port 8080 was already in use.

Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

종료 코드 1(으)로 완료된 프로세스

 

이미 컨테이너 형태로 백엔드가 돌아가고 있는 상황이며, intelliJ 내부에서 또 Run을 해 애플리케이션을 띄우려고 한 것이다. 이대로 실행을 하려면 코드를 수정하고 컨테이너가 자동으로 재시작 되는 걸 기다리거나 재시작해야 한다. 이러한 점을 미처 생각지 못했다.

 

정리

이러한 문제들을 겪으면서 구성에 대해 다시 생각하고 정리하게 되었다.

 

처음에는 그저 docker를 사용해서 하나의 가상환경을 제공하고자 했다.하지만 포트 충돌, 개발 루프 지연 등의 문제가 발생했다. 포트의 경우, 포트를 분리하면 해결이 가능할 수 있다고 생각했지만 복잡하다고 판단했다. 모든 포트를 관리해야 하기 때문이다. 그렇다고 이를 유지하기엔 코드를 고칠 때마다 백엔드에서는 컨테이너를 재시작해야 하는데 이는 매우 불편하다.

 

Docker는 기본적으로 완성된 상태(Immutable)를 실행하는 데 최적화되어 있다. 반면 개발 환경은 계속 변하는 상태(Mutable)이다. 그렇기 때문에 이를 다시 설계하고 생각해 볼 필요가 있다고 판단했다.

 

설계

재설계한 전반적인 구조는 다음과 같다.

 

추가 설명

  • GitLab에서 clone을 WSL 내부에 받는다.
  • 프론트와 백에서 webstorm과 intellij를 사용한다고 하여 여기서 WSL에 접속한다.
  • Frontend와 Backend 폴더에서 개발을 진행한다.
  • 이를 실행하게 되면 Docker 컨테이너 형식으로 Front와 Back이 실행된다.
  • 이를 통해서 localhost:5173, localhost:8080 등 브라우저에서 확인이 가능하다.

그림에서는 이해하기 쉽게 webstorm과 intellij를 직접 연결해 사용하는 것으로 표현했지만, 실제로는 JetBrains의 Gateway 방식을 사용하게 된다. 

 

JetBrains Gateway

https://www.jetbrains.com/remote-development/gateway/

 

JetBrains Gateway - Remote Development for JetBrains IDEs

Get started with remote development workflows from your favorite IDE in no time.

www.jetbrains.com

이는 IDE의 머리(UI)는 Windows에 있고 IDE의 몸통은 WSL2 안에 설치되어 실행된다. 이는 설치 과정을 보면 더 잘 이해할 수 있다.

  1. Backend 실행: WSL2 Ubuntu 내부에 IDE의 핵심 엔진 설치
  2. Thin Client 연결: Windows에서는 가벼운 'JetBrains Client'만 실행되어 WSL2 안의 엔진과 통신
  3. 성능: 모든 파일 연산과 컴파일이 리눅스(WSL2) 내부에서 일어나므로 속도가 빠름

 

세팅 과정

WSL2, Docker, IntelliJ or WebStorm이 설치되어 있다는 가정 하에 진행한다.

 

Docker 컨테이너 구성

아래 코드는 팀원들이 WSL 내부에서 git clone 후 docker-compose up -d --build 과정을 통해 생성하게 된다.

docker-compose.yml

services:
  backend:
    profiles: ["full-test"]
    build:
      context: ../../
      dockerfile: ./Infra/local_dev/backend.Dockerfile
    volumes:
      # 1. 소스 코드는 공유 (수정 시 컨테이너에 즉시 반영)
      - ../../Backend:/app
      # 2. 빌드 결과물 및 캐시 격리 (충돌 방지 핵심 - 익명 볼륨)
      - /app/build
      - /app/.gradle
    ports:
      - "8080:8080"
      - "5005:5005"
    environment:
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/${MYSQL_DATABASE}
      - SPRING_DATASOURCE_USERNAME=root
      - SPRING_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - SPRING_DATA_REDIS_HOST=redis
    depends_on:
      - mysql
      - redis
  
  frontend:
    build:
      context: ../../
      dockerfile: ./Infra/local_dev/frontend.Dockerfile
    volumes:
      - ../../Frontend:/app
      - frontend_node_modules:/app/node_modules
    ports:
      - "5173:5173"

  mysql:
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
    volumes:
      - mysql_data:/var/lib/mysql

  redis:
    image: redis:7.2-alpine
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"

volumes:
  mysql_data:
  frontend_node_modules:
  redis_data:
  • 소스 코드는 Bind Mount로 연결하고, 무거운 의존성(node_modules, build, .gradle)은 Volume으로 분리
  • /app/build, /app/.gradle 경로를 호스트로부터 격리한다. 호스트와 컨테이너의 빌드 환경 차이로 인한 충돌을 방지한다. 
    • Bind Mount가 호스트 파일을 컨테이너 /app에 덮어 씌우면서 호스트의 build 폴더로 컨테이너 내부로 들어오게 된다.
    • /app/build로 선언된 익명 볼륨이 그 위에 덮어 씌우듯이 경로를 가로챈다.
    • 이로 인해 컨테이너의 /app/build는 호스트 폴더와 연결되지 않는다. 호스트의 빌드 결과물은 컨테이너에 영향을 주지 않고, 컨테이너의 빌드 결과물도 마찬가지이다.

 

Front

FROM node:20-alpine
WORKDIR /app
COPY Frontend/package*.json ./
RUN npm install
COPY . .
# Vite의 경우 외부 접속 허용을 위해 --host 옵션 필요
CMD ["npm", "run", "dev", "--", "--host"]

Back

FROM eclipse-temurin:21-jdk-alpine
WORKDIR /app
# 빌드 도구 캐싱을 위해 설정 파일 먼저 복사
COPY Backend/gradlew .
COPY Backend/gradle gradle
COPY Backend/build.gradle Backend/settings.gradle ./

RUN chmod +x gradlew
RUN ./gradlew --version  # Gradle 미리 내려받기

COPY . .
# 개발 모드로 실행 (Spring Boot 3.x)
CMD ["./gradlew", "bootRun"]
  • --no-daemon
    • docker 컨테이너는 메인 프로세스(PID 1)가 살아있는 동안 유지된다. 해당 옵션을 사용하면 Gradle이 종료될 때까지 프로세스가 foregroud에 머물러 있으므로 docker가 작업 중이라고 인식한다.

 

IntelliJ 혹은 WebStorm에서 WSL 2 접속

Remote Develpment를 통해 원격 환경과 연결할 것이다.

wsl 연결

ubuntu 선택

자신의 환경에 맞춰 리스트업이 되니 그 중 선택하면 된다.

webstrom 버전과 frontend 연동하기 / intellij 버전과 backend 연동하기

이를 통해 WSL 2 내부에 설치를 진행하게 된다.

 

완료되면 각 폴더로 접속 가능해진다.

 

실행

Front의 경우에는 코드를 수정하면 바로 반영이 되기 때문에 컨테이너가 동작 중인 상태에서 개발을 진행하면 된다.

즉, 문제가 없다.

 

Back의 경우에는 IntelliJ에서 개발하듯이 진행하면 된다. 하지만 컨테이너가 동작 중일 때 애플리케이션 실행이 불가능하다. 이는 포트 충돌로 이어진다. 즉, 포트 충돌 문제는 해결하지 못했다. 

우선은, mysql과 redis만 띄우고 로컬(WSL 2)에서 개발을 진행하고 단위 테스트 진행 시에 Backend 컨테이너를 띄워서 테스트하는 방식으로 설계를 변경했다.

 

정리

결국 이는 WSL 2 환경을 통일한 것이며, 백에서는 mysql과 redis만 제공한 것이다.

프론트는 컨테이너가 실행 중이어야 하며 그 상황에서 개발을 해도 바로 반영이 되어 문제가 되지 않는다.

하지만, 백은 빌드하는 과정이 필요하기 때문에 컨테이너와 충돌이 발생하게 된다. 

 

개발 환경에 더 이상 시간을 쏟을 수 없다고 판단하여 이번 프로젝트는 해당 환경 구성으로 진행할 생각이다. WSL 2 환경은 모두 동일하며, JDK 버전을 21로 맞추고 mysql과 redis는 컨테이너로 접속해서 진행하니... 그래도 추후 배포 때 괜찮지 않을까 예상 중이다... (제발)

 

내가 원했던 환경은 컨테이너 위에 개발에 필요한 도구를 설치하고, 로컬이 아닌 컨테이너에 접속해서 내부에서 개발을 진행하는 것이었다. 개발을 내부에서 진행하고 빌드, 디버깅 모두 내부에서 진행하는 방식을 원했다. 그리고 이렇게 해야 개발 환경을 통일하는 것이 의미있는 작업이라고 생각했다.

 

이 부분에 대해서 2차 프로젝트 혹은 이후에 다시 고민해보고 가능한지 알아보도록 하겠다.

지금은 빠르게 CI/CD를 구축하고 배포 환경을 마련하는 것이 급선무이다.

 

내 상태

인프라를 담당으로 혼자 프로젝트에 참여한 것이 처음이라 혼자 머리가 깨져라 고민하고 진행하고 있다... 매우 힘들지만 오기도 생기고 재밌다. 한편으로는 나로 인해 팀원들에게 피해가 갈까봐 책임감이 크고 압박감을 느낀다. 물론 팀원들은 나를 다독여주고 괜찮다고 응원해준다. 우리팀 너무 따숩고 재밌고 최고다. 2차 프로젝트도 같이 하고 싶을 만큼.

최근에 CI/CD 관련해서 특강이 있었고 실습코치님이 "팀에서 인프라를 담당하고 있는 팀원이 있다면 꼭 안아주세요"라고 하셨다. 팀원들이 나를 안아줬는데 그게 생각보다 엄청 힘이 됐다. 흑흑.

'Study > Docker' 카테고리의 다른 글

[Docker] 로컬 개발 환경 세팅(vscode, IntelliJ) (1) - 실패  (1) 2026.01.21
[Docker]Docker Image Layer  (0) 2023.11.17
[Docker]Docker 사용하기 2 (공유)  (0) 2023.02.11
[Docker]Docker 사용하기  (0) 2023.02.11
[Docker]명령어  (0) 2022.10.18