A representative image showing the process of installing Docker and Docker Compose on Amazon Linux 2023 ARM64 EC2

Overview

This post summarizes the minimal installation steps to get Docker and Docker Compose running on Amazon Linux 2023-based EC2.

Installing packages

dnf is the package manager used on RHEL-based distributions (e.g., Fedora, RHEL, Amazon Linux 2023).

It plays the same role as apt-get on Ubuntu/Debian or yum on CentOS.

It downloads and installs packages from repositories and automatically resolves dependencies.

Updating packages

1sudo dnf update -y

Installing Docker

1sudo dnf install -y docker

Basic configuration

Enabling the Docker service

The docker command only works once the Docker daemon (dockerd) is actually running.

enable --now starts it immediately and registers it to start automatically after reboot.

1sudo systemctl enable --now docker

Granting Docker permissions to the current user

By default, the Docker socket (/var/run/docker.sock) requires root privileges.

Adding your user to the docker group lets you use Docker without prefixing every command with sudo.

newgrp docker is a command that immediately applies the group change to the current session.

The same effect is achieved by logging out and logging back in.

1sudo usermod -aG docker $USER
2newgrp docker

Verify that Docker runs

1docker version

On Amazon Linux 2023, docker compose is sometimes provided together with the Docker installation.

1docker compose version

When a separate Docker Compose installation is needed

If docker compose version fails, install the CLI plugin using the method below.

Create the directory

1mkdir -p ~/.docker/cli-plugins

Install: ARM64 (aarch64)

1curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-aarch64 \
2	-o ~/.docker/cli-plugins/docker-compose

For x86_64

1curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \
2	-o ~/.docker/cli-plugins/docker-compose

Add execute permission

1chmod +x ~/.docker/cli-plugins/docker-compose

Verify the Docker Compose installation

1docker compose version

Common issues

permission denied while trying to connect to the Docker daemon socket

This happens when usermod -aG docker was run, but the group has not yet been applied to the current shell.

1# Check the groups recognized by the current shell
2id -nG

If docker is not in the list, apply it to the current shell with newgrp docker. Since newgrp only applies to that shell, opening a new SSH session or logging out and back in will apply it automatically going forward.

no matching manifest for linux/arm64/v8

This occurs when running an amd64-only image on an ARM64 instance. It’s commonly encountered on A1 or Graviton-based instances.

First, check whether the image supports arm64.

1docker manifest inspect {image-name} | grep architecture

There are three options.

  • Use a tag that supports arm64. Most official images provide multi-architecture support.
  • Build a multi-architecture image yourself with docker buildx.
  • Run it emulated with --platform linux/amd64. This requires QEMU emulation and incurs significant performance degradation, so use it only as a temporary workaround.

Containers don’t come back up after reboot

systemctl enable --now docker only auto-starts the Docker daemon. Containers require a separately specified restart policy.

1docker run -d --restart unless-stopped {image-name}

If you’re using Compose, specify restart: unless-stopped on the service.

Good things to clean up before going into production

Limiting container log size

The default json-file driver accumulates logs without limit. This is a common cause of EC2 disk filling up.

1# /etc/docker/daemon.json
2{
3  "log-driver": "json-file",
4  "log-opts": {
5    "max-size": "10m",
6    "max-file": "3"
7  }
8}

Restart the daemon after configuring this. It does not apply to already running containers, so they need to be recreated.

1sudo systemctl restart docker

Pinning the Docker Compose version

The releases/latest address used earlier fetches a different version depending on when you download it. If you need a reproducible environment, pin the version.

1# Specify the version you checked on the releases page
2COMPOSE_VERSION={version-to-use}
3
4curl -SL https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-linux-aarch64 \
5	-o ~/.docker/cli-plugins/docker-compose
6
7chmod +x ~/.docker/cli-plugins/docker-compose
8docker compose version

Disk cleanup

1# Check usage
2docker system df
3
4# Clean up unused resources
5docker system prune
6
7# Also clean up unused images
8docker system prune -a

prune -a also deletes images referenced only by non-running containers. On a production server, check what will be removed before running it.

References