These steps are specifically for ARM-based EC2 instances (AWS Graviton) to host multiple websites using Docker and Caddy.
-
Launch an ARM-based Ubuntu EC2 instance (use t4g, c6g, or m6g family with Ubuntu 22.04 LTS)
-
Configure security groups:
- Allow SSH (port 22)
- Allow HTTP (port 80)
- Allow HTTPS (port 443)
-
Connect to your instance:
ssh -i your-key.pem ubuntu@your-ec2-ip
# Update the system
sudo apt update && sudo apt upgrade -y
# Install required packages
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker repository
echo "deb [arch=arm64 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
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
# Add your user to the docker group
sudo usermod -aG docker $USER
# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Apply group changes (log out and back in, or run this)
newgrp docker
# Create a main directory for hosting
mkdir -p ~/websites
cd ~/websites
# Create directories for Caddy
mkdir -p caddy/data caddy/config sites
Check for certificate directory permissions
sudo chown -R 1000:1000 caddy/data
sudo chmod -R 755 caddy/data
nano docker-compose.yml
Add the following content:
Docker Compose for Multiple Websites with Caddy (ARM-compatible)Code
nano caddy/Caddyfile
Add configuration for your websites:
Caddyfile for Multiple WebsitesCode
mkdir -p sites/website1
nano sites/website1/index.html
Add simple HTML content:
html
Copy
<!DOCTYPE html>
<html>
<head>
<title>Website 1</title>
</head>
<body>
<h1>Welcome to Website 1</h1>
<p>This is a static HTML site served through Caddy and Docker on an ARM-based EC2 instance.</p>
</body>
</html>
mkdir -p sites/website2/wordpress sites/website2/db
mkdir -p sites/website3
nano sites/website3/Dockerfile
Add Dockerfile content:
ARM-compatible Dockerfile for Node.js WebsiteCode
Configure your domain's DNS settings to point each subdomain to your EC2 instance's IP address:
- site1.example.com → Your EC2 IP
- site2.example.com → Your EC2 IP
- site3.example.com → Your EC2 IP
cd ~/websites
docker-compose up -d
# Check running containers
docker ps
# Verify container architecture
docker inspect --format '{{.Architecture}}' $(docker ps -q)
# Create a monitoring script
nano monitor.sh
Add the following content:
#!/bin/bash
echo "=== Docker Container Status ==="
docker ps -a
echo ""
echo "=== Container Architecture ==="
for container in $(docker ps -q); do
echo -n "$(docker inspect --format '{{.Name}}' $container): "
docker inspect --format '{{.Architecture}}' $container
done
echo ""
echo "=== Disk Usage ==="
df -h
echo ""
echo "=== Memory Usage ==="
free -m
echo ""
echo "=== CPU Info ==="
lscpu | grep "Architecture"
Make it executable:
chmod +x monitor.sh
- Handling ARM compatibility issues:
- If a specific image doesn't work, check the Docker Hub page for ARM64 support
- Use
docker manifest inspect image:tag
to check supported architectures - For databases, MariaDB generally has better ARM support than MySQL
- Performance tuning for ARM:
Add content:
```bash
# Create tuning script
nano arm-tune.sh
```
```bash
#!/bin/bash
# Set CPU governor to performance
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# Optimize Docker storage
echo '{
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}' | sudo tee /etc/docker/daemon.json
# Restart Docker to apply changes
sudo systemctl restart docker
```
-
Backup strategy (same as x86 but confirming ARM compatibility):
# Test backup with ARM-compatible tools mkdir -p ~/backups tar -czf ~/backups/websites-test.tar.gz ~/websites/caddy
-
Adding a fourth website with ARM compatibility: Add to docker-compose.yml:
Add to Caddyfile:
```yaml
yaml
Copy
website4:
image: python:3.9-slim
platform: linux/arm64
container_name: website4
restart: unless-stopped
volumes:
- ./sites/website4:/app
command: python -m http.server 8000
networks:
- web_network
```
```
Copy
site4.example.com {
reverse_proxy website4:8000
}
```
This setup is specifically optimized for ARM-based EC2 instances and addresses the architecture compatibility issues you were experiencing.