forgejo/README.md

132 lines
4.5 KiB
Markdown
Raw Normal View History

# forgejo
Self-hosted Forgejo git server for archiving GitHub repos and mirroring active ones. Runs on a single EC2 instance within the Sea Haven VPC, fronted by the `seahaven-com` ALB for HTTPS.
## Architecture
- **EC2**: t4g.small (arm64), Amazon Linux 2023, 50GB gp3 EBS — instance `i-0d3005fb3c36124cd`
- **Network**: Private subnet (us-east-1a), behind `seahaven-com` ALB for SSL termination
- **DNS**: `forgejo.seahaven.com` — Route53 alias record pointing to the `seahaven-com` ALB (not a direct A record)
- **TLS**: Wildcard cert on ALB, HTTP internally on port 3000
- **Backup**: Nightly `forgejo dump` to S3 + EBS snapshots via DLM (see [S3 Backups](#s3-backups))
- **Admin access**: SSM Session Manager (no SSH port exposed)
- **CI/CD**: GitHub Actions with OIDC role `githubdeploy-forgejo`
### Ports
| Port | Protocol | Source | Purpose |
|------|----------|--------|---------|
| 443 | HTTPS | ALB (public) | Web UI + HTTP git clone |
| 3000 | HTTP | ALB → instance | Internal traffic from ALB |
| 2222 | SSH | VPC + VPN | Git SSH operations |
## S3 Backups
A nightly `forgejo dump` runs at 5:00 UTC and uploads the archive to `s3://forgejo-backups-328440206208`.
**S3 lifecycle policy:**
| Phase | Duration |
|-------|----------|
| Standard | First 30 days |
| Glacier | Days 31–365 |
| Expired | After 365 days |
EBS snapshots are managed separately by DLM and run nightly at 6:00 UTC with a 7-day retention window.
To test the backup manually:
```bash
sudo /usr/local/bin/forgejo-backup.sh
```
## Autodiscovery
An hourly cron job checks the `Sea-Haven-Industries` GitHub org for new repositories and mirrors them into Forgejo automatically.
- **Active repos** are created as mirrors (ongoing sync).
- **Archived repos** are created as static one-time imports.
- **Script**: `/usr/local/bin/forgejo-autodiscover.sh`
- **Log**: `/var/log/forgejo-autodiscover.log`
## Token Refresh
A daily cron at 4:30 UTC reads the GitHub PAT from Secrets Manager (`forgejo/github-pat`) and updates the git remote URL on every mirror repository so credentials stay current.
- **Script**: `/usr/local/bin/forgejo-refresh-tokens.sh`
## PAT Rotation
The GitHub personal access token used for mirroring is a fine-grained PAT scoped to `Sea-Haven-Industries` with **Contents: Read-only** permissions and a 1-year expiration. It is stored in Secrets Manager at `forgejo/github-pat`.
To rotate:
1. Create a new fine-grained PAT on GitHub with the same scope.
2. Update the secret value in Secrets Manager (`forgejo/github-pat`).
3. The daily token-refresh cron will pick it up automatically.
To force immediate propagation:
```bash
sudo /usr/local/bin/forgejo-refresh-tokens.sh
```
## Secrets Manager
| Secret | Purpose |
|--------|---------|
| `forgejo/admin-password` | Forgejo admin user password |
| `forgejo/api-token` | Forgejo API token (used by autodiscovery and token refresh scripts) |
| `forgejo/github-pat` | GitHub fine-grained PAT for mirroring |
## First-time setup
After the stack deploys, connect via SSM and create the admin user:
```bash
aws ssm start-session --target i-0d3005fb3c36124cd
sudo -u forgejo /usr/local/bin/forgejo admin user create \
--admin \
--username adam \
--password '<password>' \
--email adam@seahavenind.com \
--config /etc/forgejo/app.ini
```
Admin password is stored in Secrets Manager at `forgejo/admin-password`.
Access the web UI at `https://forgejo.seahaven.com`.
## Migrating repos from GitHub
### Archived repos (one-time import)
In the Forgejo web UI: **New Migration → GitHub** → paste the GitHub repo URL. Use a GitHub personal access token for private repos. These are full imports (code, issues, PRs, releases).
### Active repos (mirror sync)
Same migration flow, but check **This Repository Will Be A Mirror**. Forgejo polls GitHub hourly (`DEFAULT_INTERVAL = 1h` in app.ini) and keeps the mirror in sync.
## Deployment
```bash
npm install
npx cdk deploy
```
CI/CD is handled by GitHub Actions — PRs run CI, merges to `main` deploy via the reusable CDK workflow.
## Updating Forgejo
Update the `FORGEJO_VERSION` constant in `lib/forgejo-stack.ts` and deploy. This replaces the instance, so ensure the latest EBS snapshot is available for data recovery if needed. Alternatively, update in-place via SSM:
```bash
aws ssm start-session --target i-0d3005fb3c36124cd
sudo systemctl stop forgejo
sudo curl -Lo /usr/local/bin/forgejo "https://codeberg.org/forgejo/forgejo/releases/download/v<NEW_VERSION>/forgejo-<NEW_VERSION>-linux-arm64"
sudo chmod +x /usr/local/bin/forgejo
sudo systemctl start forgejo
```