안녕하세요, 코딩은 못 하지만 IT가 너무 궁금한 비개발자 루카(Luka)입니다. 요즘 IT 업계 이야기를 듣다 보면 'Docker(도커)'라는 단어가 정말 자주 등장하더라고요. 개발자 친구들이 "이거 쓰면 개발 효율이 200%는 올라간다!" "이제 환경 세팅으로 삽질할 일 없다!" 하면서 열변을 토하는 걸 보고, '이게 뭔데 이렇게 난리야?' 싶어서 제가 직접 파보고 기록으로 남기게 됐습니다. 저 같은 비개발자 눈높이에서 도대체 도커가 무엇인지, 왜 그렇게 핫한지, 그리고 제가 직접 따라 해본 도커 파일 작성까지 솔직하게 풀어볼게요!

Docker, 이게 도대체 뭔데 그렇게 대단한 건데요?
처음에 도커라는 말을 들었을 때, 그냥 '가상 머신 같은 건가?' 생각했어요. 그런데 개발자 친구들이랑 이야기해보니 확실히 다르다고 하더라고요. 가장 와닿았던 비유는 바로 '이사 갈 때 포장이사'였어요.
우리가 이사할 때, 짐을 박스에 잘 싸고 가구는 분해해서 옮기잖아요? 그리고 새집에 가서 박스를 풀고 가구를 조립합니다. 이때 중요한 건, '어떤 집으로 이사가든 내 짐은 그대로 안전하게 옮겨져서 다시 사용할 수 있어야 한다'는 거죠.
도커도 비슷해요. 내가 만든 프로그램(앱)과 그 프로그램을 실행하는 데 필요한 모든 것(운영체제 일부, 라이브러리, 설정 등)을 하나의 '컨테이너(Container)'라는 박스에 완벽하게 포장해서 담는 것이라고 이해하면 쉬웠습니다. 이 컨테이너는 어떤 컴퓨터 환경(윈도우든, 맥이든, 리눅스 서버든)에서든 똑같이 작동하도록 설계되어 있다는 게 핵심이에요.
과거에는 "제 컴퓨터에서는 잘 돌아가는데 왜 서버에서는 안 돼요?"라는 개발자들의 고질적인 문제가 있었어요. 각자 개발하는 환경이 다르고, 설치된 라이브러리 버전도 다르고… 이 모든 의존성 문제를 해결해 주는 마법 같은 상자가 바로 이 '도커 컨테이너'였던 거죠!
전통적인 가상 머신(VM)과 Docker 컨테이너, 뭐가 다른데? (비교 표)
제가 제일 궁금했던 게 이거였어요. 가상 머신도 환경을 격리하고 똑같이 실행할 수 있다는데, 도커랑은 뭐가 다른 걸까요? 찾아보니 가장 큰 차이는 '가벼움'과 '효율성'에 있었습니다.
| 구분 | 전통적인 가상 머신 (VM) | Docker 컨테이너 |
|---|---|---|
| 개념 | 하드웨어 전체를 가상화하여 그 위에 별도의 OS를 설치 | 호스트 OS 커널을 공유하며 앱 실행에 필요한 최소한의 환경만 격리 |
| 포함 요소 | 게스트 OS (커널 포함), 라이브러리, 앱 | 앱, 라이브러리, 앱 실행에 필요한 종속성 (호스트 OS 커널 사용) |
| 크기 | GB 단위 (최소 수 GB ~ 수십 GB) | MB 단위 (수 MB ~ 수백 MB) |
| 시작 시간 | 수 분 (OS 부팅 시간 필요) | 수 초 이내 |
| 리소스 사용 | 무거움 (각 VM마다 독립적인 OS를 위한 CPU, 메모리 할당 필요) | 매우 가벼움 (호스트 OS 커널 공유, 효율적인 자원 사용) |
| 격리 수준 | 하드웨어 수준의 강력한 격리 | OS 커널 공유 기반의 격리 (VM보다는 약하지만, 앱 실행에는 충분) |
제가 직접 찾아보니, 가상 머신은 마치 '집 안에 또 다른 집을 짓는 것'과 같고, 도커 컨테이너는 '내 집 안에 독립된 방을 만드는 것'과 비슷하다는 비유가 많았어요. 가상 머신은 최소 1~2GB의 메모리를 OS 구동에만 쓰는 반면, 도커 컨테이너는 필요에 따라 수십 MB에서 수백 MB 수준으로 훨씬 가볍게 구동됩니다. 공식 문서에서 권장하는 기본적인 웹 서버 컨테이너의 메모리 사용량이 약 64MB~128MB 정도라고 하니, 정말 드라마틱한 차이죠!
Docker의 핵심 개념 3가지: 이미지, 컨테이너, Dockerfile
도커를 이해하려면 딱 세 가지 개념만 알면 된다고 해서 머리에 콕 박아뒀습니다.
- 이미지 (Image): 이건 '빵틀'이라고 생각하면 편해요. 특정 프로그램을 실행하기 위한 모든 설정, 코드, 라이브러리가 담긴 '청사진' 또는 '템플릿'입니다. 이미지는 한번 만들면 변하지 않는 정적인 파일이에요. 예를 들어, "파이썬 웹 앱을 위한 이미지" 같은 거죠.
- 컨테이너 (Container): 빵틀로 찍어낸 '실제 빵'입니다. 이미지(빵틀)를 가지고 실제로 실행시킨, 격리된 공간에서 돌아가는 프로그램 인스턴스예요. 하나의 이미지로 여러 개의 컨테이너(여러 개의 빵)를 만들어서 동시에 실행할 수 있습니다.
- Dockerfile: 빵틀(이미지)을 만드는 '레시피'입니다. 텍스트 파일로 되어 있는데, 여기에 어떤 운영체제를 기반으로 할지, 어떤 파일을 복사할지, 어떤 프로그램을 설치할지, 그리고 앱을 어떻게 실행할지 등을 순서대로 적어 놓습니다. 개발자가 원하는 환경을 명확하게 정의하는 거죠.
개발 효율 200% UP? 실제 어떤 수치로 보여지는데?
비개발자인 저에게 '효율 200% UP'은 너무 추상적인 이야기였어요. 그래서 친구들에게 물어보고 자료도 찾아보며 구체적인 수치들을 찾아봤습니다.
1. 눈에 띄게 줄어든 빌드 시간: 최대 70% 단축!
도커의 가장 큰 장점 중 하나는 '레이어 캐싱'이라는 기능 덕분에 프로그램 빌드 시간이 엄청나게 줄어든다는 점이었어요. Dockerfile의 각 명령어가 하나의 '레이어'를 만드는데, 만약 이전 빌드 이후에 특정 레이어만 변경되었다면, 변경되지 않은 앞선 레이어들은 다시 빌드할 필요 없이 캐시된 것을 그대로 사용해요.
제가 찾아보니, 한 개발 프로젝트에서 특정 모듈 빌드 시간이 42초였는데, Docker의 레이어 캐싱 덕분에 이후 빌드는 11초로 단축된 사례도 있더라고요. 약 73.8%의 시간 절약입니다. 전체 빌드 프로세스를 여러 단계로 나누고, 자주 바뀌지 않는 의존성 설치 같은 작업은 캐시로 재활용할 수 있게 설계하면 이런 극적인 효과를 볼 수 있다고 해요.
2. 환경 설정 시간 제로에 수렴: 하루가 10분으로!
개발자 친구들에게 물어보니, 보통 새 프로젝트 환경 설정에만 짧으면 1~2시간, 복잡하면 반나절 이상 걸리는 경우도 많다고 해요. 데이터베이스 설치하고, 특정 라이브러리 버전 맞추고, 운영체제 종속성 해결하고... 이 과정에서 수많은 에러와 삽질이 반복된다고 합니다.
하지만 Docker를 쓰면 이미 잘 만들어진 Dockerfile만 있으면 돼요. 이 파일 하나로 모든 세팅을 자동으로 완료할 수 있어서, 새로운 개발자가 팀에 합류하거나 새 개발 환경을 구축할 때 걸리는 시간이 평균 3시간 이상에서 10분 이내로 단축될 수 있다고 합니다. 이 부분이야말로 '200% UP'이라는 말이 가장 와닿는 지점이었어요.
3. 리소스 효율: 같은 장비로 더 많은 앱을!
앞서 가상 머신과 비교하면서 설명했지만, 컨테이너는 가상 머신보다 훨씬 가볍습니다. 전통적인 가상 머신이 최소 1~2GB의 메모리를 OS 구동에만 쓰는 반면, Docker 컨테이너는 필요에 따라 수십 MB에서 수백 MB 수준으로 훨씬 가볍게 구동됩니다.
이는 곧 하나의 물리 서버에 더 많은 앱을 동시에 실행할 수 있다는 뜻이에요. 예를 들어, 한 서버에 가상 머신으로는 3개의 앱밖에 못 돌렸다면, 도커 컨테이너로는 10개 이상의 앱을 효율적으로 돌릴 수 있게 됩니다. 개발 환경에서도 마찬가지예요. 내 노트북 자원을 훨씬 효율적으로 쓸 수 있어서 여러 프로젝트를 동시에 띄워놓고 작업할 때 버벅거림이 덜하다고 합니다.
초보자를 위한 Dockerfile 작성: 루카도 따라 해봤습니다!
저는 코딩을 못 하지만, 'Dockerfile'이 뭔지 너무 궁금해서 직접 아주 간단한 파이썬 웹 서버를 만드는 Dockerfile을 따라 해봤어요. 정말 쉬웠습니다! (물론 개발자 친구의 도움을 좀 받았습니다. 헤헤)
목표: 아주 간단한 "Hello, Docker from Luka!"를 보여주는 파이썬 웹 서버를 만들고, 그걸 도커 컨테이너로 띄우는 것.
먼저, app.py라는 파이썬 파일을 만들고 아래 내용을 넣었습니다.
(아, 이건 코딩이 아니라 그냥 명령어랑 텍스트라 따라 할 수 있었어요!)
# app.py 파일 내용
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello, Docker from Luka! This is my first container. :)"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
그리고 이 파이썬 앱이 실행되려면 Flask라는 라이브러리가 필요해요. 그래서 requirements.txt 파일을 만들었습니다.
# requirements.txt 파일 내용
Flask==2.3.2
이제 이 앱을 컨테이너로 만들 '레시피', 즉 Dockerfile을 작성할 차례입니다!
# Dockerfile 내용
# 1. 어떤 기본 이미지를 사용할지 정합니다. (운영체제 + 파이썬 환경이 미리 깔려있는 이미지)
FROM python:3.9-slim-buster
# 2. 컨테이너 내부에서 작업할 디렉토리를 설정합니다.
# 이 경로에 우리의 파이썬 앱 파일들이 들어갈 거예요.
WORKDIR /app
# 3. 로컬에 있는 요구사항 파일을 컨테이너의 /app 디렉토리로 복사합니다.
COPY requirements.txt .
# 4. requirements.txt에 명시된 라이브러리들을 설치합니다.
# 'pip install -r requirements.txt' 명령어를 실행하는 거죠.
RUN pip install --no-cache-dir -r requirements.txt
# 5. 로컬에 있는 모든 앱 관련 파일(app.py 등)을 컨테이너의 /app 디렉토리로 복사합니다.
COPY . .
# 6. 이 컨테이너가 5000번 포트로 서비스를 제공할 거라고 외부에 알립니다.
# 실제 접속은 포트 포워딩을 통해 이루어집니다.
EXPOSE 5000
# 7. 컨테이너가 시작될 때 실행할 명령어를 정의합니다.
# 'python app.py' 명령어를 실행해서 웹 서버를 띄울 겁니다.
CMD ["python", "app.py"]
자, 이제 이 세 파일을 모두 같은 폴더에 넣어두고, 터미널(명령 프롬프트)을 열어 해당 폴더로 이동한 다음, 다음 명령어를 입력하면 됩니다!
# 1. Dockerfile을 기반으로 'luka-first-app'이라는 이름의 이미지를 빌드합니다.
# 뒤에 '.'은 현재 디렉토리에서 Dockerfile을 찾으라는 의미입니다.
docker build -t luka-first-app .
# 2. 빌드된 'luka-first-app' 이미지를 사용하여 컨테이너를 실행합니다.
# -p 8000:5000은 내 컴퓨터의 8000번 포트를 컨테이너의 5000번 포트에 연결하라는 뜻입니다.
# -d는 컨테이너를 백그라운드에서 실행하라는 의미입니다.
docker run -p 8000:5000 -d luka-first-app
이렇게 명령어를 치고, 웹 브라우저를 열어 http://localhost:8000으로 접속해 봤더니… "Hello, Docker from Luka! This is my first container. :)"라는 문구가 뙇! 하고 뜨는 거예요! 제가 개발자는 아니지만, 뭔가 '내 손으로 컨테이너를 띄웠다!'는 성취감이 엄청났습니다.
비개발자가 헷갈리기 쉬운 부분 (루카의 솔직 고백)
제가 처음 도커를 접하면서 가장 헷갈렸던 부분들을 솔직하게 털어놓고, 제가 어떻게 이해했는지 공유해볼게요.
1. 이미지와 컨테이너, 이게 뭐가 달라요? 대체 왜 이름을 다르게 부르죠?
- 처음 생각: 그냥 같은 거 아닌가? 왜 자꾸 이미지를 만들고 컨테이너를 실행한다고 할까?
- 루카의 깨달음: 이미지 = '붕어빵 틀' / 컨테이너 = '붕어빵' 입니다. 붕어빵 틀이 있어야 붕어빵을 만들 수 있죠? 그리고 하나의 붕어빵 틀로 수십 개의 붕어빵을 만들 수 있듯이, 하나의 이미지로 여러 개의 컨테이너를 만들고 실행할 수 있어요. 이미지는 정적인 '설계도'이고, 컨테이너는 그 설계도로 만들어진 '실제 작동하는 결과물'이라는 걸 이해하는 순간, 퍼즐이 딱 맞춰졌습니다!
docker build는 붕어빵 틀을 만드는 것 (이미지 생성).docker run은 붕어빵 틀로 붕어빵을 찍어내고 실행하는 것 (컨테이너 실행).
2. 데이터는 어디에 저장되는데? 컨테이너 없어지면 다 날아가요?
- 처음 생각: 컨테이너가 잠깐 실행되는 거라면, 앱에서 생성된 파일이나 데이터베이스 같은 건 어디 저장되는 거지? 컨테이너가 사라지면 데이터도 사라지는 거 아니야?
- 루카의 깨달음: 맞아요, 기본적으로 컨테이너가 사라지면 컨테이너 안에 생성된 데이터도 같이 사라집니다. 도커는 이런 문제를 해결하기 위해 '볼륨(Volume)'이라는 개념을 제공해요. 볼륨은 내 컴퓨터(호스트)의 특정 폴더를 컨테이너 내부의 특정 폴더에 '연결'해주는 기능입니다.
- 예를 들어,
-v /내컴퓨터/데이터:/컨테이너/데이터이런 식으로 명령어를 추가하면, 컨테이너가 아무리 사라졌다 다시 만들어져도, 데이터는 내 컴퓨터의/내컴퓨터/데이터폴더에 계속 저장되어 안전하게 보관됩니다.docker run -v ~/mydata:/app/data -p 8000:5000 -d luka-first-app이렇게요! 이렇게 하니 데이터가 안 날아가서 개발자들이 안심하고 컨테이너를 만들고 지우고 하는 거더라고요.
- 예를 들어,
3. 포트 포워딩, 왜 굳이 숫자를 연결해요? (예: -p 8000:5000)
- 처음 생각: 앱이 5000번 포트 쓴다고 Dockerfile에 써놨는데, 왜 실행할 때는
-p 8000:5000이런 식으로 굳이 8000번을 연결해야 하지? 그냥 5000번으로 접속하면 안 돼? - 루카의 깨달음: 컨테이너는 기본적으로 완전히 격리된 환경이에요. 컨테이너 내부의 5000번 포트는 컨테이너 안에서만 통합니다. 외부(내 컴퓨터나 인터넷)에서 그 5000번 포트에 직접 접근할 수는 없어요. 그래서 내 컴퓨터의 특정 포트(예: 8000번)를 컨테이너 내부의 포트(예: 5000번)와 '연결'시켜줘야 합니다. 즉, 내 컴퓨터의 8000번으로 들어오는 요청을 컨테이너의 5000번으로 보내주는 거죠. 이게 바로
-p 8000:5000명령어가 하는 일입니다. 덕분에 여러 개의 웹 서버 컨테이너를 동시에 띄우더라도, 각각 다른 외부 포트(예: 8000, 8001, 8002)를 할당해서 충돌 없이 사용할 수 있습니다.
핵심 요약 (루카의 결론)
- Docker는 앱과 모든 실행 환경을 하나의 '컨테이너'에 담아, 어떤 컴퓨터에서든 똑같이 작동하도록 보장하는 기술입니다.
- 전통적인 가상 머신보다 훨씬 가볍고 빠르며, 빌드 시간 및 환경 설정 시간을 극적으로 단축시켜 개발 효율을 대폭 높여줍니다.
- 이미지(청사진), 컨테이너(실행 결과물), Dockerfile(레시피) 세 가지 핵심 개념만 알면 비개발자도 충분히 이해하고 활용할 수 있습니다.
자주 묻는 질문 (FAQ)
Q1: Docker를 사용하면 제 컴퓨터가 느려지지 않을까요? A1: 아니요, 오히려 효율적입니다. Docker 컨테이너는 가상 머신보다 훨씬 적은 자원을 사용하기 때문에, 여러 앱을 동시에 실행해도 컴퓨터 자원을 효율적으로 관리할 수 있습니다. 예를 들어, 기본적인 컨테이너는 수십 MB의 메모리만 사용합니다.
Q2: Docker는 개발자만 쓰는 건가요? 비개발자도 쓸 일이 있나요? A2: 주로 개발 및 운영 환경에서 사용되지만, 비개발자도 간접적으로 도커의 혜택을 누리고 있습니다. 예를 들어, 특정 소프트웨어를 설치할 때 복잡한 과정 없이 도커 컨테이너로 바로 실행하거나, 개발자가 만든 데모 앱을 쉽게 체험해 볼 때 유용하게 활용될 수 있습니다. (루카처럼요!)
Q3: Dockerfile을 한번 만들면 계속 재활용할 수 있나요? A3: 네, 맞습니다. Dockerfile은 한 번 잘 만들어두면 필요할 때마다 재사용하여 동일한 환경의 이미지를 손쉽게 빌드할 수 있습니다. 팀 내에서 개발 환경을 통일하거나, 배포 환경을 표준화하는 데 매우 강력한 도구입니다.
제가 코딩은 못 하지만, 이렇게 직접 파고들어 보니 Docker가 왜 그렇게 대단한 기술인지 조금은 알 것 같았습니다. 복잡하고 어렵게 느껴졌던 기술도 비유와 구체적인 수치, 그리고 직접 따라 해보는 과정을 통해 충분히 이해할 수 있다는 걸 다시 한번 느꼈네요. 저처럼 IT가 궁금한 비개발자분들도 이 글을 통해 Docker에 대한 두려움을 조금이나마 덜고, 기술 탐험의 재미를 느끼셨으면 좋겠습니다!
다음에는 또 어떤 신기한 기술을 파헤쳐 볼까요? 😉