How to Configure AWS S3 or Cloudflare R2 with PicList: Complete Setup Guide
To configure AWS S3 or Cloudflare R2 with PicList, add an aws-s3 bucket in Settings → Manage → Bucket, supply your Access Key ID and Secret, set the endpoint (required for R2), enable s3ForcePathStyle for R2 compatibility, and define the ACL as public-read.
PicList supports both Amazon S3 and Cloudflare R2 through its unified aws-s3 plugin, which leverages R2’s S3-compatible API. The configuration values entered in the graphical interface map directly to the JSON structure consumed by the core upload logic, specifically within scripts/upload-to-s3.js.
Adding an S3 or R2 Bucket in PicList
- Open Settings → Manage → Bucket and click the "+" button to create a new bucket configuration.
- Select aws-s3 (or aws-s3-plist, which uses the identical implementation).
- Fill in the required fields detailed in the next section.
The UI field definitions, including placeholders and validation rules, are defined in src/renderer/manage/utils/constants.ts under the aws-s3 section.
Required Configuration Fields
Access Credentials
- Access Key ID: For AWS, use the IAM user’s
accessKeyId; for Cloudflare R2, use theR2_SECRET_IDfrom your R2 API tokens. - Access Key Secret: The corresponding secret key (
accessKeySecretfor AWS,R2_SECRET_KEYfor R2).
Bucket Name and Endpoint
- Bucket Name: The exact name of your existing bucket (e.g.,
my-bucket). - Endpoint: Leave this blank for AWS S3 to use the default regional endpoint. For Cloudflare R2, this is mandatory and must follow the format
https://<ACCOUNT_ID>.r2.cloudflarestorage.com.
Path Style and Access Control
- Force Path Style (
s3ForcePathStyle): Set to true for Cloudflare R2, which requires path-style URLs (https://<endpoint>/<bucket>/<key>). For standard AWS S3, set this to false. - ACL: Typically set to
public-readto ensure uploaded objects are publicly accessible.
How PicList Uploads Files to S3 and R2
When you initiate an upload, PicList constructs an S3Client instance using the AWS SDK for JavaScript v3. The client configuration is built from your bucket settings as implemented in scripts/upload-to-s3.js:
const client = new S3Client({
region: 'auto', // Region is ignored for R2
credentials: {
accessKeyId: bucketConfig.accessKeyId,
secretAccessKey: bucketConfig.accessKeySecret,
},
endpoint: bucketConfig.endpoint, // Omitted for native AWS S3
forcePathStyle: bucketConfig.s3ForcePathStyle ?? false,
});
The PutObjectCommand is then executed with your specified Bucket, Key, Body, and ACL values. The same upload script handles both AWS S3 and Cloudflare R2; when the endpoint is omitted, the AWS SDK automatically resolves the appropriate regional endpoint for S3.
Resolving R2 Connectivity Issues in Restricted Networks
Cloudflare R2 endpoints can encounter SNI blocking by the Great Firewall. If uploads fail, inspect piclist.log to identify the resolved IP address. Add this IP to PicList’s proxy exception list under Settings → Network → Proxy to bypass the blockage. This troubleshooting step is documented in FAQ.md.
Configuration File Examples
Bucket Configuration JSON
When saved, your settings produce a JSON object structured like this (example for Cloudflare R2):
{
"type": "aws-s3",
"name": "my-r2-bucket",
"config": {
"accessKeyId": "R2_SECRET_ID",
"accessKeySecret": "R2_SECRET_KEY",
"bucketName": "my-r2-bucket",
"endpoint": "https://1234567890.r2.cloudflarestorage.com",
"s3ForcePathStyle": true,
"acl": "public-read"
}
}
Upload Script Implementation
The core logic in scripts/upload-to-s3.js demonstrates how the configuration object is consumed:
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
const fs = require('fs');
const path = require('path');
async function upload(filePath, config) {
const client = new S3Client({
region: 'auto',
credentials: {
accessKeyId: config.accessKeyId,
secretAccessKey: config.accessKeySecret,
},
endpoint: config.endpoint,
forcePathStyle: config.s3ForcePathStyle,
});
const command = new PutObjectCommand({
Bucket: config.bucketName,
Key: path.basename(filePath),
Body: fs.createReadStream(filePath),
ACL: config.acl,
});
return client.send(command);
}
Summary
- PicList uses the
aws-s3plugin for both Amazon S3 and Cloudflare R2 via S3-compatible APIs. - Cloudflare R2 requires a custom endpoint and
s3ForcePathStyle: true, while AWS S3 uses regional endpoints and virtual-hosted styles by default. - Configuration fields are defined in
src/renderer/manage/utils/constants.tsand processed byscripts/upload-to-s3.js. - For R2 users behind restrictive firewalls, adding the resolved IP to the proxy list resolves SNI blocking issues.
Frequently Asked Questions
Does PicList support Cloudflare R2 natively?
Yes. PicList supports Cloudflare R2 through the aws-s3 plugin, utilizing R2’s S3-compatible API. You configure it by selecting the aws-s3 bucket type and providing your R2-specific credentials and endpoint.
What is the correct endpoint format for Cloudflare R2?
The endpoint must be https://<ACCOUNT_ID>.r2.cloudflarestorage.com, replacing <ACCOUNT_ID> with your actual Cloudflare account ID. This value is mandatory for R2 but should be left blank for standard AWS S3 configurations.
Why does R2 require Force Path Style while AWS S3 does not?
Cloudflare R2 requires path-style URLs (https://endpoint/bucket/key) rather than virtual-hosted style (https://bucket.endpoint/key). Setting s3ForcePathStyle to true ensures the AWS SDK constructs URLs compatible with R2’s architecture.
How do I troubleshoot upload failures with R2 from China?
If you encounter timeouts or SSL errors, check piclist.log for the IP address resolved from the R2 endpoint. Add this specific IP address to the proxy list in Settings → Network → Proxy to circumvent SNI-based blocking, as noted in the project’s FAQ.md.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →