Use Cloudflare R2 with MinIO Gateway for Kestra icon Use Cloudflare R2 with MinIO Gateway for Kestra

This guide demonstrates how to use Cloudflare R2 as an object storage backend through an S3-compatible interface, exposed to Kestra via a MinIO Gateway. This setup enables Kestra to continue using S3 storage without requiring configuration changes.

Use Cloudflare R2 with MinIO Gateway for Kestra


Create an R2 Bucket

Log into Cloudflare Dashboard and create a new R2 bucket:

  1. Navigate to R2 → Create Bucket
  2. Choose a name like kestra-bucket

Generate Access Keys

Go to API Tokens → R2 Keys and create a new key pair:

  • access_key_id: Your user access key
  • secret_access_key: Your secret key

Be sure to save these credentials securely.


Retrieve the R2 Endpoint

Cloudflare R2 provides a static S3-compatible endpoint:

https://<ACCOUNT_ID>.r2.cloudflarestorage.com

Replace <ACCOUNT_ID> with your Cloudflare account ID, found in the R2 dashboard.


Set Up MinIO Gateway to R2

MinIO will act as a gateway, forwarding all S3 traffic to Cloudflare R2.

docker-compose.yml

version: '3.8'
services:
minio:
image: minio/minio:latest
container_name: minio-r2-gateway
command: gateway s3 https://<ACCOUNT_ID>.r2.cloudflarestorage.com
environment:
MINIO_ROOT_USER: <R2_ACCESS_KEY>
MINIO_ROOT_PASSWORD: <R2_SECRET_KEY>
ports:
- "9000:9000"
restart: always

Replace <ACCOUNT_ID>, <R2_ACCESS_KEY>, and <R2_SECRET_KEY> with your actual Cloudflare and access values.


Validate Setup with MinIO Client

Install the MinIO Client (mc):

mc alias set r2 http://localhost:9000 <R2_ACCESS_KEY> <R2_SECRET_KEY>
mc mb r2/kestra-bucket
mc ls r2

Configure Kestra (No Changes Required)

Since Kestra supports MinIO-compatible S3 endpoints, no changes to your configuration are required:

storage:
type: minio
minio:
endpoint: localhost
port: 9000
bucket: kestra-bucket
access-key: <R2_ACCESS_KEY>
secret-key: <R2_SECRET_KEY>

Kestra will interact with MinIO, which in turn proxies to R2.


Test with a Flow

id: r2_test_flow
namespace: company.team
tasks:
- id: write_output
type: io.kestra.plugin.scripts.python.Script
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
containerImage: ghcr.io/kestra-io/pydata:latest
outputFiles:
- r2-output.json
script: |
import json
from kestra import Kestra
data = {'message': 'stored in R2'}
Kestra.outputs(data)
with open('r2-output.json', 'w') as f:
json.dump(data, f)

Then, verify the file was stored correctly using:

mc cat r2/kestra-bucket/main/company/team/r2_test_flow/...

Expected output:

{"message": "stored in R2"}%

References


You now have Cloudflare R2 configured as your object storage backend for Kestra, fully integrated via MinIO Gateway.

Was this page helpful?