Docker 기술 블로그 최신 글
Docker 컨테이너를 이용한 개발 환경, 빌드와 서비스 배포 사례를 다룬 회사 기술 블로그 글입니다.
Docker 관련 최신 기술 블로그 글
JVM heap은 멀쩡한데 왜 메모리가 터질까? — Docker 환경 네이티브 메모리 삽질기 (Part 2)
여기어때 기술블로그 - Medium2026년 7월 1일JVM heap은 멀쩡한데 왜 메모리가 터질까? — Docker 환경 네이티브 메모리 삽질기 (Part 1)
여기어때 기술블로그 - Medium2026년 7월 1일웹개발팀 모노레포 — 1) 파이프라인 구축
웹개발팀 모노레포 — 1) 파이프라인 구축 TL;DR 중고나라 웹개발팀은 멀티레포를 모노레포로 전환하며 파이프라인을 구축했습니다. 의존성 설치 시간을 줄이기 위해 pnpm store 캐시를 설정했습니다. Turborepo + Bitbucket Pipelines 기반으로 변경된 앱만 추출해 빌드/배포했습니다. Docker 빌드 시, 앱별 필요한 의존성만 포함해 이미지 크기와 빌드/캐시 효율을 높였습니다. 서론 안녕하세요, 중고나라 웹개발팀 홍승연입니다. 중고나라 웹개발팀은 기존 멀티레포로 운영하던 프로젝트를 모노레포로 전환하고 있습니다. 모노레포는 여러 프로젝트를 하나의 리포지토리에서 관리하는 방식으로, 코드 중복을 줄이고 공통 모듈을 쉽게 재사용할 수 있게 합니다. 또한 빌드와 배포를 일관된 파이프라인으로 묶어 개발 생산성을 높여줍니다. 기존에는 각 프로젝트가 별도의 리포지토리에서 관리되어 공통으로 사용하는 코드를 재사용하기 어려웠고, 프로젝트마다 별도의 설정 및 관리가 필요했습니다. 이에 공통 페이지는 웹뷰로 배포해 여러 서비스에서 iframe으로 연동했지만, iframe 특성상 UI가 제한적이고 확장성이 낮다는 문제가 있었습니다. 또한 별도 프로젝트로 관리하다 보니 관리포인트가 늘어나면서 팀 내 피로감이 증가하고 있었습니다. 이러한 문제를 해결하기 위해 모노레포로 전환을 결정했고, 크게 아래 4가지 작업을 차례대로 진행하였습니다. 파이프라인 구축 — 웹 서비스 배포를 위해 CI/CD 파이프라인 구축 Husky 세팅 — Husky로 Git Hook을 자동화해, 팀 전체가 일관된 개발 규칙을 준수 인증 통합 — 서비스별로 분산된 인증 로직 통합 도메인 모듈 분리 — 도메인별 모듈화로 재사용성 강화 이 글은 첫 번째 주제인 “파이프라인 구축”에 대해 다루며, 나머지 주제들도 순차적으로 공유할 예정입니다. 파이프라인 구축 먼저 파이프라인을 어떻게 구축했는지 설명하겠습니다. 중고나라는 여러 웹 애플리케이션을 운영합니다. 모노레포로 이관하면서 배포 대상이 늘었고, 공통 패키지 한 번만 바꿔도 여러 앱이 연쇄적으로 설치/빌드됩니다. 그래서 모노레포 파이프라인은 빨라야 했습니다. 따라서 파이프라인 구축시 속도 최적화를 위해 세 가지를 중점적으로 고민했습니다. pnpm store 캐시를 통해 의존성 설치 시간 최적화 의존성이 변경된 앱만 필터링해 빌드/배포 Docker 이미지 빌드 시 앱별 필요한 의존성만 포함 아래에서 각 항목의 구현 방법을 차례대로 설명하겠습니다. 1. pnpm store 캐시로 의존성 설치 최적화 모노레포 CI/CD에서 시간이 오래 걸리는 단계 중 하나가 의존성 설치입니다. 매 빌드마다 새로 설치하지 않도록 다운로드한 의존성을 캐시했습니다. 일반적으로는 node_modules를 캐시하지만, 모노레포에서는 pnpm을 쓰고 있으므로 pnpm store(전역 스토어)를 캐시했습니다. 그 이유는 아래와 같습니다. pnpm store를 캐시하는 이유? pnpm은 다른 패키지 매니저와 달리 3단계 링크 구조를 사용합니다. 전역 스토어: 모든 패키지를 저장하는 실제 데이터 저장소 가상 스토어(node_modules/.pnpm): 워크스페이스별 링크 관리 실제 node_modules: 전역 스토어를 가리키는 하드링크/심볼릭 링크 집합 pnpm은 패키지 파일을 content-addressable 방식으로 전역 스토어에 보관하고, 각 워크스페이스의 node_modules는 그 스토어를 링크로만 재구성합니다. 즉, 전역 스토어만 보존되면 재설치는 대부분 링크 재구성으로 끝나고, 불필요한 다운로드를 크게 줄일 수 있습니다. 반대로 node_modules 자체 캐시는 경로/OS 변경, 네이티브 바이너리 차이 등에 취약해 쉽게 무효화되거나 오염될 수 있습니다. 이는 pnpm의 링크 구조와 중복 제거 메커니즘 때문입니다. pnpm 공식 이슈에 따르면, node_modules를 캐시할 때 두 가지 문제가 발생할 수 있습니다. node_modules 대신 pnpm store만 캐시해야 하는 이유 링크 구조 손상 위험: CI에서 압축/복
중고나라 기술 블로그2025년 9월 8일디자인 도구 Penpot(펜팟) 설치부터 활용까지
디자인 도구 Penpot(펜팟) 설치부터 활용까지 안녕하세요? Penpot(펜팟)을 소개하고자 합니다. Docker로 셀프 호스팅 구성하기 Penpot은 Elestio와 Docker로 설치가 가능합니다. 항목 설명 Docker 컨테이너(소프트웨어를 실행하는 데 필요한 모든 파일, 라이브러리, 설정 파일 등을 포함하는 패키지) 기반의 오픈소스 가상화 시스템 Docker Desktop Windows 및 macOS 운영 체제에서 Docker를 쉽게 설치하고 사용할 수 있게 해주는 애플리케이션 WSL Windows 운영 체제에서 Linux 커널을 실행할 수 있게 해주는 기능 WSL2 활성화 후 Windows에 Linux를 설치 Windows - PowerShell - 관리자로 실행을 시켜줍니다. PowerShell WSL 기능 활성화 wsl --install 시스템 재부팅 Restart-Computer WSL 버전을 WSL2로 설정 wsl --set-default-version 2 사용 가능한 배포판 목록 확인 wsl --list --online 원하는 Linux 배포판 설치 wsl --install -d Ubuntu WSL에 설치된 배보판 목록 wsl --list --verbose 설치한 Ubuntu 배포판 실행 wsl Docker Desktop 설치 및 WSL2 설정 Docker Desktop 공식 홈페이지에서 [Download for Windows]를 클릭해 다운로드하고 설치합니다. Docker Desktop 실행 후 작업 표시줄의 숨겨진 아이콘 메뉴에서 Docker 아이콘을 선택합니다. 아이콘을 마우스 오른쪽 단추로 클릭해 Docker 명령 메뉴를 표시하고 “설정”을 선택합니다. 설정 > 일반에서 “WSL 2 기반 엔진 사용”이 선택되어 있는지 확인합니다. 설정 > 리소스 > WSL 통합으로 이동해 Docker 통합을 사용하도록 설정하려는 설치된 WSL 2 배포판에서 선택합니다. Docker가 설치되었는지 확인하려면 PowerShell에서 확인을 합니다. docker --version Docker가 이미지를 실행할 수 있도록 올바르게 설치되었는지 아래와 같은 명령을 PowerShell에서 실행합니다. docker run hello-world Penpot 설치/시작하기 Docker Compose는 Docker 컨테이너들을 정의하고 실행하는 도구인데, 이를 정의하는 docker-compose.yaml 파일을 Penpot GitHub 저장소에서 다운로드해 실행할 수 있습니다. docker-compose.yaml 파일만 다운로드하면 됩니다. 설치한 Ubuntu에서 docker-compose.yaml 파일을 다운로드 Windows의 WSL2에서 설치한 Ubuntu를 실행해 다운로드합니다. docker-compose.yaml를 설치할 파일 경로는 따로 신경 쓰실 필요 없어요~! wget: 인터넷에서 파일을 다운로드할 때 사용되는 명령 줄 도구 wget https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml - 실질적으로 Windows에서 Ubuntu 가상 시스템을 실행했기 때문에 파일 경로는 파일 탐색기를 열어보면 확인하실 수 있습니다. (Ubuntu 실행 명령어에서 `ll`을 쳤을 때 실제 경로예요~!)  Penpot 서비스 실행하기 항상 Docker Compose를 통해 명령줄 도구(CLI)를 실행할 땐 Docker Desktop이 실행되고 있어야 합니다. Ubuntu에서 Penpot 서비스를 실행하고, http://localhost:9001로 접속을 합니다. 포트 9001은 wget으로 설치한 docker-compose.yaml 파일에 기본으로 설정되어 있고, 변경해서 사용할 수 있어요~! docker compose -p penpot -f docker-compose.yaml up -d Penpot 서비스 실행 중지 docker compose -
글루시스 기술 블로그2024년 7월 31일Airflow 환경 Docker compose로 containerization하기
안녕하세요, G플레이스데이터개발 팀에 올 하반기 신입으로 합류하게 된 양은석입니다. 비전공자인 저에게는 데이터 엔지니어링(DE)이 생소하고 낯설게 느껴졌는데요, DE의 핵심 도구 중 하나인 Airflow를 이해하게 된 과정과 개발 환경 설정을 통해 팀 생산성에 기여한 경험, 그리고 그 결과를 공유드리고자 이 글을 작성하게 되었습니다. 왼쪽부터 기존 로컬 환경, 새로 구축한 도커 환경, 그리고 쿠버네티스 기반 프로덕션 환경을 도식화했습니다. 이번 과제의 중심 목표는 Airflow 환경을 Docker 기반으로 구축하고, 개발 및 디버깅이 가능하도록 IDE 환경을 설정하는 것입니다. 기존에는 개발 환경과 배포 환경에서 Airflow의 실행 방식이 서로 달라 환경 변수나 설정 값이 주입되는 방식에 차이가 있었고, 그 간극 때문에 “분명 내 로컬에서는 되는데 배포 했더니 문제가 발생하는” 상황을 마주할 위험이 존재했습니다. 뿐만 아니라 각각의 로컬 개발 환경이 Python 가상 환경 도구(e.g. Miniconda)로 관리되고 있었지만 종종 이격이 발생했으며 OS 차이에 따른 문제도 심심찮게 일어났습니다. 하지만 Docker 환경을 이용하면 Local 환경의 변경 영향을 없애고 항상 동일한 형상에서 멱등성있게 테스트를 수행 가능하며, requirements.txt와 같이 Python 환경에 수정 사항이 발생한 경우 변경점에 대해서만 격리된 환경에서 검증 가능합니다. 따라서 K8S로 배포 및 운영되는 프로덕션 환경과 유사하면서 서로 동일한 환경에서 개발 및 테스트가 가능하도록 Airflow를 컨테이너화하는 작업이 필요했습니다. 이제 Airflow가 어떻게 구성되어 있고, 왜 containerization을 위해 Docker compose를 사용하였으며, 개발 환경은 어떤 방식으로 설정했는지 차례대로 살펴보도록 하겠습니다. Apache Airflow Apache Airflow는 배치 단위의 작업을 스케줄링 및 모니터링할 수 있는 워크플로 개발 도구입니다. 저희 팀은 테라바이트 단위로 흐르는 Place data를 추출, 변환 및 적재하는 ETL pipeline을 효율적으로 운영하기 위하여 Airflow의 힘을 빌리고 있습니다. Airflow는 최소 작업 단위인 task가 서로 의존성을 가지고 DAG(Directed acyclic graph)를 구성하며 일정 시간마다, 혹은 특정 조건에 의해 트리거될 때마다 실행되는 방식으로 작동합니다. 시작점으로 Airflow의 컴포넌트를 가볍게 짚어보면서 컨테이너를 어떻게 구성할지 밑그림을 그려볼 수 있습니다. 먼저, Scheduler는 이름에서 유추할 수 있듯 DAG의 실행을 스케줄링 및 오케스트레이션하는 컴포넌트입니다. DAG들의 지휘관 역할을 하면서 Metadata database에 여러 정보나 실행 상태를 저장하고, 파이썬 파일 형태로 존재하는 DAG의 디렉토리를 바라보며 일정 시간마다 변경을 감지합니다. 다음으로 Executor는 Scheduler 내부에 존재하면서 task를 실제로 수행하는 Worker를 만들고 명령합니다. 마지막으로 Webserver는 UI를 통해 DAG가 잘 돌고 있는지 모니터링할 수 있도록 도와줍니다. 구성 요소 간의 연결 관계를 파악할 때는, 만약 그 요소가 존재하지 않는다면 무슨 일이 일어날 지 상상해보는 것이 도움이 됩니다. Airflow architecture overview 이 때 어떤 Executor를 선택하느냐에 따라 Worker는 쓰레드나 프로세스가 될 수도 있고, pod이 될 수도 있기 때문에 컨테이너의 구성 방식이 바뀝니다. 예를 들어 SequentialExecutor는 하나의 작업을 단일 프로세스에서 순차적으로 실행하므로, Scheduler와 Worker의 역할을 수행하는 단일 컨테이너로 충분합니다. 반면, CeleryExecutor는 Celery라는 분산 작업 큐 시스템을 이용하여 다수의 Worker가 작업을 병렬로 처리하므로 Worker가 독립 컨테이너로 존재해야 합니다. 엔지니어는 항상 트레이드오프를 고려해야 하기 때문에 개발 환경과 운
네이버 플레이스 개발 블로그 - Medium2023년 12월 4일Datadog - "저는 모니터링 요정입니다. ✋🏻"
📖 Table of Contents 해당 포스팅은 아래의 시리즈로 구성되어 있습니다. 시리즈대로 포스팅을 읽어주세요 💚 Teamcity 를 사용한 Build Process 구성 방법 Teamcity로 Docker Container Image…
올리브영 테크블로그2022년 6월 22일ECR - "저도 배포요정입니다 ✋🏻"
📖 Table of Contents 해당 포스팅은 아래의 시리즈로 구성되어 있습니다. 시리즈대로 포스팅을 읽어주세요 💚 Teamcity 를 사용한 Build Process 구성 방법 Teamcity로 Docker Container Image…
올리브영 테크블로그2022년 6월 15일Alpine/Debian 기반 Docker 이미지 간 cp 명령 동작 차이
안녕하세요. 인프랩 DevOps Engineer 선비입니다! 오늘은 Docker를 다루며 발견하게 된 Alpine 기반 이미지의 cp 명령과 Debian 또는 Ubuntu 기반 이미지의 cp 명령의 동작 차이점을 소개해드리겠습니다. Docker…
tech.inflab.com2022년 5월 24일Teamcity - "이제부터 배포요정은 접니다 ✋🏻"
📖 Table of Contents 해당 포스팅은 아래의 시리즈로 구성되어 있습니다. 시리즈대로 포스팅을 읽어주세요 💚 Teamcity 를 사용한 Build Process 구성 방법 Teamcity로 Docker Container Image…
올리브영 테크블로그2022년 5월 3일