> ## Documentation Index
> Fetch the complete documentation index at: https://kaneo.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# The compose.yml file

> The Docker Compose file is used to start the required services.

## The initial compose file

The first step is to create a Docker Compose file. We will call it `compose.yml`.

```yml theme={"theme":{"light":"min-light","dark":"min-dark"}}
services:
  postgres:
    image: postgres:16-alpine
    env_file:
      - .env
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U kaneo -d kaneo"]
      interval: 10s
      timeout: 5s
      retries: 5

  kaneo:
    image: ghcr.io/usekaneo/kaneo:latest
    ports:
      - "5173:5173"
    env_file:
      - .env
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:5173/api/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 60s

volumes:
  postgres_data:
```

## The services and volumes

Kaneo uses the following services:

* `postgres`: The PostgreSQL database.
* `kaneo`: The combined API and web container.

Additionally, the following volumes are used:

* `postgres_data`: The PostgreSQL data.

## Required URL configuration

Copy `.env.sample` to `.env` and uncomment or set these values:

```env theme={"theme":{"light":"min-light","dark":"min-dark"}}
KANEO_CLIENT_URL=http://localhost:5173
POSTGRES_DB=kaneo
POSTGRES_USER=kaneo
POSTGRES_PASSWORD=changeme
AUTH_SECRET=                             # generate: openssl rand -hex 32
```

`KANEO_API_URL` defaults to `KANEO_CLIENT_URL/api`; set it explicitly only if you need to override the default (e.g. a reverse proxy changes the path).

This keeps the browser on one origin while the container proxies `/api` requests to the internal API process.

For this Compose setup, the bundled Kaneo container reaches PostgreSQL at the service hostname `postgres`.
If you run the API directly on your host instead, use `localhost` or set `DATABASE_URL` explicitly.

## Notes on object storage

Kaneo uses S3-compatible object storage for private uploads in task descriptions and comments.

* Object storage is optional. Kaneo runs without it, but uploads in task descriptions and comments will be unavailable.
* For local/self-hosted setups, MinIO is the recommended option when you want uploads.
* The Kaneo API creates presigned upload URLs and the browser uploads files directly to the configured storage backend.
* Kaneo serves uploaded assets back through its own API, so the bucket does not need to be public.
* If you do not configure object storage, leave the `S3_*` variables unset.
* For a complete MinIO example and backend-specific setup notes, see the [storage backends guide](/docs/core/installation/storage-backends).

### Optional MinIO service

Add this service and volume to your `compose.yml` only if you want uploads:

```yml theme={"theme":{"light":"min-light","dark":"min-dark"}}
services:
  minio:
    image: minio/minio:latest
    command: server /data --console-address ":9001"
    env_file:
      - .env
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio_data:/data
    restart: unless-stopped

volumes:
  minio_data:
```

Set the matching `S3_*` environment variables in your `.env` file. See the [environment variables page](/docs/core/installation/environment-variables).

### Example `.env` values for MinIO

```env theme={"theme":{"light":"min-light","dark":"min-dark"}}
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin

S3_ENDPOINT=http://minio:9000
S3_BUCKET=kaneo-uploads
S3_ACCESS_KEY_ID=minioadmin
S3_SECRET_ACCESS_KEY=minioadmin
S3_REGION=us-east-1
S3_FORCE_PATH_STYLE=true
```

Create the bucket before testing uploads. With MinIO, you can do that from the MinIO Console at `http://localhost:9001`.

### Using `fs` instead of MinIO

If you want to use [`fs`](https://github.com/ferdzo/fs), you can point the same `S3_*` variables at its endpoint instead of MinIO. Kaneo only needs an S3-compatible API endpoint, credentials, and a bucket.

When using `fs`, keep these differences in mind:

* Set `S3_FORCE_PATH_STYLE=true`.
* Create buckets through the S3 API or CLI, not through a web console.
* Browser uploads may require reverse-proxy CORS handling, because `fs` does not currently implement S3 CORS APIs.

After creating the compose file, the next step is to set up the environment variables.
