A Comprehensive Guide: How to Set Up Private Storage with Cloudflare R2 Buckets and S3 API Compatibility
Craft your personalized storage buckets, forging a realm of effortless file management and securely by Cloudflare R2
Vision & Architecture. This project is a robust, high-performance private file management ecosystem engineered with a focus on absolute flexibility and security. Conceptualized, architected, and designed by 0xgrey, it delivers a highly compatible and intuitive cloud storage interface powered by Cloudflare R2. By bridging the gap between streamlined user experience and enterprise-grade security protocols, the project anticipates the evolving needs of personal data management while ensuring a seamless, low-latency operational environment.
- ❇️ Full-Stack Architecture: End-to-end deployment (Flask/Nginx) featuring a fully responsive, desktop-and-mobile-optimized UI/UX.
- 📊 Real-Time Analytics: Live API data tracking for bucket utilization, active progress bars, storage capacity metrics, and monthly bandwidth reset monitoring (e.g., 10GB quotas).
- 📁 Advanced File Management: High-speed chunked uploads (1GB+ scalable), real-time filename search, download analytics, secure sharing links, and direct RAW streaming modes.
- 🎨 Dynamic Media Interface: Intelligent media handling supporting extensive file-type icons, rich preview effects, and a responsive sliding-grid layout.
- 🧩 Universal S3 Compatibility: Built on the robust Amazon S3 API (
boto3) ensuring seamless deployment, high-throughput streaming, and interoperability across cloud providers. - 🗑️ Lifecycle & Cleanup (Trash & Burn): Comprehensive state management with global bucket wipe capabilities, preventing orphaned data and maintaining R2 integrity.
- 🐳 Containerized Infrastructure: Production-ready Docker environment featuring a dual-proxy setup, highly optimized zero-cache Nginx configurations, and strict isolation.
- ☁️ Cloudflare R2 Backbone: Powered by Cloudflare's distributed edge infrastructure for zero-egress, high-availability private data management.
- 🔐 Zero-Trust Security Gate: Formidable authentication barrier utilizing timing-safe passwords, strict HttpOnly/Secure JWT sessions, proactive rate-limiting, and hardened HTTP security headers.
Password: project123
cloudflare-storage/
├── .gitignore
├── .dockerignore
├── .env.example
├── docker-compose.yml
├── backend/
+ ├── README.md # Guides delete buckets R2/AWS-S3
│ ├── Dockerfile
│ ├── requirements.txt
│ ├── app.py
│ ├── delete_buckets.py
│ └── data/
│ └── .gitkeep
├── frontend/
│ ├── Dockerfile
│ ├── nginx.conf.template # Enhanced for reverse proxy nginx + cloudflare
│ ├── index.html
│ ├── login.html
│ ├── style.css
│ ├── script.js
│ └── src/
│ └── favicon.ico
├── docs/
+ ├── README.md # Guides main host nginx + template
│ └── /etc/nginx/sites-available/your-domain
│
├── LICENSE
└── README.mdSignup & Securely Cloudflare Access
- Dashboard R2 settings → https://dash.cloudflare.com/?to=/:account/r2/overview
- Buy domain up to you (Recommended for use an infra cloudflare)
- Free tier is limit Per/month 10GB (resetting)
Install Docker & Compose if not already installed
Instal docker is optional, if you don't have.. try securely
curl -sSL https://raw.githubusercontent.com/arcxteam/succinct-prover/refs/heads/main/docker.sh | sudo bash
git clone https://github.com/arcxteam/cloudflare-storage.git
cd cloudflare-storage
Create edit & save configuration file
cp .env.example .env
nano .envExample config environment variable
R2_ACCOUNT_ID=YOUR_ACCOUNT_ID
R2_ACCESS_KEY_ID=YOUR_ACCESS_KEY_ID
R2_SECRET_ACCESS_KEY=YOUR_SECRET_ACCESS_KEY
R2_BUCKET_NAME=YOUR_NAME_CREATE_BUCKETS
+ Enabled (Public Development URL or Custom Domains, Create Record A sub-sub-domain)
R2_PUBLIC_URL=https://pub-xxxxx.r2.dev or https://sub-sub-your-domain.com
# NOTE: Choose one, personal access web-ui dashboard (upload/download)
+ Option A: IP Public server
PUBLIC_BASE_URL=http://your-ip-address
+ Option B: Localnetwork (VSCode/Codespaces/etc)
PUBLIC_BASE_URL=http://localhost
+ Option C: Custom domains
PUBLIC_BASE_URL=https://your-domain.com or sub-domain
+ Auth Security (admin login for web UI dashboard)
ADMIN_PASSWORD=Password-Here
+ Auto-generated if not set
AUTH_SECRET_KEY=your-random-secret-key
AUTH_SESSION_HOURS=24- Access Dashboard Cloudflare
- Chosee Storage & database → R2 Object Storage → Overview
- Create bucket
- Add Detail Bucket:
- Bucket name: Create unique
- Location: Automatic
- Save → Create bucket
- Return to R2, then select Manage R2 API tokens.
- Select Create Account API Tokens.
- In Permissions, select Object Read & Write.
- In Specify bucket(s), choose Apply to specific buckets only. Select the bucket you created.
- For TTL default is forever or Define how long this token will stay active:
- For Client IP Address Filtering no have action default is blank/null
- Select Create API Token.
- Copy the Access Key ID, Secret Access Key, and endpoint URL values. You will not be able to access these values again.
- Select Finish.
- Use mode Custom Domain (Production)
- Policy name:
web-app-cors - Allowed origins:
https://your-domain - Allowed methods: Pilih
GET,POST,PUT,DELETE,HEAD - Allowed headers:
* - Max age seconds:
86400 - Click "Add policy or save"`
- Use mode Localhost/Development
- Policy name:
dev-cors-policy - Allowed origins:
http://localhost:5000, http://127.0.0.1:5000 - Other are same & TLS 1.3 optional
Choose one CORS above, a format JSON
[
{
"AllowedOrigins": ["https://your-domain", "http://localhost:5000", "http://127.0.0.1:5000"],
"AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 86400
}
]Starting running
docker compose up --build -d
Monitor logs & stop
docker compose logs -f
# docker compose down
This project includes a built-in admin login portal to protect your private storage from unauthorized access. When anyone visits the web UI, they must enter the admin password before accessing the dashboard.
| Layer | Protection |
|---|---|
| Nginx | auth_request blocks all pages/API without valid session |
| Backend | JWT token in HttpOnly cookie (invisible to JavaScript/DevTools) |
| Rate Limit | Max 5 login attempts per 15 minutes per IP |
| Headers | CSP, X-Frame-Options DENY, XSS Protection, no-cache |
| Variable | Required | Description |
|---|---|---|
ADMIN_PASSWORD |
✅ Yes | Your admin login password (plain text in .env) |
AUTH_SECRET_KEY |
❌ Optional | JWT signing key. Auto-generated if empty, but session resets on container restart. Set for persistence |
AUTH_SESSION_HOURS |
❌ Optional | Login session duration in hours (default: 24) |
nano .env
# Edit: ADMIN_PASSWORD=YourNewPassword
docker compose up -d --buildpython3 -c "import secrets; print(secrets.token_hex(64))"
# Copy the output to AUTH_SECRET_KEY in .envThis project is licensed under the MIT License - see the LICENSE file for details.