BLOG POSTS
    MangoHost Blog / Install and Use Docker on Ubuntu 24 – Step-by-Step Hosting Setup
Install and Use Docker on Ubuntu 24 – Step-by-Step Hosting Setup

Install and Use Docker on Ubuntu 24 – Step-by-Step Hosting Setup

Docker has revolutionized how developers deploy and manage applications by containerizing them into lightweight, portable packages that run consistently across different environments. Ubuntu 24 offers excellent Docker support out of the box, making it the go-to choice for hosting setups that need scalability and isolation. In this guide, you’ll learn how to install Docker on Ubuntu 24, configure it properly for hosting environments, and deploy real applications while avoiding common setup pitfalls that can cause headaches down the road.

How Docker Works on Ubuntu 24

Docker operates using a client-server architecture where the Docker daemon manages containers, images, networks, and volumes. On Ubuntu 24, Docker leverages the kernel’s cgroup and namespace features to create isolated environments without the overhead of full virtualization. Unlike traditional VMs that virtualize hardware, Docker containers share the host OS kernel, making them incredibly efficient for resource utilization.

The containerization process works by layering filesystem changes on top of base images. When you run a container, Docker creates a thin writable layer over the read-only image layers, allowing multiple containers to share common base layers while maintaining isolation. This approach reduces storage requirements and speeds up container startup times significantly.

Feature Docker Containers Traditional VMs LXC Containers
Resource Overhead Low (10-50MB) High (512MB-2GB) Low (20-100MB)
Startup Time 1-3 seconds 30-60 seconds 2-5 seconds
Isolation Level Process-level Hardware-level OS-level
Portability Excellent Limited Good

Step-by-Step Docker Installation on Ubuntu 24

First, update your system and remove any conflicting packages that might interfere with the official Docker installation:

sudo apt update
sudo apt upgrade -y
sudo apt remove docker docker-engine docker.io containerd runc

Install the necessary dependencies for adding Docker’s official repository:

sudo apt install -y \
    ca-certificates \
    curl \
    gnupg \
    lsb-release \
    software-properties-common

Add Docker’s official GPG key and repository:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Install Docker Engine, CLI, and containerd:

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

Enable Docker to start automatically on boot and start the service:

sudo systemctl enable docker
sudo systemctl start docker
sudo systemctl status docker

Add your user to the docker group to run Docker commands without sudo:

sudo usermod -aG docker $USER
newgrp docker

Verify the installation by running the hello-world container:

docker run hello-world

Essential Docker Configuration for Hosting

For production hosting environments, you’ll want to configure Docker with specific settings that optimize performance and security. Create a daemon configuration file:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null <

Restart Docker to apply the configuration:

sudo systemctl restart docker

Configure UFW firewall to work properly with Docker:

sudo ufw --force enable
sudo ufw allow ssh
sudo ufw allow 2376/tcp
sudo ufw allow 2377/tcp
sudo ufw allow 7946/tcp
sudo ufw allow 7946/udp
sudo ufw allow 4789/udp

Real-World Hosting Examples

Let’s deploy a complete web application stack using Docker Compose. Create a project directory and compose file:

mkdir ~/docker-hosting-demo
cd ~/docker-hosting-demo

Create a docker-compose.yml file for a WordPress site with MySQL and Nginx reverse proxy:

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - wordpress
    restart: unless-stopped

  wordpress:
    image: wordpress:latest
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: secure_password_123
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress_data:/var/www/html
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: secure_password_123
      MYSQL_ROOT_PASSWORD: root_password_456
    volumes:
      - db_data:/var/lib/mysql
    restart: unless-stopped

volumes:
  wordpress_data:
  db_data:

Create a basic Nginx configuration:

cat > nginx.conf << 'EOF'
events {
    worker_connections 1024;
}

http {
    upstream wordpress {
        server wordpress:80;
    }

    server {
        listen 80;
        server_name your-domain.com;

        location / {
            proxy_pass http://wordpress;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}
EOF

Deploy the stack:

docker compose up -d

Monitor the deployment:

docker compose ps
docker compose logs -f

Performance Optimization and Monitoring

Docker on Ubuntu 24 performs exceptionally well when properly configured. Here are some key performance metrics and optimizations:

Configuration Default Performance Optimized Performance Improvement
Container Startup 2-3 seconds 0.5-1 second 60-75% faster
Image Pull Speed 50-100 MB/s 200-500 MB/s 4-5x faster
Memory Usage 100-200MB overhead 50-75MB overhead 50% reduction
I/O Performance 80% of native 95% of native 18% improvement

Install Docker monitoring tools:

docker run -d \
  --name=cadvisor \
  --restart=unless-stopped \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \
  --detach=true \
  gcr.io/cadvisor/cadvisor:latest

Set up system resource limits for containers:

docker run -d \
  --name nginx-limited \
  --memory="512m" \
  --cpus="1.0" \
  --restart=unless-stopped \
  nginx:alpine

Common Issues and Troubleshooting

Docker installations can hit several common snags. Here’s how to fix the most frequent problems:

Permission Denied Error: If you get permission errors when running Docker commands, ensure your user is in the docker group:

groups $USER
sudo usermod -aG docker $USER
logout
# Log back in

Docker Daemon Not Starting: Check the daemon status and logs:

sudo systemctl status docker
sudo journalctl -u docker.service -f

Storage Space Issues: Clean up unused Docker resources:

docker system df
docker system prune -a
docker volume prune
docker image prune -a

Network Connectivity Problems: Reset Docker’s network configuration:

sudo systemctl stop docker
sudo ip link delete docker0
sudo systemctl start docker

Container Memory Limits: Monitor and adjust container resource usage:

docker stats
docker update --memory="1g" --cpus="2.0" container_name

Best Practices for Production Hosting

When running Docker in production hosting environments, follow these essential practices:

  • Always use specific image tags instead of ‘latest’ to ensure reproducible deployments
  • Implement health checks in your Dockerfiles and compose files
  • Use multi-stage builds to reduce image sizes and attack surfaces
  • Set resource limits (CPU, memory, disk I/O) for all containers
  • Configure log rotation to prevent disk space issues
  • Use secrets management instead of environment variables for sensitive data
  • Regularly update base images and scan for vulnerabilities
  • Implement proper backup strategies for persistent volumes

Here’s a production-ready Dockerfile example:

FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:18-alpine AS runtime
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001
WORKDIR /app
COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --chown=nextjs:nodejs . .
USER nextjs
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1
CMD ["npm", "start"]

Set up automated container updates using Watchtower:

docker run -d \
  --name watchtower \
  --restart=unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower \
  --schedule "0 0 4 * * *" \
  --cleanup

Security Hardening for Docker Hosting

Security should be a top priority in any hosting environment. Configure Docker with these security enhancements:

Enable Docker Content Trust for image verification:

export DOCKER_CONTENT_TRUST=1
echo 'export DOCKER_CONTENT_TRUST=1' >> ~/.bashrc

Create a custom AppArmor profile for containers:

sudo tee /etc/apparmor.d/docker-custom << 'EOF'
profile docker-custom flags=(attach_disconnected,mediate_deleted) {
  network,
  capability,
  file,
  umount,
  deny @{PROC}/* w,
  deny @{PROC}/sys/kernel/{?,??} w,
  deny @{PROC}/sys/kernel/shm* w,
  deny @{PROC}/sysrq-trigger rwklx,
  deny @{PROC}/mem rwklx,
  deny @{PROC}/kmem rwklx,
}
EOF

sudo apparmor_parser -r /etc/apparmor.d/docker-custom

Run containers with the custom security profile:

docker run --security-opt apparmor=docker-custom \
  --user 1000:1000 \
  --read-only \
  --tmpfs /tmp \
  nginx:alpine

Docker on Ubuntu 24 provides a robust foundation for modern hosting environments. The combination of Ubuntu’s stability and Docker’s containerization creates an ideal platform for scalable applications. Remember to regularly monitor your containers, keep images updated, and follow security best practices to maintain a reliable hosting infrastructure. For additional resources, check the official Docker installation documentation and the Docker Compose reference.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked