Skip to main content

Docker CE 29.2.1 + Compose v5.0.2 (Ubuntu 24.04) AMI Administrator Guide

1. Quick Start Information

Connection Methods:

  • Access the instance via SSH using the ubuntu user. Use sudo to run commands requiring root privileges. To switch to the root user, use sudo su - root.

Install Information:

  • OS: Ubuntu 24.04 LTS
  • Docker version: 29.2.1 (Docker CE - Community Edition)
  • Docker Compose version: v5.0.2 (Docker Compose Plugin)
  • Containerd version: Latest stable
  • Installation Source: Docker Official Repository
  • Configuration File: /etc/docker/daemon.json

Docker Service Management:

  • Start Docker service: sudo systemctl start docker
  • Stop Docker service: sudo systemctl stop docker
  • Restart Docker service: sudo systemctl restart docker
  • Check Docker status: sudo systemctl status docker
  • Enable auto-start: sudo systemctl enable docker

Quick Verification Commands:

  • Check Docker version: docker --version
  • Check Compose version: docker compose version
  • List running containers: docker ps
  • List all containers: docker ps -a
  • List images: docker images
  • View Docker info: docker info

User Permissions:

  • The ubuntu user is added to the docker group for sudo-free Docker commands
  • Important: Log out and log back in for group changes to take effect
  • Temporary activation: newgrp docker

Firewall Configuration:

  • Please allow SSH port 22.
  • For Docker containers exposing services, open required ports in the security group.
  • For security, it is recommended to limit SSH access to trusted IPs only.

2. First Launch & Verification

Step 1: Connect to Your Instance

  1. Launch your instance in your cloud provider's console (e.g., AWS EC2)
  2. Ensure SSH port 22 is allowed in your security group
  3. Connect via SSH:
    ssh -i your-key.pem ubuntu@YOUR_PUBLIC_IP

Step 2: Verify Docker Installation

Check Docker version:

docker --version

Expected Output:

Docker version 29.2.1, build a5c7197

Check Docker Compose version:

docker compose version

Expected Output:

Docker Compose version v5.0.2

Step 3: Verify Docker Service Status

Check if Docker daemon is running:

sudo systemctl status docker

Expected Output:

● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-02-13 03:53:44 UTC

Step 4: Test Docker with Hello World

Run a test container:

docker run --rm hello-world

Expected Output:

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

How This Works:

  • docker run: Creates and starts a new container
  • --rm: Automatically removes the container when it exits
  • hello-world: A minimal test image from Docker Hub
  • Docker pulls the image (if not present), runs it, displays output, and exits

Step 5: Verify User Permissions

Check if the ubuntu user is in the docker group:

groups ubuntu

Expected Output:

ubuntu : ubuntu adm cdrom sudo dip plugdev lxd docker

Note: If docker is not listed, log out and log back in, or run newgrp docker.


3. Architecture & Detailed Configuration

This AMI uses the Docker CE (Community Edition) from the official Docker repository, ensuring you get the latest stable version with security updates and new features.

Installation Architecture:

[Docker Official Repository]

[docker-ce 29.2.1] → /usr/bin/docker
[docker-ce-cli] → /usr/bin/docker (CLI)
[containerd.io] → /usr/bin/containerd (Runtime)
[docker-buildx-plugin] → BuildKit builder
[docker-compose-plugin] → /usr/libexec/docker/cli-plugins/docker-compose

[Docker Daemon Configuration]

/etc/docker/daemon.json → Log rotation settings

[User Permissions]

ubuntu user → docker group (sudo-free access)

[Systemd Service]

docker.service → Auto-start on boot

Key Design Decisions:

  1. Official Repository: Uses Docker Inc.'s official apt repository instead of Ubuntu's outdated packages
  2. Docker Compose V2: Modern plugin-based Compose (docker compose command)
  3. Log Rotation: Prevents disk space exhaustion from container logs
  4. Sudo-Free Access: ubuntu user added to docker group for better UX
  5. Auto-Start: Docker daemon enabled to start automatically on boot

3.1. Docker Daemon Configuration

File Location: /etc/docker/daemon.json

File Content:

{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}

How This Works:

  • log-driver: json-file: Uses JSON file logging (default, but explicit)
  • max-size: 100m: Each log file is limited to 100 MB
  • max-file: 3: Keeps a maximum of 3 log files per container

Why This Is Critical:

Without log rotation, container logs grow indefinitely and can fill up disk space, causing system failures. This configuration ensures:

  • Maximum log size per container: 300 MB (3 files × 100 MB)
  • Automatic old log deletion when limit is reached
  • Production-grade log management

Example Calculation:

10 containers × 3 log files × 100 MB = 3 GB maximum log storage

3.2. Docker Repository Configuration

File Location: /etc/apt/sources.list.d/docker.list

File Content:

deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable

GPG Key Location: /etc/apt/keyrings/docker.asc

How This Works:

  • arch=amd64: Specifies architecture (x86_64)
  • signed-by=/etc/apt/keyrings/docker.asc: Verifies package signatures with Docker's GPG key
  • noble: Ubuntu 24.04 codename
  • stable: Stable release channel

Why Official Repository?

  • Ubuntu's default Docker packages (docker.io) are often outdated
  • Official repository provides latest stable releases
  • Security patches delivered faster
  • Access to Docker Compose V2 and BuildKit

4. How-To-Create: Reproduce This Environment

This section explains how this AMI was built, allowing you to reproduce the installation on any Ubuntu 24.04 system.

Step 1: Remove Old Docker Versions

Purpose: Clean up any existing Docker installations to avoid conflicts.

# Remove old Docker packages
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt-get remove $pkg
done

# Update package index
sudo apt-get update

# Install prerequisite packages
sudo apt-get install -y ca-certificates curl

How This Works:

  • docker.io: Ubuntu's old Docker package
  • docker-doc, docker-compose: Old documentation and compose versions
  • podman-docker: Alternative container runtime that can conflict
  • ca-certificates: Required for HTTPS connections to Docker repository
  • curl: Used to download Docker's GPG key

Why Remove Old Versions?

Mixing old Ubuntu packages with new Docker CE packages can cause:

  • Binary conflicts
  • Configuration incompatibilities
  • Service startup failures

Step 2: Add Docker Official Repository

Purpose: Configure apt to use Docker Inc.'s official package repository.

# Create keyrings directory
sudo install -m 0755 -d /etc/apt/keyrings

# Download Docker's official GPG key
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

# Make key readable
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add Docker repository to apt sources
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Update package index with new repository
sudo apt-get update

How This Works:

  • install -m 0755 -d: Creates directory with specific permissions (rwxr-xr-x)
  • curl -fsSL: Downloads GPG key silently (-s), follows redirects (-L), fails on errors (-f)
  • dpkg --print-architecture: Auto-detects system architecture (amd64, arm64, etc.)
  • VERSION_CODENAME: Extracted from /etc/os-release, identifies Ubuntu version (noble = 24.04)

GPG Key Verification:

The GPG key ensures that packages are:

  • Signed by Docker Inc.
  • Not tampered with during transmission
  • Authentic and trusted

Step 3: Install Docker Engine

Purpose: Install Docker CE, CLI tools, Containerd runtime, and plugins.

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

How This Works:

  • docker-ce: Docker Engine (daemon)
  • docker-ce-cli: Docker command-line interface
  • containerd.io: Container runtime (manages container lifecycle)
  • docker-buildx-plugin: BuildKit-based builder (modern image building)
  • docker-compose-plugin: Docker Compose V2 (replaces standalone docker-compose)

Package Relationships:

docker-ce (Daemon)

containerd.io (Runtime)

Containers (Running processes)

docker-ce-cli (Commands)

docker-buildx-plugin (Image building)
docker-compose-plugin (Multi-container apps)

Step 4: Configure Log Rotation and User Permissions

Purpose: Set up production-grade log management and enable sudo-free Docker access.

# Add ubuntu user to docker group
sudo usermod -aG docker ubuntu

# Create daemon configuration file
sudo tee /etc/docker/daemon.json > /dev/null <<EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
EOF

# Restart Docker to apply configuration
sudo systemctl restart docker

# Enable Docker to start on boot
sudo systemctl enable docker

How This Works:

  • usermod -aG docker ubuntu: Adds user to docker group without removing from other groups
  • tee /etc/docker/daemon.json: Creates configuration file with log rotation settings
  • systemctl restart docker: Reloads configuration
  • systemctl enable docker: Creates systemd symlink for auto-start

Group Membership Note:

After adding user to docker group:

  • Immediate effect: Not available (cached credentials)
  • Temporary activation: newgrp docker in current shell
  • Permanent activation: Log out and log back in

5. Using the Docker Environment

5.1. Running Your First Container

Pull and run an Ubuntu container:

docker run -it ubuntu:24.04 bash

Inside the container:

# You're now inside the container
cat /etc/os-release
# Shows: Ubuntu 24.04 (Noble Numbat)

# Exit the container
exit

How This Works:

  • docker run: Create and start a container
  • -it: Interactive mode with pseudo-TTY (terminal)
  • ubuntu:24.04: Image name and tag from Docker Hub
  • bash: Command to run inside the container

5.2. Running a Web Server

Run an Nginx web server:

# Run Nginx on port 8080
docker run -d -p 8080:80 --name my-nginx nginx:alpine

# Verify container is running
docker ps

# Test the web server
curl http://localhost:8080

# View logs
docker logs my-nginx

# Stop and remove container
docker stop my-nginx
docker rm my-nginx

Port Mapping Explained:

  • -p 8080:80: Maps host port 8080 to container port 80
  • 8080: External port (accessible from outside)
  • 80: Internal port (inside container)

5.3. Using Docker Compose

Create a simple application:

# Create project directory
mkdir my-app && cd my-app

# Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html

redis:
image: redis:alpine
ports:
- "6379:6379"
EOF

# Create HTML content
mkdir html
echo "<h1>Hello from Docker Compose!</h1>" > html/index.html

# Start services
docker compose up -d

# View running services
docker compose ps

# View logs
docker compose logs -f

# Stop services
docker compose down

Docker Compose V2 Note:

  • Command: docker compose (integrated plugin)
  • Old command: docker-compose (standalone, deprecated)
  • This AMI uses V2 (modern, faster, better integration)

5.4. Building Custom Images

Create a Dockerfile:

cat > Dockerfile << 'EOF'
FROM ubuntu:24.04

# Install packages
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*

# Set working directory
WORKDIR /app

# Copy application
COPY app.py .

# Run application
CMD ["python3", "app.py"]
EOF

# Create sample app
cat > app.py << 'EOF'
print("Hello from custom Docker image!")
EOF

# Build image
docker build -t my-python-app:1.0 .

# Run container
docker run --rm my-python-app:1.0

5.5. Managing Images and Containers

Cleanup Commands:

# Remove stopped containers
docker container prune

# Remove unused images
docker image prune -a

# Remove unused volumes
docker volume prune

# Remove everything (containers, images, volumes, networks)
docker system prune -a --volumes

# Check disk usage
docker system df

6. Important File Locations

File PathPurpose
/usr/bin/dockerDocker CLI binary
/usr/bin/dockerdDocker daemon binary
/usr/bin/containerdContainer runtime
/usr/libexec/docker/cli-plugins/docker-composeDocker Compose plugin
/etc/docker/daemon.jsonDocker daemon configuration
/etc/apt/sources.list.d/docker.listDocker repository configuration
/etc/apt/keyrings/docker.ascDocker GPG signing key
/var/lib/docker/Docker data directory (images, containers, volumes)
/var/lib/docker/containers/Container filesystems and metadata
/var/lib/docker/volumes/Docker volumes data
/var/run/docker.sockDocker daemon socket (API endpoint)
/usr/lib/systemd/system/docker.serviceSystemd service file

7. Troubleshooting

Issue 1: Permission Denied When Running Docker

Symptoms:

$ docker ps
permission denied while trying to connect to the Docker daemon socket

Diagnosis:

User is not in the docker group.

Solution:

Verify group membership:

groups
# If "docker" is not listed:

Option 1: Temporary (current shell only):

newgrp docker

Option 2: Permanent (requires re-login):

# Log out and log back in via SSH
exit
ssh -i your-key.pem ubuntu@YOUR_PUBLIC_IP

Issue 2: Docker Service Not Running

Symptoms:

$ docker ps
Cannot connect to the Docker daemon

Diagnosis:

Docker daemon is not running.

Solution:

Start Docker service:

sudo systemctl start docker
sudo systemctl enable docker

Check status:

sudo systemctl status docker

View logs if failing:

sudo journalctl -u docker -n 50 --no-pager

Issue 3: Disk Space Full

Symptoms:

$ docker build -t myapp .
Error: no space left on device

Diagnosis:

Docker images, containers, or logs consuming too much disk space.

Solution:

Check disk usage:

docker system df

Example Output:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images 10 2 5GB 3GB (60%)
Containers 5 1 1GB 800MB (80%)
Local Volumes 3 1 2GB 1.5GB (75%)
Build Cache 0 0 0B 0B

Clean up:

# Remove unused containers, networks, images
docker system prune

# Aggressive cleanup (removes all unused data)
docker system prune -a --volumes

Issue 4: Container Logs Too Large

Symptoms:

Disk fills up over time even after cleanup.

Diagnosis:

Container logs are not being rotated.

Solution:

Verify log configuration:

cat /etc/docker/daemon.json

Should show:

{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}

If missing, create it and restart Docker:

sudo systemctl restart docker

Manual Log Cleanup:

# Find large log files
sudo find /var/lib/docker/containers/ -name "*.log" -exec ls -lh {} \;

# Truncate specific container log
sudo truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log

Issue 5: Port Already in Use

Symptoms:

$ docker run -p 8080:80 nginx
Error: Bind for 0.0.0.0:8080 failed: port is already allocated

Diagnosis:

Another container or process is using port 8080.

Solution:

Find what's using the port:

sudo lsof -i :8080
# or
sudo netstat -tulpn | grep 8080

Stop the conflicting container:

docker ps | grep 8080
docker stop <container-id>

Or use a different port:

docker run -p 8081:80 nginx

Issue 6: Cannot Pull Images

Symptoms:

$ docker pull ubuntu:24.04
Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io: no such host

Diagnosis:

Network connectivity or DNS issue.

Solution:

Test internet connectivity:

ping -c 3 google.com
curl -I https://registry-1.docker.io

Check Docker daemon status:

sudo systemctl status docker

Restart Docker:

sudo systemctl restart docker

8. Final Notes

Key Takeaways

  1. Docker CE 29.2.1 is installed from the official Docker repository
  2. Docker Compose V2 is available as a plugin (docker compose command)
  3. Log rotation is configured to prevent disk space exhaustion
  4. Sudo-free access for the ubuntu user via docker group membership
  5. The installation is production-ready and AMI-optimized

Docker Use Cases

  • Microservices Deployment: Run containerized applications
  • Development Environments: Isolated, reproducible dev setups
  • CI/CD Pipelines: Build, test, and deploy with containers
  • Application Packaging: Bundle apps with all dependencies
  • Multi-Version Testing: Run different software versions simultaneously

Additional Resources

Support

If you encounter issues not covered in this guide:

  1. Check the troubleshooting section above
  2. Review Docker official documentation
  3. Verify your security group and firewall settings
  4. Check Docker logs: sudo journalctl -u docker -n 100

For support or questions, please contact the Easycloud team.