Clarify Spaces object storage docs
- SHA
acfe4d1b669d0335d3e3700c913b65a88ae9c7fc- Parents
-
be5b659 - Tree
97e2f6a
acfe4d1
acfe4d1b669d0335d3e3700c913b65a88ae9c7fcbe5b659
97e2f6a| Status | File | + | - |
|---|---|---|---|
| M |
cmd/shithubd/storage.go
|
5 | 4 |
| M |
deploy/cutover/SETUP-GUIDE.md
|
2 | 1 |
| M |
docs/internal/storage.md
|
6 | 5 |
| M |
docs/public/self-host/deploy.md
|
3 | 1 |
cmd/shithubd/storage.gomodified@@ -26,13 +26,14 @@ var storageCmd = &cobra.Command{ | ||
| 26 | 26 | |
| 27 | 27 | var storageCheckCmd = &cobra.Command{ |
| 28 | 28 | Use: "check", |
| 29 | - Short: "Verify S3 round-trip and repos-root writability", | |
| 29 | + Short: "Verify object-store round-trip and repos-root writability", | |
| 30 | 30 | Long: `Exits 0 when both: |
| 31 | - (a) PUT and GET succeed against the configured S3 bucket, and | |
| 31 | + (a) PUT and GET succeed against the configured S3-compatible object bucket, and | |
| 32 | 32 | (b) the configured repos_root is writable. |
| 33 | 33 | |
| 34 | -When the S3 block is unconfigured, only (b) is checked. Used in deploy | |
| 35 | -smoke tests and as a sanity check from the operator's terminal.`, | |
| 34 | +Production uses DigitalOcean Spaces through that S3-compatible API. When the | |
| 35 | +S3 block is unconfigured, only (b) is checked. Used in deploy smoke tests and | |
| 36 | +as a sanity check from the operator's terminal.`, | |
| 36 | 37 | RunE: func(cmd *cobra.Command, _ []string) error { |
| 37 | 38 | cfg, err := config.Load(nil) |
| 38 | 39 | if err != nil { |
deploy/cutover/SETUP-GUIDE.mdmodified@@ -492,7 +492,8 @@ Fill in: | ||
| 492 | 492 | - `caddy_email: ops@shithub.sh` (Let's Encrypt notifications) |
| 493 | 493 | - `db_password`, `hook_password` — paste from `/tmp/`. |
| 494 | 494 | - `session_key`, `totp_key` — paste from `/tmp/`. |
| 495 | -- `s3_endpoint: nyc3.digitaloceanspaces.com` | |
| 495 | +- `s3_endpoint: nyc3.digitaloceanspaces.com` (DigitalOcean Spaces via | |
| 496 | + the S3-compatible API) | |
| 496 | 497 | - `s3_region: us-east-1` (Spaces uses this for SigV4) |
| 497 | 498 | - `s3_bucket: shithub-prod` |
| 498 | 499 | - `s3_access_key_id`, `s3_secret_access_key` — from B2 step 5. |
docs/internal/storage.mdmodified@@ -2,7 +2,7 @@ | ||
| 2 | 2 | |
| 3 | 3 | shithub has two storage layers: |
| 4 | 4 | |
| 5 | -1. **Object storage** — S3-compatible (MinIO in dev/test, DigitalOcean Spaces in prod). Used for avatars, attachments, and (post-MVP) LFS objects. | |
| 5 | +1. **Object storage** — S3-compatible (MinIO in dev/test, DigitalOcean Spaces in prod). Used for avatars, attachments, and (post-MVP) LFS objects. The production bucket is DigitalOcean Spaces; the `s3` naming reflects the compatible API, not AWS. | |
| 6 | 6 | 2. **Repo filesystem storage** — bare git repositories on a local block-storage volume, in a sharded layout owned by the `RepoFS` helper. |
| 7 | 7 | |
| 8 | 8 | Both layers live behind the package `internal/infra/storage`. Path validation is the **security boundary** — every entry that takes user-supplied owner/repo names goes through `RepoPath`, which rejects unsafe inputs against a strict whitelist. If repo paths can be tricked, every later sprint inherits the bug; the test suite *over*-tests this. |
@@ -29,16 +29,17 @@ Two implementations: | ||
| 29 | 29 | |
| 30 | 30 | ### Bucket / key scheme |
| 31 | 31 | |
| 32 | -Single bucket per environment: `shithub-dev`, `shithub-staging`, `shithub-prod`. Per-scope key prefixes ease policy and tenant isolation: | |
| 32 | +Single bucket per environment: `shithub-dev`, `shithub-staging`, `shithub-prod`. In production this is a DigitalOcean Spaces bucket configured through the S3-compatible client. Per-scope key prefixes ease policy and tenant isolation: | |
| 33 | 33 | |
| 34 | 34 | ``` |
| 35 | 35 | lfs/<owner>/<repo>/<sha256> # LFS objects (post-MVP, key shape reserved) |
| 36 | 36 | attachments/<scope>/<id>/<filename> # issue/PR/comment attachments |
| 37 | -avatars/<owner>/<size>.<ext> # rendered avatar variants | |
| 37 | +avatars/<user_id>/<hash>.png # largest rendered avatar variant | |
| 38 | +avatars/<user_id>/<hash>-<size>.png # smaller rendered avatar variants | |
| 38 | 39 | backups/... # S37 |
| 39 | 40 | ``` |
| 40 | 41 | |
| 41 | -Keys are always lowercase. | |
| 42 | +Avatar uploads are decoded from PNG, JPEG, or GIF and re-encoded to PNG before storage. Keys are always lowercase. | |
| 42 | 43 | |
| 43 | 44 | ### Semantics worth knowing |
| 44 | 45 | |
@@ -107,7 +108,7 @@ All storage settings flow through `internal/infra/config` (see `docs/internal/co | ||
| 107 | 108 | | Key | Type | Default | Notes | |
| 108 | 109 | |---|---|---|---| |
| 109 | 110 | | `storage.repos_root` | string | `/data/repos` | Filesystem root for bare repos. Required. | |
| 110 | -| `storage.s3.endpoint` | string | `""` | Host[:port], no scheme. Empty disables S3. | | |
| 111 | +| `storage.s3.endpoint` | string | `""` | Host[:port], no scheme. Empty disables object storage. Production uses the DigitalOcean Spaces endpoint. | | |
| 111 | 112 | | `storage.s3.region` | string | `us-east-1` | Region for SigV4 signing. | |
| 112 | 113 | | `storage.s3.access_key_id` | string | `""` | | |
| 113 | 114 | | `storage.s3.secret_access_key` | string | `""` | Redacted by `config print`. | |
docs/public/self-host/deploy.mdmodified@@ -26,7 +26,9 @@ Critical variables: | ||
| 26 | 26 | - `session_key` — base64 32-byte AEAD key. Generate with |
| 27 | 27 | `openssl rand -base64 32`. |
| 28 | 28 | - `totp_key` — base64 32-byte AEAD key for at-rest TOTP secrets. |
| 29 | -- `s3_*` — bucket name, region, credentials. | |
| 29 | +- `s3_*` — runtime object storage bucket name, region, and | |
| 30 | + credentials. In the reference deployment these point at the | |
| 31 | + DigitalOcean Spaces bucket through its S3-compatible API. | |
| 30 | 32 | - `email_*` — Postmark token or SMTP creds. |
| 31 | 33 | - `wireguard_*` — peer keys for the monitoring mesh. |
| 32 | 34 | |