This project demonstrates how to use Docker Compose to build a multi-container environment for a static website deployment using Nginx and Watchtower on an AWS EC2 instance.
The goal of this task was to automate the web server setup, enable live content updates, and manage container auto-updates using Watchtower β showcasing real-world DevOps practices.
NulClass Internship β DevOps Project Task 03
By: Aman Raj Raw
π B.Tech CSE | π» DevOps & Cloud Enthusiast
π§ amanrajraw@example.com
π GitHub: Amanrajraw0
| Tool / Technology | Purpose |
|---|---|
| Docker | Containerization of applications |
| Docker Compose | Managing multi-container environments |
| Nginx | Hosting and serving the static website |
| Watchtower | Auto-updating Docker containers |
| AWS EC2 (Ubuntu 22.04) | Cloud instance for deployment |
| GitHub | Version control and project hosting |
- Launched an Ubuntu EC2 instance (Free Tier
t3.micro) in AWS regioneu-north-1 (Stockholm). - Configured Security Group:
- Port
22β SSH access - Port
80β HTTP web traffic
- Port
sudo apt update -y
sudo apt install -y docker.io
sudo systemctl enable docker
sudo systemctl start docker
docker --versionsudo apt install docker-compose-plugin -y
docker compose versionβ Docker and Docker Compose installed successfully.
task03-docker-compose/
β
βββ docker-compose.yml # Multi-container setup (Nginx + Watchtower)
βββ nginx/
β βββ index.html # Static website (auto-updates live)
β βββ nginx.conf # Nginx configuration
βββ .gitignore # Keeps repo clean and secure
βββ README.md # Project documentationversion: "3.8"
services:
nginx:
image: nginx:latest
container_name: nginx_web
ports:
- "${NGINX_PORT}:80"
volumes:
# Mount EC2 files directly into the container
- /home/ubuntu/task03-docker-compose/nginx/index.html:/usr/share/nginx/html/index.html
- /home/ubuntu/task03-docker-compose/nginx/nginx.conf:/etc/nginx/nginx.conf
environment:
- ENVIRONMENT=${ENVIRONMENT}
# Prevent Watchtower from replacing this container
labels:
- "com.centurylinklabs.watchtower.enable=false"
restart: always
watchtower:
image: containrrr/watchtower
container_name: watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --cleanup --interval 3600
restart: always- Nginx Container β Serves the website from the
nginx/folder. - Watchtower Container β Automatically checks and updates images every 1 hour.
- Bind Mounts β Ensure local HTML edits instantly reflect live on the site.
- Restart Policy β Ensures containers always start automatically on system reboot.
- Watchtower Label β Disables automatic Nginx image updates, keeping your custom changes safe.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Task 03 β Docker Compose Multi-Environment</title>
</head>
<body>
<h1>β
Task 03 β Docker Compose Multi-Environment Setup</h1>
<p>This static website is running inside a Docker container managed by Docker Compose.</p>
<p>By: <b>Aman Raj Raw</b> | B.Tech CSE | DevOps & Cloud Enthusiast</p>
<hr>
<h3>π§ Live Edit Demonstration</h3>
<p>Edit this file in <code>~/task03-docker-compose/nginx/index.html</code> to see instant updates without restarting Docker.</p>
<hr>
<h2>π Task 02 Summary (Terraform EC2 Automation)</h2>
<p>Created EC2 instance, opened ports 80/22, and auto-installed Docker using Terraform <code>user_data</code>.</p>
<h2>π³ Task 03 Summary (Docker Compose Setup)</h2>
<p>Deployed a multi-container setup (Nginx + Watchtower) with auto-update and live-edit capability.</p>
</body>
</html>sudo docker compose up -dβ Expected Output:
β Network created
β Container nginx_web started
β Container watchtower started
Check running containers:
sudo docker psExpected:
CONTAINER ID IMAGE PORTS NAMES
xxxxxxx nginx:latest 0.0.0.0:80->80/tcp nginx_web
xxxxxxx containrrr/watchtower 8080/tcp watchtowerThen open your EC2 public IP in browser:
http://13.60.223.121/β Youβll see your Task 03 webpage live.
sudo nano ~/task03-docker-compose/nginx/index.htmlAdd a new line β save β refresh your browser.
β
Changes appear instantly!
No docker restart needed β because of bind mounts.
Create .gitignore :
cat > .gitignore << 'EOF'
*.log
*.tmp
*.bak
*.swp
.docker/
.env
.aws/
*.pem
*.key
*.crt
EOFCommit and push clean repo via SSH:
git add .
git commit -m "Task03 β Docker Compose Multi-Environment Setup | NulClass Internship"
git push -u origin main| Step | Description | Status |
|---|---|---|
| β Docker Compose Up | Containers running successfully | βοΈ |
| π§ Live HTML Edit | Instant update verified | βοΈ |
| π οΈ Watchtower Logs | Auto-update service active | βοΈ |
| π Public Site | Accessible via EC2 IP | βοΈ |
| π¦ GitHub Repo | Clean structure, no credentials | βοΈ |
- Building multi-container environments using Docker Compose
- Understanding bind mounts for real-time file sync
- Managing auto-updates with Watchtower
- Deploying and maintaining containerized apps on AWS EC2
- Maintaining secure and professional GitHub DevOps repositories
This task demonstrates how to design and deploy an automated multi-environment setup using Docker Compose, ensuring scalability, maintainability, and real-time updates.
It combines automation (Task 02 β Terraform) and container orchestration (Task 03 β Docker Compose) to represent a real-world DevOps workflow.
Aman Raj Raw
π B.Tech CSE | π» DevOps & Cloud Enthusiast
π§ amanrajraw0gmail.com
π GitHub: Amanrajraw0
Thanks to NulClass for assigning this hands-on DevOps project. It provided real-world exposure to containerization, automation, and modern deployment workflows.