Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ refactor: Docker Compose: 개발 환경, 로컬 환경 작성 (6) #43

Draft
wants to merge 73 commits into
base: main
Choose a base branch
from

Conversation

Jo-Minseok
Copy link
Collaborator

@Jo-Minseok Jo-Minseok commented Feb 6, 2025

🔨 테스크

이전 PR 보러 가기

작업 사유

  • Docker 이미지를 구성함에 따라 애플리케이션들의 컨테이너를 하나 하나 생성하기에는 어려움이 존재하고, 어떤 환경(운영, 로컬, 개발)에서 어떤 Dockerfile을 사용해야 하는지 확인하기 어렵다.

  • 도커의 러닝 커브가 심한 편이다 보니 최대한 사용자에게 추상화하여 제공하고자 작업을 수행했다.

  • 추후 서비스 운영 비용의 한계로 인해 서비스를 종료했을 때 로컬에서 동작해볼 수 있도록 구현해야 포트폴리오로 의미있을 것이라 판단하여 작업을 수행했다.

  • 현재는 프론트엔드 기능 개발 시 프로덕션(운영) 서버에 요청을 보내어 기능을 테스트한다.
    네이버 부스트 캠프 정규 시즌이 끝났기에 서비스 운영 입장에서 본다면, 프론트엔드 기능 테스트를 운영 서버에 직접 적용하면서 API 테스트를 하는 것은 올바르지 않다고 판단했다.
    개발 서버를 따로 두기에는 인스턴스 비용이 2배로 증가하고, 유지 보수하는데 있어서 비용 소모가 클 것이라 판단했다.
    프론트엔드 개발을 할 때, 로컬에 백엔드 서버가 켜져있다면, 로컬 서버를 이용할 경우 격리된 환경에서 기능 테스트가 가능할 것이고, DB 데이터도 본인이 직접 조작할 수 있기에 훨씬 안전할 수 있다.
    image

  • 로컬에서 백엔드 서버를 동작하기 위해서 프론트엔드 개발자 입장에서는 백엔드 서버 동작 방식을 이해해야 한다. 하지만, Docker Compose로 수행할 경우 추상화되기 때문에 필요가 없어진다.

  • 백엔드 개발도 마찬가지로, 기존에 개발 방식은 로컬에 MySQL, Redis 서버를 Docker로 동작하여 인프라를 모방했었는데, 컨테이너를 만들때마다 DB 환경 변수를 입력해야 하고, Redis도 ACL 설정을 해야해서 번거로웠다. 또한 환경 변수도 백엔드 개발자마다 다르게 대입하는 문제가 있었어서 맞추기 어려웠다. 실제 환경과 개발 환경의 차이가 커서 제대로 동작하는 지 확인하기 어려웠다.

NGINX 배치해야 할까?

  • 정적 이미지 제공을 위해서는 개발 환경에도 배치해야 한다고 판단했다.
  • 최대한 운영 환경과 비슷하게 맞추고자 HTTPS는 CA에게 인증 받지 않은 자체 생성 SSL을 발급하도록 구현했다.

빌드 컨텍스트 외부 파일 포함 불가

  • Docker의 빌드 컨텍스트는 Dockerfile의 바로 상위 디렉토리까지만 포함된다. 더 상위 디렉토리에 있는 데이터들은 context를 포함하고자 하는 상위 디렉토리 경로로 설정해주고 Dockerfile 경로를 구체적으로 설정해야 한다.

Depends_on 옵션

Docker Compose에는 Depends_on 옵션이 있다. condition을 작성하지 않으면 단순 실행의 순서만 결정하기에 DB -> APP 순서로 단순 시작만 한다.
단순 시작만 하기에 DB가 완벽하게 준비 됐지 않았을 경우에 APP이 실행되는 문제가 있었다.
Docker Compose를 더 학습해보니 condition과 healthcheck를 사용하면 DB가 완벽하게(SQL문 초기화, DB 접속 가능 상태)가 되었을 때, APP을 시작하게 할 수 있었다.
이를 이용하여 Redis와 DB 초기화 시 APP을 구동하게 하여 표준 에러 출력을 전부 없앴다.

Docker Compose Watch 옵션

Docker Compose에 Watch 옵션을 사용하면 Hot Reload 방식을 모방할 수 있었다.
그래서 개발 환경 Docker Compose에는 프론트엔드 코드, 백엔드 코드를 Watch하게 하여 Vite와 NestJS의 Watch 문제를 해결하려 시도했지만, 파일 변경을 여전히 탐지하지 못 했다.
Polling 을 사용하기에는 CPU 사용량이 증가하기에 노트북 사용자들에게는 단점이 될 수 있어 해결하려 했다.

Vite 같은 경우 Volumes 디렉토리 경로를 프로젝트가 아닌 프로젝트 내 src로 설정해야 HMR 적용이 가능하다. 하지만, WSL 고질병 문제로 HostOS에서 바꿔도 적용이 안됨 -> 백엔드에서 이미 Polling을 사용하기에 프론트도 Vite Polling 사용하게 변경

NodeJS 같은 경우 Nodemon으로 reload를 탐지해서 HostOS에서 바꿔도 적용이 안 되기에 Polling을 사용

파일 변경을 탐지하고 강제로 실행 환경에 적용하려면 action을 rebuild로 진행하여 이미지를 아예 재빌드해야 한다.
코드 변경이 적용되기는 하지만 이미지 빌드 속도 + 컨테이너 실행 속도가 느리다 보니 반영되는데 너무 느렸다.
개발 생산성이 상당히 떨어질 것으로 판단했다.

Watch를 이용하여 NGINX의 설정 파일(nginx.conf)가 변경되었을 때, 컨테이너를 자동으로 rebuild되게 구현했다.
프론트엔드 프로젝트, 백엔드 프로젝트의 package.json에 의존성이 추가되면 자동으로 rebuild되게 구현했다.

개발 환경 컨테이너 내부 작업 vs 외부 작업 HostOS Volume 연결

개발 환경을 구축할 때 원래라면 컨테이너 내부에서 작업하고 Volume으로 백업해두는 방식을 사용한다고 봤다.
하지만, 개발 환경이 자주 바뀌는 (데스크탑 <-> 노트북) 경우에는 Volume을 이동하기에는 도커 러닝 커브가 존재한다.
단순 HostOS의 프로젝트 디렉토리만 다른 환경으로 가져가서 Compose를 동작하게 하면 개발 환경 변화에도 더 쉽게 대응할 수 있었다.

환경 설명

  • PROD: 아직 Docker Compose 구현은 안 됐으나, 클라우드 인스턴스에서 돌아갈 환경
  • LOCAL: 포트폴리오 환경으로 PROD의 로컬 버전 (코드 변경시 rebuild 외에 적용 안 됨)
  • DEV: 개발 환경용 (코드 변경 시 자동 적용 시작)

HostOS Volume 시 node_modules도 연동되는 문제 발생

  • 명기님과 개발 환경을 사용해봤을 때, 불편한 점이 있었다. 기존에는 client/src를 volume으로 연결하게 했었는데, 이럴 경우 src 바깥의 프로젝트 파일이 추가,변경,삭제가 되었을 때 적용이 안 되는 문제가 있었다.
  • client 자체를 volume으로 설정하면 호스트 OS에 있는 node_modules가 Container 내의 node_modules와 연동된다. HostOS가 우선이기에 Container 내에 있는 node_modules가 호스트 OS에 맞춰진다. 이러면 멀티 스테이징 빌드를 사용한 의미가 없어진다. 또한, 프론트엔드 라이브러리중 OS를 타는 라이브러리가 있었다. rollup 라이브러리였고, window에서 받은 라이브러리가 linux에서 동작하지 않는 문제가 있었다.
  • client는 volume으로 연결하지만 node_modules는 container에서 개별 volume으로 두게 하여 HostOS와 Volume 연결이 안 되게 구성했다.

TANSTACK 안 뜨는 문제

프론트 환경 변수로 NODE_ENV에 DEV를 입력했더니 TANSTAK이 안 뜨는 문제가 있었다. 프론트 환경 변수는 @jungmyunggi 님과 페어프로그래밍 중 필요없다는 것을 확인하여 제거했다.

📋 작업 내용

  • PM2 제거
  • 개발 환경 Docker Compose 작성
  • 로컬 환경 Docker Compose 작성
  • 개발, 로컬 환경 공통 인프라 Docker Compose 작성
  • 개발 환경 이미지 제공용 NGINX 추가
  • 개발 환경 NestJS Watch 안 되는 문제 해결
  • 개발 환경 Vite Watch 안 되는 문제 해결

📷 스크린 샷(선택 사항)

image

Jo-Minseok and others added 23 commits February 6, 2025 01:42
@Jo-Minseok Jo-Minseok added the 🔧 Chore 세팅 관련 label Feb 6, 2025
@Jo-Minseok Jo-Minseok self-assigned this Feb 6, 2025
@Jo-Minseok Jo-Minseok marked this pull request as draft February 6, 2025 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔧 Chore 세팅 관련
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants