End-to-End Setup: AWS + PuTTY + GitHub + Docker
How to set up connects between AWS, PuTTY, GitHub, and Docker
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
- Go to
https://awsacademy.instructure.com/login/canvas - Log in with your student email
- Open the AWS Academy Learner Lab course
- Go to Modules → Launch AWS Academy Learner Lab
- Click Start Lab — wait for the indicator next to "AWS" to turn green
- Click AWS to open the AWS Management Console
1.2 Launch the EC2 Instance
- In the console, go to Services → Compute → EC2
- Click Launch Instance
- 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 |
- Click Launch Instance
- 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.
- Click Create new key pair
- Name:
Western-Student(or any name you will remember) - Key pair type: RSA
- Format:
.ppkfor Windows/PuTTY —.pemfor Mac/Linux terminal - Click Create key pair — the file downloads immediately
- Save this file. Back it up. If it is lost, you cannot access the instance.
1.4 Get Your Instance's Public Address
- Go to EC2 → Instances
- Click on your instance ID
- Copy the Public IPv4 DNS — it looks like:
ec2-XX-XX-XX-XX.compute-1.amazonaws.com - 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)
- Go to
https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html - Download the MSI ("Windows Installer") 64-bit x86 option
- Run the installer (accept all defaults)
2.2 Configure PuTTY to Connect to Your Instance
- Open PuTTY
- In Session, set Host Name to your EC2 Public IPv4 DNS from Phase 1.4
- In the left tree, go to Connection → Data
- Set Auto-login username to
ec2-user
- Set Auto-login username to
- Go to Connection → SSH → Auth → Credentials
- Click Browse next to "Private key file for authentication"
- Select your
.ppkkey file downloaded in Phase 1.3
- Go to Window → Appearance
- Click Change under Font settings
- Set font to Consolas, size 14
- Navigate back to Session
- Under Saved Sessions, type
DevOps Server - Click Save
- Under Saved Sessions, type
- Click Open
- On the first connection, a security prompt appears — click Accept
- You are now logged into your EC2 instance as
ec2-user
2.3 Connecting on Mac/Linux (No PuTTY Required)
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:
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
# 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
sudo dnf install -y git
3.3 Configure Git with Your Identity
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
- Go to
https://github.com - Click Sign up and follow the prompts
- 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):
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
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
- Go to GitHub → click your profile photo → Settings
- Click SSH and GPG keys → New SSH key
- Paste the key you copied from
cat ~/.ssh/id_rsa.pub - Give it a name (e.g.,
DevOps SSH Key) - Click Add SSH key
4.4 Test the SSH Connection
ssh -T git@github.com
Expected response: "Hi username! You've successfully authenticated..."
4.5 Create Your Repository on GitHub
- On GitHub, click the green New button
- Name the repository (e.g.,
final-project) - Set visibility to Public
- Check Add a README file
- Click Create repository
4.6 Clone the Repository to Your Local Machine
- On your repo page, click the green Code button
- Copy the SSH URL
- In your terminal:
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:
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
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
mkdir -p .github/workflows
Create .github/workflows/deploy.yml with the following content:
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.
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:
ssh-keygen -t rsa -b 4096 -C your_email@example.com
Accept the default location. Do not set a passphrase for automated workflows.
cat ~/.ssh/id_rsa.pub
Copy the full output.
5.2 Add the Instance's Key to GitHub
- Go to GitHub → Settings → SSH and GPG keys → New SSH key
- Paste the key from the instance
- Name it something like
EC2 Instance Key - Click Add SSH key
5.3 Clone Your Repo on the Instance
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:
cd ~/final-project
Create docker-compose.yml:
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
docker compose up -d
The -d flag runs all containers in the background (detached mode).
7.3 Verify All Containers Are Running
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.
- Go to EC2 → Security Groups
- Select your instance's security group
- Click Edit inbound rules → Add rule
- Add:
- Type: Custom TCP, Port: 8081, Source: Anywhere-IPv4
- Type: Custom TCP, Port: 8090, Source: Anywhere-IPv4
- 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
- Navigate to
http://YOUR-EC2-DNS:8090 - Follow the installation wizard
- 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 |
- Complete the remaining wizard steps
7.7 Push Docker Compose File to GitHub
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
- In AWS Console, go to S3 → Create bucket
- Name it with "final" in the name (e.g.,
final-docs-yourusername) - Uncheck Block all public access
- Check the acknowledgment box
- Click Create bucket
8.2 Apply a Public Read Bucket Policy
- Click your bucket → Permissions tab → Bucket policy → Edit
- Paste (replacing
YOUR_BUCKET_NAME):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
}
]
}
- Click Save changes
8.3 Upload Screenshots to S3
- Click your bucket → Objects tab → Upload → Add files
- Select your screenshot images
- Click Upload
- Click on an uploaded file and copy its URL
8.4 Reference S3 Images in Your Markdown Files
In your local markdown files:

8.5 Commit and Push — Watch CI/CD Deploy
git add .
git commit -m "Add S3 images to documentation"
git push origin main
- Go to GitHub → Actions tab
- Watch the workflow run automatically
- Wait for it to complete (green checkmark)
- 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
- Go to EC2 → Security Groups → Edit inbound rules
- Remove the "All traffic" rule if it exists
- 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
- 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:
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 |