새 프로젝트에 합류한 첫날, 팀장이 건넨 저장소를 내려받아 실행 버튼을 누릅니다. 그런데 에러가 쏟아집니다. 파이썬 버전이 다르고, 데이터베이스가 안 깔려 있고, 어떤 라이브러리는 설치조차 되지 않습니다. 옆자리 동료의 노트북에서는 멀쩡히 돌아가는 그 프로그램이, 내 컴퓨터에서는 요지부동입니다.
개발자라면 누구나 겪는 이 장면의 이름이 바로 \"제 컴퓨터에선 되는데요(It works on my machine)\" 문제입니다. Docker(도커)는 정확히 이 문제를 없애기 위해 태어난 도구입니다. 오늘은 코드를 한 줄도 몰라도 이해할 수 있게, 도커가 무엇이고 왜 이렇게까지 널리 쓰이게 되었는지 차근차근 풀어보겠습니다.
프로그램을 '통째로 포장'하는 기술
도커를 이해하는 가장 쉬운 비유는 컨테이너 화물선입니다. 예전에는 항구에서 짐을 옮길 때 자루, 상자, 통을 제각각 실었습니다. 크기도 모양도 달라 배에 싣고 내리는 데 며칠이 걸렸죠. 그런데 세상의 모든 화물을 똑같은 규격의 쇠 상자(컨테이너)에 담기로 약속하자, 배든 기차든 트럭이든 상자만 옮기면 되는 시대가 열렸습니다.
도커도 똑같습니다. 프로그램 하나가 돌아가려면 코드뿐 아니라 특정 버전의 언어, 여러 라이브러리, 설정 파일, 환경 변수가 전부 맞아떨어져야 합니다. 도커는 이 모든 것을 하나의 '컨테이너'에 통째로 포장합니다. 그러면 내 노트북이든, 동료의 맥이든, 회사의 리눅스 서버든, 그 상자만 실행하면 어디서나 똑같이 동작합니다.
도커의 핵심 약속은 단 하나입니다. \"한 번 만들면, 어디서나 똑같이 돌아간다.\"
가상머신과는 무엇이 다를까
\"예전에도 가상머신(VM)이라는 게 있지 않았나요?\"라고 물을 수 있습니다. 맞습니다. 가상머신도 격리된 환경을 만들어 줍니다. 다만 방식이 무겁습니다. 가상머신은 내 컴퓨터 안에 운영체제(OS)를 통째로 하나 더 설치하는 방식입니다. 윈도우 안에 리눅스 한 대를 새로 켜는 셈이니, 부팅에 수십 초가 걸리고 메모리도 몇 기가바이트씩 잡아먹습니다.
도커 컨테이너는 훨씬 가볍습니다. OS 전체를 복제하지 않고, 이미 돌아가고 있는 운영체제의 핵심(커널)을 여러 컨테이너가 나눠 쓰기 때문입니다. 그 덕분에 컨테이너는 1초 안에 켜지고, 노트북 한 대에서 수십 개를 동시에 띄워도 버겁지 않습니다. 무거운 아파트 한 채가 가상머신이라면, 도커는 필요한 방만 뚝 떼어 쓰는 셰어하우스에 가깝습니다.
이미지와 컨테이너, 그리고 세 단어
도커를 쓰다 보면 자주 마주치는 세 단어가 있습니다. 요리에 빗대면 한 번에 이해됩니다.
| 도커 용어 | 요리 비유 | 뜻 |
|---|---|---|
| Dockerfile | 레시피 | 무엇을 어떻게 담을지 적은 설명서 |
| 이미지(Image) | 밀키트 | 레시피대로 미리 포장해 둔 완제품 |
| 컨테이너(Container) | 차려낸 요리 | 이미지를 실제로 실행한 상태 |
레시피(Dockerfile)를 한 번 써 두면, 그것으로 밀키트(이미지)를 찍어냅니다. 이 밀키트는 팀원 누구에게나 똑같이 복제해 나눠 줄 수 있습니다. 그리고 밀키트를 데워 접시에 올리는 순간, 실제로 돌아가는 컨테이너가 됩니다. 하나의 이미지에서 컨테이너를 열 개, 백 개 찍어낼 수도 있습니다.
간단한 Dockerfile은 이렇게 생겼습니다. 짧지만 위의 흐름이 그대로 담겨 있습니다.
# 파이썬 3.12가 미리 깔린 밀키트에서 시작
FROM python:3.12-slim
# 작업 폴더를 만들고 그 안으로 이동
WORKDIR /app
# 필요한 라이브러리 목록을 복사하고 설치
COPY requirements.txt .
RUN pip install -r requirements.txt
# 내 코드 전체를 상자 안으로 복사
COPY . .
# 상자가 켜지면 이 명령을 실행
CMD ["python", "app.py"]실행도 명령 두 줄이면 충분합니다. 첫 줄로 밀키트를 굽고, 둘째 줄로 요리를 차려냅니다.
# 레시피대로 'myapp'이라는 이미지를 만든다
docker build -t myapp .
# 그 이미지를 실행해 컨테이너를 띄운다 (8080 포트로 연결)
docker run -p 8080:80 myapp왜 회사들이 앞다퉈 쓸까
도커가 빠르게 표준이 된 데는 현실적인 이유가 있습니다. 첫째, 신입의 첫 출근이 편해집니다. 예전에는 개발 환경을 맞추는 데만 하루가 걸렸지만, 이제는 명령 한 줄로 팀과 똑같은 환경이 통째로 내려받아집니다. 둘째, 내 노트북에서 테스트한 그 상자를 그대로 서버에 올리기 때문에, 배포 후에야 터지는 사고가 크게 줄어듭니다.
셋째, 프로그램마다 방을 따로 쓰니 서로 간섭하지 않습니다. A 서비스는 파이썬 3.9가, B 서비스는 3.12가 필요해도 각자의 컨테이너 안에서 평화롭게 공존합니다. 한 대의 서버에 여러 서비스를 촘촘히 올리면서도 충돌 걱정이 없으니, 서버 비용도 아낄 수 있습니다.
물론 도커가 만능은 아닙니다. 컨테이너 수십, 수백 개를 한꺼번에 관리하려면 쿠버네티스 같은 또 다른 도구가 필요하고, 저장 공간이나 네트워크를 다루는 대목에서는 배울 것이 제법 많습니다. 하지만 그건 다음 단계의 이야기입니다.
오늘 기억할 한 가지
도커를 한 문장으로 줄이면 이렇습니다. \"프로그램을 실행에 필요한 모든 것과 함께 규격 상자에 담아, 어디서나 똑같이 돌리는 기술\"입니다. 복잡한 명령어를 지금 다 외울 필요는 없습니다. \"내 환경을 통째로 포장해 옮긴다\"는 감각 하나만 손에 쥐어도, 도커의 세계는 절반쯤 열린 셈입니다.
혹시 개발 공부를 하다가 환경 설정에서 번번이 막혀 좌절했다면, 그건 실력의 문제가 아니라 도구의 문제였을 가능성이 큽니다. 언젠가 도커라는 상자에 짐을 처음 담아 보는 날, \"제 컴퓨터에선 되는데요\"라는 말이 왜 사라졌는지 몸으로 이해하게 될 겁니다. 그 작은 성취의 순간을 응원합니다.
댓글 0