189 lines
6.1 KiB
Markdown
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.
|