hearth/terraform/minimal/README.md
Eric Garcia b1065ca887 feat(minimal): Add k3s-on-EC2 infrastructure for single user
Decision from 12-expert alignment dialogue on single-user scale.
Implements Option E with modifications:

- t4g.small spot instance (~$5/mo)
- k3s with Traefik for ingress + Let's Encrypt TLS
- SQLite database for Forgejo
- S3 backups with 30-day lifecycle
- EBS gp3 20GB encrypted
- Admin SSH on port 2222, Git SSH on port 22

Total cost: ~$7.50/month

Includes:
- terraform/minimal/ - full terraform configuration
- terraform/bootstrap/ - state backend (already applied)
- docs/spikes/0001-single-user-scale.md - decision documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 06:21:55 -05:00

174 lines
5.5 KiB
Markdown

# Hearth Minimal Deployment
Single EC2 + k3s infrastructure for ~1 user. Cost: ~$7.50/month.
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ Internet │
└─────────────────────────────────────────────────────────────┘
┌─────────┴─────────┐
│ Elastic IP │
│ git.beyond... │
└─────────┬─────────┘
┌───────────────┼───────────────┐
│ │ │
:22 (git) :443 (https) :2222 (admin ssh)
│ │ │
┌─────────────┴───────────────┴───────────────┴─────────────┐
│ EC2 t4g.small (spot) │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ k3s │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │ │
│ │ │ Traefik │ │ Forgejo │ │ SQLite │ │ │
│ │ │ (ingress) │ │ (git) │ │ (data) │ │ │
│ │ └─────────────┘ └─────────────┘ └──────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ EBS gp3 20GB │
└────────────────────────────────────────────────────────────┘
Daily Backup to S3
```
## Cost Breakdown
| Component | Monthly |
|-----------|---------|
| EC2 t4g.small spot | ~$5 |
| EBS gp3 20GB | ~$2 |
| Elastic IP | $0 (attached) |
| S3 backups | ~$0.50 |
| **Total** | **~$7.50** |
## Prerequisites
1. AWS CLI configured with `hearth` profile
2. Terraform >= 1.5.0
3. Domain with DNS access
## Deployment
```bash
# 1. Initialize terraform
cd terraform/minimal
terraform init
# 2. Review configuration
vim terraform.tfvars # Set your domain and email
# 3. Plan
terraform plan
# 4. Apply
terraform apply
# 5. Note the outputs
terraform output
# 6. Configure DNS
# Add A record: git.yourdomain.com -> <elastic_ip>
# 7. Wait for DNS propagation (5-30 minutes)
# 8. Visit https://git.yourdomain.com to complete Forgejo setup
```
## Post-Deployment
### SSH Access
```bash
# Admin SSH (system access)
ssh -p 2222 ec2-user@<elastic_ip>
# Check k3s status
sudo kubectl get pods -A
# View Forgejo logs
sudo kubectl logs -n forgejo deploy/forgejo
```
### Git Access
```bash
# Clone a repo (after creating it in web UI)
git clone git@git.yourdomain.com:org/repo.git
```
### Backups
Automatic daily backups to S3 at 3 AM UTC.
```bash
# Manual backup
sudo /usr/local/bin/backup-forgejo.sh hearth-backups-<account_id>
# List backups
aws s3 ls s3://hearth-backups-<account_id>/backups/
```
### Restore from Backup
```bash
# Download backup
aws s3 cp s3://hearth-backups-<account_id>/backups/backup-TIMESTAMP.tar.gz /tmp/
# Extract
tar -xzf /tmp/backup-TIMESTAMP.tar.gz -C /tmp/restore
# Stop Forgejo
sudo kubectl scale deploy/forgejo -n forgejo --replicas=0
# Restore database
sudo cp /tmp/restore/gitea.db /data/forgejo/gitea/gitea.db
sudo chown 1000:1000 /data/forgejo/gitea/gitea.db
# Start Forgejo
sudo kubectl scale deploy/forgejo -n forgejo --replicas=1
```
## Upgrade Path
When you outgrow this setup:
1. **More resources**: Change instance type in terraform.tfvars
2. **High availability**: Migrate to EKS using the same manifests
3. **Multiple users**: Add authentication via Keycloak
The Kubernetes manifests are portable to any k8s cluster.
## Troubleshooting
### Forgejo not starting
```bash
sudo kubectl describe pod -n forgejo
sudo kubectl logs -n forgejo deploy/forgejo
```
### TLS not working
```bash
# Check Traefik logs
sudo kubectl logs -n traefik deploy/traefik
# Verify DNS is pointing to correct IP
dig git.yourdomain.com
```
### Spot instance interrupted
The instance will automatically restart. Data is preserved on EBS.
Check instance status in AWS console.
## Security Notes
1. **Restrict admin access**: Update `admin_cidr_blocks` in terraform.tfvars
2. **SSH keys**: Add your public key to `~/.ssh/authorized_keys` on the instance
3. **Forgejo admin**: Create admin account during initial setup
4. **Updates**: Automatic security updates enabled via dnf-automatic