"웹 개발부터 배포, 운영까지 (2/8) — Docker는 왜 환경 통제의 출발점일까"

Docker의 핵심은 편하게 배포하는 도구라는 데 있지 않다. 더 중요한 역할은 "이 앱이 어떤 조건에서 돌아가는가"를 코드와 함께 묶어 두는 데 있다.

핵심 요약

  • Docker는 애플리케이션이 실행되기 위한 환경을 이미지로 고정하고, 그 이미지를 컨테이너로 실행하게 해 준다.
  • 입문자 관점에서 Docker의 가장 큰 장점은 배포 자동화보다 "로컬과 운영 차이를 줄인다"는 데 있다.
  • 이미지, 컨테이너, 네트워크, 볼륨을 구분해서 이해해야 Docker를 단순 명령어 모음이 아니라 운영 도구로 볼 수 있다.
  • Docker가 모든 문제를 해결하지는 않지만, 적어도 "내 컴퓨터에서는 됐는데"라는 변명을 줄이는 출발점은 된다.

Docker는 무엇을 고정하려고 등장했는가

앞선 글에서 본 것처럼 로컬과 운영은 실행 조건이 다르다. OS, 런타임 버전, 설치된 패키지, 시스템 라이브러리, 파일 경로, 시작 명령이 조금만 달라도 결과가 달라질 수 있다.

Docker는 이 차이를 줄이기 위해 등장했다. 애플리케이션이 필요로 하는 실행 조건을 이미지라는 형태로 묶고, 그 이미지를 어디서든 비슷한 방식으로 실행하자는 것이다. 즉 Docker는 "코드"만 옮기는 것이 아니라 "코드가 기대하는 실행 환경"까지 함께 옮기게 해 준다.

이 점 때문에 Docker는 배포 도구이기 전에 재현 도구다.

이미지와 컨테이너는 왜 구분해서 이해해야 할까

Docker를 배울 때 가장 먼저 헷갈리는 것이 이미지와 컨테이너다. 둘은 비슷해 보이지만 역할이 다르다.

이미지는 실행에 필요한 파일 시스템과 설정을 묶은 정적인 청사진이다. 어떤 베이스 이미지를 썼는지, 어떤 패키지를 설치했는지, 어떤 명령으로 시작할지를 포함한다. 반면 컨테이너는 그 이미지를 실제로 실행한 살아 있는 인스턴스다.

이 구분이 중요한 이유는 운영 사고의 위치를 나눠 보게 만들기 때문이다.

  • 이미지 문제: 잘못된 런타임 버전, 누락된 패키지, 빌드 단계 실수
  • 컨테이너 문제: 잘못된 환경 변수, 포트 충돌, 실행 중 상태 이상

즉 "Docker가 안 된다"가 아니라, 이미지 설계 문제인지 컨테이너 실행 문제인지 분리해서 봐야 한다.

왜 입문자에게도 Docker가 필요한가

작은 개인 프로젝트에서는 굳이 Docker 없이도 서버에 직접 Node를 설치해 배포할 수 있다. 그래서 초반에는 Docker가 과한 도구처럼 보이기도 한다. 하지만 바로 그 단순한 프로젝트에서조차 Docker의 효과는 분명하다.

첫째, 새 컴퓨터나 새 서버에서 같은 환경을 다시 만들기 쉬워진다. 둘째, 팀원이 생기면 "버전 뭐 써요?" 같은 질문을 줄일 수 있다. 셋째, 운영 이전에 로컬에서도 배포에 가까운 조건을 흉내 낼 수 있다.

특히 학습 단계에서는 Docker가 실무를 어렵게 만드는 도구가 아니라, 오히려 환경 차이를 눈에 보이게 해 주는 교재 역할을 한다. 로컬에 숨어 있던 의존성이 이미지 설계 단계에서 드러나기 때문이다.

네트워크는 왜 Docker 이해의 핵심인가

초보자는 Docker를 단순히 앱 하나 띄우는 도구로 생각하기 쉽지만, 실제 서비스는 보통 앱 하나로 끝나지 않는다. 프론트엔드, 백엔드, 데이터베이스, 캐시, 프록시가 각각 분리될 수 있고, 서로 통신해야 한다.

Docker 네트워크는 이 서비스들을 어떻게 연결할지 정하는 층이다. 같은 네트워크 안의 컨테이너는 서비스 이름으로 서로를 찾을 수 있고, 외부에 노출할 포트와 내부 통신 포트를 구분할 수 있다.

이것이 중요한 이유는 운영 구조를 더 정확히 배우게 해 주기 때문이다. 로컬에서 localhost 하나로 모든 것이 붙어 있던 세계에서 벗어나, 어떤 서비스가 외부에 열리고 어떤 서비스는 내부에서만 통신해야 하는지 감각이 생긴다.

즉 Docker 네트워크는 단순 연결 설정이 아니라, 서비스 경계를 학습하는 장치다.

볼륨은 왜 "컨테이너는 사라져도 데이터는 남아야 한다"를 말하는가

컨테이너는 기본적으로 일시적인 실행 단위다. 다시 만들 수 있고, 교체할 수 있으며, 죽었다가 재시작될 수 있다. 이 특성은 좋지만, 그 안에 데이터를 그냥 저장하면 컨테이너 생명주기와 함께 날아갈 수 있다.

그래서 Docker는 볼륨을 통해 지속 데이터를 분리한다. 애플리케이션 실행 환경은 컨테이너가 맡고, 유지해야 할 데이터는 볼륨이나 외부 스토리지가 맡는 구조다.

이 분리는 운영 사고를 줄여 준다. 앱 배포와 데이터 보존을 같은 층에서 처리하지 않게 되기 때문이다. 나중에 Supabase 같은 관리형 데이터 계층을 쓸 때도 같은 원리가 반복된다. 애플리케이션은 교체 가능하지만, 데이터는 더 엄격히 다뤄야 한다.

Docker가 해결해 주지 않는 것들도 있다

Docker를 쓰면 모든 운영 문제가 사라진다고 오해하기 쉽다. 하지만 Docker는 환경 통제 도구이지, 서비스 품질 전체를 보장하는 마법 상자가 아니다.

Docker만으로 해결되지 않는 대표 문제는 다음과 같다.

  • 애플리케이션 로직 오류
  • 잘못된 인증/권한 설계
  • 느린 쿼리와 비효율적 데이터 처리
  • 외부 API 실패 대응 부족
  • 로그, 모니터링, 알림 부재

즉 Docker는 기반을 단단하게 해 주지만, 그 위에 올라가는 아키텍처와 운영 습관까지 대신해 주지는 않는다. 그래서 이후 편들에서 API 계층, 데이터 경계, 배포 구조를 따로 다룬다.

학습 순서로 보면 Docker 다음에 무엇이 이어질까

Docker를 이해하면 운영을 더 구조적으로 보게 된다. 애플리케이션은 실행 단위이고, 데이터는 분리돼야 하며, 서비스 간 통신은 네트워크 경계 위에서 이뤄진다는 점이 보이기 때문이다.

그 다음 단계는 "그 실행 환경 안에서 무엇을 어떻게 붙일 것인가"다. API를 직접 호출할지, MCP 같은 계층을 둘지, vibe-coding으로 빠르게 붙인 기능을 어디까지 신뢰할지 같은 질문이 나온다. 결국 환경 통제 다음에는 외부 의존성 통제가 필요해진다.

그래서 Docker 다음 글은 환경 안으로 들어오는 API와 도구 연결의 문제를 다룬다.

참고 자료

  • docs/blog_series_webdev_ops_design.md
  • docs/blog_series_learning_format_v3.md
  • sources/260519_webdev_ops_sources.md
  • Docker Docs — What is Docker?: https://docs.docker.com/get-started/docker-overview/
  • Docker Docs — What is an image?: https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-an-image/
  • Docker Docs — What is a container?: https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-container/
  • Docker Docs — Networking: https://docs.docker.com/network/
  • Docker Docs — Volumes: https://docs.docker.com/engine/storage/volumes/

이 글은 웹 개발부터 배포, 운영까지 시리즈의 2/8편이다.

댓글

이 블로그의 인기 게시물

"LLM 핵심 학습 (1/6) — 기본: 토큰화·임베딩·어텐션·위치 인코딩"

"LLM 핵심 학습 (2/6) — 파인튜닝: LoRA·QLoRA·증류·Adapter"

"ML 기초 학습 (1/9) — 머신러닝과 sklearn: 학습의 좌표계"