server-ovh-prod-01-main/migrations/completed/landhometeam.md

189 lines
6.1 KiB
Markdown

# LandHomeTeam.com Migration - COMPLETED
**Migration Date**: 2025-10-08
**Status**: ✅ LIVE IN PRODUCTION
**URL**: https://landhometeam.com
## Migration Summary
Successfully migrated landhometeam.com from WordPress on DigitalOcean (ServerPilot) to a lightweight static "Coming Soon" page on OVHcloud VPS. This eliminates WordPress maintenance overhead, reduces attack surface, and allows decommissioning of the old server.
## Final Configuration
### Docker Services
- **Web Container**: `landhometeam_web` (nginx:alpine)
- **Reverse Proxy**: Traefik v3.0 (SSL via Let's Encrypt)
- **CDN/Proxy**: Cloudflare (DDoS protection, global caching)
### Access Details
- **Production URL**: https://landhometeam.com
- **Server IP**: 15.204.247.153
- **Service Path**: `~/services/landhometeam/`
- **Resources**: ~10-20MB RAM (minimal footprint)
### Architecture
- Static HTML served from read-only volume mount
- Automatic HTTP → HTTPS redirect via Traefik
- Cloudflare proxy enabled (SSL mode: Full)
- Both apex and www domains configured
## Key Learnings
1. **Traefik Middleware Requirement**: The `redirect-to-https@file` middleware must exist in `dynamic.yml` before being referenced in Docker labels
- Added redirect-to-https middleware to Traefik's dynamic.yml
- Without it, causes configuration errors or unexpected behavior
2. **Cloudflare Proxy Benefits**: Keep Cloudflare proxy enabled (orange cloud) for:
- DDoS protection
- Global CDN caching
- Origin IP hiding
- Free WAF and bot protection
3. **Cloudflare SSL Mode**: Must use "Full" or "Full (strict)" mode when proxying to HTTPS backend
- "Flexible" mode causes redirect loops
- Server uses Let's Encrypt via Traefik, Cloudflare proxies with its own cert
4. **DNS vs IP Testing**: Testing via direct IP with Host header (`curl -H "Host: domain.com" https://IP`) helps isolate DNS/proxy issues
5. **Static Site Simplicity**: No database, no PHP, no admin panel = zero maintenance and minimal security risk
## Deployment Files
### docker-compose.yml
```yaml
services:
nginx:
image: nginx:alpine
container_name: landhometeam_web
restart: unless-stopped
volumes:
- ./html:/usr/share/nginx/html:ro
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik"
# HTTP Router - redirect to HTTPS
- "traefik.http.routers.landhometeam.rule=Host(`landhometeam.com`) || Host(`www.landhometeam.com`)"
- "traefik.http.routers.landhometeam.entrypoints=web"
- "traefik.http.routers.landhometeam.middlewares=redirect-to-https@file"
# HTTPS Router
- "traefik.http.routers.landhometeam-secure.rule=Host(`landhometeam.com`) || Host(`www.landhometeam.com`)"
- "traefik.http.routers.landhometeam-secure.entrypoints=websecure"
- "traefik.http.routers.landhometeam-secure.tls=true"
- "traefik.http.routers.landhometeam-secure.tls.certresolver=letsencrypt"
- "traefik.http.services.landhometeam.loadbalancer.server.port=80"
networks:
traefik:
external: true
```
### Traefik Dynamic Configuration Addition
Added to `~/services/traefik/dynamic.yml`:
```yaml
redirect-to-https:
redirectScheme:
scheme: https
permanent: true
```
## Troubleshooting: Redirect Loop
**Problem**: Redirect loop error when accessing via Cloudflare proxy
**Root Causes**:
1. Missing `redirect-to-https` middleware in Traefik's dynamic.yml
2. Cloudflare SSL mode potentially set to "Flexible"
**Solution**:
1. Added redirect middleware to Traefik configuration
2. Set Cloudflare SSL/TLS mode to "Full"
3. Restarted Traefik: `cd ~/services/traefik && docker compose restart`
## Maintenance Commands
### View Container Status
```bash
ssh jared@15.204.247.153 "docker ps | grep landhometeam"
```
### View Logs
```bash
ssh jared@15.204.247.153 "docker logs landhometeam_web --tail 50"
```
### Update HTML Content
```bash
# Edit locally
nano deployments/landhometeam/html/index.html
# Deploy changes
scp deployments/landhometeam/html/index.html jared@15.204.247.153:~/services/landhometeam/html/
# No restart needed - changes are live immediately (Nginx serves from volume)
```
### Container Management
```bash
# Restart container
ssh jared@15.204.247.153 "cd ~/services/landhometeam && docker compose restart"
# Update Nginx image
ssh jared@15.204.247.153 "cd ~/services/landhometeam && docker compose pull && docker compose up -d"
# Stop/remove service
ssh jared@15.204.247.153 "cd ~/services/landhometeam && docker compose down"
```
## Migration Metrics
- **Migration Time**: ~1 hour (including troubleshooting)
- **Downtime**: Zero (DNS cutover to working site)
- **Resource Usage**: 10-20MB RAM (vs ~200MB+ for WordPress)
- **Monthly Savings**: ~$25+ (can decommission DigitalOcean server + ServerPilot)
- **Annual Savings**: ~$300+
## Post-Migration Tasks
- [x] Deploy container to OVH server
- [x] Configure Traefik routing and SSL
- [x] Update DNS to point to 15.204.247.153
- [x] Configure Cloudflare proxy (SSL mode: Full)
- [x] Fix redirect loop issue
- [x] Verify site loads correctly
- [ ] Monitor for 7 days
- [ ] Export any remaining data from old server
- [ ] Cancel ServerPilot subscription
- [ ] Delete DigitalOcean droplet
## Security Benefits
1. **No Database**: No SQL injection risk
2. **No PHP/WordPress**: No plugin/theme vulnerabilities
3. **Read-Only Volume**: HTML served from read-only mount
4. **Minimal Attack Surface**: Just static HTML + Nginx
5. **Automatic SSL**: Traefik handles certificate renewal
6. **No Admin Panel**: Nothing to hack or brute force
7. **Cloudflare WAF**: Additional layer of DDoS/bot protection
## Future Expansion Options
If site needs to be built out later:
### Option A: Add Contact Form
- Use external service (Formspree, Basin, etc.)
- No backend needed - services email form submissions
### Option B: Static Site Generator
- Build with Astro, Hugo, or similar
- Deploy to same `html/` directory
- Keep same Docker/Traefik setup
### Option C: Full Application
- Add backend container (Node.js, Python, etc.)
- Connect to internal network
- Still behind Traefik with same SSL/routing
All options work with existing architecture - no major infrastructure changes needed.