## What this PR does On the default `cozy-default` / `useSystemBucket` backup flow, the ClickHouse chart pointed the `clickhouse-backup` sidecar's `S3_ENDPOINT` straight at the projected `cozy-backups-creds.endpoint`, which the backup credentials projector stores as a **bare host** (no scheme) by design. `altinity/clickhouse-backup` runs `S3_ENDPOINT` through the aws-sdk-go-v2 endpoint resolver, which rejects a scheme-less value with `Custom endpoint 's3.host' was not a valid URI` — so every ClickHouse backup and restore on the default flow failed. Reproduced live on a v1.6.2 cluster: a `cozy-default` `BackupJob` against a `useSystemBucket: true` ClickHouse hangs, and the sidecar logs `S3 ResolveEndpoint ... was not a valid URI`. The fix prepends `https://` on the `useSystemBucket` path via a helper env plus `$(VAR)` expansion (a `secretKeyRef` value can't be string-interpolated), mirroring the platform's `backupstrategy-controller.endpoint` helper which force-prepends `https://` for the always-TLS external S3 ingress. The legacy and bring-your-own-Secret paths keep reading `endpoint` verbatim, since that value is tenant-supplied and already carries its own scheme. ClickHouse was the only `cozy-default` app hit by this. I audited every default-flow app: the CNPG/postgres, etcd and velero strategies already get a scheme'd URL from the endpoint helper, and mariadb and foundationdb deliberately pair a bare host with a separate TLS flag; mongodb reads a full URL from its own chart values. So this is the single scheme-class fix needed. Not addressed here (separate, non-scheme gaps surfaced during the audit, flagged for follow-up): MongoDB has no `useSystemBucket` wiring at all (its `cozy-default` strategy assumes a manually-configured `backup.endpointURL` + per-app S3 creds), and FoundationDB's self-signed-CA trust to the operator pod is a known gap. ### Screenshots Not applicable (no UI changes). ### Downstream repositories No schema or API change (only a chart template and its helm-unittest). `values.yaml` / `values.schema.json` / the CRD are untouched, so nothing downstream is affected. Leaving every box unticked per the trigger-map guidance. - [ ] No downstream repository is affected by this change - [ ] [cozystack/website](https://github.com/cozystack/website) - follow-up: - [ ] [cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack) - follow-up: - [ ] [cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack) - follow-up: - [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up: - [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up: - [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) - follow-up: - [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) - follow-up: - [ ] [cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server) - follow-up: - [ ] [cozystack/external-apps-example](https://github.com/cozystack/external-apps-example) - follow-up: - [ ] [cozystack/examples](https://github.com/cozystack/examples) - follow-up: ### Release note ```release-note fix(clickhouse): backup and restore now work on the default system-bucket (useSystemBucket) flow — the clickhouse-backup sidecar receives a scheme'd https:// S3_ENDPOINT instead of the projected bare host, which the S3 client rejected as an invalid URI. ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Corrected ClickHouse backup endpoint configuration when using the system bucket. * Ensured backup connections consistently use the required HTTPS endpoint format. * Improved handling of backup credentials across system bucket, legacy, and custom-secret configurations. * **Tests** * Added coverage validating endpoint and credential wiring for supported backup configurations. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Managed ClickHouse Service
ClickHouse is an open source high-performance and column-oriented SQL database management system (DBMS). It is used for online analytical processing (OLAP).
Backup orchestration
Two backup paths coexist on the chart; pick one per release.
Recommended: BackupClass + Plan via the Altinity strategy
The cluster-scoped Altinity strategy
(strategy.backups.cozystack.io/v1alpha1) wraps
Altinity's clickhouse-backup in a one-shot
batch/v1.Job per BackupJob / RestoreJob. It is engine-aware (FREEZE +
upload), supports both in-place and targetApplicationRef (to-copy) restore,
and does not require any in-chart CronJob.
Wiring per release:
- Set
backup.enabled: trueplus thes3*(ors3CredentialsSecret.name) fields on the chart values. The chart materialises a Secret named<release>-backup-s3carrying bucket coordinates and credentials. That Secret is consumed by the chart-emittedclickhouse-backupsidecar (rendered into the ClickHouseInstallation Pod bytemplates/clickhouse.yaml); the strategy Pod itself is a curl/jq client that reaches the sidecar's HTTP API on port 7171 and never reads the Secret directly. - Cluster admin one-time installs an
Altinitystrategy and aBackupClassthat mapsapps.cozystack.io/ClickHouseto it (seeexamples/backups/clickhouse/01-create-strategy.shand02-create-backupclass.sh). - Tenant creates a
Plan(cron schedule) or submits an ad-hocBackupJobreferencing the BackupClass. Restoring is aRestoreJobreferencing the resultingBackup; omittargetApplicationReffor in-place, set it to a second ClickHouse instance for to-copy.
Bringing your own S3 credentials Secret
Setting backup.s3CredentialsSecret.name makes the chart skip the
materialisation of <release>-backup-s3 and points the sidecar at the
referenced Secret instead. The Secret must hold the five S3 fields as
separate string keys, not a JSON blob; the per-key field names default
to bucketName / endpoint / region / accessKey / secretKey and
can be remapped via backup.s3CredentialsSecret.{bucketKey,endpointKey,…}.
Example:
apiVersion: v1
kind: Secret
metadata:
name: my-s3-creds
namespace: tenant-test
type: Opaque
stringData:
bucketName: my-clickhouse-archive
endpoint: https://s3.example.org
region: us-east-1
accessKey: AKIAIOSFODNN7EXAMPLE
secretKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
---
# In ClickHouse values.yaml:
backup:
enabled: true
s3CredentialsSecret:
name: my-s3-creds
The Cozystack
Bucketapp's BucketInfo Secret (bucket-<name>-<user>, singleBucketInfokey holding a JSON blob) is not directly consumable ass3CredentialsSecret. Either let the chart read the raw values viabackup.s3*(asexamples/backups/clickhouse/03-create-bucket.shdoes — extract coordinates from BucketInfo and pass them to the chart values), or materialise an intermediate Secret with the five string keys above.
Legacy: chart-emitted Restic CronJob
The chart still ships a CronJob that streams per-table SHOW CREATE TABLE
SELECT * FORMAT TabSeparatedinto a Restic repository. This path is kept for backward compatibility; new installations should prefer the BackupClass flow above.
To opt in:
-
Set
backup.enabled: true,backup.schedule: "0 2 * * *"(or another non-empty cron),backup.s3*andbackup.resticPassword. -
To restore manually:
restic -r s3:s3.example.org/clickhouse-backups/table_name snapshots restic -r s3:s3.example.org/clickhouse-backups/table_name restore latest --target /tmp/For more details, read Restic: Effective Backup from Stdin.
The legacy backup.schedule, backup.cleanupStrategy, and
backup.resticPassword values are deprecated and will be removed once the
Altinity strategy is the default in all reference deployments. The
chart-emitted CronJob renders only when backup.schedule is non-empty.
storageClassis annotated as immutable in the chart schema — seedocs/storage-immutability.mdfor the contract and which consumers enforce it.
Parameters
Common parameters
| Name | Description | Type | Value |
|---|---|---|---|
replicas |
Number of ClickHouse replicas. | int |
2 |
shards |
Number of ClickHouse shards. | int |
1 |
resources |
Explicit CPU and memory configuration for each ClickHouse replica. When omitted, the preset defined in resourcesPreset is applied. |
object |
{} |
resources.cpu |
CPU available to each replica. | quantity |
"" |
resources.memory |
Memory (RAM) available to each replica. | quantity |
"" |
resourcesPreset |
Default sizing preset used when resources is omitted. |
string |
t1.small |
size |
Persistent Volume Claim size available for application data. | quantity |
10Gi |
storageClass |
StorageClass used to store the data. | string |
"" |
version |
ClickHouse major.minor version to deploy. Applies to both the ClickHouse server and ClickHouse Keeper images. Downgrading to an older major is unsafe (ClickHouse cannot read data written by a newer server and Keeper snapshots are not backward compatible) — only increase this value. | string |
v24.9 |
Application-specific parameters
| Name | Description | Type | Value |
|---|---|---|---|
logStorageSize |
Size of Persistent Volume for logs. | quantity |
2Gi |
logTTL |
TTL (expiration time) for query_log and query_thread_log. |
int |
15 |
users |
Users configuration map. | map[string]object |
{} |
users[name].password |
Password for the user. | string |
"" |
users[name].readonly |
User is readonly (default: false). | bool |
false |
Backup parameters
| Name | Description | Type | Value |
|---|---|---|---|
backup |
Backup configuration. | object |
{} |
backup.enabled |
Enable backup integration. Materialises the chart-emitted <release>-backup-s3 Secret consumed by the Altinity backup strategy and, when schedule is non-empty, also renders the legacy chart-managed CronJob. |
bool |
false |
backup.useSystemBucket |
Opt-in: when true, the chart-emitted <release>-backup-s3 Secret is skipped and the clickhouse-backup sidecar reads bucket coordinates + S3 credentials from the platform-projected cozy-backups-creds Secret. S3_PATH is set to <namespace>/<release> for cross-tenant isolation. Use together with the platform cozy-default BackupClass — tenants do not need to fill any s3* field below. |
bool |
false |
backup.s3Region |
DEPRECATED. Per-tenant S3 configuration is being phased out in favour of the platform-managed cozy-default BackupClass. Optional now so tenants on useSystemBucket: true can omit it. |
string |
us-east-1 |
backup.s3Bucket |
DEPRECATED. Optional; see s3Region. |
string |
s3.example.org/clickhouse-backups |
backup.endpoint |
DEPRECATED. S3 endpoint URL for the legacy chart-emitted sidecar. | string |
"" |
backup.s3PathOverride |
DEPRECATED. Object-key prefix inside the legacy s3Bucket; the new platform flow scopes by namespace automatically. |
string |
"" |
backup.schedule |
Legacy. Cron schedule for the chart-emitted CronJob that runs the dump+restic backup. Empty (default) skips the legacy CronJob; recommended when a BackupClass + Plan from backups.cozystack.io already drives backup orchestration via the Altinity strategy. |
string |
"" |
backup.cleanupStrategy |
Legacy. Restic retention policy passed to the legacy CronJob (restic forget …). Unused by the Altinity strategy. |
string |
--keep-last=3 --keep-daily=3 --keep-within-weekly=1m |
backup.s3AccessKey |
DEPRECATED. Tenants no longer supply S3 keys; the platform-managed Bucket Secret is the source of truth. Optional now so useSystemBucket: true tenants can omit it. |
string |
<your-access-key> |
backup.s3SecretKey |
DEPRECATED. Optional; see s3AccessKey. |
string |
<your-secret-key> |
backup.resticPassword |
Legacy. Password for Restic backup encryption used by the legacy CronJob. Unused by the Altinity strategy. | string |
<password> |
backup.s3CredentialsSecret |
DEPRECATED. Pre-existing Secret reference for the legacy chart-emitted sidecar. The platform flow projects cozy-backups-creds instead. |
object |
{} |
backup.s3CredentialsSecret.name |
Name of the Secret in the application namespace. Empty means the chart materialises <release>-backup-s3 from the legacy s3* fields. |
string |
"" |
backup.s3CredentialsSecret.bucketKey |
Key in the Secret holding the bucket name. Defaults to bucketName. |
string |
"" |
backup.s3CredentialsSecret.endpointKey |
Key in the Secret holding the S3 endpoint URL. Defaults to endpoint. |
string |
"" |
backup.s3CredentialsSecret.regionKey |
Key in the Secret holding the S3 region. Defaults to region. |
string |
"" |
backup.s3CredentialsSecret.accessKeyIDKey |
Key in the Secret holding the access key ID. Defaults to accessKey. |
string |
"" |
backup.s3CredentialsSecret.secretAccessKeyKey |
Key in the Secret holding the secret access key. Defaults to secretKey. |
string |
"" |
backup.endpointCA |
CA bundle the sidecar trusts when the S3 endpoint's certificate is signed by a private CA (e.g. Cozystack's in-cluster SeaweedFS). Applies to both the per-tenant and the useSystemBucket flow, and to the clickhouse-backup sidecar only — the legacy schedule CronJob writes to S3 through restic and does not consume it, so a private-CA endpoint combined with schedule still fails TLS. Use the BackupClass flow for such an endpoint. |
object |
{} |
backup.endpointCA.name |
Name of the Secret in the application namespace. Empty (default) mounts nothing and leaves the sidecar on the system trust store only. | string |
"" |
backup.endpointCA.key |
Key inside the Secret holding the PEM CA bundle. Defaults to ca.crt. |
string |
ca.crt |
ClickHouse Keeper parameters
| Name | Description | Type | Value |
|---|---|---|---|
clickhouseKeeper |
ClickHouse Keeper configuration. | object |
{} |
clickhouseKeeper.enabled |
Deploy ClickHouse Keeper for cluster coordination. | bool |
true |
clickhouseKeeper.size |
Persistent Volume Claim size available for application data. | quantity |
1Gi |
clickhouseKeeper.resourcesPreset |
Default sizing preset. | string |
t1.micro |
clickhouseKeeper.replicas |
Number of Keeper replicas. | int |
3 |
Parameter examples and reference
resources and resourcesPreset
resources sets explicit CPU and memory configurations for each replica.
When left empty, the preset defined in resourcesPreset is applied.
resources:
cpu: 4000m
memory: 4Gi
resourcesPreset sets named CPU and memory configurations for each replica.
This setting is ignored if the corresponding resources value is set.
| Preset name | CPU | memory |
|---|---|---|
nano |
250m |
128Mi |
micro |
500m |
256Mi |
small |
1 |
512Mi |
medium |
1 |
1Gi |
large |
2 |
2Gi |
xlarge |
4 |
4Gi |
2xlarge |
8 |
8Gi |