Skip to main content

Installing Docker

How to install Docker Engine and Docker Compose on a VM, including environments where curl and wget are blocked.


Quick Install (Unrestricted Internet)​

If the VM has unrestricted outbound internet access:

Ubuntu / Debian​

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker

CentOS / RHEL / Amazon Linux​

curl -fsSL https://get.docker.com | sh
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
newgrp docker

Verify​

docker --version # 24.0+ required
docker compose version # v2 required

Enterprise / Restricted Install (No curl or wget)​

Use this path when the VM's security policy blocks curl, wget, or the Docker convenience script. The GPG key is downloaded on a machine with internet access and transferred to the VM via scp.

Debian 12 (Bookworm) — amd64​

On your local machine (with internet):

# Download the Docker GPG key
curl -fsSL https://download.docker.com/linux/debian/gpg -o docker.asc

# Transfer to the VM
scp docker.asc user@VM_IP:/tmp/

You can also download https://download.docker.com/linux/debian/gpg in a browser and save it as docker.asc.

On the VM:

# Install the GPG key
sudo mkdir -p /etc/apt/keyrings
sudo mv /tmp/docker.asc /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the Docker repository
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<'EOF'
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: bookworm
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF

# Install Docker
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Add your user to the docker group
sudo usermod -aG docker $USER
newgrp docker

Debian 12 (Bookworm) — arm64​

Identical to amd64. The Docker repo automatically serves the correct architecture. Use the same GPG key and the same docker.sources entry — apt resolves the right arm64 packages.

Ubuntu 22.04 / 24.04 — amd64 / arm64​

On your local machine:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o docker.asc
scp docker.asc user@VM_IP:/tmp/

On the VM:

sudo mkdir -p /etc/apt/keyrings
sudo mv /tmp/docker.asc /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Detect the Ubuntu codename automatically
CODENAME=$(. /etc/os-release && echo "$VERSION_CODENAME")

sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $CODENAME
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF

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

sudo usermod -aG docker $USER
newgrp docker

CentOS / RHEL 8+ / Amazon Linux 2023 — amd64 / arm64​

On your local machine:

curl -fsSL https://download.docker.com/linux/centos/gpg -o docker.asc
scp docker.asc user@VM_IP:/tmp/

On the VM:

sudo rpm --import /tmp/docker.asc

sudo tee /etc/yum.repos.d/docker-ce.repo > /dev/null <<'EOF'
[docker-ce-stable]
name=Docker CE Stable
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=file:///tmp/docker.asc
EOF

sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker

sudo usermod -aG docker $USER
newgrp docker
Amazon Linux 2023

Amazon Linux 2023 uses the CentOS/RHEL repos. Use baseurl=https://download.docker.com/linux/centos/9/$basearch/stable (hardcode 9 instead of $releasever).


Full Airgap (No Outbound Internet at All)​

If the VM cannot reach download.docker.com or any package mirrors, you must download .deb or .rpm files on a connected machine and transfer them.

Debian / Ubuntu​

On your local machine, download the five packages from download.docker.com (adjust the path for your OS, release, and architecture):

  • containerd.io
  • docker-ce-cli
  • docker-ce
  • docker-buildx-plugin
  • docker-compose-plugin
# Transfer all .deb files to the VM
scp *.deb user@VM_IP:/tmp/

# On the VM
cd /tmp
sudo dpkg -i ./containerd.io_*.deb ./docker-ce-cli_*.deb ./docker-ce_*.deb \
./docker-buildx-plugin_*.deb ./docker-compose-plugin_*.deb
sudo apt-get install -f -y

sudo usermod -aG docker $USER
newgrp docker

CentOS / RHEL​

Download the five .rpm packages from download.docker.com (adjust for architecture).

scp *.rpm user@VM_IP:/tmp/

# On the VM
cd /tmp
sudo yum localinstall -y ./containerd.io-*.rpm ./docker-ce-cli-*.rpm ./docker-ce-*.rpm \
./docker-buildx-plugin-*.rpm ./docker-compose-plugin-*.rpm
sudo systemctl enable --now docker

sudo usermod -aG docker $USER
newgrp docker

Common Issues​

apt update fails with TLS errors​

The VM's firewall or proxy is blocking HTTPS to download.docker.com. Options:

  1. Allowlist download.docker.com in the firewall/proxy
  2. Set up an internal apt mirror
  3. Use the full airgap method

apt update fails with GPG errors​

The GPG key wasn't installed correctly. Verify:

file /etc/apt/keyrings/docker.asc
# Should say "PGP public key block"

If it says "HTML document" or similar, the download was intercepted by a proxy. Re-download the key or transfer it via a different method.

Permission denied after newgrp​

Log out and SSH back in. The docker group membership only takes effect in new login sessions.

Docker installed but docker compose not found​

You have Docker but not the Compose plugin. Install it:

# Debian/Ubuntu
sudo apt-get install -y docker-compose-plugin

# CentOS/RHEL
sudo yum install -y docker-compose-plugin