Skip to main content

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:

  1. A Cloudflare account with R2 enabled.
  2. 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.

  1. Go to the Cloudflare dashboard and log in if necessary.
  2. Select Storage & databases > R2 > Overview.
  3. Select Manage in API Tokens.
  4. Select Create Account API token or Create User API token.
  5. Choose Object Read & Write permission and Apply to specific buckets only to select the buckets you want to access.
  6. Select Create API Token.
  7. 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-pictures bucket
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.

warning

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.

note

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