tenseleyflow/shithub / acfe4d1

Browse files

Clarify Spaces object storage docs

Authored by espadonne
SHA
acfe4d1b669d0335d3e3700c913b65a88ae9c7fc
Parents
be5b659
Tree
97e2f6a

4 changed files

StatusFile+-
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{
2626
 
2727
 var storageCheckCmd = &cobra.Command{
2828
 	Use:   "check",
29
-	Short: "Verify S3 round-trip and repos-root writability",
29
+	Short: "Verify object-store round-trip and repos-root writability",
3030
 	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
3232
   (b) the configured repos_root is writable.
3333
 
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.`,
3637
 	RunE: func(cmd *cobra.Command, _ []string) error {
3738
 		cfg, err := config.Load(nil)
3839
 		if err != nil {
deploy/cutover/SETUP-GUIDE.mdmodified
@@ -492,7 +492,8 @@ Fill in:
492492
 - `caddy_email: ops@shithub.sh` (Let's Encrypt notifications)
493493
 - `db_password`, `hook_password` — paste from `/tmp/`.
494494
 - `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)
496497
 - `s3_region: us-east-1` (Spaces uses this for SigV4)
497498
 - `s3_bucket: shithub-prod`
498499
 - `s3_access_key_id`, `s3_secret_access_key` — from B2 step 5.
docs/internal/storage.mdmodified
@@ -2,7 +2,7 @@
22
 
33
 shithub has two storage layers:
44
 
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.
66
 2. **Repo filesystem storage** — bare git repositories on a local block-storage volume, in a sharded layout owned by the `RepoFS` helper.
77
 
88
 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:
2929
 
3030
 ### Bucket / key scheme
3131
 
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:
3333
 
3434
 ```
3535
 lfs/<owner>/<repo>/<sha256>           # LFS objects (post-MVP, key shape reserved)
3636
 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
3839
 backups/...                           # S37
3940
 ```
4041
 
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.
4243
 
4344
 ### Semantics worth knowing
4445
 
@@ -107,7 +108,7 @@ All storage settings flow through `internal/infra/config` (see `docs/internal/co
107108
 | Key | Type | Default | Notes |
108109
 |---|---|---|---|
109110
 | `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. |
111112
 | `storage.s3.region` | string | `us-east-1` | Region for SigV4 signing. |
112113
 | `storage.s3.access_key_id` | string | `""` | |
113114
 | `storage.s3.secret_access_key` | string | `""` | Redacted by `config print`. |
docs/public/self-host/deploy.mdmodified
@@ -26,7 +26,9 @@ Critical variables:
2626
 - `session_key` — base64 32-byte AEAD key. Generate with
2727
   `openssl rand -base64 32`.
2828
 - `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.
3032
 - `email_*` — Postmark token or SMTP creds.
3133
 - `wireguard_*` — peer keys for the monitoring mesh.
3234