Skip to content

Commit d9a5be5

Browse files
committed
feat: add support for Aliyun OSS and Tencent COS storage providers
- Updated documentation to include Aliyun OSS and Tencent COS as storage options. - Introduced configuration examples for both providers in the storage providers documentation. - Enhanced the storage provider registration to accommodate new providers. - Updated the storage configuration interfaces to support OSS and COS. - Modified the S3 client and provider implementations to handle requests for OSS and COS. - Added environment variable configurations for OSS and COS. - Implemented necessary changes in the UI schema and routes to reflect the new providers. - Updated localization files for new storage provider types. Signed-off-by: Innei <[email protected]>
1 parent 6b48fe7 commit d9a5be5

File tree

29 files changed

+554
-156
lines changed

29 files changed

+554
-156
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
title: Tencent COS
3+
description: Configure Tencent Cloud Object Storage (COS) for deployments within the Tencent ecosystem.
4+
createdAt: 2025-11-24T10:06:00+08:00
5+
lastModified: 2025-11-24T22:26:48+08:00
6+
order: 38
7+
---
8+
9+
# Tencent COS Storage
10+
11+
Tencent Cloud COS is fully compatible with the S3 API and now has a dedicated provider inside Afilmory. Using `provider: 'cos'` takes care of bucket/APPID handling and builds the default `cos.<region>.myqcloud.com` endpoint for you.
12+
13+
## Configuration
14+
15+
```typescript
16+
import { defineBuilderConfig } from '@afilmory/builder'
17+
18+
export default defineBuilderConfig(() => ({
19+
storage: {
20+
provider: 'cos',
21+
bucket: process.env.COS_BUCKET!, // include the -APPID suffix, e.g. gallery-1250000000
22+
region: process.env.COS_REGION || 'ap-shanghai',
23+
accessKeyId: process.env.COS_SECRET_ID!,
24+
secretAccessKey: process.env.COS_SECRET_KEY!,
25+
endpoint: process.env.COS_ENDPOINT, // optional, defaults to https://<bucket>.cos.<region>.myqcloud.com
26+
prefix: process.env.COS_PREFIX || 'photos/',
27+
customDomain: process.env.COS_CUSTOM_DOMAIN,
28+
},
29+
}))
30+
```
31+
32+
## Environment Variables
33+
34+
```bash
35+
# Required
36+
COS_BUCKET=gallery-1250000000
37+
COS_REGION=ap-shanghai
38+
COS_SECRET_ID=AKIDxxxxxxxx
39+
COS_SECRET_KEY=yyyyyyyyyyyy
40+
41+
# Optional
42+
COS_ENDPOINT=https://cos.ap-shanghai.myqcloud.com
43+
COS_PREFIX=photos/
44+
COS_CUSTOM_DOMAIN=https://assets.example.com
45+
```
46+
47+
## COS-specific Considerations
48+
49+
- Buckets MUST include the APPID suffix (`bucketname-125xxxxxxx`).
50+
- Regional endpoints follow the pattern `https://<bucket>.cos.<region>.myqcloud.com`.
51+
- SigV4 service defaults to `s3`, matching Tencent's AWS compatibility layer. Override `sigV4Service` only for private gateways.
52+
- COS supports acceleration and CDN domains; set `customDomain` so generated URLs point to your preferred edge domain.
53+
54+
## Best Practices
55+
56+
- **Use permanent keys** for builder workloads and scope permissions with CAM policies (`name/cos:GetObject`, `cos:PutObject`, etc.).
57+
- **Leverage CLS logs** and bucket inventory to monitor sync health.
58+
- **Combine with SCF or CI** pipelines if you need to trigger builder runs after uploads.
59+
60+
## Troubleshooting
61+
62+
- _403 or 404 errors_: confirm the bucket region matches `COS_REGION` and that the IAM policy allows the requested action.
63+
- _Slow scans_: reduce `downloadConcurrency` or run builder from a Tencent CVM within the same region to minimize latency.
64+
- _Invalid bucket name_: double-check the `-APPID` suffix and that the bucket really exists in the selected region.

apps/docs/contents/storage/providers/index.mdx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: Storage Providers
33
description: Choose a storage provider for your photo collection.
44
createdAt: 2025-11-14T22:40:00+08:00
5-
lastModified: 2025-11-23T19:40:52+08:00
5+
lastModified: 2025-11-24T22:26:48+08:00
66
order: 30
77
---
88

@@ -21,6 +21,24 @@ Afilmory supports multiple storage providers for your photo collection. Choose t
2121
- Works with AWS S3, MinIO, Cloudflare R2, and other S3-compatible services
2222
- Recommended for large collections
2323

24+
### [Aliyun OSS](/storage/providers/oss)
25+
26+
**China-mainland optimized**
27+
28+
- Native endpoint defaults for `oss-` regions
29+
- Works with classic or internal network OSS domains
30+
- Ideal when data residency or ICP compliance is required
31+
- Supports CDN fronting via `customDomain`
32+
33+
### [Tencent COS](/storage/providers/cos)
34+
35+
**Tencent Cloud ecosystems**
36+
37+
- First-class support for COS buckets (`bucket-appid`)
38+
- Automatic `cos.<region>.myqcloud.com` endpoint handling
39+
- Compatible with COS acceleration domains and CLS logging
40+
- Preferred for deployments already on Tencent Cloud
41+
2442
### [B2 (Backblaze B2)](/storage/providers/b2)
2543

2644
**Cost-effective cloud storage**
@@ -60,13 +78,16 @@ Afilmory supports multiple storage providers for your photo collection. Choose t
6078
## Choosing a Provider
6179

6280
**For production:**
81+
6382
- Use **S3** or **B2** for scalability and reliability
6483

6584
**For development:**
85+
6686
- Use **Local** for fastest iteration
6787
- Use **GitHub** for simple demos
6888

6989
**For existing workflows:**
90+
7091
- Use **Eagle** if you already manage photos there
7192
- Use **GitHub** if your photos are already in a repo
7293

@@ -88,4 +109,3 @@ export default defineBuilderConfig(() => ({
88109
Credentials and sensitive information should be stored in `.env` and referenced via `process.env`.
89110

90111
See each provider's documentation for specific configuration options.
91-
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: Aliyun OSS
3+
description: Configure Aliyun Object Storage Service (OSS) for China-mainland friendly deployments.
4+
createdAt: 2025-11-24T10:05:00+08:00
5+
lastModified: 2025-11-24T22:26:48+08:00
6+
order: 37
7+
---
8+
9+
# Aliyun OSS Storage
10+
11+
Aliyun OSS is ideal when you need data residency in mainland China or want to leverage Alibaba Cloud's backbone network. The new `provider: 'oss'` option in Afilmory automatically sets sane defaults for endpoints and SigV4 signing so you only fill in the essentials.
12+
13+
## Configuration
14+
15+
```typescript
16+
import { defineBuilderConfig } from '@afilmory/builder'
17+
18+
export default defineBuilderConfig(() => ({
19+
storage: {
20+
provider: 'oss',
21+
bucket: process.env.OSS_BUCKET!,
22+
region: process.env.OSS_REGION || 'oss-cn-hangzhou',
23+
accessKeyId: process.env.OSS_ACCESS_KEY_ID!,
24+
secretAccessKey: process.env.OSS_ACCESS_KEY_SECRET!,
25+
endpoint: process.env.OSS_ENDPOINT, // optional, defaults to bucket.region.aliyuncs.com
26+
prefix: process.env.OSS_PREFIX || 'photos/',
27+
customDomain: process.env.OSS_CUSTOM_DOMAIN, // optional CDN or acceleration domain
28+
},
29+
}))
30+
```
31+
32+
## Environment Variables
33+
34+
```bash
35+
# Required
36+
OSS_BUCKET=my-gallery-assets
37+
OSS_REGION=oss-cn-hangzhou
38+
OSS_ACCESS_KEY_ID=xxxxxxxx
39+
OSS_ACCESS_KEY_SECRET=yyyyyyyy
40+
41+
# Optional
42+
OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
43+
OSS_PREFIX=photos/
44+
OSS_CUSTOM_DOMAIN=https://img.example.cn
45+
```
46+
47+
## Notes on Endpoints
48+
49+
- If you omit `endpoint`, the provider emits `https://<bucket>.<region>.aliyuncs.com`.
50+
- You can point `endpoint` to an internal VPC domain or acceleration endpoint; public URLs still honor `customDomain` when provided.
51+
- The SigV4 service defaults to `oss`. Override `sigV4Service` only when using custom gateways that expect a different service name.
52+
53+
## Best Practices
54+
55+
- **Use ICP-ready domains**: set `customDomain` to an OSS-bound domain that has completed ICP filing for production in mainland China.
56+
- **Prefix per tenant**: combine `prefix` with tenant IDs or years to simplify lifecycle policies.
57+
- **Network paths**: pair `endpoint` with the closest region (e.g., `oss-cn-shanghai-internal.aliyuncs.com`) when running builder inside Alibaba Cloud to avoid public egress.
58+
59+
## Troubleshooting
60+
61+
- _Signature mismatch_: verify your AccessKey pair and ensure system clock drift is under 5 minutes.
62+
- _403 Forbidden after upload_: confirm the RAM policy allows `oss:PutObject` / `oss:GetObject` for the bucket prefix.
63+
- _Slow downloads outside China_: front OSS with a CDN and set `customDomain` so generated URLs route through the CDN.

apps/docs/src/routes.json

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
"title": "Storage Providers",
9595
"description": "Choose a storage provider for your photo collection.",
9696
"createdAt": "2025-11-14T22:40:00+08:00",
97-
"lastModified": "2025-11-23T19:40:52+08:00",
97+
"lastModified": "2025-11-24T10:15:00+08:00",
9898
"order": "30"
9999
}
100100
},
@@ -109,6 +109,28 @@
109109
"order": "32"
110110
}
111111
},
112+
{
113+
"path": "/storage/providers/oss",
114+
"title": "Aliyun OSS",
115+
"meta": {
116+
"title": "Aliyun OSS",
117+
"description": "Configure Aliyun Object Storage Service (OSS) for China-mainland friendly deployments.",
118+
"createdAt": "2025-11-24T10:05:00+08:00",
119+
"lastModified": "2025-11-24T10:05:00+08:00",
120+
"order": "37"
121+
}
122+
},
123+
{
124+
"path": "/storage/providers/cos",
125+
"title": "Tencent COS",
126+
"meta": {
127+
"title": "Tencent COS",
128+
"description": "Configure Tencent Cloud Object Storage (COS) for deployments within the Tencent ecosystem.",
129+
"createdAt": "2025-11-24T10:06:00+08:00",
130+
"lastModified": "2025-11-24T10:06:00+08:00",
131+
"order": "38"
132+
}
133+
},
112134
{
113135
"path": "/storage/providers/b2",
114136
"title": "B2 (Backblaze B2)",

apps/docs/src/routes.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ import Route23 from '../contents/saas/cms.mdx'
2222
import Route15 from '../contents/saas/deployment.mdx'
2323
import Route22 from '../contents/saas/index.mdx'
2424
import Route10 from '../contents/storage/providers/b2.mdx'
25+
import Route26 from '../contents/storage/providers/cos.mdx'
2526
import Route14 from '../contents/storage/providers/eagle.mdx'
2627
import Route11 from '../contents/storage/providers/github.mdx'
2728
import Route8 from '../contents/storage/providers/index.mdx'
2829
import Route12 from '../contents/storage/providers/local.mdx'
30+
import Route25 from '../contents/storage/providers/oss.mdx'
2931
import Route9 from '../contents/storage/providers/s3.mdx'
3032

3133
export interface RouteConfig {
@@ -140,7 +142,7 @@ export const routes: RouteConfig[] = [
140142
title: 'Storage Providers',
141143
description: 'Choose a storage provider for your photo collection.',
142144
createdAt: '2025-11-14T22:40:00+08:00',
143-
lastModified: '2025-11-23T19:40:52+08:00',
145+
lastModified: '2025-11-24T10:15:00+08:00',
144146
order: '30',
145147
},
146148
},
@@ -156,6 +158,30 @@ export const routes: RouteConfig[] = [
156158
order: '32',
157159
},
158160
},
161+
{
162+
path: '/storage/providers/oss',
163+
component: Route25,
164+
title: 'Aliyun OSS',
165+
meta: {
166+
title: 'Aliyun OSS',
167+
description: 'Configure Aliyun Object Storage Service (OSS) for China-mainland friendly deployments.',
168+
createdAt: '2025-11-24T10:05:00+08:00',
169+
lastModified: '2025-11-24T10:05:00+08:00',
170+
order: '37',
171+
},
172+
},
173+
{
174+
path: '/storage/providers/cos',
175+
component: Route26,
176+
title: 'Tencent COS',
177+
meta: {
178+
title: 'Tencent COS',
179+
description: 'Configure Tencent Cloud Object Storage (COS) for deployments within the Tencent ecosystem.',
180+
createdAt: '2025-11-24T10:06:00+08:00',
181+
lastModified: '2025-11-24T10:06:00+08:00',
182+
order: '38',
183+
},
184+
},
159185
{
160186
path: '/storage/providers/b2',
161187
component: Route10,

be/apps/core/src/modules/configuration/setting/storage-provider.constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ export const STORAGE_PROVIDERS_SETTING_KEY = 'builder.storage.providers'
22

33
export const STORAGE_PROVIDER_SENSITIVE_FIELDS: Record<string, readonly string[]> = {
44
s3: ['secretAccessKey'],
5+
oss: ['secretAccessKey'],
6+
cos: ['secretAccessKey'],
57
github: ['token'],
68
b2: ['applicationKey'],
79
}

0 commit comments

Comments
 (0)