Ubuntu 24.04에 Docker 설치하는 방법 (Docker Compose 포함)

Ubuntu 24.04 서버에 Docker 공식 저장소를 추가해 Docker Engine과 Docker Compose를 설치하고, sudo 없이 docker 명령을 쓰는 설정, Compose로 컨테이너 실행, Doc…

Ubuntu 24.04Docker 29.9x86_64약 15분

검증된 문서입니다

클라우드 서버를 생성하여 이 문서의 명령을 처음부터 끝까지 그대로 실행하고 확인한 문서입니다.

운영체제
Ubuntu 24.04.5 LTS · x86_64
설치 버전
Docker 29.9.0 (docker-ce), Docker Compose 5.6.0, buildx 0.38.0, containerd 2.4.1
테스트 서버
DigitalOcean · 1 vCPU / 1 GB RAM / 25 GB SSD (s-1vcpu-1gb, sgp1)
마지막 확인
2026-10-13

이 문서에는 제휴 링크가 포함되어 있습니다. 링크를 통해 가입하면 코드샌드가 일정 수수료를 받을 수 있으며, 문서 내용과 평가에는 영향을 주지 않습니다.

Ubuntu 24.04 서버에 Docker 공식 저장소를 추가해 Docker Engine과 Docker Compose를 설치하고, sudo 없이 docker 명령을 쓰는 설정, Compose로 컨테이너 실행, Docker가 연 포트가 ufw 방화벽을 거치지 않는 문제와 막는 방법, 삭제하는 방법까지 정리합니다.

1. 준비물

  • Ubuntu 24.04 LTS 서버 1대 (메모리 1GB 이상 권장)
  • sudo 권한이 있는 일반 사용자 계정으로 SSH 접속
  • 외부에서 접속을 확인할 PC (방화벽 확인 단계에서 사용)

서버가 없다면 DigitalOcean의 가장 작은 Droplet(1 vCPU · 1GB)을 생성해 보세요. 이 Droplet으로도 충분히 Docker를 설치하고 컨테이너를 실행할 수 있습니다. 이 문서의 모든 과정은 Droplet(1 vCPU · 1GB 메모리 · 25GB SSD · Ubuntu 24.04 · 싱가포르)으로 서버를 생성하고, sudo 권한이 있는 일반 사용자 계정으로 확인했습니다.

2. 설치할 패키지 확인

Ubuntu 24.04 기본 저장소에도 Docker 패키지(docker.io)가 있습니다.

apt-cache policy docker.io | head -3
docker.io:
  Installed: (none)
  Candidate: 29.1.3-0ubuntu3~24.04.2

이 문서는 Docker가 직접 배포하는 공식 저장소의 docker-ce를 설치합니다. Docker 공식 문서가 안내하는 방법이고, 새 버전이 나오면 바로 받을 수 있습니다. Docker Compose도 docker compose 명령으로 함께 설치됩니다.

기본 저장소의 패키지나 다른 컨테이너 도구가 먼저 설치되어 있으면 충돌할 수 있으므로 지웁니다. 설치되어 있지 않은 패키지는 Package 'docker.io' is not installed, so not removed처럼 표시되고 넘어가므로, 처음 설치하는 서버에서도 그대로 실행해도 됩니다.

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt remove -y $pkg; done

3. Docker 공식 저장소 추가

저장소를 추가하는 데 필요한 도구를 설치합니다. 대부분 이미 설치되어 있습니다.

sudo apt update
sudo apt install -y ca-certificates curl

Docker 저장소의 서명 키를 내려받아 저장합니다. 서명 키는 내려받는 패키지가 Docker에서 만든 것인지 확인하는 데 사용됩니다. -m 0755는 폴더 권한을, a+r은 모든 사용자가 키 파일을 읽을 수 있게 한다는 뜻입니다.

sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

저장소 주소를 등록합니다. Suites 자리의 명령은 서버의 Ubuntu 코드 이름으로 바뀝니다. Ubuntu 24.04는 noble입니다.

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc

패키지 목록을 갱신하고 설치될 버전을 확인합니다. Candidate가 Docker 저장소의 버전이면 정상입니다.

sudo apt update
apt-cache policy docker-ce | head -3
docker-ce:
  Installed: (none)
  Candidate: 5:29.9.0-1~ubuntu.24.04~noble

4. Docker 설치

Docker Engine(docker-ce), 명령줄 도구(docker-ce-cli), 컨테이너 실행기(containerd.io), 이미지 빌드 도구(docker-buildx-plugin), Docker Compose(docker-compose-plugin)를 함께 설치합니다.

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

설치된 버전을 확인합니다.

docker --version
Docker version 29.9.0, build f415da8
docker compose version
Docker Compose version v5.6.0
docker buildx version
github.com/docker/buildx v0.38.0 0dbe87f36ed472fe36b6796c3f70b4210a731fc5

5. 서비스 상태 확인

설치가 끝나면 Docker 서비스가 자동으로 시작되고, 서버를 다시 시작해도 자동으로 실행되도록 등록됩니다.

sudo systemctl status docker --no-pager | head -3
● docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-10-13 02:06:24 UTC; 10s ago

docker와 컨테이너 실행기 containerd가 모두 자동 시작으로 등록되었는지 확인합니다.

systemctl is-enabled docker containerd
enabled
enabled

테스트 이미지 hello-world를 내려받아 실행합니다. 아래 문구가 표시되면 Docker가 정상입니다.

sudo docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.

6. sudo 없이 docker 명령 쓰기

지금은 sudo 없이 실행하면 아래 오류가 납니다. docker 명령은 Docker 서비스의 연결 파일(/var/run/docker.sock)을 쓰는데, 이 파일은 root와 docker 그룹만 쓸 수 있기 때문입니다.

docker run hello-world
permission denied while trying to connect to the docker API at unix:///var/run/docker.sock

현재 사용자를 docker 그룹에 추가합니다. -aG는 기존 그룹은 그대로 두고 그룹을 추가한다는 뜻이고, $USER는 지금 로그인한 사용자 이름입니다.

sudo usermod -aG docker $USER

그룹 변경은 다시 로그인해야 적용됩니다. SSH 접속을 끊고 다시 접속한 뒤 확인합니다. 그룹 목록에 docker가 보이면 됩니다.

groups
devuser sudo users docker
docker run hello-world | head -3

Hello from Docker!
This message shows that your installation appears to be working correctly.

지금까지 실행한 컨테이너 목록입니다. -a는 실행이 끝난 컨테이너까지 보여 준다는 뜻입니다.

docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED                  STATUS                              PORTS     NAMES
7ea4fe423187   hello-world   "/hello"   Less than a second ago   Exited (0) Less than a second ago             modest_pike
b74f39e59b0b   hello-world   "/hello"   6 seconds ago            Exited (0) 5 seconds ago                      musing_solomon

7. Docker Compose로 컨테이너 실행

Docker Compose는 docker compose(띄어쓰기)로 실행합니다. 예전 방식의 docker-compose(하이픈) 명령은 설치되지 않습니다. 다른 문서의 docker-compose up은 docker compose up으로 바꿔 실행하면 됩니다.

웹 서버 nginx를 실행하는 compose.yaml 파일을 만듭니다. "8080:80"은 서버의 8080 포트를 컨테이너의 80 포트로 연결한다는 뜻입니다.

mkdir ~/hello-compose && cd ~/hello-compose
cat > compose.yaml <<EOF
services:
  web:
    image: nginx:1.29
    ports:
      - "8080:80"
EOF

컨테이너를 실행합니다. -d는 터미널을 차지하지 않고 뒤에서 실행한다는 뜻입니다. 처음에는 nginx 이미지를 내려받는 줄이 여러 개 표시되고, 마지막에 아래 줄이 표시됩니다.

docker compose up -d
 Container hello-compose-web-1 Creating
 Container hello-compose-web-1 Created
 Container hello-compose-web-1 Starting
 Container hello-compose-web-1 Started

컨테이너 상태를 확인하고, 서버 안에서 접속해 봅니다. Welcome to nginx!가 표시되면 정상입니다.

docker compose ps
NAME                  IMAGE        COMMAND                  SERVICE   CREATED         STATUS        PORTS
hello-compose-web-1   nginx:1.29   "/docker-entrypoint.…"   web       2 seconds ago   Up 1 second   0.0.0.0:8080->80/tcp, [::]:8080->80/tcp
curl -s http://localhost:8080 | grep -o "<title>.*</title>"
<title>Welcome to nginx!</title>

8. 방화벽(ufw)과 Docker 포트

ufw 방화벽을 켜고 SSH만 허용합니다. 방화벽을 켜기 전에 반드시 SSH를 먼저 허용하세요. SSH를 허용하지 않고 방화벽을 켜면 서버 접속이 끊어집니다. --force는 확인 질문 없이 방화벽을 켜는 옵션입니다.

sudo ufw allow OpenSSH
Rules updated
Rules updated (v6)
sudo ufw --force enable
Firewall is active and enabled on system startup
sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

방화벽에는 8080 포트 규칙이 없습니다. 그런데 다른 PC에서 서버의 8080 포트로 접속하면 nginx 화면이 그대로 열립니다. 203.0.113.20은 서버의 IP로 바꾸세요.

curl -sS --max-time 10 http://203.0.113.20:8080 | grep -o "<title>.*</title>"
<title>Welcome to nginx!</title>

Docker는 포트를 연결할 때 리눅스 방화벽(iptables)에 직접 규칙을 추가하는데, 이 규칙이 ufw 규칙보다 먼저 적용되기 때문입니다. Docker가 추가한 8080 포트 규칙은 아래 명령으로 볼 수 있습니다.

sudo iptables -t nat -L DOCKER -n | grep 8080
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:172.18.0.2:80

서버 안에서만 접속하면 되는 서비스는 포트 앞에 127.0.0.1:을 붙여 서버 자신의 주소에만 연결합니다. sed -i는 파일 내용을 바꿔 바로 저장하는 명령입니다. 파일을 고친 뒤 docker compose up -d를 다시 실행하면 바뀐 설정으로 컨테이너를 다시 만듭니다.

sed -i 's/"8080:80"/"127.0.0.1:8080:80"/' compose.yaml
cat compose.yaml
services:
  web:
    image: nginx:1.29
    ports:
      - "127.0.0.1:8080:80"
docker compose up -d
 Container hello-compose-web-1 Recreate
 Container hello-compose-web-1 Recreated
 Container hello-compose-web-1 Starting
 Container hello-compose-web-1 Started

8080 포트가 127.0.0.1에서만 열려 있고, 서버 안에서는 그대로 접속됩니다.

sudo ss -tlnp | grep 8080
LISTEN 0      4096       127.0.0.1:8080      0.0.0.0:*    users:(("docker-proxy",pid=5588,fd=8))
curl -s http://localhost:8080 | grep -o "<title>.*</title>"
<title>Welcome to nginx!</title>

다른 PC에서 다시 접속하면 이번에는 연결되지 않습니다.

curl -sS --max-time 10 http://203.0.113.20:8080
curl: (28) Connection timed out after 10005 milliseconds

외부에 공개해야 하는 웹 서비스라면 Nginx 같은 웹 서버를 앞에 두고, 컨테이너 포트는 127.0.0.1에만 연결하는 방법을 권장합니다.

9. 문제 해결

permission denied while trying to connect to the docker API at unix:///var/run/docker.sock

현재 사용자가 docker 그룹에 없다는 뜻입니다. 6단계처럼 sudo usermod -aG docker $USER를 실행한 뒤 SSH 접속을 끊고 다시 접속하세요. 다시 접속하기 전에는 그룹 변경이 적용되지 않습니다. groups로 docker가 보이는지 확인하세요.

docker-compose: command not found

이 문서의 방법으로 설치하면 Compose는 docker compose(띄어쓰기) 명령으로 실행합니다. docker-compose up -d는 docker compose up -d로 바꿔 실행하세요.

ufw로 막았는데 컨테이너 포트에 외부에서 접속됩니다

Docker가 iptables에 직접 추가한 규칙이 ufw보다 먼저 적용되기 때문입니다. 8단계처럼 compose.yaml의 포트를 "127.0.0.1:8080:80" 꼴로 바꿔 서버 안에서만 접속되게 하세요.

10. 삭제하기

먼저 실행 중인 컨테이너를 멈추고 지웁니다. docker compose down은 compose.yaml로 만든 컨테이너와 네트워크를 지웁니다.

cd ~/hello-compose
docker compose down
 Container hello-compose-web-1 Stopping
 Container hello-compose-web-1 Stopped
 Container hello-compose-web-1 Removing
 Container hello-compose-web-1 Removed
 Network hello-compose_default Removing
 Network hello-compose_default Removed

Docker 패키지와 데이터를 모두 삭제합니다. 이미지, 컨테이너, 볼륨이 모두 지워지므로 필요한 데이터는 먼저 백업하세요. docker-ce-rootless-extras는 Docker를 설치할 때 함께 설치된 패키지입니다.

sudo apt purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker /var/lib/containerd

3단계에서 추가한 저장소와 서명 키도 삭제하고 패키지 목록을 갱신합니다.

sudo rm /etc/apt/sources.list.d/docker.sources /etc/apt/keyrings/docker.asc
sudo apt update

Docker 패키지가 남아 있지 않은지 확인합니다. 0이 표시되면 모두 삭제된 것입니다.

dpkg -l | grep -c -E "docker|containerd"
0

직접 해 보기

서버가 없다면 아래 업체에서 몇 분이면 Ubuntu 서버를 만들 수 있습니다. 이 문서는 DigitalOcean 에서 검증했습니다.