---
title: "End-to-End Setup: AWS + PuTTY + GitHub + Docker"
author: "Claude"
description: "How to set up connects between AWS, PuTTY, GitHub, and Docker"
published: "2026-02-24"
---

This document walks through the complete setup process — from a blank AWS account to a running, automatically-deploying multi-container web application. Follow the sections in order.

---

## Overview of What We're Building

```
GitHub (code repository + CI/CD automation)
    ↕  push triggers workflow
GitHub Actions (automated pipeline)
    ↕  SSH deploys to server
AWS EC2 (virtual Linux server)
    ↕  Docker runs containers on the server
Docker Compose (runs 3 services: docs, database, CMS)
    ↕  images pulled from DockerHub
DockerHub (public image registry)

AWS S3 (hosts images referenced in markdown docs)
```

---

## Phase 1 — AWS: Launch Your EC2 Instance

### 1.1 Log Into AWS Academy

1. Go to `https://awsacademy.instructure.com/login/canvas`
2. Log in with your student email
3. Open the **AWS Academy Learner Lab** course
4. Go to **Modules → Launch AWS Academy Learner Lab**
5. Click **Start Lab** — wait for the indicator next to "AWS" to turn green
6. Click **AWS** to open the AWS Management Console

### 1.2 Launch the EC2 Instance

1. In the console, go to **Services → Compute → EC2**
2. Click **Launch Instance**
3. Configure:

| Setting | Value |
|---|---|
| Name | `Final Project` |
| AMI | Red Hat Enterprise Linux 9 — Free tier eligible |
| Instance Type | `t3.medium` |
| Key Pair | Create new (see 1.3 below) |
| Network/Security Group | Create security group; check "Allow SSH traffic from Anywhere" |
| Storage | 1x 10 GiB gp3 |

4. Click **Launch Instance**
5. Click **View all instances** — wait for state to change from **Pending** to **Running**

### 1.3 Create and Save Your Key Pair

*This is done inside the launch wizard at the Key Pair step.*

1. Click **Create new key pair**
2. Name: `Western-Student` (or any name you will remember)
3. Key pair type: **RSA**
4. Format: `.ppk` for Windows/PuTTY — `.pem` for Mac/Linux terminal
5. Click **Create key pair** — the file downloads immediately
6. **Save this file.** Back it up. If it is lost, you cannot access the instance.

### 1.4 Get Your Instance's Public Address

1. Go to **EC2 → Instances**
2. Click on your instance ID
3. Copy the **Public IPv4 DNS** — it looks like:
   `ec2-XX-XX-XX-XX.compute-1.amazonaws.com`
4. Save this — you will use it for PuTTY, GitHub Secrets, and browser access

*This address resets each time the instance is stopped and restarted.*

---

## Phase 2 — PuTTY: Connect to Your Instance

*PuTTY is the SSH client for Windows that lets you control your EC2 instance from a terminal on your local machine.*

### 2.1 Install PuTTY (Windows)

1. Go to `https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html`
2. Download the **MSI ("Windows Installer") 64-bit x86** option
3. Run the installer (accept all defaults)

### 2.2 Configure PuTTY to Connect to Your Instance

1. Open PuTTY
2. In **Session**, set **Host Name** to your EC2 Public IPv4 DNS from Phase 1.4
3. In the left tree, go to **Connection → Data**
   - Set **Auto-login username** to `ec2-user`
4. Go to **Connection → SSH → Auth → Credentials**
   - Click **Browse** next to "Private key file for authentication"
   - Select your `.ppk` key file downloaded in Phase 1.3
5. Go to **Window → Appearance**
   - Click **Change** under Font settings
   - Set font to **Consolas**, size **14**
6. Navigate back to **Session**
   - Under **Saved Sessions**, type `DevOps Server`
   - Click **Save**
7. Click **Open**
8. On the first connection, a security prompt appears — click **Accept**
9. You are now logged into your EC2 instance as `ec2-user`

### 2.3 Connecting on Mac/Linux (No PuTTY Required)

```bash
ssh -l ec2-user -i ~/.ssh/Western-Student ec2-XX-XX-XX-XX.compute-1.amazonaws.com
```

*Replace the address with your actual Public IPv4 DNS. On first connection, type `yes` to accept the host key.*

### 2.4 Update Your Instance (Do This First Every Session)

Once connected via PuTTY or SSH, immediately run:

```bash
sudo dnf -y update
```

*This applies all security and software updates. Run this after every fresh launch.*

---

## Phase 3 — Instance Software Setup (via PuTTY/SSH Terminal)

*All commands in this phase are run inside the terminal connected to your EC2 instance — not on your local machine.*

### 3.1 Install Docker

```bash
# Add the Docker repository
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo

# Install Docker and dependencies
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Start Docker and enable it on boot
sudo systemctl start docker
sudo systemctl enable docker

# Add ec2-user to the docker group (avoids needing sudo for docker commands)
sudo usermod -aG docker ec2-user

# Log out and back in for the group change to take effect
exit
```

*Reconnect via PuTTY after the exit command.*

### 3.2 Install Git

```bash
sudo dnf install -y git
```

### 3.3 Configure Git with Your Identity

```bash
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
```

*These values appear on every commit. Use the same email as your GitHub account.*

---

## Phase 4 — GitHub: Repository Setup

*This phase happens on your local machine and in GitHub.com.*

### 4.1 Create a GitHub Account

1. Go to `https://github.com`
2. Click **Sign up** and follow the prompts
3. Verify your email address

### 4.2 Generate an SSH Key on Your Local Machine

In a terminal (Git Bash on Windows, Terminal on Mac/Linux):

```bash
ssh-keygen -t rsa -b 4096 -C your_email@example.com
```

- Press Enter to accept the default file location
- Optionally set a passphrase or leave blank

```bash
eval "$(ssh-agent -s)"          # Start the SSH agent
ssh-add ~/.ssh/id_rsa           # Add your key to the agent
cat ~/.ssh/id_rsa.pub           # Print your public key — copy the output
```

### 4.3 Add Your SSH Key to GitHub

1. Go to GitHub → click your profile photo → **Settings**
2. Click **SSH and GPG keys → New SSH key**
3. Paste the key you copied from `cat ~/.ssh/id_rsa.pub`
4. Give it a name (e.g., `DevOps SSH Key`)
5. Click **Add SSH key**

### 4.4 Test the SSH Connection

```bash
ssh -T git@github.com
```

*Expected response: "Hi username! You've successfully authenticated..."*

### 4.5 Create Your Repository on GitHub

1. On GitHub, click the green **New** button
2. Name the repository (e.g., `final-project`)
3. Set visibility to **Public**
4. Check **Add a README file**
5. Click **Create repository**

### 4.6 Clone the Repository to Your Local Machine

1. On your repo page, click the green **Code** button
2. Copy the **SSH** URL
3. In your terminal:

```bash
git clone git@github.com:yourusername/final-project.git
cd final-project
```

### 4.7 Create Your Project Files Locally

Inside the repo folder, create your markdown documentation files:

```bash
touch version-control.md
touch linux-fundamentals.md
touch cloud-infrastructure.md
touch containerization.md
touch index.md
```

*Edit these files in VS Code (`code .`) with your reference content. The index.md should link to each file.*

### 4.8 Stage, Commit, and Push

```bash
git add .
git commit -m "Initial documentation files"
git push origin main
```

*Go to your GitHub repo in the browser and verify the files appear.*

### 4.9 Create the GitHub Actions Workflow

```bash
mkdir -p .github/workflows
```

Create `.github/workflows/deploy.yml` with the following content:

```yaml
name: Deploy to EC2

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Deploy to EC2
      env:
        PRIVATE_KEY: ${{ secrets.EC2_SSH_KEY }}
        HOST: ${{ secrets.EC2_HOST }}
        USER: ec2-user
      run: |
        echo "$PRIVATE_KEY" > private_key.pem
        chmod 600 private_key.pem
        ssh -o StrictHostKeyChecking=no -i private_key.pem ${USER}@${HOST} '
        cd /home/ec2-user/final-project &&
        git pull origin main &&
        docker compose down &&
        docker compose up -d
        '
```

*Update the `cd` path to wherever you clone the repo on the instance in Phase 5.*

```bash
git add .
git commit -m "Add GitHub Actions deploy workflow"
git push origin main
```

---

## Phase 5 — Connect Instance to GitHub via SSH

*This creates a second SSH key — this one is on the EC2 instance so it can pull from GitHub. It is separate from the key used to connect to the instance.*

### 5.1 Generate an SSH Key on the EC2 Instance

In your PuTTY/SSH terminal connected to the instance:

```bash
ssh-keygen -t rsa -b 4096 -C your_email@example.com
```

Accept the default location. Do not set a passphrase for automated workflows.

```bash
cat ~/.ssh/id_rsa.pub
```

Copy the full output.

### 5.2 Add the Instance's Key to GitHub

1. Go to GitHub → **Settings → SSH and GPG keys → New SSH key**
2. Paste the key from the instance
3. Name it something like `EC2 Instance Key`
4. Click **Add SSH key**

### 5.3 Clone Your Repo on the Instance

```bash
cd ~
git clone git@github.com:yourusername/final-project.git
cd final-project
pwd
```

*Note the path output by `pwd` — you will need this for your deploy.yml workflow and docker-compose.yml.*

---

## Phase 6 — Add Secrets to GitHub

Go to your GitHub repo → **Settings → Secrets and variables → Actions**

Click **New repository secret** and add each of the following:

| Secret Name | Where to Get the Value |
|---|---|
| `EC2_SSH_KEY` | Contents of the `.pem` key file you downloaded in Phase 1.3 (open in a text editor and copy everything) |
| `EC2_HOST` | Your EC2 Public IPv4 DNS from Phase 1.4 |
| `AWS_ACCESS_KEY_ID` | AWS Academy → AWS Details → Show → AWS CLI |
| `AWS_SECRET_ACCESS_KEY` | AWS Academy → AWS Details → Show → AWS CLI |
| `AWS_SESSION_TOKEN` | AWS Academy → AWS Details → Show → AWS CLI |
| `AWS_REGION` | `us-east-1` |
| `S3_BUCKET_NAME` | Your S3 bucket name |

*After saving, secrets are not visible — only their names appear. To update a secret, overwrite it by creating a new one with the same name.*

---

## Phase 7 — Docker: Set Up the Multi-Container Application

*Run all commands on the EC2 instance via PuTTY/SSH.*

### 7.1 Create the Docker Compose File

Navigate to your cloned repo on the instance:

```bash
cd ~/final-project
```

Create `docker-compose.yml`:

```yaml
services:
  documentation:
    image: kobucom/pandoc:local1
    container_name: doc-final-project
    ports:
      - "8081:80"
    volumes:
      - /home/ec2-user/final-project:/usr/local/apache2/htdocs
    networks:
      - final-network
    restart: unless-stopped

  database:
    image: mysql:8.0
    container_name: database-final-project
    environment:
      - MYSQL_ROOT_PASSWORD=ComplexPass123!!
      - MYSQL_DATABASE=cms
    volumes:
      - mysql-final-data:/var/lib/mysql
    networks:
      - final-network
    restart: unless-stopped

  cms:
    image: joomla:latest
    container_name: joomla-final-project
    ports:
      - "8090:80"
    environment:
      - JOOMLA_DB_HOST=database
      - JOOMLA_DB_USER=root
      - JOOMLA_DB_PASSWORD=ComplexPass123!!
      - JOOMLA_DB_NAME=cms
    volumes:
      - web-final-data:/var/www/html
    depends_on:
      - database
    networks:
      - final-network
    restart: unless-stopped

networks:
  final-network:
    driver: bridge

volumes:
  mysql-final-data:
    driver: local
  web-final-data:
    driver: local
```

*Replace the volume path under `documentation` with the actual path output by `pwd` in Phase 5.3.*

### 7.2 Start All Containers

```bash
docker compose up -d
```

*The `-d` flag runs all containers in the background (detached mode).*

### 7.3 Verify All Containers Are Running

```bash
docker ps
```

*You should see three containers running: doc-final-project, database-final-project, and joomla-final-project.*

### 7.4 Open the Required Ports in AWS Security Group

*Containers run on ports 8081 and 8090. These must be open in the EC2 security group.*

1. Go to **EC2 → Security Groups**
2. Select your instance's security group
3. Click **Edit inbound rules → Add rule**
4. Add:
   - Type: **Custom TCP**, Port: **8081**, Source: **Anywhere-IPv4**
   - Type: **Custom TCP**, Port: **8090**, Source: **Anywhere-IPv4**
5. Click **Save rules**

### 7.5 Access Your Running Services

In a browser, replace `YOUR-EC2-DNS` with your actual Public IPv4 DNS:

| Service | URL |
|---|---|
| Documentation | `http://YOUR-EC2-DNS:8081` |
| Joomla CMS setup | `http://YOUR-EC2-DNS:8090` |

### 7.6 Complete the Joomla Installation

1. Navigate to `http://YOUR-EC2-DNS:8090`
2. Follow the installation wizard
3. On the database configuration step, enter:

| Setting | Value |
|---|---|
| Database Type | MySQLi |
| Database Host | `database` *(the service name from docker-compose.yml)* |
| Database User | `root` |
| Database Password | `ComplexPass123!!` |
| Database Name | `cms` |

4. Complete the remaining wizard steps

### 7.7 Push Docker Compose File to GitHub

```bash
git add docker-compose.yml
git commit -m "Add Docker Compose configuration"
git push origin main
```

*Pushing to main will trigger the GitHub Actions workflow. Watch it run in GitHub → Actions tab.*

---

## Phase 8 — S3: Add Images to Your Documentation

### 8.1 Create an S3 Bucket

1. In AWS Console, go to **S3 → Create bucket**
2. Name it with "final" in the name (e.g., `final-docs-yourusername`)
3. Uncheck **Block all public access**
4. Check the acknowledgment box
5. Click **Create bucket**

### 8.2 Apply a Public Read Bucket Policy

1. Click your bucket → **Permissions** tab → **Bucket policy → Edit**
2. Paste (replacing `YOUR_BUCKET_NAME`):

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
    }
  ]
}
```

3. Click **Save changes**

### 8.3 Upload Screenshots to S3

1. Click your bucket → **Objects** tab → **Upload → Add files**
2. Select your screenshot images
3. Click **Upload**
4. Click on an uploaded file and copy its URL

### 8.4 Reference S3 Images in Your Markdown Files

In your local markdown files:

```markdown
![Description of image](https://your-bucket-name.s3.us-east-1.amazonaws.com/screenshot.png)
```

### 8.5 Commit and Push — Watch CI/CD Deploy

```bash
git add .
git commit -m "Add S3 images to documentation"
git push origin main
```

1. Go to GitHub → **Actions** tab
2. Watch the workflow run automatically
3. Wait for it to complete (green checkmark)
4. Refresh `http://YOUR-EC2-DNS:8081` — your images should appear, served from S3

---

## Phase 9 — Tighten Security

*After verifying everything works, restrict the security group to only the ports you actually use.*

### 9.1 Modify the Security Group

1. Go to **EC2 → Security Groups → Edit inbound rules**
2. Remove the "All traffic" rule if it exists
3. Keep only:
   - SSH (port 22) — for terminal access via PuTTY
   - Custom TCP port 8081 — for the documentation service
   - Custom TCP port 8090 — for the Joomla CMS
4. Click **Save rules**

### 9.2 Secure Your Database Password (Production Best Practice)

The `MYSQL_ROOT_PASSWORD` in `docker-compose.yml` is stored in plain text. In a production environment, use one of these approaches instead:

**Option 1 — Environment file (.env):**

Create a `.env` file in the same directory as `docker-compose.yml`:

```
MYSQL_ROOT_PASSWORD=ComplexPass123!!
```

Reference it in `docker-compose.yml`:

```yaml
environment:
  - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
```

Add `.env` to `.gitignore` so it is never committed to GitHub.

**Option 2 — Docker Secrets** (requires Docker Swarm mode — more advanced):

Passwords are stored encrypted and injected into containers at runtime without appearing in any configuration file.

---

## Full Workflow Summary

Once everything is set up, your day-to-day workflow looks like this:

```
1. Edit markdown files locally in VS Code
2. git add .
3. git commit -m "describe your change"
4. git push origin main
        ↓
5. GitHub Actions automatically:
   - SSHs into your EC2 instance
   - Pulls the latest code from GitHub
   - Restarts Docker containers
        ↓
6. Refresh your browser at http://YOUR-EC2-DNS:8081
   to see the updated documentation — images served from S3
```

---

## Quick Reference: Where Everything Lives

| Component | Location |
|---|---|
| GitHub repo | `https://github.com/yourusername/final-project` |
| EC2 instance | AWS Console → EC2 → Instances |
| Repo on instance | `/home/ec2-user/final-project` |
| Docker Compose file | `/home/ec2-user/final-project/docker-compose.yml` |
| Deploy workflow | `.github/workflows/deploy.yml` |
| S3 bucket | AWS Console → S3 → your bucket name |
| Documentation site | `http://YOUR-EC2-DNS:8081` |
| Joomla CMS | `http://YOUR-EC2-DNS:8090` |
| GitHub Secrets | Repo → Settings → Secrets and variables → Actions |
