2편에서 Dockerfile이 이미지와 컨테이너를 잇는 다리라는 이야기를 했습니다. 이제 그 다리 위에서 어떤 길을 택할지, 즉 베이스 이미지를 무엇으로 고를지 살펴볼 차례입니다. 고등학생 입장에서 Docker를 실습해 보면 가장 많이 마주치는 이름이 ubuntu와 alpine입니다. 두 이미지를 직접 비교하면서 언제 어떤 선택이 더 쉬운지 정리해 봅시다.
이 글의 흐름
- 베이스 이미지가 결정하는 것들
- Ubuntu 이미지를 선택할 이유와 실습
- Alpine 이미지를 선택할 이유와 실습
- 상황별 체크리스트와 Compose 예시
- 다음 글에서 다룰 멀티 스테이지 빌드 예고
읽기 카드
- 예상 소요 시간: 15분
- 사전 준비: Dockerfile 기초,
apt/apk명령 감각- 읽고 나면: 우분투와 알파인의 장단점을 상황별로 설명할 수 있습니다.
베이스 이미지가 결정하는 것들
베이스 이미지는 단순히 "어떤 OS인가"를 넘어서 다음 요소를 결정합니다.
- 패키지 관리자: 우분투는
apt, 알파인은apk를 씁니다. - 기본 셸과 유틸리티: 우분투는
bash와 익숙한 GNU 유틸이 대부분 있지만, 알파인은 BusyBox 기반이라 최소한만 있습니다. - 이미지 크기와 보안 업데이트 주기: 알파인은 수십 MB 수준으로 작고, 우분투는 그보다 무겁지만 익숙한 패치 흐름을 따릅니다.
- 런타임 라이브러리: 알파인은
musl기반이라, 일부 미리 빌드된 프로그램은 그대로 실행되지 않을 수 있습니다.
즉, "무조건 가벼우면 좋다" 혹은 "무조건 익숙한 게 좋다"가 아니라 작업 목적에 맞는 균형이 중요합니다.
여기서 musl과 glibc라는 말이 처음 나오면 어렵게 느껴질 수 있습니다. 초보자 단계에서는 내부 원리까지 외울 필요는 없고, 아래처럼 규칙으로 기억해도 충분합니다.
- 우분투는 "대부분의 예제가 무난하게 잘 돌아가는 쪽"에 가깝습니다.
- 알파인은 "가볍고 빠르지만, 어떤 패키지는 그대로는 안 돌아갈 수 있는 쪽"에 가깝습니다.
즉, 알파인에서 라이브러리 오류를 만나면 너무 깊게 파고들기 전에 "이 경우는 우분투 기반 이미지가 더 편하겠다"고 판단하는 것도 좋은 선택입니다. 배포 이미지를 아주 작게 만들어야 하는 상황이 아니라면, 초반 학습에서는 우분투가 더 덜 막힐 수 있습니다.
Ubuntu 이미지를 선택할 이유
학생들이 실습할 때 우분투 이미지를 자주 고르는 이유는 명확합니다.
- 교육 자료와 동일한 환경: 대부분의 리눅스 입문 문서가 우분투 LTS 기준으로 작성되어 있어 따라 하기 쉽습니다.
- 풍부한 패키지:
apt install build-essential같은 명령으로 즉시 필요한 도구를 설치할 수 있습니다. - 디버깅 편의성:
bash,curl,ping,systemctl등 익숙한 도구가 기본 또는 간단한 설치로 준비됩니다.
Compose로 우분투 실습 컨테이너를 만들면 아래처럼 됩니다.
services:
ubuntu-lab:
image: ubuntu:24.04
command: ["bash", "-lc", "sleep infinity"]
stdin_open: true
tty: true
Ubuntu 미니 실습
- 컨테이너 띄우기
docker run -it --name ubuntu-lab --rm ubuntu:24.04 bash
- 패키지 업데이트와 설치
apt update && apt install -y git curl
- 프로세스 확인
ps aux | head -5
이 실습만으로 apt, bash, 친숙한 GNU 유틸을 바로 다룰 수 있습니다. 맥 사용자라도 터미널 하나만 열면 곧바로 리눅스 서버를 체험하게 됩니다.
Alpine 이미지를 선택할 이유
알파인을 선택하는 이유는 조금 다릅니다.
- 이미지 크기 절감:
alpine:3.20은 수십 MB 수준입니다. 배포 속도가 빨라지고, 데이터 요금이 줄어듭니다. - 빠른 기동: 기본 패키지가 적어서 컨테이너가 매우 빠르게 뜹니다.
- 보안 표면 최소화: 불필요한 도구가 거의 없어 업데이트할 대상이 적습니다.
단, 아래를 기억하세요.
- 기본 셸이
sh이므로bash가 필요하면 직접 설치합니다. apk add는 패키지 이름이 다소 다릅니다. 예:apk add curl.- 일부 바이너리는
glibc를 기대하므로 호환 패키지를 추가해야 합니다.
Alpine 미니 실습
docker run -it --name alpine-lab --rm alpine:3.20 sh
apk add --no-cache curl bash
cat /etc/os-release
짧은 명령 몇 줄만으로도 "경량 리눅스"가 어떤 느낌인지 체험할 수 있습니다. apk add --no-cache 패턴을 익히면 배포 이미지에서 불필요한 캐시 파일을 남기지 않을 수 있습니다.
프로젝트 상황에 맞춘 체크리스트
| 질문 | 우분투 추천 | 알파인 추천 |
|---|---|---|
| 리눅스 기초 실습이 목적인가? | ✅ | |
| 이미지 크기가 100MB 이하여야 하나? | ✅ | |
| glibc 기반 언어/패키지를 쓰나? | ✅ | |
| 단일 실행 파일만 배포하면 되나? | ✅ | |
| 디버깅 유틸이 많이 필요한가? | ✅ |
Compose로 두 이미지를 동시에 다뤄 보기
services:
ubuntu-lab:
image: ubuntu:24.04
command: ["bash", "-lc", "sleep infinity"]
tty: true
alpine-lab:
image: alpine:3.20
command: ["sh", "-lc", "sleep infinity"]
tty: true
docker compose up -d로 두 환경을 동시에 띄우고 docker compose exec ubuntu-lab bash, docker compose exec alpine-lab sh로 각각 접속해 보세요. 같은 명령이라도 옵션이나 패키지 이름이 다르게 느껴진다는 사실을 직접 체험할 수 있습니다.
처음 선택할 때는 아래처럼 단순 규칙으로 시작해도 좋습니다.
- 리눅스 명령과 패키지 설치를 배우는 실습이면 우분투부터 시작합니다.
- 배포 이미지를 가볍게 만들고 싶으면 알파인을 먼저 검토합니다.
- 알파인에서 패키지 호환 오류가 나면 우분투로 되돌아가도 괜찮습니다.
다음 글 예고: 멀티 스테이지 빌드
베이스 이미지를 정한 뒤에는 "빌드 환경"과 "실행 환경"을 어떻게 분리할지가 숙제입니다. 다음 4편에서는 Node 앱을 예시로 멀티 스테이지 빌드를 구성하고, 어떤 스테이지를 만들면 이미지를 더 가볍게 유지할 수 있는지 실습 중심으로 이어가겠습니다.
💬 댓글
이 글에 대한 의견을 남겨주세요