Integrating Cloudflare R2 with Konifer
Objective
Store Konifer assets in Cloudflare R2 and deliver them through temporary presigned URLs.
What you will need
Complete the common guide prerequisites. You will also need:
- A Cloudflare account with R2 enabled.
- Access to the Cloudflare dashboard or Wrangler installed.
Open the Bruno collection as described in the Guides overview. The requests for this guide are under Guides > Cloudflare R2 Integration.
1. Create a bucket in R2
Using the Cloudflare dashboard or Wrangler, create an R2 bucket named profile-pictures. To use Wrangler, run:
npx wrangler login
npx wrangler r2 bucket create profile-pictures
Verify that the new bucket appears in the bucket list:
npx wrangler r2 bucket list
2. Generate Cloudflare API credentials
Konifer integrates with Cloudflare R2 using the S3-compatible API. To enable that, you must generate API credentials that can be supplied to Konifer.
This must be done in the Cloudflare dashboard.
- Go to the Cloudflare dashboard and log in if necessary.
- Select Storage & databases > R2 > Overview.
- Select Manage in API Tokens.
- Select Create Account API token or Create User API token.
- Choose Object Read & Write permission and Apply to specific buckets only to select the buckets you want to access.
- Select Create API Token.
- Copy the Access Key ID and Secret Access Key. Store these securely as you cannot view the secret again.
You will also need your S3 API URL which is at the bottom of the page that contains your API credentials. It will look something like this:
https://<ACCOUNT_ID>.r2.cloudflarestorage.com
3. Configure Konifer
Create a file named konifer.conf and configure:
- Your
object-store(Object Store reference) - Your path configuration to always use the
profile-picturesbucket
data-store {
provider = in-memory
}
object-store {
provider = s3
s3 {
access-key = "<ACCESS_KEY_ID>"
endpoint-url = "https://<ACCOUNT_ID>.r2.cloudflarestorage.com"
region = "auto"
}
}
paths {
"/**" {
object-store {
bucket = "profile-pictures"
}
return-format {
redirect {
strategy = presigned
presigned {
ttl = 30m
}
}
}
}
}
Replace <ACCESS_KEY_ID> and <ACCOUNT_ID> with your Cloudflare values. The Secret Access Key will be supplied through
the S3_SECRET_KEY environment variable when you start Konifer.
4. Start Konifer
Start Konifer with your konifer.conf file and S3_SECRET_KEY environment variable:
read -rsp "R2 secret access key: " S3_SECRET_KEY
export S3_SECRET_KEY
printf '\n'
docker run \
--rm \
--name konifer \
--publish 8080:8080 \
--env S3_SECRET_KEY \
--mount type=bind,source="$PWD/konifer.conf",target=/app/config/konifer.conf,readonly \
ghcr.io/dmaiken/konifer:0.10.3
Leave the container running. In Bruno, send the Health request and confirm that it returns 200 OK.
5. Store an asset
Open the Store Asset request, select an image from your computer for the asset field in the multipart form body,
and send the request. Confirm that Konifer returns 201 Created.
The Bruno requests in this guide use the asset path users/123abc/profile-pictures. In the Cloudflare dashboard,
confirm that an object now appears in the profile-pictures bucket.
6. Request a variant's content
Open the Fetch Asset Content request. Enable any transformations you want under Params, then send the request.
Confirm that Konifer returns 200 OK and that Bruno displays the image.
Bruno 4.0.0 may crash while previewing JXL responses.
7. Request a presigned redirect
Open the Fetch Presigned Redirect request. Enable any transformations you want under Params, then send the request.
Konifer returns 307 Temporary Redirect because the path uses the presigned redirect strategy. This request disables
automatic redirect following so you can inspect the intermediate response. Confirm that the Location response header
contains an R2 URL with X-Amz-Algorithm, X-Amz-Expires, and X-Amz-Signature query parameters.
To follow the redirect and retrieve the image from R2, send the Fetch and Follow Presigned Redirect request. Confirm
that the final response is 200 OK and contains the image.
Bruno may display "There was an error executing the request" in its Timeline
for a 307 response. This is a Bruno redirect-handling message and does not
mean the Konifer request failed.
8. Remove assets
Optionally, if you want to delete the asset and variant, open the Recursive Delete request and execute it.
Confirm a 204 is received and all variants are removed in your profile-pictures bucket in R2.
9. Clean up
Stop Konifer with Ctrl+C, then remove the secret from your shell environment:
unset S3_SECRET_KEY