A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
81
fork

Configure Feed

Select the types of activity you want to include in your feed.

try and use pull_zone

+38 -4
+4
config-hold.example.yaml
··· 31 31 bucket: "" 32 32 # Custom S3 endpoint for non-AWS providers (e.g. "https://gateway.storjshare.io"). 33 33 endpoint: "" 34 + # CDN pull zone URL for downloads. When set, presigned GET/HEAD URLs use this host instead of the S3 endpoint. Uploads and API calls still use the S3 endpoint. 35 + pull_zone: "" 34 36 # HTTP server and identity settings. 35 37 server: 36 38 # Listen address, e.g. ":8080" or "0.0.0.0:8080". ··· 39 41 public_url: "" 40 42 # Allow unauthenticated blob reads. If false, readers need crew membership. 41 43 public: false 44 + # DID of successor hold for migration. Appview redirects all requests to the successor. 45 + successor: "" 42 46 # Use localhost for OAuth redirects during development. 43 47 test_mode: false 44 48 # Request crawl from this relay on startup to make the embedded PDS discoverable.
+4
deploy/upcloud/configs/hold.yaml.tmpl
··· 13 13 region: "{{.S3Region}}" 14 14 bucket: "{{.S3Bucket}}" 15 15 endpoint: "{{.S3Endpoint}}" 16 + pull_zone: "" 16 17 server: 17 18 addr: :8080 18 19 public_url: "https://{{.HoldDomain}}" 19 20 public: false 21 + successor: "" 20 22 test_mode: false 21 23 relay_endpoint: "" 22 24 read_timeout: 5m0s ··· 35 37 libsql_sync_interval: 1m0s 36 38 admin: 37 39 enabled: true 40 + gc: 41 + enabled: false 38 42 quota: 39 43 tiers: 40 44 deckhand:
+8
pkg/hold/config.go
··· 81 81 // Custom S3 endpoint for non-AWS providers. 82 82 Endpoint string `yaml:"endpoint" comment:"Custom S3 endpoint for non-AWS providers (e.g. \"https://gateway.storjshare.io\")."` 83 83 84 + // CDN pull zone URL for presigned download URLs. 85 + PullZone string `yaml:"pull_zone" comment:"CDN pull zone URL for downloads. When set, presigned GET/HEAD URLs use this host instead of the S3 endpoint. Uploads and API calls still use the S3 endpoint."` 86 + 84 87 // Internal distribution storage config, built from the above fields. 85 88 distStorage configuration.Storage `yaml:"-"` 86 89 } ··· 188 191 v.SetDefault("storage.region", "us-east-1") 189 192 v.SetDefault("storage.bucket", "") 190 193 v.SetDefault("storage.endpoint", "") 194 + v.SetDefault("storage.pull_zone", "") 191 195 192 196 // GC defaults 193 197 v.SetDefault("gc.enabled", false) ··· 244 248 _ = v.BindEnv("storage.region", "AWS_REGION") 245 249 _ = v.BindEnv("storage.bucket", "S3_BUCKET") 246 250 _ = v.BindEnv("storage.endpoint", "S3_ENDPOINT") 251 + _ = v.BindEnv("storage.pull_zone", "S3_PULL_ZONE") 247 252 248 253 // Bind legacy GC env vars (backward compat) 249 254 _ = v.BindEnv("gc.enabled", "GC_ENABLED") ··· 297 302 if sc.Endpoint != "" { 298 303 params["regionendpoint"] = sc.Endpoint 299 304 params["forcepathstyle"] = true 305 + } 306 + if sc.PullZone != "" { 307 + params["pullzone"] = sc.PullZone 300 308 } 301 309 302 310 storageCfg := configuration.Storage{}
+22 -4
pkg/s3/types.go
··· 33 33 34 34 // RealS3Client wraps AWS SDK v2 *s3.Client to implement S3Client interface 35 35 type RealS3Client struct { 36 - client *awss3.Client 37 - presign *awss3.PresignClient 36 + client *awss3.Client 37 + presign *awss3.PresignClient 38 + pullZone string // CDN pull zone URL for presigned GET/HEAD URLs 38 39 } 39 40 40 41 // NewRealS3Client creates a new RealS3Client wrapper ··· 64 65 func (r *RealS3Client) PresignGetObject(ctx context.Context, input *awss3.GetObjectInput, expires time.Duration) (string, error) { 65 66 result, err := r.presign.PresignGetObject(ctx, input, func(opts *awss3.PresignOptions) { 66 67 opts.Expires = expires 68 + if r.pullZone != "" { 69 + opts.ClientOptions = append(opts.ClientOptions, func(o *awss3.Options) { 70 + o.BaseEndpoint = aws.String(r.pullZone) 71 + }) 72 + } 67 73 }) 68 74 if err != nil { 69 75 return "", err ··· 75 81 func (r *RealS3Client) PresignHeadObject(ctx context.Context, input *awss3.HeadObjectInput, expires time.Duration) (string, error) { 76 82 result, err := r.presign.PresignHeadObject(ctx, input, func(opts *awss3.PresignOptions) { 77 83 opts.Expires = expires 84 + if r.pullZone != "" { 85 + opts.ClientOptions = append(opts.ClientOptions, func(o *awss3.Options) { 86 + o.BaseEndpoint = aws.String(r.pullZone) 87 + }) 88 + } 78 89 }) 79 90 if err != nil { 80 91 return "", err ··· 162 173 s3PathPrefix = strings.TrimPrefix(rootDir, "/") 163 174 } 164 175 176 + // CDN pull zone for presigned download URLs 177 + pullZone, _ := params["pullzone"].(string) 178 + 165 179 slog.Info("S3 presigned URLs enabled", 166 180 "bucket", bucket, 167 181 "region", region, 168 - "pathPrefix", s3PathPrefix) 182 + "pathPrefix", s3PathPrefix, 183 + "pullZone", pullZone) 169 184 170 185 // Create S3 client wrapped in RealS3Client for interface compatibility 186 + realClient := NewRealS3Client(client) 187 + realClient.pullZone = pullZone 188 + 171 189 return &S3Service{ 172 - Client: NewRealS3Client(client), 190 + Client: realClient, 173 191 Bucket: bucket, 174 192 PathPrefix: s3PathPrefix, 175 193 }, nil