Every document filename now mirrors its lifecycle state with a status suffix (e.g., .draft.md, .wip.md, .accepted.md). No more bare .md for tracked document types. Also renamed all from_str methods to parse to avoid FromStr trait confusion, introduced StagingDeploymentParams struct, and fixed all 19 clippy warnings across the codebase. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4.3 KiB
4.3 KiB
RFC 0015: Let's Encrypt TLS for Forgejo
| Status | Complete |
| Date | 2026-01-25 |
Summary
Enable automatic TLS certificate management via Let's Encrypt for git.beyondtheuniverse.superviber.com on the hearth instance.
Problem
Current state:
git.beyondtheuniverse.superviber.comuses self-signed certificates- API calls require
curl -kto skip verification - Blue's forge client fails without
HTTPS_INSECUREworkarounds - No automatic certificate renewal
Solution
Architecture (Final)
┌─────────────────────────────────────────────────────────┐
│ Hearth K3s (3.218.167.115) │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Traefik │ │
│ │ ┌───────────────────────────────────────────┐ │ │
│ │ │ Built-in ACME Resolver (letsencrypt) │ │ │
│ │ │ - HTTP-01 Challenge │ │ │
│ │ │ - Auto-renewal │ │ │
│ │ │ - Storage: /data/acme.json │ │ │
│ │ └───────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Forgejo (port 3000) │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Components
- Traefik built-in ACME - Handles Let's Encrypt automatically
- IngressRoute - Routes traffic to Forgejo with TLS
- PowerDNS - Self-managed DNS (also on hearth)
Implementation
Traefik on hearth was already configured with ACME support:
# Traefik args (already configured)
- --certificatesresolvers.letsencrypt.acme.email=admin@superviber.com
- --certificatesresolvers.letsencrypt.acme.storage=/data/acme.json
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
The Forgejo IngressRoute references this resolver:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: forgejo
namespace: forgejo
spec:
entryPoints:
- websecure
routes:
- match: Host(`git.beyondtheuniverse.superviber.com`)
kind: Rule
services:
- name: forgejo
port: 3000
tls:
certResolver: letsencrypt
Verification
# HTTPS works without -k flag
curl https://git.beyondtheuniverse.superviber.com/api/v1/version
# Returns: {"version":"9.0.3+gitea-1.22.0"}
# Certificate details
echo | openssl s_client -connect 3.218.167.115:443 \
-servername git.beyondtheuniverse.superviber.com 2>/dev/null | \
openssl x509 -noout -issuer -dates
# issuer=C=US, O=Let's Encrypt, CN=R12
# notBefore=Jan 25 21:23:57 2026 GMT
# notAfter=Apr 25 21:23:56 2026 GMT
Test Plan
- Traefik configured with ACME resolver
- Certificate issued by Let's Encrypt (CN=R12)
- HTTPS works without -k flag
- Browser shows secure connection
- Blue forge client works without SSL workarounds
DNS Configuration
DNS is managed via PowerDNS on hearth (3.218.167.115):
git.beyondtheuniverse.superviber.com→ 3.218.167.115
"One instance. One certificate. Done."
— Blue