kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: add storage backends guide and update references for image uploads

Andrej 3ef5f680 5e277df0

+281 -1
+1
apps/docs/core/installation/docker-compose.mdx
··· 69 69 - For local/self-hosted setups, MinIO is the recommended option when you want uploads. 70 70 - The Kaneo API creates presigned upload URLs and the browser uploads images directly to the configured storage backend. 71 71 - If you do not configure object storage, leave the `S3_*` variables unset. 72 + - For a complete MinIO example and backend-specific setup notes, see the [storage backends guide](/core/installation/storage-backends). 72 73 73 74 ### Optional MinIO service 74 75
+47 -1
apps/docs/core/installation/object-storage-and-image-uploads.mdx
··· 15 15 16 16 This means Kaneo can work with multiple backends as long as they expose a compatible S3-style API. 17 17 18 + If you want backend-specific setup examples, see the [storage backends guide](/core/installation/storage-backends). 19 + 18 20 ## Recommended local setup: MinIO 19 21 20 22 For local or self-hosted deployments, MinIO is the recommended storage backend. ··· 42 44 43 45 Create the bucket before using uploads. 44 46 47 + ## Important: internal Docker URLs are not enough in production 48 + 49 + When Kaneo generates a presigned upload URL, the browser uploads directly to your storage backend. 50 + 51 + That means `S3_ENDPOINT` must be reachable by the browser, not just by Docker containers. 52 + 53 + For example: 54 + 55 + - `http://minio:9000` works only inside Docker 56 + - `https://files.example.com` works from the browser 57 + 58 + If your Kaneo deployment is public, do not leave `S3_ENDPOINT` set to `http://minio:9000`. 59 + 60 + Use a public MinIO hostname instead, for example: 61 + 62 + ```env 63 + S3_ENDPOINT=https://files.cloud.kaneo.app 64 + S3_BUCKET=kaneo-uploads 65 + S3_ACCESS_KEY_ID=minioadmin 66 + S3_SECRET_ACCESS_KEY=minioadmin 67 + S3_REGION=us-east-1 68 + S3_FORCE_PATH_STYLE=true 69 + S3_PUBLIC_BASE_URL=https://files.cloud.kaneo.app/kaneo-uploads 70 + ``` 71 + 72 + ## Recommended public setup 73 + 74 + The simplest production setup is: 75 + 76 + - `cloud.kaneo.app` for Kaneo 77 + - `files.cloud.kaneo.app` for MinIO 78 + 79 + Expose MinIO on its own public hostname through your reverse proxy. 80 + 81 + Why this is needed: 82 + 83 + - Kaneo signs uploads against `S3_ENDPOINT` 84 + - the browser uses that signed URL directly 85 + - Docker-internal names like `minio` are not resolvable from a user's browser 86 + 87 + Using a dedicated subdomain is recommended over proxying MinIO under a path. 88 + 45 89 ## Other S3-compatible backends 46 90 47 91 Kaneo is not tied to MinIO. Any deployment can point Kaneo at another S3-compatible backend by changing the `S3_*` environment variables. ··· 107 151 108 152 - confirm the bucket exists 109 153 - confirm the credentials can write to the bucket 110 - - confirm the storage endpoint is reachable from the Kaneo API 154 + - confirm the storage endpoint is reachable from the browser 155 + - confirm `S3_ENDPOINT` is a public URL, not an internal Docker hostname 156 + - confirm `S3_PUBLIC_BASE_URL` matches the public asset host if you are using one 111 157 - if using direct browser uploads, confirm CORS is configured correctly for your storage endpoint
+232
apps/docs/core/installation/storage-backends.mdx
··· 1 + --- 2 + title: Storage backends 3 + description: Configure image uploads with MinIO, AWS S3, or Cloudflare R2. 4 + --- 5 + 6 + ## Overview 7 + 8 + Kaneo uses S3-compatible object storage for image uploads in: 9 + 10 + - task descriptions 11 + - task comments 12 + 13 + The browser uploads directly to the configured storage backend using presigned URLs. 14 + 15 + That means one rule matters for every backend: 16 + 17 + - `S3_ENDPOINT` must be reachable by the browser 18 + 19 + Do not use a Docker-internal hostname such as `http://minio:9000` for a public deployment unless the browser can actually reach it. 20 + 21 + ## Required Kaneo variables 22 + 23 + ```env 24 + S3_ENDPOINT= 25 + S3_BUCKET= 26 + S3_ACCESS_KEY_ID= 27 + S3_SECRET_ACCESS_KEY= 28 + S3_REGION=us-east-1 29 + S3_FORCE_PATH_STYLE=false 30 + S3_PUBLIC_BASE_URL= 31 + ``` 32 + 33 + Notes: 34 + 35 + - `S3_PUBLIC_BASE_URL` is recommended when your asset URL should be different from the raw S3 endpoint. 36 + - `S3_FORCE_PATH_STYLE=true` is usually needed for MinIO. 37 + - `S3_FORCE_PATH_STYLE=false` is usually correct for AWS S3 and R2. 38 + 39 + ## MinIO 40 + 41 + MinIO is the recommended self-hosted option. 42 + 43 + ### Local Docker setup 44 + 45 + For local development, this is fine: 46 + 47 + ```env 48 + MINIO_ROOT_USER=minioadmin 49 + MINIO_ROOT_PASSWORD=minioadmin 50 + 51 + S3_ENDPOINT=http://minio:9000 52 + S3_BUCKET=kaneo-uploads 53 + S3_ACCESS_KEY_ID=minioadmin 54 + S3_SECRET_ACCESS_KEY=minioadmin 55 + S3_REGION=us-east-1 56 + S3_FORCE_PATH_STYLE=true 57 + S3_PUBLIC_BASE_URL=http://localhost:9000/kaneo-uploads 58 + ``` 59 + 60 + This works when Kaneo and MinIO are on the same Docker network and your browser reaches MinIO through `localhost`. 61 + 62 + ### Public deployment 63 + 64 + For a public deployment, expose MinIO on its own hostname through your reverse proxy. 65 + 66 + Example: 67 + 68 + - Kaneo: `https://cloud.kaneo.app` 69 + - MinIO: `https://files.cloud.kaneo.app` 70 + 71 + This can be done with Caddy, Nginx, Traefik, or any other reverse proxy. 72 + 73 + Then use: 74 + 75 + ```env 76 + S3_ENDPOINT=https://files.cloud.kaneo.app 77 + S3_BUCKET=kaneo-uploads 78 + S3_ACCESS_KEY_ID=minioadmin 79 + S3_SECRET_ACCESS_KEY=minioadmin 80 + S3_REGION=us-east-1 81 + S3_FORCE_PATH_STYLE=true 82 + S3_PUBLIC_BASE_URL=https://files.cloud.kaneo.app/kaneo-uploads 83 + ``` 84 + 85 + You also need: 86 + 87 + - a created bucket 88 + - MinIO CORS allowing your Kaneo origin 89 + 90 + ## AWS S3 91 + 92 + AWS S3 is the simplest managed option. 93 + 94 + Use a bucket and an IAM user with access to that bucket. 95 + 96 + Example: 97 + 98 + ```env 99 + S3_ENDPOINT=https://s3.us-east-1.amazonaws.com 100 + S3_BUCKET=kaneo-uploads 101 + S3_ACCESS_KEY_ID=AKIA... 102 + S3_SECRET_ACCESS_KEY=... 103 + S3_REGION=us-east-1 104 + S3_FORCE_PATH_STYLE=false 105 + S3_PUBLIC_BASE_URL=https://kaneo-uploads.s3.us-east-1.amazonaws.com 106 + ``` 107 + 108 + For another AWS region, adjust both: 109 + 110 + - `S3_ENDPOINT` 111 + - `S3_PUBLIC_BASE_URL` 112 + 113 + Recommended S3 CORS policy: 114 + 115 + ```json 116 + [ 117 + { 118 + "AllowedHeaders": ["*"], 119 + "AllowedMethods": ["GET", "PUT", "HEAD"], 120 + "AllowedOrigins": ["https://cloud.kaneo.app"], 121 + "ExposeHeaders": ["ETag"] 122 + } 123 + ] 124 + ``` 125 + 126 + ## Cloudflare R2 127 + 128 + R2 works well because it exposes an S3-compatible API. 129 + 130 + Use your account endpoint, bucket, and R2 access keys. 131 + 132 + Example: 133 + 134 + ```env 135 + S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com 136 + S3_BUCKET=kaneo-uploads 137 + S3_ACCESS_KEY_ID=... 138 + S3_SECRET_ACCESS_KEY=... 139 + S3_REGION=auto 140 + S3_FORCE_PATH_STYLE=false 141 + S3_PUBLIC_BASE_URL=https://pub-<hash>.r2.dev 142 + ``` 143 + 144 + Notes: 145 + 146 + - `S3_REGION=auto` is typical for R2 147 + - `S3_PUBLIC_BASE_URL` should usually point to your public bucket domain or custom domain 148 + - if your bucket is not public, image rendering will not work from stored asset URLs 149 + 150 + ## One copy-paste self-hosted example 151 + 152 + This example gives you Kaneo + MinIO in one Compose file. 153 + 154 + ```yml 155 + services: 156 + postgres: 157 + image: postgres:16-alpine 158 + env_file: 159 + - .env 160 + volumes: 161 + - postgres_data:/var/lib/postgresql/data 162 + restart: unless-stopped 163 + healthcheck: 164 + test: ["CMD-SHELL", "pg_isready -U kaneo -d kaneo"] 165 + interval: 10s 166 + timeout: 5s 167 + retries: 5 168 + 169 + api: 170 + image: ghcr.io/usekaneo/api:latest 171 + env_file: 172 + - .env 173 + depends_on: 174 + postgres: 175 + condition: service_healthy 176 + restart: unless-stopped 177 + 178 + web: 179 + image: ghcr.io/usekaneo/web:latest 180 + env_file: 181 + - .env 182 + depends_on: 183 + - api 184 + restart: unless-stopped 185 + 186 + minio: 187 + image: minio/minio:latest 188 + command: server /data --console-address ":9001" 189 + env_file: 190 + - .env 191 + volumes: 192 + - minio_data:/data 193 + restart: unless-stopped 194 + 195 + volumes: 196 + postgres_data: 197 + minio_data: 198 + ``` 199 + 200 + Matching `.env`: 201 + 202 + ```env 203 + KANEO_CLIENT_URL=https://cloud.kaneo.app 204 + KANEO_API_URL=https://cloud.kaneo.app/api 205 + 206 + MINIO_ROOT_USER=minioadmin 207 + MINIO_ROOT_PASSWORD=change-me 208 + 209 + S3_ENDPOINT=https://files.cloud.kaneo.app 210 + S3_BUCKET=kaneo-uploads 211 + S3_ACCESS_KEY_ID=minioadmin 212 + S3_SECRET_ACCESS_KEY=change-me 213 + S3_REGION=us-east-1 214 + S3_FORCE_PATH_STYLE=true 215 + S3_PUBLIC_BASE_URL=https://files.cloud.kaneo.app/kaneo-uploads 216 + ``` 217 + 218 + Before testing uploads: 219 + 220 + 1. Create the `kaneo-uploads` bucket. 221 + 2. Configure MinIO CORS for your Kaneo origin. 222 + 3. Make sure `files.cloud.kaneo.app` resolves publicly. 223 + 224 + ## Troubleshooting 225 + 226 + If uploads fail: 227 + 228 + - check that the bucket exists 229 + - check that `S3_ENDPOINT` is public and browser-reachable 230 + - check that `S3_PUBLIC_BASE_URL` points to the correct public asset host 231 + - check CORS on your storage backend 232 + - check that the access key can `PutObject` and `GetObject`
+1
apps/docs/docs.json
··· 66 66 "core/installation/drim", 67 67 "core/installation/docker-compose", 68 68 "core/installation/object-storage-and-image-uploads", 69 + "core/installation/storage-backends", 69 70 "core/installation/environment-variables", 70 71 "core/installation/start-services" 71 72 ]