---
title: Deploying Self-Hosted Storage with Docker
description: Step-by-step guide to running Allure Report Storage in Docker, including S3-compatible storage as an alternative to the local filesystem.
---

# Deploying Self-Hosted Storage with Docker (Allure 3)

Run [Allure Report Storage](/docs/self-hosted-storage/) in a container on any machine that can run Docker.

1. [Start the service](#_1-start-the-service).
2. [Validate it's running](#_2-validate-its-running).
3. [Use S3-compatible storage instead of the filesystem](#_3-use-s3-compatible-storage-instead-of-the-filesystem) (optional).

## Requirements

- [Docker](https://docs.docker.com/get-docker/)
- [Docker Compose](https://docs.docker.com/compose/install/)

## 1. Start the service

Using the `compose.yaml` file from the [repository](https://github.com/allure-framework/allure-report-storage):

```bash
docker compose up --build
```

By default this stores report files on local disk and metadata in a bundled SQLite database, with no external database or bucket needed. Two environment variables matter:

| Variable       | Purpose                                                                              |
| -------------- | ------------------------------------------------------------------------------------ |
| `ACCESS_TOKEN` | Bootstrap bearer token - mints report-access tokens and sets a project's main branch |
| `SECRET`       | Signing secret for the report-access tokens the service issues                       |

Both are plain strings you choose yourself, not a generated or fixed-format value; pick anything long and unguessable. Their use is narrow: `ACCESS_TOKEN` only authorizes minting a report-access token (`POST /api/token`) and setting a project's main branch, nothing else; `SECRET` is never sent anywhere, it just signs the report-access tokens issued from those `ACCESS_TOKEN` requests. Neither is what you give to Allure 3 directly - that's a separate, freshly minted `ars1.<payload>.<signature>` token, covered in [Connecting Allure 3 to the storage service](/docs/self-hosted-storage/#connecting-allure-3-to-the-storage-service).

Tip:
`compose.yaml` ships placeholder defaults (`change-me` / `change-me-secret`) so the service runs out of the box for a quick test. Replace both with unique, unguessable values for anything beyond that.

## 2. Validate it's running

```bash
curl http://localhost:3000/api/ping
```

A `{"pong":true,...}` response confirms the service is up. From here, [connect Allure 3 to the storage service](/docs/self-hosted-storage/#connecting-allure-3-to-the-storage-service).

## 3. Use S3-compatible storage instead of the filesystem

Set `STORAGE_BACKEND=s3` to store report files in an S3-compatible bucket instead of on local disk. Metadata stays in SQLite either way.

| Variable               | Required | Purpose                                                                        |
| ---------------------- | -------- | ------------------------------------------------------------------------------ |
| `S3_BUCKET`            | Yes      | Bucket name                                                                    |
| `S3_REGION`            | Yes      | Bucket region (`auto` for Cloudflare R2)                                       |
| `S3_ENDPOINT`          | Yes      | S3-compatible endpoint URL                                                     |
| `S3_ACCESS_KEY_ID`     | No\*     | Access key                                                                     |
| `S3_SECRET_ACCESS_KEY` | No\*     | Secret key                                                                     |
| `S3_FORCE_PATH_STYLE`  | Yes      | `true` for most self-hosted S3-compatible servers (e.g. MinIO), `false` for R2 |
| `S3_SESSION_TOKEN`     | No       | Session token, for temporary credentials                                       |
| `S3_PREFIX`            | No       | Prefix applied to every object key                                             |
| `S3_REPORTS_PREFIX`    | No       | Prefix for report files (default `files`)                                      |
| `S3_ASSETS_PREFIX`     | No       | Prefix for shared assets (default `assets`)                                    |

\* If omitted, the AWS SDK's default credential provider chain is used instead.

Cloudflare R2 example:

```bash
STORAGE_BACKEND=s3
S3_BUCKET=allure-report-storage
S3_REGION=auto
S3_ENDPOINT=https://<cloudflare-account-id>.r2.cloudflarestorage.com
S3_ACCESS_KEY_ID=<access-key>
S3_SECRET_ACCESS_KEY=<secret-key>
S3_FORCE_PATH_STYLE=false
```

Bucket-specific R2 endpoints (`<bucket>.<account-id>.r2.cloudflarestorage.com`) are normalized internally to the account-level form above.

See [Self-hosted storage](/docs/self-hosted-storage/) for how to use it: publishing, branches, history, and deleting reports.
