화. 8월 12th, 2025

G: 안녕하세요! 🚀 오늘 우리는 개발자 필수 도구이자 IT 인프라의 핵심인 Docker와 Docker Compose를 Ubuntu에 설치하는 방법을 A부터 Z까지, 최신 버전으로 완벽하게 알아보겠습니다. 복잡하게 느껴질 수도 있지만, 이 가이드만 따라오시면 초보자도 쉽게 설치하고 바로 사용할 수 있도록 도와드릴게요! 🐳✨


🌟 왜 Docker를 사용해야 할까요?

Docker는 애플리케이션과 그에 필요한 모든 종속성(라이브러리, 설정 파일 등)을 “컨테이너”라는 격리된 환경에 패키징하는 기술입니다. 이 컨테이너는 어떤 환경에서든 동일하게 실행될 수 있도록 보장해 줍니다.

  • “내 컴퓨터에서는 잘 됐는데…?” 문제 해결: 개발 환경, 테스트 환경, 운영 환경이 달라서 발생하는 문제들을 Docker가 깔끔하게 해결해 줍니다.
  • 빠른 배포: 컨테이너는 가볍고 빠르게 생성, 시작, 중지, 삭제할 수 있어 애플리케이션 배포 및 확장이 용이합니다.
  • 격리: 컨테이너는 서로 영향을 주지 않고 독립적으로 실행되어 안정성이 높습니다.
  • 리소스 효율성: 가상 머신(VM)보다 훨씬 가볍고 자원을 적게 사용합니다.

그리고 Docker Compose는 여러 개의 컨테이너를 하나로 묶어 정의하고 관리할 수 있게 해주는 도구입니다. 웹 서비스, 데이터베이스, 캐시 서버 등 여러 컴포넌트로 이루어진 복잡한 애플리케이션을 단 한 번의 명령으로 실행하고 관리할 수 있게 해주죠!

자, 그럼 이제 본격적으로 설치를 시작해볼까요?


🛠️ 1단계: 설치 전 준비 작업

Docker를 설치하기 전에 시스템을 최신 상태로 업데이트하고, 필요한 패키지들을 설치해야 합니다.

1.1 시스템 업데이트

가장 먼저 Ubuntu 시스템의 패키지 목록을 업데이트하고, 기존 패키지들을 최신 버전으로 업그레이드합니다.

sudo apt update          # 패키지 목록 업데이트
sudo apt upgrade -y      # 기존 패키지 업그레이드 (y는 '예' 자동 응답)
  • sudo: 관리자 권한으로 명령을 실행합니다.
  • apt update: 서버에서 최신 패키지 정보를 가져옵니다.
  • apt upgrade: 현재 설치된 패키지들을 최신 버전으로 업그레이드합니다.

1.2 기존 Docker 버전 제거 (선택 사항)

만약 이전에 Docker가 설치되어 있었다면, 충돌을 방지하기 위해 깨끗하게 제거하는 것이 좋습니다. 처음 설치하는 분들은 이 단계를 건너뛰셔도 됩니다.

sudo apt remove docker docker-engine docker.io containerd runc
sudo apt autoremove -y # 불필요한 의존성 패키지 제거
  • apt remove: 지정된 패키지를 제거합니다.
  • autoremove: 더 이상 필요하지 않은 의존성 패키지를 자동으로 제거합니다.

🐳 2단계: Docker Engine 설치

Docker 공식 레포지토리를 추가하여 최신 버전의 Docker를 설치하는 것이 가장 안정적이고 권장되는 방법입니다.

2.1 필요한 도구 설치

Docker의 공식 레포지토리를 HTTPS를 통해 안전하게 사용할 수 있도록 몇 가지 패키지를 설치합니다.

sudo apt install ca-certificates curl gnupg lsb-release -y
  • ca-certificates: SSL/TLS 인증서가 필요할 때 사용됩니다.
  • curl: 웹에서 데이터를 다운로드할 때 사용되는 도구입니다.
  • gnupg: GPG 키를 관리하고 인증하는 데 사용됩니다.
  • lsb-release: 운영체제 정보를 확인하는 데 사용됩니다.

2.2 Docker 공식 GPG 키 추가

Docker 패키지의 무결성을 확인하기 위해 Docker 공식 GPG 키를 시스템에 추가합니다. 이 키는 다운로드하는 패키지가 변조되지 않았음을 보증합니다.

sudo mkdir -m 0755 -p /etc/apt/keyrings # 키링 디렉토리 생성 (없을 경우)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
  • curl -fsSL ... | sudo gpg --dearmor ...: Docker의 GPG 키를 다운로드하여 /etc/apt/keyrings/docker.gpg 파일로 저장합니다.
    • -f: 실패 시 자동 종료
    • -s: 진행 상황 표시줄 숨김
    • -S: 오류 발생 시 오류 메시지 표시
    • -L: 리다이렉션 따르기

2.3 Docker 레포지토리 추가

이제 Docker의 APT 레포지토리를 Ubuntu의 패키지 소스 목록에 추가합니다. 이렇게 하면 apt 명령어로 Docker 패키지를 설치하고 업데이트할 수 있습니다.

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  • echo ... | sudo tee ...: Docker 레포지토리 정보를 /etc/apt/sources.list.d/docker.list 파일에 추가합니다.
    • $(dpkg --print-architecture): 현재 시스템의 아키텍처(예: amd64)를 자동으로 감지합니다.
    • $(lsb_release -cs): 현재 Ubuntu 버전의 코드네임(예: jammy)을 자동으로 감지합니다.

2.4 Docker Engine 설치

레포지토리를 추가했으니, 이제 다시 패키지 목록을 업데이트하고 Docker Engine을 설치합니다.

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
  • docker-ce: Docker Community Edition (Docker Engine의 핵심)
  • docker-ce-cli: Docker 명령줄 인터페이스 (CLI)
  • containerd.io: 컨테이너 런타임 (Docker의 기반)
  • docker-buildx-plugin: Docker 빌드를 위한 확장 기능
  • docker-compose-plugin: docker compose 명령어를 사용할 수 있게 하는 플러그인 (새로운 방식)

2.5 Docker 설치 확인

설치가 성공적으로 완료되었는지 확인합니다.

sudo systemctl status docker
  • systemctl status docker: Docker 서비스의 현재 상태를 확인합니다. active (running)으로 표시되면 정상입니다. q를 눌러 나갈 수 있습니다.

2.6 Docker Non-Root 권한 설정 (⭐️ 중요!)

기본적으로 Docker 명령을 실행하려면 sudo를 사용해야 합니다. 하지만 매번 sudo를 입력하는 것은 번거롭고, 스크립트에서 사용하기 어렵습니다. 현재 사용자에게 Docker 그룹 권한을 부여하여 sudo 없이 Docker 명령을 사용할 수 있도록 설정합니다.

sudo usermod -aG docker $USER
  • usermod -aG docker $USER: 현재 로그인된 사용자($USER)를 docker 그룹에 추가합니다.

이 변경사항을 적용하려면 새로운 터미널을 열거나, 현재 터미널을 종료 후 다시 로그인해야 합니다. 가장 확실한 방법은 시스템을 재부팅하는 것입니다.

# 재부팅이 번거롭다면, 다음 명령어로 그룹 변경사항을 바로 적용할 수 있습니다.
newgrp docker
  • newgrp docker: 현재 쉘 세션에 docker 그룹의 권한을 즉시 적용합니다.

권한 설정 확인:

sudo 없이 docker run hello-world를 실행하여 테스트합니다.

docker run hello-world

첫 실행 시 Docker 이미지가 다운로드되고, 다음과 유사한 메시지가 출력됩니다.

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
...
Hello from Docker!
This message shows that your installation appears to be working correctly.
...

이 메시지가 보인다면 Docker 설치가 완벽하게 성공한 것입니다! 🎉


🛠️ 3단계: Docker Compose 설치 (레거시/별도 바이너리 방식)

참고: Docker Engine 20.10 버전 이상을 설치하셨다면, docker-compose-plugin이 함께 설치되어 docker compose 명령어로 Docker Compose 기능을 바로 사용할 수 있습니다. 이 경우 3단계는 건너뛰고 4단계 docker compose 사용법만 보셔도 됩니다.

하지만 여전히 많은 스크립트나 구버전 가이드에서 docker-compose 명령어를 사용하는 경우가 많으므로, 별도 바이너리로 docker-compose를 설치하는 방법도 함께 알려드립니다.

3.1 Docker Compose 다운로드

Docker Compose의 최신 버전을 GitHub 릴리스 페이지에서 확인하여 다운로드합니다. (예시: 2.20.2는 현재 기준 최신 버전 중 하나입니다. 실제 설치 시에는 Docker Compose GitHub Releases에서 가장 최신 버전을 확인하세요!)

# 최신 버전 확인 후 URL 변경: 예시로 2.20.2 사용
DOCKER_COMPOSE_VERSION="2.20.2"
sudo curl -L "https://github.com/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  • curl -L ... -o /usr/local/bin/docker-compose: 지정된 URL에서 Docker Compose 바이너리를 다운로드하여 /usr/local/bin/docker-compose 경로에 저장합니다.
    • $(uname -s): 운영체제 이름 (예: Linux)
    • $(uname -m): 시스템 아키텍처 (예: x86_64)

3.2 실행 권한 부여

다운로드한 바이너리가 실행될 수 있도록 실행 권한을 부여합니다.

sudo chmod +x /usr/local/bin/docker-compose
  • chmod +x: 파일에 실행 권한을 추가합니다.

3.3 Docker Compose 설치 확인

설치가 성공적으로 완료되었는지 버전을 확인하여 테스트합니다.

docker-compose --version

다음과 유사한 출력이 보인다면 성공입니다.

Docker Compose version v2.20.2

💡 4단계: Docker Compose 사용하기 (두 가지 방식 비교)

이제 Docker와 Docker Compose가 모두 설치되었습니다! 두 가지 방식의 Docker Compose 사용법을 간단히 알아보고, 기본적인 예시를 통해 동작 원리를 이해해봅시다.

4.1 docker compose (플러그인 방식, 권장)

Docker Engine 20.10 이상에서는 docker-compose-plugin이 설치되어 docker 명령어 바로 다음에 compose를 붙여 사용합니다.

docker compose version

(docker-compose --version과 유사한 결과가 나옵니다.)

4.2 docker-compose (레거시/별도 바이너리 방식)

3단계에서 별도의 바이너리를 설치했다면, 다음과 같이 docker-compose 명령어를 직접 사용합니다.

docker-compose --version

🚀 5단계: 간단한 Docker 및 Docker Compose 사용 예시

설치만 해두면 아쉽죠? 간단한 예시로 직접 컨테이너를 실행해보며 Docker의 강력함을 느껴봅시다!

5.1 Docker 단일 컨테이너 실행 예시 (Nginx 웹 서버)

Nginx 웹 서버를 Docker 컨테이너로 실행해보겠습니다.

docker run -d -p 80:80 --name my-nginx nginx
  • docker run: 새 컨테이너를 실행합니다.
  • -d: 컨테이너를 백그라운드(detached) 모드로 실행합니다.
  • -p 80:80: 호스트(내 컴퓨터)의 80번 포트를 컨테이너의 80번 포트에 연결합니다. (외부에서 localhost:80으로 접속 가능)
  • --name my-nginx: 컨테이너에 my-nginx라는 이름을 부여합니다.
  • nginx: 실행할 Docker 이미지 이름입니다. (없으면 자동으로 다운로드합니다.)

컨테이너가 잘 실행되는지 확인합니다.

docker ps

출력:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                NAMES
abcdef123456   nginx     "/docker-entrypoint...."   10 seconds ago   Up 9 seconds    0.0.0.0:80->80/tcp   my-nginx

이제 웹 브라우저를 열고 http://localhost 또는 http://(당신의_Ubuntu_IP)로 접속하면 Nginx 기본 페이지를 볼 수 있습니다!

컨테이너 중지 및 삭제:

docker stop my-nginx   # 컨테이너 중지
docker rm my-nginx     # 컨테이너 삭제

5.2 Docker Compose 다중 컨테이너 실행 예시 (간단한 웹 서비스)

웹 서버와 간단한 정적 파일을 제공하는 Docker Compose 프로젝트를 만들어 봅시다.

  1. 프로젝트 디렉토리 생성:

    mkdir my-web-app
    cd my-web-app
  2. index.html 파일 생성:

    echo "
    <h1>Hello from Docker Compose!</h1>
    <p>This is a simple web app.</p>" > index.html
  3. docker-compose.yml 파일 생성:

    텍스트 편집기(nano, vi, VS Code 등)를 열어 docker-compose.yml 파일을 생성하고 다음 내용을 붙여넣습니다.

    version: '3.8' # Docker Compose 파일 형식 버전
    
    services:
      web: # 서비스 이름 (컨테이너 이름이 됨)
        image: nginx:latest # 사용할 이미지
        ports:
          - "80:80" # 호스트 80번 포트를 컨테이너 80번 포트에 연결
        volumes:
          - ./index.html:/usr/share/nginx/html/index.html # 현재 디렉토리의 index.html을 컨테이너 내부로 마운트
        container_name: my-web-app-nginx # 컨테이너에 명시적인 이름 부여
    • version: Docker Compose 파일 형식 버전을 지정합니다. 최신 버전을 사용하는 것이 좋습니다.
    • services: 이 섹션 아래에 정의된 각 항목은 하나의 컨테이너 서비스가 됩니다.
    • web: 서비스의 이름입니다. 나중에 docker compose up 또는 docker-compose up 명령어로 이 서비스를 시작할 수 있습니다.
    • image: 컨테이너를 생성할 때 사용할 Docker 이미지입니다. nginx:latest는 Nginx의 최신 버전을 의미합니다.
    • ports: 호스트와 컨테이너 간의 포트 매핑을 정의합니다. 80:80은 호스트의 80번 포트가 컨테이너의 80번 포트에 연결됨을 의미합니다.
    • volumes: 호스트와 컨테이너 간의 파일 또는 디렉토리 공유를 설정합니다. ./index.html:/usr/share/nginx/html/index.html는 현재 디렉토리의 index.html 파일을 Nginx의 기본 웹 루트로 마운트하여 컨테이너가 해당 파일을 제공하도록 합니다.
  4. Docker Compose 실행:

    docker-compose.yml 파일이 있는 my-web-app 디렉토리에서 다음 명령어를 실행합니다.

    • 플러그인 방식 (권장):
      docker compose up -d
    • 레거시/별도 바이너리 방식:
      docker-compose up -d
    • up: docker-compose.yml 파일에 정의된 서비스를 빌드하고 시작합니다.
    • -d: 컨테이너를 백그라운드(detached) 모드로 실행합니다.

컨테이너가 시작되면 docker ps 명령어로 확인합니다.

docker ps

출력:

CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS                NAMES
abcdef123456   nginx:latest  "/docker-entrypoint...."   5 seconds ago   Up 4 seconds   0.0.0.0:80->80/tcp   my-web-app-nginx

이제 웹 브라우저를 열고 http://localhost 또는 http://(당신의_Ubuntu_IP)로 접속하면 “Hello from Docker Compose!” 메시지가 나타납니다! ✨

  1. Docker Compose 서비스 중지 및 삭제:

    # 플러그인 방식
    docker compose down
    
    # 레거시/별도 바이너리 방식
    docker-compose down
    • down: docker-compose.yml 파일에 정의된 모든 컨테이너를 중지하고 제거합니다. 네트워크 및 볼륨도 함께 정리됩니다.

⚠️ 6단계: 일반적인 문제 해결 및 팁

설치 과정 중 발생할 수 있는 몇 가지 일반적인 문제와 해결 방법을 알아봅시다.

6.1 permission denied while trying to connect to the Docker daemon socket 오류

  • 문제: docker 명령 실행 시 권한 없음 오류가 발생합니다.
  • 원인: 현재 사용자가 docker 그룹에 속해 있지 않거나, 그룹 변경사항이 적용되지 않았습니다.
  • 해결: 2.6단계의 “Docker Non-Root 권한 설정”을 다시 확인하고, sudo usermod -aG docker $USER 명령 실행 후 새로운 터미널을 열거나 재부팅합니다. (가장 확실한 방법은 재부팅)

6.2 Unable to locate package docker-ce 오류

  • 문제: Docker 패키지를 찾을 수 없다는 오류가 발생합니다.
  • 원인: Docker 공식 레포지토리가 올바르게 추가되지 않았거나, apt update가 실행되지 않았습니다.
  • 해결: 2.2단계와 2.3단계의 GPG 키 추가 및 레포지토리 추가 명령어를 다시 정확히 실행하고, 그 후에 sudo apt update를 꼭 실행합니다.

6.3 컨테이너는 실행되는데 웹 접속이 안 돼요! (방화벽 문제)

  • 문제: Docker 컨테이너가 정상적으로 실행되지만, 웹 브라우저에서 접속이 안 됩니다.
  • 원인: Ubuntu의 방화벽(UFW)이 Docker 포트 연결을 막고 있을 수 있습니다.
  • 해결:
    • UFW 비활성화 (권장하지 않음, 임시 확인용): sudo ufw disable
    • 특정 포트 허용: sudo ufw allow 80/tcp (80번 포트 허용)
    • Docker가 UFW 규칙을 우회하도록 설정 (고급): Docker의 네트워크 설정(/etc/docker/daemon.json)에 iptables: false를 추가하거나, Docker 시작 스크립트 수정 등 복잡한 방법이 있으나, 초보자에게는 특정 포트를 열어주는 것이 가장 간편합니다.
    • 가장 좋은 방법: Docker 설치 시 UFW가 활성화되어 있다면, Docker는 기본적으로 UFW 규칙을 우회하여 작동하도록 설계되어 있습니다. 만약 문제가 지속된다면, UFW를 완전히 재설정하거나, sudo ufw default deny incoming과 같이 기본 정책을 더 엄격하게 설정한 경우일 수 있습니다. sudo ufw status verbose로 현재 상태를 확인해 보세요.

6.4 Docker 데몬이 실행되지 않습니다.

  • 문제: docker 명령 실행 시 Cannot connect to the Docker daemon 오류가 발생합니다.
  • 원인: Docker 서비스(데몬)가 실행되고 있지 않습니다.
  • 해결: sudo systemctl start docker 명령으로 Docker 서비스를 시작하고, sudo systemctl enable docker로 부팅 시 자동 시작되도록 설정합니다.

🎉 마무리

축하합니다! 🎉 이제 여러분은 Ubuntu 시스템에 Docker Engine과 Docker Compose를 성공적으로 설치하고 기본적인 사용법까지 익히셨습니다.

Docker는 현대 개발 환경에서 선택이 아닌 필수가 되어가고 있습니다. 이 가이드를 통해 시작점을 마련했으니, 앞으로 더 많은 Docker 명령어와 Dockerfile 작성법, Docker Hub 사용법 등 심화된 내용들을 탐구해보시길 강력히 추천합니다.

  • 다음 스텝 추천:
    • Docker 공식 문서 탐험: Docker Docs
    • Docker Hub: 다양한 공식 및 커뮤니티 이미지를 찾아보세요. Docker Hub
    • Dockerfile 작성법 학습: 직접 이미지를 만들면서 컨테이너화의 진정한 힘을 느껴보세요.

오늘 배운 내용이 여러분의 개발 여정에 큰 도움이 되기를 바랍니다! 궁금한 점이 있다면 언제든지 댓글로 남겨주세요. 해피 코딩! 🐳💻✨

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다