diff --git a/charts/appwrite/README.md b/charts/appwrite/README.md index 0604d96..e131ac7 100644 --- a/charts/appwrite/README.md +++ b/charts/appwrite/README.md @@ -908,10 +908,10 @@ The build orchestrator and the executor. | compute.executor.podAnnotations | object | `{}` | Pod annotations, merged over `defaults.podAnnotations`. | | compute.executor.podLabels | object | `{}` | Pod labels, merged over `defaults.podLabels`. | | compute.executor.priorityClassName | string | `""` | Priority class. Empty inherits `defaults.priorityClassName`. | -| compute.executor.privileged | bool | `true` | Run the Docker daemon as a privileged container, which makes it root on its node. Required unless `runtimeClassName` names a runtime that runs Docker without it, such as Sysbox. For production, give the executor nodes of its own (`nodeSelector`, `tolerations`). | +| compute.executor.privileged | bool | `true` | Run the Docker daemon as a privileged container, which makes it root on its node. Set to false, together with `runtimeClassName`, for a runtime that runs Docker without it, such as Sysbox. For production, give the executor nodes of its own (`nodeSelector`, `tolerations`). | | compute.executor.replicaCount | int | `1` | Executor replicas. Each has its own Docker daemon: a runtime starts on the replica an execution reaches and stays there until it's idle. | | compute.executor.resources | object | `{"limits":{"memory":"4Gi"},"requests":{"cpu":"500m","memory":"1Gi"}}` | Resources of the Docker daemon container, which runs the executor and every runtime: size it for the executions you expect. | -| compute.executor.runtimeClassName | string | `""` | RuntimeClass of executor pods, e.g. `sysbox-runc`. | +| compute.executor.runtimeClassName | string | `""` | RuntimeClass of executor pods, e.g. `sysbox-runc` (with `privileged: false`). | | compute.executor.terminationGracePeriodSeconds | int | `60` | Seconds to wait on shutdown. | | compute.executor.tolerations | list | `[]` | Tolerations. Empty inherits `defaults.tolerations`. | | compute.executor.topologySpreadConstraints | list | `[]` | Topology spread constraints. Empty inherits `defaults.topologySpreadConstraints`, or spreads replicas across nodes. | diff --git a/charts/appwrite/values.schema.json b/charts/appwrite/values.schema.json index 7b0f4d1..7b1ee3d 100644 --- a/charts/appwrite/values.schema.json +++ b/charts/appwrite/values.schema.json @@ -1379,7 +1379,7 @@ "type": "string" }, "privileged": { - "description": "Run the Docker daemon as a privileged container, which makes it root on its node. Required unless `runtimeClassName` names a runtime that runs Docker without it, such as Sysbox. For production, give the executor nodes of its own (`nodeSelector`, `tolerations`).", + "description": "Run the Docker daemon as a privileged container, which makes it root on its node. Set to false, together with `runtimeClassName`, for a runtime that runs Docker without it, such as Sysbox. For production, give the executor nodes of its own (`nodeSelector`, `tolerations`).", "type": "boolean" }, "replicaCount": { @@ -1419,7 +1419,7 @@ "description": "Resources of the Docker daemon container, which runs the executor and every runtime: size it for the executions you expect." }, "runtimeClassName": { - "description": "RuntimeClass of executor pods, e.g. `sysbox-runc`.", + "description": "RuntimeClass of executor pods, e.g. `sysbox-runc` (with `privileged: false`).", "type": "string" }, "terminationGracePeriodSeconds": { diff --git a/charts/appwrite/values.yaml b/charts/appwrite/values.yaml index ea2d9b1..bf74b95 100644 --- a/charts/appwrite/values.yaml +++ b/charts/appwrite/values.yaml @@ -828,11 +828,12 @@ compute: # on Docker-in-Docker, in a namespace of its own. executor: # -- Run the Docker daemon as a privileged container, which makes it root - # on its node. Required unless `runtimeClassName` names a runtime that runs - # Docker without it, such as Sysbox. For production, give the executor - # nodes of its own (`nodeSelector`, `tolerations`). + # on its node. Set to false, together with `runtimeClassName`, for a + # runtime that runs Docker without it, such as Sysbox. For production, + # give the executor nodes of its own (`nodeSelector`, `tolerations`). privileged: true - # -- RuntimeClass of executor pods, e.g. `sysbox-runc`. + # -- RuntimeClass of executor pods, e.g. `sysbox-runc` (with + # `privileged: false`). runtimeClassName: "" # -- Namespace of the executor. Defaults to `-executor`. # Use a different one per release when several releases share a namespace. diff --git a/docs/gitops.md b/docs/gitops.md index 14dc768..7ba1081 100644 --- a/docs/gitops.md +++ b/docs/gitops.md @@ -36,12 +36,26 @@ credentials, and how upgrades run Appwrite's data migration. > clickhouse: > password: > secretName: appwrite-credentials +> storage: +> s3: # the built-in object storage's keys too +> accessKeyId: +> secretName: appwrite-credentials +> secretAccessKey: +> secretName: appwrite-credentials +> compute: +> secrets: +> existingSecret: appwrite-credentials +> executor: +> existingSecret: appwrite-executor # a copy in the executor namespace > migrations: > mode: job > ``` > -> With Functions and Sites, add the [compute Secrets](#what-goes-in-the-secrets) -> too. [Credentials](#credentials) has the details. +> Functions and Sites are on by default, so the executor needs +> [its own copy](#what-goes-in-the-secrets) of its secret and the S3 keys, in +> its namespace. Without Functions and Sites, set `compute.enabled: false` +> and leave out the `compute` block. [Credentials](#credentials) has the +> details. ## Credentials @@ -83,9 +97,9 @@ change it. | `database.password.secretName` | `db-password` (`database.password.secretKey`) | always: generated for the built-in PostgreSQL, required for an external database | | `redis.password.secretName` | `redis-password` (`redis.password.secretKey`) | built-in Redis with `redis.builtin.requirePassword` (the default), or an external Redis with a password | | `clickhouse.password.secretName` | `clickhouse-password` (`clickhouse.password.secretKey`) | built-in ClickHouse, or an external one with a password | -| `compute.secrets.existingSecret` | `executor-secret`, `orchestrator-secret` (`compute.secrets.executorSecretKey`, `orchestratorSecretKey`) | `compute.enabled` | -| `compute.executor.existingSecret`, **in the executor namespace** | `executor-secret`, `s3-access-key`, `s3-secret-key` ([executor.md](executor.md#existing-secrets)) | `compute.enabled`, with `compute.secrets.existingSecret` or an S3 `secretName` | -| `storage.s3.accessKeyId.secretName`, `storage.s3.secretAccessKey.secretName` | `s3-access-key`, `s3-secret-key` (their `secretKey`) | S3 storage | +| `compute.secrets.existingSecret` | `executor-secret`, `orchestrator-secret` (`compute.secrets.executorSecretKey`, `orchestratorSecretKey`) | `compute.enabled`, the default | +| `compute.executor.existingSecret`, **in the executor namespace** | `executor-secret`, `s3-access-key`, `s3-secret-key` ([executor.md](executor.md#existing-secrets)) | `compute.enabled`, the default, with `compute.secrets.existingSecret` or an S3 `secretName` | +| `storage.s3.accessKeyId.secretName`, `storage.s3.secretAccessKey.secretName` | `s3-access-key`, `s3-secret-key` (their `secretKey`) | `storage.device: s3`, the default: for the built-in object storage too, whose keys the chart would otherwise generate | | `documentsDb.password.secretName`, `vectorsDb.password.secretName` | `documentsdb-password`, `vectorsdb-password` (their `secretKey`) | DocumentsDB or VectorsDB with a password other than the main database's | | `smtp.password.secretName` | `smtp-password` (`smtp.password.secretKey`) | SMTP with a password | @@ -298,12 +312,22 @@ spec: clickhouse: password: secretName: appwrite-credentials - migrations: - mode: job storage: + s3: + accessKeyId: + secretName: appwrite-credentials + secretAccessKey: + secretName: appwrite-credentials volume: annotations: argocd.argoproj.io/sync-options: Prune=false,Delete=false + compute: + secrets: + existingSecret: appwrite-credentials + executor: + existingSecret: appwrite-executor + migrations: + mode: job # ... the rest of your values destination: server: https://kubernetes.default.svc diff --git a/docs/security.md b/docs/security.md index aae277e..2e678c5 100644 --- a/docs/security.md +++ b/docs/security.md @@ -77,8 +77,9 @@ Executions need a Docker daemon: the container per runtime. In the cluster the chart gives each executor pod its own daemon (Docker-in-Docker), which runs as a **privileged container: root on its node**, and it runs your users' code. That is the one exception to the -standards above, and the chart only renders it when you accept it -(`compute.executor.privileged: true`, or `runtimeClassName` for Sysbox): +standards above. It's on by default (`compute.executor.privileged: true`); +turn it off with `compute.enabled: false`, or run the daemon through Sysbox +instead (`privileged: false` with `runtimeClassName`): - The executor gets a namespace of its own, the only one labelled for the `privileged` standard. The Appwrite namespace stays `restricted` and the @@ -166,6 +167,17 @@ redis: clickhouse: password: secretName: appwrite-clickhouse # key: clickhouse-password +storage: + s3: # the built-in object storage's keys too + accessKeyId: + secretName: appwrite-s3 # key: s3-access-key + secretAccessKey: + secretName: appwrite-s3 # key: s3-secret-key +compute: # Functions and Sites, on by default + secrets: + existingSecret: appwrite-compute # keys: executor-secret, orchestrator-secret + executor: + existingSecret: appwrite-executor # a copy in the executor namespace (executor.md#existing-secrets) ``` Key names are configurable (`appwrite.secrets.keys.*`, and `secretKey` next diff --git a/docs/storage.md b/docs/storage.md index c4acaea..ae90937 100644 --- a/docs/storage.md +++ b/docs/storage.md @@ -186,12 +186,12 @@ If you restricted egress with `networkPolicy.egress.enabled`, allow the endpoint in `networkPolicy.egress.extraRules` ([security.md](security.md#egress)). -With `endpoint` empty, Appwrite talks to AWS S3 with virtual-hosted URLs +With `storage.s3.external.endpoint` empty, Appwrite talks to AWS S3 with virtual-hosted URLs (`.s3..amazonaws.com`). With an endpoint, it uses path-style URLs (`//...`), which every S3-compatible store accepts. An endpoint without a scheme gets `https://`. -| Provider | `endpoint` | `region` | +| Provider | `external.endpoint` | `external.region` | | --- | --- | --- | | AWS S3 | *(empty)* | the bucket's region, e.g. `eu-central-1` | | Cloudflare R2 | `https://.r2.cloudflarestorage.com` | `auto` | diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 5ccf8f9..ac2c5c5 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -219,10 +219,12 @@ the built-in ClickHouse with your own Secret too. ### S3: uploads fail with `SignatureDoesNotMatch`, `AccessDenied` or `NoSuchBucket` -Check `region` (R2 and GCS use `auto`), that the bucket exists, and that the -key may read, write, list and delete in it. With an `endpoint`, Appwrite uses -path-style URLs, which the store must accept -([storage.md](storage.md#s3)). +With your own store, check `storage.s3.external.region` (R2 and GCS use +`auto`), that the bucket exists, and that the key may read, write, list and +delete in it. With an `external.endpoint`, Appwrite uses path-style URLs, +which the store must accept ([storage.md](storage.md#your-own-s3-store)). With +the built-in object storage, check that the `seaweedfs` pod is ready: it +creates the bucket when it starts. ### Emails don't arrive @@ -392,7 +394,8 @@ ordinary Jobs. The alternative is [Sysbox](https://github.com/nestybox/sysbox), which runs the daemon without `privileged`: install it on the executor's nodes and set -`compute.executor.runtimeClassName: sysbox-runc` instead +`compute.executor.privileged: false` with +`compute.executor.runtimeClassName: sysbox-runc` ([executor.md](executor.md#without-a-privileged-container)). CI doesn't test it.