최근 개발 환경 정비와 애플리케이션 배포를 효율화하는 수단으로서 Docker가 급속히 보급되고 있습니다. Docker는 애플리케이션과 그 의존 환경을 하나의 “컨테이너”로 패키징하여 어디서든 동일한 환경에서 실행할 수 있는 특징을 가지고 있습니다. 이 Docker 컨테이너를 구축하려면 “Dockerfile”이라는 설계도가 필요합니다. Dockerfile은 기반이 되는 OS 이미지 지정, 설치할 소프트웨어, 환경 변수 설정 등을 기술하는 텍스트 파일입니다. 개발자는 이 파일을 사용해 맞춤형 환경을 자동으로 구축할 수 있습니다.
Ubuntu를 기반으로 하는 이유
Dockerfile을 만들 때는 먼저 기반이 되는 OS 이미지를 지정해야 합니다. 그 중에서도 특히 인기가 높은 것이 Ubuntu입니다. Ubuntu는 Debian 기반의 Linux 배포판으로, 사용 편의성과 풍부한 패키지를 통한 유연한 환경 구축이 가능합니다. Ubuntu를 기반으로 한 Dockerfile은 다음과 같은 장점이 있습니다:
풍부한 공식·커뮤니티 문서가 존재하여 학습 비용이 낮다
많은 패키지와 도구를 APT로 쉽게 설치할 수 있다
경량의 미니멀 이미지(ubuntu:20.04, ubuntu:24.04 등)가 공식적으로 제공된다
본 기사(글)의 목적과 대상 독자
본 기사에서는 “Dockerfile Ubuntu”라는 키워드를 주제로, Ubuntu 기반 Dockerfile 작성 방법을 초보자도 이해하기 쉽게 설명합니다. 구체적으로는 Dockerfile의 기본 구조부터 실제 Ubuntu 환경을 구축하는 절차, Python 등 애플리케이션 환경 도입 예시, 그리고 흔히 발생하는 오류와 그 대응 방법까지 포괄적으로 소개합니다. 다음과 같은 분들에게 추천하는 내용입니다:
Dockerfile을 처음 사용해 환경을 구축하고 싶은 분
Ubuntu에서 개발 환경을 재현성 높게 만들고 싶은 분
문제 발생 시 대응 방법까지 포함해 지식을 깊게 배우고 싶은 분
2. Dockerfile의 기본 구성
Dockerfile이란? 그 역할을 이해하자
Dockerfile은 Docker 이미지를 만들기 위한 레시피와 같은 것입니다. 구체적으로는 어떤 베이스 OS를 사용하고, 어떤 소프트웨어를 설치하며, 어떤 설정을 하는지를 기록하는 텍스트 파일입니다. 이 파일을 기반으로 docker build 명령을 실행하면, 재현성이 높은 개발 환경 및 애플리케이션 실행 환경을 쉽게 구축할 수 있습니다. Dockerfile을 사용하면 얻는 이점:
환경 구축 자동화(수작업 재현 불필요)
여러 사람이 개발할 때 환경 차이가 없어짐
CI/CD 파이프라인에도 쉽게 통합 가능
Dockerfile에서 자주 사용되는 기본 명령(디렉티브)
Dockerfile에는 여러 명령(디렉티브)이 있지만, 아래가 대표적인 것입니다. 이를 적절히 조합하여 Ubuntu 기반 Dockerfile을 만들어 나갑니다.
명령
설명
FROM
베이스가 되는 Docker 이미지를 지정합니다. 예: FROM ubuntu:24.04
RUN
쉘 명령을 실행합니다. 패키지 설치 등에 사용
COPY
로컬 파일을 이미지 내부에 복사
ADD
COPY와 비슷하지만, URL에서 가져오거나 아카이브를 풀어낼 수도 있음
WORKDIR
작업 디렉터리를 지정
ENV
환경 변수를 설정
CMD
컨테이너 시작 시 실행되는 명령을 정의(덮어쓰기 가능)
ENTRYPOINT
CMD와 비슷하지만, 강제로 실행되는 명령을 정의
Ubuntu 기반 Dockerfile의 최소 예시
아래는 Ubuntu를 기반으로 한 아주 기본적인 Dockerfile 예시입니다.
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y
curl
vim
CMD ["/bin/bash"]
이 Dockerfile은 Ubuntu 24.04를 기반으로 curl과 vim이라는 두 유틸리티를 설치하고, 마지막에 bash 쉘을 실행하도록 구성되었습니다.
Ubuntu 태그 선택에 대해
Ubuntu Docker 이미지는 Docker Hub 공식 레포지토리에서 공개됩니다. ubuntu:latest를 지정하면 최신 버전이 사용되지만, 버전을 명시적으로 고정하는 것이 권장됩니다. 예를 들어:
ubuntu:22.04 (LTS: 장기 지원 버전, 안정성 중시)
ubuntu:24.04 (최신 LTS 후보, 기능 중시)
목적에 따라 안정성을 우선할지 새로운 기능을 우선할지 검토해봅시다.
3. 실전: Ubuntu 기반 Dockerfile 만들기
Ubuntu 환경에 필요한 패키지를 설치하기
Dockerfile을 사용해 Ubuntu 환경을 구축할 때, 대부분의 경우 추가 패키지를 설치해야 합니다. 예를 들어, 개발 환경을 갖추기 위해 다음과 같은 유틸리티가 자주 사용됩니다:
curl: 파일 가져오기 및 API 확인용
vim: 간단한 텍스트 에디터
git: 버전 관리 도구
build-essential: C/C++ 빌드에 필요한 기본 도구 모음
Dockerfile에서 이를 설치하려면 RUN 명령을 사용합니다.
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y
curl
vim
git
build-essential
apt-get update를 먼저 실행함으로써 최신 패키지 목록을 가져온 후 설치할 수 있게 됩니다.
비대화형 설치 설정
Ubuntu에서는 apt-get install 시에 사용자 입력이 필요할 수 있지만, Docker 빌드 프로세스에서는 대화형 작업을 할 수 없습니다. 따라서 아래와 같이 환경 변수를 설정하고 비대화 모드로 설치하는 것이 권장됩니다.
ENV DEBIAN_FRONTEND=noninteractive
이렇게 하면 패키지 설정 시 표시되는 “지역 설정” 등의 입력을 건너뛰고 원활하게 설치가 진행됩니다.
불필요한 캐시를 삭제하여 경량화하기
APT를 사용하면 다운로드된 임시 파일(캐시)이 이미지 내부에 남아 최종 Docker 이미지가 무거워집니다. 아래와 같이 캐시를 삭제함으로써 이미지 크기를 줄일 수 있습니다.
RUN apt-get update && apt-get install -y
curl
vim
&& rm -rf /var/lib/apt/lists/*
이와 같이 여러 명령을 하나의 RUN 문으로 합치는 것으로 불필요한 레이어 증가를 방지할 수도 있습니다.
베스트 프랙티스: Dockerfile 정리 방법
실제 개발 현장에서는 다음과 같은 Dockerfile 작성에 관한 베스트 프랙티스가 권장됩니다:
RUN 명령은 가능한 한 합쳐서 레이어 수를 줄인다
ENV로 명시적으로 버전 및 설정을 정의한다
주석을 사용해 처리 목적을 명시한다
불필요한 파일을 남기지 않도록 rm이나 --no-install-recommends를 사용한다
이와 같이 하면 보다 경량화되고 유지보수가 쉬운 Dockerfile을 구축할 수 있습니다.
4. Docker 이미지 빌드와 확인
Dockerfile에서 Docker 이미지를 빌드하기
Dockerfile을 작성했으면, 다음 단계는 Docker 이미지 빌드입니다. 이는 docker build 명령을 사용하여 수행합니다. Dockerfile이 있는 디렉터리에서 아래 명령을 실행합니다。
docker build -t my-ubuntu-image .
-t 옵션은 이미지에 이름(태그)을 붙이기 위한 것입니다. 예에서는 my-ubuntu-image라는 이름을 붙이고 있습니다。
.는 Dockerfile이 존재하는 현재 디렉터리를 의미합니다。
이 명령을 실행하면 Docker는 Dockerfile의 명령을 차례대로 읽고, 그에 따라 새로운 이미지를 구축합니다。
빌드한 Docker 이미지 확인
이미지 생성이 완료되면, 다음 명령으로 확인할 수 있습니다。
docker images
이렇게 하면 로컬에 존재하는 Docker 이미지 목록이 표시되고, 아래와 같은 정보들을 확인할 수 있습니다:
REPOSITORY(이미지 이름)
TAG(태그)
IMAGE ID(고유 식별자)
CREATED(생성 일시)
SIZE(크기)
예:
REPOSITORY TAG IMAGE ID CREATED SIZE
my-ubuntu-image latest abcd1234abcd 5 minutes ago 189MB
이와 같이, 생성한 이미지가 정상적으로 등록되어 있음을 확인할 수 있습니다。
Docker 컨테이너를 실행하여 동작 확인
생성한 이미지가 올바르게 동작하는지 확인하기 위해, Docker 컨테이너를 실행해 봅시다. 아래와 같은 명령을 사용합니다。
docker run -it my-ubuntu-image
-it 옵션을 지정하면 인터랙티브 모드로 터미널을 실행할 수 있습니다。
정상적으로 시작되면, 컨테이너 내부의 bash 프롬프트가 표시되어 Ubuntu 환경에 로그인한 것과 같은 상태가 됩니다。
컨테이너 내부에서 아래와 같은 명령을 실행하여, 설치한 도구가 올바르게 동작하는지 확인할 수 있습니다:
curl --version
vim --version
문제가 없으면, Dockerfile의 작성은 성공입니다。
불필요한 이미지와 컨테이너 정리
빌드와 실험을 반복하면, 로컬에 불필요한 Docker 이미지와 컨테이너가 남게 될 수 있습니다. 정기적으로 아래와 같은 명령으로 정리하는 것을 권장합니다。
중지된 컨테이너 삭제:
docker container prune
사용되지 않는 이미지 삭제:
docker image prune
모든 사용되지 않는 데이터(주의!):
docker system prune
이러한 작업을 통해 디스크 용량 절약 및 문제 방지에 도움이 됩니다。
5. 응용: Python 환경 구축
Ubuntu 기반 Dockerfile에서 Python을 사용할 수 있게 하기
Dockerfile을 사용해 Ubuntu 환경을 구축할 때, Python 실행 환경을 추가함으로써 개발·검증·머신러닝 등 다양한 용도에 대응할 수 있습니다. Ubuntu에는 원래 Python이 설치되어 있는 경우도 있지만, 버전 관리와 패키지 관리 관점에서 직접 명시적으로 구축하는 것이 일반적입니다.
apt를 사용하여 Python을 설치하는 방법
가장 간단한 방법은 APT 패키지를 사용해 Python을 설치하는 것입니다. 아래는 그 예시입니다:
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y
python3
python3-pip
&& rm -rf /var/lib/apt/lists/*
이 방법으로는 시스템에 설치된 안정 버전의 Python(보통 Python 3.10이나 3.12 등)을 사용할 수 있습니다. 또한, pip 명령으로 Python 패키지를 추가하는 것도 가능합니다。
pyenv로 Python 버전 관리를 수행하기
특정 Python 버전을 사용하고 싶거나, 여러 버전 간 전환을 하고 싶을 때는 pyenv를 사용하는 것이 편리합니다。 아래는 Dockerfile에서 pyenv를 사용해 Python 3.11.6을 설치하는 예시입니다:
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y
git
curl
make
build-essential
libssl-dev
zlib1g-dev
libbz2-dev
libreadline-dev
libsqlite3-dev
wget
llvm
libncurses5-dev
libncursesw5-dev
xz-utils
tk-dev
libffi-dev
liblzma-dev
&& rm -rf /var/lib/apt/lists/*
# pyenv의 설치
RUN git clone https://github.com/pyenv/pyenv.git ~/.pyenv
ENV PYENV_ROOT="$HOME/.pyenv"
ENV PATH="$PYENV_ROOT/bin:$PATH"
RUN echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
# 원하는 Python 버전 설치
RUN pyenv install 3.11.6 && pyenv global 3.11.6
이와 같이 하면 보다 유연하게 Python 환경을 구축·관리할 수 있습니다。
requirements.txt를 사용한 패키지 관리
실제 프로젝트에서는 대부분 여러 Python 라이브러리가 필요합니다. 이를 관리하기 위해 사용되는 것이 requirements.txt입니다。 먼저, 프로젝트 루트 디렉터리에 requirements.txt 파일을 준비합니다:
A1. 기본적으로는 안정성과 장기 지원을 중시하는 경우에는 LTS(Long Term Support)버전을 선택하는 것이 일반적입니다. 예를 들어 ubuntu:22.04와 ubuntu:20.04는 많은 개발 현장에서 사용되고 있으며, 5년간의 지원 기간이 있어 안심하고 이용할 수 있습니다. 반면에 최신 패키지나 언어 버전을 사용하고 싶은 경우에는 ubuntu:24.04와 같은 새로운 릴리스를 선택할 수도 있지만, 사전 검증을 권장합니다.
Q2. apt-get install에서 “패키지를 찾을 수 없습니다” 라는 메시지가 나오는 이유는 무엇인가요?
A2. 가장 흔한 원인은 apt-get update를 사전에 실행하지 않은 것입니다. 패키지 리스트를 업데이트하지 않고 설치를 시도하면, 오래된 리스트 상태로 해당 패키지를 찾지 못해 오류가 발생합니다. 올바른 작성 예:
RUN apt-get update && apt-get install -y curl
또한, 패키지 이름의 오기나, 더 이상 권장되지 않는 패키지 이름(예: python이 아니라 python3)에도 주의해야 합니다.
Q3. Dockerfile에서 환경 변수를 설정하는 방법은?
A3. 환경 변수는 ENV 명령을 사용하여 설정합니다. 이는 빌드 시 및 컨테이너 실행 시에 유효한 환경 변수가 됩니다. 예:
ENV DEBIAN_FRONTEND=noninteractive
이는 APT 설치 시 대화형 프롬프트를 억제하기 위해 사용되는 전형적인 설정입니다. 또한, 애플리케이션 설정이나 API 키 등을 Dockerfile 내에서 설정할 때 활용됩니다.
Q4. Dockerfile에서 CMD와 ENTRYPOINT의 차이는 무엇인가요?
A4. 둘 다 컨테이너 시작 시 실행되는 명령을 지정하는 것이지만, 사용 방법과 동작에 차이가 있습니다.
항목
CMD
ENTRYPOINT
덮어쓰기 가능성
docker run 명령으로 덮어쓰기 가능
기본적으로 덮어쓰기되지 않음(인수로 처리)
용도
기본 실행 명령을 설정
항상 실행하고 싶은 명령을 정의
예:
CMD ["python3", "app.py"]
# vs
ENTRYPOINT ["python3"]
CMD ["app.py"]
후자의 경우, docker run my-image another_script.py 형태로 CMD를 인수로 전달할 수 있습니다.
Q5. Dockerfile을 편집했는데 변경 사항이 반영되지 않습니다. 왜인가요?
A5. Docker는 빌드 시 캐시를 사용하기 때문에, Dockerfile에 작은 변경을 가해도 캐시된 레이어가 그대로 사용되는 경우가 있습니다. 대응 방법: