Skip to content
François Turbelin edited this page Jan 19, 2026 · 18 revisions

We suggest to use Amazon S3 or a S3-compatible alternative (OVH Object Storage, CleverCloud Cellar Object Storage, Hetzner Object Storage, ...). A couple of reasons are:

  • S3 is cheaper (cost per storage, and also for data transfer) than hosting the images on a VPS.
  • Hosting the images on S3 reduces the number of requests the web server has to handle, increasing its overall responsiveness.

This is configured in ofn-install with s3_* variables.

Follow these steps to set this up:

Users and policies

  • Create an AWS account. This requires a debit/credit card and other account details.
  • Once you have access to the Amazon Web Services console, select "Identity and Access Management"
  • Click "Users" in sidebar.
  • Click "Create new users".
  • Enter a user for each server, e.g. ofn-uk-staging, ofn-uk-production.
  • Click "Create users".
  • Click "Download credentials". Make sure you download and store these!

For each user:

  • Open the user page.
  • Expand the Inline Policies section and click the link.
  • Select "Policy Generator".
  • Choose "Amazon S3" in AWS Service.
  • Select "All actions" in Actions.
  • Enter arn:aws:s3:::ofn-uk-staging,arn:aws:s3:::ofn-uk-staging/* (modify as needed for production) in ARN field.
  • Click "Add statement".
  • Click "Next step" and then save.

S3 buckets

For each server:

  • Go back to the Console homepage (click cube top left).
  • Click S3 service.
  • Click "Create Bucket".
  • Enter a suitable name, e.g. ofn-uk-staging (check the rules).
  • Click "Create".

You can use this setup for database backups as well.

NOTE - Command line client to manage S3 buckets: s3cmd

CORS configuration

It is necessary to setup a CORS configuration on the S3 buckets:

  • Open the Properties tab in the bucket. Click Permissions.
  • Click "Add/Edit CORS Configuration"
  • Add a configuration similar to this:

In JSON format:

[
    {
        "AllowedHeaders": [
            "Authorization"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "https://openfoodnetwork.org.uk"
        ],
        "MaxAgeSeconds": 3000
    }
]

In XML format:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://openfoodnetwork.org.uk</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

(edit the AllowedOrigin as needed)

  • Click Save to close dialog, and click Save on Permissions.

S3-compatible alternative

You can use any S3-compatible storage provider as long as its API is compatible with S3.

The key configuration step is to set the S3_ENDPOINT variable to point to the alternative provider endpoint. You may also need to adjust the region and bucket naming conventions depending on your provider. The S3_CORS_POLICY_DOMAIN variable will also need to be adapted to point on the domain owned by the new provider.

Since the APIs are compatible, no code changes are required.

Note: When switching to a new S3-compatible storage provider, you will need to manually migrate your files from the old bucket to the new one to maintain access to stored files.

Clone this wiki locally