mirror of
https://github.com/Sea-Haven-Industries/forgejo.git
synced 2026-09-30 05:23:11 +00:00
Some checks failed
Deploy / deploy (push) Has been cancelled
Add documentation for S3 backups with Glacier lifecycle, hourly autodiscovery of new GitHub org repos, daily PAT token refresh, PAT rotation procedure, and Secrets Manager secret inventory.
131 lines
4.5 KiB
Markdown
131 lines
4.5 KiB
Markdown
# 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
|
||
```
|