A is for Agent - Production Deployment Guide

This guide covers deploying the Jekyll website to production server 31.97.61.154 with Traefik reverse proxy and OAuth2 authentication.

πŸ“‹ Table of Contents


πŸ—οΈ Architecture Overview

Components

Internet (Port 80/443)
          ↓
    Traefik Proxy (existing)
          ↓
    β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    ↓                        ↓
OAuth2-Proxy          Nginx (Static Site)
(GitHub Auth)         (Jekyll Build)
    ↓                        ↓
Protected Routes      Public Routes
(/portal/*, etc.)     (/, /docs/, etc.)

Services

Service Container Name Port Purpose
Nginx aifa-site 80 (internal) Serves static Jekyll site
OAuth2-Proxy aifa-oauth2-proxy 4180 (internal) GitHub authentication
Traefik (existing) 80, 443 Reverse proxy, SSL termination

Networks

  • traefik-public - External network (connects to Traefik)
  • aifa-internal - Internal network (site ↔ oauth2-proxy)

Routing Rules

URL Pattern Authentication Handler
https://www.aisforagent.net/ Public Nginx β†’ Jekyll site
https://www.aisforagent.net/portal/* Protected OAuth2-Proxy β†’ Nginx
https://www.aisforagent.net/workflows/* Protected OAuth2-Proxy β†’ Nginx
https://www.aisforagent.net/blueprints/* Protected OAuth2-Proxy β†’ Nginx
https://www.aisforagent.net/playbooks/* Protected OAuth2-Proxy β†’ Nginx
https://www.aisforagent.net/oauth2/* Public OAuth2-Proxy (auth endpoints)

βœ… Prerequisites

Local Requirements

  • Docker installed and running
  • SSH access to production server
  • SSH key at ~/git/Foundry/S6web/key.file
  • Git repository cloned locally

Server Requirements

  • βœ… Traefik already running with traefik-public network
  • βœ… DNS records pointing to server:
    • www.aisforagent.net β†’ 31.97.61.154
    • aisforagent.net β†’ 31.97.61.154
  • βœ… Ports 80 and 443 accessible
  • βœ… Traefik middleware file at ~/traefik/middlewares.yml

GitHub OAuth Application

You’ll need to create a GitHub OAuth App for authentication:

  1. Go to GitHub Developer Settings
  2. Click β€œNew OAuth App”
  3. Fill in:
    • Application name: A is for Agent
    • Homepage URL: https://www.aisforagent.net
    • Authorization callback URL: https://www.aisforagent.net/oauth2/callback
  4. Save and note the Client ID and Client Secret

πŸš€ Initial Setup

1. Clone Repository (if not already done)

cd ~/git/a/Foundry
git clone <repository-url> aWebsite
cd aWebsite

2. Configure Environment Variables

Copy the example environment file:

cp .env.prod.example .env.prod

Edit .env.prod with your credentials:

nano .env.prod  # or use your preferred editor

Required values:

  • OAUTH2_PROXY_CLIENT_ID - Your GitHub OAuth Client ID
  • OAUTH2_PROXY_CLIENT_SECRET - Your GitHub OAuth Client Secret
  • OAUTH2_PROXY_COOKIE_SECRET - Generate with: openssl rand -base64 32

Example .env.prod:

OAUTH2_PROXY_CLIENT_ID=abc123def456
OAUTH2_PROXY_CLIENT_SECRET=secret789xyz
OAUTH2_PROXY_COOKIE_SECRET=ABCDEFGHabcdefgh1234567890ABCDEF==
DOMAIN=www.aisforagent.net
ENVIRONMENT=production

Optional: Restrict access to specific GitHub users/orgs:

OAUTH2_PROXY_GITHUB_USERS=username1,username2
# or
OAUTH2_PROXY_GITHUB_ORG=your-org-name

3. Add SSH Key to Agent

ssh-add ~/git/Foundry/S6web/key.file
# Enter passphrase when prompted

Verify:

ssh-add -l

βš™οΈ Configuration

DNS Configuration

Ensure DNS records are set:

# Check DNS resolution
dig www.aisforagent.net +short
# Should return: 31.97.61.154

dig aisforagent.net +short
# Should return: 31.97.61.154

Traefik Middleware

The deployment uses existing Traefik middleware from ~/traefik/middlewares.yml:

  • frontend-security@file - Security headers for web apps
  • compression@file - Gzip compression
  • redirect-to-https@file - HTTP to HTTPS redirect

These are already configured on the server.


🚒 Deployment

Build locally and deploy to server:

./deploy-prod.sh
# or
./deploy-prod.sh --full

This will:

  1. βœ“ Build Docker image locally
  2. βœ“ Test the image
  3. βœ“ Prepare remote server
  4. βœ“ Transfer all files
  5. βœ“ Build and deploy on server
  6. βœ“ Verify deployment

Option 2: Build Only

Build and test locally without deploying:

./deploy-prod.sh --build-only

Then deploy separately:

./deploy-prod.sh --deploy-only

Option 3: Manual Deployment

If the script doesn’t work, deploy manually:

# 1. Add SSH key
ssh-add ~/git/Foundry/S6web/key.file

# 2. Create remote directory
ssh root@31.97.61.154 "mkdir -p ~/aifa-website"

# 3. Transfer files
scp docker-compose.prod.yml root@31.97.61.154:~/aifa-website/
scp .env.prod root@31.97.61.154:~/aifa-website/
scp Dockerfile root@31.97.61.154:~/aifa-website/
scp nginx.conf root@31.97.61.154:~/aifa-website/

# 4. Transfer site content
rsync -avz --exclude '_site' --exclude '.git' \
  -e "ssh" ./ root@31.97.61.154:~/aifa-website/

# 5. Build and deploy
ssh root@31.97.61.154 "cd ~/aifa-website && docker-compose -f docker-compose.prod.yml up -d --build"

βœ“ Verification

1. Check Container Status

ssh root@31.97.61.154 "docker ps | grep aifa"

Expected output:

aifa-site            Up X minutes (healthy)
aifa-oauth2-proxy    Up X minutes (healthy)

2. Check Logs

Site logs:

ssh root@31.97.61.154 "docker logs -f aifa-site"

OAuth2-Proxy logs:

ssh root@31.97.61.154 "docker logs -f aifa-oauth2-proxy"

3. Test Endpoints

Public homepage:

curl -I https://www.aisforagent.net
# Expected: 200 OK

Health check:

curl https://www.aisforagent.net/health
# Expected: healthy

OAuth2 endpoint (should redirect to login):

curl -I https://www.aisforagent.net/oauth2/userinfo
# Expected: 401 Unauthorized (not logged in)

Protected portal (should redirect to GitHub):

curl -I https://www.aisforagent.net/portal/
# Expected: 302 or 303 redirect to GitHub

4. Browser Testing

  1. Public Access:
    • Visit https://www.aisforagent.net
    • Should see homepage with β€œDownload” CTA
    • No authentication required
  2. Authentication Flow:
    • Click on /portal/ link
    • Should redirect to GitHub OAuth
    • Log in with GitHub
    • Should redirect back to portal
  3. Authenticated Access:
    • After login, homepage should show β€œPremium Services” CTA
    • Portal, workflows, blueprints, and playbooks should be accessible
    • /oauth2/userinfo should return 200

5. SSL Certificate

Check SSL certificate:

openssl s_client -connect www.aisforagent.net:443 -servername www.aisforagent.net

Should show:

  • Valid Let’s Encrypt certificate
  • Expires in ~90 days
  • Subject: CN=www.aisforagent.net

πŸ”§ Troubleshooting

Issue: Containers Not Starting

Check logs:

ssh root@31.97.61.154 "docker logs aifa-site"
ssh root@31.97.61.154 "docker logs aifa-oauth2-proxy"

Check container status:

ssh root@31.97.61.154 "docker ps -a | grep aifa"

Restart containers:

ssh root@31.97.61.154 "cd ~/aifa-website && docker-compose -f docker-compose.prod.yml restart"

Issue: Site Not Accessible (404/503)

Check Traefik can see the service:

ssh root@31.97.61.154 "docker logs traefik 2>&1 | grep aifa"

Verify container is on traefik-public network:

ssh root@31.97.61.154 "docker network inspect traefik-public | grep aifa"

Check Traefik labels:

ssh root@31.97.61.154 "docker inspect aifa-site | grep -A 30 Labels"

Issue: SSL Certificate Not Generated

Check DNS:

dig www.aisforagent.net +short
# Must return: 31.97.61.154

Check Traefik certificate logs:

ssh root@31.97.61.154 "docker logs traefik | grep -i certificate"

Manual certificate trigger:

# Make an HTTPS request to trigger certificate generation
curl https://www.aisforagent.net

Wait 1-2 minutes for Let’s Encrypt validation.

Issue: OAuth Not Working

Check OAuth2-Proxy logs:

ssh root@31.97.61.154 "docker logs aifa-oauth2-proxy"

Common issues:

  • Wrong GitHub Client ID/Secret β†’ Check .env.prod
  • Wrong callback URL β†’ Must be https://www.aisforagent.net/oauth2/callback
  • Cookie secret not set β†’ Generate with openssl rand -base64 32

Test OAuth endpoint:

curl -v https://www.aisforagent.net/oauth2/userinfo
# Should return 401 if not logged in

Issue: CTA Not Switching

Check browser console:

F12 β†’ Console β†’ Look for auth errors

Verify /oauth2/userinfo is accessible:

curl -I https://www.aisforagent.net/oauth2/userinfo
# Should return 401 (not 404)

Check JavaScript is loaded:

curl https://www.aisforagent.net/assets/js/auth.js | grep oauth2

πŸ”„ Maintenance

Updating the Site

To deploy changes:

# 1. Make your changes locally
git pull origin main  # or make edits

# 2. Test locally
bundle exec jekyll serve

# 3. Deploy
./deploy-prod.sh

Viewing Logs

# Real-time logs
ssh root@31.97.61.154 "docker logs -f aifa-site"

# Last 100 lines
ssh root@31.97.61.154 "docker logs --tail 100 aifa-site"

# Logs since 1 hour ago
ssh root@31.97.61.154 "docker logs --since 1h aifa-site"

Restarting Services

# Restart all
ssh root@31.97.61.154 "cd ~/aifa-website && docker-compose -f docker-compose.prod.yml restart"

# Restart site only
ssh root@31.97.61.154 "docker restart aifa-site"

# Restart oauth2-proxy only
ssh root@31.97.61.154 "docker restart aifa-oauth2-proxy"

Updating OAuth Configuration

  1. Edit .env.prod locally
  2. Transfer to server:
    scp .env.prod root@31.97.61.154:~/aifa-website/
    
  3. Restart oauth2-proxy:
    ssh root@31.97.61.154 "docker restart aifa-oauth2-proxy"
    

Stopping the Site

ssh root@31.97.61.154 "cd ~/aifa-website && docker-compose -f docker-compose.prod.yml down"

Removing Everything

# Stop and remove containers
ssh root@31.97.61.154 "cd ~/aifa-website && docker-compose -f docker-compose.prod.yml down -v"

# Remove images
ssh root@31.97.61.154 "docker rmi aifa-site:prod"

# Remove directory
ssh root@31.97.61.154 "rm -rf ~/aifa-website"

Monitoring Resource Usage

# Real-time stats
ssh root@31.97.61.154 "docker stats aifa-site aifa-oauth2-proxy"

# Disk usage
ssh root@31.97.61.154 "docker system df"

πŸ“Š Resource Allocation

Current Limits

Service CPU Limit Memory Limit CPU Reserved Memory Reserved
aifa-site 0.5 core 512MB 0.25 core 256MB
aifa-oauth2-proxy 0.25 core 256MB 0.1 core 128MB

These are configured in docker-compose.prod.yml and can be adjusted if needed.


πŸ” Security Notes

  1. Never commit .env.prod - It contains secrets
  2. Rotate OAuth secrets regularly
  3. Restrict GitHub access - Use OAUTH2_PROXY_GITHUB_USERS or OAUTH2_PROXY_GITHUB_ORG
  4. Monitor access logs - Check who’s accessing protected routes
  5. Keep images updated - Regularly rebuild with latest base images

πŸ“ž Support

Useful Commands Reference

# SSH to server
ssh -i ~/git/Foundry/S6web/key.file root@31.97.61.154

# Check all containers
docker ps --format 'table \t\t'

# View Traefik logs
docker logs traefik

# Check networks
docker network ls
docker network inspect traefik-public

# Full system status
docker stats --no-stream
df -h
free -h

Deployed: Ready for production
Domain: https://www.aisforagent.net
Server: 31.97.61.154
Last Updated: 2025-10-11