From 2feaeb4a51480063039e922240c3fe883c22e05b Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 26 Aug 2026 16:54:15 +0200 Subject: [PATCH 01/73] docs: fix Markdown lint issues --- .markdownlint-cli2.jsonc | 3 + .markdownlint.jsonc | 25 +- .markdownlintignore | 2 +- AGENTS.md | 22 +- README.md | 30 +- archetypes/applications.md | 10 +- archetypes/guides.md | 6 +- content/api/howto.md | 94 +- content/api/v4.md | 106 +- .../2023/11-10-healthcheck-for-java.md | 4 +- content/changelog/2023/11-29-api-update.md | 2 +- .../12-13-cellar-migration-tool-update.md | 2 +- content/changelog/2023/12-15-sozu-0.15.18.md | 8 +- .../2024/01-10-documentation-changelog.md | 2 +- content/changelog/2024/01-11-redis-7.2.4.md | 8 +- content/changelog/2024/01-22-matomo-5.0.1.md | 1 + content/changelog/2024/01-24-ruby-3.3.0.md | 2 +- .../2024/01-25-clever-tools-3.1.0.md | 3 +- .../2024/02-07-clever-tools-3.2.0.md | 12 +- content/changelog/2024/02-08-sozu-0.15.19.md | 2 +- .../changelog/2024/02-12-new-grahds-region.md | 2 +- .../2024/02-16-clever-tools-3.4.0.md | 8 +- .../2024/02-22-postgresql-pgvector-support.md | 2 +- .../2024/02-26-healthcheck-for-everyone.md | 5 +- .../changelog/2024/02-26-mtl-iplb-update.md | 16 +- .../2024/02-27-images-update-part2.md | 12 +- .../2024/03-11-console-components-update.md | 2 +- content/changelog/2024/04-04-CVE-2024-3094.md | 10 +- .../2024/04-11-clever-tools-3.5.2.md | 14 +- .../04-15-new-logs-interface-public-beta.md | 4 +- .../2024/04-16-clever-tools-3.6.0.md | 2 +- .../2024/04-24-php-deprecate-warning.md | 2 +- content/changelog/2024/04-25-images-update.md | 22 +- .../changelog/2024/05-30-php-8.3-java-22.md | 28 +- content/changelog/2024/06-07-sozu-1.0.2.md | 4 +- .../2024/06-10-mongo-db-terraform.md | 2 +- .../2024/06-11-clever-tools-3.7.0.md | 2 +- .../changelog/2024/06-21-better-new-logs.md | 3 +- .../changelog/2024/06-28-new-ip-list-paris.md | 8 +- content/changelog/2024/07-01-matomo-5.1.0.md | 1 + .../2024/07-02-clever-tools-3.8.0.md | 3 +- .../changelog/2024/07-03-docker-terraform.md | 2 +- .../2024/07-04-apache-php-image-update.md | 9 +- .../2024/07-05-go-haskell-ruby-update.md | 14 +- .../2024/07-06-mysql-pgsql-update.md | 14 +- content/changelog/2024/07-10-CVE-2024-6387.md | 2 +- .../2024/07-17-keycloak-public-release.md | 2 +- .../changelog/2024/07-17-new-logs-default.md | 2 +- .../07-18-elastic-8.10.2-jenkins-2.452.3.md | 10 +- .../2024/07-18-github-action-review-apps.md | 2 +- .../changelog/2024/07-30-github-action-1.1.md | 2 +- .../2024/08-01-lagging-server-crate.md | 2 +- .../2024/08-09-python-3.12-update.md | 14 +- .../changelog/2024/08-30-deploy-url-mtl.md | 2 +- .../2024/09-12-clever-tools-3.8.3.md | 2 +- .../changelog/2024/09-12-js-client-9.0.0.md | 2 +- .../2024/10-01-python-image-changes.md | 4 +- .../changelog/2024/10-07-CVE-2024-47561.md | 2 +- content/changelog/2024/10-17-sozu-1.0.5.md | 2 +- .../2024/10-21-clever-tools-3.9.0.md | 3 +- .../2024/11-08-erlang-rust-update.md | 22 +- .../changelog/2024/11-08-mysql-mysql-8.4.0.md | 4 +- content/changelog/2024/11-09-java-update.md | 14 +- .../2024/11-21-eol-warnings-console.md | 1 + .../changelog/2024/11-27-clever-tools-3.10.md | 2 +- .../2024/12-12-python-3.13-update.md | 12 +- .../changelog/2024/12-18-clever-tools-3.11.md | 2 +- .../12-24-terraform-0.5-Keycloak-Metabase.md | 2 +- content/changelog/2025/01-06-sozu-1.0.6.md | 2 +- .../2025/01-15-node-22-lts-image-update.md | 2 +- content/changelog/2025/02-05-mysql-update.md | 4 +- .../changelog/2025/02-10-github-action-2.0.md | 2 +- .../changelog/2025/02-12-php-8.4-update.md | 12 +- .../2025/02-19-terraform-0.6-redis.md | 2 +- .../02-20-logs-interface-old-decomission.md | 2 +- content/changelog/2025/03-03-images-update.md | 38 +- .../changelog/2025/03-07-clever-tools-3.12.md | 6 +- content/changelog/2025/03-12-images-update.md | 28 +- .../changelog/2025/03-12-materia-kv-json.md | 1 + .../2025/03-18-images-update-ruby-unified.md | 24 +- content/changelog/2025/03-18-mysql-update.md | 6 +- .../changelog/2025/03-18-postgresql-16-17.md | 4 +- content/changelog/2025/03-19-paris-hds.md | 4 +- .../03-19-terraform-0.7-resources-update.md | 2 +- .../03-21-php-version-management-update.md | 6 +- .../2025/03-24-postgresql-11-12-eol.md | 9 +- .../changelog/2025/03-25-python-3.8-eol.md | 4 +- .../2025/03-27-postgresql-default.md | 4 +- .../2025/03-28-frankenphp-runtime.md | 6 +- content/changelog/2025/04-01-images-update.md | 14 +- .../2025/04-02-postgresql-replicas.md | 4 +- content/changelog/2025/04-03-images-update.md | 14 +- .../changelog/2025/04-04-postgresql-locale.md | 4 +- .../2025/04-10-mysql-8.4.4-update.md | 4 +- content/changelog/2025/04-16-images-update.md | 32 +- .../2025/04-24-keycloak-26.2.1-grafana.md | 1 + content/changelog/2025/05-06-images-update.md | 22 +- content/changelog/2025/05-07-node-24.md | 7 +- content/changelog/2025/05-13-images-update.md | 30 +- content/changelog/2025/05-16-images-update.md | 34 +- content/changelog/2025/05-16-terraform-0.8.md | 2 +- .../changelog/2025/05-20-pg-update-17.5.md | 13 +- content/changelog/2025/06-03-images-update.md | 40 +- .../2025/06-03-native-bun-support.md | 4 +- content/changelog/2025/06-03-terraform-0.9.md | 2 +- content/changelog/2025/06-04-otoroshi-17.3.md | 1 - .../2025/06-05-api-tokens-console-tips.md | 2 +- .../2025/06-05-mysql-8.0.42-8.4.5.md | 6 +- .../changelog/2025/06-10-clever-tools-3.13.md | 6 +- content/changelog/2025/06-17-images-update.md | 38 +- content/changelog/2025/07-01-images-update.md | 34 +- .../changelog/2025/07-02-terraform-0.10.md | 2 +- .../2025/07-04-linux-static-v-runtimes.md | 7 +- .../changelog/2025/07-08-terraform-0.11.md | 2 +- content/changelog/2025/07-09-images-update.md | 42 +- content/changelog/2025/07-16-otoroshi-17.4.md | 1 - content/changelog/2025/07-17-request-flow.md | 2 + .../changelog/2025/07-29-clever-tools-3.14.md | 2 +- content/changelog/2025/07-29-images-update.md | 76 +- content/changelog/2025/07-29-terraform-1.0.md | 2 +- content/changelog/2025/08-07-images-update.md | 28 +- content/changelog/2025/08-12-images-update.md | 28 +- .../changelog/2025/08-27-clever-tools-4.0.md | 3 +- .../2025/09-01-metabase-56-default.md | 1 + .../changelog/2025/09-01-pg-update-17.6.md | 13 +- content/changelog/2025/09-09-images-update.md | 60 +- content/changelog/2025/09-10-otoroshi-17.5.md | 1 - .../changelog/2025/09-12-terraform-1.1.0.md | 2 +- content/changelog/2025/09-16-images-update.md | 44 +- .../changelog/2025/09-17-clever-tools-4.1.md | 3 +- .../2025/09-18-mysql-8.0.43-8.4.6.md | 6 +- .../changelog/2025/09-24-terraform-1.2.0.md | 8 +- content/changelog/2025/09-30-images-update.md | 60 +- content/changelog/2025/10-07-images-update.md | 24 +- content/changelog/2025/10-07-redis-8.2.2.md | 1 + content/changelog/2025/10-08-postgresql-18.md | 4 +- content/changelog/2025/10-16-otoroshi-17.6.md | 1 - .../changelog/2025/10-21-clever-tools-4.2.md | 2 +- .../changelog/2025/10-22-clever-tools-4.3.md | 2 +- content/changelog/2025/10-23-images-update.md | 70 +- .../changelog/2025/10-27-terraform-1.3.0.md | 2 +- content/changelog/2025/10-31-otoroshi-17.7.md | 1 - content/changelog/2025/11-04-images-update.md | 46 +- .../changelog/2025/11-05-terraform-1.4.0.md | 2 +- content/changelog/2025/11-12-images-update.md | 56 +- .../changelog/2025/11-12-keycloak-26.4.4.md | 1 + .../changelog/2025/11-13-clever-tools-4.4.md | 2 +- .../changelog/2025/11-13-otoroshi-plugins.md | 2 + .../changelog/2025/11-17-terraform-1.5.0.md | 2 +- .../changelog/2025/11-19-terraform-1.6.0.md | 2 +- .../2025/12-01-metabase-57-default.md | 1 + .../changelog/2025/12-01-terraform-1.7.0.md | 2 +- content/changelog/2025/12-03-otoroshi-17.9.md | 1 + content/changelog/2025/12-15-pulsar-ga.md | 30 +- content/changelog/2025/12-17-images-update.md | 74 +- .../changelog/2025/12-19-terraform-1.8.0.md | 2 +- .../changelog/2026/01-14-clever-tools-4.5.md | 2 +- content/changelog/2026/01-15-images-update.md | 80 +- .../changelog/2026/01-23-terraform-1.9.0.md | 2 +- .../2026/01-27-metrics-retention-change.md | 4 +- content/changelog/2026/01-28-images-update.md | 57 +- content/changelog/2026/02-03-images-update.md | 48 +- content/changelog/2026/02-12-images-update.md | 39 +- .../changelog/2026/02-18-clever-tools-4.6.md | 2 +- content/changelog/2026/02-18-images-update.md | 34 +- content/changelog/2026/02-25-images-update.md | 26 +- .../changelog/2026/03-03-terraform-1.10.0.md | 2 +- .../changelog/2026/03-09-pg-update-18.3.md | 13 +- .../changelog/2026/03-11-clever-tools-4.7.md | 2 +- content/changelog/2026/03-19-drains-legacy.md | 3 +- .../2026/03-23-metabase-59-default.md | 1 + content/changelog/2026/03-25-images-update.md | 80 +- .../2026/03-31-mysql-8.0.45-8.4.8.md | 6 +- .../changelog/2026/04-02-terraform-1.11.0.md | 2 +- content/changelog/2026/04-07-images-update.md | 30 +- .../changelog/2026/04-09-clever-tools-4.8.md | 2 +- content/changelog/2026/04-21-images-update.md | 48 +- .../changelog/2026/04-23-otoroshi-17.15.md | 8 +- content/changelog/2026/04-28-images-update.md | 20 +- .../2026/05-11-materia-kv-graphql.md | 2 +- .../changelog/2026/05-21-pg-update-18.4.md | 13 +- content/changelog/2026/05-22-images-update.md | 88 +- .../changelog/2026/05-29-otoroshi-17.16.md | 12 +- content/changelog/2026/06-17-images-update.md | 66 +- .../changelog/2026/06-30-otoroshi-17.17.md | 8 +- content/changelog/2026/07-01-images-update.md | 28 +- content/changelog/2026/07-28-images-update.md | 71 +- .../2026/07-29-mysql-8.0.46-8.4.10.md | 6 +- content/changelog/2026/08-05-images-update.md | 50 +- content/changelog/2026/08-19-images-update.md | 50 +- content/doc/account/create-account.md | 4 +- content/doc/account/notifications.md | 26 +- content/doc/account/organisations.md | 22 +- content/doc/account/ssh-keys-management.md | 2 +- content/doc/addons/cellar.md | 102 +- content/doc/addons/config-provider.md | 20 +- content/doc/addons/elastic.md | 32 +- content/doc/addons/fs-bucket.md | 16 +- content/doc/addons/heptapod.md | 41 +- content/doc/addons/keycloak.md | 21 +- content/doc/addons/kms.md | 2 + content/doc/addons/materia-kv.md | 191 +-- content/doc/addons/materia-ts.md | 10 +- content/doc/addons/matomo.md | 2 +- content/doc/addons/metabase.md | 6 +- content/doc/addons/mysql.md | 1 + content/doc/addons/otoroshi.md | 11 +- content/doc/addons/postgresql.md | 126 +- content/doc/administrate/activity.md | 6 +- content/doc/administrate/clamav.md | 4 +- content/doc/administrate/domain-names.md | 95 +- content/doc/administrate/log-management.md | 14 +- content/doc/administrate/ssh-clever-tools.md | 15 +- content/doc/administrate/ssl.md | 16 +- content/doc/administrate/tcp-redirections.md | 2 +- content/doc/applications/docker.md | 3 +- content/doc/applications/dotnet.md | 6 +- content/doc/applications/frankenphp.md | 1 + content/doc/applications/golang.md | 22 +- content/doc/applications/haskell.md | 16 +- content/doc/applications/java/_index.md | 2 +- content/doc/applications/java/java-gradle.md | 2 +- content/doc/applications/java/java-jar.md | 2 +- content/doc/applications/java/java-maven.md | 16 +- content/doc/applications/java/java-war.md | 48 +- content/doc/applications/linux.md | 1 + content/doc/applications/meteor.md | 8 +- content/doc/applications/nodejs.md | 37 +- content/doc/applications/php/_index.md | 25 +- .../doc/applications/php/sessions-emails.md | 18 +- content/doc/applications/python/_index.md | 1 + content/doc/applications/python/servers.md | 40 +- content/doc/applications/python/uv.md | 12 +- content/doc/applications/rust.md | 21 +- .../applications/scala/play-framework-1.md | 24 +- .../applications/scala/play-framework-2.md | 12 +- content/doc/applications/static-apache.md | 3 + content/doc/applications/static.md | 2 + content/doc/applications/v.md | 1 + content/doc/best-practices/load-testing.md | 40 +- content/doc/best-practices/tips_and_tricks.md | 34 +- content/doc/billing/_index.md | 2 +- content/doc/billing/analytics-consumption.md | 8 +- content/doc/billing/payments-invoicing.md | 18 +- content/doc/billing/unified-invoices.md | 32 +- content/doc/ci-cd/custom-scripts.md | 4 +- content/doc/ci-cd/github.md | 4 +- content/doc/ci-cd/gitlab.md | 2 +- content/doc/cli/_index.md | 46 +- content/doc/cli/addons.md | 35 +- content/doc/cli/applications/_index.md | 26 +- content/doc/cli/applications/configuration.md | 34 +- .../cli/applications/deployment-lifecycle.md | 36 +- content/doc/cli/install/_index.md | 22 +- content/doc/cli/install/nexus-config.md | 42 +- content/doc/cli/kv-stores.md | 2 +- content/doc/cli/logs-drains.md | 10 +- content/doc/cli/network-groups.md | 36 +- content/doc/cli/notifications-webhooks.md | 18 +- content/doc/cli/operators.md | 21 +- content/doc/cli/profiles.md | 1 + content/doc/cli/services-depedencies.md | 14 +- content/doc/develop/env-variables.md | 92 +- content/doc/develop/network-groups.md | 13 +- content/doc/develop/oauth2-proxy.md | 12 +- content/doc/develop/request-flow.md | 30 +- content/doc/develop/tasks.md | 1 + content/doc/find-help/faq.md | 35 +- content/doc/find-help/support.md | 4 +- content/doc/find-help/troubleshooting.md | 8 +- content/doc/functions/_index.md | 4 +- content/doc/kubernetes/_index.md | 74 +- content/doc/kubernetes/operator.md | 36 +- content/doc/marketplace.md | 96 +- content/doc/metrics/_index.md | 128 +- content/doc/metrics/new-relic.md | 14 +- content/doc/metrics/warp10.md | 3 +- content/doc/quickstart.md | 50 +- content/doc/reference/cli.md | 1379 +++++++++++------ content/doc/reference/products-support.md | 4 +- .../reference-environment-variables.md | 826 +++++----- content/guides/astro.md | 5 +- content/guides/docs.md | 16 +- content/guides/docusaurus.md | 2 +- content/guides/ekg-statsd-haskell-metrics.md | 8 +- content/guides/eleventy.md | 2 +- content/guides/fluentd.md | 22 +- content/guides/ghost.md | 2 +- content/guides/go-echoip.md | 26 +- content/guides/hexo.md | 3 +- content/guides/hono.md | 4 +- content/guides/hugo-static-s3.md | 2 +- content/guides/hugo.md | 2 +- content/guides/kibana.md | 14 +- content/guides/lume-deno.md | 3 +- content/guides/mdbook.md | 2 +- content/guides/mkdocs.md | 3 +- content/guides/moodle.md | 3 +- content/guides/node-js-mongo-db.md | 2 +- content/guides/nuxt.md | 4 +- content/guides/outline.md | 18 +- content/guides/pgpool.md | 2 +- content/guides/ruby-rack-app-tutorial.md | 8 +- content/guides/ruby-rack.md | 8 +- content/guides/sftpgo.md | 20 +- content/guides/sveltekit.md | 2 +- content/guides/tutorial-drupal.md | 18 +- content/guides/tutorial-laravel.md | 2 +- content/guides/tutorial-symfony.md | 6 +- content/guides/tutorial-wordpress.md | 2 +- content/postmortem/2024-08-02.md | 78 +- content/postmortem/2025-03-03.md | 220 +-- content/postmortem/2025-10-09.md | 86 +- content/postmortem/2026-03-19.md | 32 +- drafts/community.md | 6 +- shared/kv-explorer.md | 2 +- shared/redirectionio.md | 10 +- shared/ruby.md | 42 +- shared/warp10-concepts.md | 4 +- shared/warp10-content.md | 30 +- update-cli-reference.sh | 2 + 321 files changed, 4243 insertions(+), 3643 deletions(-) create mode 100644 .markdownlint-cli2.jsonc diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 000000000..3fe7bdc40 --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,3 @@ +{ + "gitignore": true +} diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc index 22de7da50..25a9920da 100644 --- a/.markdownlint.jsonc +++ b/.markdownlint.jsonc @@ -1,16 +1,23 @@ { - "MD041": false, - "MD013": false, - "MD051": false, - "MD029": false, - // MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md033.md - "MD033": { + "MD004": { + "style": "dash" + }, + "MD013": false, + "MD029": false, + // MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md033.md + "MD033": { // Allowed elements "allowed_elements": [ "br", - "cc-smart-container", - "cc-pricing-product", "cite" ] + }, + "MD041": false, + "MD051": false, + "MD055": { + "style": "leading_and_trailing" + }, + "MD060": { + "style": "aligned" } -} \ No newline at end of file +} diff --git a/.markdownlintignore b/.markdownlintignore index ab4b6d49a..a6cb7ebc9 100644 --- a/.markdownlintignore +++ b/.markdownlintignore @@ -1,2 +1,2 @@ -/public/* +/public/** /resources diff --git a/AGENTS.md b/AGENTS.md index d25a336c2..1a2b8ee7b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,13 +5,15 @@ This file provides repository-wide guidance to coding agents working on Clever C ## Common Development Commands ### Hugo Site Development + - **Install development dependencies**: `mise install` - Installs the tools declared in `mise.toml` -- **Local development**: `hugo server` - Serves site at http://localhost:1313 with live reload +- **Local development**: `hugo server` - Serves site at with live reload - **Build for production**: `hugo` - Outputs to `public/developers/` - **Preview drafts**: `hugo server --buildDrafts` - Include draft content in local preview - **Update CLI reference**: `./update-cli-reference.sh` - Fetches latest clever-tools documentation ### Content Generation + - **New guide**: `hugo new content guides/.md` - **New documentation**: `hugo new content/doc/administrate/.md` - **New application runtime**: `hugo new content --kind applications doc/applications/.md` @@ -19,6 +21,7 @@ This file provides repository-wide guidance to coding agents working on Clever C ## Project Architecture ### Content Organization + This is a Hugo-based documentation site using the Hextra theme with the following structure: - **`/content/`** - All documentation content: @@ -36,7 +39,9 @@ This is a Hugo-based documentation site using the Hextra theme with the followin - **`/layouts/`** - Hugo templates and shortcodes for content rendering ### Content Types and Front Matter + Content uses Hugo front matter with fields such as: + - `type: docs` - Content layout type - `weight` - Sidebar ordering (integer) - `linkTitle` - Short title for sidebar navigation @@ -47,11 +52,13 @@ Content uses Hugo front matter with fields such as: - `excludeSearch: true` - Excludes from search index (recommended for changelog) For changelog entries, also include: + - `date: YYYY-MM-DD` - Publication date - `tags` - Array of product tags (lowercase) - `authors` - Array with `name`, `link`, `image` fields ### Shared Content System + - Include shared content: `{{% content "filename" %}}` - Include shared content with shortcodes: `{{% content-raw "filename" %}}` - Shared files should not contain headings (breaks ToC generation) @@ -59,6 +66,7 @@ For changelog entries, also include: ## Quality Standards ### Content Quality Requirements + - Use second person ("you") addressing readers directly - Write in active voice, avoid passive constructions - Use `organisation` and `organisations`, rather than `organization` and `organizations`; this isn't a general British-spelling requirement @@ -67,12 +75,14 @@ For changelog entries, also include: - Explain prerequisites and non-obvious behaviour, while keeping the main task path concise ### Prohibited Elements + - First-person pronouns: I, me, my, we, us, our, let's - Placeholder phrases: "please note", "at this time", "it should be noted" - Overconfident claims: "simply", "just", "easily", "quickly", "obviously" - Time-dependent promises: "soon", "in the future", "coming next month" ### Markdown and Editorial Standards + - **Markdown linting**: Run `markdownlint-cli2 "**/*.md"` with config in `.markdownlint.jsonc` - **Editorial checks**: Run Vale with `vale ` for style and terminology - **Build verification**: Always test with `hugo` before committing @@ -80,7 +90,9 @@ For changelog entries, also include: - **Paragraphs**: Aim for 3-6 lines for optimal readability ### Callouts + - Prefer GitHub-style callouts with a concise title on the marker line, as supported by the theme: + ```markdown > [!NOTE] Current behaviour > This information helps readers understand the current behaviour @@ -88,10 +100,12 @@ For changelog entries, also include: > [!WARNING] Back up your data > Back up your application database before upgrading ``` + - Use the Hugo `{{< callout >}}` shortcode only when GitHub-style syntax can't provide the required rendering or behaviour - Limit callouts to one or two per page ### Commit Messages + - For content updates, use `section(page): commit message`, for example: - `addons(postgresql): document pg_partman support` - `applications(nodejs): clarify pnpm configuration` @@ -106,6 +120,7 @@ For changelog entries, also include: - Start the subject with a lowercase imperative verb ### Code and Technical Examples + - Always provide complete, runnable code examples - Keep commands literally copyable: don't put shell-invalid placeholders or bracketed optional arguments in executable code blocks - Show optional flags in separate examples or explain where to add them @@ -145,11 +160,13 @@ The site is configured for Clever Cloud hosting with the `static` runtime and th `CC_DISABLE_MISE` prevents Clever Cloud from installing the local development dependencies because the platform manages the deployment tools directly. ## Data Management + Runtime versions and software compatibility information is maintained in `/data/runtime_versions.yml` and should be kept current with platform capabilities. The site generates various output formats including standard HTML and a special LLMS output format at `/llms.txt` for AI consumption. ## Hugo Shortcodes and Features ### Content Shortcodes + - `{{% content "filename" %}}` - Include shared content from `/shared/` directory - `{{% content-raw "filename" %}}` - Include shared content containing shortcodes - `{{% steps %}}` - Create step-by-step instructions for guides @@ -159,12 +176,14 @@ Runtime versions and software compatibility information is maintained in `/data/ - `{{< hextra/hero-subtitle >}}` - Add engaging subtitles in guides ### Hugo Content Types + - **Documentation pages**: Use `type: docs` in front matter - **Guides**: Use step-by-step structure, hero subtitles, and cards when they improve the guide - **Changelog entries**: Include date, tags, and author information - **API documentation**: Structured reference content ### Hextra Theme Features + - **Search**: Full-text search using FlexSearch - **Dark mode**: Automatic theme switching - **Responsive navigation**: Sidebar and mobile-friendly menus @@ -172,4 +191,5 @@ Runtime versions and software compatibility information is maintained in `/data/ - **Syntax highlighting**: Code block highlighting with copy functionality ## File Standards + All text files must end with a newline. diff --git a/README.md b/README.md index e9f06f113..1f5f26cf5 100644 --- a/README.md +++ b/README.md @@ -95,20 +95,20 @@ Store each entry under its publication year and name it with the `MM-DD-title.md Hugo front matter stores page metadata. This project uses the following fields: -| Field | Status | Purpose | -| --- | --- | --- | -| `aliases` | Optional | Redirects paths that existed previously. Omit the `/developers` base path, for example `/doc/docker`, and don't add an alias to a new page | -| `authors` | Changelog | Lists contributors with `name`, `link` and `image` fields | -| `date` | Changelog | Sets the publication date or date-time in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format | -| `description` | Recommended | Provides the page's description for search results and search engines | -| `draft` | Optional | Excludes unfinished content from regular builds when set to `true`. Remove the field before publication | -| `excludeSearch` | Optional | Excludes the page from the search index when set to `true`. Set it for changelog entries | -| `keywords` | Optional | Lists search keywords | -| `linkTitle` | Optional | Sets a short sidebar label, usually the product name, and defaults to `title` | -| `tags` | Changelog | Lists lowercase product tags with consistent spelling | -| `title` | Required | Sets the page heading and search-oriented title. Avoid repeating the Clever Cloud name because the generated HTML title already includes it | -| `type` | Optional | Selects a content layout and uses `docs` outside the changelog | -| `weight` | Optional | Orders pages in the sidebar and defaults to `0` | +| Field | Status | Purpose | +| --------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `aliases` | Optional | Redirects paths that existed previously. Omit the `/developers` base path, for example `/doc/docker`, and don't add an alias to a new page | +| `authors` | Changelog | Lists contributors with `name`, `link` and `image` fields | +| `date` | Changelog | Sets the publication date or date-time in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format | +| `description` | Recommended | Provides the page's description for search results and search engines | +| `draft` | Optional | Excludes unfinished content from regular builds when set to `true`. Remove the field before publication | +| `excludeSearch` | Optional | Excludes the page from the search index when set to `true`. Set it for changelog entries | +| `keywords` | Optional | Lists search keywords | +| `linkTitle` | Optional | Sets a short sidebar label, usually the product name, and defaults to `title` | +| `tags` | Changelog | Lists lowercase product tags with consistent spelling | +| `title` | Required | Sets the page heading and search-oriented title. Avoid repeating the Clever Cloud name because the generated HTML title already includes it | +| `type` | Optional | Selects a content layout and uses `docs` outside the changelog | +| `weight` | Optional | Orders pages in the sidebar and defaults to `0` | A changelog entry can use the following front matter: @@ -166,7 +166,7 @@ Run a production build before submitting a change: hugo ``` -The repository provides [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) configuration in [`.markdownlint.jsonc`](./.markdownlint.jsonc) and exclusions in [`.markdownlintignore`](./.markdownlintignore). Run the version installed by Mise: +The repository provides [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) rules in [`.markdownlint.jsonc`](./.markdownlint.jsonc), CLI configuration in [`.markdownlint-cli2.jsonc`](./.markdownlint-cli2.jsonc) and editor exclusions in [`.markdownlintignore`](./.markdownlintignore). Run the version installed by Mise: ```bash markdownlint-cli2 "**/*.md" diff --git a/archetypes/applications.md b/archetypes/applications.md index edaf1e36e..75fc50b4e 100644 --- a/archetypes/applications.md +++ b/archetypes/applications.md @@ -16,8 +16,9 @@ To create a new XXX application, use the [Clever Cloud Console](https://console. ```bash clever create --type XXX ``` -* [Learn more about Clever Tools](/doc/cli/) -* [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) + +- [Learn more about Clever Tools](/doc/cli/) +- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) ## Configure your XXX application @@ -25,7 +26,7 @@ clever create --type XXX XXX runtime only requires a working application listening on `0.0.0.0:8080`. -* [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) +- [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) ### Build phase @@ -35,11 +36,8 @@ During the build phase, ### XXX version - - ## Clever Tasks - ```bash clever create --type XXX --task "XXX" clever deploy # or clever restart if there is no code change diff --git a/archetypes/guides.md b/archetypes/guides.md index 9cc1ecef5..7012332b6 100644 --- a/archetypes/guides.md +++ b/archetypes/guides.md @@ -18,9 +18,9 @@ draft: true {{% steps %}} -### +### First step -### +### Second step {{% /steps %}} @@ -28,4 +28,4 @@ draft: true {{< cards >}} {{< card link="/developers/guides/" title="Card title" subtitle="Card subtiltle" icon="adjustments-horizontal" >}} -{{< /cards >}} \ No newline at end of file +{{< /cards >}} diff --git a/content/api/howto.md b/content/api/howto.md index 99c6b544f..3c3ca229b 100644 --- a/content/api/howto.md +++ b/content/api/howto.md @@ -24,9 +24,9 @@ The [Clever Cloud Console](https://console.clever-cloud.com) and [Clever Tools]( Clever Cloud's REST API offers two authentication mechanisms to meet different integration needs: -* **API tokens** provide a straightforward way to authenticate requests on behalf of a specific user. These tokens operate similarly to passwords and should be handled with appropriate security measures. API tokens are ideal for personal scripts, CLI tools, and scenarios where you're accessing your own resources. Use them to request the API Bridge: https://api-bridge.clever-cloud.com +- **API tokens** provide a straightforward way to authenticate requests on behalf of a specific user. These tokens operate similarly to passwords and should be handled with appropriate security measures. API tokens are ideal for personal scripts, CLI tools, and scenarios where you're accessing your own resources. Use them to request the API Bridge: -* **OAuth 1** is designed for third-party applications that need to access Clever Cloud resources on behalf of their users. This authentication flow allows applications to request permissions from users without requiring direct access to their credentials. OAuth 1 is recommended for public applications, services that integrate with multiple user accounts, or any scenario where user delegation is required. +- **OAuth 1** is designed for third-party applications that need to access Clever Cloud resources on behalf of their users. This authentication flow allows applications to request permissions from users without requiring direct access to their credentials. OAuth 1 is recommended for public applications, services that integrate with multiple user accounts, or any scenario where user delegation is required. Choose the authentication method that best aligns with your specific integration requirements and security considerations. @@ -72,6 +72,7 @@ clever curl https://api.clever-cloud.com/v4/billing/organisations/ [!TIP] > For quick testing, you can use `PLAINTEXT` with curl (percent-encode your consumer secret if it contains non-alphanumeric characters): +> > ```bash > curl -X POST "https://api.clever-cloud.com/v2/oauth/request_token_query?\ > oauth_consumer_key=&oauth_signature_method=PLAINTEXT&\ @@ -180,48 +182,48 @@ https://api.clever-cloud.com/v2/oauth/authorize?oauth_token= The user logs into Clever Cloud (if not already) and is presented with a permissions form. Available permissions are: -| Permission | Description | -|---|---| -| `access_organisations` | Access organisations | -| `access_organisations_bills` | Access organisations' bills | +| Permission | Description | +| --------------------------------------------- | -------------------------------------------- | +| `access_organisations` | Access organisations | +| `access_organisations_bills` | Access organisations' bills | | `access_organisations_consumption_statistics` | Access organisations' consumption statistics | -| `access_organisations_credit_count` | Access organisations' credit count | -| `access_personal_information` | Access personal information | -| `manage_organisations` | Manage organisations | -| `manage_organisations_applications` | Manage organisations' applications | -| `manage_organisations_members` | Manage organisations' members | -| `manage_organisations_services` | Manage organisations' add-ons | -| `manage_personal_information` | Manage personal information | -| `manage_ssh_keys` | Manage SSH keys | +| `access_organisations_credit_count` | Access organisations' credit count | +| `access_personal_information` | Access personal information | +| `manage_organisations` | Manage organisations | +| `manage_organisations_applications` | Manage organisations' applications | +| `manage_organisations_members` | Manage organisations' members | +| `manage_organisations_services` | Manage organisations' add-ons | +| `manage_personal_information` | Manage personal information | +| `manage_ssh_keys` | Manage SSH keys | You can retrieve this list programmatically with `GET https://api.clever-cloud.com/v2/oauth/rights`. Once the user approves, the browser is redirected to your `oauth_callback` URL with the following **query string** parameters: -| Parameter | Description | -|---|---| -| `oauth_token` | The request token (must match the one from step 1) | -| `oauth_verifier` | Verification code to exchange for an access token | +| Parameter | Description | +| ---------------- | -------------------------------------------------- | +| `oauth_token` | The request token (must match the one from step 1) | +| `oauth_verifier` | Verification code to exchange for an access token | ##### Exchange for an access token Exchange the request token and verifier for an access token. As with step 1, parameters can be sent as query string or form body: -* `POST https://api.clever-cloud.com/v2/oauth/access_token_query` — parameters as query string -* `POST https://api.clever-cloud.com/v2/oauth/access_token` — parameters as `application/x-www-form-urlencoded` body +- `POST https://api.clever-cloud.com/v2/oauth/access_token_query` — parameters as query string +- `POST https://api.clever-cloud.com/v2/oauth/access_token` — parameters as `application/x-www-form-urlencoded` body **Required parameters:** -| Parameter | Description | -|---|---| -| `oauth_consumer_key` | Your consumer key | -| `oauth_signature_method` | Same method as step 1 | -| `oauth_signature` | Request signature (signed with the request token secret from step 1) | -| `oauth_timestamp` | Current Unix timestamp (seconds) | -| `oauth_nonce` | Unique random string | -| `oauth_version` | `1.0` | -| `oauth_token` | The request token from step 1 | -| `oauth_verifier` | The verifier from the callback redirect | +| Parameter | Description | +| ------------------------ | -------------------------------------------------------------------- | +| `oauth_consumer_key` | Your consumer key | +| `oauth_signature_method` | Same method as step 1 | +| `oauth_signature` | Request signature (signed with the request token secret from step 1) | +| `oauth_timestamp` | Current Unix timestamp (seconds) | +| `oauth_nonce` | Unique random string | +| `oauth_version` | `1.0` | +| `oauth_token` | The request token from step 1 | +| `oauth_verifier` | The verifier from the callback redirect | **Response** (`application/x-www-form-urlencoded`) @@ -316,9 +318,9 @@ function buildBaseString(method, url, params) { The three components are: -* The HTTP method in uppercase (`GET`, `POST`, etc.) -* The base URL (without query string), percent-encoded -* All request parameters (OAuth parameters excluding `oauth_signature`, plus any query string or form body parameters), sorted alphabetically by key — then by value in case of duplicates — formatted as `key=value` pairs joined by `&`, then percent-encoded as a single string +- The HTTP method in uppercase (`GET`, `POST`, etc.) +- The base URL (without query string), percent-encoded +- All request parameters (OAuth parameters excluding `oauth_signature`, plus any query string or form body parameters), sorted alphabetically by key — then by value in case of duplicates — formatted as `key=value` pairs joined by `&`, then percent-encoded as a single string **3.** Define `sign` — it computes an HMAC with the chosen algorithm and returns the base64-encoded result: diff --git a/content/api/v4.md b/content/api/v4.md index 93f659c60..22ff8dc6a 100644 --- a/content/api/v4.md +++ b/content/api/v4.md @@ -13,7 +13,8 @@ keywords: --- Clever Cloud provides a public REST API used by its own services and customers, known as [`/v2`](/api/v2/). As our platform evolves, we're progressively moving to `/v4` endpoints, adding functionalities, with a more modern approach: -``` + +```text https://api.clever-cloud.com/v4/ ``` @@ -24,6 +25,7 @@ Each query response contains a `Sozu-Id`. If you need help from our support team {{< /callout>}} ## Billing + - `/v4/billing/organisations/{orgid}/invoices` - `/v4/billing/organisations/{orgid}/invoices/{invoiceid}` - `/v4/billing/organisations/{orgid}/invoices/{invoiceid}.html` @@ -31,13 +33,15 @@ Each query response contains a `Sozu-Id`. If you need help from our support team - Type: `GET` You can use optional parameters to filter it: -| Parameter | Type | Comment | -| :--- | :--- | :--- | -| `limit` | `int` | | -| `since` | `string` | ISO 8601 formatted | -| `until` | `string` | ISO 8601 formatted | + +| Parameter | Type | Comment | +| :-------- | :------- | :----------------- | +| `limit` | `int` | | +| `since` | `string` | ISO 8601 formatted | +| `until` | `string` | ISO 8601 formatted | Example response, for each invoice: + ```bash [ { @@ -87,11 +91,13 @@ Example response, for each invoice: ``` ## Deployments + - `/v4/orchestration/organisations/{ownerId}/applications/{applicationId}/deployments` - `/v4/orchestration/organisations/{ownerId}/applications/{applicationId}/deployments/{deploymentId}` - Type: `GET` Example response, for each deployment: + ```bash [ { @@ -134,22 +140,25 @@ Example response, for each deployment: ``` ## Instances + - `/v4/orchestration/organisations/{ownerId}/applications/{applicationId}/instances` - Type: `GET` You can use optional parameters to filter it: -| Parameter | Type | Comment | -| :--- | :--- | :--- | -| `deploymentId` | `string` | | -| `limit` | `int` | | -| `excludeDeleted` | `boolean`| | -| `since` | `string` | ISO 8601 formatted | -| `until` | `string` | ISO 8601 formatted | -| `order` | `string` | `ASC` or `DESC` | -| `includeState` | `string` | case sensitive, repeated | -| `excludeState` | `string` | case sensitive, repeated | + +| Parameter | Type | Comment | +| :--------------- | :-------- | :----------------------- | +| `deploymentId` | `string` | | +| `limit` | `int` | | +| `excludeDeleted` | `boolean` | | +| `since` | `string` | ISO 8601 formatted | +| `until` | `string` | ISO 8601 formatted | +| `order` | `string` | `ASC` or `DESC` | +| `includeState` | `string` | case sensitive, repeated | +| `excludeState` | `string` | case sensitive, repeated | Example response, for each instance: + ```bash [ { @@ -174,10 +183,12 @@ Example response, for each instance: ``` ## Load Balancers + - `/v4/load-balancers/organisations/{ownerId}/applications/{applicationId}/load-balancers/default` - Type: `GET` Example response: + ```bash [ { @@ -202,14 +213,14 @@ Example response: Answers with logs in a SSE (Server-Sent Events) stream. You can use optional parameters to filter it: | Parameter | Type | Comment | -| :--- | :--- | :--- | +| :-------------------------- | :------- | :----------------------------------------------------------------------------- | | `deploymentId` | `string` | | | `instanceId` | `string` | | | `since` | `string` | ISO 8601 formatted | | `until` | `string` | ISO 8601 formatted | | `field` | `string` | Allow to get only asked fields, repeated | | `filter` | `string` | Case insensitive `contains` type search | -| `limit` | `int64 ` | Minimum: `1` | +| `limit` | `int64` | Minimum: `1` | | `service` | `string` | systemd service name, repeated (default: `bas` and `bas-deploy`, can be `all`) | | `throttleElements` | `int` | Maximum elements read per `throttlePerInMilliseconds`, default `100` | | `throttlePerInMilliseconds` | `long` | Default `300` | @@ -232,27 +243,27 @@ Answers with logs in a SSE (Server-Sent Events) stream. You can use optional par The `recipient.type` discriminates the payload shape. Allowed values and their fields: -| `type` | Required (besides `type` and `url`) | Optional | -| :--- | :--- | :--- | -| `DATADOG` | — | — | -| `ELASTICSEARCH` | `index` | `username`, `password`, `tlsVerification` (`DEFAULT` or `TRUSTFUL`) | -| `NEWRELIC` | `apiKey` | — | -| `OVH_TCP` | — | `token`, `rfc5424StructuredDataParameters` | -| `RAW_HTTP` | — | `username`, `password` | -| `SYSLOG_TCP` | — | `rfc5424StructuredDataParameters` | -| `SYSLOG_UDP` | — | `rfc5424StructuredDataParameters` | +| `type` | Required (besides `type` and `url`) | Optional | +| :-------------- | :---------------------------------- | :------------------------------------------------------------------ | +| `DATADOG` | — | — | +| `ELASTICSEARCH` | `index` | `username`, `password`, `tlsVerification` (`DEFAULT` or `TRUSTFUL`) | +| `NEWRELIC` | `apiKey` | — | +| `OVH_TCP` | — | `token`, `rfc5424StructuredDataParameters` | +| `RAW_HTTP` | — | `username`, `password` | +| `SYSLOG_TCP` | — | `rfc5424StructuredDataParameters` | +| `SYSLOG_UDP` | — | `rfc5424StructuredDataParameters` | Field reference: -| Field | Type | Comment | -| :--- | :--- | :--- | -| `username` | `string` | Basic Auth username (`ELASTICSEARCH`, `RAW_HTTP`) | -| `password` | `string` | Basic Auth password (`ELASTICSEARCH`, `RAW_HTTP`) | -| `index` | `string` | Elasticsearch index name | -| `tlsVerification` | `string` | Elasticsearch TLS mode, `DEFAULT` (verify) or `TRUSTFUL` (skip verification) | -| `apiKey` | `string` | New Relic API key | -| `token` | `string` | OVHcloud Logs Data Platform token | -| `rfc5424StructuredDataParameters` | `string` | RFC 5424 structured data, e.g. `X-OVH-TOKEN="…"` | +| Field | Type | Comment | +| :-------------------------------- | :------- | :--------------------------------------------------------------------------- | +| `username` | `string` | Basic Auth username (`ELASTICSEARCH`, `RAW_HTTP`) | +| `password` | `string` | Basic Auth password (`ELASTICSEARCH`, `RAW_HTTP`) | +| `index` | `string` | Elasticsearch index name | +| `tlsVerification` | `string` | Elasticsearch TLS mode, `DEFAULT` (verify) or `TRUSTFUL` (skip verification) | +| `apiKey` | `string` | New Relic API key | +| `token` | `string` | OVHcloud Logs Data Platform token | +| `rfc5424StructuredDataParameters` | `string` | RFC 5424 structured data, e.g. `X-OVH-TOKEN="…"` | ### List logs drains @@ -280,12 +291,14 @@ Optional query parameters: `status`, `executionStatus`, `executionStatusNotIn`. - Type: `PATCH` — restarts log forwarding from the latest position. ## Operators + A Clever Cloud Operator deploys and manage resources for a given service. Available operators are: `keycloak`, `matomo`, `metabase`, `otoroshi`. - `/v4/addon-providers/addon-{operator_name}/addons/{operator_id}` - Type: `GET` Example response (Otoroshi — the richest payload): + ```json { "resourceId": "otoroshi_", @@ -328,7 +341,7 @@ All operators always return: `resourceId`, `addonId`, `name`, `ownerId`, `plan`, Other fields depend on the operator (`✓` = always returned, `—` = not returned, `?` = returned when set): | Field | `otoroshi` | `keycloak` | `matomo` | `metabase` | -| :--- | :---: | :---: | :---: | :---: | +| :---------------------- | :--------: | :--------: | :------: | :--------: | | `javaVersion` | ✓ | ✓ | — | ✓ | | `phpVersion` | — | — | ✓ | — | | `initialCredentials` | ✓ | ✓ | — | — | @@ -374,7 +387,9 @@ Available for `keycloak`, `metabase` and `otoroshi`. - Response: `application/yaml` — the full `otoroshictl`-compatible configuration of the instance. ### Network Groups + You can add the deployed service main application in a [Network Group](/doc/develop/network-groups/) to activate some enhanced features: + - `keycloak`: [Secured Multi Instances feature](/doc/addons/keycloak/#secured-multi-instances) - `otoroshi`: once in a Network Group, an Otoroshi instance can be used in front of Clever Cloud applications @@ -383,6 +398,7 @@ You can add the deployed service main application in a [Network Group](/doc/deve - Response code: `202` Response contains the full operator object with `networkGroup` feature enabled: + ```bash "features": { "networkGroup": { @@ -403,18 +419,20 @@ If no Network Group is found, the `networkGroup` feature value is `null`: ``` ## Products zones + - `/v4/products/zones` - `/v4/products/zones/{name}` - Type: `GET` You can use optional query parameters to filter the results: -| Parameter | Type | Comment | -| :--- | :--- | :--- | +| Parameter | Type | Comment | +| :-------- | :------- | :----------------------------------------------- | | `tag` | `string` | Filter zones on tags (e.g. `infra:clever-cloud`) | -| `ownerId` | `string` | Restrict to zones the given owner has access to | +| `ownerId` | `string` | Restrict to zones the given owner has access to | Example response, for each zone: + ```bash [ { @@ -434,12 +452,14 @@ Example response, for each zone: ``` ## Pulsar policies + - `/v4/addon-providers/addon-pulsar/addons/{addon-id}/storage-policies` - Type: `GET`/`PATCH` Define or get offload/retention policies of a [Pulsar add-on](/doc/addons/pulsar). Retention is how long messages are kept in the topic. Offload is how long messages are kept in the hot storage (NVMe SSD) before being moved to Cellar object storage (S3 compatible, HDD). Example query/response: + ```json { "retentionPolicies": { @@ -453,9 +473,9 @@ Example query/response: } ``` -| Field | Type | Comment | -| :--- | :--- | :--- | -| `sizeInBytes` | `int64` | Size threshold in bytes. Optional. A negative value means no limit. | +| Field | Type | Comment | +| :------------------ | :------ | :------------------------------------------------------------------------ | +| `sizeInBytes` | `int64` | Size threshold in bytes. Optional. A negative value means no limit. | | `durationInMinutes` | `int64` | Duration threshold in minutes. Optional. A negative value means no limit. | When both fields are omitted (or `null`), retention is infinite and offload is disabled. diff --git a/content/changelog/2023/11-10-healthcheck-for-java.md b/content/changelog/2023/11-10-healthcheck-for-java.md index 05eb39090..5b572a636 100644 --- a/content/changelog/2023/11-10-healthcheck-for-java.md +++ b/content/changelog/2023/11-10-healthcheck-for-java.md @@ -16,8 +16,8 @@ excludeSearch: true You can now define the paths that the orchestrator will call to validate a deployment for Java applications through one or multiple `CC_HEALTH_CHECK_PATH` environment variables. It works as follows: -* If the application responds on this specified path, and the response code is between `200` and `300`, the orchestrator considers that the deployment has been validated. -* If it responds with another error code outside this interval, the application is considered to have failed its deployment. +- If the application responds on this specified path, and the response code is between `200` and `300`, the orchestrator considers that the deployment has been validated. +- If it responds with another error code outside this interval, the application is considered to have failed its deployment. Currently, the orchestrator only checks whether the application is listening to TCP port `8080`. It does not always mean that the application has started correctly. diff --git a/content/changelog/2023/11-29-api-update.md b/content/changelog/2023/11-29-api-update.md index db764ad14..edf200d28 100644 --- a/content/changelog/2023/11-29-api-update.md +++ b/content/changelog/2023/11-29-api-update.md @@ -18,7 +18,7 @@ excludeSearch: true --- For years, you can deploy applications on Clever Cloud as a `Task` with the API or more recently the `CC_TASK=true` environment variable. As this feature will be widely available and used, the API has been updated to return such a state in the `instance.lifetime` object: -```json{filename="GET https://api.clever-cloud.com/v2/self/applications/",linenos=table,hl_lines=[17]} +```json {filename="GET https://api.clever-cloud.com/v2/self/applications/",linenos=table,hl_lines=[17]} { "id": "string", "name": "string", diff --git a/content/changelog/2023/12-13-cellar-migration-tool-update.md b/content/changelog/2023/12-13-cellar-migration-tool-update.md index 34880b757..aa178ba31 100644 --- a/content/changelog/2023/12-13-cellar-migration-tool-update.md +++ b/content/changelog/2023/12-13-cellar-migration-tool-update.md @@ -16,4 +16,4 @@ excludeSearch: true If you want to import your object storage data on Clever Cloud, you can use our open source [Cellar migration tool](https://github.com/CleverCloud/cellar-migration/releases/tag/v2.1.0), written in Rust. Its new release adds support for keep-alive when used from S3 clients and prevents panic if a network error occurs. - - Check this project [on GitHub](https://github.com/CleverCloud/cellar-migration) {{< icon "github" >}} +- Check this project [on GitHub](https://github.com/CleverCloud/cellar-migration) {{< icon "github" >}} diff --git a/content/changelog/2023/12-15-sozu-0.15.18.md b/content/changelog/2023/12-15-sozu-0.15.18.md index 3053f6ab9..01ceeff8f 100644 --- a/content/changelog/2023/12-15-sozu-0.15.18.md +++ b/content/changelog/2023/12-15-sozu-0.15.18.md @@ -15,7 +15,7 @@ excludeSearch: true Our open source reverse proxy, Sōzu, is now deployed in its version 0.15.18. It gives performance enhancements and: -* Fix 502 following a 304 response with a body that does not respect RFCs -* Fix of a panic when upgrading from HTTP to WS or from HTTPs to WSs -* Fix encryption issues when reusing TLS sessions (bump of Rustls) -* Added a `--json` flag to all commands +- Fix 502 following a 304 response with a body that does not respect RFCs +- Fix of a panic when upgrading from HTTP to WS or from HTTPs to WSs +- Fix encryption issues when reusing TLS sessions (bump of Rustls) +- Added a `--json` flag to all commands diff --git a/content/changelog/2024/01-10-documentation-changelog.md b/content/changelog/2024/01-10-documentation-changelog.md index 21d9d146a..6120806c2 100644 --- a/content/changelog/2024/01-10-documentation-changelog.md +++ b/content/changelog/2024/01-10-documentation-changelog.md @@ -20,4 +20,4 @@ aliases: excludeSearch: true --- -A changelog has been [added](/changelog) to our [Developer Center](). It will be regularly updated by the Clever Cloud teams to give you an overview of our new features, but also changes made and deprecations planned on the platform. +A changelog has been [added](/changelog) to our Developer Center. It will be regularly updated by the Clever Cloud teams to give you an overview of our new features, but also changes made and deprecations planned on the platform. diff --git a/content/changelog/2024/01-11-redis-7.2.4.md b/content/changelog/2024/01-11-redis-7.2.4.md index 1d30b2efd..da85ab9cb 100644 --- a/content/changelog/2024/01-11-redis-7.2.4.md +++ b/content/changelog/2024/01-11-redis-7.2.4.md @@ -19,12 +19,12 @@ Redis™ `7.2.4` is now available for each new deployment. You can easily migrat ## Security fixes -* (CVE-2023-41056) In some cases, Redis™ may incorrectly handle resizing of memory buffers which can result in incorrect accounting of buffer sizes and lead to heap overflow and potential remote code execution. +- (CVE-2023-41056) In some cases, Redis™ may incorrectly handle resizing of memory buffers which can result in incorrect accounting of buffer sizes and lead to heap overflow and potential remote code execution. ## Bug fixes -* Fix crashes of cluster commands clusters with mixed versions of 7.0 and 7.2 (#12805, #12832) -* Fix slot ownership not being properly handled when deleting a slot from a node (#12564) -* Fix atomicity issues with the RedisModuleEvent_Key module API event (#12733) +- Fix crashes of cluster commands clusters with mixed versions of 7.0 and 7.2 (#12805, #12832) +- Fix slot ownership not being properly handled when deleting a slot from a node (#12564) +- Fix atomicity issues with the RedisModuleEvent_Key module API event (#12733) - [Learn more about Redis™ 7.2.x branch](https://redis.com/blog/introducing-redis-7-2/). diff --git a/content/changelog/2024/01-22-matomo-5.0.1.md b/content/changelog/2024/01-22-matomo-5.0.1.md index f289ffe6a..a6fc72385 100644 --- a/content/changelog/2024/01-22-matomo-5.0.1.md +++ b/content/changelog/2024/01-22-matomo-5.0.1.md @@ -20,5 +20,6 @@ excludeSearch: true [Matomo](https://matomo.org/) 5.0 was released mid-December, version 5.0.1 is now available. Since then, we've worked on the support of this new branch on Clever Cloud. It's done! You can deploy this latest version right now from our [Console](https://console.clever-cloud.com) or [Clever Tools](https://github.com/CleverCloud/clever-tools). Existing customers add-ons are already up-to-date. + - [Learn more about Matomo 5.0](https://matomo.org/changelog/matomo-5-0-0/) - [Learn more about Matomo 5.0.1](https://matomo.org/changelog/matomo-5-0-1/) diff --git a/content/changelog/2024/01-24-ruby-3.3.0.md b/content/changelog/2024/01-24-ruby-3.3.0.md index fc248f7b8..9a0bc7c36 100644 --- a/content/changelog/2024/01-24-ruby-3.3.0.md +++ b/content/changelog/2024/01-24-ruby-3.3.0.md @@ -16,7 +16,7 @@ excludeSearch: true You can now choose the `3.3.0` release of Ruby when you deploy Ruby on Rails applications on Clever Cloud. It can be set either through your `Gemfile` or the `CC_RUBY_VERSION` [environment variable](/doc/reference/reference-environment-variables/#ruby). -* [Learn more about Ruby 3.3.0 release](https://www.ruby-lang.org/en/news/2023/12/25/ruby-3-3-0-released/) +- [Learn more about Ruby 3.3.0 release](https://www.ruby-lang.org/en/news/2023/12/25/ruby-3-3-0-released/) {{< callout type="info" >}} If you use Node.js on this image, be aware that default version is now 20.11.0 (LTS). If you need another release to deploy your application, set the `CC_NODE_VERSION` [environment variable](/doc/develop/env-variables/). diff --git a/content/changelog/2024/01-25-clever-tools-3.1.0.md b/content/changelog/2024/01-25-clever-tools-3.1.0.md index d2fa4e83c..c691b4826 100644 --- a/content/changelog/2024/01-25-clever-tools-3.1.0.md +++ b/content/changelog/2024/01-25-clever-tools-3.1.0.md @@ -18,6 +18,7 @@ excludeSearch: true --- For several months, we were preparing our CLI, [Clever Tools](https://github.com/CleverCloud/clever-tools/), for big changes. It starts to be ready for prime time with the 3.1.0 release. First, the packaging process moved to GitHub Actions with some improvements: + - You can now get the [list of releases](https://github.com/CleverCloud/clever-tools/releases) with a changelog and source code archives - No more beta channel: you'll be able to test new features easier - Better process, quicker tests, more releases! @@ -30,7 +31,7 @@ Of course, there are also some bug fixes. And be prepared: more new features are To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/02-07-clever-tools-3.2.0.md b/content/changelog/2024/02-07-clever-tools-3.2.0.md index 5d93fb106..306477632 100644 --- a/content/changelog/2024/02-07-clever-tools-3.2.0.md +++ b/content/changelog/2024/02-07-clever-tools-3.2.0.md @@ -19,15 +19,15 @@ excludeSearch: true As mentioned [in the previous release](../01-25-clever-tools-3.1.0/), the packaging process moved to GitHub Actions to provide a better process, quicker tests and more frequent releases. We start with [the 3.2.0](https://github.com/CleverCloud/clever-tools/releases/tag/3.2.0) adding the log auto retry feature on network failures and some fixes: -* **api:** improve error message with `EAI_AGAIN` and `ECONNRESET` ([b134213](https://github.com/CleverCloud/clever-tools/commit/b134213f30d46dd7f5690a38425deb4fd752148c)) -* **logs:** improve error message with `EAI_AGAIN` and `ECONNRESET` ([fada067](https://github.com/CleverCloud/clever-tools/commit/fada06771369173e579f5fd3a708ff3cef40c95f)) -* **logs:** improve open and error debug message ([28dd996](https://github.com/CleverCloud/clever-tools/commit/28dd9968bec8de9545c6b940be732d3f8f87a8f9)) -* **logs:** increase connection timeout ([a4ec4b9](https://github.com/CleverCloud/clever-tools/commit/a4ec4b90b5d3938e27679edeb7d375281def3776)) -* **logs:** only print SSE errors as debug when verbose mode is enabled ([3ea21c6](https://github.com/CleverCloud/clever-tools/commit/3ea21c6a4ff75db8df5f8177bba10ef17c2962e0)) +- **api:** improve error message with `EAI_AGAIN` and `ECONNRESET` ([b134213](https://github.com/CleverCloud/clever-tools/commit/b134213f30d46dd7f5690a38425deb4fd752148c)) +- **logs:** improve error message with `EAI_AGAIN` and `ECONNRESET` ([fada067](https://github.com/CleverCloud/clever-tools/commit/fada06771369173e579f5fd3a708ff3cef40c95f)) +- **logs:** improve open and error debug message ([28dd996](https://github.com/CleverCloud/clever-tools/commit/28dd9968bec8de9545c6b940be732d3f8f87a8f9)) +- **logs:** increase connection timeout ([a4ec4b9](https://github.com/CleverCloud/clever-tools/commit/a4ec4b90b5d3938e27679edeb7d375281def3776)) +- **logs:** only print SSE errors as debug when verbose mode is enabled ([3ea21c6](https://github.com/CleverCloud/clever-tools/commit/3ea21c6a4ff75db8df5f8177bba10ef17c2962e0)) To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/02-08-sozu-0.15.19.md b/content/changelog/2024/02-08-sozu-0.15.19.md index ba1500216..c7949c97b 100644 --- a/content/changelog/2024/02-08-sozu-0.15.19.md +++ b/content/changelog/2024/02-08-sozu-0.15.19.md @@ -20,4 +20,4 @@ Our open source reverse proxy, Sōzu, is now deployed in its version 0.15.19. We - Read the full changelog [on GitHub](https://github.com/sozu-proxy/sozu/releases/tag/0.15.19) {{< icon "github" >}} -We expect the next release to be 1.0, with [protobuf](https://protobuf.dev/) everywhere and 2x faster messaging. We'll now use [Metal I/O](https://github.com/tokio-rs/mio) also for communication between workers, rather than threadpools. A release candidate should be released this month. \ No newline at end of file +We expect the next release to be 1.0, with [protobuf](https://protobuf.dev/) everywhere and 2x faster messaging. We'll now use [Metal I/O](https://github.com/tokio-rs/mio) also for communication between workers, rather than threadpools. A release candidate should be released this month. diff --git a/content/changelog/2024/02-12-new-grahds-region.md b/content/changelog/2024/02-12-new-grahds-region.md index f5eed3f21..104a64fb9 100644 --- a/content/changelog/2024/02-12-new-grahds-region.md +++ b/content/changelog/2024/02-12-new-grahds-region.md @@ -19,4 +19,4 @@ For some time now, you can deploy your applications and add-ons through Clever C Some customers asked us to make the Gravelines HDS region available independently for applications and add-ons, we listened to them. You can now deploy to it from [`clever-tools`](https://github.com/CleverCloud/clever-tools) or [the Console](https://console.clever-cloud.com) as `grahds`. -Please note that Clever Cloud’s services and infrastructures obtained the ISO 9001 certification last year, we’re waiting for the definitive approval of ISO 27001. HDS certification is the next step and our current priority \ No newline at end of file +Please note that Clever Cloud’s services and infrastructures obtained the ISO 9001 certification last year, we’re waiting for the definitive approval of ISO 27001. HDS certification is the next step and our current priority diff --git a/content/changelog/2024/02-16-clever-tools-3.4.0.md b/content/changelog/2024/02-16-clever-tools-3.4.0.md index b1e899df4..be775b312 100644 --- a/content/changelog/2024/02-16-clever-tools-3.4.0.md +++ b/content/changelog/2024/02-16-clever-tools-3.4.0.md @@ -23,25 +23,25 @@ But it's the `create` and `deploy` commands which are the most improved by this To create a Node.js application once logged in, you can now just: -``` +```console clever create -t node ``` If you need a JSON response for a Go application deployed on Gravelines HDS: -``` +```console clever create --type go --region grahds --format json ``` Last but not least: you can deploy a specific tag from your local git repository adding the `--tag` or `-t` option: -``` +```console clever deploy --tag v0.4.2 ``` To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/02-22-postgresql-pgvector-support.md b/content/changelog/2024/02-22-postgresql-pgvector-support.md index d9828470a..d65d8d8da 100644 --- a/content/changelog/2024/02-22-postgresql-pgvector-support.md +++ b/content/changelog/2024/02-22-postgresql-pgvector-support.md @@ -26,4 +26,4 @@ We recently noticed an increased interest from our clients in supporting the `pg If you need `pgvector`, open a ticket to our support team through [the Console Ticket Center](https://console.clever-cloud.com/ticket-center-choice). If you need any other extension, feel free to ask, we will try our best to respond to your use-case. -- Learn more about `pgvector` [on GitHub](https://github.com/pgvector/pgvector) {{< icon "github" >}} \ No newline at end of file +- Learn more about `pgvector` [on GitHub](https://github.com/pgvector/pgvector) {{< icon "github" >}} diff --git a/content/changelog/2024/02-26-healthcheck-for-everyone.md b/content/changelog/2024/02-26-healthcheck-for-everyone.md index 2305a1465..74b2dbf69 100644 --- a/content/changelog/2024/02-26-healthcheck-for-everyone.md +++ b/content/changelog/2024/02-26-healthcheck-for-everyone.md @@ -17,8 +17,7 @@ Up until now, the deployment process only checked whether the application is lis You can now define the paths that the orchestrator will call to validate a deployment for applications through one or multiple `CC_HEALTH_CHECK_PATH` environment variables. It works as follows: -* If the application responds on this specified path, and the response code is between `200` and `300`, the orchestrator considers that the deployment has been validated. -* If it responds with a code outside this interval, the application is considered to have failed its deployment. +- If the application responds on this specified path, and the response code is between `200` and `300`, the orchestrator considers that the deployment has been validated. +- If it responds with a code outside this interval, the application is considered to have failed its deployment. - Read the documentation about [Deployment healthcheck path](/doc/develop/healthcheck/) 📖 - diff --git a/content/changelog/2024/02-26-mtl-iplb-update.md b/content/changelog/2024/02-26-mtl-iplb-update.md index c87876023..c9219b4fb 100644 --- a/content/changelog/2024/02-26-mtl-iplb-update.md +++ b/content/changelog/2024/02-26-mtl-iplb-update.md @@ -24,14 +24,14 @@ If you configure your domains through CNAME records, this update will be transpa ## Applications -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.mtl.clever-cloud.com.` | -| A
Only if CNAME is not available | @ 10800 IN A 158.69.109.229
@ 10800 IN A 149.56.117.183 | +| Record Type | Value | +| ----------------------------------- | ------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.mtl.clever-cloud.com.` | +| A
Only if CNAME is not available | @ 10800 IN A 158.69.109.229
@ 10800 IN A 149.56.117.183 | ## Add-ons -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain-sdc.mtl.clever-cloud.com.` | -| A
Only if CNAME is not available | @ 10800 IN A 54.39.154.128
@ 10800 IN A 167.114.35.164 | +| Record Type | Value | +| ----------------------------------- | ----------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain-sdc.mtl.clever-cloud.com.` | +| A
Only if CNAME is not available | @ 10800 IN A 54.39.154.128
@ 10800 IN A 167.114.35.164 | diff --git a/content/changelog/2024/02-27-images-update-part2.md b/content/changelog/2024/02-27-images-update-part2.md index 93365f43a..cd21f5470 100644 --- a/content/changelog/2024/02-27-images-update-part2.md +++ b/content/changelog/2024/02-27-images-update-part2.md @@ -18,11 +18,11 @@ Earlier this month, we published [a first set of updates](../02-02-images-update New images include security patches, Linux kernel 6.7.1, OpenSSL 3.2.1 and Node.js 20.11.0 by default. For the latter, you can set it via the `CC_NODE_VERSION` [environment variable](/doc/reference/reference-environment-variables/#commons-to-all-applications). Other changes are as follows: -* **.NET:** - * Version 8.0 support - * `CC_DOTNET_VERSION` [environment variable](/doc/reference/reference-environment-variables/#net) can be `6.0` or `8.0` -* **Java - Elastic / APM:** - * The agent has been updated to 1.47.1 - * Java 21 support +- **.NET:** + - Version 8.0 support + - `CC_DOTNET_VERSION` [environment variable](/doc/reference/reference-environment-variables/#net) can be `6.0` or `8.0` +- **Java - Elastic / APM:** + - The agent has been updated to 1.47.1 + - Java 21 support New PHP image is next to come, with 8.3 version support, we're currently working on it. After that, we'll bring our new strategy to build images into production. We're currently testing it, and preparing enhancements for multiples runtimes. Your applications will automatically benefit from it when available. [Stay tuned](/changelog/index.xml). diff --git a/content/changelog/2024/03-11-console-components-update.md b/content/changelog/2024/03-11-console-components-update.md index 396bb2e5a..47e28b193 100644 --- a/content/changelog/2024/03-11-console-components-update.md +++ b/content/changelog/2024/03-11-console-components-update.md @@ -17,4 +17,4 @@ aliases: excludeSearch: true --- -In our ongoing effort to improve our [Console](https://console.clever-cloud.com) experience, we upgraded some of its components. It now uses [JS Client 8.2.0](../02-27-js-client-8.2.0/) and [Web Components 13.0.0](../03-07-web-components-v13/). This update also brings some fixes regarding deployment logs links and Warp10 calls. \ No newline at end of file +In our ongoing effort to improve our [Console](https://console.clever-cloud.com) experience, we upgraded some of its components. It now uses [JS Client 8.2.0](../02-27-js-client-8.2.0/) and [Web Components 13.0.0](../03-07-web-components-v13/). This update also brings some fixes regarding deployment logs links and Warp10 calls. diff --git a/content/changelog/2024/04-04-CVE-2024-3094.md b/content/changelog/2024/04-04-CVE-2024-3094.md index 19b49cdc7..481c5c508 100644 --- a/content/changelog/2024/04-04-CVE-2024-3094.md +++ b/content/changelog/2024/04-04-CVE-2024-3094.md @@ -26,9 +26,9 @@ Nevertheless, we immediately put the backdoored version on a deny list to preven You can know more about this CVE following these links: -* https://boehs.org/node/everything-i-know-about-the-xz-backdoor -* https://gynvael.coldwind.pl/?lang=en&id=782 -* https://lcamtuf.substack.com/p/technologist-vs-spy-the-xz-backdoor -* https://www.openwall.com/lists/oss-security/2024/03/29/4 +- +- +- +- -You can contact [our support team](https://console.clever-cloud.com/ticket-center-choice) if you have further questions about this topic. \ No newline at end of file +You can contact [our support team](https://console.clever-cloud.com/ticket-center-choice) if you have further questions about this topic. diff --git a/content/changelog/2024/04-11-clever-tools-3.5.2.md b/content/changelog/2024/04-11-clever-tools-3.5.2.md index 6aec80c95..6c9bc406d 100644 --- a/content/changelog/2024/04-11-clever-tools-3.5.2.md +++ b/content/changelog/2024/04-11-clever-tools-3.5.2.md @@ -25,7 +25,7 @@ Clever Tasks can now be directly created and configured from Clever Tools. They' To create a Clever Task using Python for example: -``` +```console # We create a Python App and its Git repository mkdir pythonTask && cd pythonTask echo 'print("Hello, from a Clever Cloud Task!")' > task.py @@ -38,25 +38,27 @@ clever deploy If you want to check if an application will deploy as a `TASK` or the `REGULAR` way, use `clever status`. Change the executed command using an environment variable. Set another value, for example with a bash script: -``` +```console clever env set CC_RUN_COMMAND "bash a_bash_script.sh" ``` + Clever Tasks will evolve with enhancements planed over the coming months. Feel free to tell us about your needs or ideas on this! -* [Learn more about Clever Tasks](/doc/develop/tasks/) +- [Learn more about Clever Tasks](/doc/develop/tasks/) Last but not least, we're introducing the access to Materia KV. Those granted with alpha access can now create a serverless, synchronously-replicated (over our 3 data centers in Paris) key-value add-on. You'll be able to use it with multiples kind of clients. First to be supported is Redis API. Thus, you can run: -```` +````markdown clever addon create kv myKV source <(clever addon env addon_myKV_id -F shell) redis-cli -h $KV_HOST -p $KV_PORT --tls PING ```` -* [Learn more about Materia KV](https://www.clever.cloud/blog/company/2024/04/16/materiadb-kv-materia-functions/) ([FR](https://www.clever.cloud/fr/blog/entreprise/2024/04/16/materiadb-kv-functions/)) + +- [Learn more about Materia KV](https://www.clever.cloud/blog/company/2024/04/16/materiadb-kv-materia-functions/) ([FR](https://www.clever.cloud/fr/blog/entreprise/2024/04/16/materiadb-kv-functions/)) To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install) -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/04-15-new-logs-interface-public-beta.md b/content/changelog/2024/04-15-new-logs-interface-public-beta.md index 8e616c121..b0e555377 100644 --- a/content/changelog/2024/04-15-new-logs-interface-public-beta.md +++ b/content/changelog/2024/04-15-new-logs-interface-public-beta.md @@ -23,5 +23,5 @@ This new feature is available for **applications only**. In this new interface you'll get better access to your instance/deployments, dark/light themes, a text filter, multiple settings (stored into your Clever Cloud account). -* [Learn more about our new Logs interface](https://www.clever.cloud/blog/company/2024/04/15/our-new-logs-interface/) ([FR](https://www.clever.cloud/fr/blog/entreprise/2024/04/15/notre-nouvelle-interface-de-logs-est-disponible/)) -* [Give us feedback about new Logs interface](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface) +- [Learn more about our new Logs interface](https://www.clever.cloud/blog/company/2024/04/15/our-new-logs-interface/) ([FR](https://www.clever.cloud/fr/blog/entreprise/2024/04/15/notre-nouvelle-interface-de-logs-est-disponible/)) +- [Give us feedback about new Logs interface](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface) diff --git a/content/changelog/2024/04-16-clever-tools-3.6.0.md b/content/changelog/2024/04-16-clever-tools-3.6.0.md index 4a8baa7e0..86641a3c7 100644 --- a/content/changelog/2024/04-16-clever-tools-3.6.0.md +++ b/content/changelog/2024/04-16-clever-tools-3.6.0.md @@ -21,7 +21,7 @@ Clever Tools 3.6 is now available, with some minor fixes and a new feature: the To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install) -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/04-24-php-deprecate-warning.md b/content/changelog/2024/04-24-php-deprecate-warning.md index ecd29fec9..f82bf4fd5 100644 --- a/content/changelog/2024/04-24-php-deprecate-warning.md +++ b/content/changelog/2024/04-24-php-deprecate-warning.md @@ -21,4 +21,4 @@ As we still see a lot of applications using deprecated versions, the new PHP ima There is no short term plan to cut access to supported versions such as PHP 5.6 or 7.x, but you do it at your own risks. -* Learn more about [PHP releases lifecycle](https://www.php.net/supported-versions.php) +- Learn more about [PHP releases lifecycle](https://www.php.net/supported-versions.php) diff --git a/content/changelog/2024/04-25-images-update.md b/content/changelog/2024/04-25-images-update.md index 26e64b857..751ee2be0 100644 --- a/content/changelog/2024/04-25-images-update.md +++ b/content/changelog/2024/04-25-images-update.md @@ -16,17 +16,17 @@ excludeSearch: true We've updated all our images and deployed them without any impact for our users. They include our new action executor, which will help to make some features available soon. They also include the following changes: -* **Common:** - * Linux kernel 6.8.6 - * glibc security fix (CVE-2024-2961) - * Node.js 20.12.2 as default version -* **Ruby:** - * Update to 3.0.7, 3.1.5, 3.2.4 and 3.3.1 (CVE-2024-27282, CVE-2024-27281 et CVE-2024-27280) -* **Elixir:** - * Update to 21.16.2, 22.3.4.27, 23.3.4.20, 24.3.4.17, 25.3.2.11, 26.2.4 -* **.NET:** - * Update to 8.0.103, 8.0.3 +- **Common:** + - Linux kernel 6.8.6 + - glibc security fix (CVE-2024-2961) + - Node.js 20.12.2 as default version +- **Ruby:** + - Update to 3.0.7, 3.1.5, 3.2.4 and 3.3.1 (CVE-2024-27282, CVE-2024-27281 et CVE-2024-27280) +- **Elixir:** + - Update to 21.16.2, 22.3.4.27, 23.3.4.20, 24.3.4.17, 25.3.2.11, 26.2.4 +- **.NET:** + - Update to 8.0.103, 8.0.3 We had to delay the release of PHP image with 8.3 version support, to better support some extensions and include latest security fixes. It will start to deploy next week and include an informative message when a deprecated version of PHP is used. -* Learn more about the [message for deprecated PHP versions](../04-24-php-deprecate-warning/). +- Learn more about the [message for deprecated PHP versions](../04-24-php-deprecate-warning/). diff --git a/content/changelog/2024/05-30-php-8.3-java-22.md b/content/changelog/2024/05-30-php-8.3-java-22.md index 582470604..596ff31e5 100644 --- a/content/changelog/2024/05-30-php-8.3-java-22.md +++ b/content/changelog/2024/05-30-php-8.3-java-22.md @@ -16,17 +16,17 @@ excludeSearch: true We've updated some of our images and deployed them without any impact for our users. You can now set `CC_PHP_VERSION` to `8.3`. It's the default version for new PHP applications. If `CC_PHP_VERSION` is set to `8`, version 8.2 is still used. We also start to warn you if you use a [deprecated](https://www.php.net/supported-versions.php) PHP version, older than `8.1`. Other changes include: -* **Common:** - * Linux kernel 6.8.11 (PHP is still 6.8.6) - * Node.js 20.14.0 as default version -* **.NET, Go, Rust:** - * Fix for crons -* **.NET:** - * Fix for deployment issues with 8.x branch -* **Java:** - * Support for Java 22 (non LTS) - * Support for NewRelic with Java 22 -* **PHP:** - * Composer 2.7.6 - * Support for PHP 8.3 with [all supported extensions](/doc/applications/php/extensions/#available-extensions-and-modules) - * PHP info apps are available for PHP [8.0](https://php80info.cleverapps.io), [8.1](https://php81info.cleverapps.io), [8.2](https://php82info.cleverapps.io) and [8.3](https://php83info.cleverapps.io) +- **Common:** + - Linux kernel 6.8.11 (PHP is still 6.8.6) + - Node.js 20.14.0 as default version +- **.NET, Go, Rust:** + - Fix for crons +- **.NET:** + - Fix for deployment issues with 8.x branch +- **Java:** + - Support for Java 22 (non LTS) + - Support for NewRelic with Java 22 +- **PHP:** + - Composer 2.7.6 + - Support for PHP 8.3 with [all supported extensions](/doc/applications/php/extensions/#available-extensions-and-modules) + - PHP info apps are available for PHP [8.0](https://php80info.cleverapps.io), [8.1](https://php81info.cleverapps.io), [8.2](https://php82info.cleverapps.io) and [8.3](https://php83info.cleverapps.io) diff --git a/content/changelog/2024/06-07-sozu-1.0.2.md b/content/changelog/2024/06-07-sozu-1.0.2.md index 57cb09d30..b20a84eb5 100644 --- a/content/changelog/2024/06-07-sozu-1.0.2.md +++ b/content/changelog/2024/06-07-sozu-1.0.2.md @@ -23,5 +23,5 @@ The communication between processes is more efficient thanks to [ProtoBuf](https We've also fixed a bug affecting socket timeouts on frontends, ensuring better handling of requests. -* [New Sōzu website](https://www.sozu.io) -* Learn more about [Sōzu new releases](https://github.com/sozu-proxy/sozu/releases) {{< icon "github" >}} \ No newline at end of file +- [New Sōzu website](https://www.sozu.io) +- Learn more about [Sōzu new releases](https://github.com/sozu-proxy/sozu/releases) {{< icon "github" >}} diff --git a/content/changelog/2024/06-10-mongo-db-terraform.md b/content/changelog/2024/06-10-mongo-db-terraform.md index d0846cd88..68440e66c 100644 --- a/content/changelog/2024/06-10-mongo-db-terraform.md +++ b/content/changelog/2024/06-10-mongo-db-terraform.md @@ -21,4 +21,4 @@ If you can deploy on Clever Cloud through our [Console](https://console.clever-c We've recently added support for Python and [Materia KV](/doc/addons/materia-kv/). It's MongoDB's turn [to be available](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs/resources/mongodb). You can now create such an add-on, choose its plan, region and get the credentials to connect to it. -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2024/06-11-clever-tools-3.7.0.md b/content/changelog/2024/06-11-clever-tools-3.7.0.md index 528a5cb9f..4fb854d6e 100644 --- a/content/changelog/2024/06-11-clever-tools-3.7.0.md +++ b/content/changelog/2024/06-11-clever-tools-3.7.0.md @@ -21,7 +21,7 @@ excludeSearch: true To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/06-21-better-new-logs.md b/content/changelog/2024/06-21-better-new-logs.md index 4b098a1d2..67c703e2e 100644 --- a/content/changelog/2024/06-21-better-new-logs.md +++ b/content/changelog/2024/06-21-better-new-logs.md @@ -30,5 +30,4 @@ Some of you also asked for a change of the default behavior of this Logs interfa Depending on your feedback, we'll improve this further in the coming weeks. Here again, this is a first step as the indexed logs will open up a wide range of possibilities in this area. -* Share your comments and ideas on our [GitHub Community](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface) - +- Share your comments and ideas on our [GitHub Community](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface) diff --git a/content/changelog/2024/06-28-new-ip-list-paris.md b/content/changelog/2024/06-28-new-ip-list-paris.md index 76083b081..96a57c604 100644 --- a/content/changelog/2024/06-28-new-ip-list-paris.md +++ b/content/changelog/2024/06-28-new-ip-list-paris.md @@ -19,10 +19,10 @@ excludeSearch: true As our network evolves, we've updated [IP list for Paris (PAR) zone](/doc/administrate/domain-names/#your-application-runs-in-the-europeparis-par-zone). If you use A records for DNS configuration, update them. 4 new IP addresses should be added (`91.208.207.220` to `91.208.207.223`). **We strongly recommend using CNAME records instead.** -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.par.clever-cloud.com.` | -| A
Only if CNAME is not available | `@ 10800 IN A 91.208.207.214`
`@ 10800 IN A 91.208.207.215`
`@ 10800 IN A 91.208.207.216`
`@ 10800 IN A 91.208.207.217`
`@ 10800 IN A 91.208.207.218`
`@ 10800 IN A 91.208.207.220`
`@ 10800 IN A 91.208.207.221`
`@ 10800 IN A 91.208.207.222`
`@ 10800 IN A 91.208.207.223` | +| Record Type | Value | +| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.par.clever-cloud.com.` | +| A
Only if CNAME is not available | `@ 10800 IN A 91.208.207.214`
`@ 10800 IN A 91.208.207.215`
`@ 10800 IN A 91.208.207.216`
`@ 10800 IN A 91.208.207.217`
`@ 10800 IN A 91.208.207.218`
`@ 10800 IN A 91.208.207.220`
`@ 10800 IN A 91.208.207.221`
`@ 10800 IN A 91.208.207.222`
`@ 10800 IN A 91.208.207.223` | We are going to remove 4 IPs that **you must stop to use between now and August 23rd**: diff --git a/content/changelog/2024/07-01-matomo-5.1.0.md b/content/changelog/2024/07-01-matomo-5.1.0.md index 61884dd1a..65c9c6254 100644 --- a/content/changelog/2024/07-01-matomo-5.1.0.md +++ b/content/changelog/2024/07-01-matomo-5.1.0.md @@ -20,6 +20,7 @@ excludeSearch: true Our [Matomo](https://matomo.org/) add-on has been updated to version `5.1.0` which is now used by default. You can deploy this latest release from our [Console](https://console.clever-cloud.com) or [Clever Tools](https://github.com/CleverCloud/clever-tools). Existing customers add-ons are already up-to-date. Here are the changes since previous deployed version (`5.0.1`): + - [Learn more about Matomo 5.0.2](https://matomo.org/changelog/matomo-5-0-2/) - [Learn more about Matomo 5.0.3](https://matomo.org/changelog/matomo-5-0-3/) - [Learn more about Matomo 5.1.0](https://matomo.org/changelog/matomo-5-1-0/) diff --git a/content/changelog/2024/07-02-clever-tools-3.8.0.md b/content/changelog/2024/07-02-clever-tools-3.8.0.md index 7c6856a85..56354a1d2 100644 --- a/content/changelog/2024/07-02-clever-tools-3.8.0.md +++ b/content/changelog/2024/07-02-clever-tools-3.8.0.md @@ -28,6 +28,7 @@ clever restart --app app_id clever restart --app my_app_name clever restart --app my_app_name --org my_org_name ``` + `clever applications list` new command can be used from any folder of your system. It prints details about applications across your organisations. You can filter the result with `--org` or `-o` option. It includes IDs, names and local aliases (if available) in a table. ## More (consistent) options @@ -59,7 +60,7 @@ Multiple new features are also available in this "Big Summer Update". Access Log To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install) -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/07-03-docker-terraform.md b/content/changelog/2024/07-03-docker-terraform.md index ce7f86a62..8161b43c6 100644 --- a/content/changelog/2024/07-03-docker-terraform.md +++ b/content/changelog/2024/07-03-docker-terraform.md @@ -21,4 +21,4 @@ To manage your resources as code on Clever Cloud, from applications to add-ons ( You can define instances count or flavors, region, dependencies, ports, Dockerfile and application paths, registry credentials and more. Read [the full parameters list](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs/resources/docker). -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2024/07-04-apache-php-image-update.md b/content/changelog/2024/07-04-apache-php-image-update.md index fd3fec212..1b138a2a0 100644 --- a/content/changelog/2024/07-04-apache-php-image-update.md +++ b/content/changelog/2024/07-04-apache-php-image-update.md @@ -15,10 +15,11 @@ excludeSearch: true --- We've updated our PHP image to support versions [8.2.21](https://www.php.net/ChangeLog-8.php#8.2.21) and [8.3.9](https://www.php.net/ChangeLog-8.php#8.3.9): -* They fix a bug [introduced](https://github.com/api-platform/core/issues/6416) in 8.2.20 and 8.3.8 which we had previously patched -* This image includes a fix for GnuPG extension -* PHP info apps are up-to-date: [8.2](https://php82info.cleverapps.io) and [8.3](https://php83info.cleverapps.io) + +- They fix a bug [introduced](https://github.com/api-platform/core/issues/6416) in 8.2.20 and 8.3.8 which we had previously patched +- This image includes a fix for GnuPG extension +- PHP info apps are up-to-date: [8.2](https://php82info.cleverapps.io) and [8.3](https://php83info.cleverapps.io) Over the past few weeks, we have also included [Apache 2.4.60](https://dlcdn.apache.org/httpd/CHANGES_2.4.60), fixing CVE-2024-36387, 38472, 38473, 38474, 38475, 38476, 38477, 39573 and [Composer 2.7.7](https://github.com/composer/composer/releases/tag/2.7.7), fixing CVE-2024-35241, 35242. -* Learn more about [PHP on Clever Cloud](/doc/applications/php/) +- Learn more about [PHP on Clever Cloud](/doc/applications/php/) diff --git a/content/changelog/2024/07-05-go-haskell-ruby-update.md b/content/changelog/2024/07-05-go-haskell-ruby-update.md index 9a6813323..08bd88120 100644 --- a/content/changelog/2024/07-05-go-haskell-ruby-update.md +++ b/content/changelog/2024/07-05-go-haskell-ruby-update.md @@ -16,10 +16,10 @@ excludeSearch: true We've updated some of our images: -* **Go:** - * Default to 1.22.5 - * Fixes CVE-2024-2479 -* **Haskell:** - * Includes Stack 2.15.7 -* **Ruby:** - * Supports 3.1.6, 3.3.2 and 3.3.3 +- **Go:** + - Default to 1.22.5 + - Fixes CVE-2024-2479 +- **Haskell:** + - Includes Stack 2.15.7 +- **Ruby:** + - Supports 3.1.6, 3.3.2 and 3.3.3 diff --git a/content/changelog/2024/07-06-mysql-pgsql-update.md b/content/changelog/2024/07-06-mysql-pgsql-update.md index 245ea12c0..e9af4aefa 100644 --- a/content/changelog/2024/07-06-mysql-pgsql-update.md +++ b/content/changelog/2024/07-06-mysql-pgsql-update.md @@ -16,10 +16,10 @@ excludeSearch: true We've updated some of our database services: -* **MySQL:** - * Version 8.0.34-26 -* **PostgreSQL:** - * Version 15.7 - * `pgvector` extension 0.7.1 - * `timescaledb` extension 2.14.2 - * `pg_ivm` extension 1.8 is now available (ask it to [our support team](https://console.clever-cloud.com/ticket-center-choice)) +- **MySQL:** + - Version 8.0.34-26 +- **PostgreSQL:** + - Version 15.7 + - `pgvector` extension 0.7.1 + - `timescaledb` extension 2.14.2 + - `pg_ivm` extension 1.8 is now available (ask it to [our support team](https://console.clever-cloud.com/ticket-center-choice)) diff --git a/content/changelog/2024/07-10-CVE-2024-6387.md b/content/changelog/2024/07-10-CVE-2024-6387.md index 48dc6b7dd..c355d2792 100644 --- a/content/changelog/2024/07-10-CVE-2024-6387.md +++ b/content/changelog/2024/07-10-CVE-2024-6387.md @@ -22,4 +22,4 @@ As stated [by Qualys](https://www.qualys.com/regresshion-cve-2024-6387/), « *ve There was no known exploit for 64-bit systems, but we immediately strengthened firewall rules for port 22 and packaged OpenSSH 9.8p1. Then we deployed it on all our systems, images, managed services and started to redeploy applications gradually for our customers. This work is now completed on all our servers and thousands of virtual machines without any impact. -You can contact [our support team](https://console.clever-cloud.com/ticket-center-choice) if you have further questions about this topic. \ No newline at end of file +You can contact [our support team](https://console.clever-cloud.com/ticket-center-choice) if you have further questions about this topic. diff --git a/content/changelog/2024/07-17-keycloak-public-release.md b/content/changelog/2024/07-17-keycloak-public-release.md index 6d239a44c..be06367a8 100644 --- a/content/changelog/2024/07-17-keycloak-public-release.md +++ b/content/changelog/2024/07-17-keycloak-public-release.md @@ -19,4 +19,4 @@ excludeSearch: true Clever Cloud provides a Keycloak add-on, developed with Please Open-it, for some months in private alpha. We're releasing it publicly, with a new version and some fixes. Any Clever Cloud user can now deploy a Keycloak service from [API](/api/), [Clever Tools](https://github.com/CleverCloud/clever-tools) or [Console](https://console.clever-cloud.com) and use it. If you have any question or feedback, use our [GitHub Community space](https://github.com/CleverCloud/Community/discussions/categories/keycloak). -- [Learn more about Keycloak on Clever Cloud](/doc/addons/keycloak/) \ No newline at end of file +- [Learn more about Keycloak on Clever Cloud](/doc/addons/keycloak/) diff --git a/content/changelog/2024/07-17-new-logs-default.md b/content/changelog/2024/07-17-new-logs-default.md index 1fdfcf5ab..512731d24 100644 --- a/content/changelog/2024/07-17-new-logs-default.md +++ b/content/changelog/2024/07-17-new-logs-default.md @@ -18,4 +18,4 @@ aliases: excludeSearch: true --- -New logs interface is available in the Console in public beta [for some months](../04-15-new-logs-interface-public-beta/), and we already [enhanced it](../06-21-better-new-logs/). We're now confident enough to use it by default. You can still disable it. If you have any question or feedback, use our [GitHub Community space](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface). \ No newline at end of file +New logs interface is available in the Console in public beta [for some months](../04-15-new-logs-interface-public-beta/), and we already [enhanced it](../06-21-better-new-logs/). We're now confident enough to use it by default. You can still disable it. If you have any question or feedback, use our [GitHub Community space](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface). diff --git a/content/changelog/2024/07-18-elastic-8.10.2-jenkins-2.452.3.md b/content/changelog/2024/07-18-elastic-8.10.2-jenkins-2.452.3.md index 0ef2f7240..3a39a4f5f 100644 --- a/content/changelog/2024/07-18-elastic-8.10.2-jenkins-2.452.3.md +++ b/content/changelog/2024/07-18-elastic-8.10.2-jenkins-2.452.3.md @@ -19,8 +19,8 @@ excludeSearch: true We've updated Elasticsearch and Jenkins services: -* **Elasticsearch:** - * Version 8.10.2 -* **Jenkins:** - * New add-ons are deployed with version 2.452.3 and Java 21 - * Existing Jenkins were upgraded to Java 17 +- **Elasticsearch:** + - Version 8.10.2 +- **Jenkins:** + - New add-ons are deployed with version 2.452.3 and Java 21 + - Existing Jenkins were upgraded to Java 17 diff --git a/content/changelog/2024/07-18-github-action-review-apps.md b/content/changelog/2024/07-18-github-action-review-apps.md index e2ab502e5..54b30b947 100644 --- a/content/changelog/2024/07-18-github-action-review-apps.md +++ b/content/changelog/2024/07-18-github-action-review-apps.md @@ -30,4 +30,4 @@ Some months ago, Clever Cloud released [a new GitHub Action](https://github.com/ type: '' ``` -- [Learn more about how to deploy from GitHub to Clever Cloud](/doc/ci-cd/github/) \ No newline at end of file +- [Learn more about how to deploy from GitHub to Clever Cloud](/doc/ci-cd/github/) diff --git a/content/changelog/2024/07-30-github-action-1.1.md b/content/changelog/2024/07-30-github-action-1.1.md index d06341a2b..6ab20ad8e 100644 --- a/content/changelog/2024/07-30-github-action-1.1.md +++ b/content/changelog/2024/07-30-github-action-1.1.md @@ -19,4 +19,4 @@ excludeSearch: true Update for [GitHub Action](https://github.com/marketplace/actions/clever-cloud-review-app-on-prs) to deploy applications from GitHub to Clever Cloud. Version 1.1 simplifies workflow files and gives conditional comments depending on the actions performed on the PR (deploy, update, delete). -- [Learn more about how to deploy from GitHub to Clever Cloud](/doc/ci-cd/github/) \ No newline at end of file +- [Learn more about how to deploy from GitHub to Clever Cloud](/doc/ci-cd/github/) diff --git a/content/changelog/2024/08-01-lagging-server-crate.md b/content/changelog/2024/08-01-lagging-server-crate.md index 9e60e2076..0fe8b56be 100644 --- a/content/changelog/2024/08-01-lagging-server-crate.md +++ b/content/changelog/2024/08-01-lagging-server-crate.md @@ -19,4 +19,4 @@ excludeSearch: true When we release new versions of our reverse proxy [Sōzu](https://www.sozu.io), we now systematically run performances tests. To conduct some of them directly from our CI, we developed a small tool: Lagging Server. It's open source, and now [available as a Rust crate](https://crates.io/crates/lagging_server) anyone can use. -* Learn more about [Lagging Server](https://github.com/CleverCloud/lagging_server) {{< icon "github" >}} \ No newline at end of file +- Learn more about [Lagging Server](https://github.com/CleverCloud/lagging_server) {{< icon "github" >}} diff --git a/content/changelog/2024/08-09-python-3.12-update.md b/content/changelog/2024/08-09-python-3.12-update.md index ec856d571..adc7eb7cf 100644 --- a/content/changelog/2024/08-09-python-3.12-update.md +++ b/content/changelog/2024/08-09-python-3.12-update.md @@ -19,10 +19,10 @@ excludeSearch: true We've updated Docker and Python image and deployed them without any impact for our users. -* **Common:** - * Linux kernel 6.10.2 -* **Docker:** - * Lighter updated image -* **Python:** - * Python 3.12 support - * A fix for missing system locales +- **Common:** + - Linux kernel 6.10.2 +- **Docker:** + - Lighter updated image +- **Python:** + - Python 3.12 support + - A fix for missing system locales diff --git a/content/changelog/2024/08-30-deploy-url-mtl.md b/content/changelog/2024/08-30-deploy-url-mtl.md index f86e8ba0b..9c81ffe73 100644 --- a/content/changelog/2024/08-30-deploy-url-mtl.md +++ b/content/changelog/2024/08-30-deploy-url-mtl.md @@ -19,7 +19,7 @@ excludeSearch: true We improved our git services on Montreal zone. Newly created applications now use `push-n2-mtl-clevercloud-customers.services.clever-cloud.com` as deployment URL. Applications still using the previous URL starting with `push-n1` won't be impacted by this change. If the new URL is not in your known hosts, you can see a warning during `git+ssh` operations: -``` +```text ❯ git clone git+ssh://git@push-n2-mtl-clevercloud-customers.services.clever-cloud.com/app_xxx.git Cloning into 'app_xxx'… The authenticity of host 'push-n2-mtl-clevercloud-customers.services.clever-cloud.com (192.99.188.152)' can't be established. diff --git a/content/changelog/2024/09-12-clever-tools-3.8.3.md b/content/changelog/2024/09-12-clever-tools-3.8.3.md index e10a75463..7f835b727 100644 --- a/content/changelog/2024/09-12-clever-tools-3.8.3.md +++ b/content/changelog/2024/09-12-clever-tools-3.8.3.md @@ -21,7 +21,7 @@ After two minor releases fixing issues with drains, [Clever Tools 3.8.3](https:/ To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/09-12-js-client-9.0.0.md b/content/changelog/2024/09-12-js-client-9.0.0.md index 49d2c39b2..ee4c8e186 100644 --- a/content/changelog/2024/09-12-js-client-9.0.0.md +++ b/content/changelog/2024/09-12-js-client-9.0.0.md @@ -17,4 +17,4 @@ aliases: excludeSearch: true --- -We released [Clever Cloud JS client 9.0.0](https://github.com/CleverCloud/clever-client.js/blob/master/CHANGELOG.md#900-2024-09-11). It computes OAuth v1 signature with Web Crypto for all platforms (Browser, Node.js, Deno, Bun, CF workers, etc.) instead of relying on `node:crypto`. This will simplify usage of the client with a bundler. \ No newline at end of file +We released [Clever Cloud JS client 9.0.0](https://github.com/CleverCloud/clever-client.js/blob/master/CHANGELOG.md#900-2024-09-11). It computes OAuth v1 signature with Web Crypto for all platforms (Browser, Node.js, Deno, Bun, CF workers, etc.) instead of relying on `node:crypto`. This will simplify usage of the client with a bundler. diff --git a/content/changelog/2024/10-01-python-image-changes.md b/content/changelog/2024/10-01-python-image-changes.md index 702944766..c361c2e74 100644 --- a/content/changelog/2024/10-01-python-image-changes.md +++ b/content/changelog/2024/10-01-python-image-changes.md @@ -22,7 +22,7 @@ We only support [pip](https://packaging.python.org/en/latest/tutorials/installin We'll enhance its native support in coming releases of our Python image. -* [Learn more about uv](https://github.com/astral-sh/uv) {{< icon "github" >}} +- [Learn more about uv](https://github.com/astral-sh/uv) {{< icon "github" >}} ## Python versions: time to clean up @@ -32,7 +32,7 @@ We'll also get closer to [the official Python release cycle](https://devguide.py If you need to sideload unsupported Python versions, `uv` [can help you](https://docs.astral.sh/uv/guides/install-python/). You can also deploy your applications through [Docker](/doc/applications/docker), but you should avoid to use end of life runtime in your applications. -* Learn more about [Python on Clever Cloud](/doc/applications/python/) +- Learn more about [Python on Clever Cloud](/doc/applications/python/) ## What's next? diff --git a/content/changelog/2024/10-07-CVE-2024-47561.md b/content/changelog/2024/10-07-CVE-2024-47561.md index 0629706de..7b3123c65 100644 --- a/content/changelog/2024/10-07-CVE-2024-47561.md +++ b/content/changelog/2024/10-07-CVE-2024-47561.md @@ -15,4 +15,4 @@ excludeSearch: true On October 4th, we were informed of [a schema parsing vulnerability](https://nvd.nist.gov/vuln/detail/CVE-2024-47561) in the Java SDK of Apache Avro 1.11.3 and previous versions, allowing bad actors to execute arbitrary code. Our security team instantly made sanity checks, and listed impacted services. -We upgraded our tools using Avro to 1.11.4. As Apache Pulsar was impacted, we upgraded our cluster to [version 3.3.2](https://github.com/apache/pulsar/releases/tag/v3.3.2). The complete rolling of these updates is now ended, without any impact to our users. You can contact [our support team](https://console.clever-cloud.com/ticket-center-choice) if you have further questions about this topic. \ No newline at end of file +We upgraded our tools using Avro to 1.11.4. As Apache Pulsar was impacted, we upgraded our cluster to [version 3.3.2](https://github.com/apache/pulsar/releases/tag/v3.3.2). The complete rolling of these updates is now ended, without any impact to our users. You can contact [our support team](https://console.clever-cloud.com/ticket-center-choice) if you have further questions about this topic. diff --git a/content/changelog/2024/10-17-sozu-1.0.5.md b/content/changelog/2024/10-17-sozu-1.0.5.md index 1d716de94..9c4431afc 100644 --- a/content/changelog/2024/10-17-sozu-1.0.5.md +++ b/content/changelog/2024/10-17-sozu-1.0.5.md @@ -20,4 +20,4 @@ excludeSearch: true We're currently testing the 1.1.0 release candidate of Sōzu, with HTTP/2 support, coming soon on Clever Cloud. -* Learn more about [Sōzu new releases](https://github.com/sozu-proxy/sozu/releases) {{< icon "github" >}} \ No newline at end of file +- Learn more about [Sōzu new releases](https://github.com/sozu-proxy/sozu/releases) {{< icon "github" >}} diff --git a/content/changelog/2024/10-21-clever-tools-3.9.0.md b/content/changelog/2024/10-21-clever-tools-3.9.0.md index 9b71dfac0..2b9859927 100644 --- a/content/changelog/2024/10-21-clever-tools-3.9.0.md +++ b/content/changelog/2024/10-21-clever-tools-3.9.0.md @@ -20,6 +20,7 @@ excludeSearch: true [Clever Tools 3.9](https://github.com/CleverCloud/clever-tools/releases/tag/3.9.0) is available. It's the first minor release since our [Big Summer Update](../07-02-clever-tools-3.8.0/). Over the past few months, we've revamped many things under the hood, to clean the code and prepare next big changes we're working on. ## List and diagnose your domains + This new version brings two new features to manage domains. First is `clever domain overview`, allowing you to list domains linked to your account, across all the organisations you manage. List only domains containing a specific text string in their name thanks to the `--filter` option. Use the `json` output (`--format`/`-F`) and tools such as [jless](https://jless.io/) to navigate through long lists easily. This feature uses a new "short" link for the Console, which doesn't require organisation or user ID: @@ -37,7 +38,7 @@ This release also provides bug fixes, the token expiry date/time in `clever prof To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/11-08-erlang-rust-update.md b/content/changelog/2024/11-08-erlang-rust-update.md index 94f2319e4..a302aaca8 100644 --- a/content/changelog/2024/11-08-erlang-rust-update.md +++ b/content/changelog/2024/11-08-erlang-rust-update.md @@ -17,16 +17,16 @@ aliases: We’ve updated Elixir and Rust images. They were deployed without any impact for our users. -* **Common:** - * Linux kernel 6.11.6 - * Lighter Vector binary - * New build/deploy message with colors - * Users can now use multiple OpenVPN clients in a single instance -* **Elixir:** - * Elixir 1.17 - * Erlang 27.1.2 -* **Rust:** - * Rust 1.82.0 - * libassuan fix +- **Common:** + - Linux kernel 6.11.6 + - Lighter Vector binary + - New build/deploy message with colors + - Users can now use multiple OpenVPN clients in a single instance +- **Elixir:** + - Elixir 1.17 + - Erlang 27.1.2 +- **Rust:** + - Rust 1.82.0 + - libassuan fix We also started to add [Redirection.io](https://redirection.io) agent in our images with this update, as part of our [Enthusiast Tools initiative](../10-01-python-image-changes/), and plan to ease its native support in coming releases. diff --git a/content/changelog/2024/11-08-mysql-mysql-8.4.0.md b/content/changelog/2024/11-08-mysql-mysql-8.4.0.md index 22003ae2c..98b9e3d36 100644 --- a/content/changelog/2024/11-08-mysql-mysql-8.4.0.md +++ b/content/changelog/2024/11-08-mysql-mysql-8.4.0.md @@ -16,5 +16,5 @@ excludeSearch: true MySQL 8.4 is available on Clever Cloud. You can deploy it as a new add-on or migrate existing ones. As this is the first release (8.4.0) of this long term support (LTS) branch for the [Percona Server](https://www.percona.com/mysql/software/percona-server-for-mysql) we use, it's tagged as `early`. That means you should consider it mostly to make some tests and discover what's new. But we recommend [waiting a bit](https://www.percona.com/blog/do-not-upgrade-to-any-version-of-mysql-after-8-0-37/) before using a new branch in production. -* [Learn more about MySQL 8.4](https://www.percona.com/blog/mysql-8-4-first-peek/) -* [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) +- [Learn more about MySQL 8.4](https://www.percona.com/blog/mysql-8-4-first-peek/) +- [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) diff --git a/content/changelog/2024/11-09-java-update.md b/content/changelog/2024/11-09-java-update.md index 3a34cff24..255f943fb 100644 --- a/content/changelog/2024/11-09-java-update.md +++ b/content/changelog/2024/11-09-java-update.md @@ -16,11 +16,11 @@ excludeSearch: true We’ve updated Java image. It was deployed without any impact for our users. - * Java 23 support - * Linux kernel 6.11.6 - * Lighter Vector binary - * New build/deploy message with colors - * [Redirection.io](https://redirection.io) agent is included in the image - * Users can now use multiple OpenVPN clients in a single instance +- Java 23 support +- Linux kernel 6.11.6 +- Lighter Vector binary +- New build/deploy message with colors +- [Redirection.io](https://redirection.io) agent is included in the image +- Users can now use multiple OpenVPN clients in a single instance -As Java 22 is now [considered as end-of-life](https://www.oracle.com/fr/java/technologies/java-se-support-roadmap.html), we invite you to upgrade `CC_JAVA_VERSION` of your applications to `23` or to `21` (latest LTS). \ No newline at end of file +As Java 22 is now [considered as end-of-life](https://www.oracle.com/fr/java/technologies/java-se-support-roadmap.html), we invite you to upgrade `CC_JAVA_VERSION` of your applications to `23` or to `21` (latest LTS). diff --git a/content/changelog/2024/11-21-eol-warnings-console.md b/content/changelog/2024/11-21-eol-warnings-console.md index ef24b35ad..8b1d7d6df 100644 --- a/content/changelog/2024/11-21-eol-warnings-console.md +++ b/content/changelog/2024/11-21-eol-warnings-console.md @@ -18,6 +18,7 @@ excludeSearch: true --- [Earlier this year](../04-24-php-deprecate-warning/), we started to show warnings in logs when you deploy PHP applications with a `CC_PHP_VERSION` corresponding to a release considered as [end-of-life by PHP community](https://www.php.net/supported-versions.php). Today, we start showing such warnings in the environment variables panel of applications in the Clever Cloud Console for: + - `CC_PHP_VERSION` - `CC_PYTHON_VERSION` - `CC_RUBY_VERSION` diff --git a/content/changelog/2024/11-27-clever-tools-3.10.md b/content/changelog/2024/11-27-clever-tools-3.10.md index 2e4584c9e..f29e756ae 100644 --- a/content/changelog/2024/11-27-clever-tools-3.10.md +++ b/content/changelog/2024/11-27-clever-tools-3.10.md @@ -25,7 +25,7 @@ clever addon create es-addon --option plugins=analysis-icu,mapper-murmur3 To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/12-12-python-3.13-update.md b/content/changelog/2024/12-12-python-3.13-update.md index 50cd6c46d..d158dc909 100644 --- a/content/changelog/2024/12-12-python-3.13-update.md +++ b/content/changelog/2024/12-12-python-3.13-update.md @@ -16,10 +16,10 @@ excludeSearch: true We deployed an updated Python image with no impact for our users. - * uv 0.5.7 - * Linux kernel 6.11.6 - * Redirection.io agent - * Python 3.13 support - * Python 3.7 withdrawal +- uv 0.5.7 +- Linux kernel 6.11.6 +- Redirection.io agent +- Python 3.13 support +- Python 3.7 withdrawal -You can now use `3.13` as `CC_PYTHON_VERSION` environment variable. This version will also be used as default value. As announced [in October](../10-01-python-image-changes), Python 3.7 is not supported anymore. However, you can use `uv` to [install or use Python 3.7](https://docs.astral.sh/uv/guides/install-python/#installing-a-specific-version). \ No newline at end of file +You can now use `3.13` as `CC_PYTHON_VERSION` environment variable. This version will also be used as default value. As announced [in October](../10-01-python-image-changes), Python 3.7 is not supported anymore. However, you can use `uv` to [install or use Python 3.7](https://docs.astral.sh/uv/guides/install-python/#installing-a-specific-version). diff --git a/content/changelog/2024/12-18-clever-tools-3.11.md b/content/changelog/2024/12-18-clever-tools-3.11.md index c62f53b6c..7863d9b39 100644 --- a/content/changelog/2024/12-18-clever-tools-3.11.md +++ b/content/changelog/2024/12-18-clever-tools-3.11.md @@ -30,7 +30,7 @@ You can learn more about `clever kv` in [Clever Tools documentation](/doc/cli/kv To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2024/12-24-terraform-0.5-Keycloak-Metabase.md b/content/changelog/2024/12-24-terraform-0.5-Keycloak-Metabase.md index 475c109c8..071370189 100644 --- a/content/changelog/2024/12-24-terraform-0.5-Keycloak-Metabase.md +++ b/content/changelog/2024/12-24-terraform-0.5-Keycloak-Metabase.md @@ -20,4 +20,4 @@ excludeSearch: true You can now deploy [Keycloak](/doc/addons/keycloak) and [Metabase](/doc/addons/metabase) add-ons using our Terraform provider, compatible with OpenTofu. -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/01-06-sozu-1.0.6.md b/content/changelog/2025/01-06-sozu-1.0.6.md index c619f958c..7b2583552 100644 --- a/content/changelog/2025/01-06-sozu-1.0.6.md +++ b/content/changelog/2025/01-06-sozu-1.0.6.md @@ -18,4 +18,4 @@ excludeSearch: true [Sōzu](https://www.sozu.io) 1.0.6 is now available and deployed on all our shared and dedicated load balancers. It comes with a fix for a TLS bug we encountered with [Metabase](/doc/addons/metabase) instances in some cases. We've also overhauled the custom pages for 4xx and 5xx errors. They now display a better designed and more detailed message. -* Learn more about [Sōzu new releases](https://github.com/sozu-proxy/sozu/releases) {{< icon "github" >}} +- Learn more about [Sōzu new releases](https://github.com/sozu-proxy/sozu/releases) {{< icon "github" >}} diff --git a/content/changelog/2025/01-15-node-22-lts-image-update.md b/content/changelog/2025/01-15-node-22-lts-image-update.md index 4b3122e77..8c4d23739 100644 --- a/content/changelog/2025/01-15-node-22-lts-image-update.md +++ b/content/changelog/2025/01-15-node-22-lts-image-update.md @@ -18,7 +18,7 @@ We deployed an updated Node.js image with no impact for our users. It uses `22.1 It's the first image to include the [Mise package manager](https://mise.jdx.dev/), allowing you to install and manage many developer tools, environment variables, secrets, aliases, tasks, hooks through commands or a configuration file. It's compatible with [asdf ecosystem](https://mise.jdx.dev/dev-tools/comparison-to-asdf.html). -* Learn more about [Mise](https://mise.jdx.dev/) +- Learn more about [Mise](https://mise.jdx.dev/) ## Redirection.io easy setup diff --git a/content/changelog/2025/02-05-mysql-update.md b/content/changelog/2025/02-05-mysql-update.md index bad195d46..23ed49d37 100644 --- a/content/changelog/2025/02-05-mysql-update.md +++ b/content/changelog/2025/02-05-mysql-update.md @@ -14,5 +14,5 @@ excludeSearch: true We updated MySQL images for releases 8.4 (8.4.2-2) and 8.0 (8.0.39-30). A new option is available at database creation from Clever Tools: [skip-log-bin](https://dev.mysql.com/doc/refman/8.4/en/replication-options-binary-log.html#option_mysqld_log-bin). To use it, add `--option skip-log-bin` flag with the `clever create addon mysql-addon` command. -* [Learn more about MySQL 8.4](https://www.percona.com/blog/mysql-8-4-first-peek/) -* [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) +- [Learn more about MySQL 8.4](https://www.percona.com/blog/mysql-8-4-first-peek/) +- [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) diff --git a/content/changelog/2025/02-10-github-action-2.0.md b/content/changelog/2025/02-10-github-action-2.0.md index ee557b4f8..9717c2690 100644 --- a/content/changelog/2025/02-10-github-action-2.0.md +++ b/content/changelog/2025/02-10-github-action-2.0.md @@ -17,4 +17,4 @@ excludeSearch: true Update for [GitHub Action](https://github.com/marketplace/actions/clever-cloud-review-app-on-prs) to deploy applications from GitHub to Clever Cloud. Version 2.0 brings an improved interface for the comment section on deployments, as well as updated security practices in names and docs. -- [Learn more about how to deploy from GitHub to Clever Cloud](/doc/ci-cd/github/) \ No newline at end of file +- [Learn more about how to deploy from GitHub to Clever Cloud](/doc/ci-cd/github/) diff --git a/content/changelog/2025/02-12-php-8.4-update.md b/content/changelog/2025/02-12-php-8.4-update.md index 8d37e147a..2fd2c3b0e 100644 --- a/content/changelog/2025/02-12-php-8.4-update.md +++ b/content/changelog/2025/02-12-php-8.4-update.md @@ -14,14 +14,14 @@ excludeSearch: true We deployed an updated PHP image with no impact for our users. - * PHP 8.4.3 - * Composer 2.8.5 - * Symfony CLI 5.10.7 - * Linux kernel 6.12.9 +- PHP 8.4.3 +- Composer 2.8.5 +- Symfony CLI 5.10.7 +- Linux kernel 6.12.9 You can now use `8.4` as `CC_PHP_VERSION` environment variable, `8.3` is still the default for now. Only some extensions support PHP 8.4 for now: apcu, amqp, blackfire, event, elastic-apm, gnupg, grpc, imap, mailparse, maxminddb, memcache, memcached, mongodb, newrelic, oauth, pdflib, protobuf pspell, rdkafka, redis, ssh2, solr, tideways, uploadprogress, zip. We'll add support for more extensions as they are released. -* [PHP migration guide from 8.3 to 8.4](https://www.php.net/migration84) -* [Learn more about PHP on Clever Cloud](/doc/applications/php/) +- [PHP migration guide from 8.3 to 8.4](https://www.php.net/migration84) +- [Learn more about PHP on Clever Cloud](/doc/applications/php/) diff --git a/content/changelog/2025/02-19-terraform-0.6-redis.md b/content/changelog/2025/02-19-terraform-0.6-redis.md index c625f53c0..dcbc0b168 100644 --- a/content/changelog/2025/02-19-terraform-0.6-redis.md +++ b/content/changelog/2025/02-19-terraform-0.6-redis.md @@ -17,4 +17,4 @@ excludeSearch: true You can now deploy [Redis®](/doc/addons/redis) add-ons using our Terraform provider, compatible with OpenTofu. The [0.6.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v0.6.0) of the Clever Cloud Terraform provider also introduce the resource update. You can now apply a new plan without destroying and recreating the resource starting with PHP applications. -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/02-20-logs-interface-old-decomission.md b/content/changelog/2025/02-20-logs-interface-old-decomission.md index 094bbb2f6..3b2ed6c34 100644 --- a/content/changelog/2025/02-20-logs-interface-old-decomission.md +++ b/content/changelog/2025/02-20-logs-interface-old-decomission.md @@ -19,4 +19,4 @@ excludeSearch: true Next, we'll use the new stack for add-ons, access logs and continue improving the interface. A big step will be to introduce logs indexing, allowing you to better search through your logs and load the latest. -Feel free to ask for features and improvements in our [GitHub Community space](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface). \ No newline at end of file +Feel free to ask for features and improvements in our [GitHub Community space](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface). diff --git a/content/changelog/2025/03-03-images-update.md b/content/changelog/2025/03-03-images-update.md index ae5203039..580082275 100644 --- a/content/changelog/2025/03-03-images-update.md +++ b/content/changelog/2025/03-03-images-update.md @@ -14,24 +14,24 @@ excludeSearch: true We deployed and updated all our images, except Docker, Go, Java, Node and Ruby, with no impact for our users. -* **Common:** - * Linux kernel 6.13.5 -* **.NET:** - * Update to 8.0.108 -* **Elixir:** - * Update to 1.18.2 - * Erlang 27.2.2 -* **Haskell:** - * Stack 2.15.7 -* **PHP:** - * Update to 8.4.4 - * Composer 2.8.6 - * `CC_APACHE_HEADERS_SIZE` [environment variable](/doc/reference/reference-environment-variables/) -* **Python:** - * Update to 3.13.2 - * pip 24.3.1 - * uv 0.6.3 -* **Rust:** - * Update to 1.85.0 +- **Common:** + - Linux kernel 6.13.5 +- **.NET:** + - Update to 8.0.108 +- **Elixir:** + - Update to 1.18.2 + - Erlang 27.2.2 +- **Haskell:** + - Stack 2.15.7 +- **PHP:** + - Update to 8.4.4 + - Composer 2.8.6 + - `CC_APACHE_HEADERS_SIZE` [environment variable](/doc/reference/reference-environment-variables/) +- **Python:** + - Update to 3.13.2 + - pip 24.3.1 + - uv 0.6.3 +- **Rust:** + - Update to 1.85.0 All these images include [Mise and Redirection.io easy setup](/changelog/2025/01-15-node-22-lts-image-update/). diff --git a/content/changelog/2025/03-07-clever-tools-3.12.md b/content/changelog/2025/03-07-clever-tools-3.12.md index 0f7fca1e9..6e5bb2ace 100644 --- a/content/changelog/2025/03-07-clever-tools-3.12.md +++ b/content/changelog/2025/03-07-clever-tools-3.12.md @@ -18,6 +18,7 @@ excludeSearch: true [Clever Tools 3.12](https://github.com/CleverCloud/clever-tools/releases/tag/3.12.0) is available. It includes some bug fixes and two new experimental features, available through feature flags. ## API Tokens + First is `clever tokens`, which allows you to create and manage API tokens, and use them to request the Clever Cloud API: ```bash @@ -26,6 +27,7 @@ clever features enable tokens clever tokens create "CI job Foobar" clever tokens create "Quick local test" --expiration 1h ``` + You can also list or revoke tokens: ```bash @@ -38,6 +40,7 @@ Once created, API tokens must be used through the bridge URL: ```bash curl https://api-bridge.clever-cloud.com/v2/self -H "Authorization: Bearer [API_TOKEN]" ``` + - [Clever Cloud API Documentation](/api) - [Give your feedback about API Tokens](https://github.com/CleverCloud/Community/discussions/categories/api-tokens) @@ -97,9 +100,10 @@ As this beta feature evolves, we'll add demos, documentations and videos to help - [Give your feedback about Network Groups](https://github.com/CleverCloud/Community/discussions/categories/network-groups) ## How to upgrade + To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2025/03-12-images-update.md b/content/changelog/2025/03-12-images-update.md index de3169d5f..dd19c54fe 100644 --- a/content/changelog/2025/03-12-images-update.md +++ b/content/changelog/2025/03-12-images-update.md @@ -14,17 +14,17 @@ excludeSearch: true We deployed and updated all our images, except Java and Ruby, with no impact for our users. -* **Common:** - * Linux kernel 6.13.6 -* **Docker:** - * Update to 28.0.1 -* **Elixir:** - * Update to 1.18.3 - * Erlang 27.3 -* **Go:** - * Update to 1.24.1 -* **Node.js:** - * Update to 22.14.0 -* **Python:** - * pip 25.0.1 - * uv 0.6.4 +- **Common:** + - Linux kernel 6.13.6 +- **Docker:** + - Update to 28.0.1 +- **Elixir:** + - Update to 1.18.3 + - Erlang 27.3 +- **Go:** + - Update to 1.24.1 +- **Node.js:** + - Update to 22.14.0 +- **Python:** + - pip 25.0.1 + - uv 0.6.4 diff --git a/content/changelog/2025/03-12-materia-kv-json.md b/content/changelog/2025/03-12-materia-kv-json.md index 1c88e1dff..904ff81fd 100644 --- a/content/changelog/2025/03-12-materia-kv-json.md +++ b/content/changelog/2025/03-12-materia-kv-json.md @@ -16,6 +16,7 @@ excludeSearch: true --- Materia KV now supports some `JSON` commands : + - `JSON.SET`: sets JSON value at path in key - `JSON.GET`: gets JSON value at path from key - `JSON.DEL`: deletes JSON value at path from key diff --git a/content/changelog/2025/03-18-images-update-ruby-unified.md b/content/changelog/2025/03-18-images-update-ruby-unified.md index a562da904..1d21625a4 100644 --- a/content/changelog/2025/03-18-images-update-ruby-unified.md +++ b/content/changelog/2025/03-18-images-update-ruby-unified.md @@ -14,17 +14,17 @@ excludeSearch: true We deployed and updated all our images, except Java, with no impact for our users. It now includes Ruby as part as our new unified image stack. -* **Common:** - * Linux kernel 6.13.7 -* **PHP:** - * Update to 8.4.5 - * Apache 2.4.63 -* **Python:** - * uv 0.6.6 - * nginx 1.26.3 -* **Ruby:** - * Update to 3.4.2 - * Bundler 2.6.5 - * nginx 1.26.3 +- **Common:** + - Linux kernel 6.13.7 +- **PHP:** + - Update to 8.4.5 + - Apache 2.4.63 +- **Python:** + - uv 0.6.6 + - nginx 1.26.3 +- **Ruby:** + - Update to 3.4.2 + - Bundler 2.6.5 + - nginx 1.26.3 Note that Ruby 3.4 is the default only in Ruby applications. Ruby 3.2 is still default on other runtimes, use [rbenv](https://github.com/rbenv/rbenv) and `RBENV_VERSION` to switch to Ruby 3.4 for now. diff --git a/content/changelog/2025/03-18-mysql-update.md b/content/changelog/2025/03-18-mysql-update.md index 4de4fe4f8..3693d7a89 100644 --- a/content/changelog/2025/03-18-mysql-update.md +++ b/content/changelog/2025/03-18-mysql-update.md @@ -14,6 +14,6 @@ excludeSearch: true We updated MySQL images 8.0 and 8.4 from Percona Server. They're now available for add-ons creation and migration. -* [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) -* [Learn more about MySQL 8.0.41-32](https://docs.percona.com/percona-server/8.0/release-notes/8.0.41-32.html) -* [Learn more about MySQL 8.4.3-3](https://docs.percona.com/percona-server/8.4/release-notes/8.4.3-3.html) +- [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) +- [Learn more about MySQL 8.0.41-32](https://docs.percona.com/percona-server/8.0/release-notes/8.0.41-32.html) +- [Learn more about MySQL 8.4.3-3](https://docs.percona.com/percona-server/8.4/release-notes/8.4.3-3.html) diff --git a/content/changelog/2025/03-18-postgresql-16-17.md b/content/changelog/2025/03-18-postgresql-16-17.md index c76eb2bae..c8d200435 100644 --- a/content/changelog/2025/03-18-postgresql-16-17.md +++ b/content/changelog/2025/03-18-postgresql-16-17.md @@ -16,5 +16,5 @@ PostgreSQL 16.8 and 17.4 are now available for add-on creation and migration. So We also updated PostgreSQL 15 to release 15.12, PostgreSQL 14 to release 14.17, PostgreSQL 13 to release 13.20. Migrate your database to the desired major version to get the latest release. -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) -* [PostgreSQL release notes](https://www.postgresql.org/docs/release/) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [PostgreSQL release notes](https://www.postgresql.org/docs/release/) diff --git a/content/changelog/2025/03-19-paris-hds.md b/content/changelog/2025/03-19-paris-hds.md index 5de69976b..31355c410 100644 --- a/content/changelog/2025/03-19-paris-hds.md +++ b/content/changelog/2025/03-19-paris-hds.md @@ -14,5 +14,5 @@ excludeSearch: true Clever Cloud is HDS-certified for [all six activities](https://www.clever.cloud/fr/hebergement-donnees-de-sante/) and you can now deploy on `parhds` zone from the [API](/api/), [Clever Tools](/doc/cli/) or the [Console](https://console.clever-cloud.com). To benefit from certified hosting for health data, you need to deploy in an HDS zone and to sign up to a specific contract. This begins with [an initial discussion with our team](https://www.clever.cloud/fr/hebergement-donnees-de-sante/contact-hds/). -* [Learn more about Clever Cloud HDS certification](https://www.clever.cloud/fr/hebergement-donnees-de-sante/) -* [Learn more about HDS hosting on Clever Cloud](https://www.clever.cloud/fr/blog/entreprise/2025/03/19/cloud-hds-avec-clever-cloud/) +- [Learn more about Clever Cloud HDS certification](https://www.clever.cloud/fr/hebergement-donnees-de-sante/) +- [Learn more about HDS hosting on Clever Cloud](https://www.clever.cloud/fr/blog/entreprise/2025/03/19/cloud-hds-avec-clever-cloud/) diff --git a/content/changelog/2025/03-19-terraform-0.7-resources-update.md b/content/changelog/2025/03-19-terraform-0.7-resources-update.md index 4b30de072..bb7073d15 100644 --- a/content/changelog/2025/03-19-terraform-0.7-resources-update.md +++ b/content/changelog/2025/03-19-terraform-0.7-resources-update.md @@ -17,4 +17,4 @@ excludeSearch: true With [0.6.0 release](/changelog/2025/02-19-terraform-0.6-redis/) of the Clever Cloud Terraform provider (compatible with OpenTofu), we introduced the support of resource update. Starting with [0.7.0](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v0.7.0) you can now apply a new plan without destroying and recreating the resource on Docker, Java, Python, Scala and Static applications. -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/03-21-php-version-management-update.md b/content/changelog/2025/03-21-php-version-management-update.md index df231b069..7a4931824 100644 --- a/content/changelog/2025/03-21-php-version-management-update.md +++ b/content/changelog/2025/03-21-php-version-management-update.md @@ -16,9 +16,9 @@ Starting today, PHP applications on Clever Cloud are created with `CC_PHP_VERSIO Starting april 30th, the default minor PHP version for branch `8` will move from `8.3` to `8.4`, released last November. If you need to keep using PHP 8.3, just set `CC_PHP_VERSION=8.3` in your environment variables from the Console or with Clever Tools: -``` +```bash clever env set CC_PHP_VERSION 8.3 --app ``` -* [Learn more about PHP on Clever Cloud](/doc/applications/php/) -* [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) +- [Learn more about PHP on Clever Cloud](/doc/applications/php/) +- [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) diff --git a/content/changelog/2025/03-24-postgresql-11-12-eol.md b/content/changelog/2025/03-24-postgresql-11-12-eol.md index cb27065ed..7ac50adcc 100644 --- a/content/changelog/2025/03-24-postgresql-11-12-eol.md +++ b/content/changelog/2025/03-24-postgresql-11-12-eol.md @@ -13,10 +13,11 @@ excludeSearch: true --- As [PostgreSQL 16 and 17 are now available](/changelog/2025/03-18-postgresql-16-17/) on Clever Cloud, we'll start to limit access to end-of-life releases: PostgreSQL 11 and 12. **Starting April 30th**, you won't be able to create new PostgreSQL 11 or 12 add-ons. Note that: -* PG11/12 databases deployed before April 30th will still be available after this deadline -* Customers will still be able to manage their existing PG11/12 databases after this deadline + +- PG11/12 databases deployed before April 30th will still be available after this deadline +- Customers will still be able to manage their existing PG11/12 databases after this deadline But **we recommend you to migrate to an actively supported version**. You can do it easily using our included migration tool in your add-on parameters. In the coming weeks, you'll start to see warnings in [the Console](https://console.clever-cloud.com) if you are still using PostgreSQL 12 or a lower version. -* [PostgreSQL versioning policy](https://www.postgresql.org/support/versioning/) -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [PostgreSQL versioning policy](https://www.postgresql.org/support/versioning/) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) diff --git a/content/changelog/2025/03-25-python-3.8-eol.md b/content/changelog/2025/03-25-python-3.8-eol.md index c33c50141..29231aad0 100644 --- a/content/changelog/2025/03-25-python-3.8-eol.md +++ b/content/changelog/2025/03-25-python-3.8-eol.md @@ -18,5 +18,5 @@ To upgrade to a more recent version of Python, you only need to update `CC_PYTHO If you need to keep Python 3.8 for legacy reasons, you can [use uv](https://docs.astral.sh/uv/guides/install-python/#installing-a-specific-version) or [Mise](https://mise.jdx.dev/lang/python.html) which are available in all our recently updated images. -* [Learn more about Python on Clever Cloud](/doc/applications/python/) -* [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) +- [Learn more about Python on Clever Cloud](/doc/applications/python/) +- [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) diff --git a/content/changelog/2025/03-27-postgresql-default.md b/content/changelog/2025/03-27-postgresql-default.md index 0eded7e71..b6563b0ee 100644 --- a/content/changelog/2025/03-27-postgresql-default.md +++ b/content/changelog/2025/03-27-postgresql-default.md @@ -14,5 +14,5 @@ excludeSearch: true As [PostgreSQL 16 and 17 are available](/changelog/2025/03-18-postgresql-16-17/) on Clever Cloud, we start using PostgreSQL 17 as the default version for new add-ons. **Starting today**, when you create a new PostgreSQL database, it will be setup with PostgreSQL 17. -* [PostgreSQL versioning policy](https://www.postgresql.org/support/versioning/) -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [PostgreSQL versioning policy](https://www.postgresql.org/support/versioning/) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) diff --git a/content/changelog/2025/03-28-frankenphp-runtime.md b/content/changelog/2025/03-28-frankenphp-runtime.md index 4394bc39c..9669914ac 100644 --- a/content/changelog/2025/03-28-frankenphp-runtime.md +++ b/content/changelog/2025/03-28-frankenphp-runtime.md @@ -33,6 +33,6 @@ FrankenPHP on Clever Cloud comes with [lots of extensions](/doc/applications/fra As it's a new image, help us improve it by reporting any issue or suggestion on the [Clever Cloud Community](https://github.com/CleverCloud/Community/discussions/categories/frankenphp). -* [FrankenPHP and Materia KV example](https://github.com/CleverCloud/frankenphp-kv-json-example) -* [Learn more about FrankenPHP on Clever Cloud](/doc/applications/frankenphp/) -* [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) +- [FrankenPHP and Materia KV example](https://github.com/CleverCloud/frankenphp-kv-json-example) +- [Learn more about FrankenPHP on Clever Cloud](/doc/applications/frankenphp/) +- [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) diff --git a/content/changelog/2025/04-01-images-update.md b/content/changelog/2025/04-01-images-update.md index 19bac28e9..be392e828 100644 --- a/content/changelog/2025/04-01-images-update.md +++ b/content/changelog/2025/04-01-images-update.md @@ -14,10 +14,10 @@ excludeSearch: true We deployed and updated all our images, except Docker and Java, with no impact for our users. -* **Common:** - * Linux kernel 6.13.8 - * Mise 2025.3.11 -* **Python:** - * uv 0.6.11 -* **Rust:** - * Update to 1.85.1 +- **Common:** + - Linux kernel 6.13.8 + - Mise 2025.3.11 +- **Python:** + - uv 0.6.11 +- **Rust:** + - Update to 1.85.1 diff --git a/content/changelog/2025/04-02-postgresql-replicas.md b/content/changelog/2025/04-02-postgresql-replicas.md index ca8ba8fa0..4df8ea6bd 100644 --- a/content/changelog/2025/04-02-postgresql-replicas.md +++ b/content/changelog/2025/04-02-postgresql-replicas.md @@ -16,5 +16,5 @@ PostgreSQL dashboard in [the Clever Cloud Console](https://console.clever-cloud. To set up replicas, ask your sales representative or [contact support](https://console.clever-cloud.com/ticket-center-choice). -* [Learn more about PostgreSQL replication](/doc/addons/postgresql#replication) -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [Learn more about PostgreSQL replication](/doc/addons/postgresql#replication) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) diff --git a/content/changelog/2025/04-03-images-update.md b/content/changelog/2025/04-03-images-update.md index f41cfcc35..5ac40c300 100644 --- a/content/changelog/2025/04-03-images-update.md +++ b/content/changelog/2025/04-03-images-update.md @@ -14,13 +14,13 @@ excludeSearch: true We deployed and updated all our images, with no impact for our users. -* **Common:** - * Fix an issue with scaling feature - * Linux kernel 6.13.9 - * Mise 2025.3.11 - * Tailscale 1.82.0 -* **Go:** - * Update to 1.24.2 +- **Common:** + - Fix an issue with scaling feature + - Linux kernel 6.13.9 + - Mise 2025.3.11 + - Tailscale 1.82.0 +- **Go:** + - Update to 1.24.2 SQL Server extensions (`sqlsrv` and `pdo_sqlsrv`) are now available for PHP 8.1 to 8.4. To enable them, add `ENABLE_SQLSRV=true` or `ENABLE_PDO_SQLSRV=true` environment variables to your application. diff --git a/content/changelog/2025/04-04-postgresql-locale.md b/content/changelog/2025/04-04-postgresql-locale.md index e632b839e..12f5cfe3e 100644 --- a/content/changelog/2025/04-04-postgresql-locale.md +++ b/content/changelog/2025/04-04-postgresql-locale.md @@ -20,5 +20,5 @@ clever addon create postgresql-addon pgLocaleTest --plan xxs_sml --option locale This will create a PostgreSQL database with the `en_US` locale instead of the default `en_GB` locale. -* [PostgreSQL versioning policy](https://www.postgresql.org/support/versioning/) -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [PostgreSQL versioning policy](https://www.postgresql.org/support/versioning/) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) diff --git a/content/changelog/2025/04-10-mysql-8.4.4-update.md b/content/changelog/2025/04-10-mysql-8.4.4-update.md index 4cfba047d..285bced84 100644 --- a/content/changelog/2025/04-10-mysql-8.4.4-update.md +++ b/content/changelog/2025/04-10-mysql-8.4.4-update.md @@ -14,5 +14,5 @@ excludeSearch: true We updated MySQL 8.4 from Percona Server. They're now available for add-ons creation and migration. -* [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) -* [Learn more about MySQL 8.4.4-4](https://docs.percona.com/percona-server/8.4/release-notes/8.4.4-4.html) +- [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) +- [Learn more about MySQL 8.4.4-4](https://docs.percona.com/percona-server/8.4/release-notes/8.4.4-4.html) diff --git a/content/changelog/2025/04-16-images-update.md b/content/changelog/2025/04-16-images-update.md index a43eb4c71..17d938cf6 100644 --- a/content/changelog/2025/04-16-images-update.md +++ b/content/changelog/2025/04-16-images-update.md @@ -14,21 +14,21 @@ excludeSearch: true We updated all our images, except Java. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.14.2 - * Mise 2025.4.2 - * OpenSSH 10.0p2 - * OpenSSL 3.5.0 - * Tailscale 1.82.0 -* **Node.js:** - * Bun 1.2.9 -* **PHP:** - * Update to 8.4.6 - * Composer 2.8.8 -* **Python:** - * Update to 3.13.3 - * uv 0.6.14 -* **Rust:** - * Update to 1.86.0 +- **Common:** + - Linux kernel 6.14.2 + - Mise 2025.4.2 + - OpenSSH 10.0p2 + - OpenSSL 3.5.0 + - Tailscale 1.82.0 +- **Node.js:** + - Bun 1.2.9 +- **PHP:** + - Update to 8.4.6 + - Composer 2.8.8 +- **Python:** + - Update to 3.13.3 + - uv 0.6.14 +- **Rust:** + - Update to 1.86.0 Bun is now part of our included tools, and will be natively supported in an upcoming release of our Node.js runtime. diff --git a/content/changelog/2025/04-24-keycloak-26.2.1-grafana.md b/content/changelog/2025/04-24-keycloak-26.2.1-grafana.md index 709277f1e..4725e7db9 100644 --- a/content/changelog/2025/04-24-keycloak-26.2.1-grafana.md +++ b/content/changelog/2025/04-24-keycloak-26.2.1-grafana.md @@ -20,6 +20,7 @@ The release `26.2.1` of Keycloak is available on Clever Cloud. [This new branch ## Grafana dashboard Each Clever Cloud account organisation [comes with a pre-configured Grafana service](/doc/metrics/#publish-your-own-metrics). With recent Keycloak enhancements on metrics and observability, we've worked on a Grafana dashboard ready to import: + - Go to the `Metrics in Grafana` section of your organisation or personal space in [Console](https://console.clever-cloud.com/) - Open Grafana, click on the `+` icon in the upper right corner and select `Import` dashboard - Import this [JSON file](https://cc-keycloak.cellar-c2.services.clever-cloud.com/keycloak-grafana-dashboard.json) diff --git a/content/changelog/2025/05-06-images-update.md b/content/changelog/2025/05-06-images-update.md index 52e08baac..7d36ff44c 100644 --- a/content/changelog/2025/05-06-images-update.md +++ b/content/changelog/2025/05-06-images-update.md @@ -14,17 +14,17 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.14.4 - * Mise 2025.5.0 - * Redis 8.0.0 - * Tailscale 1.82.5 -* **Go:** - * Update to 1.24.2 -* **Node.js:** - * Update to 22.15 (npm 10.9.2) -* **Python:** - * uv 0.7.2 +- **Common:** + - Linux kernel 6.14.4 + - Mise 2025.5.0 + - Redis 8.0.0 + - Tailscale 1.82.5 +- **Go:** + - Update to 1.24.2 +- **Node.js:** + - Update to 22.15 (npm 10.9.2) +- **Python:** + - uv 0.7.2 As previously announced, Python 3.8 [is not available in our images anymore](/changelog/2025/03-25-python-3.8-eol/) and PHP 8.4 [is now used as default](/changelog/2025/03-21-php-version-management-update/) for `CC_PHP_VERSION=8`. As Node.js 18 and Ruby 3.1 are now end-of-life, you'll get a warning if you use them. diff --git a/content/changelog/2025/05-07-node-24.md b/content/changelog/2025/05-07-node-24.md index 2e106d832..4d4a20513 100644 --- a/content/changelog/2025/05-07-node-24.md +++ b/content/changelog/2025/05-07-node-24.md @@ -13,6 +13,7 @@ excludeSearch: true --- 2025 is an important year for Node.js ecosystem with big changes for multiple branches: + - 18.x LTS is end-of-life since April 30th and won't receive any new security updates - 20.x LTS is in maintenance mode and will receive security updates until April 30th, 2026 - 22.x LTS, will enter maintenance mode in October and will receive security updates until April 30th, 2027 @@ -21,6 +22,6 @@ excludeSearch: true In Clever Cloud runtimes, we use the latest LTS version by default. Thus, it's currently 22.x, and we'll move to 24.x in October. Until then you can use 24.x branch by setting the `CC_NODE_VERSION` environment variable to `^24`, `24` or `24.0`, for example: -* [Learn more about Node.js release cycle](https://nodejs.org/en/about/releases/) -* [Learn more about Node.js on Clever Cloud](/doc/applications/nodejs/) -* [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) +- [Learn more about Node.js release cycle](https://nodejs.org/en/about/releases/) +- [Learn more about Node.js on Clever Cloud](/doc/applications/nodejs/) +- [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/) diff --git a/content/changelog/2025/05-13-images-update.md b/content/changelog/2025/05-13-images-update.md index 984d081b9..f7a3e8257 100644 --- a/content/changelog/2025/05-13-images-update.md +++ b/content/changelog/2025/05-13-images-update.md @@ -14,18 +14,18 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.14.6 -* **Docker:** - * Update to 28.11.1 -* **Elixir** - * Erlang 25.3.2.21 - * Erlang 26.2.5.12 - * Erlang 27.3.4 -* **Go:** - * Update to 1.24.3 -* **PHP:** - * Update to 8.3.21 - * Update to 8.4.7 -* **Python:** - * uv 0.7.3 +- **Common:** + - Linux kernel 6.14.6 +- **Docker:** + - Update to 28.11.1 +- **Elixir** + - Erlang 25.3.2.21 + - Erlang 26.2.5.12 + - Erlang 27.3.4 +- **Go:** + - Update to 1.24.3 +- **PHP:** + - Update to 8.3.21 + - Update to 8.4.7 +- **Python:** + - uv 0.7.3 diff --git a/content/changelog/2025/05-16-images-update.md b/content/changelog/2025/05-16-images-update.md index 0f9241182..feff6ff25 100644 --- a/content/changelog/2025/05-16-images-update.md +++ b/content/changelog/2025/05-16-images-update.md @@ -14,23 +14,23 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.14.6 with stability fix - * Mise 2025.5.3 - * Redis 8.0.1 - * SQLite 3.49.2 -* **Node.js:** - * Update to 22.15.1 (npm 10.9.2) - * Bun 1.2.9 -* **PHP:** - * Composer 2.8.9 -* **Ruby:** - * Update to 3.1.7 - * Update to 3.2.8 - * Update to 3.3.8 - * Update to 3.4.3 -* **Rust:** - * Update to 1.87.0 +- **Common:** + - Linux kernel 6.14.6 with stability fix + - Mise 2025.5.3 + - Redis 8.0.1 + - SQLite 3.49.2 +- **Node.js:** + - Update to 22.15.1 (npm 10.9.2) + - Bun 1.2.9 +- **PHP:** + - Composer 2.8.9 +- **Ruby:** + - Update to 3.1.7 + - Update to 3.2.8 + - Update to 3.3.8 + - Update to 3.4.3 +- **Rust:** + - Update to 1.87.0 This release introduces `CC_NODE_VERSION` support [for Node.js applications](/changelog/2025/05-16-node-versions/). When an application is restarted for image update, it won't appear as `Maintenance` anymore, but as `Maintenance/ImageUpdate` diff --git a/content/changelog/2025/05-16-terraform-0.8.md b/content/changelog/2025/05-16-terraform-0.8.md index 8e6411352..3838ddeb9 100644 --- a/content/changelog/2025/05-16-terraform-0.8.md +++ b/content/changelog/2025/05-16-terraform-0.8.md @@ -17,4 +17,4 @@ excludeSearch: true The [0.8.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v0.8.0) of the Clever Cloud Terraform provider introduces support for [FS Buckets](/doc/addons/fs-bucket/) and update for [Cellar add-ons](/doc/addons/cellar/) -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/05-20-pg-update-17.5.md b/content/changelog/2025/05-20-pg-update-17.5.md index 92b5aa2fc..3e8c0b7f2 100644 --- a/content/changelog/2025/05-20-pg-update-17.5.md +++ b/content/changelog/2025/05-20-pg-update-17.5.md @@ -13,12 +13,13 @@ excludeSearch: true --- New PostgreSQL versions are available for new add-ons and migration: -* PostgreSQL 17.5 -* PostgreSQL 16.9 -* PostgreSQL 15.13 -* PostgreSQL 14.18 -* PostgreSQL 13.21 + +- PostgreSQL 17.5 +- PostgreSQL 16.9 +- PostgreSQL 15.13 +- PostgreSQL 14.18 +- PostgreSQL 13.21 It includes [fixes and improvements](https://www.postgresql.org/about/news/postgresql-175-169-1513-1418-and-1321-released-3072/), including a security patch for [CVE-2025-4207](https://nvd.nist.gov/vuln/detail/CVE-2025-4207). -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) diff --git a/content/changelog/2025/06-03-images-update.md b/content/changelog/2025/06-03-images-update.md index 80e969bc0..8b71a335f 100644 --- a/content/changelog/2025/06-03-images-update.md +++ b/content/changelog/2025/06-03-images-update.md @@ -14,32 +14,34 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.14.9 - * Mise 2025.5.17 - * Redis 8.0.2 - * SQLite 3.50.0 -* **Elixir:** - * Update to 1.18.4 - * Erlang 28.0 -* **FrankenPHP:** - * Update to 1.6.2 -* **Go:** - * Update to 1.24.3 -* **Node.js:** - * Update to 22.16.0 (npm 10.9.2) - * Bun 1.2.15 -* **Python:** - * uv 0.7.9 -* **Ruby:** - * Update to 3.4.4 +- **Common:** + - Linux kernel 6.14.9 + - Mise 2025.5.17 + - Redis 8.0.2 + - SQLite 3.50.0 +- **Elixir:** + - Update to 1.18.4 + - Erlang 28.0 +- **FrankenPHP:** + - Update to 1.6.2 +- **Go:** + - Update to 1.24.3 +- **Node.js:** + - Update to 22.16.0 (npm 10.9.2) + - Bun 1.2.15 +- **Python:** + - uv 0.7.9 +- **Ruby:** + - Update to 3.4.4 ## Bun native support + This release introduces [Bun](https://bun.sh) native support on Clever Cloud, with auto-detection of `bun.lock` file. - [Learn more about Bun support on Clever Cloud](/changelog/2025/06-03-native-bun-support/) ## FrankenPHP custom port + You can also set `CC_FRANKENPHP_PORT` to use a different port than the default `8080`. It allows you to use services in front of your FrankenPHP application such as [Redirection.io](/doc/reference/reference-environment-variables/#use-redirectionio-as-a-proxy) for example. - [Learn more about FrankenPHP on Clever Cloud](/doc/applications/frankenphp/) diff --git a/content/changelog/2025/06-03-native-bun-support.md b/content/changelog/2025/06-03-native-bun-support.md index 4e13868ac..12655026e 100644 --- a/content/changelog/2025/06-03-native-bun-support.md +++ b/content/changelog/2025/06-03-native-bun-support.md @@ -18,7 +18,7 @@ If a `bun.lock` file is detected at the root of your project, and you didn't ask Want to give it a try? Just launch these commands with Bun and [Clever Tools CLI](/doc/cli/install) installed on your system: -``` +```bash mkdir bunDemo cd bunDemo @@ -35,4 +35,4 @@ clever open You'll get a basic React application running on Bun, deployed on Clever Cloud. -* [Learn more about Bun & Node.js on Clever Cloud](/doc/applications/nodejs) +- [Learn more about Bun & Node.js on Clever Cloud](/doc/applications/nodejs) diff --git a/content/changelog/2025/06-03-terraform-0.9.md b/content/changelog/2025/06-03-terraform-0.9.md index 1be536d9e..4e662f3ab 100644 --- a/content/changelog/2025/06-03-terraform-0.9.md +++ b/content/changelog/2025/06-03-terraform-0.9.md @@ -17,4 +17,4 @@ excludeSearch: true The [0.9.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v0.9.0) of the Clever Cloud Terraform provider introduces support for `play2` applications and git local repositories. Starting with this release, if you change an application environment variable, it will be restarted automatically. -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/06-04-otoroshi-17.3.md b/content/changelog/2025/06-04-otoroshi-17.3.md index 8fd608e1a..8660731cf 100644 --- a/content/changelog/2025/06-04-otoroshi-17.3.md +++ b/content/changelog/2025/06-04-otoroshi-17.3.md @@ -31,4 +31,3 @@ clever otoroshi version update yourOtoroshiNameOrId v17.3.1_1749049547 - [Learn more about Otoroshi Workflows](https://maif.github.io/otoroshi/manual/docs/topics/workflows) - [Learn more about Otoroshi with LLM on Clever Cloud](/doc/addons/otoroshi/) - diff --git a/content/changelog/2025/06-05-api-tokens-console-tips.md b/content/changelog/2025/06-05-api-tokens-console-tips.md index a05534d58..6bc6d22c6 100644 --- a/content/changelog/2025/06-05-api-tokens-console-tips.md +++ b/content/changelog/2025/06-05-api-tokens-console-tips.md @@ -24,7 +24,7 @@ This interface also shows the token name, description, public ID, creation and e To create an API token, you need to provide: - Your current password -- Your 2FA code if active (activate it [here](https://console.clever-cloud.com/users/me/authentication)) +- Your 2FA code if active ([activate 2FA in the Console](https://console.clever-cloud.com/users/me/authentication)) If you created your Clever Cloud account through the GitHub integration, you'll be asked to set a password first. diff --git a/content/changelog/2025/06-05-mysql-8.0.42-8.4.5.md b/content/changelog/2025/06-05-mysql-8.0.42-8.4.5.md index d0a247eb9..79f2575a7 100644 --- a/content/changelog/2025/06-05-mysql-8.0.42-8.4.5.md +++ b/content/changelog/2025/06-05-mysql-8.0.42-8.4.5.md @@ -14,6 +14,6 @@ excludeSearch: true We updated MySQL 8.0 and 8.4 from Percona Server. They're now available for add-ons creation and migration. -* [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) -* [Learn more about MySQL 8.0.42](https://docs.percona.com/percona-server/8.0/release-notes/8.0.42-33.html) -* [Learn more about MySQL 8.4.5](https://docs.percona.com/percona-server/8.4/release-notes/8.4.5-5.html) +- [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) +- [Learn more about MySQL 8.0.42](https://docs.percona.com/percona-server/8.0/release-notes/8.0.42-33.html) +- [Learn more about MySQL 8.4.5](https://docs.percona.com/percona-server/8.4/release-notes/8.4.5-5.html) diff --git a/content/changelog/2025/06-10-clever-tools-3.13.md b/content/changelog/2025/06-10-clever-tools-3.13.md index c9fcfd670..925c5bb1d 100644 --- a/content/changelog/2025/06-10-clever-tools-3.13.md +++ b/content/changelog/2025/06-10-clever-tools-3.13.md @@ -44,7 +44,7 @@ clever otoroshi version update otoroshi_id Manage your Clever Cloud account's emails and public SSH keys with the new `clever emails` and `clever ssh-keys` commands: -``` +```console clever emails clever ssh-keys -F json @@ -62,7 +62,7 @@ clever ssh-keys remove-all You can also use `clever config` to set an application as a [Clever Task](/doc/develop/tasks/) after its creation of get this option configuration: -``` +```console clever config get task clever config set task true clever config set task false @@ -75,7 +75,7 @@ clever config update --name "My new task name" --enable-task To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2025/06-17-images-update.md b/content/changelog/2025/06-17-images-update.md index 7d487c97d..05be345cf 100644 --- a/content/changelog/2025/06-17-images-update.md +++ b/content/changelog/2025/06-17-images-update.md @@ -14,25 +14,25 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.14.11 - * Mise 2025.6.4 -* **Docker:** - * Update to 28.2.2 - * Buildx 0.24.0 -* **FrankenPHP:** - * Update to 1.7.0 (PHP 8.4.8) -* **Go:** - * Update to 1.24.4 -* **Node.js:** - * Bun 1.2.16 -* **Python:** - * Update to 3.13.4 - * Update to 3.12.11 - * Update to 3.11.13 - * Update to 3.10.18 - * Update to 3.9.23 - * uv 0.7.13 +- **Common:** + - Linux kernel 6.14.11 + - Mise 2025.6.4 +- **Docker:** + - Update to 28.2.2 + - Buildx 0.24.0 +- **FrankenPHP:** + - Update to 1.7.0 (PHP 8.4.8) +- **Go:** + - Update to 1.24.4 +- **Node.js:** + - Bun 1.2.16 +- **Python:** + - Update to 3.13.4 + - Update to 3.12.11 + - Update to 3.11.13 + - Update to 3.10.18 + - Update to 3.9.23 + - uv 0.7.13 ## Other changes diff --git a/content/changelog/2025/07-01-images-update.md b/content/changelog/2025/07-01-images-update.md index 8dc2db02b..830356ff1 100644 --- a/content/changelog/2025/07-01-images-update.md +++ b/content/changelog/2025/07-01-images-update.md @@ -14,23 +14,23 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.14.11 - * Mise 2025.6.6 - * SQLite 3.50.1 -* **Docker:** - * Update to 28.3 - * Buildx 0.25.0 -* **Node.js:** - * Update to 22.17.0 - * Bun 1.2.17 -* **Python:** - * Update to 3.13.5 - * uv 0.7.17 -* **Rust:** - * Update to 1.88.0 -* **V:** - * Update to 0.4.11 +- **Common:** + - Linux kernel 6.14.11 + - Mise 2025.6.6 + - SQLite 3.50.1 +- **Docker:** + - Update to 28.3 + - Buildx 0.25.0 +- **Node.js:** + - Update to 22.17.0 + - Bun 1.2.17 +- **Python:** + - Update to 3.13.5 + - uv 0.7.17 +- **Rust:** + - Update to 1.88.0 +- **V:** + - Update to 0.4.11 ## Linux, Static and V runtimes diff --git a/content/changelog/2025/07-02-terraform-0.10.md b/content/changelog/2025/07-02-terraform-0.10.md index 6165a8b2b..4685b2168 100644 --- a/content/changelog/2025/07-02-terraform-0.10.md +++ b/content/changelog/2025/07-02-terraform-0.10.md @@ -17,4 +17,4 @@ excludeSearch: true The [0.10.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v0.10.0) of the Clever Cloud Terraform provider is available. It fixes some bugs, introduces support for [Network Groups](/doc/develop/network-groups/) and [Pulsar](/doc/addons/pulsar/). You can set a version for a [PostgreSQL add-on](/doc/addons/postgresql/). -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/07-04-linux-static-v-runtimes.md b/content/changelog/2025/07-04-linux-static-v-runtimes.md index 75ea11349..15008cf32 100644 --- a/content/changelog/2025/07-04-linux-static-v-runtimes.md +++ b/content/changelog/2025/07-04-linux-static-v-runtimes.md @@ -15,12 +15,13 @@ excludeSearch: true --- You can now deploy your applications using the new `linux`, `static` and `v` runtimes on Clever Cloud: + - `linux` is a general purpose runtime that supports any language, and fully takes advantage of the [Mise package manager](https://mise.jdx.dev/) - `static` is a lightweight runtime for static sites, with auto-build for many static site generators (SSG) - `v` is a runtime for applications written in the [V programming language](https://vlang.io/) As they are new runtimes, help us improve it by reporting any issue or suggestion on the [Clever Cloud Community](https://github.com/CleverCloud/Community/discussions/categories/paas-runtimes). -* [Learn more about the Linux runtime](/doc/applications/linux/) -* [Learn more about the Static runtime](/doc/applications/static/) -* [Learn more about the V runtime](/doc/applications/v/) +- [Learn more about the Linux runtime](/doc/applications/linux/) +- [Learn more about the Static runtime](/doc/applications/static/) +- [Learn more about the V runtime](/doc/applications/v/) diff --git a/content/changelog/2025/07-08-terraform-0.11.md b/content/changelog/2025/07-08-terraform-0.11.md index 2f0c4b3f9..2e06db28e 100644 --- a/content/changelog/2025/07-08-terraform-0.11.md +++ b/content/changelog/2025/07-08-terraform-0.11.md @@ -17,4 +17,4 @@ excludeSearch: true The [0.11.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v0.11.0) of the Clever Cloud Terraform provider is available. It allows disabling backups for a [PostgreSQL add-on](/doc/addons/postgresql/). -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/07-09-images-update.md b/content/changelog/2025/07-09-images-update.md index ddea8ce80..c97cc29f8 100644 --- a/content/changelog/2025/07-09-images-update.md +++ b/content/changelog/2025/07-09-images-update.md @@ -14,27 +14,27 @@ excludeSearch: true We updated all our images, except PHP with Apache. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.15.5 - * Hugo 0.148.0 - * Mise 2025.7.1 - * SQLite 3.50.2 - * Redis 8.0.3 -* **Docker:** - * Update to 28.3.1 -* **FrankenPHP:** - * Update to 1.8.0 (PHP 8.4.10, Caddy 2.10.0) -* **Java:** - * Now part of the unified image - * Java 24 support - * GraalVM CE 23.0.2 (Java 17) - * GraalVM CE 23.1.2 (Java 21) - * Gradle 8.14.3 - * Maven 3.9.10 -* **Node.js:** - * Bun 1.2.18 -* **Python:** - * uv 0.7.19 +- **Common:** + - Linux kernel 6.15.5 + - Hugo 0.148.0 + - Mise 2025.7.1 + - SQLite 3.50.2 + - Redis 8.0.3 +- **Docker:** + - Update to 28.3.1 +- **FrankenPHP:** + - Update to 1.8.0 (PHP 8.4.10, Caddy 2.10.0) +- **Java:** + - Now part of the unified image + - Java 24 support + - GraalVM CE 23.0.2 (Java 17) + - GraalVM CE 23.1.2 (Java 21) + - Gradle 8.14.3 + - Maven 3.9.10 +- **Node.js:** + - Bun 1.2.18 +- **Python:** + - uv 0.7.19 ## FrankenPHP, Linux, Static and V runtimes diff --git a/content/changelog/2025/07-16-otoroshi-17.4.md b/content/changelog/2025/07-16-otoroshi-17.4.md index f82ce2289..2786db03a 100644 --- a/content/changelog/2025/07-16-otoroshi-17.4.md +++ b/content/changelog/2025/07-16-otoroshi-17.4.md @@ -29,4 +29,3 @@ clever otoroshi version update yourOtoroshiNameOrId v17.4.0_1752074416 - [Learn more about Otoroshi Workflows](https://maif.github.io/otoroshi/manual/docs/topics/workflows) - [Learn more about Otoroshi with LLM on Clever Cloud](/doc/addons/otoroshi/) - diff --git a/content/changelog/2025/07-17-request-flow.md b/content/changelog/2025/07-17-request-flow.md index 557959c85..586424f08 100644 --- a/content/changelog/2025/07-17-request-flow.md +++ b/content/changelog/2025/07-17-request-flow.md @@ -23,6 +23,7 @@ Clever Cloud exists to ease developers' life. For many years, you can use [Varni ## Easier Redirection.io and Varnish activation First, we've removed some barriers to use Redirection.io and Varnish: + - To setup Varnish add a `clevercloud/varnish.vcl` file or define it with `CC_VARNISH_FILE` environment variable - To setup Redirection.io, `CC_REDIRECTIONIO_PROJECT_KEY` is now the only required environment variable @@ -31,6 +32,7 @@ First, we've removed some barriers to use Redirection.io and Varnish: In recent runtimes where Clever Cloud manage the port configuration (`frankenphp`, `static`), nothing else is needed. By default, Clever Cloud will configure the reverse proxy to listen on port `8080` and redirect to port `9000`. So in runtimes where the user controls the port configuration, the application must listen on port `9000` once Redirection.io or Varnish is activated. If both are activated: + - Varnish is exposed first: listens on port `8080`, forward to Redirection.io on port `8081` - Redirection.io listens on port `8081`, forward to the application on port `9000` diff --git a/content/changelog/2025/07-29-clever-tools-3.14.md b/content/changelog/2025/07-29-clever-tools-3.14.md index afcef40fc..f6304f814 100644 --- a/content/changelog/2025/07-29-clever-tools-3.14.md +++ b/content/changelog/2025/07-29-clever-tools-3.14.md @@ -30,7 +30,7 @@ npm exec -- clever-tools@3.14 profile --format json To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2025/07-29-images-update.md b/content/changelog/2025/07-29-images-update.md index 9daa404f3..962b4f396 100644 --- a/content/changelog/2025/07-29-images-update.md +++ b/content/changelog/2025/07-29-images-update.md @@ -14,41 +14,41 @@ excludeSearch: true We updated all our images, except Node.js & Bun. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.15.8 - * Mise 2025.7.29 - * Tailscale 1.86.0 -* **Docker:** - * Update to 28.3.2 - * Buildx 0.26.1 -* **Elixir:** - * Update to 27.3.4.2 - * Update to 28.0.2 -* **Go:** - * Update to 1.24.5 -* **Java:** - * Update to 8.0.462 - * Update to 11.0.28 - * Update to 17.0.16 - * Update to 21.0.8 - * Update to 24.0.2 - * Maven 3.9.11 -* **FrankenPHP:** - * Update to 1.9.0 (PHP 8.4.10, Caddy v2.10.0) -* **PHP:** - * Update to 8.1.33 - * Update to 8.2.29 - * Update to 8.3.23 - * Update to 8.4.10 - * Apache 2.4.64 - * Composer 2.8.10 -* **Python:** - * uv 0.8.3 -* **Ruby:** - * Update to 3.2.9 - * Update to 3.3.9 - * Update to 3.4.5 -* **Static:** - * Hugo 0.148.2 - * Static Web Server 2.38.0 - * Zola 0.21.0 +- **Common:** + - Linux kernel 6.15.8 + - Mise 2025.7.29 + - Tailscale 1.86.0 +- **Docker:** + - Update to 28.3.2 + - Buildx 0.26.1 +- **Elixir:** + - Update to 27.3.4.2 + - Update to 28.0.2 +- **Go:** + - Update to 1.24.5 +- **Java:** + - Update to 8.0.462 + - Update to 11.0.28 + - Update to 17.0.16 + - Update to 21.0.8 + - Update to 24.0.2 + - Maven 3.9.11 +- **FrankenPHP:** + - Update to 1.9.0 (PHP 8.4.10, Caddy v2.10.0) +- **PHP:** + - Update to 8.1.33 + - Update to 8.2.29 + - Update to 8.3.23 + - Update to 8.4.10 + - Apache 2.4.64 + - Composer 2.8.10 +- **Python:** + - uv 0.8.3 +- **Ruby:** + - Update to 3.2.9 + - Update to 3.3.9 + - Update to 3.4.5 +- **Static:** + - Hugo 0.148.2 + - Static Web Server 2.38.0 + - Zola 0.21.0 diff --git a/content/changelog/2025/07-29-terraform-1.0.md b/content/changelog/2025/07-29-terraform-1.0.md index e031d2474..67fe70bcf 100644 --- a/content/changelog/2025/07-29-terraform-1.0.md +++ b/content/changelog/2025/07-29-terraform-1.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.0.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.0.0) of the Clever Cloud Terraform provider is available. It fixes some bugs, supports [Rust runtime](/doc/applications/rust/) and uses real ID instead of add-on ID for add-ons. -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/08-07-images-update.md b/content/changelog/2025/08-07-images-update.md index d4303fba0..b9c31ec7f 100644 --- a/content/changelog/2025/08-07-images-update.md +++ b/content/changelog/2025/08-07-images-update.md @@ -14,19 +14,19 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.15.9 - * Mise 2025.8.4 - * SQLite 3.50.3 - * Tailscale 1.86.2 -* **.NET:** - * Update to 9.0.108 -* **Docker:** - * Update to 28.3.3 -* **Node.js & Bun:** - * Bun 1.2.19 - * Node.js 22.18.0 (npm 10.9.3) -* **Python:** - * uv 0.8.4 +- **Common:** + - Linux kernel 6.15.9 + - Mise 2025.8.4 + - SQLite 3.50.3 + - Tailscale 1.86.2 +- **.NET:** + - Update to 9.0.108 +- **Docker:** + - Update to 28.3.3 +- **Node.js & Bun:** + - Bun 1.2.19 + - Node.js 22.18.0 (npm 10.9.3) +- **Python:** + - uv 0.8.4 In the [.NET runtime](/doc/applications/dotnet), you can now use `CC_DOTNET_VERSION=9.0`. diff --git a/content/changelog/2025/08-12-images-update.md b/content/changelog/2025/08-12-images-update.md index ec5854bbc..3c31ecaaa 100644 --- a/content/changelog/2025/08-12-images-update.md +++ b/content/changelog/2025/08-12-images-update.md @@ -14,19 +14,19 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Tailscale 1.86.4 -* **Go:** - * Update to 1.24.6 -* **Java:** - * Gradle 9.0.0 -* **Node.js & Bun:** - * Bun 1.2.20 -* **Python:** - * 3.13.6 - * pip 25.2 - * uv 0.8.8 -* **Rust:** - * Update to 1.89.0 +- **Common:** + - Tailscale 1.86.4 +- **Go:** + - Update to 1.24.6 +- **Java:** + - Gradle 9.0.0 +- **Node.js & Bun:** + - Bun 1.2.20 +- **Python:** + - 3.13.6 + - pip 25.2 + - uv 0.8.8 +- **Rust:** + - Update to 1.89.0 In the [Bun & Node.js runtime](/doc/applications/nodejs), you can now set `CC_NODE_BUILD_TOOL` to `pnpm` or `yarn-berry`. diff --git a/content/changelog/2025/08-27-clever-tools-4.0.md b/content/changelog/2025/08-27-clever-tools-4.0.md index a917ddf2c..7618509fb 100644 --- a/content/changelog/2025/08-27-clever-tools-4.0.md +++ b/content/changelog/2025/08-27-clever-tools-4.0.md @@ -18,6 +18,7 @@ excludeSearch: true Clever Tools 4.0 is available. It's a new major version as there are multiple breaking changes. Not in commands nor behavior, but in runtime, code quality and tooling. This release is now based on Node.js 22 and [Clever Cloud JS client 11.0](https://www.npmjs.com/package/@clevercloud/client). Under the hood we've also : + - Updated [CONTRIBUTING](https://github.com/CleverCloud/clever-tools/blob/master/CONTRIBUTING.md) and [README](https://github.com/CleverCloud/clever-tools/blob/master/README.md) files - Removed lots of dependencies, updated those remaining - Added scripts and tools to ease the development and contribution @@ -34,7 +35,7 @@ These changes will pave the way for future major improvements and new features a To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2025/09-01-metabase-56-default.md b/content/changelog/2025/09-01-metabase-56-default.md index 91443fe13..e71a1cc5b 100644 --- a/content/changelog/2025/09-01-metabase-56-default.md +++ b/content/changelog/2025/09-01-metabase-56-default.md @@ -16,6 +16,7 @@ excludeSearch: true --- The `x.56` branch of Metabase is available on Clever Cloud [since last month](/changelog/2025/08-08-metabase-56/). It's now the default branch deployed with the [release 0.56.3](https://github.com/metabase/metabase/releases/tag/v0.56.3). It means that: + - All new add-ons will use it - All add-ons using default configuration (`community-latest`) will use it after a rebuild diff --git a/content/changelog/2025/09-01-pg-update-17.6.md b/content/changelog/2025/09-01-pg-update-17.6.md index f69809aa2..8ffc81891 100644 --- a/content/changelog/2025/09-01-pg-update-17.6.md +++ b/content/changelog/2025/09-01-pg-update-17.6.md @@ -13,12 +13,13 @@ excludeSearch: true --- New PostgreSQL versions are available for new add-ons and migration: -* PostgreSQL 17.6 -* PostgreSQL 16.10 -* PostgreSQL 15.14 -* PostgreSQL 14.19 -* PostgreSQL 13.22 + +- PostgreSQL 17.6 +- PostgreSQL 16.10 +- PostgreSQL 15.14 +- PostgreSQL 14.19 +- PostgreSQL 13.22 It includes [fixes and improvements](https://www.postgresql.org/about/news/postgresql-176-1610-1514-1419-1322-and-18-beta-3-released-3118/), with security patches for [CVE-2025-8713](https://nvd.nist.gov/vuln/detail/CVE-2025-8713), [CVE-2025-8714](https://nvd.nist.gov/vuln/detail/CVE-2025-8714) and [CVE-2025-8715](https://nvd.nist.gov/vuln/detail/CVE-2025-8715). -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) diff --git a/content/changelog/2025/09-09-images-update.md b/content/changelog/2025/09-09-images-update.md index 634d19026..88e823a8e 100644 --- a/content/changelog/2025/09-09-images-update.md +++ b/content/changelog/2025/09-09-images-update.md @@ -14,35 +14,35 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * FFmpeg 8.0 - * Linux kernel 6.15.9 - * Mise 2025.9.6 - * Redis 8.2.1 - * SQLite 3.50.4 - * Varnish 7.7.3 -* **Docker:** - * Update to 28.4.0 - * Buildx 0.28.0 -* **FrankenPHP:** - * Update to 1.9.1 -* **Go:** - * Update to 1.25.1 -* **Node.js & Bun:** - * Update to 22.19.0 (npm 10.9.3) - * Bun 1.2.21 - * Yarn 4.9.4 -* **PHP:** - * Update to PHP 8.3.25 - * Update to PHP 8.4.12 - * Composer 2.2.25 (LTS) - * Composer 2.8.11 -* **Python:** - * 3.13.7 - * uv 0.8.15 -* **Static:** - * Hugo 0.145 removal - * Hugo 0.149.1 +- **Common:** + - FFmpeg 8.0 + - Linux kernel 6.15.9 + - Mise 2025.9.6 + - Redis 8.2.1 + - SQLite 3.50.4 + - Varnish 7.7.3 +- **Docker:** + - Update to 28.4.0 + - Buildx 0.28.0 +- **FrankenPHP:** + - Update to 1.9.1 +- **Go:** + - Update to 1.25.1 +- **Node.js & Bun:** + - Update to 22.19.0 (npm 10.9.3) + - Bun 1.2.21 + - Yarn 4.9.4 +- **PHP:** + - Update to PHP 8.3.25 + - Update to PHP 8.4.12 + - Composer 2.2.25 (LTS) + - Composer 2.8.11 +- **Python:** + - 3.13.7 + - uv 0.8.15 +- **Static:** + - Hugo 0.145 removal + - Hugo 0.149.1 ## Bun 1.2.21: native Clever Cloud add-ons support @@ -50,7 +50,7 @@ The latest Bun 1.2 release [brings native MySQL support](https://bun.com/blog/bu We provide a GitHub repository with ready-to-use examples: -* [Clever Cloud add-ons native Bun support example scripts](https://github.com/CleverCloud/bun-addons-examples) +- [Clever Cloud add-ons native Bun support example scripts](https://github.com/CleverCloud/bun-addons-examples) ## Hugo version update diff --git a/content/changelog/2025/09-10-otoroshi-17.5.md b/content/changelog/2025/09-10-otoroshi-17.5.md index 5b6d26c37..7e17f35a2 100644 --- a/content/changelog/2025/09-10-otoroshi-17.5.md +++ b/content/changelog/2025/09-10-otoroshi-17.5.md @@ -29,4 +29,3 @@ clever otoroshi version update yourOtoroshiNameOrId v17.5.1_1757489873 - [Learn more about Otoroshi Workflows](https://maif.github.io/otoroshi/manual/docs/topics/workflows) - [Learn more about Otoroshi with LLM on Clever Cloud](/doc/addons/otoroshi/) - diff --git a/content/changelog/2025/09-12-terraform-1.1.0.md b/content/changelog/2025/09-12-terraform-1.1.0.md index 363861103..480a31f2b 100644 --- a/content/changelog/2025/09-12-terraform-1.1.0.md +++ b/content/changelog/2025/09-12-terraform-1.1.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.1.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.1.0) of the Clever Cloud Terraform provider is available. It brings bug fixes, update capability to `frankenphp` and multiple add-ons: `keycloak`, `kv`, `metabase`, `mongodb`, `mysql`, `otoroshi`, `postgresql`, `pulsar`, `redis`. -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/09-16-images-update.md b/content/changelog/2025/09-16-images-update.md index f356f4d8d..36e44d747 100644 --- a/content/changelog/2025/09-16-images-update.md +++ b/content/changelog/2025/09-16-images-update.md @@ -14,28 +14,28 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.16.7 - * Clever Tools 4.0.2 - * Mise 2025.9.9 - * Tailscale 1.88.1 -* **Elixir:** - * Erlang 26.2.5.15 - * Erlang 27.3.4.3 - * Erlang 28.0.3 -* **Node.js & Bun:** - * Bun 1.2.22 -* **PHP:** - * Apache 2.4.65 - * Imagick extension 3.8.0 - * Symfony: fix binary name (was `symfony-cli`, now `symfony`) -* **Python:** - * uv 0.8.17 -* **Static:** - * Caddy 2.10.2 - * Hugo 0.146 removal - * Hugo 0.150.0 - * Static Web Server 2.38.1 +- **Common:** + - Linux kernel 6.16.7 + - Clever Tools 4.0.2 + - Mise 2025.9.9 + - Tailscale 1.88.1 +- **Elixir:** + - Erlang 26.2.5.15 + - Erlang 27.3.4.3 + - Erlang 28.0.3 +- **Node.js & Bun:** + - Bun 1.2.22 +- **PHP:** + - Apache 2.4.65 + - Imagick extension 3.8.0 + - Symfony: fix binary name (was `symfony-cli`, now `symfony`) +- **Python:** + - uv 0.8.17 +- **Static:** + - Caddy 2.10.2 + - Hugo 0.146 removal + - Hugo 0.150.0 + - Static Web Server 2.38.1 ## Hugo version update diff --git a/content/changelog/2025/09-17-clever-tools-4.1.md b/content/changelog/2025/09-17-clever-tools-4.1.md index 8851ce42d..bae27afb4 100644 --- a/content/changelog/2025/09-17-clever-tools-4.1.md +++ b/content/changelog/2025/09-17-clever-tools-4.1.md @@ -16,6 +16,7 @@ excludeSearch: true --- [Clever Tools 4.1.0](https://github.com/CleverCloud/clever-tools/releases/tag/4.1.0) is available. It fixes some bugs and: + - Return application runtime information in `clever status` - Return the local alias after a successful `clever link` command - Add JSON format with details to `clever domain` and `clever domain favourite` commands @@ -24,7 +25,7 @@ excludeSearch: true To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2025/09-18-mysql-8.0.43-8.4.6.md b/content/changelog/2025/09-18-mysql-8.0.43-8.4.6.md index 3b29c1e21..184d86012 100644 --- a/content/changelog/2025/09-18-mysql-8.0.43-8.4.6.md +++ b/content/changelog/2025/09-18-mysql-8.0.43-8.4.6.md @@ -14,6 +14,6 @@ excludeSearch: true We updated MySQL 8.0 and 8.4 from Percona Server. They're now available for add-ons creation and migration. -* [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) -* [Learn more about MySQL 8.0.43](https://docs.percona.com/percona-server/8.0/release-notes/8.0.43-34.html) -* [Learn more about MySQL 8.4.6](https://docs.percona.com/percona-server/8.4/release-notes/8.4.6-6.html) +- [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) +- [Learn more about MySQL 8.0.43](https://docs.percona.com/percona-server/8.0/release-notes/8.0.43-34.html) +- [Learn more about MySQL 8.4.6](https://docs.percona.com/percona-server/8.4/release-notes/8.4.6-6.html) diff --git a/content/changelog/2025/09-24-terraform-1.2.0.md b/content/changelog/2025/09-24-terraform-1.2.0.md index b18347354..33a758cf3 100644 --- a/content/changelog/2025/09-24-terraform-1.2.0.md +++ b/content/changelog/2025/09-24-terraform-1.2.0.md @@ -18,7 +18,8 @@ excludeSearch: true The [1.2.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.2.0) of the Clever Cloud Terraform provider is available. It brings multiple bug fixes with some cleaning. It also adds support for Ruby runtime and drains. There is a format change in domains management: -``` + +```text vhosts = [ "api.${var.cc_global_tld}/v4/addon-providers/es-addon", local.api_v2_vhost, @@ -26,11 +27,12 @@ There is a format change in domains management: ``` becomes: -``` + +```text vhosts = [ { fqdn = "api.${var.cc_global_tld}", path_begin = "/v4/addon-providers/es-addon" }, { fqdn = "api.${var.cc_global_tld}", path_begin = "/v2/providers/es-addon" } ] ``` -* Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [our Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/09-30-images-update.md b/content/changelog/2025/09-30-images-update.md index e51290568..c50f13169 100644 --- a/content/changelog/2025/09-30-images-update.md +++ b/content/changelog/2025/09-30-images-update.md @@ -14,33 +14,33 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.16.9 - * Clever Tools 4.1.0 - * Mise 2025.9.23 - * PostgreSQL Client 18.0 - * Varnish 8.0.0 - * Varnish modules 0.27.0 -* **Elixir:** - * Erlang 28.1 -* **FrankenPHP:** - * We now use glibc binary (1.9.1) -* **Java:** - * Gradle 9.1.0 -* **Node.js & Bun:** - * Update to 22.20.0 (npm 10.9.3) - * Bun 1.2.23 -* **PHP:** - * Update to PHP 8.3.26 - * Update to PHP 8.4.13 - * Excimer extension 1.2.5 (PHP 8.4 support) - * Composer 2.8.12 - * Symfony CLI 5.14.1 -* **Python:** - * uv 0.8.22 -* **Ruby:** - * Update to Ruby 3.4.6 -* **Static:** - * Hugo 0.150.1 -* **V:** - * Update to 0.4.12 +- **Common:** + - Linux kernel 6.16.9 + - Clever Tools 4.1.0 + - Mise 2025.9.23 + - PostgreSQL Client 18.0 + - Varnish 8.0.0 + - Varnish modules 0.27.0 +- **Elixir:** + - Erlang 28.1 +- **FrankenPHP:** + - We now use glibc binary (1.9.1) +- **Java:** + - Gradle 9.1.0 +- **Node.js & Bun:** + - Update to 22.20.0 (npm 10.9.3) + - Bun 1.2.23 +- **PHP:** + - Update to PHP 8.3.26 + - Update to PHP 8.4.13 + - Excimer extension 1.2.5 (PHP 8.4 support) + - Composer 2.8.12 + - Symfony CLI 5.14.1 +- **Python:** + - uv 0.8.22 +- **Ruby:** + - Update to Ruby 3.4.6 +- **Static:** + - Hugo 0.150.1 +- **V:** + - Update to 0.4.12 diff --git a/content/changelog/2025/10-07-images-update.md b/content/changelog/2025/10-07-images-update.md index 7c216ceee..158af6967 100644 --- a/content/changelog/2025/10-07-images-update.md +++ b/content/changelog/2025/10-07-images-update.md @@ -14,15 +14,15 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.16.10 - * Mise 2025.10.3 - * OpenSSL 3.5.4 - * Redis 8.2.2 - * Sops 3.11.0 -* **Java:** - * Update to Java 25 LTS -* **PHP:** - * Symfony CLI 5.15.1 -* **Python:** - * uv 0.8.23 +- **Common:** + - Linux kernel 6.16.10 + - Mise 2025.10.3 + - OpenSSL 3.5.4 + - Redis 8.2.2 + - Sops 3.11.0 +- **Java:** + - Update to Java 25 LTS +- **PHP:** + - Symfony CLI 5.15.1 +- **Python:** + - uv 0.8.23 diff --git a/content/changelog/2025/10-07-redis-8.2.2.md b/content/changelog/2025/10-07-redis-8.2.2.md index e6225106f..91d6eaffd 100644 --- a/content/changelog/2025/10-07-redis-8.2.2.md +++ b/content/changelog/2025/10-07-redis-8.2.2.md @@ -16,6 +16,7 @@ excludeSearch: true --- We updated Redis™ to [release 8.2.2](https://github.com/redis/redis/releases/tag/8.2.2). It brings bug fixes, enhancements, better performance and security patches for: + - [CVE-2025-46817](https://nvd.nist.gov/vuln/detail/CVE-2025-46817) - [CVE-2025-46818](https://nvd.nist.gov/vuln/detail/CVE-2025-46818) - [CVE-2025-46819](https://nvd.nist.gov/vuln/detail/CVE-2025-46819) diff --git a/content/changelog/2025/10-08-postgresql-18.md b/content/changelog/2025/10-08-postgresql-18.md index 01db43a1b..b477f8464 100644 --- a/content/changelog/2025/10-08-postgresql-18.md +++ b/content/changelog/2025/10-08-postgresql-18.md @@ -16,5 +16,5 @@ excludeSearch: true You can simply test it with a new add-on or update an existing one through automatic and safe Clever Cloud's migration process. -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) -* [PostgreSQL release notes](https://www.postgresql.org/docs/release/) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [PostgreSQL release notes](https://www.postgresql.org/docs/release/) diff --git a/content/changelog/2025/10-16-otoroshi-17.6.md b/content/changelog/2025/10-16-otoroshi-17.6.md index 46cd35e86..ffdd426f6 100644 --- a/content/changelog/2025/10-16-otoroshi-17.6.md +++ b/content/changelog/2025/10-16-otoroshi-17.6.md @@ -29,4 +29,3 @@ clever otoroshi version update yourOtoroshiNameOrId v17.6.3_1760617667 - [Learn more about Biscuit Studio](https://cloud-apim.github.io/otoroshi-biscuit-studio/docs/overview) - [Learn more about Otoroshi with LLM on Clever Cloud](/doc/addons/otoroshi/) - diff --git a/content/changelog/2025/10-21-clever-tools-4.2.md b/content/changelog/2025/10-21-clever-tools-4.2.md index 297cd82ee..00df3ab82 100644 --- a/content/changelog/2025/10-21-clever-tools-4.2.md +++ b/content/changelog/2025/10-21-clever-tools-4.2.md @@ -21,7 +21,7 @@ excludeSearch: true To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2025/10-22-clever-tools-4.3.md b/content/changelog/2025/10-22-clever-tools-4.3.md index 0b0e44fbe..8299facd6 100644 --- a/content/changelog/2025/10-22-clever-tools-4.3.md +++ b/content/changelog/2025/10-22-clever-tools-4.3.md @@ -21,7 +21,7 @@ excludeSearch: true To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2025/10-23-images-update.md b/content/changelog/2025/10-23-images-update.md index 6981b0787..657f86af8 100644 --- a/content/changelog/2025/10-23-images-update.md +++ b/content/changelog/2025/10-23-images-update.md @@ -14,41 +14,41 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.17.4 - * Clever Tools 4.3.0 - * Mise 2025.10.11 - * OpenSSH 10.2_p1 - * Ripgrep 15.0.0 - * Tailscale 1.88.3 -* **Docker:** - * Update to 28.5.1 - * Buildx 0.29.1 -* **Elixir:** - * Update to 1.19.1 - * Erlang 28.1.1 -* **Go:** - * Update to 1.25.3 -* **Node.js:** - * Update to 22.21.0 - * Bun 1.3.1 - * Yarn 4.10.3 -* **PHP:** - * Update to 8.3.27 - * Update to 8.4.14 - * memcached 1.6.39 - * memcached extension 3.4.0 -* **Python:** - * Update to Python 3.9.24 - * Update to Python 3.10.19 - * Update to Python 3.11.14 - * Update to Python 3.12.12 - * Update to Python 3.13.9 - * uv 0.9.4 -* **Ruby:** - * Update to Ruby 3.4.7 -* **Static:** - * Hugo 0.151.2 +- **Common:** + - Linux kernel 6.17.4 + - Clever Tools 4.3.0 + - Mise 2025.10.11 + - OpenSSH 10.2_p1 + - Ripgrep 15.0.0 + - Tailscale 1.88.3 +- **Docker:** + - Update to 28.5.1 + - Buildx 0.29.1 +- **Elixir:** + - Update to 1.19.1 + - Erlang 28.1.1 +- **Go:** + - Update to 1.25.3 +- **Node.js:** + - Update to 22.21.0 + - Bun 1.3.1 + - Yarn 4.10.3 +- **PHP:** + - Update to 8.3.27 + - Update to 8.4.14 + - memcached 1.6.39 + - memcached extension 3.4.0 +- **Python:** + - Update to Python 3.9.24 + - Update to Python 3.10.19 + - Update to Python 3.11.14 + - Update to Python 3.12.12 + - Update to Python 3.13.9 + - uv 0.9.4 +- **Ruby:** + - Update to Ruby 3.4.7 +- **Static:** + - Hugo 0.151.2 ## Node.js 25 support, 24 LTS as default version diff --git a/content/changelog/2025/10-27-terraform-1.3.0.md b/content/changelog/2025/10-27-terraform-1.3.0.md index e884861e2..9cc4a875d 100644 --- a/content/changelog/2025/10-27-terraform-1.3.0.md +++ b/content/changelog/2025/10-27-terraform-1.3.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.3.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.3.0) of the Clever Cloud Terraform provider is available. It brings multiple bug fixes, returns full URI of [MongoDB] add-ons as sensitive fields, and [MySQL] read-only users generated from the [Console](https://console.clever-cloud.com). It supports [.NET](/doc/applications/dotnet/) and [V (Vlang)](/doc/applications/v/) runtimes, [Configuration Providers](/doc/addons/config-provider/), and [Matomo](/doc/addons/matomo/) services. -* Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/10-31-otoroshi-17.7.md b/content/changelog/2025/10-31-otoroshi-17.7.md index c652ca29b..9fc00a8db 100644 --- a/content/changelog/2025/10-31-otoroshi-17.7.md +++ b/content/changelog/2025/10-31-otoroshi-17.7.md @@ -28,4 +28,3 @@ clever otoroshi version update yourOtoroshiNameOrId v17.7.0_1762500043 ``` - [Learn more about Otoroshi with LLM on Clever Cloud](/doc/addons/otoroshi/) - diff --git a/content/changelog/2025/11-04-images-update.md b/content/changelog/2025/11-04-images-update.md index 36028c3bb..061c981c6 100644 --- a/content/changelog/2025/11-04-images-update.md +++ b/content/changelog/2025/11-04-images-update.md @@ -14,26 +14,26 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.16.12 (we had issues with previous 6.17.4) - * Mise 2025.10.18 - * Redis 8.2.3 - * Ripgrep 15.1.0 - * Tailscale 1.90.2 -* **Elixir:** - * Update to 1.19.2 - * Erlang 27.3.4.4 -* **Java:** - * Update to 11.0.29_p7 - * Update to 17.0.16_p8 - * Update to 21.0.9_p10 - * Update to 25.0.1_p8 - * Gradle 9.2.0 -* **Node.js:** - * Update to 24.11.0 LTS (npm 11.6.1) -* **Python:** - * pip 25.3 - * uv 0.9.7 -* **Static:** - * Hugo 0.152.1 - * Static Web Server 2.39.0 +- **Common:** + - Linux kernel 6.16.12 (we had issues with previous 6.17.4) + - Mise 2025.10.18 + - Redis 8.2.3 + - Ripgrep 15.1.0 + - Tailscale 1.90.2 +- **Elixir:** + - Update to 1.19.2 + - Erlang 27.3.4.4 +- **Java:** + - Update to 11.0.29_p7 + - Update to 17.0.16_p8 + - Update to 21.0.9_p10 + - Update to 25.0.1_p8 + - Gradle 9.2.0 +- **Node.js:** + - Update to 24.11.0 LTS (npm 11.6.1) +- **Python:** + - pip 25.3 + - uv 0.9.7 +- **Static:** + - Hugo 0.152.1 + - Static Web Server 2.39.0 diff --git a/content/changelog/2025/11-05-terraform-1.4.0.md b/content/changelog/2025/11-05-terraform-1.4.0.md index 6f0a9451a..da66ce79a 100644 --- a/content/changelog/2025/11-05-terraform-1.4.0.md +++ b/content/changelog/2025/11-05-terraform-1.4.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.4.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.4.0) of the Clever Cloud Terraform provider is available. It now uses API when available for Keycloak, Metabase, Otoroshi, rather than [service dependencies](/changelog/2025/10-22-operators-cleanup/). It brings support for [Elastic Stack](/doc/addons/elastic/) (Elasticsearch with APM, Kibana), load balancer datasource, and replaces applications when the region is changed. -* Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/11-12-images-update.md b/content/changelog/2025/11-12-images-update.md index d48d74058..a2eddd5db 100644 --- a/content/changelog/2025/11-12-images-update.md +++ b/content/changelog/2025/11-12-images-update.md @@ -14,31 +14,31 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.17.7 - * Clang, lld, lldb, LLVM 21.1.5 - * cURL 8.17.0 - * Mise 2025.11.1 - * Perl 5.42.0 - * Poppler 25.11.0 - * SQLite 3.51.0 - * Tailscale 1.90.6 -* **Go:** - * Update to 1.25.4 -* **PHP:** - * Apcu extension 5.1.27 - * Blackfire extension 1.92.49 - * Mailparse extension 3.1.9 - * Maxmind DB extension 1.12.1 - * MongoDB extension 1.21.2 - * OAuth extension 2.0.10 (PHP 7.1+, 2.0.9 remains for PHP 7.0) - * OpenTelemetry extension 1.2.1 - * Redis extension 6.2.0 - * Solr extension 2.8.1 - * Tideways extension 5.30.0 (Daemon 1.11.4) - * YAML extension 2.2.5 - * Zip extension 1.22.7 -* **Scala:** - * Play Framework 1.8 - * Play Framework 1.9 - * Play Framework 1.10 +- **Common:** + - Linux kernel 6.17.7 + - Clang, lld, lldb, LLVM 21.1.5 + - cURL 8.17.0 + - Mise 2025.11.1 + - Perl 5.42.0 + - Poppler 25.11.0 + - SQLite 3.51.0 + - Tailscale 1.90.6 +- **Go:** + - Update to 1.25.4 +- **PHP:** + - Apcu extension 5.1.27 + - Blackfire extension 1.92.49 + - Mailparse extension 3.1.9 + - Maxmind DB extension 1.12.1 + - MongoDB extension 1.21.2 + - OAuth extension 2.0.10 (PHP 7.1+, 2.0.9 remains for PHP 7.0) + - OpenTelemetry extension 1.2.1 + - Redis extension 6.2.0 + - Solr extension 2.8.1 + - Tideways extension 5.30.0 (Daemon 1.11.4) + - YAML extension 2.2.5 + - Zip extension 1.22.7 +- **Scala:** + - Play Framework 1.8 + - Play Framework 1.9 + - Play Framework 1.10 diff --git a/content/changelog/2025/11-12-keycloak-26.4.4.md b/content/changelog/2025/11-12-keycloak-26.4.4.md index 24ef7c655..3024f7f82 100644 --- a/content/changelog/2025/11-12-keycloak-26.4.4.md +++ b/content/changelog/2025/11-12-keycloak-26.4.4.md @@ -16,6 +16,7 @@ excludeSearch: true --- [The release 26.4.4](https://github.com/keycloak/keycloak/releases/26.4.4) of Keycloak is available on Clever Cloud. It brings multiple enhancements and bug fixes. Starting with this release, Keycloak is deployed with two new plugins: + - [Groups regexp mapper](https://github.com/please-openit/keycloak-groups-regexp-mapper): map groups that only fit to a regexp (by name), it avoids mapping all user groups into a token - [HTTP Get request mapper](https://github.com/please-openit/keycloak-http-get-request-mapper): add a result from an external service (HTTP GET request) to user's tokens diff --git a/content/changelog/2025/11-13-clever-tools-4.4.md b/content/changelog/2025/11-13-clever-tools-4.4.md index b1d73ea91..c456b84c6 100644 --- a/content/changelog/2025/11-13-clever-tools-4.4.md +++ b/content/changelog/2025/11-13-clever-tools-4.4.md @@ -30,7 +30,7 @@ otoroshictl resources get routes To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2025/11-13-otoroshi-plugins.md b/content/changelog/2025/11-13-otoroshi-plugins.md index d39ec9193..b015913d4 100644 --- a/content/changelog/2025/11-13-otoroshi-plugins.md +++ b/content/changelog/2025/11-13-otoroshi-plugins.md @@ -16,8 +16,10 @@ excludeSearch: true --- Otoroshi on Clever Cloud comes with many included plugins to manage AI based APIs, Model Context Protocol (MCP), API Portal, Biscuit authentication, Dynamic JS or Mailer, etc. Now you can also load any other custom plugin by setting the `CC_OTOROSHI_PLUGINS_URLS` environment variable of the underlying Java application: + - Add URLs pointing to the plugins JAR files, separated by a space or a new line - Rebuild the application This works for any Otoroshi version deployed on Clever Cloud. If you want to learn more about Otoroshi plugins and how to create your own, check the [Otoroshi documentation](https://maif.github.io/otoroshi/manual/docs/plugins/create-plugins). + - [Learn more about Otoroshi with LLM on Clever Cloud](/doc/addons/otoroshi/) diff --git a/content/changelog/2025/11-17-terraform-1.5.0.md b/content/changelog/2025/11-17-terraform-1.5.0.md index 13920f522..e5399e095 100644 --- a/content/changelog/2025/11-17-terraform-1.5.0.md +++ b/content/changelog/2025/11-17-terraform-1.5.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.5.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.5.0) of the Clever Cloud Terraform provider is available. It brings bug fixes, support for [Network Groups](/doc/develop/network-groups/), GitHub applications from public or private repositories, migration of PostgreSQL databases. -* Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/11-19-terraform-1.6.0.md b/content/changelog/2025/11-19-terraform-1.6.0.md index 2ea17a346..177ad608a 100644 --- a/content/changelog/2025/11-19-terraform-1.6.0.md +++ b/content/changelog/2025/11-19-terraform-1.6.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.6.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.6.0) of the Clever Cloud Terraform provider is available. It brings bug fixes and allows to disable [Network Groups](/doc/develop/network-groups/). -* Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/12-01-metabase-57-default.md b/content/changelog/2025/12-01-metabase-57-default.md index 3526c83a6..819f95e00 100644 --- a/content/changelog/2025/12-01-metabase-57-default.md +++ b/content/changelog/2025/12-01-metabase-57-default.md @@ -16,6 +16,7 @@ excludeSearch: true --- The `x.57` branch of Metabase is available on Clever Cloud [since last month](/changelog/2025/11-10-metabase-57/). It's now the default branch deployed with the [release 0.57.4](https://github.com/metabase/metabase/releases/tag/v0.57.4). It means that: + - All new add-ons will use it - All add-ons using default configuration (`community-latest`) will use it after a rebuild diff --git a/content/changelog/2025/12-01-terraform-1.7.0.md b/content/changelog/2025/12-01-terraform-1.7.0.md index 3ae3443ac..d4ad436d0 100644 --- a/content/changelog/2025/12-01-terraform-1.7.0.md +++ b/content/changelog/2025/12-01-terraform-1.7.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.7.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.7.0) of the Clever Cloud Terraform provider is available. It brings bug fixes, reboot action for applications and encryption at rest for PostgreSQL databases. -* Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2025/12-03-otoroshi-17.9.md b/content/changelog/2025/12-03-otoroshi-17.9.md index 7c4164aad..a7656a183 100644 --- a/content/changelog/2025/12-03-otoroshi-17.9.md +++ b/content/changelog/2025/12-03-otoroshi-17.9.md @@ -16,6 +16,7 @@ excludeSearch: true --- [Otoroshi v17.9](https://github.com/MAIF/otoroshi/releases/tag/v17.9.0) is available with multiple improvements and bug fixes and two new plugins we've contributed to: + - LLMs.txt Accept Markdown: proxies requests with `Accept: text/markdown` header according to [llms.txt proposal](https://llmstxt.org/) - Swagger UI: serves a Swagger UI page from a configurable OpenAPI specification URL diff --git a/content/changelog/2025/12-15-pulsar-ga.md b/content/changelog/2025/12-15-pulsar-ga.md index 505716908..1a27fa9e1 100644 --- a/content/changelog/2025/12-15-pulsar-ga.md +++ b/content/changelog/2025/12-15-pulsar-ga.md @@ -21,25 +21,25 @@ Apache Pulsar is out of Beta on Clever Cloud. It doesn't change anything for exi Monthly prices will be as follows: -| Traffic IN/OUT | Price per GB | -|--------|--------------| -| < 512 MB | Free | -| 512 MB - 100 GB | €0.800 | -| 100 GB - 500 GB | €0.500 | -| 500 GB - 5 TB | €0.400 | -| > 5 TB | €0.300 | +| Traffic IN/OUT | Price per GB | +| --------------- | ------------ | +| < 512 MB | Free | +| 512 MB - 100 GB | €0.800 | +| 100 GB - 500 GB | €0.500 | +| 500 GB - 5 TB | €0.400 | +| > 5 TB | €0.300 | | Hot Storage (SSD) | Price per GB | -|--------|--------------| -| < 256 MB | Free | -| 256 MB - 50 GB | €0.200 | -| 50 GB - 250 GB | €0.150 | -| 250 GB - 1 TB | €0.120 | -| > 1 TB | €0.100 | +| ----------------- | ------------ | +| < 256 MB | Free | +| 256 MB - 50 GB | €0.200 | +| 50 GB - 250 GB | €0.150 | +| 250 GB - 1 TB | €0.120 | +| > 1 TB | €0.100 | | Cold Storage (HDD) | Price per GB | -|------|--------------| -| All volumes | €0.015 | +| ------------------ | ------------ | +| All volumes | €0.015 | In the coming weeks, we will update the Pulsar dashboard and product page to reflect these changes. diff --git a/content/changelog/2025/12-17-images-update.md b/content/changelog/2025/12-17-images-update.md index 199fc4ce3..9b864d1ec 100644 --- a/content/changelog/2025/12-17-images-update.md +++ b/content/changelog/2025/12-17-images-update.md @@ -14,43 +14,43 @@ excludeSearch: true We updated all our images except FrankenPHP and PHP. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.17.12 - * Anubis 1.23.1 - * Clever Tools 4.4.1 - * Git 2.52.0 - * Mise 2025.12.1 - * Nano 8.7 - * Poppler 25.12.0 - * Postgresql-client 18.1 - * Redis 8.4 - * Rust 1.92.0 - * Tailscale 1.90.9 - * Tmux 3.6 -* **Docker:** - * Docker 29.0.2 - * Docker Buildx 0.30.1 -* **Elixir:** - * Update to 1.19.4 - * Erlang 26.2.5.16 - * Erlang 27.3.4.6 - * Erlang 28.2 -* **Go:** - * Update to 1.25.5 -* **Node.js:** - * Update to 24.11.1 (npm 11.6.1) - * Bun 1.3.4 - * Yarn 4.12.0 -* **Python:** - * Update to 3.9.25 - * Update to 3.12.0 - * Update to 3.13.11 - * uv 0.9.17 -* **Ruby:** - * Update to 3.3.10 - * Update to 3.4.7 -* **Static:** - * Static Web Server 2.40.1 +- **Common:** + - Linux kernel 6.17.12 + - Anubis 1.23.1 + - Clever Tools 4.4.1 + - Git 2.52.0 + - Mise 2025.12.1 + - Nano 8.7 + - Poppler 25.12.0 + - Postgresql-client 18.1 + - Redis 8.4 + - Rust 1.92.0 + - Tailscale 1.90.9 + - Tmux 3.6 +- **Docker:** + - Docker 29.0.2 + - Docker Buildx 0.30.1 +- **Elixir:** + - Update to 1.19.4 + - Erlang 26.2.5.16 + - Erlang 27.3.4.6 + - Erlang 28.2 +- **Go:** + - Update to 1.25.5 +- **Node.js:** + - Update to 24.11.1 (npm 11.6.1) + - Bun 1.3.4 + - Yarn 4.12.0 +- **Python:** + - Update to 3.9.25 + - Update to 3.12.0 + - Update to 3.13.11 + - uv 0.9.17 +- **Ruby:** + - Update to 3.3.10 + - Update to 3.4.7 +- **Static:** + - Static Web Server 2.40.1 ## Elixir support diff --git a/content/changelog/2025/12-19-terraform-1.8.0.md b/content/changelog/2025/12-19-terraform-1.8.0.md index a77805f65..cada13af0 100644 --- a/content/changelog/2025/12-19-terraform-1.8.0.md +++ b/content/changelog/2025/12-19-terraform-1.8.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.8.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.8.0) of the Clever Cloud Terraform provider is available. It brings bug fixes, `clevercloud_database_query` action, upload action for FS Buckets, exposed environment variables for applications and more Clever Cloud's Keycloak features. -* Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2026/01-14-clever-tools-4.5.md b/content/changelog/2026/01-14-clever-tools-4.5.md index fe29f13ab..0acbacec9 100644 --- a/content/changelog/2026/01-14-clever-tools-4.5.md +++ b/content/changelog/2026/01-14-clever-tools-4.5.md @@ -35,7 +35,7 @@ These changes were an essential building block for the next major step: redesign To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2026/01-15-images-update.md b/content/changelog/2026/01-15-images-update.md index 24b1131b5..30bf8f5b9 100644 --- a/content/changelog/2026/01-15-images-update.md +++ b/content/changelog/2026/01-15-images-update.md @@ -14,46 +14,46 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.17.13 - * cURL 8.18.0 - * NGINX 1.28.1 - * OAuth2 Proxy 7.13.0 - * Otoroshictl 0.0.13 - * Poppler 26.01.0 - * Tailscale 1.92.4 -* **Docker:** - * Update to 29.1.4 -* **Elixir:** - * Update to 1.19.5 - * Erlang 28.3 -* **Node.js:** - * Update to 24.13.0 (npm 11.6.2) - * Bun 1.3.6 -* **PHP:** - * Update to 8.1.34 - * Update to 8.2.30 - * Update to 8.3.29 - * Update to 8.4.16 - * Update to 8.5.1 - * Composer 2.9.2 - * Symfony CLI 5.16.1 - * Blackfire extension 1.92.51 - * gRPC extension 1.76.0 - * Imagick extension 3.8.1 - * Maxmind DB extension 1.13.0 - * New Relic extension 12.2.0.27 - * Protobuf extension 3.23.4, 3.25.8 and 4.33.2 - * Redis extension 6.3.0 - * Tideways extension 5.31.0 (Daemon 1.11.4) - * YAML extension 2.3.0 -* **Python:** - * uv 0.9.24 -* **Ruby:** - * Update to 3.4.8 - * Update to 4.0.1 -* **V (Vlang):** - * Update to 0.5 +- **Common:** + - Linux kernel 6.17.13 + - cURL 8.18.0 + - NGINX 1.28.1 + - OAuth2 Proxy 7.13.0 + - Otoroshictl 0.0.13 + - Poppler 26.01.0 + - Tailscale 1.92.4 +- **Docker:** + - Update to 29.1.4 +- **Elixir:** + - Update to 1.19.5 + - Erlang 28.3 +- **Node.js:** + - Update to 24.13.0 (npm 11.6.2) + - Bun 1.3.6 +- **PHP:** + - Update to 8.1.34 + - Update to 8.2.30 + - Update to 8.3.29 + - Update to 8.4.16 + - Update to 8.5.1 + - Composer 2.9.2 + - Symfony CLI 5.16.1 + - Blackfire extension 1.92.51 + - gRPC extension 1.76.0 + - Imagick extension 3.8.1 + - Maxmind DB extension 1.13.0 + - New Relic extension 12.2.0.27 + - Protobuf extension 3.23.4, 3.25.8 and 4.33.2 + - Redis extension 6.3.0 + - Tideways extension 5.31.0 (Daemon 1.11.4) + - YAML extension 2.3.0 +- **Python:** + - uv 0.9.24 +- **Ruby:** + - Update to 3.4.8 + - Update to 4.0.1 +- **V (Vlang):** + - Update to 0.5 ## PHP 8.5 and Composer 2.9 diff --git a/content/changelog/2026/01-23-terraform-1.9.0.md b/content/changelog/2026/01-23-terraform-1.9.0.md index 84d820929..4e90befb3 100644 --- a/content/changelog/2026/01-23-terraform-1.9.0.md +++ b/content/changelog/2026/01-23-terraform-1.9.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.9.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.9.0) of the Clever Cloud Terraform provider is available. It brings bug fixes, Java JAR support, app-to-app dependencies, more integrations and backup datasource for PostgreSQL. -* Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2026/01-27-metrics-retention-change.md b/content/changelog/2026/01-27-metrics-retention-change.md index 4d834da39..18341f16e 100644 --- a/content/changelog/2026/01-27-metrics-retention-change.md +++ b/content/changelog/2026/01-27-metrics-retention-change.md @@ -16,5 +16,5 @@ Starting February 2nd, 2026, the retention period for custom application metrics **System metrics remain unaffected** by this change. All automatically collected metrics, including CPU usage, RAM consumption, disk usage, network activity, and load metrics, will continue to be available with the existing retention period. -* [Learn more about metrics on Clever Cloud](/doc/metrics/) -* [How to publish your own metrics](/doc/metrics/#publish-your-own-metrics) +- [Learn more about metrics on Clever Cloud](/doc/metrics/) +- [How to publish your own metrics](/doc/metrics/#publish-your-own-metrics) diff --git a/content/changelog/2026/01-28-images-update.md b/content/changelog/2026/01-28-images-update.md index 41ae82cc3..f632d1602 100644 --- a/content/changelog/2026/01-28-images-update.md +++ b/content/changelog/2026/01-28-images-update.md @@ -14,38 +14,39 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Clever Tools 4.5.3 - * qpdf 12.3.2 - * Mise 2026.1.8 -* **Docker:** - * Update to 29.2.0 - * Docker Buildx 0.31.0 -* **Elixir:** - * Erlang 28.3.1 -* **Go:** - * Update to 1.25.6 -* **Java:** - * Gradle 8.14.4 - * Gradle 9.3.0 - * Maven 3.9.12 -* **Node.js & Bun:** - * Bun 1.3.7 -* **PHP:** - * Update to 8.3.30 - * Update to 8.4.17 - * Update to 8.5.2 - * Composer 2.9.4 -* **Python:** - * uv 0.9.26 -* **Ruby:** - * Update to 3.2.10 -* **Rust:** - * Update to 1.93.0 +- **Common:** + - Clever Tools 4.5.3 + - qpdf 12.3.2 + - Mise 2026.1.8 +- **Docker:** + - Update to 29.2.0 + - Docker Buildx 0.31.0 +- **Elixir:** + - Erlang 28.3.1 +- **Go:** + - Update to 1.25.6 +- **Java:** + - Gradle 8.14.4 + - Gradle 9.3.0 + - Maven 3.9.12 +- **Node.js & Bun:** + - Bun 1.3.7 +- **PHP:** + - Update to 8.3.30 + - Update to 8.4.17 + - Update to 8.5.2 + - Composer 2.9.4 +- **Python:** + - uv 0.9.26 +- **Ruby:** + - Update to 3.2.10 +- **Rust:** + - Update to 1.93.0 ## Request Flow expansion Request Flow is now available in .NET, Elixir, Haskell and Rust applications. We plan its expansion to more runtimes in the coming weeks in three releases: + - Go and Node.js/Bun - Java and PHP - Python and Ruby diff --git a/content/changelog/2026/02-03-images-update.md b/content/changelog/2026/02-03-images-update.md index c20166cad..afb9c61c7 100644 --- a/content/changelog/2026/02-03-images-update.md +++ b/content/changelog/2026/02-03-images-update.md @@ -14,30 +14,30 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * OAuth2 Proxy 7.14.2 - * Otoroshictl 0.0.15 - * Tailscale 1.94.1 -* **.NET:** - * Update to 6.0.136 -* **Docker:** - * Docker Buildx 0.31.1 -* **Java:** - * Update to 11.0.30_p7 - * Update to 17.0.18_p8 - * Update to 21.0.10_p7 - * Update to 25.0.2_p10 - * Gradle 9.3.1 -* **Node.js & Bun:** - * Bun 1.3.8 -* **PHP:** - * Composer 2.9.5 - * mcrypt extension 1.0.9 - * PDFlib extension 11.0.0 - * solr extension 2.9.1 - * xdebug extension 3.5.0 -* **Python:** - * uv 0.9.28 +- **Common:** + - OAuth2 Proxy 7.14.2 + - Otoroshictl 0.0.15 + - Tailscale 1.94.1 +- **.NET:** + - Update to 6.0.136 +- **Docker:** + - Docker Buildx 0.31.1 +- **Java:** + - Update to 11.0.30_p7 + - Update to 17.0.18_p8 + - Update to 21.0.10_p7 + - Update to 25.0.2_p10 + - Gradle 9.3.1 +- **Node.js & Bun:** + - Bun 1.3.8 +- **PHP:** + - Composer 2.9.5 + - mcrypt extension 1.0.9 + - PDFlib extension 11.0.0 + - solr extension 2.9.1 + - xdebug extension 3.5.0 +- **Python:** + - uv 0.9.28 ## Docker Buildx diff --git a/content/changelog/2026/02-12-images-update.md b/content/changelog/2026/02-12-images-update.md index cfd658ae4..32de9f0f0 100644 --- a/content/changelog/2026/02-12-images-update.md +++ b/content/changelog/2026/02-12-images-update.md @@ -14,25 +14,25 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * git 2.53.0 - * Mise 2026.2.8 - * nginx 1.28.2 - * pgpool2 4.7 -* **.NET:** - * Update to 10.0.102 -* **Docker:** - * Docker 29.2.1 -* **Go:** - * Update to 1.26.0 -* **Node.js & Bun:** - * Bun 1.3.9 - * nvm 0.40.4 -* **Python:** - * Update to 3.13.12 - * Update to 3.14.3 - * pip 26.0.1 - * uv 0.10.2 +- **Common:** + - git 2.53.0 + - Mise 2026.2.8 + - nginx 1.28.2 + - pgpool2 4.7 +- **.NET:** + - Update to 10.0.102 +- **Docker:** + - Docker 29.2.1 +- **Go:** + - Update to 1.26.0 +- **Node.js & Bun:** + - Bun 1.3.9 + - nvm 0.40.4 +- **Python:** + - Update to 3.13.12 + - Update to 3.14.3 + - pip 26.0.1 + - uv 0.10.2 ## .NET 10 support @@ -51,5 +51,6 @@ Latest branch of Mise includes many changes such as Node.js version detection fr ## Fixes This release includes: + - A fix for [Mise Tasks management in Linux Runtime](/doc/applications/linux/#build-and-run-commands) - A fix for `CC_NODE_BUILD_TOOL=yarn-berry` diff --git a/content/changelog/2026/02-18-clever-tools-4.6.md b/content/changelog/2026/02-18-clever-tools-4.6.md index fb335674f..cd7e61bc5 100644 --- a/content/changelog/2026/02-18-clever-tools-4.6.md +++ b/content/changelog/2026/02-18-clever-tools-4.6.md @@ -99,7 +99,7 @@ clever features disable system-git To upgrade Clever Tools, [use your favorite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2026/02-18-images-update.md b/content/changelog/2026/02-18-images-update.md index e8c0926dc..eebed4784 100644 --- a/content/changelog/2026/02-18-images-update.md +++ b/content/changelog/2026/02-18-images-update.md @@ -14,23 +14,23 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Linux Kernel 6.19.2 - * ClamAV 1.5.1 - * Mise 2026.2.13 - * Otoroshictl 0.0.16 -* **.NET:** - * Update to 8.0.123 - * Update to 9.0.113 -* **Elixir:** - * Erlang 27.3.4.7 -* **Node.js & Bun:** - * Update to 24.13.1 (npm 11.8.0) -* **PHP:** - * Update to 8.4.18 - * Update to 8.5.3 -* **Rust:** - * Update to 1.93.1 +- **Common:** + - Linux Kernel 6.19.2 + - ClamAV 1.5.1 + - Mise 2026.2.13 + - Otoroshictl 0.0.16 +- **.NET:** + - Update to 8.0.123 + - Update to 9.0.113 +- **Elixir:** + - Erlang 27.3.4.7 +- **Node.js & Bun:** + - Update to 24.13.1 (npm 11.8.0) +- **PHP:** + - Update to 8.4.18 + - Update to 8.5.3 +- **Rust:** + - Update to 1.93.1 ## Apache Basic Auth diff --git a/content/changelog/2026/02-25-images-update.md b/content/changelog/2026/02-25-images-update.md index 5659d6cad..c8af66b7a 100644 --- a/content/changelog/2026/02-25-images-update.md +++ b/content/changelog/2026/02-25-images-update.md @@ -14,19 +14,19 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Clever Tools 4.6.1 - * md4c 0.5.2 - * Redis 8.6.1 - * Mise 2026.2.19 - * Otoroshictl 0.0.17 -* **FrankenPHP:** - * Update to 1.11.3 (with `CC_PHP_VERSION=8.5`) -* **Python:** - * uv 0.10.4 -* **Static:** - * Caddy 2.11.1 - * Static Web Server 2.41.0 +- **Common:** + - Clever Tools 4.6.1 + - md4c 0.5.2 + - Redis 8.6.1 + - Mise 2026.2.19 + - Otoroshictl 0.0.17 +- **FrankenPHP:** + - Update to 1.11.3 (with `CC_PHP_VERSION=8.5`) +- **Python:** + - uv 0.10.4 +- **Static:** + - Caddy 2.11.1 + - Static Web Server 2.41.0 ## PHP Version in FrankenPHP diff --git a/content/changelog/2026/03-03-terraform-1.10.0.md b/content/changelog/2026/03-03-terraform-1.10.0.md index 6a8000a9f..722aea4bb 100644 --- a/content/changelog/2026/03-03-terraform-1.10.0.md +++ b/content/changelog/2026/03-03-terraform-1.10.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.10.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.10.0) of the Clever Cloud Terraform provider is available. It adds Linux runtime support for applications, missing feature flags for MySQL, PostgreSQL and MongoDB add-ons, and includes multiple bug fixes (add-on API responses, app state handling, Elasticsearch versioning, OAuth signature method). -* Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2026/03-09-pg-update-18.3.md b/content/changelog/2026/03-09-pg-update-18.3.md index 358790e41..f83010cec 100644 --- a/content/changelog/2026/03-09-pg-update-18.3.md +++ b/content/changelog/2026/03-09-pg-update-18.3.md @@ -13,12 +13,13 @@ excludeSearch: true --- New PostgreSQL versions are available for new add-ons and migration: -* PostgreSQL 18.3 -* PostgreSQL 17.9 -* PostgreSQL 16.13 -* PostgreSQL 15.17 -* PostgreSQL 14.22 + +- PostgreSQL 18.3 +- PostgreSQL 17.9 +- PostgreSQL 16.13 +- PostgreSQL 15.17 +- PostgreSQL 14.22 These versions include [multiple bug fixes and improvements](https://www.postgresql.org/about/news/postgresql-183-179-1613-1517-and-1422-released-3246/). PostgreSQL 14 and 15 are now shipped without `plls` and `plcoffee` extensions, which are no longer supported with up to date add-ons. -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) diff --git a/content/changelog/2026/03-11-clever-tools-4.7.md b/content/changelog/2026/03-11-clever-tools-4.7.md index 4294dcee2..587bec463 100644 --- a/content/changelog/2026/03-11-clever-tools-4.7.md +++ b/content/changelog/2026/03-11-clever-tools-4.7.md @@ -58,7 +58,7 @@ The `clever drain` and `clever drain get` commands now display message rates and To upgrade Clever Tools, [use your favourite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2026/03-19-drains-legacy.md b/content/changelog/2026/03-19-drains-legacy.md index 31a9aa940..c39eb8c70 100644 --- a/content/changelog/2026/03-19-drains-legacy.md +++ b/content/changelog/2026/03-19-drains-legacy.md @@ -15,6 +15,7 @@ excludeSearch: true For the past few months, Clever Cloud has provided a new drain stack and a `v4` API that is more reliable and provides better monitoring. It's available through Clever Tools since [release `4.4.0`](https://github.com/CleverCloud/clever-tools/releases/tag/4.4.0). If you still use the legacy drains implementation, we encourage you to migrate to the new stack as soon as possible. The legacy drains will be disabled on June 1st, 2026. In the meantime, we will make some changes to prepare for the migration and help you transition smoothly: + - March 19th, 2026: we added `CC_PREVENT_LEGACY_LOGSCOLLECTION=false` environment variable on applications linked to a legacy active drain - Starting with the next image release, if not set to `false`, we will consider this environment variable as `true` and only push logs of applications with a drain to the new drain stack - June 1st, 2026: legacy drains will be disabled and all applications will need to use the new drain stack to receive logs @@ -25,4 +26,4 @@ To migrate to the new drain stack, just create a new drain with Clever Tools, th If you have any questions or if you need help with the migration, contact [our support team](https://console.clever-cloud.com/ticket-center-choice). -- [Learn more about Clever Tools drain command ](/doc/cli/logs-drains/) +- [Learn more about Clever Tools drain command](/doc/cli/logs-drains/) diff --git a/content/changelog/2026/03-23-metabase-59-default.md b/content/changelog/2026/03-23-metabase-59-default.md index 506bf1850..4efe3292d 100644 --- a/content/changelog/2026/03-23-metabase-59-default.md +++ b/content/changelog/2026/03-23-metabase-59-default.md @@ -16,6 +16,7 @@ excludeSearch: true --- The `x.59` branch of Metabase is available on Clever Cloud [since earlier this month](/changelog/2026/03-03-metabase-59/). It's now the default branch deployed with the [release 0.59.3](https://github.com/metabase/metabase/releases/tag/v0.59.3). It means that: + - All new add-ons will use it - All add-ons using default configuration (`community-latest`) will use it after a rebuild diff --git a/content/changelog/2026/03-25-images-update.md b/content/changelog/2026/03-25-images-update.md index 353d5795d..2b8710ed4 100644 --- a/content/changelog/2026/03-25-images-update.md +++ b/content/changelog/2026/03-25-images-update.md @@ -14,46 +14,46 @@ excludeSearch: true We updated all our images, except PHP. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.19.7 - * Anubis 1.25.0 - * Chromium 146.0.7680.153 - * Clever Tools 4.7.1 - * cURL 8.19.0 - * FFmpeg 8.1 - * Ghostscript 10.07 - * OAuth2 Proxy 7.14.3 - * Poppler 26.03 - * SQLite 3.52.0 - * Varnish 8.0.1 - * Vim 9.2.0096 -* **Elixir:** - * Erlang 26.2.5.18 - * Erlang 27.3.4.9 - * Erlang 28.4.1 -* **FrankenPHP:** - * Update to 1.12.1 with PHP 8.5.4 (with `CC_PHP_VERSION=8.5`) -* **Go:** - * Update to 1.26.1 -* **Java:** - * Gradle 9.4.1 - * Maven 3.9.14 -* **Node.js & Bun:** - * Update to 24.14.1 (npm 11.11.0) - * Bun 1.3.11 - * Yarn 4.13.0 -* **Python:** - * Update to 3.10.20 - * Update to 3.11.15 - * Update to 3.12.13 - * uv 0.10.12 -* **Ruby:** - * Update to 3.4.9 -* **Rust:** - * Update to 1.94.0 - * Rustup 1.29.0 -* **Static:** - * Caddy 2.11.2 +- **Common:** + - Linux kernel 6.19.7 + - Anubis 1.25.0 + - Chromium 146.0.7680.153 + - Clever Tools 4.7.1 + - cURL 8.19.0 + - FFmpeg 8.1 + - Ghostscript 10.07 + - OAuth2 Proxy 7.14.3 + - Poppler 26.03 + - SQLite 3.52.0 + - Varnish 8.0.1 + - Vim 9.2.0096 +- **Elixir:** + - Erlang 26.2.5.18 + - Erlang 27.3.4.9 + - Erlang 28.4.1 +- **FrankenPHP:** + - Update to 1.12.1 with PHP 8.5.4 (with `CC_PHP_VERSION=8.5`) +- **Go:** + - Update to 1.26.1 +- **Java:** + - Gradle 9.4.1 + - Maven 3.9.14 +- **Node.js & Bun:** + - Update to 24.14.1 (npm 11.11.0) + - Bun 1.3.11 + - Yarn 4.13.0 +- **Python:** + - Update to 3.10.20 + - Update to 3.11.15 + - Update to 3.12.13 + - uv 0.10.12 +- **Ruby:** + - Update to 3.4.9 +- **Rust:** + - Update to 1.94.0 + - Rustup 1.29.0 +- **Static:** + - Caddy 2.11.2 ## PHP & Composer version diff --git a/content/changelog/2026/03-31-mysql-8.0.45-8.4.8.md b/content/changelog/2026/03-31-mysql-8.0.45-8.4.8.md index 625ce0561..efa73e73f 100644 --- a/content/changelog/2026/03-31-mysql-8.0.45-8.4.8.md +++ b/content/changelog/2026/03-31-mysql-8.0.45-8.4.8.md @@ -14,6 +14,6 @@ excludeSearch: true We updated MySQL images for releases 8.4 (8.4.8-8) and 8.0 (8.0.45-36). They're now available for add-ons creation and migration. -* [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) -* [Learn more about MySQL 8.0.45](https://docs.percona.com/percona-server/8.0/release-notes/8.0.45-36.html) -* [Learn more about MySQL 8.4.8](https://docs.percona.com/percona-server/8.4/release-notes/8.4.8-8.html) +- [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) +- [Learn more about MySQL 8.0.45](https://docs.percona.com/percona-server/8.0/release-notes/8.0.45-36.html) +- [Learn more about MySQL 8.4.8](https://docs.percona.com/percona-server/8.4/release-notes/8.4.8-8.html) diff --git a/content/changelog/2026/04-02-terraform-1.11.0.md b/content/changelog/2026/04-02-terraform-1.11.0.md index 255a45f82..7a28dc663 100644 --- a/content/changelog/2026/04-02-terraform-1.11.0.md +++ b/content/changelog/2026/04-02-terraform-1.11.0.md @@ -17,4 +17,4 @@ excludeSearch: true The [1.11.0 release](https://github.com/CleverCloud/terraform-provider-clevercloud/releases/tag/v1.11.0) of the Clever Cloud Terraform provider is available. It adds new resources (add-on provider, OAuth consumer, vulnerability scanner), improved validation for environment variables, add-on options and plan slugs, exponential backoff retry for 503 errors, and multiple bug fixes. -* Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) +- Learn more about [Clever Cloud Terraform provider](https://registry.terraform.io/providers/CleverCloud/clevercloud/latest/docs) diff --git a/content/changelog/2026/04-07-images-update.md b/content/changelog/2026/04-07-images-update.md index 16827c560..c61dcdf1b 100644 --- a/content/changelog/2026/04-07-images-update.md +++ b/content/changelog/2026/04-07-images-update.md @@ -14,21 +14,21 @@ excludeSearch: true We updated all our images, except PHP. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.19.11 - * nginx 1.28.3 - * OAuth2 Proxy 7.15.1 - * Tailscale 1.96.3 -* **Python:** - * uv 0.11.2 -* **Ruby:** - * Update to 3.3.11 - * Update to 4.0.2 -* **Static:** - * mdBook 0.5.2 - * Static Web Server 2.42.0 -* **V (Vlang):** - * Update to 0.5.1 +- **Common:** + - Linux kernel 6.19.11 + - nginx 1.28.3 + - OAuth2 Proxy 7.15.1 + - Tailscale 1.96.3 +- **Python:** + - uv 0.11.2 +- **Ruby:** + - Update to 3.3.11 + - Update to 4.0.2 +- **Static:** + - mdBook 0.5.2 + - Static Web Server 2.42.0 +- **V (Vlang):** + - Update to 0.5.1 ## mdBook 0.5 diff --git a/content/changelog/2026/04-09-clever-tools-4.8.md b/content/changelog/2026/04-09-clever-tools-4.8.md index b203d8bb3..e29d9a55a 100644 --- a/content/changelog/2026/04-09-clever-tools-4.8.md +++ b/content/changelog/2026/04-09-clever-tools-4.8.md @@ -75,7 +75,7 @@ clever drain remove --addon postgresql_xxxxxxxx To upgrade Clever Tools, [use your favourite package manager](/doc/cli/install/). For example with `npm`: -``` +```console npm update -g clever-tools clever version ``` diff --git a/content/changelog/2026/04-21-images-update.md b/content/changelog/2026/04-21-images-update.md index 972f24d7a..f3654efa0 100644 --- a/content/changelog/2026/04-21-images-update.md +++ b/content/changelog/2026/04-21-images-update.md @@ -14,27 +14,27 @@ excludeSearch: true We updated all our images, except PHP. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.19.13 - * Chromium 147.0.7727.101 - * Clever Tools 4.8.0 - * htop 3.5.0 - * nano 9.0 - * nginx 1.30.0 - * OpenSSH 10.3p1 - * OpenSSL 3.5.6 - * SQLite 3.53.0 -* **FrankenPHP:** - * Update to 1.12.2 (with `CC_PHP_VERSION=8.5`) - * Symfony CLI 5.17.1 -* **Go:** - * Update to 1.26.2 -* **Node.js & Bun:** - * Update to 24.15.0 (npm 11.12.1) - * Bun 1.3.12 -* **Python:** - * Update to 3.13.13 - * Update to 3.14.4 - * uv 0.11.7 -* **Ruby:** - * Update to 3.2.11 +- **Common:** + - Linux kernel 6.19.13 + - Chromium 147.0.7727.101 + - Clever Tools 4.8.0 + - htop 3.5.0 + - nano 9.0 + - nginx 1.30.0 + - OpenSSH 10.3p1 + - OpenSSL 3.5.6 + - SQLite 3.53.0 +- **FrankenPHP:** + - Update to 1.12.2 (with `CC_PHP_VERSION=8.5`) + - Symfony CLI 5.17.1 +- **Go:** + - Update to 1.26.2 +- **Node.js & Bun:** + - Update to 24.15.0 (npm 11.12.1) + - Bun 1.3.12 +- **Python:** + - Update to 3.13.13 + - Update to 3.14.4 + - uv 0.11.7 +- **Ruby:** + - Update to 3.2.11 diff --git a/content/changelog/2026/04-23-otoroshi-17.15.md b/content/changelog/2026/04-23-otoroshi-17.15.md index c902e3555..8f7939e0a 100644 --- a/content/changelog/2026/04-23-otoroshi-17.15.md +++ b/content/changelog/2026/04-23-otoroshi-17.15.md @@ -17,19 +17,19 @@ excludeSearch: true [Otoroshi v17.15.1](https://github.com/MAIF/otoroshi/releases/tag/v17.15.1) is available. It introduces an OAuth2 token exchange plugin implementing [RFC 8693](https://datatracker.ietf.org/doc/html/rfc8693) for secure service-to-service API communication, a new `PluginPreset` kind to package and reuse plugin configurations, a `MandatoryConsumerPreset` plugin and a workflow-based authentication module. The `OAuth2Caller` plugin can now rely on an authentication module for the client credentials flow, and `$2b$` / `$2y$` Bcrypt hashes are now accepted. -### A redesigned admin interface and manual +## A redesigned admin interface and manual The admin interface has been redesigned with refreshed themes, a new home page, a reworked API editor with sticky actions and form views capped at 1000 px to improve readability. The UI also now only displays entities a user is actually authorized to see. The full manual has been reworked as well, with ditaa schemas replaced by mermaid ones, and the OpenAPI specification and Swagger UI can be protected behind an optional access secret. -### API management, data exporters and plugin development +## API management, data exporters and plugin development API management gains direct subscription to a plan and a new consistency service. The PostgreSQL data exporter now supports retention and plugin developers can rely on a reusable stateful clients internal API. Several fixes address a race condition in data exporters loading, legacy audit event layouts, body consumption handling and the `OAuth2Caller` password grant type. -### LLM extension: agents, memory and Kreuzberg +## LLM extension: agents, memory and Kreuzberg This release includes LLM extension [0.0.75](https://github.com/cloud-apim/otoroshi-llm-extension/releases/tag/0.0.75), which significantly expands agent capabilities with built-in tools (`system_exec`, `file_read`, `file_write`, `http_call`), a per-session working memory, autonomous persistent memory on Redis and PostgreSQL and a new agent OpenAI proxy plugin. Embedding stores and persistent memories now support many backends (PostgreSQL, Redis, Elasticsearch, OpenSearch, Qdrant, Weaviate, Pinecone, ChromaDB), a semantic cache on Redis with a custom embedding model and MCP audit events. The Anthropic provider exposes version and beta settings, and [Kreuzberg](https://kreuzberg.dev) is now available as a content-to-markdown and OCR backend. -### Java 25 is now required +## Java 25 is now required Otoroshi 17.15 requires Java 25 to load the Kreuzberg content-to-markdown and OCR backend. Starting with this release, all new Otoroshi add-ons are created with `CC_JAVA_VERSION=25`, and any update to Otoroshi 17.15 automatically switches the underlying Java application to Java 25. If you prefer to handle this manually, you can set `CC_JAVA_VERSION` to `25` on the Java application backing your Otoroshi add-on and rebuild it before updating Otoroshi itself. diff --git a/content/changelog/2026/04-28-images-update.md b/content/changelog/2026/04-28-images-update.md index ae6183706..575e53867 100644 --- a/content/changelog/2026/04-28-images-update.md +++ b/content/changelog/2026/04-28-images-update.md @@ -14,13 +14,13 @@ excludeSearch: true We updated all our images, except PHP. Deployment is in progress for all our users. -* **Common:** - * Linux kernel 6.19.14 - * CA certificates 20260223 - * Git 2.54.0 -* **Node.js & Bun:** - * Yarn 4.14.1 -* **Ruby:** - * Update to 3.2.11 - * Update to 3.4.9 - * Update to 4.0.3 +- **Common:** + - Linux kernel 6.19.14 + - CA certificates 20260223 + - Git 2.54.0 +- **Node.js & Bun:** + - Yarn 4.14.1 +- **Ruby:** + - Update to 3.2.11 + - Update to 3.4.9 + - Update to 4.0.3 diff --git a/content/changelog/2026/05-11-materia-kv-graphql.md b/content/changelog/2026/05-11-materia-kv-graphql.md index a15af9a89..8523014d5 100644 --- a/content/changelog/2026/05-11-materia-kv-graphql.md +++ b/content/changelog/2026/05-11-materia-kv-graphql.md @@ -18,7 +18,7 @@ excludeSearch: true As Materia KV is a distributed cluster, the GraphQL endpoint is a single URL shared by every add-on in a given region. For Paris: -``` +```text https://materiakv-graphql.eu-fr-1.services.clever-cloud.com/graphql ``` diff --git a/content/changelog/2026/05-21-pg-update-18.4.md b/content/changelog/2026/05-21-pg-update-18.4.md index ddaf0ef91..e73b587f3 100644 --- a/content/changelog/2026/05-21-pg-update-18.4.md +++ b/content/changelog/2026/05-21-pg-update-18.4.md @@ -13,14 +13,15 @@ excludeSearch: true --- New PostgreSQL versions are available for new add-ons and migration: -* PostgreSQL 18.4 -* PostgreSQL 17.10 -* PostgreSQL 16.14 -* PostgreSQL 15.18 -* PostgreSQL 14.23 + +- PostgreSQL 18.4 +- PostgreSQL 17.10 +- PostgreSQL 16.14 +- PostgreSQL 15.18 +- PostgreSQL 14.23 These versions include [over 60 bug fixes and improvements](https://www.postgresql.org/about/news/postgresql-184-1710-1614-1518-and-1423-released-3297), with security patches for 11 CVEs: [CVE-2026-6472](https://nvd.nist.gov/vuln/detail/CVE-2026-6472), [CVE-2026-6473](https://nvd.nist.gov/vuln/detail/CVE-2026-6473), [CVE-2026-6474](https://nvd.nist.gov/vuln/detail/CVE-2026-6474), [CVE-2026-6475](https://nvd.nist.gov/vuln/detail/CVE-2026-6475), [CVE-2026-6476](https://nvd.nist.gov/vuln/detail/CVE-2026-6476), [CVE-2026-6477](https://nvd.nist.gov/vuln/detail/CVE-2026-6477), [CVE-2026-6478](https://nvd.nist.gov/vuln/detail/CVE-2026-6478), [CVE-2026-6479](https://nvd.nist.gov/vuln/detail/CVE-2026-6479), [CVE-2026-6575](https://nvd.nist.gov/vuln/detail/CVE-2026-6575), [CVE-2026-6637](https://nvd.nist.gov/vuln/detail/CVE-2026-6637) and [CVE-2026-6638](https://nvd.nist.gov/vuln/detail/CVE-2026-6638). PostgreSQL 14 reaches its end of life on 12 November 2026. Plan a migration to a newer version before that date to keep receiving security updates. Also note that PostgreSQL 11 [is not available anymore](/changelog/2025/03-24-postgresql-11-12-eol/) for migrations on Clever Cloud. -* [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) diff --git a/content/changelog/2026/05-22-images-update.md b/content/changelog/2026/05-22-images-update.md index 889bfb504..822003be5 100644 --- a/content/changelog/2026/05-22-images-update.md +++ b/content/changelog/2026/05-22-images-update.md @@ -14,50 +14,50 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Apache 2.4.67 - * Chromium 148.0.7778.167 - * Clever Tools 4.10.0 - * cURL 8.20.0 - * Mise 2026.5.3 - * NGINX 1.30.1 - * OAuth2 Proxy 7.15.2 - * Redis 8.6.3 - * SQLite 3.53.1 -* **FrankenPHP:** - * Update to 1.12.3 (For `CC_PHP_VERSION=8.5`) -* **Go:** - * Go 1.26.3 -* **Java:** - * Update to 1.8.0.492_p09 - * Update to 11.0.31_p11 - * Update to 17.0.19_p10 - * Update to 21.0.11_p10 - * Update to 25.0.3_p9 - * Gradle 8.14.5 - * Gradle 9.5.1 -* **Node.js & Bun:** - * Bun 1.3.14 -* **PHP:** - * Update to 8.2.31 - * Update to 8.3.31 - * Update to 8.4.21 - * Update to 8.5.6 - * Composer 2.2.27 - * Composer 2.9.7 -* **Python:** - * Update to 3.14.5 - * uv 0.11.15 -* **Ruby:** - * Update to 4.0.5 -* **Scala:** - * Play Framework 1.2.7.2 - * Play Framework 1.11.0 -* **Static:** - * Hugo 0.152.2 - * Hugo 0.159.2 - * Hugo 0.160.1 - * Hugo 0.161.1 +- **Common:** + - Apache 2.4.67 + - Chromium 148.0.7778.167 + - Clever Tools 4.10.0 + - cURL 8.20.0 + - Mise 2026.5.3 + - NGINX 1.30.1 + - OAuth2 Proxy 7.15.2 + - Redis 8.6.3 + - SQLite 3.53.1 +- **FrankenPHP:** + - Update to 1.12.3 (For `CC_PHP_VERSION=8.5`) +- **Go:** + - Go 1.26.3 +- **Java:** + - Update to 1.8.0.492_p09 + - Update to 11.0.31_p11 + - Update to 17.0.19_p10 + - Update to 21.0.11_p10 + - Update to 25.0.3_p9 + - Gradle 8.14.5 + - Gradle 9.5.1 +- **Node.js & Bun:** + - Bun 1.3.14 +- **PHP:** + - Update to 8.2.31 + - Update to 8.3.31 + - Update to 8.4.21 + - Update to 8.5.6 + - Composer 2.2.27 + - Composer 2.9.7 +- **Python:** + - Update to 3.14.5 + - uv 0.11.15 +- **Ruby:** + - Update to 4.0.5 +- **Scala:** + - Play Framework 1.2.7.2 + - Play Framework 1.11.0 +- **Static:** + - Hugo 0.152.2 + - Hugo 0.159.2 + - Hugo 0.160.1 + - Hugo 0.161.1 ## Linux Kernel diff --git a/content/changelog/2026/05-29-otoroshi-17.16.md b/content/changelog/2026/05-29-otoroshi-17.16.md index 81586c3e9..861392902 100644 --- a/content/changelog/2026/05-29-otoroshi-17.16.md +++ b/content/changelog/2026/05-29-otoroshi-17.16.md @@ -17,7 +17,7 @@ excludeSearch: true [Otoroshi v17.16.0](https://github.com/MAIF/otoroshi/releases/tag/v17.16.0) is available. This release focuses on observability, API lifecycle management, Kubernetes deployments and a set of brand-new HTTP standards plugins. It also ships an updated LLM extension featuring an AI Assistant for the admin interface and an updated WAF extension. The Otoroshi documentation has been substantially expanded as well. -### User analytics, dashboards and a global event stream +## User analytics, dashboards and a global event stream Otoroshi gains a complete user analytics stack. A PostgreSQL-based analytics exporter stores and queries events at scale, and you can now build your own dashboards with a graphical widget editor, drill-down support and a set of default dashboards shipped out of the box. User-defined alerts are built from analytics queries through a graphical condition editor, with a dedicated alerting interface and a scheduled evaluation job. Dashboards, alerts and analytics queries are all integrated with RBAC. @@ -25,7 +25,7 @@ A new global node event stream page in the back office streams audit, alert and - [Learn more about dashboards, analytics queries and alerts](https://maif.github.io/otoroshi/manual/docs/topics/user-analytics/) -### API management and new HTTP standards plugins +## API management and new HTTP standards plugins API management hardens the split between draft and production: a clear version banner, read-only production views and plan lifecycle enforcement that locks the `Api` entity fields once a plan is published. A getting-started stepper guides newcomers, and the draft subscription listing, top bar search and API key plan editor have all been cleaned up. @@ -34,21 +34,21 @@ This release introduces three plugins implementing recent HTTP standards. The HT - [HTTP Message Signatures (RFC 9421) tutorial](https://maif.github.io/otoroshi/manual/docs/tutorials/http-message-signatures-rfc9421/) - [Learn more about RFC 9440 Client-Cert headers](https://maif.github.io/otoroshi/manual/docs/topics/tls/#rfc-9440--client-cert--client-cert-chain-headers) -### Distributed rate limiting, mailers and exporters +## Distributed rate limiting, mailers and exporters A new distributed rate-limiting strategy backed by atomic Lua scripts on Redis provides predictable, cluster-aware quotas across nodes. It is a drop-in alternative to the previous distributed strategy and is configurable per route. Scaleway TEM and MailPace join the supported mailers. -### Reworked Kubernetes deployments +## Reworked Kubernetes deployments The Helm chart has been almost entirely rewritten with first-class cluster mode (leader and worker deployments), a Redis secured by default based on the CloudPirates Redis chart, and proper HPA, PDB, NetworkPolicies, RBAC, webhooks and certificate templates. The Kustomize manifests reach feature parity with Helm through a component-based split, and the generated CRDs now expose previously missing entities, including APIs, dashboards, alerts and the new analytics resources. -### LLM extension: an AI Assistant and Meta MCP +## LLM extension: an AI Assistant and Meta MCP This release includes LLM extension [0.0.76](https://github.com/cloud-apim/otoroshi-llm-extension/releases/tag/0.0.76), which adds an AI Assistant to the Otoroshi admin interface. The assistant can search the documentation, query the admin API and run administrative tasks through its Search, Doc and Execute tools, with a conversational chat window, streaming responses, light and dark themes and API key-based access. A hybrid semantic and lexical search engine backs documentation queries. The extension also introduces a Meta MCP connector that aggregates and proxies multiple MCP servers with dynamic capabilities, an Otoroshi MCP server plugin exposing the assistant tools, and image generation support in the `Response` and `OpenResponse` plugins. The Monaco editor is now used across all administration pages of the extension. -### Updated bundled plugins +## Updated bundled plugins Every plugin delivered with Otoroshi on Clever Cloud has been rebuilt against 17.16.0. The WAF extension ([0.0.9](https://github.com/cloud-apim/otoroshi-waf-extension/releases/tag/0.0.9)) upgrades the OWASP Core Rule Set to v4.26.0. diff --git a/content/changelog/2026/06-17-images-update.md b/content/changelog/2026/06-17-images-update.md index 5a9c21fc1..ae26bf9c4 100644 --- a/content/changelog/2026/06-17-images-update.md +++ b/content/changelog/2026/06-17-images-update.md @@ -14,39 +14,39 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Apache 2.4.68 - * Chromium 149.0.7827.114 - * Mise 2026.6.0 - * NGINX 1.30.2 - * OAuth2 Proxy 7.15.3 - * Redis 8.8.0 -* **Docker:** - * Update to 29.5.2 -* **Erlang/Elixir:** - * Rebar 3.27.0 -* **FrankenPHP:** - * Update to 1.12.4 (For `CC_PHP_VERSION=8.5`) -* **Go:** - * Go 1.26.4 -* **Node.js & Bun:** - * Yarn 4.16.0 -* **PHP:** - * Update to 8.4.22 - * Update to 8.5.7 - * Composer 1.20.28 - * Composer 2.2.28 - * Composer 2.10.1 -* **Python:** - * Update to 3.13.14 - * Update to 3.14.6 - * pip 26.1.2 - * uv 0.11.21 -* **Rust:** - * Rust 1.96.0 -* **Static:** - * Hugo 0.162.1 - * Static Web Server 2.43.0 +- **Common:** + - Apache 2.4.68 + - Chromium 149.0.7827.114 + - Mise 2026.6.0 + - NGINX 1.30.2 + - OAuth2 Proxy 7.15.3 + - Redis 8.8.0 +- **Docker:** + - Update to 29.5.2 +- **Erlang/Elixir:** + - Rebar 3.27.0 +- **FrankenPHP:** + - Update to 1.12.4 (For `CC_PHP_VERSION=8.5`) +- **Go:** + - Go 1.26.4 +- **Node.js & Bun:** + - Yarn 4.16.0 +- **PHP:** + - Update to 8.4.22 + - Update to 8.5.7 + - Composer 1.20.28 + - Composer 2.2.28 + - Composer 2.10.1 +- **Python:** + - Update to 3.13.14 + - Update to 3.14.6 + - pip 26.1.2 + - uv 0.11.21 +- **Rust:** + - Rust 1.96.0 +- **Static:** + - Hugo 0.162.1 + - Static Web Server 2.43.0 ## Hugo version update diff --git a/content/changelog/2026/06-30-otoroshi-17.17.md b/content/changelog/2026/06-30-otoroshi-17.17.md index f130e33bb..d97462eb1 100644 --- a/content/changelog/2026/06-30-otoroshi-17.17.md +++ b/content/changelog/2026/06-30-otoroshi-17.17.md @@ -14,21 +14,21 @@ excludeSearch: true [Otoroshi v17.17.0](https://github.com/MAIF/otoroshi/releases/tag/v17.17.0) is available on Clever Cloud. This release adds standards-based token introspection, hardens API key validation and improves Elasticsearch compatibility. It also ships LLM extension [0.0.82](https://github.com/cloud-apim/otoroshi-llm-extension/releases/tag/0.0.82), which builds on [0.0.81](https://github.com/cloud-apim/otoroshi-llm-extension/releases/tag/0.0.81) and [0.0.80](https://github.com/cloud-apim/otoroshi-llm-extension/releases/tag/0.0.80). -### RFC 7662 token introspection and admin bootstrap +## RFC 7662 token introspection and admin bootstrap Otoroshi now implements the [RFC 7662](https://datatracker.ietf.org/doc/html/rfc7662) introspection flow, so you can validate opaque access tokens against an introspection endpoint. The `OIDCJwtVerifier` also reads the audience from an array, aligning it with providers that emit `aud` as a list. The initial admin password can now be generated and stored in a temporary file at first startup, which makes automated and reproducible bootstrap of a fresh instance easier. -### Hardened API key validation +## Hardened API key validation Several fixes tighten how API keys are accepted. Disabled API keys are no longer accepted in client-id-only mode, and a bearer signature validation bypass in that same mode has been corrected. Legacy quota declarations are now reported on the API key quotas endpoint, so quota reporting stays consistent across key formats. -### Elasticsearch 8 and Expression Language +## Elasticsearch 8 and Expression Language Writes to Elasticsearch 8 no longer include the deprecated `_type` field, and the cluster version can be auto-filled from the interface. The Expression Language handles default values more reliably and fixes the ordering of `ctx.geolocation.*` and `ctx.useragent.*` expressions. The `NgErrorRewriter` plugin also receives several improvements, and ingress fetching now targets the correct API group. -### LLM extension: A2A, MCP virtual servers and gateway discovery +## LLM extension: A2A, MCP virtual servers and gateway discovery The bundled LLM extension reaches [0.0.82](https://github.com/cloud-apim/otoroshi-llm-extension/releases/tag/0.0.82) and includes the features introduced in 0.0.81 and 0.0.80. The provider and capability catalogs are now exposed through the authenticated admin API, and a new `RampartBodyRedactionBackend` terminal plugin reads the request body, redacts PII with the local Rampart model and returns the redacted body directly. The Mistral provider adopts the OpenAI content representation for chat messages, improving support for structured and multi-part content. diff --git a/content/changelog/2026/07-01-images-update.md b/content/changelog/2026/07-01-images-update.md index 73a5464e9..ee5ddb5d3 100644 --- a/content/changelog/2026/07-01-images-update.md +++ b/content/changelog/2026/07-01-images-update.md @@ -14,20 +14,20 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * cURL 8.21.0 - * Mise 2026.6.14 - * NGINX 1.30.3 -* **Docker:** - * Update to 29.6.1 -* **Java:** - * Gradle 9.6.1 -* **PHP:** - * `mod_ssl` module is now loaded -* **Python:** - * uv 0.11.25 -* **Static:** - * Hugo 0.163.3 +- **Common:** + - cURL 8.21.0 + - Mise 2026.6.14 + - NGINX 1.30.3 +- **Docker:** + - Update to 29.6.1 +- **Java:** + - Gradle 9.6.1 +- **PHP:** + - `mod_ssl` module is now loaded +- **Python:** + - uv 0.11.25 +- **Static:** + - Hugo 0.163.3 ## Hugo version update diff --git a/content/changelog/2026/07-28-images-update.md b/content/changelog/2026/07-28-images-update.md index e0e0c5696..89393b523 100644 --- a/content/changelog/2026/07-28-images-update.md +++ b/content/changelog/2026/07-28-images-update.md @@ -14,43 +14,42 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Chromium 150.0.7871.186 - * Clever Tools 4.11.0 - * Git 2.55.0 - * Nano 9.1 - * NGINX 1.30.4 - * OpenSSH 10.4_p1 - * Perl 5.44.0 - * Poppler 26.07.0 - * Zellij 0.43.1 -* **Docker:** - * Update to 29.6.2 -* **Go:** - * Go 1.26.5 -* **Node.js & Bun:** - * Node.js 24.18.0 (npm 11.16.0) - * Yarn 4.17.1 -* **Java:** - * Update to 11.0.32_p9 - * Update to 21.0.12_p8 -* **PHP:** - * Update to 8.2.32 - * Update to 8.3.32 - * Update to 8.4.23 - * Update to 8.5.8 - * Composer 2.10.2 - * Elastic APM agent 1.17.0 - * New Relic extension 12.8.0.37 -* **Python:** - * uv 0.11.29 -* **Rust:** - * Update to 1.97.1 -* **Static:** - * Caddy 2.11.4 - * Hugo 0.164.0 +- **Common:** + - Chromium 150.0.7871.186 + - Clever Tools 4.11.0 + - Git 2.55.0 + - Nano 9.1 + - NGINX 1.30.4 + - OpenSSH 10.4_p1 + - Perl 5.44.0 + - Poppler 26.07.0 + - Zellij 0.43.1 +- **Docker:** + - Update to 29.6.2 +- **Go:** + - Go 1.26.5 +- **Node.js & Bun:** + - Node.js 24.18.0 (npm 11.16.0) + - Yarn 4.17.1 +- **Java:** + - Update to 11.0.32_p9 + - Update to 21.0.12_p8 +- **PHP:** + - Update to 8.2.32 + - Update to 8.3.32 + - Update to 8.4.23 + - Update to 8.5.8 + - Composer 2.10.2 + - Elastic APM agent 1.17.0 + - New Relic extension 12.8.0.37 +- **Python:** + - uv 0.11.29 +- **Rust:** + - Update to 1.97.1 +- **Static:** + - Caddy 2.11.4 + - Hugo 0.164.0 ## Linux Kernel Kernel is [now updated independently](/changelog/2026/05-12-linux-kernel-7.0.6). Current version is 7.1.5. - diff --git a/content/changelog/2026/07-29-mysql-8.0.46-8.4.10.md b/content/changelog/2026/07-29-mysql-8.0.46-8.4.10.md index 45f3ddf03..01cfd4e7e 100644 --- a/content/changelog/2026/07-29-mysql-8.0.46-8.4.10.md +++ b/content/changelog/2026/07-29-mysql-8.0.46-8.4.10.md @@ -18,6 +18,6 @@ The 8.4 release addresses eight security vulnerabilities: [CVE-2026-46850](https MySQL 8.0 [reached its end of life on 30 April 2026](https://www.mysql.com/support/eol-notice.html), and 8.0.46-37 is [the final release of the Percona Server 8.0 series](https://docs.percona.com/new/2026/06/10/percona-server-for-mysql-8046-37-has-been-released/). If you run a MySQL 8.0 add-on, we recommend you migrate it to the 8.4 LTS branch. -* [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) -* [Learn more about MySQL 8.0.46](https://docs.percona.com/percona-server/8.0/release-notes/8.0.46-37.html) -* [Learn more about MySQL 8.4.10](https://docs.percona.com/percona-server/8.4/release-notes/8.4.10-10.html) +- [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) +- [Learn more about MySQL 8.0.46](https://docs.percona.com/percona-server/8.0/release-notes/8.0.46-37.html) +- [Learn more about MySQL 8.4.10](https://docs.percona.com/percona-server/8.4/release-notes/8.4.10-10.html) diff --git a/content/changelog/2026/08-05-images-update.md b/content/changelog/2026/08-05-images-update.md index 2a0daf17e..e3942833f 100644 --- a/content/changelog/2026/08-05-images-update.md +++ b/content/changelog/2026/08-05-images-update.md @@ -14,31 +14,31 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Chromium 151.0.7922.71 - * Redis 8.10.0 - * Ripgrep 15.2.0 -* **.NET:** - * Update to 8.0.129 - * Update to 9.0.119 - * Update to 10.0.110 -* **Java:** - * Update to 1.8.0.502_p07 - * Update to 17.0.20_p8 - * Update to 25.0.4_p7 -* **Node.js & Bun:** - * Node.js 24.18.1 (npm 11.16.0) - * Yarn 4.18.0 -* **PHP:** - * Update to 8.2.33 - * Update to 8.3.33 - * Update to 8.4.24 - * Update to 8.5.9 - * Blackfire agent 2026.7.0 - * Blackfire extension 2026.7.1 -* **Python:** - * pip 26.2 - * uv 0.12.0 +- **Common:** + - Chromium 151.0.7922.71 + - Redis 8.10.0 + - Ripgrep 15.2.0 +- **.NET:** + - Update to 8.0.129 + - Update to 9.0.119 + - Update to 10.0.110 +- **Java:** + - Update to 1.8.0.502_p07 + - Update to 17.0.20_p8 + - Update to 25.0.4_p7 +- **Node.js & Bun:** + - Node.js 24.18.1 (npm 11.16.0) + - Yarn 4.18.0 +- **PHP:** + - Update to 8.2.33 + - Update to 8.3.33 + - Update to 8.4.24 + - Update to 8.5.9 + - Blackfire agent 2026.7.0 + - Blackfire extension 2026.7.1 +- **Python:** + - pip 26.2 + - uv 0.12.0 ## Linux Kernel diff --git a/content/changelog/2026/08-19-images-update.md b/content/changelog/2026/08-19-images-update.md index 4477cafc2..376fb637d 100644 --- a/content/changelog/2026/08-19-images-update.md +++ b/content/changelog/2026/08-19-images-update.md @@ -14,31 +14,31 @@ excludeSearch: true We updated all our images. Deployment is in progress for all our users. -* **Common:** - * Anubis 1.26.2 - * ClamAV 1.5.4 - * Chromium 151.0.7922.137 - * FFmpeg 9.0 - * Nano 9.2 - * OpenSSH 10.5_p1 - * Poppler 26.08.0 - * pdfio 1.6.4 is now available - * qpdf is no longer included - * rsync 3.5.0 -* **Go:** - * Update to 1.26.6 -* **Node.js & Bun:** - * Node.js 24.19.0 (npm 11.17.0) -* **Python:** - * Update to 3.10.21 - * Update to 3.11.16 - * Update to 3.12.14 - * Update to 3.13.15 - * Update to 3.14.7 -* **Ruby:** - * Update to 3.3.12 - * Update to 3.4.10 - * Update to 4.0.6 +- **Common:** + - Anubis 1.26.2 + - ClamAV 1.5.4 + - Chromium 151.0.7922.137 + - FFmpeg 9.0 + - Nano 9.2 + - OpenSSH 10.5_p1 + - Poppler 26.08.0 + - pdfio 1.6.4 is now available + - qpdf is no longer included + - rsync 3.5.0 +- **Go:** + - Update to 1.26.6 +- **Node.js & Bun:** + - Node.js 24.19.0 (npm 11.17.0) +- **Python:** + - Update to 3.10.21 + - Update to 3.11.16 + - Update to 3.12.14 + - Update to 3.13.15 + - Update to 3.14.7 +- **Ruby:** + - Update to 3.3.12 + - Update to 3.4.10 + - Update to 4.0.6 ## Health Check and Request Flow improvements diff --git a/content/doc/account/create-account.md b/content/doc/account/create-account.md index b9571c3c5..728d907cd 100644 --- a/content/doc/account/create-account.md +++ b/content/doc/account/create-account.md @@ -32,8 +32,8 @@ The GitHub signup allows you to create an account or link your existing one to G This process asks the following permissions: -* Read your Public Key -* Read User Repositories +- Read your Public Key +- Read User Repositories The "repository permission" is used to deploy your GitHub apps directly to Clever Cloud, with a simple step. diff --git a/content/doc/account/notifications.md b/content/doc/account/notifications.md index 38ed82b72..1c7ec7722 100644 --- a/content/doc/account/notifications.md +++ b/content/doc/account/notifications.md @@ -90,20 +90,20 @@ the result of the deployment in your Slack channel. Available webhooks events are organised by category: -| Category | Events | -|----------|--------| -| **Account** | `ACCOUNT_CREATION`, `ACCOUNT_DELETION`, `ACCOUNT_EDITION` | -| **Organisation** | `ORGANISATION_CREATION`, `ORGANISATION_DELETION`, `ORGANISATION_EDITION` | -| **Add-on** | `ADDON_CREATION`, `ADDON_DELETION` | -| **Application** | `APPLICATION_CREATION`, `APPLICATION_DELETION`, `APPLICATION_EDITION`, `APPLICATION_REDEPLOY`, `APPLICATION_STOP` | -| **Deployment** | `DEPLOYMENT_ACTION_BEGIN`, `DEPLOYMENT_ACTION_END`, `DEPLOYMENT_FAIL`, `DEPLOYMENT_SUCCESS`, `GIT_PUSH` | -| **Other** | `CLEVER_TOOLS_REQUEST`, `CREDITS_ADDED` | +| Category | Events | +| ---------------- | ----------------------------------------------------------------------------------------------------------------- | +| **Account** | `ACCOUNT_CREATION`, `ACCOUNT_DELETION`, `ACCOUNT_EDITION` | +| **Organisation** | `ORGANISATION_CREATION`, `ORGANISATION_DELETION`, `ORGANISATION_EDITION` | +| **Add-on** | `ADDON_CREATION`, `ADDON_DELETION` | +| **Application** | `APPLICATION_CREATION`, `APPLICATION_DELETION`, `APPLICATION_EDITION`, `APPLICATION_REDEPLOY`, `APPLICATION_STOP` | +| **Deployment** | `DEPLOYMENT_ACTION_BEGIN`, `DEPLOYMENT_ACTION_END`, `DEPLOYMENT_FAIL`, `DEPLOYMENT_SUCCESS`, `GIT_PUSH` | +| **Other** | `CLEVER_TOOLS_REQUEST`, `CREDITS_ADDED` | Some events are grouped in meta-events for easier selection: -| Meta-Event | Included Events | -|------------|-----------------| -| `META_CREDITS` | `CREDITS_ADDED` | -| `META_DEPLOYMENT_RESULT` | `DEPLOYMENT_FAIL`, `DEPLOYMENT_SUCCESS` | -| `META_SERVICE_LIFECYCLE` | `APPLICATION_STOP`, `DEPLOYMENT_ACTION_BEGIN`, `DEPLOYMENT_FAIL`, `DEPLOYMENT_SUCCESS` | +| Meta-Event | Included Events | +| ------------------------- | --------------------------------------------------------------------------------------------------------- | +| `META_CREDITS` | `CREDITS_ADDED` | +| `META_DEPLOYMENT_RESULT` | `DEPLOYMENT_FAIL`, `DEPLOYMENT_SUCCESS` | +| `META_SERVICE_LIFECYCLE` | `APPLICATION_STOP`, `DEPLOYMENT_ACTION_BEGIN`, `DEPLOYMENT_FAIL`, `DEPLOYMENT_SUCCESS` | | `META_SERVICE_MANAGEMENT` | `ADDON_CREATION`, `ADDON_DELETION`, `APPLICATION_CREATION`, `APPLICATION_EDITION`, `APPLICATION_DELETION` | diff --git a/content/doc/account/organisations.md b/content/doc/account/organisations.md index 94acffba9..2b01a3ae2 100644 --- a/content/doc/account/organisations.md +++ b/content/doc/account/organisations.md @@ -33,14 +33,14 @@ In order to add an organisation, just click on "Add an organisation" in the top The table below describes rights assigned to roles: -Role | Admin | Manager | Developer | Accountant | ------|-------|---------|-----------|------------| -Add Member | ✓ | ✓ | | | -Remove Member | ✓ | ✓ | | | -Add Application | ✓ | ✓ | ✓ | | -Remove Application | ✓ | ✓ | | | -Add / Remove add-on | ✓ | ✓ | | | -Edit organisation | ✓ | ✓ | | | -Delete organisation | ✓ | | | | -Access Bills & Receive Invoices | ✓ | | | ✓ | -Access Repositories | ✓ | ✓ | ✓ | | +| Role | Admin | Manager | Developer | Accountant | +| ------------------------------- | ----- | ------- | --------- | ---------- | +| Add Member | ✓ | ✓ | | | +| Remove Member | ✓ | ✓ | | | +| Add Application | ✓ | ✓ | ✓ | | +| Remove Application | ✓ | ✓ | | | +| Add / Remove add-on | ✓ | ✓ | | | +| Edit organisation | ✓ | ✓ | | | +| Delete organisation | ✓ | | | | +| Access Bills & Receive Invoices | ✓ | | | ✓ | +| Access Repositories | ✓ | ✓ | ✓ | | diff --git a/content/doc/account/ssh-keys-management.md b/content/doc/account/ssh-keys-management.md index 9954b2cc8..d8177a0ac 100644 --- a/content/doc/account/ssh-keys-management.md +++ b/content/doc/account/ssh-keys-management.md @@ -149,7 +149,7 @@ clever curl -X PUT -H "Content-Type: application/json" --data "\"$(cat ~/.ssh/yo If you want to clone a repository from a private repository, you can add a [private SSH key](/doc/reference/common-configuration#private-ssh-key) to an application by creating a folder clevercloud at the root of your application and creating the file `clevercloud/ssh.json` with the following content: -```json{filename="clevercloud/ssh.json"} +```json {filename="clevercloud/ssh.json"} { "privateKeyFile": "path/to/file" } diff --git a/content/doc/addons/cellar.md b/content/doc/addons/cellar.md index cedb35a8a..d495ea348 100644 --- a/content/doc/addons/cellar.md +++ b/content/doc/addons/cellar.md @@ -188,9 +188,10 @@ You only need to specify a custom endpoint (e.g. `cellar-c2.services.clever-clou [Bun](https://bun.sh) includes a [native S3 client](https://bun.sh/docs/api/s3) with no external dependency. It works with any S3-compatible service, including Cellar. **Required environment variables:** - - `CELLAR_ADDON_HOST` - Cellar endpoint (e.g., `cellar-c2.services.clever-cloud.com`) - - `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID - - `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key + +- `CELLAR_ADDON_HOST` - Cellar endpoint (e.g., `cellar-c2.services.clever-cloud.com`) +- `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID +- `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key These variables are automatically available in your application when you [link a Cellar add-on](/doc/addons/cellar/) to it on Clever Cloud, regardless of the runtime (for example in a [Node.js & Bun application](/doc/applications/nodejs/)). @@ -236,9 +237,10 @@ You only need to specify a custom endpoint (e.g. `cellar-c2.services.clever-clou Using AWS SDK for JavaScript v3 (recommended): **Required environment variables:** - - `CELLAR_ADDON_HOST` - Cellar endpoint URL (e.g., `https://cellar-c2.services.clever-cloud.com`) - - `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID - - `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key + +- `CELLAR_ADDON_HOST` - Cellar endpoint URL (e.g., `https://cellar-c2.services.clever-cloud.com`) +- `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID +- `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key Some SDKs require a region even with a custom endpoint, so set `region` to the literal value "`default`". @@ -303,13 +305,15 @@ You only need to specify a custom endpoint (e.g. `cellar-c2.services.clever-clou Make sure to use latest version of the `2.X`, new versions are released regularly. See [the AWS Java SDK Documentation](https://github.com/aws/aws-sdk-java-v2/#using-the-sdk) for more details. **Required environment variables:** - - `CELLAR_ADDON_HOST` - Cellar endpoint URL (e.g., `https://cellar-c2.services.clever-cloud.com`) - - `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID - - `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key + +- `CELLAR_ADDON_HOST` - Cellar endpoint URL (e.g., `https://cellar-c2.services.clever-cloud.com`) +- `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID +- `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key **Optional (for SDK 2.30.0+ checksum compatibility):** - - `AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED` - - `AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED` + +- `AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED` +- `AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED` Some SDKs require a region even with a custom endpoint, so just provide the literal value "`default`" to satisfy that requirement. @@ -375,9 +379,10 @@ You only need to specify a custom endpoint (e.g. `cellar-c2.services.clever-clou This script uses boto3, the AWS SDK for Python. **Required environment variables:** - - `CELLAR_ADDON_HOST` - Cellar endpoint URL (e.g., `https://cellar-c2.services.clever-cloud.com`) - - `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID - - `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key + +- `CELLAR_ADDON_HOST` - Cellar endpoint URL (e.g., `https://cellar-c2.services.clever-cloud.com`) +- `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID +- `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key Some SDKs require a region even with a custom endpoint, so set the `region_name` to the literal value "`default`" when instantiating the client. @@ -430,25 +435,26 @@ You only need to specify a custom endpoint (e.g. `cellar-c2.services.clever-clou you must configure a S3 service with a custom endpoint. **Required environment variables:** - - `CELLAR_ADDON_HOST` - Cellar endpoint URL (e.g., `cellar-c2.services.clever-cloud.com`) - - `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID - - `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key + +- `CELLAR_ADDON_HOST` - Cellar endpoint URL (e.g., `cellar-c2.services.clever-cloud.com`) +- `CELLAR_ADDON_KEY_ID` - Your Cellar access key ID +- `CELLAR_ADDON_KEY_SECRET` - Your Cellar secret access key Use this configuration in your `config/storage.yml`: - ```yaml {filename="config/storage.yml"} - cellar: - service: S3 - access_key_id: <%= ENV.fetch('CELLAR_ADDON_KEY_ID') %> - secret_access_key: <%= ENV.fetch('CELLAR_ADDON_KEY_SECRET') %> - endpoint: https://<%= ENV.fetch('CELLAR_ADDON_HOST') %> - region: 'us-west-1' - force_path_style: true - bucket: mybucket - # If experiencing checksum validation errors, add: - # request_checksum_calculation: 'when_required' - # response_checksum_validation: 'when_required' - ``` +```yaml {filename="config/storage.yml"} +cellar: + service: S3 + access_key_id: <%= ENV.fetch('CELLAR_ADDON_KEY_ID') %> + secret_access_key: <%= ENV.fetch('CELLAR_ADDON_KEY_SECRET') %> + endpoint: https://<%= ENV.fetch('CELLAR_ADDON_HOST') %> + region: 'us-west-1' + force_path_style: true + bucket: mybucket + # If experiencing checksum validation errors, add: + # request_checksum_calculation: 'when_required' + # response_checksum_validation: 'when_required' +``` Although the `region` parameter appears, it's not used by Cellar. The region value serves to satisfy ActiveStorage and the aws-sdk-s3 gem. Without a region option, an exception would raise : `missing keyword: region (ArgumentError)`. If region is an empty string you will get the following error: `missing region; use :region option or export region name to ENV['AWS_REGION'] (Aws::Errors::MissingRegionError)`. @@ -513,7 +519,6 @@ s3cmd delpolicy s3:// The original ACL should apply to all of your objects after that. - ### IP restrictions If you need to restrict your S3 Cellar to certain IPs, you can use a policy. @@ -553,12 +558,14 @@ To do so, you can use the template below in a `policy.json` file. This example s ``` To apply the policy, use this command: -``` + +```text s3cmd setpolicy ./policy.json s3:// ``` To delete the policy, use this command: -``` + +```text s3cmd delpolicy ./policy.json s3:// ``` @@ -696,9 +703,9 @@ Only the latest version of a file is visible, while previous versions remain hid Versioning can't be enabled for a single file: it will cover the entire bucket. A bucket can be in one of three state : - - Unversioned (The default) - - Versioning-enabled - - Versioning-suspended +- Unversioned (The default) +- Versioning-enabled +- Versioning-suspended You enable and suspend versioning at the bucket level. Once you enable versioning on a bucket, it can never return to an unversioned state. But you can suspend versioning on that bucket at any time. Once versioning is enabled, any object you add have a unique version ID. Object that were already existing before enabling versioning have a version ID of `null`. @@ -718,7 +725,7 @@ For that reason, we do recommend you to enable versioning when creating a new bu mc alias set https://cellar-c2.services.clever-cloud.com ``` - ### Activate versioning with MinIO +### Activate versioning with MinIO To activate versioning, you can use MinIO and the following command. @@ -734,11 +741,11 @@ For that reason, we do recommend you to enable versioning when creating a new bu mc version info / --json ``` - ### How to use versioning +### How to use versioning with AWS CLI When versioning is enabled, the newly added object is automatically provided with a unique identifier. Only the latest version of an object is shown with a `mc ls /`. - #### List versioned objects +#### List versioned objects If you need to list all the object in your bucket, including the different versions of the files stored in it, you can run : @@ -752,7 +759,7 @@ When versioning is enabled, the newly added object is automatically provided wit mc ls --versions // ``` - #### Get a version of an object +#### Get a version of an object You can get the specific version of an object using its version ID obtained using the previous command. @@ -760,7 +767,7 @@ When versioning is enabled, the newly added object is automatically provided wit mc get --vid // ``` - #### Delete a version of an object +#### Delete a version of an object You can delete the specific version of an object using its version ID. @@ -768,14 +775,13 @@ When versioning is enabled, the newly added object is automatically provided wit mc rm --vid // ``` - {{< /tab >}} {{< tab name="AWS CLI" icon="aws" >}} The following command assumes you have configured your AWS CLI and added an alias as shown earlier in the section [Creating a bucket with AWS CLI](/doc/addons/cellar/#with-aws-cli) - ### Activate versioning with AWS CLI +### Activate versioning with AWS CLI To activate versioning, you can use AWS CLI. You can use the following command to enable it on a bucket. @@ -795,11 +801,11 @@ When versioning is enabled, the newly added object is automatically provided wit aws s3api get-bucket-versioning --bucket ``` - ### How to use versioning +### How to use versioning When versioning is enabled, the added object automatically gets a versionID. Only the latest version of an object if shown. - #### List all versioned Object +#### List all versioned Object If you need to list all the objects in your bucket, including the different versions of the files stored in it, you can use : @@ -807,7 +813,7 @@ When versioning is enabled, the newly added object is automatically provided wit aws s3api list-object-versions --bucket ``` - #### List all the version of a specific Object +#### List all the version of a specific Object If you want to check the different versions of a specific object, you can use the following command. In this example, we find the versions of test.txt : @@ -815,7 +821,7 @@ When versioning is enabled, the newly added object is automatically provided wit aws s3api list-object-versions --bucket --prefix ``` - #### Get the version of an Object +#### Get the version of an Object If you want to retrieve the previous version of an object, you need the versionID that you can get with any of the two previous command. You can use : @@ -823,7 +829,7 @@ When versioning is enabled, the newly added object is automatically provided wit aws s3api get-object --bucket --version-id '' --key /path/to/save/file/copy/test.txt ``` - #### Delete the version of an object +#### Delete the version of an object To remove a version of an object, you can use this command : diff --git a/content/doc/addons/config-provider.md b/content/doc/addons/config-provider.md index 43a4a82fc..8579678d5 100644 --- a/content/doc/addons/config-provider.md +++ b/content/doc/addons/config-provider.md @@ -25,15 +25,15 @@ Let's take an example with 2 Node.js applications exposing some REST APIs: `ship The `shipping-api` application needs the following environment variables: -* `PULSAR_TOPIC=order` -* `USER_API_HOST=https://user.example.com/api` -* `ENABLE_PARTNERS=true` +- `PULSAR_TOPIC=order` +- `USER_API_HOST=https://user.example.com/api` +- `ENABLE_PARTNERS=true` The `payment-api` application needs the following environment variables: -* `PULSAR_TOPIC=order` -* `USER_API_HOST=https://user.example.com/api` -* `ENABLE_SEPA=false` +- `PULSAR_TOPIC=order` +- `USER_API_HOST=https://user.example.com/api` +- `ENABLE_SEPA=false` ![Two Node.js applications with their own environment variables](/images/schema-config-provider-01.svg "Two Node.js applications with their own environment variables") @@ -72,10 +72,10 @@ At any point, you can link/unlink an application from the configuration provider ## Details and behaviour -* As with any other add-on, you can only link a configuration provider to applications that are in the same organisation. -* Variables defined directly in the application override the ones injected from the configuration provider. -* When you update the variables of a configuration provider, all applications linked to it will be automatically restarted. -* You can create multiple configuration providers in your organisation and link them to different applications. +- As with any other add-on, you can only link a configuration provider to applications that are in the same organisation. +- Variables defined directly in the application override the ones injected from the configuration provider. +- When you update the variables of a configuration provider, all applications linked to it will be automatically restarted. +- You can create multiple configuration providers in your organisation and link them to different applications. ## Pricing diff --git a/content/doc/addons/elastic.md b/content/doc/addons/elastic.md index 6e5476788..cd07a9d01 100644 --- a/content/doc/addons/elastic.md +++ b/content/doc/addons/elastic.md @@ -81,7 +81,7 @@ You can change the URL to point to your own custom configuration. Here is a configuration example for RUM activation: -```bash{filename="es-apm-serverconfig.sh"} +```bash {filename="es-apm-serverconfig.sh"} #!/bin/bash -l cat <apm-server.yml @@ -132,21 +132,21 @@ The agent will periodically scan for JVM processes and will attach to them if ne Elasticsearch managed by Clever Cloud comes with these plugins, you can activate at add-on creation: -| Plugin | Description | -| ------ | ----------- | -| analysis-icu | Adds extended Unicode support using the ICU libraries | -| analysis-kuromoji | Advanced analysis of Japanese using the Kuromoji analyzer | -| analysis-nori | Morphological analysis of Korean using the Lucene Nori analyzer | -| analysis-phonetic | Analyzes tokens into their phonetic equivalent using Soundex, Metaphone, Caverphone, and other codecs | -| analysis-smartcn | An analyzer for Chinese or mixed Chinese-English text | -| analysis-stempel | Provides high quality stemming for Polish | -| analysis-ukrainian | Provides stemming for Ukrainian | -| discovery-ec2 | Uses the AWS API to identify the addresses of seed hosts | -| discovery-azure-classic | Uses the Azure Classic API to identify the addresses of seed hosts | -| discovery-gce | Uses the GCE API to identify the addresses of seed hosts | -| mapper-size | Provides the `_size` metadata field which, when enabled, indexes the size in bytes of the original `_source` field | -| mapper-murmur3 | Allows hashes to be computed at index-time and stored in the index for later use with the cardinality aggregation | -| mapper-annotated-text | Provides the ability to index text that is a combination of free-text and special markup | +| Plugin | Description | +| ----------------------- | ------------------------------------------------------------------------------------------------------------------ | +| analysis-icu | Adds extended Unicode support using the ICU libraries | +| analysis-kuromoji | Advanced analysis of Japanese using the Kuromoji analyzer | +| analysis-nori | Morphological analysis of Korean using the Lucene Nori analyzer | +| analysis-phonetic | Analyzes tokens into their phonetic equivalent using Soundex, Metaphone, Caverphone, and other codecs | +| analysis-smartcn | An analyzer for Chinese or mixed Chinese-English text | +| analysis-stempel | Provides high quality stemming for Polish | +| analysis-ukrainian | Provides stemming for Ukrainian | +| discovery-ec2 | Uses the AWS API to identify the addresses of seed hosts | +| discovery-azure-classic | Uses the Azure Classic API to identify the addresses of seed hosts | +| discovery-gce | Uses the GCE API to identify the addresses of seed hosts | +| mapper-size | Provides the `_size` metadata field which, when enabled, indexes the size in bytes of the original `_source` field | +| mapper-murmur3 | Allows hashes to be computed at index-time and stored in the index for later use with the cardinality aggregation | +| mapper-annotated-text | Provides the ability to index text that is a combination of free-text and special markup | {{< callout type="info" >}} Plugin activation is only available at add-on creation, through [API](/api) or the `--option` flag of [Clever Tools](/doc/cli/addons/#create--rename--delete). You must pass the option as a comma-separated list: `plugins=plugin1,plugin2`. To modify enabled plugins on an existing add-on, contact [support team](https://console.clever-cloud.com/ticket-center-choice). diff --git a/content/doc/addons/fs-bucket.md b/content/doc/addons/fs-bucket.md index 7039c99ca..1734d2bf7 100644 --- a/content/doc/addons/fs-bucket.md +++ b/content/doc/addons/fs-bucket.md @@ -98,12 +98,12 @@ You can find a pre-filled json object to copy in the dashboard of your FSBucket It's a json array containing objects with at least two fields: -Usage | Field | Description ----------|--------------|-------------------------------------------------------------- -Required | bucket | The bucket id you can find in the console. It begins with `bucket_`. This is for "old-style" buckets (created before the 7 December 2015) -Required | bucket_host | The bucket host you can find in the console. It begins with `bucket-` and ends with `services.clever-cloud.com`. This is for "new-style" buckets. -Required | folder | The folder you want the bucket to be mounted in. Should start with `/`. Using the example *myFolder*, you can access your bucket via the *myFolder* folder at the root of your application (which absolute path is available in the `APP_HOME` environment variable) -Optional | apps | Whitelist of the applications allowed to mount this bucket. It's helpful if you need to deploy a *preprod* app and a *prod* app using the exact same codebase but different buckets +| Usage | Field | Description | +| -------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Required | bucket | The bucket id you can find in the console. It begins with `bucket_`. This is for "old-style" buckets (created before the 7 December 2015) | +| Required | bucket_host | The bucket host you can find in the console. It begins with `bucket-` and ends with `services.clever-cloud.com`. This is for "new-style" buckets. | +| Required | folder | The folder you want the bucket to be mounted in. Should start with `/`. Using the example *myFolder*, you can access your bucket via the *myFolder* folder at the root of your application (which absolute path is available in the `APP_HOME` environment variable) | +| Optional | apps | Whitelist of the applications allowed to mount this bucket. It's helpful if you need to deploy a *preprod* app and a *prod* app using the exact same codebase but different buckets | The folder must not exist in your repository (or it needs to be empty). Otherwise, the mount of your bucket will be ignored. You can mount the same bucket in different folders, but they will share the same content, so it's not the solution. You should prefer to mount the bucket in only one folder and then manage multiple subfolders in it. @@ -131,8 +131,8 @@ in the FS bucket. The **Add-on information** tab of your FS Bucket in [Clever Cloud Console](https://console.clever-cloud.com) displays information you need to connect using SSH File Transfer Protocol (SFTP). You can use the following SSH public keys to ensure the connection is authentic and trusted: -| Algorithm | Key size | Fingerprint | -|-----------|----------|----------------------------------------------------| +| Algorithm | Key size | Fingerprint | +| --------- | -------- | ---------------------------------------------------- | | ED25519 | 256 | `SHA256:+ku6hhQb1O3OVzkZa2B+htPD+P+5K/X6QQYWXym/4Zo` | | ED25519 | 256 | `SHA256:8tZzRvA3Fh9poG7g1bu8m0LQS819UBh7AYcEXJYiPqw` | | ED25519 | 256 | `SHA256:HHGCP5cf0jQbQrIRXjiC9aYJGNQ+L9ijOmJUueLp+9A` | diff --git a/content/doc/addons/heptapod.md b/content/doc/addons/heptapod.md index 0468e637a..5c8ff3fe4 100644 --- a/content/doc/addons/heptapod.md +++ b/content/doc/addons/heptapod.md @@ -31,18 +31,18 @@ Clever Cloud users can benefit from **Heptapod Cloud** software, along with **He Heptapod Cloud comes with the following benefits: -* **Cost Reduction**: No licensing or application maintenance costs, flexible and competitive usage-based pricing per active user. -* **Automatic Updates**: Heptapod aligns with the continuously evolving GitLab, ensuring you effortlessly benefit from the latest features and security patches. -* **Technical and Functional Support**: Whether for technical or functional questions, support teams are ready to answer all your queries. -* **Scalability**: As your team grows or you manage dozens or hundreds of small or large projects for testing and deployment, Heptapod Cloud is designed to handle it. Increase capacities or quantities of CI/CD runners associated with your projects, those of runtimes, storage, or databases managed by Clever Cloud, or adjust bandwidth to handle heavy loads. All these services are native and structured to meet your scaling needs with ease. +- **Cost Reduction**: No licensing or application maintenance costs, flexible and competitive usage-based pricing per active user. +- **Automatic Updates**: Heptapod aligns with the continuously evolving GitLab, ensuring you effortlessly benefit from the latest features and security patches. +- **Technical and Functional Support**: Whether for technical or functional questions, support teams are ready to answer all your queries. +- **Scalability**: As your team grows or you manage dozens or hundreds of small or large projects for testing and deployment, Heptapod Cloud is designed to handle it. Increase capacities or quantities of CI/CD runners associated with your projects, those of runtimes, storage, or databases managed by Clever Cloud, or adjust bandwidth to handle heavy loads. All these services are native and structured to meet your scaling needs with ease. Heptapod Cloud provides your team with a suite of collaborative tools for software or document production management: -* **Team, Collaborators, and Access Rights:** Add and manage team members, organise roles and access rights based on projects. -* **Git and Mercurial Repository Management:** Heptapod provides a robust and intuitive repository management system for Git and Mercurial, allowing you to effortlessly create, manage, and collaborate on your codebase or documents. With advanced version control and branch management features, you can easily track changes, merge your code, and maintain the integrity and history of your private or public projects. -* **Project Management and Ticket Tracking:** The ticket tracking system allows you to efficiently manage tasks, incidents, and collaborate seamlessly with your team. Stay organized by setting milestones, qualifying with labels, and customising workflows for advanced control of your operations. -* **Collaboration and Code Review:** Heptapod provides a wide range of features for effective collaboration, code or document reviews, online comments, and real-time collaboration tools. Work seamlessly with your team, track exchanges, merge requests, and improve the overall quality of your projects. -* **Embedded Wiki and Documentation:** Knowledge sharing is crucial for high-performing teams. Easily create and maintain comprehensive documentation for your projects, centralise and share knowledge, and provide a smooth experience for new collaborators. +- **Team, Collaborators, and Access Rights:** Add and manage team members, organise roles and access rights based on projects. +- **Git and Mercurial Repository Management:** Heptapod provides a robust and intuitive repository management system for Git and Mercurial, allowing you to effortlessly create, manage, and collaborate on your codebase or documents. With advanced version control and branch management features, you can easily track changes, merge your code, and maintain the integrity and history of your private or public projects. +- **Project Management and Ticket Tracking:** The ticket tracking system allows you to efficiently manage tasks, incidents, and collaborate seamlessly with your team. Stay organized by setting milestones, qualifying with labels, and customising workflows for advanced control of your operations. +- **Collaboration and Code Review:** Heptapod provides a wide range of features for effective collaboration, code or document reviews, online comments, and real-time collaboration tools. Work seamlessly with your team, track exchanges, merge requests, and improve the overall quality of your projects. +- **Embedded Wiki and Documentation:** Knowledge sharing is crucial for high-performing teams. Easily create and maintain comprehensive documentation for your projects, centralise and share knowledge, and provide a smooth experience for new collaborators. ## Accessing Heptapod Cloud @@ -87,10 +87,10 @@ Fully integrated with Heptapod Cloud, the service can also be used from a self-m Clever Cloud Runners for Heptapod comes with the following features: -* **Quick activation:** Activate Clever Cloud Runners for Heptapod for your organisation with just one click. -* **Easy customization:** Easily define your pipelines using templates for the most popular languages. Edit and validate definitions from the interface or directly from the project file. -* **Integrated tracking:** Monitor the execution of your tasks in real time, receive notifications of pipeline success or failure, and view activity reports online. -* **[Components Catalog](/doc/ci-cd/gitlab/#deploy-directly-from-heptapod):** Connect your repository to Clever Cloud and deploy on production, create review apps, and automate tasks. +- **Quick activation:** Activate Clever Cloud Runners for Heptapod for your organisation with just one click. +- **Easy customization:** Easily define your pipelines using templates for the most popular languages. Edit and validate definitions from the interface or directly from the project file. +- **Integrated tracking:** Monitor the execution of your tasks in real time, receive notifications of pipeline success or failure, and view activity reports online. +- **[Components Catalog](/doc/ci-cd/gitlab/#deploy-directly-from-heptapod):** Connect your repository to Clever Cloud and deploy on production, create review apps, and automate tasks. #### Provisioning @@ -114,10 +114,10 @@ This is nothing but the standard GitLab mechanism. If you maintain your own Grou In order to have the Clever Cloud Runner take your jobs, simply activate the shared runners on the wished Groups and Projects: -* Navigate to the Group Settings CI/CD page. -* Expand the Runners section. -* You will be able to activate the shared runners directly from there or allow Projects or sub-Groups to override the Group setting in case you don't want to activate on the full Group. -* Always check the resulting configuration in the Projects Settings CI/CD pages, and correct it if needed. Changes in the Group Settings are not always immediately taken into account on enclosed Projects. +- Navigate to the Group Settings CI/CD page. +- Expand the Runners section. +- You will be able to activate the shared runners directly from there or allow Projects or sub-Groups to override the Group setting in case you don't want to activate on the full Group. +- Always check the resulting configuration in the Projects Settings CI/CD pages, and correct it if needed. Changes in the Group Settings are not always immediately taken into account on enclosed Projects. #### Running only the Clever Cloud Runner @@ -178,7 +178,7 @@ tests: ##### Differences with a Heptapod Runner using the standard Docker executor -**Automatic Dependency Proxy** +###### Automatic Dependency Proxy The Dependency Proxy is a standard GitLab Free feature that provides transparent caching of Docker Hub images to minimize bandwidth and avoid rate limiting problems. @@ -186,7 +186,8 @@ tests: The automatic Dependency Proxy should be mostly transparent to users, except in case of services using a namespaced Docker image and not having an explicit alias. For these, we provide a single service network name whereas the standard executor provides two (replacing forward slashes either by double underscores or dashes). We chose the dash-based RFC compliant one. In short, use octobus-heptapod to reach a service whose Docker image is octobus/heptapod:sometag, or better, set your own explicit alias. -**Job cache** +###### Job cache + Currently, the job cache is discarded at the end of each job. This is because we don't have offloading capabilities for the cache yet, and the entire virtual machine gets decommissioned at the end of the job. @@ -210,7 +211,7 @@ In other words, one size does not fit all. Jobs executed by the Clever Cloud Runner can specify the scale (flavour) of the Docker host it needs, using the `CI_CLEVER_CLOUD_FLAVOR` variable. -```yaml{filename=".gitlab-ci.yml"} +```yaml {filename=".gitlab-ci.yml"} small-job: variables: CI_CLEVER_CLOUD_FLAVOR: XS diff --git a/content/doc/addons/keycloak.md b/content/doc/addons/keycloak.md index 32077077f..c40bbbb5a 100644 --- a/content/doc/addons/keycloak.md +++ b/content/doc/addons/keycloak.md @@ -25,7 +25,9 @@ To fit the most common needs, the Keycloak add-on comes with batteries included: {{< callout type="info" >}}Share your feedback on Keycloak operator through [our community page](https://github.com/CleverCloud/Community/discussions/categories/keycloak){{< /callout >}} ## Key features + Keycloak on Clever Cloud allows you to effortlessly set up a tailored authentication and access management solution, that you can adjust to your needs and workloads. It offers a wide panel of services such as: + - Secure Identity Management - Single Sign-On (SSO) - Centralized Administration @@ -41,6 +43,7 @@ Keycloak on Clever Cloud allows you to effortlessly set up a tailored authentica The Clever Cloud Keycloak add-on is designed to meet the most common needs, built with [Please Open-it](https://please-open.it/) and hosted on our services. For the most complex and loaded systems, our partner and Keycloak experts behind this add-on, can provide assistance: [contact us](mailto:sales@clever-cloud.com). ## How it works? + When you create the Keycloak add-on, Clever Cloud automatically deploys: - A [Java](/doc/applications/java/java-jar) instance with Keycloak pre-loaded and configured @@ -56,6 +59,7 @@ By default, Keycloak on Clever Cloud uses small-size resources, i.e: - Less than 100 MB in FS Bucket They are dimensioned to suit a majority of needs. Even if this Keycloak add-on might handle heavy traffic and an important number of simultaneous connections, the default configuration should handle the following load (based on [Keycloak](https://www.keycloak.org/high-availability/concepts-memory-and-cpu-sizing) sizing recommendation): + - 5 logins by second - 90 credential grants by the second - 70 refresh tokens by second @@ -65,6 +69,7 @@ You can however manage and adjust them directly in the Console to fit your needs ## Create a Keycloak add-on ### From the Console + 1. [Create a new add-on](https://console.clever-cloud.com/users/me/addons/new) by clicking the **Create…** dropdown in the sidebar and then **an add-on** 2. Select the Keycloak add-on 3. You can skip linking the add-on to an application, it won't be needed @@ -77,7 +82,7 @@ You can however manage and adjust them directly in the Console to fit your needs Make sure you have `clever-tools` installed locally. Please refer to the [setup guide](/doc/cli/install/) if needed. In your terminal, run `clever addon create keycloak --org ` (`--org` is optional). You'll get URLs to manage your Keycloak instance and the temporary credentials: -``` +```bash $ clever addon create keycloak myKeycloak Add-on created successfully! ID: addon_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx @@ -117,6 +122,7 @@ If you also need a more resilient database, contact your sales representative or ## Version management To change the version of a Keycloak add-on on Clever Cloud, you can: + - Use the Console Dashboard - Use [Clever Tools](/doc/cli/operators/) - Update the `CC_KEYCLOAK_VERSION` environment variable of the underlying Java Application and rebuild it @@ -183,12 +189,12 @@ You can restrict who can reach your Keycloak instance with two complementary mec Starting with version `26.6`, the Keycloak add-on can filter incoming requests based on the client's public IP, with separate rules for each realm and for each endpoint category (admin console and admin API, public endpoints, SCIM provisioning). Filtering is configured through environment variables of the underlying Java application. Each variable accepts a comma-separated list of IP addresses and blocked requests receive an `HTTP 403` response. -| Variable | Scope | Protected paths | -|----------|-------|-----------------| -| `CC_KEYCLOAK_ADMIN_IPS_` | Admin endpoints of a given realm | `/admin//*`, `/admin/realms//*` | -| `CC_KEYCLOAK_PUBLIC_IPS_` | Public endpoints of a given realm (login, tokens, user authentication) | `/realms//*` | -| `CC_KEYCLOAK_SCIM_IPS_` | SCIM provisioning endpoints of a given realm (requires the `scim-api` feature, see below) | `/realms//scim/*` | -| `CC_KEYCLOAK_ADMIN_IPS` | Global fallback for admin endpoints not covered by a per-realm rule | `/admin/*` | +| Variable | Scope | Protected paths | +| -------------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------------------- | +| `CC_KEYCLOAK_ADMIN_IPS_` | Admin endpoints of a given realm | `/admin//*`, `/admin/realms//*` | +| `CC_KEYCLOAK_PUBLIC_IPS_` | Public endpoints of a given realm (login, tokens, user authentication) | `/realms//*` | +| `CC_KEYCLOAK_SCIM_IPS_` | SCIM provisioning endpoints of a given realm (requires the `scim-api` feature, see below) | `/realms//scim/*` | +| `CC_KEYCLOAK_ADMIN_IPS` | Global fallback for admin endpoints not covered by a per-realm rule | `/admin/*` | The realm name in the variable suffix must match the realm name as it appears in URLs (case-sensitive). Per-realm rules take precedence over the global admin filter. If none of these variables is set, Keycloak keeps its standard public behavior. @@ -221,6 +227,7 @@ You can also assign these flows to your own clients if needed. Since version `25.06`, Keycloak add-on exposes [Prometheus](https://prometheus.io/) metrics on port `9000`. Use Clever Cloud's [Grafana integration](/doc/metrics/#publish-your-own-metrics) to visualize them. You can also use a Grafana dashboard ready to import, available starting with Keycloak `26.2` release: + - Go to the `Metrics in Grafana` section of your organisation or personal space in [Console](https://console.clever-cloud.com/) - Open Grafana, click on the `+` icon in the upper right corner and select `Import` dashboard - Import this [JSON file](https://cc-keycloak.cellar-c2.services.clever-cloud.com/keycloak-grafana-dashboard.json) diff --git a/content/doc/addons/kms.md b/content/doc/addons/kms.md index d1006d83f..c39801eb6 100644 --- a/content/doc/addons/kms.md +++ b/content/doc/addons/kms.md @@ -58,6 +58,7 @@ flowchart LR ## Prerequisites To use Clever KMS you'll need : + - An authorized access for your organisation - Clever Tools with KMS commands - A compatible Vault CLI @@ -245,6 +246,7 @@ The ciphertext isn't stored by Clever KMS; it must be stored by the client in it ### Decrypt ciphertext To get back the original payload, call the decrypt route with the ciphertext and the transit key name: + ```bash ❯ vault write transit/decrypt/my-key ciphertext=vault:v1:75Le-Zs1fzJP-_l-vPdePoabvNXYGsBtcj0Ii4LcJ_eNHeImfNWz1aAH82uyPcGgyfExcyNk5Ds9lW-C Key Value diff --git a/content/doc/addons/materia-kv.md b/content/doc/addons/materia-kv.md index 82a523fee..ab5ef2c15 100644 --- a/content/doc/addons/materia-kv.md +++ b/content/doc/addons/materia-kv.md @@ -64,7 +64,7 @@ redis-cli -h $KV_HOST -p $KV_PORT --tls PING Here is an example of what you can expect: -``` +```bash $ clever addon create kv testKV Add-on created successfully! @@ -88,11 +88,11 @@ You can also deploy Materia KV add-ons with [Terraform provider](https://registr To connect to a Materia KV add-on, you need 3 parameters: the host, the port and a token. You can set these parameters as environment variables by doing `source <(clever addon env addon ADDON_ID -F shell)`. The variables set are: -* `$KV_HOST` and its alias `$REDIS_HOST` -* `$KV_PORT` and its alias `$REDIS_PORT` -* `$KV_TOKEN` and its alias `$REDIS_PASSWORD` -* `$REDIS_CLI_URL` -* `$REDISCLI_AUTH` +- `$KV_HOST` and its alias `$REDIS_HOST` +- `$KV_PORT` and its alias `$REDIS_PORT` +- `$KV_TOKEN` and its alias `$REDIS_PASSWORD` +- `$REDIS_CLI_URL` +- `$REDISCLI_AUTH` You can directly use these environment variables to connect to a Materia KV add-on using `redis-cli` if `REDISCLI_AUTH` is set: @@ -102,7 +102,6 @@ redis-cli -h $KV_HOST -p $KV_PORT --tls Materia KV is also compatible with alternatives such as [iredis](https://github.com/laixintao/iredis). - ### Fish shell users If you use the Fish shell, you can use the following command to set the environment variables: @@ -119,7 +118,7 @@ By default, Materia KV uses TLS on the 6379 port. You can use non-TLS connection We're exploring how [Clever Tools](https://github.com/CleverCloud/clever-tools/) can natively support Materia KV and helps you to manage such add-ons without any additional software or configuration. The `clever kv` command is available since [version 3.11](https://github.com/CleverCloud/clever-tools/releases/tag/3.11.0). -* [Learn more about Clever KV](/doc/cli/kv-stores/) +- [Learn more about Clever KV](/doc/cli/kv-stores/) ### Supported types and commands @@ -131,85 +130,86 @@ Supported value types are: Find below the list of currently supported commands: -|
Commands
| Description | -| ------- | ----------- | -| `APPEND` | If `key` already exists and is a string, this command appends the value at the end of the string. If `key` doesn't exist it is created and set as an empty string, so `APPEND` will be similar to `SET` in this special case. | -| `AUTH` | Authenticate the current connection using the token as `password`. | -| `CLIENT ID` | Returns the `ID` of the current connection. A connection ID has is never repeated and is monotonically incremental. | -| `COMMAND` | Return an array with details about every supported command. | -| `COMMAND COUNT` | Return the number of supported commands. | -| `COMMAND DOCS` | Return documentary information about commands. By default, the reply includes all the server's commands. You can use the optional command-name argument to specify the names of one or more commands. The reply includes a map for each returned command. | -| `COMMAND INFO` | Returns an array reply of details about multiple Materia KV commands. Same result format as `COMMAND` except you can specify which commands get returned. If you request details about non-existing commands, their return position will be `nil`. | -| `COMMAND LIST` | Return an array of the server's command names. | -| `DBSIZE` | Return the number of keys in the currently-selected database. | -| `DECR` | Decrements the number stored at `key` by one. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. | -| `DECRBY` | Decrements the number stored at `key` by the given `decrement`. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. | -| `DEL` | Removes the specified `key`. A key is ignored if it doesn't exist. | -| `EXISTS` | Returns if `key` exists. | -| `EXPIRE` | Set a `key` time to live in seconds. After the timeout has expired, the `key` will be automatically deleted. The time to live can be updated using the `EXPIRE` command or cleared using the `PERSIST` command. | -| `EXPIREAT` | Sets a `key` to expire at the specified Unix timestamp (in seconds). After that time, the `key` is automatically deleted. Returns `1` if the timeout was set, `0` if the `key` doesn't exist. | -| `FLUSHALL` | Delete all the keys of all the existing databases, not just the currently selected one. This command never fails. | -| `FLUSHDB` | Delete all the keys of the currently selected DB. This command never fails. | -| `GET` | Get the value of `key`. If the `key` doesn't exist the special value nil is returned. An error is returned if the value stored at `key` is not a string, because `GET` only handles string values. | -| `GETBIT` | Returns the bit value at offset in the string value stored at `key`. | -| `GETDEL` | Gets the value of `key` and deletes the key. If the `key` doesn't exist, returns `nil`. Returns an error if the value stored at `key` isn't a string. | -| `GETRANGE` | Returns the substring of the string value stored at `key`, determined by the offsets start and end (both are inclusive). Negative offsets can be used in order to provide an offset starting from the end of the string. So `-1` means the last character, `-2` the penultimate and so forth. | -| `HDEL` | Removes the specified fields from the hash stored at `key`. Specified fields that do not exist within this hash are ignored. If `key` does not exist, it is treated as an empty hash and this command returns `0`. | -| `HELLO` | Switch to a different protocol, optionally authenticating and setting the connection's name, or provide a contextual client report. It always replies with a list of current server and connection properties. | -| `HEXISTS` | Returns `1` if `field` exists in the hash stored at `key`, `0` if `field` or `key` don't exist. Returns an error if the value stored at `key` isn't a hash. | -| `HGET` | Returns the value associated with `field` in the hash stored at `key`. If `key` does not exist, or `field` is not present in the hash, `nil` is returned. | -| `HGETALL` | Returns all fields and values of the hash stored at `key`. In the returned value, every field name is followed by its value, so the length of the reply is twice the size of the hash. | -| `HINCRBY` | Increments the number stored at `field` in the hash stored at `key` by the given `increment`. If `key` doesn't exist, creates a new key holding a hash. If `field` doesn't exist, sets the value to `0` before performing the operation. Returns an error if the field contains a value of the wrong type or the resulting value exceeds a 64-bit signed integer. | -| `HLEN` | Returns the number of fields contained in the hash stored at `key`. If `key` does not exist, it is treated as an empty hash and `0` is returned. | -| `HMGET` | Returns the values associated with the specified `fields` in the hash stored at `key`. For every field that does not exist in the hash, a `nil` value is returned. Because of this, the operation never fails. | -| `HSCAN` | Incrementally iterate over hash fields and associated values. It is a cursor based iterator, this means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. An iteration starts when the cursor is set to `0`, and terminates when the cursor returned by the server is `0`. | -| `HSET` | Sets the specified fields to their respective values in the hash stored at `key`. If `key` does not exist, a new key holding a hash is created. If `key` exists but does not hold a hash, an error is returned. | -| `HSETNX` | Sets `field` in the hash stored at `key` to `value`, only if `field` doesn't yet exist. If `key` doesn't exist, creates a new key holding a hash. If `field` already exists, the operation has no effect. Returns `1` if `field` is a new field in the hash and the value was set, `0` if `field` already exists. | -| `INCR` | Increments the number stored at `key` by one. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. | -| `INCRBY` | Increments the number stored at `key` by the given `increment`. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. | -| `INCRBYFLOAT` | Increment the string representing a floating point number stored at `key` by the specified `increment`. If the key does not exist, it is set to `0` before performing the operation. An error is returned if the key contains a value of the wrong type or a string that can not be represented as a floating point number. | -| `INFO` | The `INFO` command returns information and statistics about the server in a format that is simple to parse by computers and easy to read by humans. | -| `JSON.DEL` | Deletes JSON value at path from key. Returns the number of paths deleted. Can delete array elements or object fields. | -| `JSON.GET` | Gets JSON value at path from key. Supports both single and multiple path queries with different path notations. | -| `JSON.SET` | Sets JSON value at root path (`$`) and updating existing paths in key. Creates new key if it doesn't exist. | -| `KEYS` | Returns all keys matching `pattern`, can be `*` | -| `LOLWUT` | Returns Materia KV's version and might be hiding an easter egg 👀 | -| `MGET` | Returns the values of all specified keys. For every key that doesn't hold a string value or doesn't exist, the special value `nil` is returned. Because of this, the operation never fails. | -| `MSET` | Sets the given keys to their respective values. `MSET` replaces existing values with new values, just as regular `SET`. `MSET` is atomic, so all given keys are set at once. It is not possible for clients to see that some keys were updated while others are unchanged. | -| `PERSIST` | Remove the existing time to live associated with the `key`. | -| `PEXPIRE` | Set a `key` time to live in milliseconds. After the timeout has expired, the `key` will be automatically deleted. The time to live can be updated using the `PEXPIRE` command or cleared using the `PERSIST` command. | -| `PEXPIREAT` | Sets a `key` to expire at the specified absolute Unix timestamp in milliseconds. After that time, the `key` is automatically deleted. Returns `1` if the timeout was set, `0` if the `key` doesn't exist. | -| `PING` | Returns `PONG` if no argument is provided, otherwise return a copy of the argument as a bulk. | -| `PTTL` | Returns the remaining time to live of a `key`, in milliseconds. | -| `SADD` | Add the specified members to the set stored at `key`. Specified members that are already a member of this set are ignored. If `key` doesn't exist, a new set is created before adding the specified members. | -| `SCAN` | Incrementally iterate over a collection of elements. It is a cursor based iterator, this means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. An iteration starts when the cursor is set to `0`, and terminates when the cursor returned by the server is `0`. | -| `SCARD` | Returns the set cardinality (number of elements) of the set stored at `key`. | -| `SDIFF` | Returns the members of the set resulting from the difference between the first set and all the successive sets. | -| `SDIFFSTORE` | This command is equal to `SDIFF`, but instead of returning the resulting set, it is stored in `destination`. If `destination` already exists, it is overwritten. | -| `SET` | Set `key` to hold the string `value`. If key already holds a value, it is overwritten, regardless of its type. | -| `SETBIT` | Sets or clears the bit at offset in the string value stored at `key`. | -| `SINTER` | Returns the members of the set resulting from the intersection of all the given sets. | -| `SINTERCARD` | Returns the number of elements that would result from the intersection of all given sets. | -| `SINTERSTORE` | This command is equal to `SINTER`, but instead of returning the resulting set, it is stored in `destination`. If `destination` already exists, it is overwritten. | -| `SISMEMBER` | Returns if `member` is a member of the set stored at `key`. | -| `SMEMBERS` | Returns all the members of the set value stored at `key`. | -| `SMISMEMBER` | Returns whether each member is a member of the set stored at `key`. For every member, `1` is returned if the value is a member of the set, or `0` if the element is not a member of the set or if `key` doesn't exist. | -| `SMOVE` | Move `member` from the set at `source` to the set at `destination`. This operation is atomic. In every given moment the element will appear to be a member of `source` or `destination` for other clients. | -| `SPOP` | Removes and returns one or more random members from the set value stored at `key`. | -| `SRANDMEMBER` | When called with just the `key` argument, return a random element from the set value stored at `key`. | -| `SREM` | Remove the specified members from the set stored at `key`. Specified members that are not a member of this set are ignored. If `key` doesn't exist, it is treated as an empty set and this command returns `0`. | -| `SSCAN` | Incrementally iterate over set elements. It is a cursor based iterator, this means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. An iteration starts when the cursor is set to `0`, and terminates when the cursor returned by the server is `0`. | -| `STRLEN` | Returns the length of the string value stored at `key`. An error is returned when key holds a non-string value. | -| `SUNION` | Returns the members of the set resulting from the union of all the given sets. | -| `SUNIONSTORE` | This command is equal to `SUNION`, but instead of returning the resulting set, it is stored in `destination`. If `destination` already exists, it is overwritten. | -| `TTL` | Returns the remaining time to live of a `key`, in seconds. | -| `TYPE` | Returns the string representation of the type of the value stored at `key`. Can be: `hash`, `list`, `set` or `string`. | +| Commands | Description | +| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `APPEND` | If `key` already exists and is a string, this command appends the value at the end of the string. If `key` doesn't exist it is created and set as an empty string, so `APPEND` will be similar to `SET` in this special case. | +| `AUTH` | Authenticate the current connection using the token as `password`. | +| `CLIENT ID` | Returns the `ID` of the current connection. A connection ID has is never repeated and is monotonically incremental. | +| `COMMAND` | Return an array with details about every supported command. | +| `COMMAND COUNT` | Return the number of supported commands. | +| `COMMAND DOCS` | Return documentary information about commands. By default, the reply includes all the server's commands. You can use the optional command-name argument to specify the names of one or more commands. The reply includes a map for each returned command. | +| `COMMAND INFO` | Returns an array reply of details about multiple Materia KV commands. Same result format as `COMMAND` except you can specify which commands get returned. If you request details about non-existing commands, their return position will be `nil`. | +| `COMMAND LIST` | Return an array of the server's command names. | +| `DBSIZE` | Return the number of keys in the currently-selected database. | +| `DECR` | Decrements the number stored at `key` by one. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. | +| `DECRBY` | Decrements the number stored at `key` by the given `decrement`. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. | +| `DEL` | Removes the specified `key`. A key is ignored if it doesn't exist. | +| `EXISTS` | Returns if `key` exists. | +| `EXPIRE` | Set a `key` time to live in seconds. After the timeout has expired, the `key` will be automatically deleted. The time to live can be updated using the `EXPIRE` command or cleared using the `PERSIST` command. | +| `EXPIREAT` | Sets a `key` to expire at the specified Unix timestamp (in seconds). After that time, the `key` is automatically deleted. Returns `1` if the timeout was set, `0` if the `key` doesn't exist. | +| `FLUSHALL` | Delete all the keys of all the existing databases, not just the currently selected one. This command never fails. | +| `FLUSHDB` | Delete all the keys of the currently selected DB. This command never fails. | +| `GET` | Get the value of `key`. If the `key` doesn't exist the special value nil is returned. An error is returned if the value stored at `key` is not a string, because `GET` only handles string values. | +| `GETBIT` | Returns the bit value at offset in the string value stored at `key`. | +| `GETDEL` | Gets the value of `key` and deletes the key. If the `key` doesn't exist, returns `nil`. Returns an error if the value stored at `key` isn't a string. | +| `GETRANGE` | Returns the substring of the string value stored at `key`, determined by the offsets start and end (both are inclusive). Negative offsets can be used in order to provide an offset starting from the end of the string. So `-1` means the last character, `-2` the penultimate and so forth. | +| `HDEL` | Removes the specified fields from the hash stored at `key`. Specified fields that do not exist within this hash are ignored. If `key` does not exist, it is treated as an empty hash and this command returns `0`. | +| `HELLO` | Switch to a different protocol, optionally authenticating and setting the connection's name, or provide a contextual client report. It always replies with a list of current server and connection properties. | +| `HEXISTS` | Returns `1` if `field` exists in the hash stored at `key`, `0` if `field` or `key` don't exist. Returns an error if the value stored at `key` isn't a hash. | +| `HGET` | Returns the value associated with `field` in the hash stored at `key`. If `key` does not exist, or `field` is not present in the hash, `nil` is returned. | +| `HGETALL` | Returns all fields and values of the hash stored at `key`. In the returned value, every field name is followed by its value, so the length of the reply is twice the size of the hash. | +| `HINCRBY` | Increments the number stored at `field` in the hash stored at `key` by the given `increment`. If `key` doesn't exist, creates a new key holding a hash. If `field` doesn't exist, sets the value to `0` before performing the operation. Returns an error if the field contains a value of the wrong type or the resulting value exceeds a 64-bit signed integer. | +| `HLEN` | Returns the number of fields contained in the hash stored at `key`. If `key` does not exist, it is treated as an empty hash and `0` is returned. | +| `HMGET` | Returns the values associated with the specified `fields` in the hash stored at `key`. For every field that does not exist in the hash, a `nil` value is returned. Because of this, the operation never fails. | +| `HSCAN` | Incrementally iterate over hash fields and associated values. It is a cursor based iterator, this means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. An iteration starts when the cursor is set to `0`, and terminates when the cursor returned by the server is `0`. | +| `HSET` | Sets the specified fields to their respective values in the hash stored at `key`. If `key` does not exist, a new key holding a hash is created. If `key` exists but does not hold a hash, an error is returned. | +| `HSETNX` | Sets `field` in the hash stored at `key` to `value`, only if `field` doesn't yet exist. If `key` doesn't exist, creates a new key holding a hash. If `field` already exists, the operation has no effect. Returns `1` if `field` is a new field in the hash and the value was set, `0` if `field` already exists. | +| `INCR` | Increments the number stored at `key` by one. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. | +| `INCRBY` | Increments the number stored at `key` by the given `increment`. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. | +| `INCRBYFLOAT` | Increment the string representing a floating point number stored at `key` by the specified `increment`. If the key does not exist, it is set to `0` before performing the operation. An error is returned if the key contains a value of the wrong type or a string that can not be represented as a floating point number. | +| `INFO` | The `INFO` command returns information and statistics about the server in a format that is simple to parse by computers and easy to read by humans. | +| `JSON.DEL` | Deletes JSON value at path from key. Returns the number of paths deleted. Can delete array elements or object fields. | +| `JSON.GET` | Gets JSON value at path from key. Supports both single and multiple path queries with different path notations. | +| `JSON.SET` | Sets JSON value at root path (`$`) and updating existing paths in key. Creates new key if it doesn't exist. | +| `KEYS` | Returns all keys matching `pattern`, can be `*` | +| `LOLWUT` | Returns Materia KV's version and might be hiding an easter egg 👀 | +| `MGET` | Returns the values of all specified keys. For every key that doesn't hold a string value or doesn't exist, the special value `nil` is returned. Because of this, the operation never fails. | +| `MSET` | Sets the given keys to their respective values. `MSET` replaces existing values with new values, just as regular `SET`. `MSET` is atomic, so all given keys are set at once. It is not possible for clients to see that some keys were updated while others are unchanged. | +| `PERSIST` | Remove the existing time to live associated with the `key`. | +| `PEXPIRE` | Set a `key` time to live in milliseconds. After the timeout has expired, the `key` will be automatically deleted. The time to live can be updated using the `PEXPIRE` command or cleared using the `PERSIST` command. | +| `PEXPIREAT` | Sets a `key` to expire at the specified absolute Unix timestamp in milliseconds. After that time, the `key` is automatically deleted. Returns `1` if the timeout was set, `0` if the `key` doesn't exist. | +| `PING` | Returns `PONG` if no argument is provided, otherwise return a copy of the argument as a bulk. | +| `PTTL` | Returns the remaining time to live of a `key`, in milliseconds. | +| `SADD` | Add the specified members to the set stored at `key`. Specified members that are already a member of this set are ignored. If `key` doesn't exist, a new set is created before adding the specified members. | +| `SCAN` | Incrementally iterate over a collection of elements. It is a cursor based iterator, this means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. An iteration starts when the cursor is set to `0`, and terminates when the cursor returned by the server is `0`. | +| `SCARD` | Returns the set cardinality (number of elements) of the set stored at `key`. | +| `SDIFF` | Returns the members of the set resulting from the difference between the first set and all the successive sets. | +| `SDIFFSTORE` | This command is equal to `SDIFF`, but instead of returning the resulting set, it is stored in `destination`. If `destination` already exists, it is overwritten. | +| `SET` | Set `key` to hold the string `value`. If key already holds a value, it is overwritten, regardless of its type. | +| `SETBIT` | Sets or clears the bit at offset in the string value stored at `key`. | +| `SINTER` | Returns the members of the set resulting from the intersection of all the given sets. | +| `SINTERCARD` | Returns the number of elements that would result from the intersection of all given sets. | +| `SINTERSTORE` | This command is equal to `SINTER`, but instead of returning the resulting set, it is stored in `destination`. If `destination` already exists, it is overwritten. | +| `SISMEMBER` | Returns if `member` is a member of the set stored at `key`. | +| `SMEMBERS` | Returns all the members of the set value stored at `key`. | +| `SMISMEMBER` | Returns whether each member is a member of the set stored at `key`. For every member, `1` is returned if the value is a member of the set, or `0` if the element is not a member of the set or if `key` doesn't exist. | +| `SMOVE` | Move `member` from the set at `source` to the set at `destination`. This operation is atomic. In every given moment the element will appear to be a member of `source` or `destination` for other clients. | +| `SPOP` | Removes and returns one or more random members from the set value stored at `key`. | +| `SRANDMEMBER` | When called with just the `key` argument, return a random element from the set value stored at `key`. | +| `SREM` | Remove the specified members from the set stored at `key`. Specified members that are not a member of this set are ignored. If `key` doesn't exist, it is treated as an empty set and this command returns `0`. | +| `SSCAN` | Incrementally iterate over set elements. It is a cursor based iterator, this means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. An iteration starts when the cursor is set to `0`, and terminates when the cursor returned by the server is `0`. | +| `STRLEN` | Returns the length of the string value stored at `key`. An error is returned when key holds a non-string value. | +| `SUNION` | Returns the members of the set resulting from the union of all the given sets. | +| `SUNIONSTORE` | This command is equal to `SUNION`, but instead of returning the resulting set, it is stored in `destination`. If `destination` already exists, it is overwritten. | +| `TTL` | Returns the remaining time to live of a `key`, in seconds. | +| `TYPE` | Returns the string representation of the type of the value stored at `key`. Can be: `hash`, `list`, `set` or `string`. | ### JSON commands Materia KV provides preliminary support for JSON data type operations, compatible with Redis API JSON commands and clients. Unlike Redis JSON which uses a dedicated data type, our implementation works directly with classic string data types while maintaining API compatibility. #### Path Syntax and Behavior + - `$`: Root element (required for setting values, optional for `GET`/`DEL`) - `$.field`: Access field in object - `$..field`: Recursively search for all matching fields @@ -251,6 +251,7 @@ OK ``` #### Current Limitations + - `JSON.SET` can only create new documents at root path (`$`) - `JSON.SET` can't create new fields in existing documents - Nested path creation is not supported (e.g., `$.new.child.field`) @@ -266,7 +267,7 @@ The GraphQL layer is **read-only** today — the schema exposes no mutation type Materia KV is a distributed cluster: the GraphQL endpoint is a single URL shared by every add-on in a given region, over HTTPS on the standard port. For the Paris region, it is: -``` +```text https://materiakv-graphql.eu-fr-1.services.clever-cloud.com/graphql ``` @@ -402,11 +403,11 @@ JSON documents written via `JSON.SET` are stored on top of strings. The schema h We've prepared a few examples to help you get started with Materia KV: -* [Materia KV Go client](https://github.com/CleverCloud/mkv-go-cli) -* [Materia KV raw TCP V demo](https://github.com/CleverCloud/mkv-raw-tcp-v) -* [Materia KV raw TCP Ruby demo](https://github.com/CleverCloud/mkv-raw-tcp-ruby) -* [Materia KV PHP sessions with TTL demo](https://github.com/CleverCloud/php-sessions-kv-example) -* [Materia KV write via Redis API, read via GraphQL](https://github.com/CleverCloud/kv-graphql-example) +- [Materia KV Go client](https://github.com/CleverCloud/mkv-go-cli) +- [Materia KV raw TCP V demo](https://github.com/CleverCloud/mkv-raw-tcp-v) +- [Materia KV raw TCP Ruby demo](https://github.com/CleverCloud/mkv-raw-tcp-ruby) +- [Materia KV PHP sessions with TTL demo](https://github.com/CleverCloud/php-sessions-kv-example) +- [Materia KV write via Redis API, read via GraphQL](https://github.com/CleverCloud/kv-graphql-example) ## How Materia KV differs from Redis @@ -478,14 +479,14 @@ Active background cleanup of expired keys is under active development. Future re Materia KV enforces stricter size limits than Redis due to the constraints of the underlying distributed transaction engine. -| Limit | Redis | Materia KV | -|-------|-------|------------| -| Max key size | 512 MB | 8 KB | -| Max value size | 512 MB | 5 MB | -| Max transaction size | N/A | 10 MB (reads + writes) | -| Transaction duration | N/A | 5 seconds | -| Max keys per `DEL` | No limit | 100 | -| Storage per add-on | Plan-dependent | 128 MB (during Beta, can be increased) | +| Limit | Redis | Materia KV | +| -------------------- | -------------- | -------------------------------------- | +| Max key size | 512 MB | 8 KB | +| Max value size | 512 MB | 5 MB | +| Max transaction size | N/A | 10 MB (reads + writes) | +| Transaction duration | N/A | 5 seconds | +| Max keys per `DEL` | No limit | 100 | +| Storage per add-on | Plan-dependent | 128 MB (during Beta, can be increased) | The system enforces the 8 KB key limit and 5 MB value limit at the application level. The 10 MB transaction limit and 5-second duration are FoundationDB constraints that apply to the sum of all data read and written within a single command's transaction. diff --git a/content/doc/addons/materia-ts.md b/content/doc/addons/materia-ts.md index 56159df43..f3ccd07b5 100644 --- a/content/doc/addons/materia-ts.md +++ b/content/doc/addons/materia-ts.md @@ -38,12 +38,12 @@ The add-on is immediately created and you can start using it with provided token Materia TS uses Warp10 time series engine and WarpsScript query language. It provides PromQL and Prometheus Ingestion gateway in addition to warp10 endpoints. You can also use [Time Series Language (TSL)](https://github.com/ovh/tsl/) previously written by OVHcloud Metrics team. -| Endpoint | Description | -| -------- | ----------- | +| Endpoint | Description | +| ----------------------------------------------------------------------- | ------------------------------------ | | `https://materiats.eu-fr-1.services.clever-cloud.com:443/api/v0/update` | Warp10 compatible Ingestion endpoint | -| `https://materiats.eu-fr-1.services.clever-cloud.com:443/api/v0/exec` | WarpScript query language endpoint | -| `https://catalyst-materiats.eu-fr-1.services.clever-cloud.com:443/` | Prometheus Ingestion gateway | -| `https://prometheus-materiats.eu-fr-1.services.clever-cloud.com:433` | PromQL endpoint | +| `https://materiats.eu-fr-1.services.clever-cloud.com:443/api/v0/exec` | WarpScript query language endpoint | +| `https://catalyst-materiats.eu-fr-1.services.clever-cloud.com:443/` | Prometheus Ingestion gateway | +| `https://prometheus-materiats.eu-fr-1.services.clever-cloud.com:433` | PromQL endpoint | For complete technical documentation on Warp 10 and its query language, see our [Warp 10 documentation](/doc/metrics/warp10/). diff --git a/content/doc/addons/matomo.md b/content/doc/addons/matomo.md index 32b7a6449..a30596c41 100644 --- a/content/doc/addons/matomo.md +++ b/content/doc/addons/matomo.md @@ -53,7 +53,7 @@ We've already integrated the Clever Cloud SSO, so you can login directly into yo Make sure you have `clever-tools` installed locally. Please refer to the [setup guide](/doc/cli/install/) if needed. In your terminal, `clever addon create addon-matomo --region --org ` (`--org` and `--region` are optional). You'll get URLs to manage your Matomo instance: -``` +```bash $ clever addon create addon-matomo myMatomo Add-on created successfully! ID: addon_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx diff --git a/content/doc/addons/metabase.md b/content/doc/addons/metabase.md index 860207b32..47a528d76 100644 --- a/content/doc/addons/metabase.md +++ b/content/doc/addons/metabase.md @@ -47,7 +47,7 @@ You can also save questions and **organize** them in _collections_. When opening Make sure you have `clever-tools` installed locally. Please refer to the [setup guide](/doc/cli/install/) if needed. In your terminal, run `clever addon create metabase --org ` (`--org` is optional). You'll get URLs to manage your Metabase instance and the temporary credentials: -``` +```bash $ clever addon create metabase myMetabase Add-on created successfully! ID: addon_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx @@ -73,7 +73,7 @@ Refer to the [Clever Tools documentation](/doc/cli/addons/) for more details on Once you created your add-on, open the management URL or look for `MB_SITE_URL` value in the Metabase dashboard from the Console. The first time you connect, you will be taken to a wizard to create the first user, data sources, etc. Then you can configure and use it. -* [Learn how to use Metabase](https://www.metabase.com/learn/metabase-basics/getting-started/find-data) +- [Learn how to use Metabase](https://www.metabase.com/learn/metabase-basics/getting-started/find-data) ## Password reset @@ -94,7 +94,7 @@ Its name is the same as the add-on name, followed by the add-on ID. Add a `CC_PRE_RUN_HOOK` environment variable with this value (replace `email@example.com` with your own address): -``` +```text MB_DB_CONNECTION_URI="$POSTGRESQL_ADDON_URI" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar reset-password email@example.com ``` diff --git a/content/doc/addons/mysql.md b/content/doc/addons/mysql.md index ce765a61c..142ca3d18 100644 --- a/content/doc/addons/mysql.md +++ b/content/doc/addons/mysql.md @@ -19,6 +19,7 @@ aliases: - /doc/en/mysql-hosting --- ## Overview + MySQL is an open source relational database management system (RDBMS). Clever Cloud's add-on uses the [Percona Server](https://www.percona.com/mysql/software/percona-server-for-mysql), a 100% compatible open source implementation, with performances improvements and more features. ## Supported Versions diff --git a/content/doc/addons/otoroshi.md b/content/doc/addons/otoroshi.md index 72e94a4dd..ae248e7a6 100644 --- a/content/doc/addons/otoroshi.md +++ b/content/doc/addons/otoroshi.md @@ -37,7 +37,7 @@ On Clever Cloud, it comes with pre-configured with features included such as [Co Make sure you have `clever-tools` installed locally. Please refer to the [setup guide](/doc/cli/install/) if needed. In your terminal, run `clever addon create otoroshi --org ` (`--org` is optional). You'll get URLs to manage your Otoroshi with LLM instance and the temporary credentials: -``` +```bash $ clever addon create otoroshi myOtoroshi Add-on created successfully! ID: addon_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx @@ -107,7 +107,7 @@ clever otoroshi open webui myOtoroshi The first time you connect, change the initial password (Security -> Administrators -> Edit user). -* [Learn how to use Otoroshi](https://maif.github.io/otoroshi/manual/docs/index.html) +- [Learn how to use Otoroshi](https://maif.github.io/otoroshi/manual/docs/index.html) ## Underlying resources @@ -130,14 +130,17 @@ They are dimensioned to suit a majority of needs. You can however manage and adj Otoroshi on Clever Cloud comes with LLM Extension. It provides a unified gateway for managing and interacting with Large Language Models through an OpenAI-compatible API interface, with [MCP support](https://www.clever.cloud/blog/company/2025/01/21/create-your-own-mcp-client-server-as-easy-as-1-2-3-with-otoroshi/). This extension streamlines the integration and management of multiple LLM providers including Ollama instances, OpenAI, Mistral, Anthropic, DeepSeek, Eleven Labs, Gemini, Groq, Hive, Hugging Face, Leonardo AI, Luma, OVH and Scaleway AI Endpoints. It supports audio, image, moderation and text generation models. ### Smarter AI operations + The extension enhances your LLM operations with intelligent workload distribution and automatic failover mechanisms, ensuring consistent service availability. It implements sophisticated features such as semantic caching to optimize response times and reduce costs, while providing comprehensive quota management capabilities for effective resource allocation. {{< youtube id="M8sA9xuE3gs">}} ### Security and Management + Security is paramount with built-in features for API key management through Otoroshi's secure vault system. The extension leverages Otoroshi's advanced authorization framework to implement fine-grained access controls based on user identity, API keys, consumer metadata, and request parameters. Additionally, prompt fencing technology helps prevent sensitive information leakage and ensures response quality. ### Observability and Enhancement + Every LLM interaction is thoroughly audited, capturing detailed information about consumers, providers, and usage patterns. The extension also includes robust prompt engineering capabilities, allowing you to create and maintain a library of contextually enhanced prompts and templates for improved efficiency and consistency in LLM interactions. - [Otoroshi LLM extension documentation](https://cloud-apim.github.io/otoroshi-llm-extension/docs/overview) @@ -148,11 +151,13 @@ Every LLM interaction is thoroughly audited, capturing detailed information abou Otoroshi on Clever Cloud integrates Coraza, a high-performance Web Application Firewall (WAF), through a WebAssembly-based plugin. This integration provides enterprise-grade security features to protect your applications using the OWASP Core Rule Set (CRS). ### Security features + The Coraza WAF plugin enables robust security policy enforcement while maintaining high performance across deployments of any scale. It seamlessly integrates with Otoroshi's existing infrastructure to provide comprehensive protection against web application threats. The integration provides advanced security capabilities through OWASP CRS implementation, allowing you to create and enforce custom security policies. The system generates detailed audit logs for security monitoring and compliance purposes, with full integration into Otoroshi's existing logging and monitoring infrastructure. ### Enterprise Capabilities + Designed for production environments, the Coraza WAF plugin offers flexible configuration options, supporting both detection and prevention modes. It enables customized rule sets per domain and provides detailed security event tracking through Otoroshi's event management system. The implementation is optimized for minimal performance impact while maintaining robust security controls. - [Otoroshi Coraza WAF documentation](https://maif.github.io/otoroshi/manual/docs/tutorials/instantiate-waf-coraza) @@ -163,6 +168,6 @@ Otoroshi exposes a comprehensive REST API that enables programmatic control over An OpenAPI descriptor is available from your instance: -``` +```text https://xxxxxxxxxxxx-api-otoroshi.services/apis/openapi.json ``` diff --git a/content/doc/addons/postgresql.md b/content/doc/addons/postgresql.md index 7407861b8..631ec2d96 100644 --- a/content/doc/addons/postgresql.md +++ b/content/doc/addons/postgresql.md @@ -38,6 +38,7 @@ It's not installed by default on a PostgreSQL add-on, if you need it, you can co ## Migrating from an old database Some applications require a non-empty database to run properly. If you want to import your **SQL** dump, you can use several methods: + 1. [WebGUI (Adminer)](https://dbms-adminer.clever-cloud.com/) 2. Command line tool for PostgreSQL administration like `psql` 3. Any PostgreSQL client such as [pgAdmin](https://www.pgadmin.org/) @@ -49,11 +50,12 @@ Some applications require a non-empty database to run properly. If you want to i You can add up to 2 replicas to an existing PostgreSQL (v12 or higher) database on Clever Cloud to enhance performance and reliability. They're set up as read-only [standby servers](https://www.postgresql.org/docs/current/runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY) with full physical replication, in a different availability zone (AZ) or region if requested. You can see if a database is a [primary server](https://www.postgresql.org/docs/current/runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-PRIMARY) or a replica from PostgreSQL dashboard in [the Console](https://console.clever-cloud.com). If a primary server isn't available, you can promote a replica as a standalone server and link it to applications. This database will: + - Become a primary server (using `pg_ctl promote` command internally) with read/write capabilities - Delete its replication link to the original primary server > [!Note] Replication setup isn't yet available from API or the Console -> To create and configure PostgreSQL replicas, contact your sales representative or [Clever Cloud support](https://console.clever-cloud.com/ticket-center-choice). +> To create and configure PostgreSQL replicas, contact your sales representative or [Clever Cloud support](https://console.clever-cloud.com/ticket-center-choice). ## Direct access @@ -87,72 +89,72 @@ You can learn more about Pgpool-II on the [dedicated documentation page](/guides PostgreSQL databases managed by Clever Cloud comes with these extensions: -Extension              | Description ------------------------ | ----------- - adminpack              | Administrative functions for PostgreSQL (not supported on PostgreSQL 17+) - autoinc                | Functions for autoincrementing fields - btree_gin              | Support for indexing common datatypes in GIN - btree_gist             | Support for indexing common datatypes in GiST - citext                 | Data type for case-insensitive character strings - cube                   | Data type for multidimensional cubes - dblink                 | Connect to other PostgreSQL databases from within a database - dict_int               | Text search dictionary template for integers - dict_xsyn              | Text search dictionary template for extended synonym processing - earthdistance          | Calculate great-circle distances on the surface of the Earth - file_fdw               | Foreign-data wrapper for flat file access - fuzzystrmatch          | Determine similarities and distance between strings - hstore                 | Data type for storing sets of (key, value) pairs - hypopg                 | Hypothetical indexes for PostgreSQL - insert_username        | Functions for tracking who changed a table - intagg                 | Integer aggregator and enumerator (obsolete) - intarray               | Functions, operators, and index support for 1-D arrays of integers - isn                    | Data types for international product numbering standards - lo                     | Large Object maintenance - ltree                  | Data type for hierarchical tree-like structures - moddatetime            | Functions for tracking last modification time - pageinspect            | Inspect the contents of database pages at a low level - pg_buffercache         | Examine the shared buffer cache - pg_freespacemap        | Examine the free space map (FSM) - pg_stat_statements     | Track planning and execution statistics of all SQL statements executed - pg_trgm                | Text similarity measurement and index searching based on trigrams - pgcrypto               | Cryptographic functions - pgrowlocks             | Show row-level locking information - pgstattuple            | Show tuple-level statistics - pgvector | Vector data type and ivfflat and hnsw access methods - plcoffee               | PL/CoffeeScript (v8) trusted procedural language (not supported on PostgreSQL 14+) - plls                   | PL/LiveScript (v8) trusted procedural language (not supported on PostgreSQL 14+) - plpgsql                | PL/pgSQL procedural language - plv8                   | PL/JavaScript (v8) trusted procedural language (not supported on PostgreSQL 16+) - postgis                | PostGIS geometry and geography spatial types and functions - postgis_raster         | PostGIS raster types and functions - postgis_tiger_geocoder | PostGIS tiger geocoder and reverse geocoder - postgis_topology       | PostGIS topology spatial types and functions - postgres_fdw           | Foreign-data wrapper for remote PostgreSQL servers - refint                 | Functions for implementing referential integrity (obsolete) - seg                    | Data type for representing line segments or floating-point intervals - sslinfo                | Information about SSL certificates - tablefunc              | Functions that manipulate whole tables, including crosstab - tcn                    | Triggered change notifications - unaccent               | Text search dictionary that removes accents - uuid-ossp              | Generate universally unique identifiers (UUIDs) - xml2                   | XPath querying and XSLT +| Extension | Description | +| ---------------------- | ---------------------------------------------------------------------------------- | +| adminpack | Administrative functions for PostgreSQL (not supported on PostgreSQL 17+) | +| autoinc | Functions for autoincrementing fields | +| btree_gin | Support for indexing common datatypes in GIN | +| btree_gist | Support for indexing common datatypes in GiST | +| citext | Data type for case-insensitive character strings | +| cube | Data type for multidimensional cubes | +| dblink | Connect to other PostgreSQL databases from within a database | +| dict_int | Text search dictionary template for integers | +| dict_xsyn | Text search dictionary template for extended synonym processing | +| earthdistance | Calculate great-circle distances on the surface of the Earth | +| file_fdw | Foreign-data wrapper for flat file access | +| fuzzystrmatch | Determine similarities and distance between strings | +| hstore | Data type for storing sets of (key, value) pairs | +| hypopg | Hypothetical indexes for PostgreSQL | +| insert_username | Functions for tracking who changed a table | +| intagg | Integer aggregator and enumerator (obsolete) | +| intarray | Functions, operators, and index support for 1-D arrays of integers | +| isn | Data types for international product numbering standards | +| lo | Large Object maintenance | +| ltree | Data type for hierarchical tree-like structures | +| moddatetime | Functions for tracking last modification time | +| pageinspect | Inspect the contents of database pages at a low level | +| pg_buffercache | Examine the shared buffer cache | +| pg_freespacemap | Examine the free space map (FSM) | +| pg_stat_statements | Track planning and execution statistics of all SQL statements executed | +| pg_trgm | Text similarity measurement and index searching based on trigrams | +| pgcrypto | Cryptographic functions | +| pgrowlocks | Show row-level locking information | +| pgstattuple | Show tuple-level statistics | +| pgvector | Vector data type and ivfflat and hnsw access methods | +| plcoffee | PL/CoffeeScript (v8) trusted procedural language (not supported on PostgreSQL 14+) | +| plls | PL/LiveScript (v8) trusted procedural language (not supported on PostgreSQL 14+) | +| plpgsql | PL/pgSQL procedural language | +| plv8 | PL/JavaScript (v8) trusted procedural language (not supported on PostgreSQL 16+) | +| postgis | PostGIS geometry and geography spatial types and functions | +| postgis_raster | PostGIS raster types and functions | +| postgis_tiger_geocoder | PostGIS tiger geocoder and reverse geocoder | +| postgis_topology | PostGIS topology spatial types and functions | +| postgres_fdw | Foreign-data wrapper for remote PostgreSQL servers | +| refint | Functions for implementing referential integrity (obsolete) | +| seg | Data type for representing line segments or floating-point intervals | +| sslinfo | Information about SSL certificates | +| tablefunc | Functions that manipulate whole tables, including crosstab | +| tcn | Triggered change notifications | +| unaccent | Text search dictionary that removes accents | +| uuid-ossp | Generate universally unique identifiers (UUIDs) | +| xml2 | XPath querying and XSLT | ## On-demand extensions In the [Console's Ticket Center](https://console.clever-cloud.com/ticket-center-choice), you can ask our support team to add any of these extensions for you: -Extension | Description ------------ | ----------- -pg_cron | Job scheduler for PostgreSQL -pg_ivm | Incremental view maintenance for PostgreSQL -pg_net | Enables asynchronous (non-blocking) HTTP/HTTPS requests with SQL -pg_partman | Extension to manage partitioned tables by time or ID -pg_repack | Reorganize tables in PostgreSQL databases with minimal locks -pgaudit | Provides detailed session and/or object audit logging via the standard PostgreSQL logging facility -pgsql-http | HTTP client for PostgreSQL -pgtap | Unit testing for PostgreSQL -rum | Provides an access method to work with a RUM index -timescaledb | Enables scalable inserts and complex queries for time-series data (Apache 2 Edition) +| Extension | Description | +| ----------- | -------------------------------------------------------------------------------------------------- | +| pg_cron | Job scheduler for PostgreSQL | +| pg_ivm | Incremental view maintenance for PostgreSQL | +| pg_net | Enables asynchronous (non-blocking) HTTP/HTTPS requests with SQL | +| pg_partman | Extension to manage partitioned tables by time or ID | +| pg_repack | Reorganize tables in PostgreSQL databases with minimal locks | +| pgaudit | Provides detailed session and/or object audit logging via the standard PostgreSQL logging facility | +| pgsql-http | HTTP client for PostgreSQL | +| pgtap | Unit testing for PostgreSQL | +| rum | Provides an access method to work with a RUM index | +| timescaledb | Enables scalable inserts and complex queries for time-series data (Apache 2 Edition) | {{< callout type="warning" >}} On-demand extensions aren't available for DEV plans. diff --git a/content/doc/administrate/activity.md b/content/doc/administrate/activity.md index ad48fa162..7e16e3ae4 100644 --- a/content/doc/administrate/activity.md +++ b/content/doc/administrate/activity.md @@ -14,10 +14,10 @@ keywords: Follow your application activities and lifecycle from the **Activity** option in the application menu. Every time your application redeploys, a new block appears on the timeline. Re-deployment triggers can be either: - - An action performed by you or by a member of your organisation - - An action performed by Clever Cloud +- An action performed by you or by a member of your organisation +- An action performed by Clever Cloud - ## Re-deployment triggered by you +## Re-deployment triggered by you This happens when you or a member of your organisation performs an action on the application, like: diff --git a/content/doc/administrate/clamav.md b/content/doc/administrate/clamav.md index e00cb86bc..81250e1fc 100644 --- a/content/doc/administrate/clamav.md +++ b/content/doc/administrate/clamav.md @@ -28,8 +28,8 @@ CC_CLAMAV=true This variable is used to start these two services: -* **clamav-daemon.service** (multi-threaded daemon that uses libclamav to scan files for viruses). -* **clamav-freshclam.service** (used to update signature database sets to the latest version). +- **clamav-daemon.service** (multi-threaded daemon that uses libclamav to scan files for viruses). +- **clamav-freshclam.service** (used to update signature database sets to the latest version). The signature database is updated every 2 hours. diff --git a/content/doc/administrate/domain-names.md b/content/doc/administrate/domain-names.md index 16ddcb39f..b10056ae3 100644 --- a/content/doc/administrate/domain-names.md +++ b/content/doc/administrate/domain-names.md @@ -16,8 +16,8 @@ aliases: When creating an application, you have two (non-exclusive) choices for domain names: -* Using a personal domain name -* Using a `cleverapps.io` free domain for development and testing purposes, with built-in SSL +- Using a personal domain name +- Using a `cleverapps.io` free domain for development and testing purposes, with built-in SSL Add it in the application configuration: in the console, click **application name** in the first panel, then choose **domain names**. You'll have to choose to add a custom domain name or use a subdomain under `*.cleverapps.io`. @@ -32,6 +32,7 @@ You can set multiple custom or `cleverapps.io` domain names to an application, b ![Primary domain link](/images/primary-domain-link.webp) To select the primary domain name: + - Click the star icon next to the domain name in the **Domain names** section of your application in the Console - Use the `clever domain favourite set example.com` command in [Clever Tools](/doc/cli/applications/configuration/#domain) - Use the dedicated `/vhosts/favourite` endpoint [in the API](/api/v2/#put-/organisations/-id-/applications/-appId-/vhosts/favourite) @@ -67,90 +68,90 @@ We also support wildcard personal domain names, to do so use the standard patter Provide the following to your registrar: -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.par.clever-cloud.com.` | -| A
Only if CNAME is not available | `@ 10800 IN A 91.208.207.214`
`@ 10800 IN A 91.208.207.215`
`@ 10800 IN A 91.208.207.216`
`@ 10800 IN A 91.208.207.217`
`@ 10800 IN A 91.208.207.218`
`@ 10800 IN A 91.208.207.220`
`@ 10800 IN A 91.208.207.221`
`@ 10800 IN A 91.208.207.222`
`@ 10800 IN A 91.208.207.223` | +| Record Type | Value | +| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.par.clever-cloud.com.` | +| A
Only if CNAME is not available | `@ 10800 IN A 91.208.207.214`
`@ 10800 IN A 91.208.207.215`
`@ 10800 IN A 91.208.207.216`
`@ 10800 IN A 91.208.207.217`
`@ 10800 IN A 91.208.207.218`
`@ 10800 IN A 91.208.207.220`
`@ 10800 IN A 91.208.207.221`
`@ 10800 IN A 91.208.207.222`
`@ 10800 IN A 91.208.207.223` | ### Europe/Paris HDS (PARHDS) Provide the following to your registrar: -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.parhds.clever-cloud.com.` | -| A
Only if CNAME is not available | `@ 10800 IN A 91.208.207.214`
`@ 10800 IN A 91.208.207.215`
`@ 10800 IN A 91.208.207.220`
`@ 10800 IN A 91.208.207.221`
`@ 10800 IN A 91.208.207.222`
`@ 10800 IN A 91.208.207.223` | +| Record Type | Value | +| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.parhds.clever-cloud.com.` | +| A
Only if CNAME is not available | `@ 10800 IN A 91.208.207.214`
`@ 10800 IN A 91.208.207.215`
`@ 10800 IN A 91.208.207.220`
`@ 10800 IN A 91.208.207.221`
`@ 10800 IN A 91.208.207.222`
`@ 10800 IN A 91.208.207.223` | To benefit from certified hosting for health data, you need to deploy in an HDS zone and to sign up to a specific contract. This begins with [an initial discussion with our team](https://www.clever.cloud/fr/hebergement-donnees-de-sante/contact-hds/). ### Europe/Paris onto Scaleway (SCW) -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.scw.clever-cloud.com.` | +| Record Type | Value | +| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.scw.clever-cloud.com.` | | A
Only if CNAME is not available | `@ 10800 IN A 212.129.27.239`
`@ 10800 IN A 212.83.186.147`
`@ 10800 IN A 212.83.186.216`
`@ 10800 IN A 212.129.27.183` | ### Europe/Gravelines HDS (GRAHDS) -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.grahds.clever-cloud.com.` | -| A
Only if CNAME is not available | `@ 10800 IN A 188.165.58.196`
`@ 10800 IN A 188.165.58.200` | +| Record Type | Value | +| ----------------------------------- | ---------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.grahds.clever-cloud.com.` | +| A
Only if CNAME is not available | `@ 10800 IN A 188.165.58.196`
`@ 10800 IN A 188.165.58.200` | To benefit from certified hosting for health data, you need to deploy in an HDS zone and to sign up to a specific contract. This begins with [an initial discussion with our team](https://www.clever.cloud/fr/hebergement-donnees-de-sante/contact-hds/). ### Europe/London (LDN) -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.ldn.clever-cloud.com.` | -| A
Only if CNAME is not available | `@ 10800 IN A 77.68.78.36`
`@ 10800 IN A 77.68.94.247` | +| Record Type | Value | +| ----------------------------------- | ------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.ldn.clever-cloud.com.` | +| A
Only if CNAME is not available | `@ 10800 IN A 77.68.78.36`
`@ 10800 IN A 77.68.94.247` | ### Europe/Roubaix (RBX) -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.rbx.clever-cloud.com.` | +| Record Type | Value | +| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.rbx.clever-cloud.com.` | | A
Only if CNAME is not available | `@ 10800 IN A 87.98.177.176`
`@ 10800 IN A 87.98.177.181`
`@ 10800 IN A 87.98.180.173`
`@ 10800 IN A 87.98.182.136` | ### Europe/Roubaix HDS (RBXHDS) -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.rbxhds.clever-cloud.com.` | -| A
Only if CNAME is not available | `@ 10800 IN A 135.125.16.47`
`@ 10800 IN A 135.125.16.49` | +| Record Type | Value | +| ----------------------------------- | ---------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.rbxhds.clever-cloud.com.` | +| A
Only if CNAME is not available | `@ 10800 IN A 135.125.16.47`
`@ 10800 IN A 135.125.16.49` | To benefit from certified hosting for health data, you need to deploy in an HDS zone and to sign up to a specific contract. This begins with [an initial discussion with our team](https://www.clever.cloud/fr/hebergement-donnees-de-sante/contact-hds/). ### Europe/Warsaw (WSW) -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.wsw.clever-cloud.com.` | +| Record Type | Value | +| ----------------------------------- | -------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.wsw.clever-cloud.com.` | | A
Only if CNAME is not available | `@ 10800 IN A 145.239.17.127`
`@ 10800 IN A 145.239.17.192` | ### North-America/Montreal (MTL) Provide the following to your registrar: -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.mtl.clever-cloud.com.` | +| Record Type | Value | +| ----------------------------------- | -------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.mtl.clever-cloud.com.` | | A
Only if CNAME is not available | `@ 10800 IN A 158.69.109.229`
`@ 10800 IN A 149.56.117.183` | ### Asia/Singapore (SGP) -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.sgp.clever-cloud.com.` | -| A
Only if CNAME is not available | `@ 10800 IN A 51.79.197.159`
`@ 10800 IN A 51.79.197.160` | +| Record Type | Value | +| ----------------------------------- | ------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.sgp.clever-cloud.com.` | +| A
Only if CNAME is not available | `@ 10800 IN A 51.79.197.159`
`@ 10800 IN A 51.79.197.160` | ### Oceania/Sydney (SYD) -| Record Type | Value | -| ----------- | ----- | -| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.syd.clever-cloud.com.` | -| A
Only if CNAME is not available | `@ 10800 IN A 139.99.253.215`
`@ 10800 IN A 139.99.253.237` | +| Record Type | Value | +| ----------------------------------- | -------------------------------------------------------------- | +| CNAME
Recommended | `{yoursubdomain} 10800 IN CNAME domain.syd.clever-cloud.com.` | +| A
Only if CNAME is not available | `@ 10800 IN A 139.99.253.215`
`@ 10800 IN A 139.99.253.237` | {{< callout type="warning" >}} You cannot use a CNAME on a top-level domain, or on a subdomain which already has DNS records. @@ -166,11 +167,11 @@ Remember that DNS changes may take time to propagate (usually a few hours, somet ### Contextual Example -| Domain Name Use Case | CNAME config | Record A config | Web redirections | -|-----------------------------|-------------------------------------------------|-----------------------------------------------------------------|--------------------------------------------| -| `www.example.com`
`example.com` | Point `www.example.com` to `domain.par/mtl.clever-cloud.com.` | No A record needed | Redirect `example.com` to `www.example.com` | -| `www.example.com` | Point `www.example.com` to `domain.par/mtl.clever-cloud.com.` | No A record needed | No redirect needed | -| `example.com` | No CNAME record needed | Point `example.com` to the two IP addresses of the selected region | No redirect needed | +| Domain Name Use Case | CNAME config | Record A config | Web redirections | +| ------------------------------------ | ------------------------------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------- | +| `www.example.com`
`example.com` | Point `www.example.com` to `domain.par/mtl.clever-cloud.com.` | No A record needed | Redirect `example.com` to `www.example.com` | +| `www.example.com` | Point `www.example.com` to `domain.par/mtl.clever-cloud.com.` | No A record needed | No redirect needed | +| `example.com` | No CNAME record needed | Point `example.com` to the two IP addresses of the selected region | No redirect needed | ## Path routing diff --git a/content/doc/administrate/log-management.md b/content/doc/administrate/log-management.md index 959860278..d07d83a51 100644 --- a/content/doc/administrate/log-management.md +++ b/content/doc/administrate/log-management.md @@ -24,7 +24,7 @@ There are two text filter modes: exact match (case-sensitive) and regular expres This interface is constantly improving, used for logs and access logs, send us your feedback through our GitHub Community: -* [Give your feedback about new Logs interface](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface) +- [Give your feedback about new Logs interface](https://github.com/CleverCloud/Community/discussions/categories/new-logs-interface) {{< callout type="info">}} Logs are retained for 7 days, sometimes more for specific customers/needs. @@ -261,9 +261,9 @@ On your terminal, use the following command: Replace the following values: - - `` - - `` - - `` +- `` +- `` +- `` {{< /tab >}} @@ -275,9 +275,9 @@ On your terminal, use the following command: Replace the following values: - - `` - - `` - - `` +- `` +- `` +- `` {{< /tab >}} diff --git a/content/doc/administrate/ssh-clever-tools.md b/content/doc/administrate/ssh-clever-tools.md index f463e1f2e..da5c71f44 100644 --- a/content/doc/administrate/ssh-clever-tools.md +++ b/content/doc/administrate/ssh-clever-tools.md @@ -33,8 +33,8 @@ For security reasons, you can't connect on the instance that hosts your Docker a You need to have at least one of the following installed locally: -* the [Clever Tools CLI](/doc/cli/) -* an SSH client (e.g [putty](https://putty.org/) for windows users) +- the [Clever Tools CLI](/doc/cli/) +- an SSH client (e.g [putty](https://putty.org/) for windows users) ### Make sure you have a properly configured SSH key @@ -128,7 +128,8 @@ You can also use `journalctl` [with other options](https://www.commandlinux.com/ ## Troubleshooting A commonly encountered issue when using `clever ssh` is: -``` + +```text Error: Failed to choose instance: 'Error while running choice script: Error: This application has no instances you can ssh to' ``` @@ -136,11 +137,13 @@ First, make sure your application is running, otherwise there is no instance to If your application is up, this means you aren't allowed to access the organisation or application. This might be due to permission issue. If you're supposed to have access to the application, this is likely due to a key management issue. To fix it: -* make sure you've added your public key on your Clever Cloud profile. You can refer to our documentation to [add your SSH key on Clever Cloud](/doc/account/ssh-keys-management#add-a-public-ssh-key-on-clever-cloud) -* make sure your SSH agent is using the proper private key + +- make sure you've added your public key on your Clever Cloud profile. You can refer to our documentation to [add your SSH key on Clever Cloud](/doc/account/ssh-keys-management#add-a-public-ssh-key-on-clever-cloud) +- make sure your SSH agent is using the proper private key A useful command for debugging is: -``` + +```bash ssh -t ssh@sshgateway-clevercloud-customers.services.clever-cloud.com -v ``` diff --git a/content/doc/administrate/ssl.md b/content/doc/administrate/ssl.md index 7e406d90a..f10020753 100644 --- a/content/doc/administrate/ssl.md +++ b/content/doc/administrate/ssl.md @@ -37,12 +37,16 @@ Clever Cloud automatically generates and renews TLS certificates for your domain ### Alternative Options #### Immediate Certificate Coverage + To avoid any period without certificate coverage (e.g., during migration from another provider): + 1. [Upload your existing certificate](#uploading-my-own-certificates) first 2. Let Clever Cloud generate a new certificate automatically when your uploaded one expires #### Wildcard Certificates + Clever Cloud's automatic certificate generation doesn't support wildcard certificates. For wildcard certificates, you can: + - Generate your own Let's Encrypt certificate - Purchase a commercial certificate - [Contact support](https://console.clever-cloud.com/ticket-center-choice) for a quote on managed certificate services @@ -128,12 +132,12 @@ You should note that `.pem`` files use the unix way of terminating lines with a You `.pem` file must be correctly formatted to successfully upload your certificate. This checklist might help you troubleshoot uncesuccessful certificate submission. -| Certificate Specifications | -|------------------------| -| ✅   The private key is included | -| ✅   Keys lenght are RSA and either 2048 or 4096 | -| ✅   ECDSA is not used to create your certificate | -| ✅   The line feed (LF) characters at the end | +| Certificate Specifications | +| ------------------------------------------------------------------------------------------------------------------------------------ | +| ✅   The private key is included | +| ✅   Keys lenght are RSA and either 2048 or 4096 | +| ✅   ECDSA is not used to create your certificate | +| ✅   The line feed (LF) characters at the end | | ✅   The certificate chain include your certificate together with all the intermediary CA certificates that signed it, in that order | ## Sending Certificates Manually diff --git a/content/doc/administrate/tcp-redirections.md b/content/doc/administrate/tcp-redirections.md index 67a3e7873..7c4ae7642 100644 --- a/content/doc/administrate/tcp-redirections.md +++ b/content/doc/administrate/tcp-redirections.md @@ -106,4 +106,4 @@ Example: if your redirection is on port **5500** and the **default** namespace, ```bash clever tcp-redirs remove 5500 --namespace default -``` \ No newline at end of file +``` diff --git a/content/doc/applications/docker.md b/content/doc/applications/docker.md index 22466c28b..7a1a3c1d1 100644 --- a/content/doc/applications/docker.md +++ b/content/doc/applications/docker.md @@ -36,8 +36,7 @@ Docker containers can encapsulate any payload, and will run consistently on and Clever Cloud allows you to deploy any application running inside a Docker container. This page explains how to set up your application to run it on our service. -> [!NOTE] -> Clever Cloud supports many languages, but some users have specific application needs. With Docker, they can create custom stacks without relying on Clever Cloud's specific support. +Clever Cloud supports many languages, but some users have specific application needs. With Docker, they can create custom stacks without relying on Clever Cloud's specific support. > [!WARNING] > [FS Buckets](/doc/best-practices/cloud-storage/#what-is-fs-bucket) access, Dockerfile validation, and Docker Compose functionalities are not supported. diff --git a/content/doc/applications/dotnet.md b/content/doc/applications/dotnet.md index dc7874c7c..a9b0cd404 100644 --- a/content/doc/applications/dotnet.md +++ b/content/doc/applications/dotnet.md @@ -50,9 +50,9 @@ You can change the default version by setting the `CC_DOTNET_VERSION` environmen Be sure that: -* You have pushed in **master** branch. -* You listen on port **8080**, by default each .NET application is created with the `ASPNETCORE_URLS="http://0.0.0.0:8080"` environment variable. -* You have committed the different files of your project and the corresponding project file (`.csproj`, `.fsproj` or `.vbproj`). +- You have pushed in **master** branch. +- You listen on port **8080**, by default each .NET application is created with the `ASPNETCORE_URLS="http://0.0.0.0:8080"` environment variable. +- You have committed the different files of your project and the corresponding project file (`.csproj`, `.fsproj` or `.vbproj`). Take an example with the [cc-dotnet-demo](https://github.com/CleverCloud/cc-dotnet-demo). diff --git a/content/doc/applications/frankenphp.md b/content/doc/applications/frankenphp.md index 73f5dbc4b..d98c04e83 100644 --- a/content/doc/applications/frankenphp.md +++ b/content/doc/applications/frankenphp.md @@ -32,6 +32,7 @@ To create a new FrankenPHP application, use the [Clever Cloud Console](https://c ```bash clever create --type frankenphp ``` + - [Learn more about Clever Tools](/doc/cli/) - [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) diff --git a/content/doc/applications/golang.md b/content/doc/applications/golang.md index 7560d24a5..aeb941036 100644 --- a/content/doc/applications/golang.md +++ b/content/doc/applications/golang.md @@ -93,12 +93,12 @@ Clever Cloud supports multiple ways to build and run a Go application. The build ### Environment variables -| Name | Description | -| :--- | :---------- | +| Name | Description | +| :----------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | | `CC_GO_BUILD_TOOL` | Available values: `gomod`, `gobuild`, `makefile`. Determines how to build and install your application. `goget` still exists but is deprecated. | -| `CC_GO_BINARY` | Required when using the `makefile` build tool. Path to the built binary, used to launch your application. | -| `CC_GO_PKG` | Package path passed to `go install`. Overrides auto-detection from `go.mod`. Default is `main.go` when no `go.mod` is present. | -| `CC_GO_RUNDIR` | Run the application from the specified path, relative to `$GOPATH/src/`. Deprecated. | +| `CC_GO_BINARY` | Required when using the `makefile` build tool. Path to the built binary, used to launch your application. | +| `CC_GO_PKG` | Package path passed to `go install`. Overrides auto-detection from `go.mod`. Default is `main.go` when no `go.mod` is present. | +| `CC_GO_RUNDIR` | Run the application from the specified path, relative to `$GOPATH/src/`. Deprecated. | The default `GOPATH` is `${HOME}/go_home`. The build command is `go install ` for all non-Makefile methods. If a `vendor/` directory is present, it is included in the build cache. @@ -122,12 +122,12 @@ An example of a `Makefile`, to use with `CC_GO_BINARY=bin/myApp`: BINARY=bin/myApp build: -# To install a specific Go version, you can add: -# go install golang.org/dl/gox.xx.x@latest -# ${HOME}/go_home/bin/gox.xx.x download -# Then use `${HOME}/go_home/bin/gox.xx.x` instead of `go` - echo "Build the application as ./${BINARY}" - go build -o ${BINARY} main.go +# To install a specific Go version, you can add: +# go install golang.org/dl/gox.xx.x@latest +# ${HOME}/go_home/bin/gox.xx.x download +# Then use `${HOME}/go_home/bin/gox.xx.x` instead of `go` + echo "Build the application as ./${BINARY}" + go build -o ${BINARY} main.go ``` - [A more complex project using a Go Workspace and a Makefile](https://github.com/CleverCloud/go-workspaces) diff --git a/content/doc/applications/haskell.md b/content/doc/applications/haskell.md index 3af098c04..94e9f773b 100644 --- a/content/doc/applications/haskell.md +++ b/content/doc/applications/haskell.md @@ -40,17 +40,17 @@ There are many ways to write web applications in Haskell, from raw [WAI](https:/ Be sure that: -* you have pushed in **master branch** -* you listen on **port 8080** -* you have one and only one binary target in your [`.cabal` file](#dependencies) -* your project has a `stack.yaml` file +- you have pushed in **master branch** +- you listen on **port 8080** +- you have one and only one binary target in your [`.cabal` file](#dependencies) +- your project has a `stack.yaml` file The steps ran in order are: -* `stack setup` -* `stack install --only-dependencies` -* `stack install` -* `.//my-exe` (or the contents of `CC_RUN_COMMAND`) +- `stack setup` +- `stack install --only-dependencies` +- `stack install` +- `.//my-exe` (or the contents of `CC_RUN_COMMAND`) The executable built by `stack build` (or the command you specify) must start a web server listening on `0.0.0.0:8080`. diff --git a/content/doc/applications/java/_index.md b/content/doc/applications/java/_index.md index 10e345e03..03e984ccb 100644 --- a/content/doc/applications/java/_index.md +++ b/content/doc/applications/java/_index.md @@ -36,7 +36,7 @@ Find detailed instructions according to your framework {{< /cards >}} -### More Frameworks +## More Frameworks Looking for instructions on a specific framework deployment? diff --git a/content/doc/applications/java/java-gradle.md b/content/doc/applications/java/java-gradle.md index 34e147fa5..b44358d8e 100644 --- a/content/doc/applications/java/java-gradle.md +++ b/content/doc/applications/java/java-gradle.md @@ -71,7 +71,7 @@ The full configuration can look like the following: You can use the following properties: | Usage | Field | Description | -|----------|-------------------|---------------------------------------------------------------------------| +| -------- | ----------------- | ------------------------------------------------------------------------- | | Optional | **build → type** | can be maven, gradle or ant | | Optional | **build → goal** | is the target you want to use to build your project | | Required | **deploy → goal** | the goal/target and options you want to execute to deploy/run you project | diff --git a/content/doc/applications/java/java-jar.md b/content/doc/applications/java/java-jar.md index 5dca6563c..cbcc43a12 100644 --- a/content/doc/applications/java/java-jar.md +++ b/content/doc/applications/java/java-jar.md @@ -104,7 +104,7 @@ The full configuration can look like the following: You can use the following properties: | Usage | Field | Description | -|----------|---------------------|---------------------------------------------------------------------------| +| -------- | ------------------- | ------------------------------------------------------------------------- | | Optional | **build → type** | can be `maven`, `gradle` or `ant` | | Optional | **build → goal** | is the target you want to use to build your project | | Optional | **deploy → goal** | the goal/target and options you want to execute to deploy/run you project | diff --git a/content/doc/applications/java/java-maven.md b/content/doc/applications/java/java-maven.md index c70be884c..5a72886aa 100644 --- a/content/doc/applications/java/java-maven.md +++ b/content/doc/applications/java/java-maven.md @@ -25,13 +25,13 @@ Note : like other runtimes, Java application needs to listen on `0.0.0.0:8080` Maven is essentially a project management and comprehension tool and as such provides a way to help with managing: -* Builds -* Documentation -* Reporting -* Dependencies -* SCMs -* Releases -* Distribution +- Builds +- Documentation +- Reporting +- Dependencies +- SCMs +- Releases +- Distribution {{% content "create-application" %}} @@ -97,7 +97,7 @@ The full configuration can look like the following: You can use the following properties: | Usage | Field | Description | -|----------|-------------------|---------------------------------------------------------------------------| +| -------- | ----------------- | ------------------------------------------------------------------------- | | Optional | **build → type** | can be `maven`, `gradle` or `ant` | | Optional | **build → goal** | is the target you want to use to build your project | | Required | **deploy → goal** | the goal/target and options you want to execute to deploy/run you project | diff --git a/content/doc/applications/java/java-war.md b/content/doc/applications/java/java-war.md index c6f7fe40f..069612667 100644 --- a/content/doc/applications/java/java-war.md +++ b/content/doc/applications/java/java-war.md @@ -23,9 +23,9 @@ Clever Cloud allows you to run WAR or EAR applications. You can deploy these pro In {{< tooltip title="JEE">}}JEE{{< /tooltip >}}, application modules are packaged as EAR and WAR based on their purpose. -* {{< tooltip title="WAR" >}}WAR{{< /tooltip >}}: Web modules which contains Servlet class files, JSP FIles, supporting files, GIF and HTML files are packaged as JAR file with *.war* extension. +- {{< tooltip title="WAR" >}}WAR{{< /tooltip >}}: Web modules which contains Servlet class files, JSP FIles, supporting files, GIF and HTML files are packaged as JAR file with *.war* extension. -* {{< tooltip title="EAR" >}}EAR{{< /tooltip >}}: `*.war` and `*.jar` files are packaged as JAR file with `.ear` extension and deployed into Application Server. EAR file contains configuration such as application security role mapping, EJB reference mapping and context root URL mapping of web modules. +- {{< tooltip title="EAR" >}}EAR{{< /tooltip >}}: `*.war` and `*.jar` files are packaged as JAR file with `.ear` extension and deployed into Application Server. EAR file contains configuration such as application security role mapping, EJB reference mapping and context root URL mapping of web modules. Note: like other runtimes, your Java application needs to listen on `0.0.0.0:8080`. @@ -94,12 +94,12 @@ Here are the mandatory fields: } ``` -|Usage |Field |Description| -|----------|--------|------------------------------------------------------------------------| -|Required |**container**|Name of the container to use. Should contain one of the values inside parentheses in the containers table (uppercase).| -|Required |file |Should contain the path of the war/ear file relative to your application root.| -| Optional |context |- Must start with a slash (/), can be "/"
- Defines the base path you want your app to be under. If your app has a /foobar endpoint, it will be available under the `/{my-context}/foobar` path.
- Not needed for an `ear` file.
- The default value for a war is the name of the war without the extensions: helloworld-1.0.war will be deployed under the `/helloworld-1.0` context.| -| Optional |checkMe |- This field is recommended.
- A path to GET in order to test if the application is really running.
- By default we will consider that the application is up if the container is up.
- With this option, we will try to GET `/{checkMe}` for each one of your wars and consider the app down until every single checkMe path that replies a 200.| +| Usage | Field | Description | +| -------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Required | **container** | Name of the container to use. Should contain one of the values inside parentheses in the containers table (uppercase). | +| Required | file | Should contain the path of the war/ear file relative to your application root. | +| Optional | context | - Must start with a slash (/), can be "/"
- Defines the base path you want your app to be under. If your app has a /foobar endpoint, it will be available under the `/{my-context}/foobar` path.
- Not needed for an `ear` file.
- The default value for a war is the name of the war without the extensions: helloworld-1.0.war will be deployed under the `/helloworld-1.0` context. | +| Optional | checkMe | - This field is recommended.
- A path to GET in order to test if the application is really running.
- By default we will consider that the application is up if the container is up.
- With this option, we will try to GET `/{checkMe}` for each one of your wars and consider the app down until every single checkMe path that replies a 200. | #### Let Clever Cloud build your application @@ -118,10 +118,10 @@ That you can do, by setting the "build" field object in the `war.json` file: } ``` -| Usage | Field | Description | -|---------------------------------|-------|------------------------------------------------| -|Required | **type** |- The tool you want to use to build your app.
- Can be "maven", "gradle", "sbt" or "ant" | -|Required | **goal** |- The goal you want the tool to execute.
- Basically, for maven, you want to put "package" in here. | +| Usage | Field | Description | +| -------- | -------- | ------------------------------------------------------------------------------------------------------ | +| Required | **type** | - The tool you want to use to build your app.
- Can be "maven", "gradle", "sbt" or "ant" | +| Required | **goal** | - The goal you want the tool to execute.
- Basically, for maven, you want to put "package" in here. | {{% content "new-relic" %}} @@ -129,18 +129,18 @@ That you can do, by setting the "build" field object in the `war.json` file: Here's the list of the configuration values for the "container" field in `war.json` (with **End Of Life** versions tagged as `EOL`): -| Value | Description | EOL | -|------------|----------------------------------------------------------------------------------------------|-----| -| JETTY9 | Use Jetty servlet container 9.x (see ) | EOL | -| JETTY11 | Use Jetty servlet container 11.x (see ) | EOL | -| PAYARA5 | Use Payara servlet container 5.x (see ) | EOL | -| PAYARA6 | Use Payara servlet container 6.x (see ) | EOL | -| TOMCAT8 | Use Tomcat servlet container 8.x (see ) | EOL | -| TOMCAT9 | Use Tomcat servlet container 9.x (see ) | | -| TOMCAT10 | Use Tomcat servlet container 10.x (see ) | | -| WILDFLY9 | Use Wildfly servlet container 9.x (see ) | EOL | -| WILDFLY27 | Use Wildfly servlet container 27.x (see ) | EOL | -| WILDFLY33 | Use Wildfly servlet container 33.x (see ) | EOL | +| Value | Description | EOL | +| --------- | ---------------------------------------------------------------------------------------- | --- | +| JETTY9 | Use Jetty servlet container 9.x (see ) | EOL | +| JETTY11 | Use Jetty servlet container 11.x (see ) | EOL | +| PAYARA5 | Use Payara servlet container 5.x (see ) | EOL | +| PAYARA6 | Use Payara servlet container 6.x (see ) | EOL | +| TOMCAT8 | Use Tomcat servlet container 8.x (see ) | EOL | +| TOMCAT9 | Use Tomcat servlet container 9.x (see ) | | +| TOMCAT10 | Use Tomcat servlet container 10.x (see ) | | +| WILDFLY9 | Use Wildfly servlet container 9.x (see ) | EOL | +| WILDFLY27 | Use Wildfly servlet container 27.x (see ) | EOL | +| WILDFLY33 | Use Wildfly servlet container 33.x (see ) | EOL | {{% content "java-env-injection" %}} diff --git a/content/doc/applications/linux.md b/content/doc/applications/linux.md index 36dbfec9b..2f2d6a206 100644 --- a/content/doc/applications/linux.md +++ b/content/doc/applications/linux.md @@ -30,6 +30,7 @@ To create a new Linux application, use the [Clever Cloud Console](https://consol ```bash clever create --type linux ``` + - [Learn more about Clever Tools](/doc/cli/) - [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) diff --git a/content/doc/applications/meteor.md b/content/doc/applications/meteor.md index ac056429e..f7b7448ce 100644 --- a/content/doc/applications/meteor.md +++ b/content/doc/applications/meteor.md @@ -36,9 +36,9 @@ Be sure your `.meteor` folder is in your git repository. To run your Meteor.js application you need a few mandatory environment variables: -* `MONGO_URL`: this is the mongo uri you can find in your mongodb's dashboard, it has to start with `mongodb://` -* `ROOT_URL`: this is your application's root url. It has to start with `http://` or `https://` -* `PORT`: keep the current value of 8080 +- `MONGO_URL`: this is the mongo uri you can find in your mongodb's dashboard, it has to start with `mongodb://` +- `ROOT_URL`: this is your application's root url. It has to start with `http://` or `https://` +- `PORT`: keep the current value of 8080 With Meteor 2.6.n comes MongoDB 5.n and [the new npm driver](https://guide.meteor.com/2.6-migration.html). You need to append `?directConnection=true` in your `MONGO_URL` to avoid the new mongo driver Service Discovery feature. @@ -94,7 +94,7 @@ Your application will then be built using `meteor build --server-only` and deplo Oplog tailing is supported on dedicated databases (starting from Hazelnut size). Contact the support to enable oplog. Once enabled, set the following environment variable: -* `MONGO_OPLOG_URL`: `mongodb://[…]mongodb.services.clever-cloud.com:{DB_PORT}/local?authSource={DB_NAME}` +- `MONGO_OPLOG_URL`: `mongodb://[…]mongodb.services.clever-cloud.com:{DB_PORT}/local?authSource={DB_NAME}` Since Meteor 2.6.n the mongo driver detect the `MONGO_OPLOG_URL` by itself and you should not add this to your environment variables. diff --git a/content/doc/applications/nodejs.md b/content/doc/applications/nodejs.md index 0dc281abb..698e08d05 100644 --- a/content/doc/applications/nodejs.md +++ b/content/doc/applications/nodejs.md @@ -45,8 +45,9 @@ To create a new Node.js & Bun application, use the [Clever Cloud Console](https: ```bash clever create --type node ``` -* [Learn more about Clever Tools](/doc/cli/) -* [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) + +- [Learn more about Clever Tools](/doc/cli/) +- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) ## Configure your Node.js & Bun application @@ -54,11 +55,11 @@ clever create --type node Be sure that: -* You listen on HTTP port **0.0.0.0:8080** -* You have a `package.json` file -* Your `package.json` either has a **scripts.start** or a **main** field -* The folder `/node_modules` is mentioned in your `.gitignore` file -* You enable production mode by setting the [environment variable](#setting-up-environment-variables-on-clever-cloud) `NODE_ENV=production` +- You listen on HTTP port **0.0.0.0:8080** +- You have a `package.json` file +- Your `package.json` either has a **scripts.start** or a **main** field +- The folder `/node_modules` is mentioned in your `.gitignore` file +- You enable production mode by setting the [environment variable](#setting-up-environment-variables-on-clever-cloud) `NODE_ENV=production` ### Memory management @@ -111,7 +112,7 @@ You can use additional scripts as an alternative to [Clever Cloud hooks](/doc/de If you need some modules you can easily add some with the *dependencies* field in your `package.json`. Here is an example: -```json {linenos=table} +```json {linenos=table} { "name" : { … }, "engines": { … }, @@ -132,12 +133,12 @@ If your application has private dependencies, you can add a [private SSH key](/d Clever Cloud supports any package manager compatible with Node.js ecosystem. The [environment variable](#setting-up-environment-variables-on-clever-cloud) `CC_NODE_BUILD_TOOL` allows you to define which one you want to use to install dependencies during the build phase: -* `bun`: uses [Bun](https://bun.sh) as a package manager and as a runtime -* `npm` or `npm-install`: default, uses [npm install](https://docs.npmjs.com/cli/install) -* `npm-ci`: uses [npm clean-install](https://docs.npmjs.com/cli/ci) -* `pnpm`: uses [pnpm](https://pnpm.io) -* `yarn-berry`: uses [Yarn](https://yarnpkg.com/) -* `custom`: use another package manager, defined with `CC_CUSTOM_BUILD_TOOL` +- `bun`: uses [Bun](https://bun.sh) as a package manager and as a runtime +- `npm` or `npm-install`: default, uses [npm install](https://docs.npmjs.com/cli/install) +- `npm-ci`: uses [npm clean-install](https://docs.npmjs.com/cli/ci) +- `pnpm`: uses [pnpm](https://pnpm.io) +- `yarn-berry`: uses [Yarn](https://yarnpkg.com/) +- `custom`: use another package manager, defined with `CC_CUSTOM_BUILD_TOOL` > [!NOTE] Yarn 1.x and 2.x deprecation > `yarn` and `yarn2` are still valid values but the Yarn team no longer maintains 1.x and 2.x branches. Use `yarn-berry` instead. @@ -153,7 +154,7 @@ deno = "latest" Then it will be installed during deployment. You can replace `latest` with a specific version. -* [Lume with Deno guide](/guides/lume-deno/) +- [Lume with Deno guide](/guides/lume-deno/) ### Automatic detection @@ -182,7 +183,7 @@ If you use Bun, your application is deployed with the latest available version o Bun includes a [native S3 client](https://bun.sh/docs/api/s3) that works with [Cellar](/doc/addons/cellar/#using-sdks), the Clever Cloud S3-compatible object storage service, with no external dependency required. -* [Learn more about Bun native Clever Cloud add-ons support with examples](https://github.com/CleverCloud/bun-addons-examples) +- [Learn more about Bun native Clever Cloud add-ons support with examples](https://github.com/CleverCloud/bun-addons-examples) ### pnpm and Yarn versions @@ -196,8 +197,8 @@ To load a specific version, set the `packageManager` field in your `package.json This is the default way to manage version for pnpm and Yarn when a new project is initialized. It will define the version used for dependency installation during the build phase and in run command. Yarn `1.22.22` remains the default system version included for legacy reasons. -* If `CC_NODE_BUILD_TOOL` is set to `yarn-berry`, the latest 4.x packaged version of Yarn becomes the system default -* If you use Yarn 1.x or Yarn 2.x, a deprecation warning is displayed during deployment as they're not maintained anymore +- If `CC_NODE_BUILD_TOOL` is set to `yarn-berry`, the latest 4.x packaged version of Yarn becomes the system default +- If you use Yarn 1.x or Yarn 2.x, a deprecation warning is displayed during deployment as they're not maintained anymore > [!TIP] > If you set `CC_NODE_BUILD_TOOL` to `yarn-berry` in any Clever Cloud runtime, Yarn 4.x becomes the default system version. diff --git a/content/doc/applications/php/_index.md b/content/doc/applications/php/_index.md index 7cf2bd727..10dd56e56 100644 --- a/content/doc/applications/php/_index.md +++ b/content/doc/applications/php/_index.md @@ -40,6 +40,7 @@ To create a new PHP application, use the [Clever Cloud Console](https://console. ```bash clever create --type php ``` + - [Learn more about Clever Tools](/doc/cli/) - [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) @@ -130,17 +131,17 @@ date.timezone=Europe/Paris Clever Cloud configures PHP's [`memory_limit`](https://www.php.net/manual/en/ini.core.php#ini.memory-limit) directive, which limits how much memory each PHP script can allocate. For web requests, this limit applies independently within each PHP-FPM worker; memory is not reserved when workers start. Both the default limit and the maximum value accepted through `MEMORY_LIMIT` depend on the application's available memory, which excludes memory reserved for the system: | Flavor | Default `memory_limit` | Maximum `MEMORY_LIMIT` | -|--------|-----------------------:|-----------------------:| -| Nano | 91 MiB | 358 MiB | -| XS | 161 MiB | 859 MiB | -| S | 249 MiB | 1683 MiB | -| M | 406 MiB | 3579 MiB | -| L | 658 MiB | 7523 MiB | -| XL | 1051 MiB | 15496 MiB | -| 2XL | 1377 MiB | 23503 MiB | -| 3XL | 1666 MiB | 31525 MiB | - -To change the limit, set [`MEMORY_LIMIT`](/doc/reference/reference-environment-variables#php) to a positive integer interpreted in MiB, without a unit suffix. +| ------ | ---------------------: | ---------------------: | +| Nano | 91 MiB | 358 MiB | +| XS | 161 MiB | 859 MiB | +| S | 249 MiB | 1683 MiB | +| M | 406 MiB | 3579 MiB | +| L | 658 MiB | 7523 MiB | +| XL | 1051 MiB | 15496 MiB | +| 2XL | 1377 MiB | 23503 MiB | +| 3XL | 1666 MiB | 31525 MiB | + +To change the limit, set [`MEMORY_LIMIT`](/doc/reference/reference-environment-variables#php) to a positive integer interpreted in MiB, without a unit suffix. For example, to allow each PHP script to allocate up to 128 MiB: @@ -148,7 +149,7 @@ For example, to allow each PHP script to allocate up to 128 MiB: clever env set MEMORY_LIMIT 128 ``` -If `MEMORY_LIMIT` exceeds the maximum value for the selected flavor, Clever Cloud keeps the automatically calculated limit and logs a warning during deployment. Clever Cloud also calculates the number of PHP-FPM workers automatically. +If `MEMORY_LIMIT` exceeds the maximum value for the selected flavor, Clever Cloud keeps the automatically calculated limit and logs a warning during deployment. Clever Cloud also calculates the number of PHP-FPM workers automatically. On XS and larger flavors, setting [`CC_CONFIGURATION_PM_MAX_CHILDREN`](/doc/reference/reference-environment-variables#php) can lower the calculated memory limit. On Nano, the platform always uses six workers. If you also set a valid `MEMORY_LIMIT`, it takes precedence over the adjustment based on the number of workers. diff --git a/content/doc/applications/php/sessions-emails.md b/content/doc/applications/php/sessions-emails.md index c8c2ccf4b..34f5199a7 100644 --- a/content/doc/applications/php/sessions-emails.md +++ b/content/doc/applications/php/sessions-emails.md @@ -53,12 +53,12 @@ Mailpace add-on can send emails through PHP `mail()` function. You have to turn Services like [Mailgun](https://www.mailgun.com/) or [Mailjet](https://www.mailjet.com/) provide SMTP servers. If your application has no other way but to use the `mail` function of PHP to send emails, you have to configure a SMTP server. This can be done through environment variables: -| Name | Description | Default | -|------|-------------|---------| -| `CC_MTA_SERVER_HOST` | Host of the SMTP server | | -| `CC_MTA_SERVER_PORT` | Port of the SMTP server | `465` | -| `CC_MTA_AUTH_USER` | User to authenticate to the SMTP server | | -| `CC_MTA_AUTH_PASSWORD` | Password to authenticate to the SMTP server | | -| `CC_MTA_SERVER_USE_TLS` | Enable or disable TLS | `true` | -| `CC_MTA_SERVER_STARTTLS` | Enable or disable STARTTLS | `false` | -| `CC_MTA_SERVER_AUTH_METHOD` | Enable or disable authentication | `on` | +| Name | Description | Default | +| --------------------------- | ------------------------------------------- | ------- | +| `CC_MTA_SERVER_HOST` | Host of the SMTP server | | +| `CC_MTA_SERVER_PORT` | Port of the SMTP server | `465` | +| `CC_MTA_AUTH_USER` | User to authenticate to the SMTP server | | +| `CC_MTA_AUTH_PASSWORD` | Password to authenticate to the SMTP server | | +| `CC_MTA_SERVER_USE_TLS` | Enable or disable TLS | `true` | +| `CC_MTA_SERVER_STARTTLS` | Enable or disable STARTTLS | `false` | +| `CC_MTA_SERVER_AUTH_METHOD` | Enable or disable authentication | `on` | diff --git a/content/doc/applications/python/_index.md b/content/doc/applications/python/_index.md index 6bdf7a131..a7c2b5d02 100644 --- a/content/doc/applications/python/_index.md +++ b/content/doc/applications/python/_index.md @@ -40,6 +40,7 @@ To create a new Python application, use the [Clever Cloud Console](https://conso ```bash clever create --type python ``` + - [Learn more about Clever Tools](/doc/cli/) - [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) diff --git a/content/doc/applications/python/servers.md b/content/doc/applications/python/servers.md index 695167877..6768e14f1 100644 --- a/content/doc/applications/python/servers.md +++ b/content/doc/applications/python/servers.md @@ -20,13 +20,13 @@ uWSGI, Gunicorn and Nginx settings can be configured by setting environment vari ### uWSGI -| Name | Description | Default | -|------|-------------|---------| -| `HARAKIRI` | Timeout (in seconds) after which an unresponsive process is killed | `180` | -| `WSGI_BUFFER_SIZE` | Maximal size (in bytes) for the headers of a request | `4096` | -| `WSGI_POST_BUFFERING` | Buffer size (in bytes) for uploads | `4096` | -| `WSGI_WORKERS` | Number of workers | depends on the scaler | -| `WSGI_THREADS` | Number of threads per worker | depends on the scaler | +| Name | Description | Default | +| --------------------- | ------------------------------------------------------------------ | --------------------- | +| `HARAKIRI` | Timeout (in seconds) after which an unresponsive process is killed | `180` | +| `WSGI_BUFFER_SIZE` | Maximal size (in bytes) for the headers of a request | `4096` | +| `WSGI_POST_BUFFERING` | Buffer size (in bytes) for uploads | `4096` | +| `WSGI_WORKERS` | Number of workers | depends on the scaler | +| `WSGI_THREADS` | Number of threads per worker | depends on the scaler | You can inject additional uWSGI configuration directives with `CC_UWSGI_EXTRA_CONFIG`. To disable the file wrapper, set `CC_UWSGI_DISABLE_FILE_WRAPPER` to `true`. @@ -39,19 +39,19 @@ To enable [uWSGI asynchronous](https://uwsgi-docs.readthedocs.io/en/latest/Async ### Gunicorn -| Name | Description | Default | -|------|-------------|---------| -| `CC_GUNICORN_WORKER_CLASS` | Type of worker to use. [Available workers](https://gunicorn.org/reference/settings/#worker_class) | `sync` | -| `CC_GUNICORN_TIMEOUT` | Gunicorn timeout (in seconds) | `30` | -| `CC_GUNICORN_LOGLEVEL` | Gunicorn log level | `info` | +| Name | Description | Default | +| -------------------------- | ------------------------------------------------------------------------------------------------- | ------- | +| `CC_GUNICORN_WORKER_CLASS` | Type of worker to use. [Available workers](https://gunicorn.org/reference/settings/#worker_class) | `sync` | +| `CC_GUNICORN_TIMEOUT` | Gunicorn timeout (in seconds) | `30` | +| `CC_GUNICORN_LOGLEVEL` | Gunicorn log level | `info` | ### Nginx -| Name | Description | Default | -|------|-------------|---------| -| `NGINX_READ_TIMEOUT` | Response timeout in seconds (similar to `HARAKIRI`) | `300` | -| `ENABLE_GZIP_COMPRESSION` | Enable gzip compression (`on`, `yes`, or `true`) | | -| `GZIP_TYPES` | The mime types to gzip | `text/plain text/css text/xml text/javascript application/json application/xml application/javascript image/svg+xml` | +| Name | Description | Default | +| ------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| `NGINX_READ_TIMEOUT` | Response timeout in seconds (similar to `HARAKIRI`) | `300` | +| `ENABLE_GZIP_COMPRESSION` | Enable gzip compression (`on`, `yes`, or `true`) | | +| `GZIP_TYPES` | The mime types to gzip | `text/plain text/css text/xml text/javascript application/json application/xml application/javascript image/svg+xml` | #### Basic authentication @@ -88,10 +88,10 @@ Nginx settings can be configured further in `clevercloud/http.json`. All its fie To enable Nginx to serve your static resources, you have to set two environment variables. -| Name | Description | -|------|-------------| +| Name | Description | +| ------------------- | --------------------------------------------------------------------------------------------- | | `STATIC_FILES_PATH` | Directory where your static files are stored (absolute path relative to the application root) | -| `STATIC_URL_PREFIX` | URL path under which you want to serve static files (e.g. `/public`) | +| `STATIC_URL_PREFIX` | URL path under which you want to serve static files (e.g. `/public`) | You can also use a [Filesystem Bucket](/doc/addons/fs-bucket) to store your static files. diff --git a/content/doc/applications/python/uv.md b/content/doc/applications/python/uv.md index 2933ad892..dc0f1c72a 100644 --- a/content/doc/applications/python/uv.md +++ b/content/doc/applications/python/uv.md @@ -44,12 +44,12 @@ The application starts with the command defined in `CC_PYTHON_UV_RUN_COMMAND`. I `CC_RUN_COMMAND` takes precedence over `CC_PYTHON_UV_RUN_COMMAND` if both are set. -| Name | Description | Required | Default | -| ---- | ----------- | -------- | ------- | -| `CC_PYTHON_UV_RUN_COMMAND` | Command to start the application (e.g. `uv run python app.py`) | Yes | - | -| `CC_RUN_COMMAND` | Overrides `CC_PYTHON_UV_RUN_COMMAND` if set | No | - | -| `ENVIRONMENT` | Set to `development` to include dev dependencies during build | No | `production` | -| `PORT` | Port used by your HTTP server | No | `8080` | +| Name | Description | Required | Default | +| -------------------------- | -------------------------------------------------------------- | -------- | ------------ | +| `CC_PYTHON_UV_RUN_COMMAND` | Command to start the application (e.g. `uv run python app.py`) | Yes | - | +| `CC_RUN_COMMAND` | Overrides `CC_PYTHON_UV_RUN_COMMAND` if set | No | - | +| `ENVIRONMENT` | Set to `development` to include dev dependencies during build | No | `production` | +| `PORT` | Port used by your HTTP server | No | `8080` | ## Differences with legacy Python deployment diff --git a/content/doc/applications/rust.md b/content/doc/applications/rust.md index a2d663f87..df940532f 100644 --- a/content/doc/applications/rust.md +++ b/content/doc/applications/rust.md @@ -40,10 +40,10 @@ Clever Cloud allows you to deploy Rust web applications. This page will explain Make sure that: -* you have pushed in **master** branch -* you listen on port **8080** -* you have committed `Cargo.lock` -* you have at least one binary target in `Cargo.toml` +- you have pushed in **master** branch +- you listen on port **8080** +- you have committed `Cargo.lock` +- you have at least one binary target in `Cargo.toml` The result of `cargo build --release --locked` must be an executable which starts a web server listening on `0.0.0.0:8080`. @@ -112,8 +112,8 @@ First, you need to use the `HTTPS` url as the git url for your dependency in you Then, you need to create a personal access token. It allows to not use your password: -* `Github`: -* `GitLab`: (API rights are needed) +- `Github`: +- `GitLab`: (API rights are needed) Once you have the token, we need to tell Git to use a credential store. For that, we are going to create it. @@ -131,10 +131,10 @@ If you have multiple private repositories, add them accordingly. Now, go into the environment variables page of your application and create those environment variables: -* `GIT_USERNAME`: your Github / gitlab / other username -* `GIT_PASSWORD`: your Github / gitlab / other password -* `CC_PRE_BUILD_HOOK`: clevercloud/pre-build.sh -* `CC_POST_BUILD_HOOK`: rm /home/bas/.git-credentials +- `GIT_USERNAME`: your Github / gitlab / other username +- `GIT_PASSWORD`: your Github / gitlab / other password +- `CC_PRE_BUILD_HOOK`: clevercloud/pre-build.sh +- `CC_POST_BUILD_HOOK`: rm /home/bas/.git-credentials This adds the git configuration before the build start and it cleans it after the build has been done. @@ -177,4 +177,3 @@ This loads the environment variable in your `main` function and use `.expect` to {{% content "url_healthcheck" %}} {{% content "request-flow" %}} - diff --git a/content/doc/applications/scala/play-framework-1.md b/content/doc/applications/scala/play-framework-1.md index 461989296..d6209e7e5 100644 --- a/content/doc/applications/scala/play-framework-1.md +++ b/content/doc/applications/scala/play-framework-1.md @@ -35,16 +35,16 @@ Clever Cloud supports Play! **1.2** to **1.11**. You can select the Play! versio The `PLAY1_VERSION` environment variable can contain one of the following values: -* `1.2` or `12` for **Play! 1.2** -* `1.3` or `12` for **Play! 1.3** -* `1.4` or `14` for **Play! 1.4** -* `1.5` or `15` for **Play! 1.5** -* `1.6` or `16` for **Play! 1.6** -* `1.7` or `17` for **Play! 1.7** -* `1.8` or `18` for **Play! 1.8** -* `1.9` or `19` for **Play! 1.9** -* `1.10` or `110` for **Play! 1.10** -* `1.11` or `111` for **Play! 1.11** +- `1.2` or `12` for **Play! 1.2** +- `1.3` or `12` for **Play! 1.3** +- `1.4` or `14` for **Play! 1.4** +- `1.5` or `15` for **Play! 1.5** +- `1.6` or `16` for **Play! 1.6** +- `1.7` or `17` for **Play! 1.7** +- `1.8` or `18` for **Play! 1.8** +- `1.9` or `19` for **Play! 1.9** +- `1.10` or `110` for **Play! 1.10** +- `1.11` or `111` for **Play! 1.11** ### Play! configuration with application.conf @@ -53,13 +53,13 @@ It means that you can define special keys in your `application.conf` file that w You can for example: -* set production mode so the files are compiled at startup time and the errors are logged in a file: +- set production mode so the files are compiled at startup time and the errors are logged in a file: ```bash %clevercloud.application.mode=prod ``` -* set up a mysql database (using environment variables) +- set up a mysql database (using environment variables) ```bash %clevercloud.db.url="jdbc:mysql://"${MYSQL_ADDON_HOST}"/"${MYSQL_ADDON_DB} diff --git a/content/doc/applications/scala/play-framework-2.md b/content/doc/applications/scala/play-framework-2.md index bfadbb9de..d3617d1cd 100644 --- a/content/doc/applications/scala/play-framework-2.md +++ b/content/doc/applications/scala/play-framework-2.md @@ -32,7 +32,7 @@ Clever Cloud supports Play! 2 applications natively. The following guide explain ### Mandatory configuration -* Starting from **Play 2.4**, your application needs **Java 8** to run. Please read [select java version](/doc/applications/java/java-war/#available-java-versions "Select Java version") for more information. +- Starting from **Play 2.4**, your application needs **Java 8** to run. Please read [select java version](/doc/applications/java/java-war/#available-java-versions "Select Java version") for more information. Play! 2 applications use sbt. Please have a look at [deploy Scala apps](/doc/applications/scala) for a complete documentation on sbt deployment options. @@ -40,9 +40,9 @@ Play! 2 applications use sbt. Please have a look at [deploy Scala apps](/doc/app To deploy a Play! application you have to set a secret in your `conf/application.conf` the environment variable name depends on your Play2! version: -* 2.6.x: `play.http.secret.key=${?APPLICATION_SECRET}`, to generate secret use `sbt playGenerateSecret`; -* 2.4.x -> 2.5.x: `play.crypto.secret=${?APPLICATION_SECRET}` -> `sbt playGenerateSecret`; -* 2.3.x: `application.secret=${?APPLICATION_SECRET}` -> `sbt play-generate-secret`. +- 2.6.x: `play.http.secret.key=${?APPLICATION_SECRET}`, to generate secret use `sbt playGenerateSecret`; +- 2.4.x -> 2.5.x: `play.crypto.secret=${?APPLICATION_SECRET}` -> `sbt playGenerateSecret`; +- 2.3.x: `application.secret=${?APPLICATION_SECRET}` -> `sbt play-generate-secret`. Then, in your Clever Cloud application define `APPLICATION_SECRET` [environment variable](#setting-up-environment-variables-on-clever-cloud) with the generated value. @@ -87,7 +87,7 @@ To expose an environment variable through Play configuration, add `my.option=${? If your project fails with the error `sbt.ResolveException: unresolved dependency: play#sbt-plugin;2.0: not found` this is because some versions of Play2 try to retrieve a nonexistent version of "sbt-plugin" which is required by the framework. You have two options to fix this problem: -* You can set the "play.version" environment variable in the `/clevercloud/sbt.json` file. For example, for Play 2.0.4: +- You can set the "play.version" environment variable in the `/clevercloud/sbt.json` file. For example, for Play 2.0.4: ``` javascript { @@ -97,7 +97,7 @@ You have two options to fix this problem: } ``` -* You can modify `plugins.sbt` in the project folder of your app like the following: +- You can modify `plugins.sbt` in the project folder of your app like the following: ``` scala // Comment to get more information during initialization diff --git a/content/doc/applications/static-apache.md b/content/doc/applications/static-apache.md index f327d8ede..5ad209fb3 100644 --- a/content/doc/applications/static-apache.md +++ b/content/doc/applications/static-apache.md @@ -90,9 +90,11 @@ To use it with our static applications, you need a `.htaccess` file like this at ``` + You can find your `PRERENDER_TOKEN` on your [Prerender.io account](https://prerender.io/). You can verify your configuration work using [this guide](https://docs.prerender.io/docs/how-to-test-your-site-after-you-have-successfully-validated-your-prerender-integration). + ## Apache Configuration with `CC_WEBROOT` If you set the `CC_WEBROOT = /` environment variable, make sure you put your `.htaccess` file at the root of your `/`. This is where Apache will look for directives when you deploy an application in a Static runtime. @@ -100,6 +102,7 @@ If you set the `CC_WEBROOT = /` environment variable, make sure you If you don't set the [`CC_WEBROOT`](/doc/reference/reference-environment-variables/#php) environment variable, the root of your project is the root of your web server. ## 🎓 Static Site Generators (SSG) guides + {{% content-raw "static-guides" %}} {{% content "request-flow" %}} diff --git a/content/doc/applications/static.md b/content/doc/applications/static.md index ac0bd5dc4..bc98ce195 100644 --- a/content/doc/applications/static.md +++ b/content/doc/applications/static.md @@ -41,6 +41,7 @@ To create a new Static application, use the [Clever Cloud Console](https://conso ```bash clever create --type static ``` + - [Learn more about Clever Tools](/doc/cli/) - [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) @@ -143,6 +144,7 @@ Supported Static Site Generators (SSG) are: - Detected file: `config.toml` ## 🎓 Static Site Generators (SSG) guides + {{% content-raw "static-guides" %}} {{% content "url_healthcheck" %}} diff --git a/content/doc/applications/v.md b/content/doc/applications/v.md index 4d4816d49..0cae3c86d 100644 --- a/content/doc/applications/v.md +++ b/content/doc/applications/v.md @@ -26,6 +26,7 @@ To create a new V (Vlang) application, use the [Clever Cloud Console](https://co ```bash clever create --type v ``` + - [Learn more about Clever Tools](/doc/cli/) - [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) diff --git a/content/doc/best-practices/load-testing.md b/content/doc/best-practices/load-testing.md index b7e1ffc50..1666e6e29 100644 --- a/content/doc/best-practices/load-testing.md +++ b/content/doc/best-practices/load-testing.md @@ -19,9 +19,9 @@ Performing a performance test is the best way to determine how your application In general, these tests make it possible to identify: -* the maximum number of concurrent users -* whether the current resources are sufficient to operate your application in good conditions -* and the maximum operational capacity of your application +- the maximum number of concurrent users +- whether the current resources are sufficient to operate your application in good conditions +- and the maximum operational capacity of your application ## Considerations to take into account @@ -33,19 +33,19 @@ In case you have dedicated frontends, note that too much load could impact your Performing these tests will allow you: -* to have perspective on the performance and stability of your infrastructure. -* to be able to identify bottlenecks in particular stress scenarios -* to identify and remove any weaknesses in architectures via supervision and performance management strategies and increase scalability +- to have perspective on the performance and stability of your infrastructure. +- to be able to identify bottlenecks in particular stress scenarios +- to identify and remove any weaknesses in architectures via supervision and performance management strategies and increase scalability The determining elements are: -* The response time of your transactions (poorly optimized requests, etc.) -* The performance of the application (single-threaded application, expectations of external services, generation of logs in a file, etc.) -* The performance of managed services such as databases (lack of indexes, unnecessary iterations, etc.) -* Software design in general -* Hardware limitations such as CPU, RAM, network, etc. -* bad middleware configurations (databases, server, etc.) -* The response time between the client and the application +- The response time of your transactions (poorly optimized requests, etc.) +- The performance of the application (single-threaded application, expectations of external services, generation of logs in a file, etc.) +- The performance of managed services such as databases (lack of indexes, unnecessary iterations, etc.) +- Software design in general +- Hardware limitations such as CPU, RAM, network, etc. +- bad middleware configurations (databases, server, etc.) +- The response time between the client and the application ## Online and local load tools @@ -55,15 +55,15 @@ Choosing a load-testing solution will depend on several factors. If simplicity a Online services are available to perform your tests. Most offer typical user journey scenarios to allow you to simulate a user: -* [K6](https://k6.io) -* [Octoperf](https://octoperf.com) -* [Loader.io](https://loader.io) +- [K6](https://k6.io) +- [Octoperf](https://octoperf.com) +- [Loader.io](https://loader.io) ### Local, with open source alternatives Some open source services to be installed on an infrastructure (workstation or IaaS in the best case) are also available: -* [Gatling](https://gatling.io) -* [Drill](https://github.com/fcsonline/drill) -* [Locust](https://locust.io) -* [Jmeter](https://jmeter.apache.org) +- [Gatling](https://gatling.io) +- [Drill](https://github.com/fcsonline/drill) +- [Locust](https://locust.io) +- [Jmeter](https://jmeter.apache.org) diff --git a/content/doc/best-practices/tips_and_tricks.md b/content/doc/best-practices/tips_and_tricks.md index 6bd44a18c..9492c1642 100644 --- a/content/doc/best-practices/tips_and_tricks.md +++ b/content/doc/best-practices/tips_and_tricks.md @@ -23,18 +23,18 @@ The [Clever Cloud Console](https://console.clever-cloud.com) is your control cen The left sidebar menu includes a powerful search function. Beyond simple name searches, you can use special keywords to filter your resources: -| Keyword | What it Shows | -| ------- | ----------- | -| `is:addon` | Lists all your add-ons | -| `is:app` | Shows only applications | +| Keyword | What it Shows | +| -------------- | --------------------------------------------------------------------------------- | +| `is:addon` | Lists all your add-ons | +| `is:app` | Shows only applications | | `is:[addon]` | Filters specific add-on types (Examples: `is:postgresql`, `is:redis`, `is:mysql`) | -| `is:[runtime]` | Shows applications by runtime (Examples: `is:node`, `is:php`, `is:java`) | +| `is:[runtime]` | Shows applications by runtime (Examples: `is:node`, `is:php`, `is:java`) | ### OpenSearch support Clever Cloud supports OpenSearch, allowing you to add [the Console](https://console.clever-cloud.com) as a search engine in your browser, such as [Chrome](https://support.google.com/chrome/answer/95426) or [Firefox](https://support.mozilla.org/kb/add-or-remove-search-engine-firefox). Then, you can quickly search for applications, add-ons or organisations directly from your address bar. For example, add: -``` +```yaml name: Clever Cloud shortcut: cc search URL: https://console.clever-cloud.com/search?q=%s @@ -103,17 +103,17 @@ Press the `/` key anywhere in the Console to search for applications, add-ons, o Use these shortcuts when viewing applications or add-ons: -| Key | Takes You To | -| --- | ----------- | +| Key | Takes You To | +| --- | ----------------------- | | `?` | Keyboard shortcuts help | -| `a` | Application activity | -| `d` | Domain settings | -| `e` | Environment variables | -| `i` | Resource information | -| `l` | Logs view | -| `m` | Application metrics | -| `o` | Overview page | -| `s` | Scalability settings | +| `a` | Application activity | +| `d` | Domain settings | +| `e` | Environment variables | +| `i` | Resource information | +| `l` | Logs view | +| `m` | Application metrics | +| `o` | Overview page | +| `s` | Scalability settings | ### Running One-Time Tasks @@ -303,7 +303,6 @@ Each application maintains: - Individual environment variables - Automatic TLS certificate generation - [Path routing documentation](/doc/administrate/domain-names/#path-routing) ### Create Custom Add-ons @@ -326,7 +325,6 @@ The `cleverapps.io` domain system offers: Remove these domains when moving to production with your custom domain. - ### API-First Platform Clever Cloud's entire platform runs on its public API: diff --git a/content/doc/billing/_index.md b/content/doc/billing/_index.md index 060038253..2b886776a 100644 --- a/content/doc/billing/_index.md +++ b/content/doc/billing/_index.md @@ -23,6 +23,6 @@ aliases: {{< cards >}} {{< card link="/developers/doc/billing/analytics-consumption" title="Analytics and consumption" icon="chart-bar" >}} {{< card link="/developers/doc/billing/payments-invoicing" title="Payments & invoicing" icon="banknotes" >}} - {{< card link="https://www.clever.cloud/pricing/" title="Pricing" icon="currency-euro" >}} + {{< card link="" title="Pricing" icon="currency-euro" >}} {{< card link="/developers/doc/billing/unified-invoices" title="Unified invoicing" icon="user-group" >}} {{< /cards >}} diff --git a/content/doc/billing/analytics-consumption.md b/content/doc/billing/analytics-consumption.md index 9e5e3f940..6e158464b 100644 --- a/content/doc/billing/analytics-consumption.md +++ b/content/doc/billing/analytics-consumption.md @@ -20,10 +20,10 @@ Clever Cloud's billing is based on several types of products: applications (Java The calculation of consumption is based on the second of running. Once your monthly bill has been generated, you can refer to it to find out by service: -* the size of the instances used -* the execution time -* the unit price per second -* the total monthly amount +- the size of the instances used +- the execution time +- the unit price per second +- the total monthly amount To find your consumption history, it is visible in the **Metrics in Grafana** service via a specific Grafana dashboard. This is called the **Uptime Service**. diff --git a/content/doc/billing/payments-invoicing.md b/content/doc/billing/payments-invoicing.md index 66bf154a8..5acf2c3ad 100644 --- a/content/doc/billing/payments-invoicing.md +++ b/content/doc/billing/payments-invoicing.md @@ -19,10 +19,10 @@ aliases: In the sidebar of the organisation section, there are three alternatives to buy credit for your applications: -* Credit card (powered by Stripe) -* Paypal -* Bank transfer: we accept international bank transfers. This option will generate a reference that you will have to add to your bank transfert, as a note. -* SEPA Direct Debit: we support payment via SEPA debit. More information in the [SEPA Direct Debit section](#sepa-direct-debit) +- Credit card (powered by Stripe) +- Paypal +- Bank transfer: we accept international bank transfers. This option will generate a reference that you will have to add to your bank transfert, as a note. +- SEPA Direct Debit: we support payment via SEPA debit. More information in the [SEPA Direct Debit section](#sepa-direct-debit) ## Invoices @@ -36,9 +36,9 @@ Also an organisation member with the accountant role can receive invoices as des ## Change Billing Information -* for personal account: available in *Profile > Informations* +- for personal account: available in *Profile > Informations* -* for organisation: available in *Information > Billing details* +- for organisation: available in *Information > Billing details* ![Clever Cloud Console: "Information menu from the organisation"](/images/billing-infos.png "organisation information") @@ -58,9 +58,9 @@ Mandate: > > Debit instructions are issued in the following cases: > -> * when you confirm an invoice payment; -> * starting 5 days after issuing the invoice, would you set your IBAN as default payment method; -> * would the first debit fail, new attempts will be made every day up to 15 days after invoice issuance and every 5 days after that. +> - when you confirm an invoice payment; +> - starting 5 days after issuing the invoice, would you set your IBAN as default payment method; +> - would the first debit fail, new attempts will be made every day up to 15 days after invoice issuance and every 5 days after that. > Your rights are explained in a statement that you can obtain from your bank. ### About invoices issuance and notifications diff --git a/content/doc/billing/unified-invoices.md b/content/doc/billing/unified-invoices.md index 6b199a215..784b3359a 100644 --- a/content/doc/billing/unified-invoices.md +++ b/content/doc/billing/unified-invoices.md @@ -23,9 +23,9 @@ At the beginning of each month, a new invoice is generated for each organisation The invoice is made up of three distinct sections: -* A summary of the total amount to be paid for the current month -* An exploded view of the invoice calculation, including credits used, coupons, provision for the coming month etc. -* and full details of the operating time of each service, of each service invoiced, of storage used etc. +- A summary of the total amount to be paid for the current month +- An exploded view of the invoice calculation, including credits used, coupons, provision for the coming month etc. +- and full details of the operating time of each service, of each service invoiced, of storage used etc. To find your invoices, go to your organisation and click on **Invoices** to see a list of them and their payment status: @@ -41,14 +41,14 @@ This first section shows the fee for the use of Clever Cloud over a month. Any d This part details line by line the evolution of your credit with: -* The balance of free credits (a) -* Pre-paid credits (b) -* The use of free credits (c) -* Expired credits (d) -* Use of your prepaid credits (e) -* Estimated consumption for the next period (f) -* Invoiced credits pending payment (g) -* Amount of prepaid credits to be topped up (h) +- The balance of free credits (a) +- Pre-paid credits (b) +- The use of free credits (c) +- Expired credits (d) +- Use of your prepaid credits (e) +- Estimated consumption for the next period (f) +- Invoiced credits pending payment (g) +- Amount of prepaid credits to be topped up (h) The **amount of prepaid credits to be topped up** and the **new balance of credits after settlement** are explained via calculations of the different types of credits and their use over time. @@ -65,8 +65,8 @@ This section of the invoice details the usage of each cloud service. While applications are billed on a per second basis, this may be different for managed services. From a billing point of view there are X categories -* time-based billing (per second) -* resource consumption billing +- time-based billing (per second) +- resource consumption billing For example, dedicated databases are charged by the second, just like applications. In contrast, services such as Cellar object storage or Pulsar are charged according to the volume of data stored and the volume of outgoing traffic. @@ -83,10 +83,10 @@ For each organisation it is possible to register one or more payment methods ([s As long as an invoice remains *pending*, we'll perform these actions on specific days: -* Try to issue an automatic payment using your favorite payment method everyday from the +- Try to issue an automatic payment using your favorite payment method everyday from the 5th to the 15th day after issuing the invoice, then every 5 days after that. -* Send a reminder via email every 5 days if the payment remains unsuccessful. -* Shutdown of your services everyday starting day 31 after invoice issue. +- Send a reminder via email every 5 days if the payment remains unsuccessful. +- Shutdown of your services everyday starting day 31 after invoice issue. This schedule can adapt according to your company's payment delays. Please reach out to us via the support to ensure the best experience. diff --git a/content/doc/ci-cd/custom-scripts.md b/content/doc/ci-cd/custom-scripts.md index 3e2ef919b..9d7957c41 100644 --- a/content/doc/ci-cd/custom-scripts.md +++ b/content/doc/ci-cd/custom-scripts.md @@ -61,7 +61,7 @@ before_script: # Download clever-tools before any script executes ## 🎓 Go further {{< cards >}} - {{< card link="https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables" title="GitHub variables" subtitle="List of GitHub default CI/CD variables" icon="github" >}} - {{< card link="https://docs.gitlab.com/ee/ci/variables/predefined_variables.html" title="GitLab variables" subtitle="List of GitLab predefined variables" icon="gitlab" >}} + {{< card link="" title="GitHub variables" subtitle="List of GitHub default CI/CD variables" icon="github" >}} + {{< card link="" title="GitLab variables" subtitle="List of GitLab predefined variables" icon="gitlab" >}} {{< card link="/developers/doc/cli" title="Clever Tools CLI" subtitle="Deploy and manage your applications and dependencies from your terminal." icon="command-line" >}} {{< /cards >}} diff --git a/content/doc/ci-cd/github.md b/content/doc/ci-cd/github.md index 9684cea56..32328fa6e 100644 --- a/content/doc/ci-cd/github.md +++ b/content/doc/ci-cd/github.md @@ -40,6 +40,7 @@ on: types: [opened, closed, synchronize, reopened] branches: [ main ] ``` + Then, use the action and define the mandatory input: ```yaml @@ -68,7 +69,6 @@ name: Create review app set-env: true # Enables the command to set en vars on Clever Cloud ``` - {{% content "ci-cd-configuration" %}} Full instructions are available on the [Action project](https://github.com/CleverCloud/clever-cloud-review-app). @@ -84,6 +84,6 @@ If you encounter troubles or bugs using the GitHub Action, feel free to open an ## 🎓 Go further {{< cards >}} - {{< card link="https://docs.github.com/en/actions" title="GitHub Actions documentation" subtitle="Find help in GitHub Actions documentation" icon="github" >}} + {{< card link="" title="GitHub Actions documentation" subtitle="Find help in GitHub Actions documentation" icon="github" >}} {{< card link="/developers/doc/cli" title="Clever Tools CLI" subtitle="Deploy and manage your applications and dependencies from your terminal." icon="command-line" >}} {{< /cards >}} diff --git a/content/doc/ci-cd/gitlab.md b/content/doc/ci-cd/gitlab.md index ae5ed726f..f58af701a 100644 --- a/content/doc/ci-cd/gitlab.md +++ b/content/doc/ci-cd/gitlab.md @@ -86,6 +86,6 @@ If you encounter troubles or bugs using the GitLab component, feel free to open ## 🎓 Go further {{< cards >}} - {{< card link="https://docs.gitlab.com/ee/ci/components" title="GitLab Components" subtitle="Learn how to use GitLab components" icon="gitlab" >}} + {{< card link="" title="GitLab Components" subtitle="Learn how to use GitLab components" icon="gitlab" >}} {{< card link="/developers/doc/cli" title="Clever Tools CLI" subtitle="Deploy and manage your applications and dependencies from your terminal." icon="command-line" >}} {{< /cards >}} diff --git a/content/doc/cli/_index.md b/content/doc/cli/_index.md index eb29d6731..c97f6ee39 100644 --- a/content/doc/cli/_index.md +++ b/content/doc/cli/_index.md @@ -65,14 +65,14 @@ You'll find below the first commands to know to connect Clever Tools to your acc To show Clever tools available commands, use: -``` +```console clever clever help ``` For each of them, you can add these parameters: -``` +```console [--help, -?] Display help about this program (default: false) [--version, -V] Display the version of this program (default: false) [--color] Choose whether to print colors or not. You can also use --no-color (default: true) @@ -89,20 +89,20 @@ Some features are available as experimental, before they're completely ready for Experimental features can be (de)activated on-demand. To list them, use: -``` +```console clever features ``` To (de)activate an experimental feature, use: -``` +```console clever features enable theFeature clever features disable theFeature ``` To get information about how to use an experimental feature, use: -``` +```console clever features info theFeature ``` @@ -110,7 +110,7 @@ clever features info theFeature To check the current version or get information about your setup, use: -``` +```console clever version clever diag clever diag --format json @@ -123,7 +123,7 @@ clever diag --format json To connect to your Clever Cloud account, use: -``` +```console clever login ``` @@ -131,7 +131,7 @@ It will open your default browser and start an Open Authorization ([OAuth](https If you already know them, you can use: -``` +```console clever login --secret SECRET --token TOKEN ``` @@ -140,7 +140,7 @@ clever login --secret SECRET --token TOKEN To log out, delete this file or use: -``` +```console clever logout clever logout --alias ALIAS ``` @@ -149,7 +149,7 @@ clever logout --alias ALIAS To get information about the current logged-in user (ID, name, email, 2FA activation, etc.), use: -``` +```console clever profile clever profile open clever profile -F json @@ -161,32 +161,32 @@ To manage multiple profiles or configure per-profile overrides, see: [Profiles a To list primary email and secondary emails associated with your Clever Cloud account, you can use: -``` +```console clever emails clever emails -F json ``` To open the email management page in your browser, use: -``` +```console clever emails open ``` To add a secondary email, use: -``` +```console clever emails add email@example.com ``` To set a secondary email as primary, use: -``` +```console clever emails primary email@example.com ``` To remove one or all secondary emails, use: -``` +```console clever emails remove email@example.com clever emails remove-all clever emails remove-all --yes @@ -196,26 +196,26 @@ clever emails remove-all --yes To list public SSH keys associated with your Clever Cloud account, you can use: -``` +```console clever ssh-keys clever ssh-keys -F json ``` To open the public SSH keys management page in your browser, use: -``` +```console clever ssh-keys open ``` To add a new public SSH key, use: -``` +```console clever ssh-keys add myPublicKey ~/.ssh/id_ecdsa.pub ``` To remove one or all public SSH keys, use: -``` +```console clever ssh-keys remove myPublicKey clever ssh-keys remove-all clever ssh-keys remove-all --yes @@ -232,26 +232,26 @@ To use our public API, you need to be authenticated for most endpoints. If you'r You can query [Clever Cloud public API](/api/) with a bearer token thanks to the Auth Bridge. To create a token, use: -``` +```console clever tokens create myTokenName clever tokens create myTokenName --expiration 2w --format json ``` Once created, you can use it replacing the API endpoint with `https://api-bridge.clever-cloud.com`. For example: -``` +```console curl https://api-bridge.clever-cloud.com/v2/self -H "Authorization: Bearer myToken" ``` To list all your tokens, use: -``` +```console clever tokens clever tokens -F json ``` To revoke a token, use: -``` +```console clever tokens revoke myTokenId ``` diff --git a/content/doc/cli/addons.md b/content/doc/cli/addons.md index 374b3807d..b6981f1eb 100644 --- a/content/doc/cli/addons.md +++ b/content/doc/cli/addons.md @@ -15,7 +15,7 @@ keywords: Add-ons on Clever Cloud are databases, storage services, tools or third party services you can enable through `clever addon provider`. For each of the following commands, you can target a specific user/organisation: -``` +```console [--org, -o, --owner] Organisation ID (or name, if unambiguous) ``` @@ -23,7 +23,7 @@ Add-ons on Clever Cloud are databases, storage services, tools or third party se To list provisioned add-ons, use: -``` +```console clever addon clever addon list clever addon list --format json @@ -33,7 +33,7 @@ clever addon list --format json To use add-ons, you need to identify the corresponding provider. To get information about them (plans, regions, versions), use: -``` +```console clever addon providers clever addon providers show PROVIDER_NAME ``` @@ -42,13 +42,13 @@ clever addon providers show PROVIDER_NAME To create an add-on, select a provider and choose a name: -``` +```console clever addon create PROVIDER ADDON_NAME ``` You can set `plan`, `region`, `version`, `option` and directly `link` an add-on to an application through these parameters: -``` +```console [--link, -l] ALIAS Link the created add-on to the app with the specified alias [--yes, -y] Skip confirmation even if the add-on is not free (default: false) [--plan, -p] PLAN Add-on plan, depends on the provider @@ -63,13 +63,13 @@ You can set `plan`, `region`, `version`, `option` and directly `link` an add-on To rename an add-on, use: -``` +```console clever addon rename ADDON_ID_OR_NAME ADDON_NEW_NAME ``` To delete an add-on, use: -``` +```console clever addon delete [--yes, -y] ADDON_ID_OR_NAME ``` @@ -77,7 +77,7 @@ clever addon delete [--yes, -y] ADDON_ID_OR_NAME Each add-on comes with environment variables. To get them, use: -``` +```console clever addon env [--format, -F] FORMAT ADDON_ID ``` @@ -88,7 +88,7 @@ For some add-ons, an interface URL, default credentials or other instructions ca If you're testing [Materia KV](/doc/addons/materia-kv/), our next generation of serverless distributed database, synchronously-replicated, compatible with Redis® protocol, you can create an add-on and immediately use it: -``` +```console clever addon create kv ADDON_NAME source <(clever addon env ADDON_ID --format shell) redis-cli -h $KV_HOST -p $KV_PORT --tls @@ -96,7 +96,8 @@ redis-cli -h $KV_HOST -p $KV_PORT --tls > [!TIP] > If you use the Fish shell, you can use the following command to set the environment variables: -> ``` +> +> ```console > clever addon env ADDON_ID --format shell | source > ``` @@ -104,14 +105,14 @@ redis-cli -h $KV_HOST -p $KV_PORT --tls Configuration Providers are add-ons that store environment variables you can share across multiple applications through [service dependencies](/doc/cli/services-depedencies/). They have their own dedicated commands: -``` +```console clever config-provider list clever config-provider list --format json ``` To get, set or remove environment variables of a Configuration Provider, use: -``` +```console clever config-provider get CONFIG_PROVIDER_ID_OR_NAME clever config-provider get CONFIG_PROVIDER_ID_OR_NAME --format shell clever config-provider set CONFIG_PROVIDER_ID_OR_NAME VARIABLE_NAME VARIABLE_VALUE @@ -120,14 +121,14 @@ clever config-provider rm CONFIG_PROVIDER_ID_OR_NAME VARIABLE_NAME You can import environment variables from `stdin` (this replaces all existing variables): -``` +```console clever config-provider import CONFIG_PROVIDER_ID_OR_NAME < .env clever config-provider import CONFIG_PROVIDER_ID_OR_NAME --format json < config.json ``` To open the Configuration Provider in Clever Cloud Console, use: -``` +```console clever config-provider open CONFIG_PROVIDER_ID_OR_NAME ``` @@ -138,19 +139,19 @@ clever config-provider open CONFIG_PROVIDER_ID_OR_NAME Databases are backup every day, with last 7 days of backups available to download. You can list them, available formats are: `human` (default) or `json`: -``` +```console clever database backups DATABASE-ID [--format, -F] FORMAT ``` To download one of them, use: -``` +```console clever database backups download [--output, --out] OUTPUT_FILE DATABASE_ID BACKUP_ID ``` This command is still under development and will evolve over time. To get information about backups and download them, you can use our API and `clever curl`. For example: -``` +```console clever curl -X GET https://api.clever-cloud.com/v2/backups// ``` diff --git a/content/doc/cli/applications/_index.md b/content/doc/cli/applications/_index.md index 6edd4b044..6f16b977f 100644 --- a/content/doc/cli/applications/_index.md +++ b/content/doc/cli/applications/_index.md @@ -22,7 +22,7 @@ aliases: You can create a new application on Clever Cloud, linked to your local folder. Only its `type` is required, it should be one of: `docker`, `dotnet`, `elixir`, `frankenphp`, `go`, `gradle`, `haskell`, `jar`, `linux`, `maven`, `meteor`, `node`, `php`, `play1`, `play2`, `python`, `ruby`, `rust`, `sbt`, `static`, `static-apache`, `v` or `war`. Result can be printed in `human` or `json` format. -``` +```console clever create -t TYPE APP_NAME clever create -t TYPE --format json ``` @@ -32,9 +32,9 @@ clever create -t TYPE --format json You can also use one of the following optional parameters: -#### Tasks +### Tasks -``` +```console [--task, -T] COMMAND ``` @@ -47,7 +47,7 @@ You can execute a Task whenever needed through a `clever restart` or modify it a #### GitHub repositories -``` +```console --github owner/repo ``` @@ -57,7 +57,7 @@ If your Clever Cloud account is linked to a GitHub account, you can deploy any o You can ask to deploy your application in a specific organisation/user account, region, with an alias different from its name: -``` +```console [--org, -o, --owner] ID/NAME [--alias, -a] ALIAS [--region, -r] ZONE @@ -84,7 +84,7 @@ Default region is our Paris datacenters (`par`), but it can be: After the application creation, you can ask for a `json` formatted report instead of an `human` sentence: -``` +```console [--format, -F] FORMAT ``` @@ -92,19 +92,19 @@ After the application creation, you can ask for a `json` formatted report instea If an application already exists in your Clever Cloud account, you can link it to any local directory to control it easily. You can even link several applications to a single folder, each one with a different name and/or alias. This is done through the `.clever.json` file. -``` +```console clever link APP_ID_OR_NAME [--alias, -a] ALIAS [--org, -o, --owner] ORG_ID_OR_NAME ``` If multiple applications are linked, you can define one as default with it alias: -``` +```console clever make-default ALIAS ``` To unlink an application: -``` +```console clever unlink ALIAS ``` @@ -112,13 +112,13 @@ clever unlink ALIAS You can list linked applications of a folder, you'll get : ID, alias and deployment URL. -``` +```console clever applications ``` If you only need to get aliases or the result in the JSON format: -``` +```console [--only-aliases] List only application aliases (default: false) [--json, -j] Show result in JSON format (default: false) ``` @@ -127,7 +127,7 @@ If you only need to get aliases or the result in the JSON format: To list all applications across all organisations you have access to, you can use: -``` +```console clever applications list -F json clever applications list --org ORG_ID_OR_NAME ``` @@ -136,7 +136,7 @@ clever applications list --org ORG_ID_OR_NAME To delete an application and unlink it from the current folder you only need to: -``` +```console clever delete clever delete --alias ALIAS clever delete --app APP_ID_OR_NAME diff --git a/content/doc/cli/applications/configuration.md b/content/doc/cli/applications/configuration.md index 5a77adbd5..52300c79b 100644 --- a/content/doc/cli/applications/configuration.md +++ b/content/doc/cli/applications/configuration.md @@ -25,20 +25,20 @@ A Clever Cloud application can easily be configured once created, through follow Each application has options you can get/set: `cancel-on-push`, `description`, `force-https`, `name`, `sticky-sessions`, `task`, `zero-downtime`. -``` +```console clever config get parameter clever config set parameter value ``` To update multiple configuration parameters at a time, use: -``` +```console clever config update FLAGS ``` Available parameters are : -``` +```console [--name] Set name [--description] Set description [--enable-zero-downtime] Enable zero-downtime (default: false) @@ -57,14 +57,14 @@ Available parameters are : Environment variables of Clever Cloud applications can easily be modified: -``` +```console clever env set VARIABLE VALUE clever env rm VARIABLE ``` You can import local environment variables (comma separated) or from a file through `stdin`. If it's a JSON file, each object should be composed of a `name` and a `value`. -``` +```console clever env import-vars VAR_NAME1,VAR_NAME2 clever env import < .env cat .env.json | clever env import --json @@ -72,14 +72,14 @@ cat .env.json | clever env import --json To show or export environment variables of an application, use: -``` +```console clever env clever env > .env ``` You can also export environment variables in a sourceable format (`export ENV_NAME="VALUE";`): -``` +```console clever env --format shell ``` @@ -90,13 +90,13 @@ clever env --format shell By default, a Clever Cloud application gets `app_id.cleverapps.io` as fully qualified domain name ([FQDN](https://fr.wikipedia.org/wiki/Fully_qualified_domain_name)). To see it, use: -``` +```console clever domain ``` To get an overview of domains linked to any of your applications and organisations, use: -``` +```console clever domain overview clever domain overview --filter domain.tld clever domain overview --filter .tld --format json @@ -107,7 +107,7 @@ clever domain overview --filter .tld --format json To add/remove a domain to an application, use: -``` +```console add Add a domain name to a Clever Cloud application rm Remove a domain name from a Clever Cloud application ``` @@ -117,14 +117,14 @@ rm Remove a domain name from a Clever Cloud application To (un)set [the favourite domain](/doc/administrate/domain-names/#primary-favourite-domain-name), use: -``` +```console clever domain favourite set FQDN clever domain favourite unset ``` To check if the domains of an application are properly configured, use: -``` +```console clever domain diag clever domain diag --format json clever domain diag --app APP_ID_OR_NAME @@ -132,7 +132,7 @@ clever domain diag --app APP_ID_OR_NAME You can only diagnose some domains of the application using a text filter: -``` +```console clever domain diag --filter .tld clever domain diag --filter mydomain.tld ``` @@ -144,7 +144,7 @@ clever domain diag --filter mydomain.tld You can easily change the number of instances and `flavor` for an application. It can have a different `flavor` used for build phase, to get it done faster. We also provide horizontal and vertical scaling: you can set a minimal/maximal `flavor` and number of instance, then we autoscale depending on incoming load. To change this, use `clever scale` with the following options: -``` +```console [--flavor] FLAVOR The scale of your application [--min-flavor] MINFLAVOR The minimum scale for your application [--max-flavor] MAXFLAVOR The maximum scale for your application @@ -163,21 +163,21 @@ You can easily change the number of instances and `flavor` for an application. I A Clever Cloud application activate TCP redirections in `default` or `cleverapps` namespace: -``` +```console clever tcp-redirs add --namespace NAMESPACE clever tcp-redirs remove --namespace NAMESPACE PORT ``` To list enabled TCP redirections, use: -``` +```console clever tcp-redirs clever tcp-redirs --format json ``` To list available namespaces, use: -``` +```console clever tcp-redirs list-namespaces ``` diff --git a/content/doc/cli/applications/deployment-lifecycle.md b/content/doc/cli/applications/deployment-lifecycle.md index 998a5c2c7..5fa7ee13e 100644 --- a/content/doc/cli/applications/deployment-lifecycle.md +++ b/content/doc/cli/applications/deployment-lifecycle.md @@ -28,13 +28,13 @@ A Clever Cloud application can easily be deployed and accessed once created, thr Once changes are committed in your local git repository, you can deploy it: -``` +```console clever deploy ``` It will `git push` your code on the remote repository of your application on Clever Cloud automatically. You can, of course, use option to `force push` or use specific local branch for example: -``` +```console [--branch, -b] BRANCH Branch to push (current branch by default) (default: ) [--tag, -t] TAG Tag to push (none by default) (default: ) [--quiet, -q] Don't show logs during deployment (default: false) @@ -50,7 +50,7 @@ It will `git push` your code on the remote repository of your application on Cle Once deployed, you can open the application on your default browser or [Clever Cloud Console](https://console.clever-cloud.com): -``` +```console clever open clever console ``` @@ -59,7 +59,7 @@ clever console To get application state, options or running/scaling status, use: -``` +```console clever status clever status --format json ``` @@ -68,13 +68,13 @@ clever status --format json Once deployed, an application can be restarted: -``` +```console clever restart ``` By default, it will use its build cache when available. But you can override it or use other available options: -``` +```console [--commit] COMMIT ID Restart the application with a specific commit ID [--without-cache] Restart the application without using cache (default: false) [--quiet, -q] Don't show logs during deployment (default: false) @@ -85,7 +85,7 @@ By default, it will use its build cache when available. But you can override it To stop an application or cancel any ongoing deployment, use: -``` +```console clever stop clever cancel-deploy ``` @@ -94,13 +94,13 @@ clever cancel-deploy A Clever Cloud application is a running virtual machine you can ssh to, as a user (`bas`). By default, it will use `OpenSSH` configuration, but you can target a specific identity file: -``` +```console clever ssh [--identity-file, -i] IDENTITY-FILE ``` To ssh a specific application, use: -``` +```console clever ssh --app APP_ID_OR_NAME ``` @@ -108,13 +108,13 @@ clever ssh --app APP_ID_OR_NAME When you deploy an application on Clever Cloud, we collect its logs, hosted in our internal Pulsar stack, all included. To listen to the stream, use: -``` +```console clever logs ``` You can also get logs from a specific timeline, deployment or add-on through options: -``` +```console [--before, --until] BEFORE Fetch logs before this date/time (ISO8601 date, positive number in seconds or duration, e.g.: 1h) [--after, --since] AFTER Fetch logs after this date/time (ISO8601 date, positive number in seconds or duration, e.g.: 1h) [--search] SEARCH Fetch logs matching this pattern @@ -127,16 +127,16 @@ You can also get logs from a specific timeline, deployment or add-on through opt When you deploy an application on Clever Cloud, we collect its access logs, hosted in our internal Pulsar stack, all included. To listen to the stream, use: -``` +```console clever accesslogs ``` > [!TIP] -> This now uses our v4 API, it's available as Alpha feature for now. +> This now uses our v4 API, it's available as Alpha feature for now. You can also get access logs from a specific timeline or add-on through options, in multiple formats: -``` +```console [--before, --until] BEFORE Fetch logs before this date/time (ISO8601 date, positive number in seconds or duration, e.g.: 1h) [--after, --since] AFTER Fetch logs after this date/time (ISO8601 date, positive number in seconds or duration, e.g.: 1h) [--format, -F] FORMAT Output format (human, json, json-stream) (default: human) @@ -144,14 +144,14 @@ You can also get access logs from a specific timeline or add-on through options, You can for example get access logs in JSON stream format for the last hour with: -``` +```console clever accesslogs --format json-stream --since 1h clever accesslogs -F json-stream | jq '.source.ip' ``` or JSON if you add a date/time end limit: -``` +```console clever accesslogs --app APP_NAME --since 2025-04-21T13:37:42 --until 1d -F json | jq '[.[] | {date, countryCode: .source.countryCode, ip: .source.ip, port: .source.port}]' clever accesslogs --app APP_NAME --since 2025-04-21T13:37:42 --until 1d -F json | jq '.[] | [.date, .source.countryCode, .source.ip, .source.port] | @sh' ``` @@ -163,13 +163,13 @@ clever accesslogs --app APP_NAME --since 2025-04-21T13:37:42 --until 1d -F json To get deployment activity, use: -``` +```console clever activity ``` By default, it will show you last 10 deployments. You can show all or listen to a stream of incoming deployments through options: -``` +```console [--follow, -f] Track new deployments in activity list (default: false) [--show-all] Show all activity (default: false) [--format, -F] FORMAT Output format (human, json, json-stream) diff --git a/content/doc/cli/install/_index.md b/content/doc/cli/install/_index.md index 32c2cceb0..f98c66a5f 100644 --- a/content/doc/cli/install/_index.md +++ b/content/doc/cli/install/_index.md @@ -42,7 +42,7 @@ Clever Cloud CLI is based on Node.js. We thought it to be easily available on an If you use Arch Linux, install packages [from AUR](https://aur.archlinux.org/packages/clever-tools-bin/). If you don't know how to use this, run: -``` +```console git clone https://aur.archlinux.org/clever-tools-bin.git clever-tools cd clever-tools makepkg -si @@ -52,7 +52,7 @@ makepkg -si If you use a GNU/Linux distribution that uses `.rpm` packages like CentOS or Fedora, run: -``` +```console curl -s https://clever-tools.clever-cloud.com/repos/cc-nexus-rpm.repo > /etc/yum.repos.d/cc-nexus-rpm.repo yum update yum install clever-tools @@ -65,7 +65,7 @@ yum install clever-tools If you use a GNU/Linux distribution that uses `.deb` packages like Debian or Ubuntu, run: -``` +```console curl -fsSL https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key | gpg --dearmor -o /usr/share/keyrings/cc-nexus-deb.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/cc-nexus-deb.gpg] https://nexus.clever-cloud.com/repository/deb stable main" | tee -a /etc/apt/sources.list apt update @@ -80,7 +80,7 @@ apt install clever-tools If you are using Exherbo, run: -``` +```console cave resolve repository/CleverCloud -zx1 cave resolve clever-tools-bin -zx ``` @@ -89,7 +89,7 @@ cave resolve clever-tools-bin -zx If you use another GNU/Linux distribution, download the `.tar.gz` archive and extract the binary in your `PATH`: -``` +```console curl -O https://clever-tools.clever-cloud.com/releases/latest/clever-tools-latest_linux.tar.gz tar xvzf clever-tools-latest_linux.tar.gz cp clever-tools-latest_linux/clever ~/.local/bin/ @@ -97,7 +97,7 @@ cp clever-tools-latest_linux/clever ~/.local/bin/ > [!TIP] > The packages are available on Clever Cloud's Cellar bucket: [clever-tools-latest_linux.tar.gz](https://clever-tools.clever-cloud.com/releases/latest/clever-tools-latest_linux.tar.gz). \ -> Retrieve any release by replacing `latest` (path and filename) with the version number you need. +> Retrieve any release by replacing `latest` (path and filename) with the version number you need. ## macOS @@ -107,7 +107,7 @@ We only provide macOS packages for Apple Silicon processors. On an Intel Mac, pr If you use macOS and you have [Homebrew](https://brew.sh) installed, run: -``` +```console brew install CleverCloud/homebrew-tap/clever-tools ``` @@ -115,7 +115,7 @@ brew install CleverCloud/homebrew-tap/clever-tools If you use macOS, but you don't have [Homebrew](https://brew.sh) installed, download the `.tar.gz` archive and extract the binary in your `PATH`: -``` +```console curl -O https://clever-tools.clever-cloud.com/releases/latest/clever-tools-latest_macos.tar.gz tar xvzf clever-tools-latest_macos.tar.gz cp clever-tools-latest_macos/clever ~/.local/bin/ @@ -131,7 +131,7 @@ cp clever-tools-latest_macos/clever ~/.local/bin/ If you use Windows run in a terminal: -``` +```console winget install CleverTools ``` @@ -151,9 +151,9 @@ $env:PATH += ";$(Resolve-Path .\clever-tools-latest_win\)" ## Docker -If you are using docker, use the image provided [here](https://hub.docker.com/r/clevercloud/clever-tools/). +If you are using Docker, use the [Clever Tools image from Docker Hub](https://hub.docker.com/r/clevercloud/clever-tools/). -``` +```console docker pull clevercloud/clever-tools docker run --rm clever-tools ``` diff --git a/content/doc/cli/install/nexus-config.md b/content/doc/cli/install/nexus-config.md index 145b48f51..d4c9f7b5a 100644 --- a/content/doc/cli/install/nexus-config.md +++ b/content/doc/cli/install/nexus-config.md @@ -18,17 +18,17 @@ We use a self hosted Nexus repository to distribute `.deb` and `.rpm`. It's avai ### `.deb` repository -We have a repository for `.deb` packages, available [here](https://nexus.clever-cloud.com/#browse/browse:deb). +We provide a [Nexus repository for `.deb` packages](https://nexus.clever-cloud.com/#browse/browse:deb). -* stable: [deb](https://nexus.clever-cloud.com/#browse/browse:deb) +- stable: [deb](https://nexus.clever-cloud.com/#browse/browse:deb) The repository is signed with the PGP key `Clever Cloud Nexus (deb)`. The public key is published on the Cellar at [https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key](https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key). The private key, public key and passphrase are stored in our vault. ### `.rpm` repository -We have a repository for `.rpm` packages, available [here](https://nexus.clever-cloud.com/#browse/browse:rpm). +We provide a [Nexus repository for `.rpm` packages](https://nexus.clever-cloud.com/#browse/browse:rpm). -* Link to Nexus [yum-repositories docs](https://help.sonatype.com/en/yum-repositories.html) +- Link to Nexus [yum-repositories docs](https://help.sonatype.com/en/yum-repositories.html) The repository is not signed, but the `.rpm` packages are. @@ -38,22 +38,22 @@ The repo description is maintained in this git repo at `templates/rpm/cc-nexus-r Steps to follow to generate a new pair of GnuPG keys: -* Prepare a random string for the passphrase (30+ chars is good) -* Run `gpg --gen-key` -* Name: `Clever Cloud Nexus (deb)` -* Email: ci@clever-cloud.com -* Get the ID of the new generated key with `gpg --list-keys` -* Export the public key in a file - * `gpg --armor --output cc-nexus-deb.public.gpg.key --export ` -* Publish the public key on the Cellar - * `s3cmd -c .s3cfg put --acl-public cc-nexus-deb.public.gpg.key s3://clever-tools.clever-cloud.com/gpg/` -* Export the private key in a file - * `gpg --armor --output cc-nexus-deb.private.gpg.key --export-secret-key ` -* Update the private key where it's needed - * The `deb` private key and passphrase need to be set in both `deb` and `deb-stable` repo in Nexus. - * The `rpm` private key and passphrase need to be set in Jenkins. -* Combine both keys into one file - * `cat cc-nexus-deb.*.gpg.key cc-nexus-deb.combined.gpg.key` -* Add the combined key to the vault along with the random passphrase. +- Prepare a random string for the passphrase (30+ chars is good) +- Run `gpg --gen-key` +- Name: `Clever Cloud Nexus (deb)` +- Email: +- Get the ID of the new generated key with `gpg --list-keys` +- Export the public key in a file + - `gpg --armor --output cc-nexus-deb.public.gpg.key --export ` +- Publish the public key on the Cellar + - `s3cmd -c .s3cfg put --acl-public cc-nexus-deb.public.gpg.key s3://clever-tools.clever-cloud.com/gpg/` +- Export the private key in a file + - `gpg --armor --output cc-nexus-deb.private.gpg.key --export-secret-key ` +- Update the private key where it's needed + - The `deb` private key and passphrase need to be set in both `deb` and `deb-stable` repo in Nexus. + - The `rpm` private key and passphrase need to be set in Jenkins. +- Combine both keys into one file + - `cat cc-nexus-deb.*.gpg.key cc-nexus-deb.combined.gpg.key` +- Add the combined key to the vault along with the random passphrase. This is an example for `deb` but the same goes for `rpm`. diff --git a/content/doc/cli/kv-stores.md b/content/doc/cli/kv-stores.md index 8c321433a..8575361d0 100644 --- a/content/doc/cli/kv-stores.md +++ b/content/doc/cli/kv-stores.md @@ -17,7 +17,7 @@ aliases: If you're using [Materia KV](/doc/addons/materia-kv/), our next generation of key-value databases, serverless, distributed, synchronously-replicated, compatible with the Redis® protocol (and later DynamoDB, GraphQL), you can easily create an add-on with Clever Tools: -``` +```console clever addon create kv ADDON_NAME ``` diff --git a/content/doc/cli/logs-drains.md b/content/doc/cli/logs-drains.md index d2107936f..d8a2cd9f9 100644 --- a/content/doc/cli/logs-drains.md +++ b/content/doc/cli/logs-drains.md @@ -17,7 +17,7 @@ aliases: You can use Clever Tools to control logs drains, through following commands. Each can target a specific application, adding `--app APP_ID_OR_NAME` or a local alias (`--alias`, `-a`): -``` +```console clever drain clever drain -F json clever drain create @@ -30,7 +30,7 @@ clever drain disable All drain subcommands also accept `--addon ADDON_ID_OR_REAL_ID` to target an add-on instead of an application. The `--addon` option is mutually exclusive with `--app` and `--alias`. -``` +```console clever drain --addon postgresql_xxxxxxxx clever drain create --addon postgresql_xxxxxxxx raw-http https://logs.example.com clever drain get --addon postgresql_xxxxxxxx @@ -51,7 +51,7 @@ Where `DRAIN-TYPE` is one of: Drain creation supports the following options: -``` +```console [--username, -u] USERNAME Basic auth username (for elasticsearch or raw-http) [--password, -p] PASSWORD Basic auth password (for elasticsearch or raw-http) [--api-key, -k] API_KEY API key (for newrelic) @@ -67,7 +67,7 @@ ElasticSearch drains use the Elastic bulk API. To match this endpoint, specify ` Datadog has two zones, EU and COM. An account on one zone is not available on the other, make sure to target the good EU or COM intake endpoint. To create a [Datadog](https://docs.datadoghq.com/api/?lang=python#send-logs-over-http) drain, you just need to use one of the following command depending on your zone: -``` +```console # EU clever drain create datadog "https://http-intake.logs.datadoghq.eu/v1/input/?ddsource=clevercloud&service=&host=" # US @@ -80,6 +80,6 @@ The `host` query parameter is not mandatory: in the Datadog pipeline configurati NewRelic has two zones, EU and US. An account on one zone is not available on the other, make sure to target the good EU or US intake endpoint. To create a [NewRelic](https://docs.newrelic.com/docs/logs/log-api/introduction-log-api/) drain, you just need to use: -``` +```console clever drain create newrelic "https://log-api.eu.newrelic.com/log/v1" --api-key ``` diff --git a/content/doc/cli/network-groups.md b/content/doc/cli/network-groups.md index ce8a43de2..13f8ff1e0 100644 --- a/content/doc/cli/network-groups.md +++ b/content/doc/cli/network-groups.md @@ -16,9 +16,9 @@ aliases: [Network Groups](/doc/develop/network-groups/) (NG) are a way to create a private secure network between resources inside Clever Cloud infrastructure, using [WireGuard](https://www.wireguard.com/). It's also possible to connect external resources to a Network Group. There are three components to this feature: -* Network Group: a group of resources that can communicate with each through an encrypted tunnel -* Member: a resource that can be part of a Network Group (`application`, `addon` or `external`) -* Peer: Instance of a resource connected to a Network Group (can be `external`) +- Network Group: a group of resources that can communicate with each through an encrypted tunnel +- Member: a resource that can be part of a Network Group (`application`, `addon` or `external`) +- Peer: Instance of a resource connected to a Network Group (can be `external`) A Network Group is defined by an ID (`ngId`) and a `label`. It can be completed by a `description` and `tags`. @@ -42,13 +42,13 @@ When an application connects to a Network Group, you can reach it on any port in Activate `ng` feature flag to manage Network Groups: -``` +```console clever features enable ng ``` Then, check it works with the following command: -``` +```console clever ng ``` @@ -58,19 +58,19 @@ In all the following examples, you can target a specific organisation with the ` A Network Group is simple to create: -``` +```console clever ng create myNG ``` You can create it declaring its members: -``` +```console clever ng create myNG --link app_xxx,postgresql_xxx ``` You can add a description and tags: -``` +```console clever ng create myNG --description "My first NG" --tags test,ng ``` @@ -78,7 +78,7 @@ clever ng create myNG --description "My first NG" --tags test,ng You can delete a Network Group through its ID or label: -``` +```console clever ng delete ngId clever ng delete ngLabel ``` @@ -87,7 +87,7 @@ clever ng delete ngLabel Once created, you can list your Network Groups: -``` +```console clever ng ┌─────────┬───────-┬─────────-─┬───────────────┬─────────┬───────┐ @@ -103,7 +103,7 @@ A `json` formatted output is available with the `--format/-F json` option. To (un)link an application, add-on or external peer to a Network Group: -``` +```console clever ng link app_xxx ngIdOrLabel clever ng unlink redis_xxx ngIdorLabel ``` @@ -118,13 +118,13 @@ After an unlink, you may need to restart the application to apply the changes. To create an external peer in a Network Group, you need to provide a label, Network Group and WireGuard public key: -``` +```console clever ng create external myExternalPeer myNG wg_public_key ``` To delete an external peer from a Network Group: -``` +```console clever ng delete external peerIdOrLabel myNG ``` @@ -132,20 +132,20 @@ clever ng delete external peerIdOrLabel myNG To get information about a Network Group or a resource (a `json` formatted output is available): -``` +```console clever ng get ngIdOrLabel -F json clever ng get resourceIdOrName ``` You can specify the type of resource to look for with the `--type` option (`NetworkGroup`, `Member`, `CleverPeer`, `ExternalPeer`): -``` +```console clever ng get resourceIdOrName --type ExternalPeer ``` You can also search for Network Groups, members or peers: -``` +```console clever ng search text_to_search -F json clever ng search text_to_search --type Member ``` @@ -158,7 +158,7 @@ clever ng search text_to_search --type Member To get the WireGuard configuration of a peer (a `json` formatted output is available): -``` +```console clever ng get-config peerIdOrLabel myNG ``` @@ -166,6 +166,6 @@ clever ng get-config peerIdOrLabel myNG You can find ready to deploy projects using Network Groups in the following repositories: -- https://github.com/CleverCloud/network-groups-example +- Create your own and [let us know](https://github.com/CleverCloud/Community/discussions/categories/network-groups)! diff --git a/content/doc/cli/notifications-webhooks.md b/content/doc/cli/notifications-webhooks.md index 4244b5ca3..04b60fced 100644 --- a/content/doc/cli/notifications-webhooks.md +++ b/content/doc/cli/notifications-webhooks.md @@ -20,7 +20,7 @@ aliases: When events happen on Clever Cloud, during add-ons or applications lifecycle for example, you can send email notifications or trigger webhooks. For each of the following command, you can list all items and/or target a specific user/organisation through these parameters: -``` +```console [--org, -o, --owner] Organisation ID (or name, if unambiguous) [--list-all] List all notifications for your user or for an organisation with the `--org` option (default: false) ``` @@ -29,20 +29,20 @@ When events happen on Clever Cloud, during add-ons or applications lifecycle for You can send email notifications when [an event occurs](/doc/account/notifications/#available-events). To list them, use: -``` +```console clever notify-email clever notify-email --format json ``` To add a notification process to an application, use: -``` +```console clever notify-email add --notify ||"ORGANISATION" NAME ``` Available options are: -``` +```console [--event] TYPE Restrict notifications to specific event types [--service] SERVICE_ID Restrict notifications to specific applications and add-ons --notify ||"ORGANISATION" Notify a user, a specific email address or the whole organisation (multiple values allowed, comma separated) @@ -50,7 +50,7 @@ Available options are: To delete a notification process, use: -``` +```console clever notify-email remove NOTIFICATION-ID ``` @@ -58,19 +58,19 @@ clever notify-email remove NOTIFICATION-ID You can trigger Webhooks when an event occurs. To list them, use: -``` +```console clever webhooks -F json ``` To add a webhook to an application, use: -``` +```console clever webhooks add NAME URL ``` You can set the format, restrict to a service or [event types](/doc/account/notifications/#available-events) through these parameters: -``` +```console [--format] FORMAT Format of the body sent to the webhook ('raw', 'slack', 'gitter', or 'flowdock') (default: raw) [--event] TYPE Restrict notifications to specific event types [--service] SERVICE_ID Restrict notifications to specific applications and add-ons @@ -78,6 +78,6 @@ You can set the format, restrict to a service or [event types](/doc/account/noti To delete a webhook, use: -``` +```console clever webhooks remove NOTIFICATION-ID ``` diff --git a/content/doc/cli/operators.md b/content/doc/cli/operators.md index 7a0f739f6..9f500c480 100644 --- a/content/doc/cli/operators.md +++ b/content/doc/cli/operators.md @@ -15,13 +15,13 @@ keywords: Operators allow you to deploy services as turnkey solutions on Clever Cloud. They provision resources, configure them and expose an API and tools to ease their management during their lifecycle. To add operators commands to Clever Tools, enable the `operators` feature: -``` +```console clever features enable operators ``` Then, you can use the commands to manage Keycloak, Matomo, Metabase and Otoroshi instances on Clever Cloud. For example to list them deployed services: -``` +```console clever keycloak clever matomo clever metabase @@ -30,31 +30,32 @@ clever otoroshi To get information about a deployed service, use: -``` +```console clever keycloak get myKeycloak clever matomo get matomo_id --format json ``` > [!TIP] > You can target a deployed service by its ID or name. +> ## Service management To restart or rebuild (restart without cache) a deployed service, use: -``` +```console clever metabase restart myMetabase clever otoroshi rebuild otoroshi_id ``` To open the deployed service dashboard in Clever Cloud Console, use: -``` +```console clever keycloak open myKeycloak ``` You can also open the service web management interface or logs of the underlying application: -``` +```console clever otoroshi open logs myOtoroshi clever otoroshi open webui otoroshi_id ``` @@ -63,20 +64,20 @@ clever otoroshi open webui otoroshi_id To check the version of a deployed service, use: -``` +```console clever matomo version check matomo_id clever metabase version check myMetabase --format json ``` To update to a specific version, use: -``` +```console clever keycloak version update myKeycloak --target 24.0.1 ``` To see a list of available versions, don't provide a target version: -``` +```console clever otoroshi version update otoroshi_id ``` @@ -84,7 +85,7 @@ clever otoroshi version update otoroshi_id Keycloak and Otoroshi can be easily linked to a [Network Group](/doc/cli/network-groups/). To enable/disable this feature, use: -``` +```console clever keycloak enable-ng myKeycloak clever otoroshi disable-ng otoroshi_id ``` diff --git a/content/doc/cli/profiles.md b/content/doc/cli/profiles.md index 549b22f64..9d1cf5fda 100644 --- a/content/doc/cli/profiles.md +++ b/content/doc/cli/profiles.md @@ -16,6 +16,7 @@ You can use multiple profiles with Clever Tools, all stored in the configuration > [!TIP] > The configuration file lives in your OS config directory: +> > - Windows: `%APPDATA%\clever-cloud\clever-tools.json` > - Other systems: XDG config directory (typically `~/.config/clever-cloud/clever-tools.json`) diff --git a/content/doc/cli/services-depedencies.md b/content/doc/cli/services-depedencies.md index 5cc783455..e6f94822a 100644 --- a/content/doc/cli/services-depedencies.md +++ b/content/doc/cli/services-depedencies.md @@ -20,7 +20,7 @@ Each can target a specific application, adding `--app APP_ID_OR_NAME` or a local To list exposed configuration, use: -``` +```console clever published-config clever published-config -F json clever published-config --format shell @@ -28,13 +28,13 @@ clever published-config --format shell To configure exposed configuration, use: -``` +```console clever published-config COMMAND ``` Available commands are `set`, `rm` (remove) or `import`. The latter reads data from `stdin` so use it as is: -``` +```console clever published-config import < file.config ``` @@ -42,14 +42,14 @@ clever published-config import < file.config To list services dependencies, use: -``` +```console clever service clever service --format json ``` You can filter results through these options. -``` +```console [--only-apps] Only show app dependencies (default: false) [--only-addons] Only show add-on dependencies (default: false) [--show-all] Show all available add-ons and applications (default: false) @@ -57,14 +57,14 @@ You can filter results through these options. To create or delete services dependencies, use: -``` +```console clever service COMMAND ADDON_OR_APP_ID clever service COMMAND ADDON_OR_APP_NAME ``` Available commands are: -``` +```console link-app Add an existing app as a dependency unlink-app Remove an app from the dependencies link-addon Link an existing add-on to this application diff --git a/content/doc/develop/env-variables.md b/content/doc/develop/env-variables.md index e799ee5f5..7080fe99d 100644 --- a/content/doc/develop/env-variables.md +++ b/content/doc/develop/env-variables.md @@ -21,14 +21,14 @@ injected in your application's environment. Variables are defined on a per-application basis. They are defined in four ways: -* By provisioned add-ons linked to applications. The variables names +- By provisioned add-ons linked to applications. The variables names are listed in the add-on's information panel. -* By linked applications with exposed configuration. +- By linked applications with exposed configuration. -* By adding variables yourself in the "Environment variables" panel of your application. +- By adding variables yourself in the "Environment variables" panel of your application. -* Some environment variables are added automatically for each application. +- Some environment variables are added automatically for each application. Please note that if you define or modify environment variables, you will need to redeploy your application to make it use the new variables. @@ -42,28 +42,26 @@ to inform you about the current context of your application and about the applic They can be accessed as classic environment variables. -* `APP_ID`: the ID of the application. Each application has a unique identifier used to +- `APP_ID`: the ID of the application. Each application has a unique identifier used to identify it in our system. This ID is the same than the one you can find in the information section of your application. -* `INSTANCE_ID`: the ID of the current instance (scaler) of your application. It's unique for each +- `INSTANCE_ID`: the ID of the current instance (scaler) of your application. It's unique for each instance of your application and changes every time you deploy it. -* `INSTANCE_TYPE`: The type of the instance (scaler). Its value can be `build` or `production`. +- `INSTANCE_TYPE`: The type of the instance (scaler). Its value can be `build` or `production`. `build` is when your application is being built on a dedicated instance. -* `COMMIT_ID`: the commit ID used as a base to deploy your application. As we remove +- `COMMIT_ID`: the commit ID used as a base to deploy your application. As we remove the `.git` directory before the deployment (to avoid security problems), it can be used to know which version of your application is running on the server. -* `APP_HOME`: The absolute path of your application on the server. Can be used to +- `APP_HOME`: The absolute path of your application on the server. Can be used to create absolute links in your application (e.g. `${APP_HOME}/foo/bar`). -* `CC_PRETTY_INSTANCE_NAME`: A random string name generated for each instance using pokemon names. +- `CC_PRETTY_INSTANCE_NAME`: A random string name generated for each instance using pokemon names. -* `INSTANCE_NUMBER`: See below - -[dedicated-instance]: /developers/doc/administrate/apps-management#edit-application-configuration +- `INSTANCE_NUMBER`: See below ### What is the `INSTANCE_NUMBER` variable used for? @@ -79,14 +77,14 @@ It's handy if you want to only run crons on 1 instance (e.g. only on instance 0) We use environment variables for some settings: -* `CC_DISABLE_BUILD_CACHE_UPLOAD`: allows you to ask that the cache archive is neither +- `CC_DISABLE_BUILD_CACHE_UPLOAD`: allows you to ask that the cache archive is neither created nor uploaded after the build process. Thus, restarts won't be speeded up, as the build process will be launched each time. -* `IGNORE_FROM_BUILDCACHE`: allows you to specify paths to ignore when the build +- `IGNORE_FROM_BUILDCACHE`: allows you to specify paths to ignore when the build cache archive is created. Must be relative to your application root. (e.g. `foo/bar:foo/baz` where `bar` or `baz` can be either a directory or a file) -* `CC_OVERRIDE_BUILDCACHE`: allows you to specify paths that will be in the build cache. +- `CC_OVERRIDE_BUILDCACHE`: allows you to specify paths that will be in the build cache. Only those files/directories will be cached (e.g. `foo/bar:foo/baz` where `bar` or `baz` can be either a directory or a file). @@ -97,24 +95,24 @@ examples of the formats available on our different modes. ### Rules -* Letters (ASCII only, upper and lower case) - * Valid: `user_id`, `USER_ID`, `UsERId`, `userid`, `USERID` - * Invalid: `user_id?`, `?userid`, `user.id`, `user id` -* Digits (but not for first character) - * Valid: `user2id`, `userid42` - * Invalid: `2userid`, `1user_Id` -* Underscores - * Valid: `user_id`, `all_user_id`, `_user_id`, `_user_id__` -* Everything else is not allowed +- Letters (ASCII only, upper and lower case) + - Valid: `user_id`, `USER_ID`, `UsERId`, `userid`, `USERID` + - Invalid: `user_id?`, `?userid`, `user.id`, `user id` +- Digits (but not for first character) + - Valid: `user2id`, `userid42` + - Invalid: `2userid`, `1user_Id` +- Underscores + - Valid: `user_id`, `all_user_id`, `_user_id`, `_user_id__` +- Everything else is not allowed #### Java properties rules exception In case of a Java application you can also use: -* Dashes - * Valid: `spring-boot`, `spring-boot-database`, `--spring-boot`, `--spring` -* Dots - * Valid: `spring.boot`, `spring.datasource.url`, `.spring.url` +- Dashes + - Valid: `spring-boot`, `spring-boot-database`, `--spring-boot`, `--spring` +- Dots + - Valid: `spring.boot`, `spring.datasource.url`, `.spring.url` ### Format @@ -127,7 +125,7 @@ The format of an expert variable is `VAR_NAME="VAR_VALUE"`. Here are some examples: -* Multiple variables examples: +- Multiple variables examples: ```bash EMPTY="" @@ -138,7 +136,7 @@ Here are some examples: TWO="value TWO" ``` -* Multiline: +- Multiline: ```bash MULTI="line one @@ -146,7 +144,7 @@ Here are some examples: line three" ``` -* Empty value: +- Empty value: ```bash EMPTY="" @@ -160,7 +158,7 @@ Note: You must put these variables in an array (see the multiple variable exampl Here are some examples: -* Multiline: +- Multiline: ```json { @@ -169,7 +167,7 @@ Here are some examples: } ``` -* Empty value: +- Empty value: ```json { @@ -178,7 +176,7 @@ Here are some examples: } ``` -* Multiple variables examples: +- Multiple variables examples: ```json [ @@ -208,19 +206,19 @@ You can find more information in the documentation pages related to your applica Here is a non-exhaustive summary: -| Language | Usage | -|----------|-------| -| Go | `os.Getenv("MY_VAR")`| -| Haskell | `Os.Getenv["MY_VAR"]` | -| Node.js | `process.env["MY_VAR"]`| -| Java WAR | `System.getProperties().getProperty("MY_VAR")` | -| PHP | `getenv("MY_VAR")` | +| Language | Usage | +| ------------------------------------- | -------------------------------------------------------------- | +| Go | `os.Getenv("MY_VAR")` | +| Haskell | `Os.Getenv["MY_VAR"]` | +| Node.js | `process.env["MY_VAR"]` | +| Java WAR | `System.getProperties().getProperty("MY_VAR")` | +| PHP | `getenv("MY_VAR")` | | Play! Framework 1 & Play! Framework 2 | `System.getenv("MY_VAR")` or `${MY_VAR}` in `application.conf` | -| Python | `os.getenv("MY_VAR")` | -| Ruby | `ENV["MY_VAR"]` | -| Rust | `std::env::var("MY_VAR")` | -| Scala | `System.getenv("MY_VAR")` | -| .NET | `System.Environment.GetEnvironmentVariable("MY_VAR")` | +| Python | `os.getenv("MY_VAR")` | +| Ruby | `ENV["MY_VAR"]` | +| Rust | `std::env::var("MY_VAR")` | +| Scala | `System.getenv("MY_VAR")` | +| .NET | `System.Environment.GetEnvironmentVariable("MY_VAR")` | ## Specific languages diff --git a/content/doc/develop/network-groups.md b/content/doc/develop/network-groups.md index 501b44584..576d170f4 100644 --- a/content/doc/develop/network-groups.md +++ b/content/doc/develop/network-groups.md @@ -15,9 +15,9 @@ aliases: Network Groups (NG) are a way to create a private secure network between resources inside Clever Cloud infrastructure, using [WireGuard](https://www.wireguard.com/). It's also possible to connect external resources to a Network Group. There are three components to this feature: -* Network Group: a group of resources that can communicate with each through an encrypted tunnel -* Member: a resource that can be part of a Network Group (`application`, `addon` or `external`) -* Peer: Instance of a resource connected to a Network Group (can be `external`) +- Network Group: a group of resources that can communicate with each through an encrypted tunnel +- Member: a resource that can be part of a Network Group (`application`, `addon` or `external`) +- Peer: Instance of a resource connected to a Network Group (can be `external`) A Network Group is defined by an ID (`ngId`) and a `label`. It can be completed by a `description` and `tags`. @@ -77,6 +77,7 @@ flowchart TD ## Concepts ### Network Group + Network Groups operate as an overlay network, on top of the existing physical network infrastructure (underlay). When two peers communicate within a Network Group, packets are encapsulated in WireGuard tunnels that traverse Clever Cloud's underlay network. This approach enables the creation of flexible virtual network topologies without modifying the underlying physical infrastructure. Thanks to this overlay architecture, you can establish private and secure communications between your resources, even if they are physically dispersed across different zones of Clever Cloud's infrastructure or outside of it. @@ -84,19 +85,25 @@ This approach enables the creation of flexible virtual network topologies withou Each Network Group has a unique ID (ngId), a human-readable label, and can include an optional description and tags for organisation. ### Members + Resources connected to a Network Group can be applications or add-ons running on Clever Cloud (databases, services, etc.), or external resources outside of Clever Cloud (a third-party server, your local machine). Each member is accessible via a domain name. ### Peers + Individual instances of a member resource. For example, if your application scales to three instances, each instance becomes a peer in the Network Group with its own IP address from the assigned CIDR range. ## Key Benefits + Network Groups offer secure communication with all traffic between resources encrypted using WireGuard. You gain DNS resolution to access resources by domain name within the Network Group, along with internal port access to reach any port on any resource inside the Network Group. This creates a simplified architecture where you can connect applications and their dependencies in a private network. ## Use Cases + Network Groups excel in microservices architecture by connecting multiple services securely without exposing them to the public internet. They simplify database access by allowing applications to access database add-ons through a secure channel. For legacy integration, they help connect external systems securely to your cloud applications. They also provide isolated environments for development and testing. ## Technical Implementation + Network Groups leverage WireGuard, a modern VPN protocol known for its simplicity, speed, and security. When you create a Network Group, a dedicated CIDR range is allocated for your Network Group and WireGuard configurations are generated. When members join, they're assigned DNS names and IPs from the CIDR range, encrypted tunnels are established between peers, and traffic between resources flows through these secure tunnels. ## Best Practices + Create Network Groups based on functional requirements or environments such as production or staging. Use clear, consistent naming for Network Groups and tag them appropriately. Establish different Network Groups to separate security domains, and keep track of which resources belong to which Network Groups. diff --git a/content/doc/develop/oauth2-proxy.md b/content/doc/develop/oauth2-proxy.md index a7f29c82f..f6f555971 100644 --- a/content/doc/develop/oauth2-proxy.md +++ b/content/doc/develop/oauth2-proxy.md @@ -142,12 +142,12 @@ OAUTH2_PROXY_REDIS_CONNECTION_URL="redis://:password@host:port" OAuth2 Proxy logs its configuration errors and exits, so read the deployment logs from the bottom up. The health check reports the public port as closed, which is a consequence of the middleware being down rather than a problem with your application: -| Log message | Cause | -| ----------- | ----- | -| `cookie_secret must be 16, 24, or 32 bytes` | The secret has the wrong length, see [Generate the cookie secret](#generate-the-cookie-secret) | -| `missing setting for email validation` | The configuration carries neither `OAUTH2_PROXY_EMAIL_DOMAINS` nor `OAUTH2_PROXY_AUTHENTICATED_EMAILS_FILE` | -| `Your application is not listening on 8080` | OAuth2 Proxy failed to start, the preceding message holds the reason | -| `Some software are not listening as expected: 9000` | OAuth2 Proxy runs, your application doesn't listen on port `9000` | +| Log message | Cause | +| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `cookie_secret must be 16, 24, or 32 bytes` | The secret has the wrong length, see [Generate the cookie secret](#generate-the-cookie-secret) | +| `missing setting for email validation` | The configuration carries neither `OAUTH2_PROXY_EMAIL_DOMAINS` nor `OAUTH2_PROXY_AUTHENTICATED_EMAILS_FILE` | +| `Your application is not listening on 8080` | OAuth2 Proxy failed to start, the preceding message holds the reason | +| `Some software are not listening as expected: 9000` | OAuth2 Proxy runs, your application doesn't listen on port `9000` | A login that loops between your application and the identity provider points to `OAUTH2_PROXY_REDIRECT_URL` not matching the callback declared in the provider. A `403 Forbidden` after a successful login points to an email address outside your authorization rules, or to a missing `email` scope. diff --git a/content/doc/develop/request-flow.md b/content/doc/develop/request-flow.md index 8d8c293f5..284f29d9d 100644 --- a/content/doc/develop/request-flow.md +++ b/content/doc/develop/request-flow.md @@ -24,14 +24,14 @@ Request Flow is available for all runtimes except Docker, where you define and m ## Supported services -| Service | Activation | Description | -| ------- | ---------- | ----------- | -| `block` | `CC_REQUEST_FLOW="block"` | Blocks public access with a `200 OK` response. Other ports remain accessible through [Network Groups](/doc/develop/network-groups/) | -| `custom` | `CC_REQUEST_FLOW="custom"` | Any custom reverse proxy, started with `CC_REQUEST_FLOW_CUSTOM` | -| `oauth2-proxy` | `CC_REQUEST_FLOW="oauth2-proxy"` | Authentication proxy using [OAuth2 Proxy](/doc/develop/oauth2-proxy/) | -| `otoroshi-challenge` | `OTOROSHI_CHALLENGE_SECRET` | [Otoroshi](/doc/addons/otoroshi/) challenge verification proxy | -| `redirectionio` | `CC_REDIRECTIONIO_PROJECT_KEY` | HTTP redirects, rewrites, SEO | -| `varnish` | `clevercloud/varnish.vcl` file or `CC_VARNISH_FILE` | HTTP cache accelerator | +| Service | Activation | Description | +| -------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| `block` | `CC_REQUEST_FLOW="block"` | Blocks public access with a `200 OK` response. Other ports remain accessible through [Network Groups](/doc/develop/network-groups/) | +| `custom` | `CC_REQUEST_FLOW="custom"` | Any custom reverse proxy, started with `CC_REQUEST_FLOW_CUSTOM` | +| `oauth2-proxy` | `CC_REQUEST_FLOW="oauth2-proxy"` | Authentication proxy using [OAuth2 Proxy](/doc/develop/oauth2-proxy/) | +| `otoroshi-challenge` | `OTOROSHI_CHALLENGE_SECRET` | [Otoroshi](/doc/addons/otoroshi/) challenge verification proxy | +| `redirectionio` | `CC_REDIRECTIONIO_PROJECT_KEY` | HTTP redirects, rewrites, SEO | +| `varnish` | `clevercloud/varnish.vcl` file or `CC_VARNISH_FILE` | HTTP cache accelerator | ## Automatic detection @@ -111,13 +111,13 @@ For an application that manages its own HTTP server, this example produces the f ## Environment variables reference -| Name | Description | -| ---- | ----------- | -| `CC_REQUEST_FLOW` | Comma-separated list of middleware to chain (e.g. `varnish,redirectionio`). Special values: `disable`, `block` | -| `CC_REQUEST_FLOW_CUSTOM` | Command to start a custom middleware. Must contain `@@LISTEN_PORT@@` and `@@FORWARD_PORT@@` placeholders | -| `CC_REDIRECTIONIO_PROJECT_KEY` | Redirection.io project key. Activates Redirection.io in the request flow | -| `CC_VARNISH_FILE` | Path to a custom Varnish VCL file (default: `clevercloud/varnish.vcl`) | -| `OTOROSHI_CHALLENGE_SECRET` | Otoroshi challenge secret. Activates Otoroshi Challenge verification in the request flow | +| Name | Description | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------- | +| `CC_REQUEST_FLOW` | Comma-separated list of middleware to chain (e.g. `varnish,redirectionio`). Special values: `disable`, `block` | +| `CC_REQUEST_FLOW_CUSTOM` | Command to start a custom middleware. Must contain `@@LISTEN_PORT@@` and `@@FORWARD_PORT@@` placeholders | +| `CC_REDIRECTIONIO_PROJECT_KEY` | Redirection.io project key. Activates Redirection.io in the request flow | +| `CC_VARNISH_FILE` | Path to a custom Varnish VCL file (default: `clevercloud/varnish.vcl`) | +| `OTOROSHI_CHALLENGE_SECRET` | Otoroshi challenge secret. Activates Otoroshi Challenge verification in the request flow | ## Troubleshooting diff --git a/content/doc/develop/tasks.md b/content/doc/develop/tasks.md index 3713a6af4..a76b831e6 100644 --- a/content/doc/develop/tasks.md +++ b/content/doc/develop/tasks.md @@ -21,6 +21,7 @@ This will guide you in the process of creating a Clever Task: an application tha ### With the Clever Tools CLI Make sure you have [Clever Tools installed](/doc/cli/) and in your project folder, run `clever create --type --task `. You can also add options such as ` --region --org ` where: + 1. `app-name` the name you want for your application, 2. `zone` deployment zone (`par` for Paris or `mtl` for Montreal for example) 3. `org` the organisation ID the application will be created under diff --git a/content/doc/find-help/faq.md b/content/doc/find-help/faq.md index d8faa9391..2a6a19594 100644 --- a/content/doc/find-help/faq.md +++ b/content/doc/find-help/faq.md @@ -27,28 +27,30 @@ When enabling auto-scalability, you have to set a minimum and a maximum of activ {{< /callout >}} ## Which application runtimes are supported by Clever Cloud? + Currently, Clever Cloud supports: -* .NET -* Docker -* Elixir -* Go -* Haskell -* Java (Jar, Maven, Gradle, War/Ear, Play Framework 1 & 2) and Groovy with Gradle -* Linux -* Meteor.js -* Node.js & Bun -* PHP and FrankenPHP -* Python -* Ruby -* Rust -* Scala (SBT, Play Framework 1 & 2) -* Static sites (with or without Apache) -* V (Vlang) +- .NET +- Docker +- Elixir +- Go +- Haskell +- Java (Jar, Maven, Gradle, War/Ear, Play Framework 1 & 2) and Groovy with Gradle +- Linux +- Meteor.js +- Node.js & Bun +- PHP and FrankenPHP +- Python +- Ruby +- Rust +- Scala (SBT, Play Framework 1 & 2) +- Static sites (with or without Apache) +- V (Vlang) See the full list in the [applications documentation](/doc/applications/), or browse the [guides](/guides/) for frameworks and services you can deploy on Clever Cloud. ## How many applications can I create? + As many as you want. We've not set a limited number of apps by developer. ## How to setup domain names I own? @@ -219,7 +221,6 @@ Clever Cloud stores all backups on [Cellar](https://www.clever.cloud/product/cel For custom configurations (for example, multiple retention policies), contact Support. To locate backups not visible in the Console, use [Clever Tools](https://github.com/CleverCloud/clever-tools) with: `clever database backups DATABASE-ID [--format, -F] FORMAT`. Find more [documentation on restoring backups with the CLI](/doc/cli/addons/#database-backups). - ## I can't create my add-on To create add-ons, you need to complete your account information, including your city and ZIP code. diff --git a/content/doc/find-help/support.md b/content/doc/find-help/support.md index 7ed2dafc6..54409b27d 100644 --- a/content/doc/find-help/support.md +++ b/content/doc/find-help/support.md @@ -23,7 +23,7 @@ We provide basic support free-of-charge to all our users, even those who are not Seek help by querying us by email, allowing you to quickly gain answers to your Clever Cloud specific questions and open a ticket directly with our support staff. We will respond to your email within a few hours, or two business days in the worst case. -* +- ## Ticket Center @@ -39,4 +39,4 @@ Clever Cloud offers a premium support option providing 24/7 a direct line to our Get more information and contact our sales team at: -* +- diff --git a/content/doc/find-help/troubleshooting.md b/content/doc/find-help/troubleshooting.md index 8ceaf458b..7dc8019d5 100644 --- a/content/doc/find-help/troubleshooting.md +++ b/content/doc/find-help/troubleshooting.md @@ -134,9 +134,10 @@ You are not allowed to create apps and add-ons, and run your current apps. {{% details title="Possible reasons why your app has been moderated" closed="true" %}} The main reasons why your account has been moderated are: + - You run some forbidden apps such as those described on [this page](https://www.clever.cloud/acceptable-use-policy/) - You have not paid your pending invoices older than 30 days -- Clever Cloud system considers the lack of personal information or missing payment information as suspicious +- Clever Cloud system considers the lack of personal information or missing payment information as suspicious - Our payment platform has spotted you as emitting fraudulent payments. {{% /details %}} @@ -169,16 +170,17 @@ For operations that may exceed the 180-second limit, implement one of these appr 2. Create an asynchronous worker system: move long-running tasks to a background [worker](/doc/develop/workers/) 3. [Purchase a custom load balancer from Clever Cloud](https://www.clever.cloud/fr/contact/) with different timeouts -##### Additional considerations: +### Additional considerations - Design your application architecture to handle timeouts gracefully - Break up long-running operations into smaller tasks Use your embedded [Grafana](/doc/metrics/) to monitor resource usage when implementing any of these solutions. -##### How can I diagnosing Network Issue with `curl` +### Diagnose network issues with `curl` To gather detailed timing information for each step of the connection process, run the following `curl` command: + ``` bash curl -o /dev/null -s -w "DNS resolution: %{time_namelookup}s\nTCP connection: %{time_connect}s\nTLS handshake: %{time_appconnect}s\nTime to first byte: %{time_starttransfer}s\nTotal time: %{time_total}s\n" https:// ``` diff --git a/content/doc/functions/_index.md b/content/doc/functions/_index.md index b918478a7..af7f9a471 100644 --- a/content/doc/functions/_index.md +++ b/content/doc/functions/_index.md @@ -102,6 +102,7 @@ sequenceDiagram ## Prerequisites To use Clever Functions you'll need : + - An authorized access for your organisation - Clever Tools with Functions commands @@ -152,6 +153,7 @@ clever functions deploy --org ?trigger=http ``` diff --git a/content/doc/kubernetes/_index.md b/content/doc/kubernetes/_index.md index a4e44ee99..3520f359b 100644 --- a/content/doc/kubernetes/_index.md +++ b/content/doc/kubernetes/_index.md @@ -89,11 +89,11 @@ A Kubernetes cluster on Clever Cloud is made of a control plane and one or more You choose how the control plane is distributed at creation time. The topology decides the placement of the Kubernetes components, the available flavors, whether workloads share the same VMs as the control plane, and ultimately what gets billed. Three layouts are available: -|Topology|Customers|VMs you pay for|Flavors|Default node group included?|Typical use case| -|---|---|---|---|---|---| -|`ALL_IN_ONE`|Essential|`replicationFactor` × bundle VM (control plane + integrated worker node). Additional node groups billed separately|`S`, `M`, `L`, `XL`|No node group, but each bundle VM is also a worker node — additional node groups optional|Development, testing, small single-team clusters| -|`DEDICATED_COMPUTE`|Business|`replicationFactor` × control plane VM **plus** every worker VM in your node groups|`XS`, `S`, `M`, `L`, `XL`|No — provision a node group at creation with `--nodegroup` or later|Production clusters where control plane and workloads stay isolated| -|`DISTRIBUTED`|Enterprise|For each of 5 components: `replicationFactor` × component VM **plus** every worker VM in your node groups|`2XS`, `XS`, `S`, `M`, `L`, `XL`|No — provision a node group at creation or later|Demanding production clusters needing fine-grained HA per control plane component| +| Topology | Customers | VMs you pay for | Flavors | Default node group included? | Typical use case | +| ------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | +| `ALL_IN_ONE` | Essential | `replicationFactor` × bundle VM (control plane + integrated worker node). Additional node groups billed separately | `S`, `M`, `L`, `XL` | No node group, but each bundle VM is also a worker node — additional node groups optional | Development, testing, small single-team clusters | +| `DEDICATED_COMPUTE` | Business | `replicationFactor` × control plane VM **plus** every worker VM in your node groups | `XS`, `S`, `M`, `L`, `XL` | No — provision a node group at creation with `--nodegroup` or later | Production clusters where control plane and workloads stay isolated | +| `DISTRIBUTED` | Enterprise | For each of 5 components: `replicationFactor` × component VM **plus** every worker VM in your node groups | `2XS`, `XS`, `S`, `M`, `L`, `XL` | No — provision a node group at creation or later | Demanding production clusters needing fine-grained HA per control plane component | `ALL_IN_ONE` is the default when no topology is specified at cluster creation through Clever Tools or the Console. A replication factor (`1` to `5`) applies to the control plane VMs: the higher the factor, the more resilient the control plane and, in `DEDICATED_COMPUTE` or `DISTRIBUTED`, the more sites it is spread across (up to three Parisian datacenters). In `DISTRIBUTED`, each of the five components has its own flavor and its own replication factor, letting you scale a busy `apiserver` higher than a quieter `scheduler`. @@ -260,7 +260,7 @@ clever k8s nodegroups delete myCluster workers Define a `NodeGroup` resource in a YAML file and apply it: -```yaml{filename="example-nodegroup.yaml"} +```yaml {filename="example-nodegroup.yaml"} apiVersion: api.clever-cloud.com/v1 kind: NodeGroup metadata: @@ -357,7 +357,7 @@ kubectl create secret docker-registry dockerhub-creds \ Reference the secret from your Pod spec via `imagePullSecrets`: -```yaml{filename="deployment-private.yaml"} +```yaml {filename="deployment-private.yaml"} apiVersion: apps/v1 kind: Deployment metadata: @@ -401,7 +401,7 @@ kubectl expose deployment/nginx --type=LoadBalancer --port 80 Alternatively, you can create a YAML file named `deployment-demo.yaml` with the following content and apply it using `kubectl apply -f deployment-demo.yaml`: -```yaml{filename="deployment-demo.yaml"} +```yaml {filename="deployment-demo.yaml"} apiVersion: apps/v1 kind: Deployment metadata: @@ -463,37 +463,37 @@ In practice: The bundle hosts the five control plane components and an integrated worker node on the same VMs. The price below covers everything; additional node groups attached to an `ALL_IN_ONE` cluster are billed separately at the [node group rate](#node-groups-workers). -|Flavor|Resources|Hourly price|Monthly price| -|---|---|---|---| -|S|8 vCPU / 12 GB|0.0889 €|64.00 €| -|M|10 vCPU / 16 GB|0.1167 €|84.00 €| -|L|12 vCPU / 24 GB|0.1667 €|120.00 €| -|XL|16 vCPU / 32 GB|0.2222 €|160.00 €| +| Flavor | Resources | Hourly price | Monthly price | +| ------ | --------------- | ------------ | ------------- | +| S | 8 vCPU / 12 GB | 0.0889 € | 64.00 € | +| M | 10 vCPU / 16 GB | 0.1167 € | 84.00 € | +| L | 12 vCPU / 24 GB | 0.1667 € | 120.00 € | +| XL | 16 vCPU / 32 GB | 0.2222 € | 160.00 € | ### Business (`DEDICATED_COMPUTE`) control plane One VM per replication factor, dedicated to the control plane. -|Flavor|Resources|Hourly price|Monthly price| -|---|---|---|---| -|XS|6 vCPU / 8 GB|0.0917 €|66.00 €| -|S|8 vCPU / 12 GB|0.1333 €|96.00 €| -|M|10 vCPU / 16 GB|0.1750 €|126.00 €| -|L|12 vCPU / 24 GB|0.2500 €|180.00 €| -|XL|16 vCPU / 32 GB|0.3333 €|240.00 €| +| Flavor | Resources | Hourly price | Monthly price | +| ------ | --------------- | ------------ | ------------- | +| XS | 6 vCPU / 8 GB | 0.0917 € | 66.00 € | +| S | 8 vCPU / 12 GB | 0.1333 € | 96.00 € | +| M | 10 vCPU / 16 GB | 0.1750 € | 126.00 € | +| L | 12 vCPU / 24 GB | 0.2500 € | 180.00 € | +| XL | 16 vCPU / 32 GB | 0.3333 € | 240.00 € | ### Enterprise (`DISTRIBUTED`) control plane For each of the five components (`apiserver`, `controller-manager`, `scheduler`, `cloud-controller-manager`, `node-group-operator`), pay `replicationFactor` × the per-VM price below. Each component picks its own flavor and replication factor. -|Flavor|Resources|Hourly price|Monthly price per component| -|---|---|---|---| -|2XS|4 vCPU / 4 GB|0.0500 €|36.00 €| -|XS|6 vCPU / 8 GB|0.0917 €|66.00 €| -|S|8 vCPU / 12 GB|0.1333 €|96.00 €| -|M|10 vCPU / 16 GB|0.1750 €|126.00 €| -|L|12 vCPU / 24 GB|0.2500 €|180.00 €| -|XL|16 vCPU / 32 GB|0.3333 €|240.00 €| +| Flavor | Resources | Hourly price | Monthly price per component | +| ------ | --------------- | ------------ | --------------------------- | +| 2XS | 4 vCPU / 4 GB | 0.0500 € | 36.00 € | +| XS | 6 vCPU / 8 GB | 0.0917 € | 66.00 € | +| S | 8 vCPU / 12 GB | 0.1333 € | 96.00 € | +| M | 10 vCPU / 16 GB | 0.1750 € | 126.00 € | +| L | 12 vCPU / 24 GB | 0.2500 € | 180.00 € | +| XL | 16 vCPU / 32 GB | 0.3333 € | 240.00 € | The price above is **per component VM** (one of the five) at `replicationFactor = 1`. A minimal Distributed cluster with all five components in 2XS at rf=1 therefore costs `5 × 36.00 € = 180.00 €/month` for the control plane alone, plus the [node group rate](#node-groups-workers) for your workers. @@ -501,14 +501,14 @@ The price above is **per component VM** (one of the five) at `replicationFactor Worker VMs in node groups attached to any cluster. An `ALL_IN_ONE` cluster ships with one worker node integrated in each bundle VM (no extra rate); any **additional** node group you attach to an `ALL_IN_ONE` cluster is billed at the rate below, like for `DEDICATED_COMPUTE` and `DISTRIBUTED`. -|Flavor|Resources|Hourly price|Monthly price| -|---|---|---|---| -|2XS|4 vCPU / 4 GB|0.0333 €|24.00 €| -|XS|6 vCPU / 8 GB|0.0611 €|44.00 €| -|S|8 vCPU / 12 GB|0.0889 €|64.00 €| -|M|10 vCPU / 16 GB|0.1167 €|84.00 €| -|L|12 vCPU / 24 GB|0.1667 €|120.00 €| -|XL|16 vCPU / 32 GB|0.2222 €|160.00 €| +| Flavor | Resources | Hourly price | Monthly price | +| ------ | --------------- | ------------ | ------------- | +| 2XS | 4 vCPU / 4 GB | 0.0333 € | 24.00 € | +| XS | 6 vCPU / 8 GB | 0.0611 € | 44.00 € | +| S | 8 vCPU / 12 GB | 0.0889 € | 64.00 € | +| M | 10 vCPU / 16 GB | 0.1167 € | 84.00 € | +| L | 12 vCPU / 24 GB | 0.1667 € | 120.00 € | +| XL | 16 vCPU / 32 GB | 0.2222 € | 160.00 € | ## Clever Kubernetes Operator diff --git a/content/doc/kubernetes/operator.md b/content/doc/kubernetes/operator.md index 39cbc95c7..da1a35460 100644 --- a/content/doc/kubernetes/operator.md +++ b/content/doc/kubernetes/operator.md @@ -18,7 +18,7 @@ The [Clever Kubernetes Operator](https://github.com/CleverCloud/clever-kubernete Modern applications often require a combination of containerized workloads and managed services, such as databases or caches. Managing these resources separately across platforms can become complex and error-prone. The Clever Kubernetes Operator simplifies this process by acting as a bridge, allowing developers to define and interact with Clever Cloud's resources using familiar Kubernetes paradigms. -### Why Use the Clever Kubernetes Operator? +## Why Use the Clever Kubernetes Operator? The Clever Kubernetes Operator was born from a concrete need: to allow users to manage Clever Cloud services directly from a Kubernetes cluster. It reconciles the best of both worlds: @@ -27,7 +27,7 @@ The Clever Kubernetes Operator was born from a concrete need: to allow users to While Kubernetes excels at deploying applications, databases come with operational constraints (backup, replication, restoration, updates…) that make self-management challenging. With the operator, you can maintain the comfort of a managed service while keeping control in your Kubernetes manifests. -### Supported Services +## Supported Services Originally designed for managed databases, the Clever Kubernetes Operator has expanded to support a wide range of Clever Cloud services as native Kubernetes Custom Resources: @@ -52,7 +52,7 @@ Originally designed for managed databases, the Clever Kubernetes Operator has ex - Keycloak - And more services to come -### Key Features +## Key Features The Clever Kubernetes Operator provides: @@ -68,7 +68,6 @@ This documentation guides you through: - Installing and configuring the Clever Kubernetes Operator in your cluster. - Managing Clever Cloud resources such as PostgreSQL and Redis through examples. - ## Prerequisites Before you begin, ensure that you have the following tools and resources based on your intended actions: @@ -82,7 +81,7 @@ Before you begin, ensure that you have the following tools and resources based o ### To Deploy the Operator - **Kubernetes Cluster:** Ensure you have access to a running Kubernetes cluster. -- **Kubectl:** Install Kubernetes command-line tool for managing cluster resources Installation guide available at https://kubernetes.io/docs/tasks/tools/. +- **Kubectl:** Install Kubernetes command-line tool for managing cluster resources Installation guide available at . - **Clever Cloud Account Credentials:** [Obtain API tokens and secrets from your Clever Cloud](/api/howto) account to configure the operator. These prerequisites are essential for getting started with the Clever Kubernetes Operator, whether you're contributing to its development or deploying it in production. @@ -113,11 +112,11 @@ consumer-secret = "your-consumer-secret" ``` **Best for:** + - Production environments - Full control over permissions - Fine-grained access scope configuration - > #### Need an easier way to get these credentials? > > Yes, the OAuth dance can be complex. For a simpler setup, there is a small application that you can deploy on Clever Cloud that automates most of the process for you. @@ -137,6 +136,7 @@ secret = "your-secret" If you already use the Clever Cloud CLI (clever-tools), you can extract these credentials from its configuration file, typically located at `$HOME/.config/clever-cloud/clever-tools.json`. The token and secret values can be found in this file and reused for the operator configuration. **Best for:** + - Standard usage scenarios - Development, testing, or demos - Users already using Clever Cloud CLI @@ -153,11 +153,11 @@ token = "your-bearer-token" ``` **Best for:** + - Simple integrations - Quick scripts or automation - Environments using the "oauthless" backend authentication - ## Installation The Clever Kubernetes Operator can be deployed in several ways depending on your needs. @@ -211,7 +211,7 @@ Replace ``, ``, ``, and ` kubectl logs -n clever-kubernetes-operator @@ -583,16 +582,19 @@ If you encounter issues with the Clever Kubernetes Operator, here are some commo **Possible Solutions:** 1. Check the operator logs for errors: + ```bash kubectl logs -n clever-kubernetes-operator ``` 2. Verify the custom resource is valid: + ```bash kubectl get -o yaml ``` 3. Ensure the CRDs are properly installed: + ```bash kubectl get crds | grep clevercloud ``` diff --git a/content/doc/marketplace.md b/content/doc/marketplace.md index 501218d8f..65f701e7b 100644 --- a/content/doc/marketplace.md +++ b/content/doc/marketplace.md @@ -24,9 +24,9 @@ Clever Cloud allows its Marketplace partners to provide services as add-ons with You want to help us to offer more services to our users? [Contact us](https://partners.clever-cloud.com). Then, you will be able to use our dedicated tools and APIs to provide your service as an add-on, whether they're hosted on Clever Cloud or not. -* [Add-on Manifest](#add-on-manifest): to provide your service as an add-on -* [Add-on provider requests](#add-on-provider-requests): to provision, modify or delete add-ons -* [Add-on infos API](#add-on-infos-api): to list provisioned add-ons and get detailed information about them +- [Add-on Manifest](#add-on-manifest): to provide your service as an add-on +- [Add-on provider requests](#add-on-provider-requests): to provision, modify or delete add-ons +- [Add-on infos API](#add-on-infos-api): to list provisioned add-ons and get detailed information about them ## Add-on Manifest @@ -55,16 +55,16 @@ First, provide a JSON manifest file that describes your add-on: ### Available fields -* `id` - An ID for your add-on. All lower case, no spaces or punctuation. Underscores and dashes are allowed. This can’t be changed after the first push. It is also used for HTTP basic auth when making provisioning calls. -* `name` (Optional) - A human-readable name for your add-on. You will be able to change it later in the dashboard, so you don't even have to provide it right now. -* `api/config_vars` - A list of configuration variables that will be returned on provisioning calls. Each `config_var` name must start with the capitalized, add-on id with underscores, as in the example. -* `api/password` - Password that Clever Cloud will send in HTTP basic auth when making provisioning calls. You should generate a long random string for that field. -* `api/sso_salt` - Shared secret used in single sign-on between the Clever Cloud admin panel and your service’s admin panel. You should generate a long random string for that field. -* `api/regions` - The list of geographical zones supported by your add-on. It cannot be empty. As for now, it *MUST* contain the element "eu". More will be supported. -* `api/production/base_url` - The production endpoint on which Clever Cloud sends actions requests (provision and deprovision). -* `api/production/sso_url` - The production endpoint for single sign-on. -* `api/test/base_url` - The test endpoint on which Clever Cloud sends actions requests. Used to test your service when you create an add-on provider. After the add-on creation,`api/production/base_url` is used. -* `api/test/sso_url` - The test endpoint for single sign-on. Used to test your service when you create an add-on provider. After that, the `api/production/sso_url` is used. +- `id` - An ID for your add-on. All lower case, no spaces or punctuation. Underscores and dashes are allowed. This can’t be changed after the first push. It is also used for HTTP basic auth when making provisioning calls. +- `name` (Optional) - A human-readable name for your add-on. You will be able to change it later in the dashboard, so you don't even have to provide it right now. +- `api/config_vars` - A list of configuration variables that will be returned on provisioning calls. Each `config_var` name must start with the capitalized, add-on id with underscores, as in the example. +- `api/password` - Password that Clever Cloud will send in HTTP basic auth when making provisioning calls. You should generate a long random string for that field. +- `api/sso_salt` - Shared secret used in single sign-on between the Clever Cloud admin panel and your service’s admin panel. You should generate a long random string for that field. +- `api/regions` - The list of geographical zones supported by your add-on. It cannot be empty. As for now, it *MUST* contain the element "eu". More will be supported. +- `api/production/base_url` - The production endpoint on which Clever Cloud sends actions requests (provision and deprovision). +- `api/production/sso_url` - The production endpoint for single sign-on. +- `api/test/base_url` - The test endpoint on which Clever Cloud sends actions requests. Used to test your service when you create an add-on provider. After the add-on creation,`api/production/base_url` is used. +- `api/test/sso_url` - The test endpoint for single sign-on. Used to test your service when you create an add-on provider. After that, the `api/production/sso_url` is used. ## Add-on Provider requests @@ -99,22 +99,22 @@ Response Body: { The request body contains the following fields: -* `addon_id` - The id we give to your add-on to identify it on our side. -* `owner_id` - The id of the customer this add-on will belong to. -* `owner_name` - The name of the customer. (Actually, the name of the organisation) -* `user_id` - The id of the user that is performing the action of provisioning this +- `addon_id` - The id we give to your add-on to identify it on our side. +- `owner_id` - The id of the customer this add-on will belong to. +- `owner_name` - The name of the customer. (Actually, the name of the organisation) +- `user_id` - The id of the user that is performing the action of provisioning this add-on. (The user will do it for the account of `owner_id`). -* `plan` - The slug field for the plan the user chose. You can create +- `plan` - The slug field for the plan the user chose. You can create plans in the dashboard once your add-on manifest has been uploaded to the Clever Cloud platform. We send you the slug of the given plan, not its name. -* `region` - The region to provision the add-on. As for now, only "EU" will be sent. -* `callback_url` - The URL you can use to get details about the add-on and the user. This URL is available as soon as the provisioning is done. You can't use this URL during the POST call. -* `options` - String -> String map with options. +- `region` - The region to provision the add-on. As for now, only "EU" will be sent. +- `callback_url` - The URL you can use to get details about the add-on and the user. This URL is available as soon as the provisioning is done. You can't use this URL during the POST call. +- `options` - String -> String map with options. The response body contains the following fields: -* `id` - The add-on id as seen from your side. It *MUST* be a String. -* `config` (Optional) - A String -> String map with value for each config\_var defined in your manifest. A key that is not in your config\_vars will be ignored. -* `message` (Optional) - A creation message we will display in the dashboard. +- `id` - The add-on id as seen from your side. It *MUST* be a String. +- `config` (Optional) - A String -> String map with value for each config\_var defined in your manifest. A key that is not in your config\_vars will be ignored. +- `message` (Optional) - A creation message we will display in the dashboard. ### De-provisioning @@ -128,14 +128,14 @@ Request Body: none Response Status: 200 ``` -* `addon_id` - This is the same as the `id` field set in the response to the provisioning call. +- `addon_id` - This is the same as the `id` field set in the response to the provisioning call. ### Examples You can find templates for add-on providers in various languages on GitHub: -* [Node.js](https://github.com/Redsmin/passport-clevercloud) -* [Scala with Play! Framework 2](https://github.com/CleverCloud/addon-provider-template) +- [Node.js](https://github.com/Redsmin/passport-clevercloud) +- [Scala with Play! Framework 2](https://github.com/CleverCloud/addon-provider-template) ## Add-on Infos API @@ -166,15 +166,15 @@ Response Body: [ ] ``` -* `provider_id` - Should be the same as the "id" field of your uploaded manifest. +- `provider_id` - Should be the same as the "id" field of your uploaded manifest. -* `addon_id` - The add-on's id from Clever Cloud's POV. +- `addon_id` - The add-on's id from Clever Cloud's POV. -* `callback_url` - URL to call to get more details about this add-on. +- `callback_url` - URL to call to get more details about this add-on. -* `plan` - The current plan of this add-on. +- `plan` - The current plan of this add-on. -* `owner_id` - The id of the owner that provisioned the add-on. This should never change. +- `owner_id` - The id of the owner that provisioned the add-on. This should never change. ### Get information about a specific add-on @@ -199,23 +199,23 @@ Response Body: { This endpoint gives you more information about a provisioned add-on. -* `id` - The add-on id from Clever Cloud's POV. +- `id` - The add-on id from Clever Cloud's POV. -* `name` - The name the user gave to this add-on in the Clever Cloud dashboard. +- `name` - The name the user gave to this add-on in the Clever Cloud dashboard. -* `config` - Configuration variables as you defined during the provision call. +- `config` - Configuration variables as you defined during the provision call. -* `callback_url` - The URL you just called. +- `callback_url` - The URL you just called. -* `owner_email` - One of the owner's email address. +- `owner_email` - One of the owner's email address. -* `owner_emails` - All the owner's email addresses. +- `owner_emails` - All the owner's email addresses. -* `owner_id` - The id of the owner that provisioned the add-on. This should never change. +- `owner_id` - The id of the owner that provisioned the add-on. This should never change. -* `region` - The region this add-on is located in. As for now, only "eu" is supported. +- `region` - The region this add-on is located in. As for now, only "eu" is supported. -* `domains` - Originally the domains names for the application owning the add-on. We return an empty list. +- `domains` - Originally the domains names for the application owning the add-on. We return an empty list. ### Update the configuration variables for an add-on @@ -339,13 +339,13 @@ Content-Type: application/x-www-form-urlencoded id=×tamp=&nav-data=&email=&user_id=&signature= ``` -* The hostname or `sso_url` comes from your add-on manifest -* The `id` is the ID for the previously provisioned resource -* The `timestamp` is a millisecond timestamp. You *SHOULD* verify that it's not older than a few minutes (like 5) -* The `user_id` is a unique string identifying the current user on the Clever Cloud platform -* The `email` is the current primary email of the current user on the Clever Cloud platform -* The `nav-data` contains information like the current app name and installed add-ons for Clever Cloud's Console. At the time of writing this doc, this field is always empty -* The `signature` is computed using the formula below +- The hostname or `sso_url` comes from your add-on manifest +- The `id` is the ID for the previously provisioned resource +- The `timestamp` is a millisecond timestamp. You *SHOULD* verify that it's not older than a few minutes (like 5) +- The `user_id` is a unique string identifying the current user on the Clever Cloud platform +- The `email` is the current primary email of the current user on the Clever Cloud platform +- The `nav-data` contains information like the current app name and installed add-ons for Clever Cloud's Console. At the time of writing this doc, this field is always empty +- The `signature` is computed using the formula below ### Token diff --git a/content/doc/metrics/_index.md b/content/doc/metrics/_index.md index ded3915a6..8b13fcfec 100644 --- a/content/doc/metrics/_index.md +++ b/content/doc/metrics/_index.md @@ -55,7 +55,7 @@ For example, check [this tutorial on how to create Slack alerts with Grafana](ht ### Templated dashboards in Grafana -Pre-configured dashboards are available in your `Clever Cloud` directory to help you visualize your application metrics. +Pre-configured dashboards are available in your `Clever Cloud` directory to help you visualize your application metrics. To customize a template and preserve your changes, create and save a **copy** of the dashboard in a **different** directory. Original templates may be overwritten when the Clever Cloud team releases updates. @@ -100,69 +100,69 @@ Telegraf provide lots of metrics described in their [documentation](https://gith Below, the list of all Warp 10 classes representing Telegraf metrics : -| Metric | Metric | -| ----------------------------------- | ----------------------------------- | -| conntrack.ip_conntrack_count | mem.swap_free | -| conntrack.ip_conntrack_max | mem.swap_total | -| cpu.usage_guest | mem.total | -| cpu.usage_guest_nice | mem.used | -| cpu.usage_idle | mem.used_percent | -| cpu.usage_iowait | mem.vmalloc_chunk | -| cpu.usage_irq | mem.vmalloc_total | -| cpu.usage_nice | mem.vmalloc_used | -| cpu.usage_softirq | mem.wired | -| cpu.usage_steal | mem.write_back | -| cpu.usage_system | mem.write_back_tmp | -| cpu.usage_user | net.bytes_recv | -| disk.free | net.bytes_sent | -| disk.inodes_free | net.drop_in | -| disk.inodes_total | net.drop_out | -| disk.inodes_used | net.err_in | -| disk.total | net.err_out | -| disk.used | net.packets_recv | -| disk.used_percent | net.packets_sent | -| http_response.http_response_code | net_response.response_time | -| http_response.response_time | net_response.result_code | -| http_response.result_code | net_response.result_type | -| http_response.result_type | netstat.tcp_close | -| kernel.boot_time | netstat.tcp_close_wait | -| kernel.context_switches | netstat.tcp_closing | -| kernel.entropy_avail | netstat.tcp_established | -| kernel.interrupts | netstat.tcp_fin_wait1 | -| kernel.processes_forked | netstat.tcp_fin_wait2 | -| mem.active | netstat.tcp_last_ack | -| mem.available | netstat.tcp_listen | -| mem.available_percent | netstat.tcp_none | -| mem.buffered | netstat.tcp_syn_recv | -| mem.cached | netstat.tcp_syn_sent | -| mem.commit_limit | netstat.tcp_time_wait | -| mem.committed_as | netstat.udp_socket | -| mem.dirty | processes.blocked | -| mem.free | processes.dead | -| mem.high_free | processes.idle | -| mem.high_total | processes.paging | -| mem.huge_page_size | processes.running | -| mem.huge_pages_free | processes.sleeping | -| mem.huge_pages_total | processes.stopped | -| mem.inactive | processes.total | -| mem.low_free | processes.total_threads | -| mem.low_total | processes.unknown | -| mem.mapped | processes.zombies | -| mem.page_tables | procstat_lookup.pid_count | -| mem.shared | system.load1 | -| mem.slab | system.load1_per_cpu | -| mem.swap_cached | jvm.statsd-jvm-profiler_heap_ps-old-gen_max.value | -| jvm.statsd-jvm-profiler_pending-finalization-count.value | jvm.statsd-jvm-profiler_nonheap_total_committed.value | -| jvm.statsd-jvm-profiler_loaded-class-count.value | jvm.metrics_jvm_heapMemoryUsage_used.value | -| jvm.statsd-jvm-profiler_gc_PS_Scavenge_count.value | jvm.metrics_jvm_nonHeapMemoryUsage_used.value | -| jvm.statsd-jvm-profiler_nonheap_metaspace_init.value | jvm.statsd-jvm-profiler_nonheap_total_used.value | -| jvm.statsd-jvm-profiler_heap_ps-survivor-space_used.value | jvm.statsd-jvm-profiler_heap_ps-eden-space_init.value | -| jvm.statsd-jvm-profiler_gc_PS_MarkSweep_time.value | jvm.statsd-jvm-profiler_nonheap_total_max.value | -| jvm.statsd-jvm-profiler_heap_ps-eden-space_max.value | jvm.statsd-jvm-profiler_nonheap_compressed-class-space_max.value | -| jvm.statsd-jvm-profiler_heap_total_init.value | jvm.statsd-jvm-profiler_nonheap_code-cache_used.value | -| jvm.statsd-jvm-profiler_nonheap_metaspace_used.value | jvm.statsd-jvm-profiler_nonheap_compressed-class-space_init.value | -| jvm.statsd-jvm-profiler_nonheap_metaspace_max.value | jvm.statsd-jvm-profiler_gc_PS_MarkSweep_count.value | -| jvm.statsd-jvm-profiler_heap_ps-eden-space_used.value | | +| Metric | Metric | +| --------------------------------------------------------- | ----------------------------------------------------------------- | +| conntrack.ip_conntrack_count | mem.swap_free | +| conntrack.ip_conntrack_max | mem.swap_total | +| cpu.usage_guest | mem.total | +| cpu.usage_guest_nice | mem.used | +| cpu.usage_idle | mem.used_percent | +| cpu.usage_iowait | mem.vmalloc_chunk | +| cpu.usage_irq | mem.vmalloc_total | +| cpu.usage_nice | mem.vmalloc_used | +| cpu.usage_softirq | mem.wired | +| cpu.usage_steal | mem.write_back | +| cpu.usage_system | mem.write_back_tmp | +| cpu.usage_user | net.bytes_recv | +| disk.free | net.bytes_sent | +| disk.inodes_free | net.drop_in | +| disk.inodes_total | net.drop_out | +| disk.inodes_used | net.err_in | +| disk.total | net.err_out | +| disk.used | net.packets_recv | +| disk.used_percent | net.packets_sent | +| http_response.http_response_code | net_response.response_time | +| http_response.response_time | net_response.result_code | +| http_response.result_code | net_response.result_type | +| http_response.result_type | netstat.tcp_close | +| kernel.boot_time | netstat.tcp_close_wait | +| kernel.context_switches | netstat.tcp_closing | +| kernel.entropy_avail | netstat.tcp_established | +| kernel.interrupts | netstat.tcp_fin_wait1 | +| kernel.processes_forked | netstat.tcp_fin_wait2 | +| mem.active | netstat.tcp_last_ack | +| mem.available | netstat.tcp_listen | +| mem.available_percent | netstat.tcp_none | +| mem.buffered | netstat.tcp_syn_recv | +| mem.cached | netstat.tcp_syn_sent | +| mem.commit_limit | netstat.tcp_time_wait | +| mem.committed_as | netstat.udp_socket | +| mem.dirty | processes.blocked | +| mem.free | processes.dead | +| mem.high_free | processes.idle | +| mem.high_total | processes.paging | +| mem.huge_page_size | processes.running | +| mem.huge_pages_free | processes.sleeping | +| mem.huge_pages_total | processes.stopped | +| mem.inactive | processes.total | +| mem.low_free | processes.total_threads | +| mem.low_total | processes.unknown | +| mem.mapped | processes.zombies | +| mem.page_tables | procstat_lookup.pid_count | +| mem.shared | system.load1 | +| mem.slab | system.load1_per_cpu | +| mem.swap_cached | jvm.statsd-jvm-profiler_heap_ps-old-gen_max.value | +| jvm.statsd-jvm-profiler_pending-finalization-count.value | jvm.statsd-jvm-profiler_nonheap_total_committed.value | +| jvm.statsd-jvm-profiler_loaded-class-count.value | jvm.metrics_jvm_heapMemoryUsage_used.value | +| jvm.statsd-jvm-profiler_gc_PS_Scavenge_count.value | jvm.metrics_jvm_nonHeapMemoryUsage_used.value | +| jvm.statsd-jvm-profiler_nonheap_metaspace_init.value | jvm.statsd-jvm-profiler_nonheap_total_used.value | +| jvm.statsd-jvm-profiler_heap_ps-survivor-space_used.value | jvm.statsd-jvm-profiler_heap_ps-eden-space_init.value | +| jvm.statsd-jvm-profiler_gc_PS_MarkSweep_time.value | jvm.statsd-jvm-profiler_nonheap_total_max.value | +| jvm.statsd-jvm-profiler_heap_ps-eden-space_max.value | jvm.statsd-jvm-profiler_nonheap_compressed-class-space_max.value | +| jvm.statsd-jvm-profiler_heap_total_init.value | jvm.statsd-jvm-profiler_nonheap_code-cache_used.value | +| jvm.statsd-jvm-profiler_nonheap_metaspace_used.value | jvm.statsd-jvm-profiler_nonheap_compressed-class-space_init.value | +| jvm.statsd-jvm-profiler_nonheap_metaspace_max.value | jvm.statsd-jvm-profiler_gc_PS_MarkSweep_count.value | +| jvm.statsd-jvm-profiler_heap_ps-eden-space_used.value | | ### Examples and usages diff --git a/content/doc/metrics/new-relic.md b/content/doc/metrics/new-relic.md index 9971c087b..c035f4e87 100644 --- a/content/doc/metrics/new-relic.md +++ b/content/doc/metrics/new-relic.md @@ -67,13 +67,13 @@ If the `appname` or `NEW_RELIC_APP_NAME` is not specified, we use your applicati If you need to fine-tune agent settings, you can use the following environment variables: -| Variable | -|-------------------- -|[`CC_NEWRELIC_BROWSER_MONITORING_AUTO_INSTRUMENT`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-autorum) | -|[`CC_NEWRELIC_DISTRIBUTED_TRACING_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-distributed-enabled) | -|[`CC_NEWRELIC_ERROR_COLLECTOR_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-err-enabled) | -|[`CC_NEWRELIC_TRANSACTION_TRACER_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-tt-enable) | -|[`CC_NEWRELIC_TRANSACTION_TRACER_RECORD_SQL`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-tt-sql) | +| Variable | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [`CC_NEWRELIC_BROWSER_MONITORING_AUTO_INSTRUMENT`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-autorum) | +| [`CC_NEWRELIC_DISTRIBUTED_TRACING_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-distributed-enabled) | +| [`CC_NEWRELIC_ERROR_COLLECTOR_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-err-enabled) | +| [`CC_NEWRELIC_TRANSACTION_TRACER_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-tt-enable) | +| [`CC_NEWRELIC_TRANSACTION_TRACER_RECORD_SQL`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-tt-sql) | ### Usage diff --git a/content/doc/metrics/warp10.md b/content/doc/metrics/warp10.md index 0d8afa0ce..33bd9255c 100644 --- a/content/doc/metrics/warp10.md +++ b/content/doc/metrics/warp10.md @@ -24,13 +24,14 @@ The Clever Cloud Warp 10 endpoint is: https://c2-warp10-clevercloud-customers.services.clever-cloud.com/api/v0 ``` -* Learn more about [endpoint gateway on warp10.io](https://www.warp10.io/content/03_Documentation/03_Interacting_with_Warp_10/01_Introduction) +- Learn more about [endpoint gateway on warp10.io](https://www.warp10.io/content/03_Documentation/03_Interacting_with_Warp_10/01_Introduction) You can find the endpoint and an available token under the `metric` tab of your application. You can query our Warp 10 platform with your own script. Here's an example with `curl`: ```bash curl -T https://c2-warp10-clevercloud-customers.services.clever-cloud.com/api/v0/exec ``` + ## Token Tokens are based on your application with the notion of producer and owner. Hence, only the data owner can see it. diff --git a/content/doc/quickstart.md b/content/doc/quickstart.md index cafd38ef7..0b14c6cb5 100644 --- a/content/doc/quickstart.md +++ b/content/doc/quickstart.md @@ -44,8 +44,8 @@ There are two ways to sign up for Clever Cloud: **email** or **GitHub login**. The GitHub sign up allows you to create an account or link your existing one to GitHub, in one click. This process asks the following permissions: -* Read your Public Key -* Read User Repositories +- Read your Public Key +- Read User Repositories The "repository permission" is used to deploy your GitHub apps directly to Clever Cloud, with a simple step. If you need to give access to Clever Cloud's API to a specific GitHub organisation, you can [do it here](https://github.com/settings/connections/applications/d96bd8fd996d2ca783cc). @@ -67,10 +67,10 @@ Please, backup your recovery codes, we won't be able to restore access to your a An application is defined on Clever Cloud by the following elements: -* a dedicated language/framework; -* a deployment method (FTP and/or Git); -* resources consumption (CPU, RAM, Disk…), depending on the language or framework used; -* an optional configuration file you may add to your project. +- a dedicated language/framework; +- a deployment method (FTP and/or Git); +- resources consumption (CPU, RAM, Disk…), depending on the language or framework used; +- an optional configuration file you may add to your project. If one of these elements is missing, Clever Cloud can't deploy your application properly (except the configuration file, optional in some cases). @@ -145,8 +145,8 @@ Enter the name and the description of your application. #### Optional steps -* The wizard will offer you to [add an add-on](/doc/addons) to your application -* The wizard will offer you to [add environment variables](/doc/develop/env-variables) to your application +- The wizard will offer you to [add an add-on](/doc/addons) to your application +- The wizard will offer you to [add environment variables](/doc/develop/env-variables) to your application {{% /steps %}} @@ -232,9 +232,9 @@ The full tutorial about adding SSH key is here: [adding SSH keys](/doc/account/s {{% details title= "Git ⋅ Unable to resolve the reference master" closed="true" %}} You are probably trying to push from another branch. Keep in mind that: -* You can only push to the **master** branch for deployment. Trying to push to another branch will trigger an error. -* You cannot push a tag (which refers to a commit) to the remote repository. If you do so, **no deployment** will be triggered. -* In order to push to **master** from a non-master local branch, use this syntax: +- You can only push to the **master** branch for deployment. Trying to push to another branch will trigger an error. +- You cannot push a tag (which refers to a commit) to the remote repository. If you do so, **no deployment** will be triggered. +- In order to push to **master** from a non-master local branch, use this syntax: ```bash git push :master @@ -262,16 +262,16 @@ If you have to push directly to a repository to deploy an application (eg if you There are many tabs available in the application's menu on Clever Console: -* **Information:** General information about your application -* **Scalability:** Set-up scalability options -* **Domain names:** Manage custom domain names -* **Environment variables:** Manage environment variables -* **Service dependencies:** Link add-ons and applications -* **Exposed configuration:** Manage exposed environment variables -* **Activity:** Track last deployments -* **Logs:** Visualize application's logs -* **Metrics:** Visualize application's metrics -* **Consumption:** Visualize your application's consumption. +- **Information:** General information about your application +- **Scalability:** Set-up scalability options +- **Domain names:** Manage custom domain names +- **Environment variables:** Manage environment variables +- **Service dependencies:** Link add-ons and applications +- **Exposed configuration:** Manage exposed environment variables +- **Activity:** Track last deployments +- **Logs:** Visualize application's logs +- **Metrics:** Visualize application's metrics +- **Consumption:** Visualize your application's consumption. ### Create your first add-on @@ -351,8 +351,8 @@ Clever Cloud provides multiple add-ons to work with your applications: There are two kinds of billing: -* Per-month billing: Add-ons with fixed resources (storage, CPU and RAM) -* Per-usage billing: Add-ons based on consumption, like [FS Bucket](/doc/addons/fs-bucket) and [Cellar](/doc/addons/cellar) +- Per-month billing: Add-ons with fixed resources (storage, CPU and RAM) +- Per-usage billing: Add-ons based on consumption, like [FS Bucket](/doc/addons/fs-bucket) and [Cellar](/doc/addons/cellar) {{< callout type="warning" >}} **Free Plan:** add-ons having a free plan are meant for testing purposes, not production usage. These add-ons usually rely on shared resources, resulting in variable, non-guaranteed performances and stability. Shared clusters may not be running the same version as dedicated instances. @@ -366,11 +366,11 @@ There are two kinds of billing: Once an add-on is created, at least two tabs are available in the Clever Cloud console: -* **Add-on dashboard:** This screen provides and overview of your add-on and its options, depending on the type of add-on it is. +- **Add-on dashboard:** This screen provides and overview of your add-on and its options, depending on the type of add-on it is. !["Add-on dashboard"](/images/addon-dashboard.png "Example of an add-on dashboard") -* **Information tab:** This screen sums-up the characteristics of the selected add-on. +- **Information tab:** This screen sums-up the characteristics of the selected add-on. The system shows features and environment variables (if applicable). Other tabs may be available, depending on the add-on type. diff --git a/content/doc/reference/cli.md b/content/doc/reference/cli.md index f296e8ee3..90216fec8 100644 --- a/content/doc/reference/cli.md +++ b/content/doc/reference/cli.md @@ -19,10 +19,13 @@ aliases: - /reference/clever-tools/getting_started --- + + This document is automatically generated from Clever Tools and Clever Cloud API. It covers all Clever Tools commands and options. Use it to better understand this CLI and its capabilities or to train/use LLMs, AI-assisted IDEs. To use Clever Tools, you need: -- A Clever Cloud account, create one at https://console.clever-cloud.com/ + +- A Clever Cloud account, create one at - The Clever Tools CLI installed, see installation instructions below In CI/CD pipelines or for one-off usage, you can use it through `npx` or `npm exec`: @@ -51,7 +54,7 @@ Clever Cloud CLI is based on Node.js. We thought it to be easily available on an If you use Arch Linux, install packages [from AUR](https://aur.archlinux.org/packages/clever-tools-bin/). If you don't know how to use this, run: -``` +```console git clone https://aur.archlinux.org/clever-tools-bin.git clever-tools cd clever-tools makepkg -si @@ -61,7 +64,7 @@ makepkg -si If you use a GNU/Linux distribution that uses `.rpm` packages like CentOS or Fedora, run: -``` +```console curl -s https://clever-tools.clever-cloud.com/repos/cc-nexus-rpm.repo > /etc/yum.repos.d/cc-nexus-rpm.repo yum update yum install clever-tools @@ -74,7 +77,7 @@ yum install clever-tools If you use a GNU/Linux distribution that uses `.deb` packages like Debian or Ubuntu, run: -``` +```console curl -fsSL https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key | gpg --dearmor -o /usr/share/keyrings/cc-nexus-deb.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/cc-nexus-deb.gpg] https://nexus.clever-cloud.com/repository/deb stable main" | tee -a /etc/apt/sources.list apt update @@ -89,7 +92,7 @@ apt install clever-tools If you are using Exherbo, run: -``` +```console cave resolve repository/CleverCloud -zx1 cave resolve clever-tools-bin -zx ``` @@ -98,7 +101,7 @@ cave resolve clever-tools-bin -zx If you use another GNU/Linux distribution, download the `.tar.gz` archive and extract the binary in your `PATH`: -``` +```console curl -O https://clever-tools.clever-cloud.com/releases/latest/clever-tools-latest_linux.tar.gz tar xvzf clever-tools-latest_linux.tar.gz cp clever-tools-latest_linux/clever ~/.local/bin/ @@ -106,7 +109,7 @@ cp clever-tools-latest_linux/clever ~/.local/bin/ > [!TIP] > The packages are available on Clever Cloud's Cellar bucket: [clever-tools-latest_linux.tar.gz](https://clever-tools.clever-cloud.com/releases/latest/clever-tools-latest_linux.tar.gz). \ -> Retrieve any release by replacing `latest` (path and filename) with the version number you need. +> Retrieve any release by replacing `latest` (path and filename) with the version number you need. ### macOS @@ -116,7 +119,7 @@ We only provide macOS packages for Apple Silicon processors. On an Intel Mac, pr If you use macOS and you have [Homebrew](https://brew.sh) installed, run: -``` +```console brew install CleverCloud/homebrew-tap/clever-tools ``` @@ -124,7 +127,7 @@ brew install CleverCloud/homebrew-tap/clever-tools If you use macOS, but you don't have [Homebrew](https://brew.sh) installed, download the `.tar.gz` archive and extract the binary in your `PATH`: -``` +```console curl -O https://clever-tools.clever-cloud.com/releases/latest/clever-tools-latest_macos.tar.gz tar xvzf clever-tools-latest_macos.tar.gz cp clever-tools-latest_macos/clever ~/.local/bin/ @@ -140,7 +143,7 @@ cp clever-tools-latest_macos/clever ~/.local/bin/ If you use Windows run in a terminal: -``` +```console winget install CleverTools ``` @@ -160,9 +163,9 @@ $env:PATH += ";$(Resolve-Path .\clever-tools-latest_win\)" ### Docker -If you are using docker, use the image provided [here](https://hub.docker.com/r/clevercloud/clever-tools/). +If you are using Docker, use the [Clever Tools image from Docker Hub](https://hub.docker.com/r/clevercloud/clever-tools/). -``` +```console docker pull clevercloud/clever-tools docker run --rm clever-tools ``` @@ -268,12 +271,14 @@ Default deployment zone is `par`, default plan is the lowest available. **Since:** 2.1.0 **Usage** -``` + +```console clever accesslogs [options] ``` **Options** -``` + +```console --addon Add-on ID or real ID --after, --since Fetch logs after this date/time (ISO8601 date, positive number in seconds or duration, e.g.: 1h) -a, --alias Short name for the application @@ -289,12 +294,14 @@ clever accesslogs [options] **Since:** 0.2.3 **Usage** -``` + +```console clever activity [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -f, --follow Track new deployments in activity list @@ -309,12 +316,14 @@ clever activity [options] **Since:** 0.2.3 **Usage** -``` + +```console clever addon [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -326,18 +335,21 @@ clever addon [options] **Since:** 0.2.3 **Usage** -``` + +```console clever addon create [options] ``` **Arguments** -``` + +```console addon-provider Add-on provider addon-name Add-on name ``` **Options** -``` + +```console --addon-version The version to use for the add-on -F, --format Output format (human, json) (default: human) -l, --link Link the created add-on to the app with the specified alias @@ -355,17 +367,20 @@ addon-name Add-on name **Since:** 0.2.3 **Usage** -``` + +```console clever addon delete [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) -y, --yes Skip confirmation prompts ``` @@ -377,17 +392,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 2.11.0 **Usage** -``` + +```console clever addon env [options] ``` **Arguments** -``` + +```console addon-id Add-on ID or real ID ``` **Options** -``` + +```console -F, --format Output format (human, json, shell) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) (deprecated, organisation is now resolved automatically) ``` @@ -399,12 +417,14 @@ addon-id Add-on ID or real ID **Since:** 0.2.3 **Usage** -``` + +```console clever addon list [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -416,12 +436,14 @@ clever addon list [options] **Since:** 0.2.3 **Usage** -``` + +```console clever addon providers [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -433,17 +455,20 @@ clever addon providers [options] **Since:** 0.2.3 **Usage** -``` + +```console clever addon providers show [options] ``` **Arguments** -``` + +```console addon-provider Add-on provider ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -455,18 +480,21 @@ addon-provider Add-on provider **Since:** 0.3.0 **Usage** -``` + +```console clever addon rename [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) addon-name Add-on name ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -477,12 +505,14 @@ addon-name Add-on name **Since:** 0.3.0 **Usage** -``` + +```console clever applications [options] ``` **Options** -``` + +```console -j, --json Show result in JSON format --only-aliases List only application aliases ``` @@ -494,12 +524,14 @@ clever applications [options] **Since:** 3.8.0 **Usage** -``` + +```console clever applications list [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -511,12 +543,14 @@ clever applications list [options] **Since:** 0.2.0 **Usage** -``` + +```console clever cancel-deploy [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -528,12 +562,14 @@ clever cancel-deploy [options] **Since:** 2.5.0 **Usage** -``` + +```console clever config [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -545,17 +581,20 @@ clever config [options] **Since:** 2.5.0 **Usage** -``` + +```console clever config get [options] ``` **Arguments** -``` + +```console configuration-name Configuration to manage: name, description, zero-downtime, sticky-sessions, cancel-on-push, force-https, or task ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -567,18 +606,21 @@ configuration-name Configuration to manage: name, description, zero- **Since:** 2.5.0 **Usage** -``` + +```console clever config set [options] ``` **Arguments** -``` + +```console configuration-name Configuration to manage: name, description, zero-downtime, sticky-sessions, cancel-on-push, force-https, or task configuration-value The new value of the configuration ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -590,12 +632,14 @@ configuration-value The new value of the configuration **Since:** 2.5.0 **Usage** -``` + +```console clever config update [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) --description Set application description @@ -619,7 +663,8 @@ clever config update [options] **Since:** 4.6.0 **Usage** -``` + +```console clever config-provider ``` @@ -630,17 +675,20 @@ clever config-provider **Since:** 4.6.0 **Usage** -``` + +```console clever config-provider get [options] ``` **Arguments** -``` + +```console addon-id|config-provider-id|addon-name Add-on ID, real ID (config_xxx) or name (if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json, shell) (default: human) ``` @@ -652,17 +700,20 @@ addon-id|config-provider-id|addon-name Add-on ID, real ID (config_xxx) or nam **Since:** 4.6.0 **Usage** -``` + +```console clever config-provider import [options] ``` **Arguments** -``` + +```console addon-id|config-provider-id|addon-name Add-on ID, real ID (config_xxx) or name (if unambiguous) ``` **Options** -``` + +```console -F, --format Input format (name-equals-value, json) (default: name-equals-value) ``` @@ -673,12 +724,14 @@ addon-id|config-provider-id|addon-name Add-on ID, real ID (config_xxx) or nam **Since:** 4.6.0 **Usage** -``` + +```console clever config-provider list [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -689,12 +742,14 @@ clever config-provider list [options] **Since:** 4.6.0 **Usage** -``` + +```console clever config-provider open ``` **Arguments** -``` + +```console addon-id|config-provider-id|addon-name Add-on ID, real ID (config_xxx) or name (if unambiguous) ``` @@ -705,29 +760,33 @@ addon-id|config-provider-id|addon-name Add-on ID, real ID (config_xxx) or nam **Since:** 4.6.0 **Usage** -``` + +```console clever config-provider rm ``` **Arguments** -``` + +```console addon-id|config-provider-id|addon-name Add-on ID, real ID (config_xxx) or name (if unambiguous) variable-name Name of the environment variable ``` ### config-provider set -**Description:** Add or update an environment variable named with the value +**Description:** Add or update an environment variable named `` with the value `` **Since:** 4.6.0 **Usage** -``` + +```console clever config-provider set ``` **Arguments** -``` + +```console addon-id|config-provider-id|addon-name Add-on ID, real ID (config_xxx) or name (if unambiguous) variable-name Name of the environment variable variable-value Value of the environment variable @@ -740,12 +799,14 @@ variable-value Value of the environment variable **Since:** 1.0.0 **Usage** -``` + +```console clever console [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -757,17 +818,20 @@ clever console [options] **Since:** 0.2.0 **Usage** -``` + +```console clever create --type [] [options] ``` **Arguments** -``` + +```console app-name Application name (current directory name is used if not specified) (optional) ``` **Options** -``` + +```console -t, --type Instance type (required) -a, --alias Short name for the application -F, --format Output format (human, json) (default: human) @@ -784,7 +848,8 @@ app-name Application name (current directory name **Since:** 2.10.0 **Usage** -``` + +```console clever curl ``` @@ -795,7 +860,8 @@ clever curl **Since:** 2.10.0 **Usage** -``` + +```console clever database ``` @@ -806,17 +872,20 @@ clever database **Since:** 2.10.0 **Usage** -``` + +```console clever database backups [options] ``` **Arguments** -``` + +```console database-id|addon-id Any database ID (format: addon_UUID, postgresql_UUID, mysql_UUID, ...) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) (deprecated, organisation is now resolved automatically) ``` @@ -828,18 +897,21 @@ database-id|addon-id Any database ID (format: addon_UUID, pos **Since:** 2.10.0 **Usage** -``` + +```console clever database backups download [options] ``` **Arguments** -``` + +```console database-id|addon-id Any database ID (format: addon_UUID, postgresql_UUID, mysql_UUID, ...) backup-id A Database backup ID (format: UUID) ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) (deprecated, organisation is now resolved automatically) --output, --out Redirect the output of the command in a file ``` @@ -851,12 +923,14 @@ backup-id A Database backup ID (format: UUID) **Since:** 0.7.0 **Usage** -``` + +```console clever delete [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -y, --yes Skip confirmation and delete the application directly @@ -869,12 +943,14 @@ clever delete [options] **Since:** 0.2.0 **Usage** -``` + +```console clever deploy [options] ``` **Options** -``` + +```console -a, --alias Short name for the application -b, --branch Branch to push (current branch by default) -e, --exit-on Step at which the logs streaming is ended (deploy-start, deploy-end, never) (default: deploy-end) @@ -892,12 +968,14 @@ clever deploy [options] **Since:** 1.6.0 **Usage** -``` + +```console clever diag [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -908,12 +986,14 @@ clever diag [options] **Since:** 0.2.0 **Usage** -``` + +```console clever domain [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -F, --format Output format (human, json) (default: human) @@ -926,17 +1006,20 @@ clever domain [options] **Since:** 0.2.0 **Usage** -``` + +```console clever domain add [options] ``` **Arguments** -``` + +```console fqdn Domain name of the application ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -948,12 +1031,14 @@ fqdn Domain name of the application **Since:** 3.9.0 **Usage** -``` + +```console clever domain diag [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) --filter Check only domains containing the provided text @@ -967,12 +1052,14 @@ clever domain diag [options] **Since:** 2.7.0 **Usage** -``` + +```console clever domain favourite [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -F, --format Output format (human, json) (default: human) @@ -985,17 +1072,20 @@ clever domain favourite [options] **Since:** 2.7.0 **Usage** -``` + +```console clever domain favourite set [options] ``` **Arguments** -``` + +```console fqdn Domain name of the application ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -1007,12 +1097,14 @@ fqdn Domain name of the application **Since:** 2.7.0 **Usage** -``` + +```console clever domain favourite unset [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -1024,12 +1116,14 @@ clever domain favourite unset [options] **Since:** 3.9.0 **Usage** -``` + +```console clever domain overview [options] ``` **Options** -``` + +```console --filter Get only domains containing the provided text -F, --format Output format (human, json) (default: human) ``` @@ -1041,17 +1135,20 @@ clever domain overview [options] **Since:** 0.2.0 **Usage** -``` + +```console clever domain rm [options] ``` **Arguments** -``` + +```console fqdn Domain name of the application ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -1063,12 +1160,14 @@ fqdn Domain name of the application **Since:** 0.9.0 **Usage** -``` + +```console clever drain [options] ``` **Options** -``` + +```console --addon Add-on ID or real ID -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) @@ -1082,17 +1181,20 @@ clever drain [options] **Since:** 4.11.0 **Usage** -``` + +```console clever drain check [options] ``` **Arguments** -``` + +```console drain-id Drain ID ``` **Options** -``` + +```console --addon Add-on ID or real ID -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) @@ -1106,18 +1208,21 @@ drain-id Drain ID **Since:** 0.9.0 **Usage** -``` + +```console clever drain create [options] ``` **Arguments** -``` + +```console drain-type Drain type (betterstack, datadog, elasticsearch, newrelic, ovh-tcp, raw-http, syslog-tcp, syslog-udp) drain-url Drain URL ``` **Options** -``` + +```console --addon Add-on ID or real ID -a, --alias Short name for the application -k, --api-key API key (for newrelic) @@ -1136,17 +1241,20 @@ drain-url Drain URL **Since:** 0.9.0 **Usage** -``` + +```console clever drain disable [options] ``` **Arguments** -``` + +```console drain-id Drain ID ``` **Options** -``` + +```console --addon Add-on ID or real ID -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) @@ -1159,17 +1267,20 @@ drain-id Drain ID **Since:** 0.9.0 **Usage** -``` + +```console clever drain enable [options] ``` **Arguments** -``` + +```console drain-id Drain ID ``` **Options** -``` + +```console --addon Add-on ID or real ID -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) @@ -1182,17 +1293,20 @@ drain-id Drain ID **Since:** 0.9.0 **Usage** -``` + +```console clever drain get [options] ``` **Arguments** -``` + +```console drain-id Drain ID ``` **Options** -``` + +```console --addon Add-on ID or real ID -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) @@ -1206,17 +1320,20 @@ drain-id Drain ID **Since:** 0.9.0 **Usage** -``` + +```console clever drain remove [options] ``` **Arguments** -``` + +```console drain-id Drain ID ``` **Options** -``` + +```console --addon Add-on ID or real ID -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) @@ -1229,12 +1346,14 @@ drain-id Drain ID **Since:** 3.13.0 **Usage** -``` + +```console clever emails [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -1245,12 +1364,14 @@ clever emails [options] **Since:** 3.13.0 **Usage** -``` + +```console clever emails add ``` **Arguments** -``` + +```console email Email address ``` @@ -1261,7 +1382,8 @@ email Email address **Since:** 3.13.0 **Usage** -``` + +```console clever emails open ``` @@ -1272,12 +1394,14 @@ clever emails open **Since:** 3.13.0 **Usage** -``` + +```console clever emails primary ``` **Arguments** -``` + +```console email Email address ``` @@ -1288,12 +1412,14 @@ email Email address **Since:** 3.13.0 **Usage** -``` + +```console clever emails remove ``` **Arguments** -``` + +```console email Email address ``` @@ -1304,12 +1430,14 @@ email Email address **Since:** 3.13.0 **Usage** -``` + +```console clever emails remove-all [options] ``` **Options** -``` + +```console -y, --yes Skip confirmation ``` @@ -1320,12 +1448,14 @@ clever emails remove-all [options] **Since:** 0.2.0 **Usage** -``` + +```console clever env [options] ``` **Options** -``` + +```console --add-export Display sourceable env variables setting (deprecated, use `--format shell` instead) -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) @@ -1340,12 +1470,14 @@ clever env [options] **Since:** 0.3.0 **Usage** -``` + +```console clever env import [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) --json Import variables as JSON (an array of { "name": "THE_NAME", "value": "THE_VALUE" } objects) @@ -1353,22 +1485,25 @@ clever env import [options] ### env import-vars -**Description:** Add or update environment variables named (comma-separated), taking their values from the current environment +**Description:** Add or update environment variables named `` (comma-separated), taking their values from the current environment **Since:** 2.0.0 **Usage** -``` + +```console clever env import-vars [options] ``` **Arguments** -``` + +```console variable-names Comma separated list of names of the environment variables ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -1380,40 +1515,46 @@ variable-names Comma separated list of names of the environment **Since:** 0.3.0 **Usage** -``` + +```console clever env rm [options] ``` **Arguments** -``` + +```console variable-name Name of the environment variable ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` ### env set -**Description:** Add or update an environment variable named with the value +**Description:** Add or update an environment variable named `` with the value `` **Since:** 0.3.0 **Usage** -``` + +```console clever env set [options] ``` **Arguments** -``` + +```console variable-name Name of the environment variable variable-value Value of the environment variable ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -1425,12 +1566,14 @@ variable-value Value of the environment variable **Since:** 3.11.0 **Usage** -``` + +```console clever features [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -1441,12 +1584,14 @@ clever features [options] **Since:** 3.11.0 **Usage** -``` + +```console clever features disable ``` **Arguments** -``` + +```console features Comma-separated list of experimental features to manage ``` @@ -1457,12 +1602,14 @@ features Comma-separated list of experimental features to manage **Since:** 3.11.0 **Usage** -``` + +```console clever features enable ``` **Arguments** -``` + +```console features Comma-separated list of experimental features to manage ``` @@ -1473,12 +1620,14 @@ features Comma-separated list of experimental features to manage **Since:** 3.11.0 **Usage** -``` + +```console clever features info ``` **Arguments** -``` + +```console feature Experimental feature to manage ``` @@ -1489,12 +1638,14 @@ feature Experimental feature to manage **Since:** 3.11.0 **Usage** -``` + +```console clever features list [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -1505,7 +1656,8 @@ clever features list [options] **Since:** 0.1.0 **Usage** -``` + +```console clever help ``` @@ -1516,7 +1668,8 @@ clever help **Since:** 4.3.0 **Usage** -``` + +```console clever k8s ``` @@ -1527,17 +1680,20 @@ clever k8s **Since:** 4.9.0 **Usage** -``` + +```console clever k8s activity [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) --limit Number of events to fetch (1 to 1000) (default: 50) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) @@ -1550,17 +1706,20 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 4.3.0 **Usage** -``` + +```console clever k8s add-persistent-storage [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -1571,17 +1730,20 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 4.3.0 **Usage** -``` + +```console clever k8s create [options] ``` **Arguments** -``` + +```console cluster-name Kubernetes cluster name ``` **Options** -``` + +```console --autoscaling Enable the cluster autoscaler --cluster-version Kubernetes version to deploy (e.g.: 1.36) --description Free-form cluster description @@ -1603,17 +1765,20 @@ cluster-name Kubernetes cluster name **Since:** 4.3.0 **Usage** -``` + +```console clever k8s delete [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) -y, --yes Skip confirmation prompts ``` @@ -1625,17 +1790,20 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 4.3.0 **Usage** -``` + +```console clever k8s get [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -1647,17 +1815,20 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 4.3.0 **Usage** -``` + +```console clever k8s get-kubeconfig [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -1668,12 +1839,14 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 4.3.0 **Usage** -``` + +```console clever k8s list [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -1685,7 +1858,8 @@ clever k8s list [options] **Since:** 4.9.0 **Usage** -``` + +```console clever k8s nodegroups ``` @@ -1696,19 +1870,22 @@ clever k8s nodegroups **Since:** 4.9.0 **Usage** -``` + +```console clever k8s nodegroups create [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name nodegroup-name Node group name (lowercase RFC 1123, max 63 chars) flavor:count Node group flavor and target node count (format: :, e.g.: XS:3) ``` **Options** -``` + +```console --autoscaling Enable cluster autoscaler for this node group (requires --min and --max) --description Free-form node group description --max Maximum node count when autoscaling is enabled @@ -1724,18 +1901,21 @@ flavor:count Node group flavor and target node count **Since:** 4.9.0 **Usage** -``` + +```console clever k8s nodegroups delete [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name nodegroup-id|nodegroup-name Kubernetes node group ID or name ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) -y, --yes Skip confirmation prompts ``` @@ -1747,18 +1927,21 @@ nodegroup-id|nodegroup-name Kubernetes node group ID or name **Since:** 4.9.0 **Usage** -``` + +```console clever k8s nodegroups get [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name nodegroup-id|nodegroup-name Kubernetes node group ID or name ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -1770,17 +1953,20 @@ nodegroup-id|nodegroup-name Kubernetes node group ID or name **Since:** 4.9.0 **Usage** -``` + +```console clever k8s nodegroups list [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -1792,18 +1978,21 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 4.9.0 **Usage** -``` + +```console clever k8s nodegroups update [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name nodegroup-id|nodegroup-name Kubernetes node group ID or name ``` **Options** -``` + +```console --autoscaling Enable the cluster autoscaler --count Target node count --description Free-form node group description @@ -1821,12 +2010,14 @@ nodegroup-id|nodegroup-name Kubernetes node group ID or name **Since:** 4.9.0 **Usage** -``` + +```console clever k8s quota [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -1838,17 +2029,20 @@ clever k8s quota [options] **Since:** 4.9.0 **Usage** -``` + +```console clever k8s update [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console --autoscaling Enable the cluster autoscaler --description Free-form cluster description --disable-autoscaling Disable the cluster autoscaler @@ -1864,17 +2058,20 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 4.9.0 **Usage** -``` + +```console clever k8s version [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -1886,17 +2083,20 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 4.9.0 **Usage** -``` + +```console clever k8s version check [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -1908,17 +2108,20 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 4.9.0 **Usage** -``` + +```console clever k8s version update [options] ``` **Arguments** -``` + +```console cluster-id|cluster-name Kubernetes cluster ID or name ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) --target Target version to upgrade to (e.g.: 24, 2.4, 2.4.1) ``` @@ -1930,12 +2133,14 @@ cluster-id|cluster-name Kubernetes cluster ID or name **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -1946,12 +2151,14 @@ clever keycloak [options] **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak disable-ng ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -1962,12 +2169,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak enable-ng ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -1978,17 +2187,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak get [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -1999,12 +2211,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak open ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2015,12 +2229,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak open logs ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2031,12 +2247,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak open webui ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2047,12 +2265,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak rebuild ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2063,12 +2283,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak restart ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2079,17 +2301,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak version [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -2100,17 +2325,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak version check [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -2121,17 +2349,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever keycloak version update [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console --target Target version to upgrade to (e.g.: 24, 2.4, 2.4.1) ``` @@ -2142,18 +2373,21 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.11.0 **Usage** -``` + +```console clever kv [options] ``` **Arguments** -``` + +```console kv-id|addon-id|addon-name Add-on/Real ID (or name, if unambiguous) of a Materia KV or Redis® add-on command The raw command to send to the Materia KV or Redis® add-on ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2165,17 +2399,20 @@ command The raw command to send to the Materia K **Since:** 0.2.0 **Usage** -``` + +```console clever link [options] ``` **Arguments** -``` + +```console app-id|app-name Application ID (or name, if unambiguous) ``` **Options** -``` + +```console -a, --alias Short name for the application -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2187,12 +2424,14 @@ app-id|app-name Application ID (or name, if unambiguous) **Since:** 0.2.0 **Usage** -``` + +```console clever login [options] ``` **Options** -``` + +```console -a, --alias Profile alias (default: default) --api-host API host URL override --auth-bridge-host Auth bridge URL override @@ -2211,12 +2450,14 @@ clever login [options] **Since:** 1.0.0 **Usage** -``` + +```console clever logout [options] ``` **Options** -``` + +```console -a, --alias Alias of the profile to log out ``` @@ -2227,12 +2468,14 @@ clever logout [options] **Since:** 0.2.0 **Usage** -``` + +```console clever logs [options] ``` **Options** -``` + +```console --addon Add-on ID or real ID --after, --since Fetch logs after this date/time (ISO8601 date, positive number in seconds or duration, e.g.: 1h) -a, --alias Short name for the application @@ -2250,12 +2493,14 @@ clever logs [options] **Since:** 0.5.0 **Usage** -``` + +```console clever make-default ``` **Arguments** -``` + +```console app-alias Application alias ``` @@ -2266,12 +2511,14 @@ app-alias Application alias **Since:** 3.13.0 **Usage** -``` + +```console clever matomo [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -2282,17 +2529,20 @@ clever matomo [options] **Since:** 3.13.0 **Usage** -``` + +```console clever matomo get [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -2303,12 +2553,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever matomo open ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2319,12 +2571,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever matomo open logs ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2335,12 +2589,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever matomo open webui ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2351,12 +2607,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever matomo rebuild ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2367,12 +2625,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever matomo restart ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2383,12 +2643,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever metabase [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -2399,17 +2661,20 @@ clever metabase [options] **Since:** 3.13.0 **Usage** -``` + +```console clever metabase get [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -2420,12 +2685,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever metabase open ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2436,12 +2703,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever metabase open logs ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2452,12 +2721,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever metabase open webui ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2468,12 +2739,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever metabase rebuild ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2484,12 +2757,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever metabase restart ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -2500,17 +2775,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever metabase version [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -2521,17 +2799,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever metabase version check [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -2542,17 +2823,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever metabase version update [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console --target Target version to upgrade to (e.g.: 24, 2.4, 2.4.1) ``` @@ -2563,12 +2847,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.12.0 **Usage** -``` + +```console clever ng [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2580,17 +2866,20 @@ clever ng [options] **Since:** 3.12.0 **Usage** -``` + +```console clever ng create [options] ``` **Arguments** -``` + +```console ng-label Network Group label ``` **Options** -``` + +```console --description Network Group description --link Comma separated list of members IDs to link to a Network Group (app_xxx, external_xxx, mysql_xxx, postgresql_xxx, redis_xxx, etc.) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) @@ -2604,19 +2893,22 @@ ng-label Network Group label **Since:** 3.12.0 **Usage** -``` + +```console clever ng create external [options] ``` **Arguments** -``` + +```console external-peer-label External peer label ng-id|ng-label Network Group ID or label public-key WireGuard public key of the external peer to link to a Network Group ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2627,17 +2919,20 @@ public-key WireGuard public key of the external pee **Since:** 3.12.0 **Usage** -``` + +```console clever ng delete [options] ``` **Arguments** -``` + +```console ng-id|ng-label Network Group ID or label ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2648,18 +2943,21 @@ ng-id|ng-label Network Group ID or label **Since:** 3.12.0 **Usage** -``` + +```console clever ng delete external [options] ``` **Arguments** -``` + +```console peer-id|peer-label External peer ID or label ng-id|ng-label Network Group ID or label ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2670,17 +2968,20 @@ ng-id|ng-label Network Group ID or label **Since:** 3.12.0 **Usage** -``` + +```console clever ng get [options] ``` **Arguments** -``` + +```console id|label ID or Label of a Network Group, a member or an (external) peer ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) --type Type of resource to look for (NetworkGroup, Member, CleverPeer, ExternalPeer) @@ -2693,18 +2994,21 @@ id|label ID or Label of a Network Group, a member **Since:** 3.12.0 **Usage** -``` + +```console clever ng get-config [options] ``` **Arguments** -``` + +```console peer-id|peer-label External peer ID or label ng-id|ng-label Network Group ID or label ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2715,18 +3019,21 @@ ng-id|ng-label Network Group ID or label **Since:** 3.12.0 **Usage** -``` + +```console clever ng link [options] ``` **Arguments** -``` + +```console id ID of a resource to (un)link to a Network Group ng-id|ng-label Network Group ID or label ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2737,17 +3044,20 @@ ng-id|ng-label Network Group ID or label **Since:** 3.12.0 **Usage** -``` + +```console clever ng search [options] ``` **Arguments** -``` + +```console id|label ID or Label of a Network Group, a member or an (external) peer ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) --type Type of resource to look for (NetworkGroup, Member, CleverPeer, ExternalPeer) @@ -2760,18 +3070,21 @@ id|label ID or Label of a Network Group, a member **Since:** 3.12.0 **Usage** -``` + +```console clever ng unlink [options] ``` **Arguments** -``` + +```console id ID of a resource to (un)link to a Network Group ng-id|ng-label Network Group ID or label ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2782,12 +3095,14 @@ ng-id|ng-label Network Group ID or label **Since:** 0.6.1 **Usage** -``` + +```console clever notify-email [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) --list-all List all notifications for your user or for an organisation with the '--org' option -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) @@ -2800,17 +3115,20 @@ clever notify-email [options] **Since:** 0.6.1 **Usage** -``` + +```console clever notify-email add --notify [options] ``` **Arguments** -``` + +```console name Notification name ``` **Options** -``` + +```console --notify Notify a user, a specific email address or the whole organisation (multiple values allowed, comma separated) (required) --event Restrict notifications to specific event types -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) @@ -2824,17 +3142,20 @@ name Notification name **Since:** 0.6.1 **Usage** -``` + +```console clever notify-email remove [options] ``` **Arguments** -``` + +```console notification-id Notification ID ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` @@ -2845,7 +3166,8 @@ notification-id Notification ID **Since:** 4.8.0 **Usage** -``` + +```console clever oauth-consumers ``` @@ -2856,17 +3178,20 @@ clever oauth-consumers **Since:** 4.8.0 **Usage** -``` + +```console clever oauth-consumers create [options] ``` **Arguments** -``` + +```console name Consumer name ``` **Options** -``` + +```console --base-url OAuth callback base URL -d, --description Consumer description -F, --format Output format (human, json) (default: human) @@ -2883,17 +3208,20 @@ name Consumer name **Since:** 4.8.0 **Usage** -``` + +```console clever oauth-consumers delete [options] ``` **Arguments** -``` + +```console consumer-key|consumer-name OAuth consumer key (or name, if unambiguous) ``` **Options** -``` + +```console -y, --yes Skip confirmation prompts ``` @@ -2904,17 +3232,20 @@ consumer-key|consumer-name OAuth consumer key (or name, if unambiguous) **Since:** 4.8.0 **Usage** -``` + +```console clever oauth-consumers get [options] ``` **Arguments** -``` + +```console consumer-key|consumer-name OAuth consumer key (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) --with-secret Include the consumer secret in the output ``` @@ -2926,12 +3257,14 @@ consumer-key|consumer-name OAuth consumer key (or name, if unambiguous) **Since:** 4.8.0 **Usage** -``` + +```console clever oauth-consumers list [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -2942,12 +3275,14 @@ clever oauth-consumers list [options] **Since:** 4.8.0 **Usage** -``` + +```console clever oauth-consumers open ``` **Arguments** -``` + +```console consumer-key|consumer-name OAuth consumer key (or name, if unambiguous) ``` @@ -2958,17 +3293,20 @@ consumer-key|consumer-name OAuth consumer key (or name, if unambiguous) **Since:** 4.8.0 **Usage** -``` + +```console clever oauth-consumers update [options] ``` **Arguments** -``` + +```console consumer-key|consumer-name OAuth consumer key (or name, if unambiguous) ``` **Options** -``` + +```console --base-url OAuth callback base URL -d, --description Consumer description -F, --format Output format (human, json) (default: human) @@ -2985,12 +3323,14 @@ consumer-key|consumer-name OAuth consumer key (or name, if unambiguous) **Since:** 0.5.0 **Usage** -``` + +```console clever open [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -3002,12 +3342,14 @@ clever open [options] **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -3018,12 +3360,14 @@ clever otoroshi [options] **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi disable-ng ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -3034,12 +3378,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi enable-ng ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -3050,17 +3396,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi get [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -3071,12 +3420,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 4.4.0 **Usage** -``` + +```console clever otoroshi get-config ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -3087,12 +3438,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi open ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -3103,12 +3456,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi open logs ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -3119,12 +3474,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 4.9.0 **Usage** -``` + +```console clever otoroshi open swaggerui ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -3135,12 +3492,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi open webui ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -3151,12 +3510,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi rebuild ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -3167,12 +3528,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi restart ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` @@ -3183,17 +3546,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi version [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -3204,17 +3570,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi version check [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -3225,17 +3594,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 3.13.0 **Usage** -``` + +```console clever otoroshi version update [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console --target Target version to upgrade to (e.g.: 24, 2.4, 2.4.1) ``` @@ -3246,12 +3618,14 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 0.10.1 **Usage** -``` + +```console clever profile [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -3262,12 +3636,14 @@ clever profile [options] **Since:** 4.6.0 **Usage** -``` + +```console clever profile list [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -3278,7 +3654,8 @@ clever profile list [options] **Since:** 3.11.0 **Usage** -``` + +```console clever profile open ``` @@ -3289,12 +3666,14 @@ clever profile open **Since:** 4.6.0 **Usage** -``` + +```console clever profile switch [options] ``` **Options** -``` + +```console -a, --alias Alias of the profile to switch to ``` @@ -3305,12 +3684,14 @@ clever profile switch [options] **Since:** 0.5.0 **Usage** -``` + +```console clever published-config [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -F, --format Output format (human, json, shell) (default: human) @@ -3324,12 +3705,14 @@ clever published-config [options] **Since:** 0.5.0 **Usage** -``` + +```console clever published-config import [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) --json Import variables as JSON (an array of { "name": "THE_NAME", "value": "THE_VALUE" } objects) @@ -3342,40 +3725,46 @@ clever published-config import [options] **Since:** 0.5.0 **Usage** -``` + +```console clever published-config rm [options] ``` **Arguments** -``` + +```console variable-name Name of the environment variable ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` ### published-config set -**Description:** Add or update a published configuration item named with the value +**Description:** Add or update a published configuration item named `` with the value `` **Since:** 0.5.0 **Usage** -``` + +```console clever published-config set [options] ``` **Arguments** -``` + +```console variable-name Name of the environment variable variable-value Value of the environment variable ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -3387,12 +3776,14 @@ variable-value Value of the environment variable **Since:** 0.4.0 **Usage** -``` + +```console clever restart [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) --commit Restart the application with a specific commit ID @@ -3409,12 +3800,14 @@ clever restart [options] **Since:** 0.4.0 **Usage** -``` + +```console clever scale [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) --build-flavor The size of the build instance, or 'disabled' if you want to disable dedicated build instances @@ -3433,12 +3826,14 @@ clever scale [options] **Since:** 0.5.0 **Usage** -``` + +```console clever service [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -F, --format Output format (human, json) (default: human) @@ -3454,17 +3849,20 @@ clever service [options] **Since:** 0.5.0 **Usage** -``` + +```console clever service link-addon [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -3476,17 +3874,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 0.5.0 **Usage** -``` + +```console clever service link-app [options] ``` **Arguments** -``` + +```console app-id|app-name Application ID (or name, if unambiguous) ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -3498,17 +3899,20 @@ app-id|app-name Application ID (or name, if unambiguous) **Since:** 0.5.0 **Usage** -``` + +```console clever service unlink-addon [options] ``` **Arguments** -``` + +```console addon-id|addon-name Add-on ID (or name, if unambiguous) ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -3520,17 +3924,20 @@ addon-id|addon-name Add-on ID (or name, if unambiguous) **Since:** 0.5.0 **Usage** -``` + +```console clever service unlink-app [options] ``` **Arguments** -``` + +```console app-id|app-name Application ID (or name, if unambiguous) ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -3542,12 +3949,14 @@ app-id|app-name Application ID (or name, if unambiguous) **Since:** 0.7.0 **Usage** -``` + +```console clever ssh [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -c, --command Execute a command on the remote instance and exit @@ -3561,12 +3970,14 @@ clever ssh [options] **Since:** 3.13.0 **Usage** -``` + +```console clever ssh-keys [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -3577,12 +3988,14 @@ clever ssh-keys [options] **Since:** 3.13.0 **Usage** -``` + +```console clever ssh-keys add ``` **Arguments** -``` + +```console ssh-key-name SSH key name ssh-key-path SSH public key path (.pub) ``` @@ -3594,7 +4007,8 @@ ssh-key-path SSH public key path (.pub) **Since:** 3.13.0 **Usage** -``` + +```console clever ssh-keys open ``` @@ -3605,12 +4019,14 @@ clever ssh-keys open **Since:** 3.13.0 **Usage** -``` + +```console clever ssh-keys remove ``` **Arguments** -``` + +```console ssh-key-name SSH key name ``` @@ -3621,12 +4037,14 @@ ssh-key-name SSH key name **Since:** 3.13.0 **Usage** -``` + +```console clever ssh-keys remove-all [options] ``` **Options** -``` + +```console -y, --yes Skip confirmation and remove all SSH keys directly ``` @@ -3637,12 +4055,14 @@ clever ssh-keys remove-all [options] **Since:** 0.2.0 **Usage** -``` + +```console clever status [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -F, --format Output format (human, json) (default: human) @@ -3655,12 +4075,14 @@ clever status [options] **Since:** 0.2.0 **Usage** -``` + +```console clever stop [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) ``` @@ -3672,12 +4094,14 @@ clever stop [options] **Since:** 2.3.0 **Usage** -``` + +```console clever tcp-redirs [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -F, --format Output format (human, json) (default: human) @@ -3690,12 +4114,14 @@ clever tcp-redirs [options] **Since:** 2.3.0 **Usage** -``` + +```console clever tcp-redirs add --namespace [options] ``` **Options** -``` + +```console --namespace Namespace in which the TCP redirection should be (required) -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) @@ -3708,12 +4134,14 @@ clever tcp-redirs add --namespace [options] **Since:** 2.3.0 **Usage** -``` + +```console clever tcp-redirs list-namespaces [options] ``` **Options** -``` + +```console -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) -F, --format Output format (human, json) (default: human) @@ -3726,17 +4154,20 @@ clever tcp-redirs list-namespaces [options] **Since:** 2.3.0 **Usage** -``` + +```console clever tcp-redirs remove --namespace [options] ``` **Arguments** -``` + +```console port port identifying the TCP redirection ``` **Options** -``` + +```console --namespace Namespace in which the TCP redirection should be (required) -a, --alias Short name for the application --app Application to manage by its ID (or name, if unambiguous) @@ -3744,17 +4175,19 @@ port port identifying the TCP redirection ## tokens -**Description:** Manage API tokens to query Clever Cloud API from https://api-bridge.clever-cloud.com +**Description:** Manage API tokens to query Clever Cloud API from **Since:** 3.12.0 **Usage** -``` + +```console clever tokens [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) ``` @@ -3765,17 +4198,20 @@ clever tokens [options] **Since:** 3.12.0 **Usage** -``` + +```console clever tokens create [options] ``` **Arguments** -``` + +```console api-token-name API token name ``` **Options** -``` + +```console -e, --expiration Duration until API token expiration (e.g.: 1h, 4d, 2w, 6M) (default: 1y) -F, --format Output format (human, json) (default: human) ``` @@ -3787,12 +4223,14 @@ api-token-name API token name **Since:** 3.12.0 **Usage** -``` + +```console clever tokens revoke ``` **Arguments** -``` + +```console api-token-id API token ID ``` @@ -3803,12 +4241,14 @@ api-token-id API token ID **Since:** 0.2.0 **Usage** -``` + +```console clever unlink ``` **Arguments** -``` + +```console app-alias Application alias ``` @@ -3819,7 +4259,8 @@ app-alias Application alias **Since:** 1.0.0 **Usage** -``` + +```console clever version ``` @@ -3830,12 +4271,14 @@ clever version **Since:** 0.6.0 **Usage** -``` + +```console clever webhooks [options] ``` **Options** -``` + +```console -F, --format Output format (human, json) (default: human) --list-all List all notifications for your user or for an organisation with the '--org' option -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) @@ -3848,18 +4291,21 @@ clever webhooks [options] **Since:** 0.6.0 **Usage** -``` + +```console clever webhooks add [options] ``` **Arguments** -``` + +```console name Notification name url Webhook URL ``` **Options** -``` + +```console --event Restrict notifications to specific event types --format Format of the body sent to the webhook ('raw', 'slack', 'gitter', or 'flowdock') (default: raw) -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) @@ -3873,21 +4319,24 @@ url Webhook URL **Since:** 0.6.0 **Usage** -``` + +```console clever webhooks remove [options] ``` **Arguments** -``` + +```console notification-id Notification ID ``` **Options** -``` + +```console -o, --org, --owner Organisation to target by its ID (or name, if unambiguous) ``` ## Clever Cloud complete documentation -For more comprehensive information about Clever Cloud, read the complete documentation: https://www.clever-cloud.com/developers/doc/ -Clever Cloud complete documentation is available in a LLM-optimized format: https://www.clever-cloud.com/developers/llms.txt +For more comprehensive information about Clever Cloud, read the complete documentation: +Clever Cloud complete documentation is available in a LLM-optimized format: diff --git a/content/doc/reference/products-support.md b/content/doc/reference/products-support.md index d67c590a7..7e8c469c0 100644 --- a/content/doc/reference/products-support.md +++ b/content/doc/reference/products-support.md @@ -16,7 +16,7 @@ This is a product matrix showing the services that are available with our Terraf ## Add-ons available on Terraform and K8S-Operator | Product | Terraform | K8S operator | -|-----------------|-----------|--------------| +| --------------- | --------- | ------------ | | Cellar | ✅ | | | Config Provider | ✅ | ✅ | | Elastic Stack | ✅ | ✅ | @@ -36,7 +36,7 @@ This is a product matrix showing the services that are available with our Terraf ## Runtimes available on Terraform and K8S-Operator | Product | Terraform | K8S operator | -|-------------|-----------|--------------| +| ----------- | --------- | ------------ | | .NET | ✅ | | | Docker | ✅ | | | FrankenPHP | ✅ | | diff --git a/content/doc/reference/reference-environment-variables.md b/content/doc/reference/reference-environment-variables.md index e913296de..8212c5bae 100644 --- a/content/doc/reference/reference-environment-variables.md +++ b/content/doc/reference/reference-environment-variables.md @@ -24,64 +24,64 @@ aliases: These are read-only variables that are generated for each scaler before they build and start your application. -| Name | Description | Example value | -|-----------------------|------------------------------|--------------------------------| -|[`INSTANCE_NUMBER`](/doc/develop/env-variables/#what-is-the-instance_number-variable-used-for "What is the INSTANCE_NUMBER variable used for?") | Allows your application to differentiate each running node on the application level. | 0, 1… | -|`INSTANCE_TYPE` | Whether this instance is a "build" instance or a "production" instance. | build, production | -|`INSTANCE_ID` | The ID of the current instance (scaler) of your application. It's unique for each instance of your application and changes every time you deploy it. | 518c8d8f-e304-4310-81e0-9c4237d55645 | -|`CC_PRETTY_INSTANCE_NAME` | The random generated string as instance pretty name using pokemon names. | Tiny rhyhorn | -|`APP_ID` | The ID of your Clever Cloud application | app_649a93d1-6677-44bc-aca7-6f46107d6e02 | -|`APP_HOME` | The absolute path to your application folder | /home/bas/app_649a93d1-6677-44bc-aca7-6f46107d6e02 | -|`CC_DEPLOYMENT_ID` | Internal id of current deployment | f7efaf04-1a63-45a1-8503-0de7c750ee48 | -|`CC_COMMIT_ID` | The id of the commit that's currently running | d88cd2ae1aaa91923ed2bd689d95d713b6f3f45f | -|`CC_REVERSE_PROXY_IPS` | A comma separated list of trusted IP addresses. You should only accept requests coming from these IP addresses. | x.y.z.z,x.y.z.z | -|`ELASTIC_APM_SERVICE_NAME` | Sets the name of your service/application in Elastic APM. Automatically defined when you have linked an Elastic APM service to your application. You can override it by defining it yourself | Your application's name conforming to Elastic APM naming convention | -|`CC_APP_NAME` | The customer defined application name | cloud-api-production | -|`PORT` | The mandatory port value is 8080 | 8080 | +| Name | Description | Example value | +| ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| [`INSTANCE_NUMBER`](/doc/develop/env-variables/#what-is-the-instance_number-variable-used-for "What is the INSTANCE_NUMBER variable used for?") | Allows your application to differentiate each running node on the application level. | 0, 1… | +| `INSTANCE_TYPE` | Whether this instance is a "build" instance or a "production" instance. | build, production | +| `INSTANCE_ID` | The ID of the current instance (scaler) of your application. It's unique for each instance of your application and changes every time you deploy it. | 518c8d8f-e304-4310-81e0-9c4237d55645 | +| `CC_PRETTY_INSTANCE_NAME` | The random generated string as instance pretty name using pokemon names. | Tiny rhyhorn | +| `APP_ID` | The ID of your Clever Cloud application | app_649a93d1-6677-44bc-aca7-6f46107d6e02 | +| `APP_HOME` | The absolute path to your application folder | /home/bas/app_649a93d1-6677-44bc-aca7-6f46107d6e02 | +| `CC_DEPLOYMENT_ID` | Internal id of current deployment | f7efaf04-1a63-45a1-8503-0de7c750ee48 | +| `CC_COMMIT_ID` | The id of the commit that's currently running | d88cd2ae1aaa91923ed2bd689d95d713b6f3f45f | +| `CC_REVERSE_PROXY_IPS` | A comma separated list of trusted IP addresses. You should only accept requests coming from these IP addresses. | x.y.z.z,x.y.z.z | +| `ELASTIC_APM_SERVICE_NAME` | Sets the name of your service/application in Elastic APM. Automatically defined when you have linked an Elastic APM service to your application. You can override it by defining it yourself | Your application's name conforming to Elastic APM naming convention | +| `CC_APP_NAME` | The customer defined application name | cloud-api-production | +| `PORT` | The mandatory port value is 8080 | 8080 | ### Variables you can define So you can alter the build&start process for your application. -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|`APP_FOLDER` | Folder in which the application is located (inside the git repository) | | -|`CC_DISABLE_JVM_AGENT` | Disable JVM agent activation | | -|`CC_GIT_FULL_CLONE` | If set to `false`, the git repository is cloned with `--depth 1` to speed up the deployment | true | -|`CC_DISABLE_GIT_SUBMODULES` | Disable Git submodules initialization & synchronization | | -|`CC_PREVENT_LOGSCOLLECTION` | Disable Vector service used to collect and send logs | `false`| -|[`CC_HEALTH_CHECK_PATH`](/doc/develop/healthcheck) | Custom path to validate your application deployment | | -|`CC_SSH_PRIVATE_KEY` | A ssh private key to setup for the user running your application | | -|`CC_SSH_PRIVATE_KEY_FILE` | The name to use for the file containing the private ssh key | id_ed25519 | -|`CC_WORKER_RESTART` | One of `always`, `on-failure` or `no`. Control whether workers need to be restarted when they exit. This setting controls all workers. | on-failure | -|`CC_WORKER_RESTART_DELAY` | Define a delay in seconds to restart the worker when they exit. | 1 | -|[`CC_WORKER_COMMAND`](/doc/develop/workers) | Command to run in background as a worker process. You can run multiple workers. | | +| Name | Description | Default value | +| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `APP_FOLDER` | Folder in which the application is located (inside the git repository) | | +| `CC_DISABLE_JVM_AGENT` | Disable JVM agent activation | | +| `CC_GIT_FULL_CLONE` | If set to `false`, the git repository is cloned with `--depth 1` to speed up the deployment | true | +| `CC_DISABLE_GIT_SUBMODULES` | Disable Git submodules initialization & synchronization | | +| `CC_PREVENT_LOGSCOLLECTION` | Disable Vector service used to collect and send logs | `false` | +| [`CC_HEALTH_CHECK_PATH`](/doc/develop/healthcheck) | Custom path to validate your application deployment | | +| `CC_SSH_PRIVATE_KEY` | A ssh private key to setup for the user running your application | | +| `CC_SSH_PRIVATE_KEY_FILE` | The name to use for the file containing the private ssh key | id_ed25519 | +| `CC_WORKER_RESTART` | One of `always`, `on-failure` or `no`. Control whether workers need to be restarted when they exit. This setting controls all workers. | on-failure | +| `CC_WORKER_RESTART_DELAY` | Define a delay in seconds to restart the worker when they exit. | 1 | +| [`CC_WORKER_COMMAND`](/doc/develop/workers) | Command to run in background as a worker process. You can run multiple workers. | | You can set some tools' version in any runtime (except Docker): -| Name | Description | -|------|-------------| -| `CC_HUGO_VERSION` | Set the Hugo version, for example `0.161` | | -| `CC_NODE_VERSION` | Set Node.js version, for example `24`, `23.11` or `22.15.1` | | +| Name | Description | +| ----------------- | ----------------------------------------------------------- | +| `CC_HUGO_VERSION` | Set the Hugo version, for example `0.161` | +| `CC_NODE_VERSION` | Set Node.js version, for example `24`, `23.11` or `22.15.1` | #### Control build and dependencies cache -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|`CC_CACHE_DEPENDENCIES` | Enable caching of your build dependencies to speed up following builds. | false | -|`CC_CACHE_DEPENDENCIES_EXTRA_PATHS` | Add custom paths to the dependencies cache. Expected format: Colon-separated PATH-style string. Paths are considered relative to APP_HOME. One level of `../` is allowed. E.g. `../.cargo:lib:vendor` will select `/home/bas/.cargo`, `/home/bas/{app_id}/lib` and `/home/bas/{app_id}/vendor` | | -|[`CC_DISABLE_BUILD_CACHE_UPLOAD`](/doc/develop/env-variables/#settings-you-can-define-using-environment-variables "Settings you can define using environment variables") | Disable creation and upload of cache archive. Restarts won't be speeded up. | `false` | -|[`CC_IGNORE_FROM_BUILDCACHE`](/doc/develop/env-variables/#settings-you-can-define-using-environment-variables "Settings you can define using environment variables") | Allows to specify paths to ignore when the build cache archive is created. | | -|[`IGNORE_FROM_BUILDCACHE`](/doc/develop/env-variables/#settings-you-can-define-using-environment-variables "Settings you can define using environment variables") | (Deprecated) Allows to specify paths to ignore when the build cache archive is created. | | -|[`CC_OVERRIDE_BUILDCACHE`](/doc/develop/env-variables/#settings-you-can-define-using-environment-variables "Settings you can define using environment variables") | Allows to specify paths that will be in the build cache. Only those files / directories will be cached | | +| Name | Description | Default value | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `CC_CACHE_DEPENDENCIES` | Enable caching of your build dependencies to speed up following builds. | false | +| `CC_CACHE_DEPENDENCIES_EXTRA_PATHS` | Add custom paths to the dependencies cache. Expected format: Colon-separated PATH-style string. Paths are considered relative to APP_HOME. One level of `../` is allowed. E.g. `../.cargo:lib:vendor` will select `/home/bas/.cargo`, `/home/bas/{app_id}/lib` and `/home/bas/{app_id}/vendor` | | +| [`CC_DISABLE_BUILD_CACHE_UPLOAD`](/doc/develop/env-variables/#settings-you-can-define-using-environment-variables "Settings you can define using environment variables") | Disable creation and upload of cache archive. Restarts won't be speeded up. | `false` | +| [`CC_IGNORE_FROM_BUILDCACHE`](/doc/develop/env-variables/#settings-you-can-define-using-environment-variables "Settings you can define using environment variables") | Allows to specify paths to ignore when the build cache archive is created. | | +| [`IGNORE_FROM_BUILDCACHE`](/doc/develop/env-variables/#settings-you-can-define-using-environment-variables "Settings you can define using environment variables") | (Deprecated) Allows to specify paths to ignore when the build cache archive is created. | | +| [`CC_OVERRIDE_BUILDCACHE`](/doc/develop/env-variables/#settings-you-can-define-using-environment-variables "Settings you can define using environment variables") | Allows to specify paths that will be in the build cache. Only those files / directories will be cached | | #### Control the deployment's behavior -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|`CC_RUN_COMMAND` | Custom command to run your application. | | -|`CC_TASK` | If set to true, the deployer runs `CC_RUN_COMMAND` and terminates the instance after running the task. Trigger an execution using `git push` or starting your instance | false | -|[`CC_TROUBLESHOOT`](/doc/find-help/troubleshooting "Troubleshooting") | Enable debug log level, will also keep the VM up after failure for 15 minutes so you can SSH and debug. Don't forget to cancel deployment if you push a new commit. | false | +| Name | Description | Default value | +| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `CC_RUN_COMMAND` | Custom command to run your application. | | +| `CC_TASK` | If set to true, the deployer runs `CC_RUN_COMMAND` and terminates the instance after running the task. Trigger an execution using `git push` or starting your instance | false | +| [`CC_TROUBLESHOOT`](/doc/find-help/troubleshooting "Troubleshooting") | Enable debug log level, will also keep the VM up after failure for 15 minutes so you can SSH and debug. Don't forget to cancel deployment if you push a new commit. | false | {{< callout emoji="🐳" >}} `CC_RUN_COMMAND` has no effect on Docker. To run Docker, use `CMD` in your [Dockerfile](/doc/applications/docker/#dockerized-rust-application-deployment). @@ -91,38 +91,38 @@ You can set some tools' version in any runtime (except Docker): Use these to define [commands to run](/doc/develop/build-hooks) between various steps of the deployment. -| Name | Description | -|-----------------------|------------------------------| -|[`CC_PRE_BUILD_HOOK`](/doc/develop/build-hooks/#pre-build "Pre build hook") | Ran before the dependencies are fetched. If it fails, the deployment fails. | -|[`CC_POST_BUILD_HOOK`](/doc/develop/build-hooks/#post-build "Post build hook") | Ran after the project is built, and before the cache archive is generated. If it fails, the deployment fails. | -|[`CC_PRE_RUN_HOOK`](/doc/develop/build-hooks/#pre-run "Pre run hook") | Ran before the application is started, but after the cache archive has been generated. If it fails, the deployment fails. | -|[`CC_RUN_FAILED_HOOK`](/doc/develop/build-hooks/#run-successfail "Run succeeded/failed hook") | Ran once the application has failed to start. | -|[`CC_RUN_SUCCEEDED_HOOK`](/doc/develop/build-hooks/#run-successfail "Run succeeded/failed hook" )| Ran once the application has started successfuly. | +| Name | Description | +| ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| [`CC_PRE_BUILD_HOOK`](/doc/develop/build-hooks/#pre-build "Pre build hook") | Ran before the dependencies are fetched. If it fails, the deployment fails. | +| [`CC_POST_BUILD_HOOK`](/doc/develop/build-hooks/#post-build "Post build hook") | Ran after the project is built, and before the cache archive is generated. If it fails, the deployment fails. | +| [`CC_PRE_RUN_HOOK`](/doc/develop/build-hooks/#pre-run "Pre run hook") | Ran before the application is started, but after the cache archive has been generated. If it fails, the deployment fails. | +| [`CC_RUN_FAILED_HOOK`](/doc/develop/build-hooks/#run-successfail "Run succeeded/failed hook") | Ran once the application has failed to start. | +| [`CC_RUN_SUCCEEDED_HOOK`](/doc/develop/build-hooks/#run-successfail "Run succeeded/failed hook" ) | Ran once the application has started successfuly. | #### Configure extra software -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|[`CC_CLAMAV`](/doc/administrate/clamav "Clamav") | Start the clamav and clamav-freshclam services (the database is updated every 2 hours). WARNING: Clamscan consumes a lot of resources (~ 1GB of memory), make sure you have a scaler with enough memory to avoid OOM. | false | -|[`CC_CLAMAV_MAXQUEUE`](/doc/administrate/clamav "Clamav") | Maximum number of queued items. | 100 | -|[`CC_CLAMAV_MAXTHREADS`](/doc/administrate/clamav "Clamav") | Maximum number of threads running at the same time. | 10 | -|[`CC_METRICS_PROMETHEUS_PASSWORD`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the password for the basic auth of the Prometheus endpoint | | -|[`CC_METRICS_PROMETHEUS_PATH`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the path on which the Prometheus endpoint is available | /metrics | -|[`CC_METRICS_PROMETHEUS_PORT`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the port on which the Prometheus endpoint is available | 9100 | -|[`CC_METRICS_PROMETHEUS_RESPONSE_TIMEOUT`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the timeout in seconds to collect the application metrics. This value **must** be below 60 seconds as data are collected every minutes | 3 | -|[`CC_METRICS_PROMETHEUS_USER`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the user for the basic auth of the Prometheus endpoint | | -|[`CC_REQUEST_FLOW`](/doc/develop/request-flow "Request Flow") | Comma-separated list of middleware to chain between the public port and your application (`block`, `custom`, `oauth2-proxy`, `otoroshi-challenge`, `redirectionio`, `varnish`). Special values: `disable`, `block` | | -|[`CC_REQUEST_FLOW_CUSTOM`](/doc/develop/request-flow/#custom-middleware "Request Flow") | Command starting a custom middleware, with the `@@LISTEN_PORT@@` and `@@FORWARD_PORT@@` placeholders | | -|[`CC_VARNISH_FILE`](/doc/develop/varnish "Cache") | The path to the Varnish configuration file, relative to your application root | `/clevercloud/varnish.vcl` | -|[`CC_VARNISH_STORAGE_SIZE`](/doc/develop/varnish "Cache") | Configure the size of the Varnish cache. | 1G | -|[`CC_WORKER_COMMAND`](/doc/develop/workers "Workers") | Command to run in background as a worker process. You can run multiple workers. | | +| Name | Description | Default value | +| ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| [`CC_CLAMAV`](/doc/administrate/clamav "Clamav") | Start the clamav and clamav-freshclam services (the database is updated every 2 hours). WARNING: Clamscan consumes a lot of resources (~ 1GB of memory), make sure you have a scaler with enough memory to avoid OOM. | false | +| [`CC_CLAMAV_MAXQUEUE`](/doc/administrate/clamav "Clamav") | Maximum number of queued items. | 100 | +| [`CC_CLAMAV_MAXTHREADS`](/doc/administrate/clamav "Clamav") | Maximum number of threads running at the same time. | 10 | +| [`CC_METRICS_PROMETHEUS_PASSWORD`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the password for the basic auth of the Prometheus endpoint | | +| [`CC_METRICS_PROMETHEUS_PATH`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the path on which the Prometheus endpoint is available | /metrics | +| [`CC_METRICS_PROMETHEUS_PORT`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the port on which the Prometheus endpoint is available | 9100 | +| [`CC_METRICS_PROMETHEUS_RESPONSE_TIMEOUT`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the timeout in seconds to collect the application metrics. This value **must** be below 60 seconds as data are collected every minutes | 3 | +| [`CC_METRICS_PROMETHEUS_USER`](/doc/metrics/#publish-your-own-metrics "Publish your own metrics") | Define the user for the basic auth of the Prometheus endpoint | | +| [`CC_REQUEST_FLOW`](/doc/develop/request-flow "Request Flow") | Comma-separated list of middleware to chain between the public port and your application (`block`, `custom`, `oauth2-proxy`, `otoroshi-challenge`, `redirectionio`, `varnish`). Special values: `disable`, `block` | | +| [`CC_REQUEST_FLOW_CUSTOM`](/doc/develop/request-flow/#custom-middleware "Request Flow") | Command starting a custom middleware, with the `@@LISTEN_PORT@@` and `@@FORWARD_PORT@@` placeholders | | +| [`CC_VARNISH_FILE`](/doc/develop/varnish "Cache") | The path to the Varnish configuration file, relative to your application root | `/clevercloud/varnish.vcl` | +| [`CC_VARNISH_STORAGE_SIZE`](/doc/develop/varnish "Cache") | Configure the size of the Varnish cache. | 1G | +| [`CC_WORKER_COMMAND`](/doc/develop/workers "Workers") | Command to run in background as a worker process. You can run multiple workers. | | {{% content "mise" %}} -| Name | Description | Default value | -|-----------------|--------------------------|--------------------------------| -|`CC_DISABLE_MISE`| Set to `true` to disable Mise | | -|`CC_MISE_FILE_PATH`| Path to the `mise.toml` file, relative to your application root | `mise.toml` | +| Name | Description | Default value | +| ------------------- | --------------------------------------------------------------- | ------------- | +| `CC_DISABLE_MISE` | Set to `true` to disable Mise | | +| `CC_MISE_FILE_PATH` | Path to the `mise.toml` file, relative to your application root | `mise.toml` | {{% content "redirectionio" %}} > [!NOTE] Redirection.io is not available in Docker and PHP applications @@ -133,12 +133,12 @@ Use these to define [commands to run](/doc/develop/build-hooks) between various Note that `Reusable keys` are required to use multiple instances. You can [generate one here](https://login.tailscale.com/admin/settings/keys "Generate tailscale key"). -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -| [`TAILSCALE_ACCEPT_DNS`](https://tailscale.com/kb/1072/client-preferences#use-tailscale-dns-settings) | Tailscale use its default DNS settings | `true` | -| [`TAILSCALE_ACCEPT_ROUTES`](https://tailscale.com/kb/1072/client-preferences#use-tailscale-subnets) | Tailscale uses its subnets settings | `false` | -| [`TAILSCALE_AUTH_KEY`](https://tailscale.com/ "tailscale.com") | Contains your Tailscale Auth key | | -| `TAILSCALE_LOGIN_SERVER`| Contains the login server | | +| Name | Description | Default value | +| ----------------------------------------------------------------------------------------------------- | -------------------------------------- | ------------- | +| [`TAILSCALE_ACCEPT_DNS`](https://tailscale.com/kb/1072/client-preferences#use-tailscale-dns-settings) | Tailscale use its default DNS settings | `true` | +| [`TAILSCALE_ACCEPT_ROUTES`](https://tailscale.com/kb/1072/client-preferences#use-tailscale-subnets) | Tailscale uses its subnets settings | `false` | +| [`TAILSCALE_AUTH_KEY`](https://tailscale.com/ "tailscale.com") | Contains your Tailscale Auth key | | +| `TAILSCALE_LOGIN_SERVER` | Contains the login server | | #### How it works? @@ -150,108 +150,108 @@ If `TAILSCALE_LOGIN_SERVER` is provided, the agent will be configured to reach a [Docker Documentation](/doc/applications/docker) -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|`CC_DOCKERFILE` | The name of the Dockerfile to build. | Dockerfile | -|`CC_DOCKER_BUILDX` | Set to `false` to use Docker legacy build | true | -|`CC_DOCKER_EXPOSED_HTTP_PORT` | Set to custom HTTP port if your Docker container runs on custom port. | 8080 | -|`CC_DOCKER_EXPOSED_TCP_PORT` | Set to custom TCP port if your Docker container runs on custom port. | 4040 | -|`CC_DOCKER_FIXED_CIDR_V6` | Activate the support of IPv6 with an IPv6 subnet int the docker daemon. | | -|`CC_DOCKER_LOGIN_PASSWORD` | The password of your username. | | -|`CC_DOCKER_LOGIN_SERVER` | The server of your private registry (optional). | Docker’s public registry | -|`CC_DOCKER_LOGIN_USERNAME` | The username to login to a private registry. | | -|`CC_MOUNT_DOCKER_SOCKET` | Set to true to access the host Docker socket from inside your container. | false | +| Name | Description | Default value | +| ----------------------------- | ------------------------------------------------------------------------ | ------------------------ | +| `CC_DOCKERFILE` | The name of the Dockerfile to build. | Dockerfile | +| `CC_DOCKER_BUILDX` | Set to `false` to use Docker legacy build | true | +| `CC_DOCKER_EXPOSED_HTTP_PORT` | Set to custom HTTP port if your Docker container runs on custom port. | 8080 | +| `CC_DOCKER_EXPOSED_TCP_PORT` | Set to custom TCP port if your Docker container runs on custom port. | 4040 | +| `CC_DOCKER_FIXED_CIDR_V6` | Activate the support of IPv6 with an IPv6 subnet int the docker daemon. | | +| `CC_DOCKER_LOGIN_PASSWORD` | The password of your username. | | +| `CC_DOCKER_LOGIN_SERVER` | The server of your private registry (optional). | Docker’s public registry | +| `CC_DOCKER_LOGIN_USERNAME` | The username to login to a private registry. | | +| `CC_MOUNT_DOCKER_SOCKET` | Set to true to access the host Docker socket from inside your container. | false | ## .NET [.NET Documentation](/doc/applications/dotnet) -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|`CC_DOTNET_PROFILE` | Override the build configuration settings in your project. | Release | -|`CC_DOTNET_PROJ` | The name of your project file to use for the build, without the .csproj / .fsproj / .vbproj extension. | | -|`CC_DOTNET_TFM` | Compiles for a specific framework. The framework must be defined in the project file. Example : `net5.0` | | -|`CC_DOTNET_VERSION` | Choose the .NET Core version between `6.0`,`8.0`, `9.0`. | 8.0 | -|`CC_RUN_COMMAND` | Custom command to run your application. | | +| Name | Description | Default value | +| ------------------- | -------------------------------------------------------------------------------------------------------- | ------------- | +| `CC_DOTNET_PROFILE` | Override the build configuration settings in your project. | Release | +| `CC_DOTNET_PROJ` | The name of your project file to use for the build, without the .csproj / .fsproj / .vbproj extension. | | +| `CC_DOTNET_TFM` | Compiles for a specific framework. The framework must be defined in the project file. Example : `net5.0` | | +| `CC_DOTNET_VERSION` | Choose the .NET Core version between `6.0`,`8.0`, `9.0`. | 8.0 | +| `CC_RUN_COMMAND` | Custom command to run your application. | | ## Elixir [Elixir Documentation](/doc/applications/elixir) - | Name | Description | Default value | - |-----------------------|------------------------------|--------------------------------| - |`CC_ELIXIR_VERSION` | Choose the Elixir version among [those supported](/doc/applications/elixir/#mandatory-configuration) | | - |`CC_MIX_BUILD_GOAL` | The mix goal to build the application (default compile) | | - |`CC_PHOENIX_ASSETS_DIR` | Folder in which your Phoenix assets are located. | | - |`CC_PHOENIX_DIGEST_GOAL` | Phoenix digest goal. | phx.digest | - |`CC_PHOENIX_RUN_ECTO_MIGRATE` | Whether to run 'mix ecto.migrate' or not. | true | - |`CC_PHOENIX_SERVER_GOAL` | Phoenix server goal. | phx.server | - |`CC_RUN_COMMAND` | Custom command to run your application. Replaces the default behaviour. | | + | Name | Description | Default value | + | ----------------------------- | ---------------------------------------------------------------------------------------------------- | ------------- | + | `CC_ELIXIR_VERSION` | Choose the Elixir version among [those supported](/doc/applications/elixir/#mandatory-configuration) | | + | `CC_MIX_BUILD_GOAL` | The mix goal to build the application (default compile) | | + | `CC_PHOENIX_ASSETS_DIR` | Folder in which your Phoenix assets are located. | | + | `CC_PHOENIX_DIGEST_GOAL` | Phoenix digest goal. | phx.digest | + | `CC_PHOENIX_RUN_ECTO_MIGRATE` | Whether to run 'mix ecto.migrate' or not. | true | + | `CC_PHOENIX_SERVER_GOAL` | Phoenix server goal. | phx.server | + | `CC_RUN_COMMAND` | Custom command to run your application. Replaces the default behaviour. | | ## FrankenPHP [FrankenPHP Documentation](/doc/applications/frankenphp) -| Name | Description | Default value | -|---------------|-------------| ---------------| -| `CC_FRANKENPHP_PORT` | The port on which FrankenPHP listens for HTTP requests | `8080` | -| `CC_FRANKENPHP_WORKER` | Path to the worker script, relative to the root of your project (e.g. `/worker/script.php`) | | -| `CC_PHP_COMPOSER_FLAGS` | Flags to pass to Composer | `-n --no-dev --no-progress --no-scripts` | -| `CC_PHP_DEV_DEPENDENCIES` | Set to `install` to install PHP development dependencies during build | | -| `CC_WEBROOT` | Path to the web content to serve, relative to the root of your application | `/` | +| Name | Description | Default value | +| ------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------- | +| `CC_FRANKENPHP_PORT` | The port on which FrankenPHP listens for HTTP requests | `8080` | +| `CC_FRANKENPHP_WORKER` | Path to the worker script, relative to the root of your project (e.g. `/worker/script.php`) | | +| `CC_PHP_COMPOSER_FLAGS` | Flags to pass to Composer | `-n --no-dev --no-progress --no-scripts` | +| `CC_PHP_DEV_DEPENDENCIES` | Set to `install` to install PHP development dependencies during build | | +| `CC_WEBROOT` | Path to the web content to serve, relative to the root of your application | `/` | ## Go [Go Documentation](/doc/applications/golang) -| Name | Description | -| :------- | :---- | +| Name | Description | +| :----------------- | :---------------------------------------------------------------------------------------------------------------- | | `CC_GO_BUILD_TOOL` | Available values: `gomod`, `gobuild`. Build and install your application. `goget` still exists but is deprecated. | -| `CC_GO_RUNDIR` | Run the application from the specified path, relative to `$GOPATH/src/`, now deprecated. | -| `CC_GO_PKG` | Tell the `CC_GO_BUILD_TOOL` which file contains the `main()` function, default `main.go`. | +| `CC_GO_RUNDIR` | Run the application from the specified path, relative to `$GOPATH/src/`, now deprecated. | +| `CC_GO_PKG` | Tell the `CC_GO_BUILD_TOOL` which file contains the `main()` function, default `main.go`. | ## Haskell [Haskell Documentation](/doc/applications/haskell) -| Name | Description | -|-----------------------|------------------------------| -|[`CC_HASKELL_STACK_TARGET`](/doc/applications/haskell/#specify-stack-package-target "Specify Stack package target") | Specify Stack package target. | -|`CC_HASKELL_STACK_SETUP_COMMAND` | Only use this variable to override the default `setup` Stack step command | -|`CC_HASKELL_STACK_INSTALL_COMMAND` | Only use this variable to override the default `install` Stack step command | -|`CC_HASKELL_STACK_INSTALL_DEPENDENCIES_COMMAND` | Only use this variable to override the default `install --only-dependencies` Stack step command | -|`CC_RUN_COMMAND` | Custom command to run your application. | +| Name | Description | +| ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | +| [`CC_HASKELL_STACK_TARGET`](/doc/applications/haskell/#specify-stack-package-target "Specify Stack package target") | Specify Stack package target. | +| `CC_HASKELL_STACK_SETUP_COMMAND` | Only use this variable to override the default `setup` Stack step command | +| `CC_HASKELL_STACK_INSTALL_COMMAND` | Only use this variable to override the default `install` Stack step command | +| `CC_HASKELL_STACK_INSTALL_DEPENDENCIES_COMMAND` | Only use this variable to override the default `install --only-dependencies` Stack step command | +| `CC_RUN_COMMAND` | Custom command to run your application. | ## Java / Scala - [Java Documentation](/doc/applications/java) - [Scala Documentation](/doc/applications/scala) -| Name | Description | Default value | -|------|-------------|---------------| -|`CC_DISABLE_MAX_METASPACE` | Allows to disable the Java option `-XX:MaxMetaspaceSize` | | -|`CC_EXTRA_JAVA_ARGS` | Define extra arguments to pass to `java` for JAR | | -|`CC_JAR_ARGS` | Define arguments to pass to the launched JAR | | -|`CC_JAR_PATH` | Define the path to your JAR | | -|`CC_JAVA_VERSION` | Choose the JVM version between for OpenJDK or `graalvm-ce` for GraalVM | 21 | -|`CC_MAVEN_PROFILES` | Define which Maven profile to use during default build | | -|`CC_RUN_COMMAND` | Custom command to run your application. Replaces the default behavior | | -|`CC_SBT_TARGET_BIN` | Define the bin to pick in the `CC_SBT_TARGET_DIR`. The first bin found in the `CC_SBT_TARGET_DIR` | -|`CC_SBT_TARGET_DIR` | Define the folder the `target` dir is in. `/target/universal/stage/bin` is concatenated to the given directory | `.` | -|`GRADLE_DEPLOY_GOAL` | Define which Gradle goals to run during build | | -|`MAVEN_DEPLOY_GOAL` | Define which Maven goals to run during build | | -|`NUDGE_APPID` | | | -|`PLAY1_VERSION` | Define which play1 version to use between `1.2`, `1.3`, `1.4` and `1.5` | | -|`SBT_DEPLOY_GOAL` | Define which SBT goals to run during build | stage | +| Name | Description | Default value | +| -------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------- | +| `CC_DISABLE_MAX_METASPACE` | Allows to disable the Java option `-XX:MaxMetaspaceSize` | | +| `CC_EXTRA_JAVA_ARGS` | Define extra arguments to pass to `java` for JAR | | +| `CC_JAR_ARGS` | Define arguments to pass to the launched JAR | | +| `CC_JAR_PATH` | Define the path to your JAR | | +| `CC_JAVA_VERSION` | Choose the JVM version between for OpenJDK or `graalvm-ce` for GraalVM | 21 | +| `CC_MAVEN_PROFILES` | Define which Maven profile to use during default build | | +| `CC_RUN_COMMAND` | Custom command to run your application. Replaces the default behavior | | +| `CC_SBT_TARGET_BIN` | Define the bin to pick in the `CC_SBT_TARGET_DIR`. The first bin found in the `CC_SBT_TARGET_DIR` | | +| `CC_SBT_TARGET_DIR` | Define the folder the `target` dir is in. `/target/universal/stage/bin` is concatenated to the given directory | `.` | +| `GRADLE_DEPLOY_GOAL` | Define which Gradle goals to run during build | | +| `MAVEN_DEPLOY_GOAL` | Define which Maven goals to run during build | | +| `NUDGE_APPID` | | | +| `PLAY1_VERSION` | Define which play1 version to use between `1.2`, `1.3`, `1.4` and `1.5` | | +| `SBT_DEPLOY_GOAL` | Define which SBT goals to run during build | stage | ## Linux [Linux Documentation](/doc/applications/linux) -| Name | Description | Default value | -|------|-------------|---------------| -| `CC_BUILD_COMMAND` | The command to run during the build phase | `` | -| `CC_RUN_COMMAND` | The command to run during the run phase | `` | +| Name | Description | Default value | +| ------------------ | ----------------------------------------- | ------------- | +| `CC_BUILD_COMMAND` | The command to run during the build phase | `` | +| `CC_RUN_COMMAND` | The command to run during the run phase | `` | Use Linux runtime with [Mise package manager](#install-tools-with-mise-package-manager) to install your dependencies easily @@ -259,92 +259,92 @@ Use Linux runtime with [Mise package manager](#install-tools-with-mise-package-m [Node.js Documentation](/doc/applications/nodejs) -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|[`CC_NODE_VERSION`](/doc/applications/nodejs#set-nodejs-version)| Set Node.js version, for example `24`, `23.11` or `22.15.1` | | -|`CC_NODE_DEV_DEPENDENCIES` | Control if development dependencies are installed or not. Values are either `install` or `ignore` | `ignore` | -|`CC_RUN_COMMAND` | Define a custom command. Example for Meteor: `node .build/bundle/main.js ` | | -|`CC_NODE_BUILD_TOOL` | Choose your build tool between bun, npm, npm-ci, pnpm, yarn, yarn2, yarn-berry and custom | npm | -|`CC_CUSTOM_BUILD_TOOL`| A custom command to run (with `CC_NODE_BUILD_TOOL` set to `custom`) | | -|`CC_NPM_REGISTRY` | The host of your private repository, available values: `github` or the registry host. | registry.npmjs.org | -|`CC_NPM_BASIC_AUTH`| Private repository credentials, in the form `user:password`. You can't use this if `CC_NPM_TOKEN` is set | | -|`NPM_TOKEN` | Private repository token | | +| Name | Description | Default value | +| ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------ | +| [`CC_NODE_VERSION`](/doc/applications/nodejs#set-nodejs-version) | Set Node.js version, for example `24`, `23.11` or `22.15.1` | | +| `CC_NODE_DEV_DEPENDENCIES` | Control if development dependencies are installed or not. Values are either `install` or `ignore` | `ignore` | +| `CC_RUN_COMMAND` | Define a custom command. Example for Meteor: `node .build/bundle/main.js ` | | +| `CC_NODE_BUILD_TOOL` | Choose your build tool between bun, npm, npm-ci, pnpm, yarn, yarn2, yarn-berry and custom | npm | +| `CC_CUSTOM_BUILD_TOOL` | A custom command to run (with `CC_NODE_BUILD_TOOL` set to `custom`) | | +| `CC_NPM_REGISTRY` | The host of your private repository, available values: `github` or the registry host. | registry.npmjs.org | +| `CC_NPM_BASIC_AUTH` | Private repository credentials, in the form `user:password`. You can't use this if `CC_NPM_TOKEN` is set | | +| `NPM_TOKEN` | Private repository token | | ## PHP [PHP Documentation](/doc/applications/php) -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|`ALWAYS_POPULATE_RAW_POST_DATA` | | | -|`CC_COMPOSER_VERSION` | Choose your composer version between `2` or `lts` | 2 | -|[`CC_CONFIGURATION_PM_MAX_CHILDREN`](/doc/applications/php/#memory-limit) | Set the number of PHP-FPM workers. On XS and larger flavors, increasing it can lower the automatically calculated memory limit. Nano always uses six workers | Depends on the scaler size | -|[`CC_CGI_IMPLEMENTATION`](/doc/applications/php/apache/#change-the-fastcgi-module) | Choose the Apache FastCGI module between `fastcgi` and `proxy_fcgi` | proxy_fcgi | -|`CC_HTTP_BASIC_AUTH` | Restrict HTTP access to your application. Example: `login:password`. You can define multiple credentials using additional `CC_HTTP_BASIC_AUTH_n` (where `n` is a number) environment variables. | | -| `CC_APACHE_HEADERS_SIZE` | Set the maximum size of the headers in Apache, between `8` and `256`. Effective value depends on deployment region. [Ask for a dedicated load balancer](https://console.clever-cloud.com/ticket-center-choice) for a specific value | 8 | -|`CC_LDAP_CA_CERT` | | | -|`CC_MTA_AUTH_PASSWORD` | Password to authenticate to the SMTP server | | -|`CC_MTA_AUTH_USER` | User to authenticate to the SMTP server | | -|`CC_MTA_SERVER_AUTH_METHOD` | Enable or disable authentication to the SMTP server | on | -|`CC_MTA_SERVER_HOST` | Host of the SMTP server | | -|`CC_MTA_SERVER_PORT` | Port of the SMTP server | 465 | -|`CC_MTA_SERVER_USE_TLS` | Enable or disable TLS when connecting to the SMTP server | true | -|`CC_OPCACHE_INTERNED_STRINGS_BUFFER` | The amount of memory used to store interned strings, in megabytes. | Default 4 (PHP5), 8 (PHP7) | -|`CC_OPCACHE_MAX_ACCELERATED_FILES` | Maximum number of files handled by opcache. | Default depends on the scaler size | -|`CC_OPCACHE_MEMORY` | Set the shared opcache memory size | Default is about 1/8 of the RAM | -|`CC_OPCACHE_PRELOAD` | The path of the PHP preload file (PHP version 7.4 or higher). | | -|[`CC_PHP_ASYNC_APP_BUCKET`](/doc/applications/php/sessions-emails/#speed-up-or-disable-the-session-fs-bucket "Speed up or disable the session on FS Bucket") | Mount the default app FS bucket asynchronously. If set, should have value `async` | | -|[`CC_PHP_DEV_DEPENDENCIES`](/doc/applications/php/composer/#development-dependencies "Development dependencies") | Set to `install` to include dev dependencies; unset or set to `skip` to exclude them | | -|[`CC_PHP_DISABLE_APP_BUCKET`](/doc/applications/php/sessions-emails/#speed-up-or-disable-the-session-fs-bucket "Speed up or disable the session on FS Bucket") | Disable entirely the app FS Bucket. Values are either `true`, `yes` or `disable` | | -|`CC_PHP_VERSION` | Choose your PHP version among [those supported](/doc/applications/php/#php-version) | 8.3 | -|`CC_REALPATH_CACHE_TTL` | The size of the realpath cache to be used by PHP | 120 | -|`CC_WEBROOT` | Define the `DocumentRoot` of your project | `.` | -|`ENABLE_ELASTIC_APM_AGENT` | Elastic APM Agent for PHP | `true` if `ELASTIC_APM_SERVER_URL` is defined, `false` otherwise | -|`ENABLE_GRPC` | Enable the use of gRPC module | false | -|`ENABLE_PDFLIB` | Enable the use of PDFlib module | false | -|`ENABLE_REDIS` | | false | -|`HTTP_TIMEOUT` | Define a custom HTTP timeout | 180 | -|`LDAPTLS_CACERT` | | | -|`MAX_INPUT_VARS` | | | -|[`MEMORY_LIMIT`](/doc/applications/php/#memory-limit) | Set the maximum memory each PHP script can allocate, as a positive integer interpreted in MiB without a unit suffix | Depends on the scaler size | -|[`SESSION_TYPE`](/doc/applications/php/sessions-emails/#use-materia-kv-or-redis-to-store-php-sessions "Use Materia KV or Redis to store PHP sessions") | Choose `redis` to use it as session store | | -|`SOCKSIFY_EVERYTHING` | | | -|`SQREEN_API_APP_NAME` | The name of your sqreen application. | | -|`SQREEN_API_TOKEN` | organisation token. | | +| Name | Description | Default value | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `ALWAYS_POPULATE_RAW_POST_DATA` | | | +| `CC_COMPOSER_VERSION` | Choose your composer version between `2` or `lts` | 2 | +| [`CC_CONFIGURATION_PM_MAX_CHILDREN`](/doc/applications/php/#memory-limit) | Set the number of PHP-FPM workers. On XS and larger flavors, increasing it can lower the automatically calculated memory limit. Nano always uses six workers | Depends on the scaler size | +| [`CC_CGI_IMPLEMENTATION`](/doc/applications/php/apache/#change-the-fastcgi-module) | Choose the Apache FastCGI module between `fastcgi` and `proxy_fcgi` | proxy_fcgi | +| `CC_HTTP_BASIC_AUTH` | Restrict HTTP access to your application. Example: `login:password`. You can define multiple credentials using additional `CC_HTTP_BASIC_AUTH_n` (where `n` is a number) environment variables. | | +| `CC_APACHE_HEADERS_SIZE` | Set the maximum size of the headers in Apache, between `8` and `256`. Effective value depends on deployment region. [Ask for a dedicated load balancer](https://console.clever-cloud.com/ticket-center-choice) for a specific value | 8 | +| `CC_LDAP_CA_CERT` | | | +| `CC_MTA_AUTH_PASSWORD` | Password to authenticate to the SMTP server | | +| `CC_MTA_AUTH_USER` | User to authenticate to the SMTP server | | +| `CC_MTA_SERVER_AUTH_METHOD` | Enable or disable authentication to the SMTP server | on | +| `CC_MTA_SERVER_HOST` | Host of the SMTP server | | +| `CC_MTA_SERVER_PORT` | Port of the SMTP server | 465 | +| `CC_MTA_SERVER_USE_TLS` | Enable or disable TLS when connecting to the SMTP server | true | +| `CC_OPCACHE_INTERNED_STRINGS_BUFFER` | The amount of memory used to store interned strings, in megabytes. | Default 4 (PHP5), 8 (PHP7) | +| `CC_OPCACHE_MAX_ACCELERATED_FILES` | Maximum number of files handled by opcache. | Default depends on the scaler size | +| `CC_OPCACHE_MEMORY` | Set the shared opcache memory size | Default is about 1/8 of the RAM | +| `CC_OPCACHE_PRELOAD` | The path of the PHP preload file (PHP version 7.4 or higher). | | +| [`CC_PHP_ASYNC_APP_BUCKET`](/doc/applications/php/sessions-emails/#speed-up-or-disable-the-session-fs-bucket "Speed up or disable the session on FS Bucket") | Mount the default app FS bucket asynchronously. If set, should have value `async` | | +| [`CC_PHP_DEV_DEPENDENCIES`](/doc/applications/php/composer/#development-dependencies "Development dependencies") | Set to `install` to include dev dependencies; unset or set to `skip` to exclude them | | +| [`CC_PHP_DISABLE_APP_BUCKET`](/doc/applications/php/sessions-emails/#speed-up-or-disable-the-session-fs-bucket "Speed up or disable the session on FS Bucket") | Disable entirely the app FS Bucket. Values are either `true`, `yes` or `disable` | | +| `CC_PHP_VERSION` | Choose your PHP version among [those supported](/doc/applications/php/#php-version) | 8.3 | +| `CC_REALPATH_CACHE_TTL` | The size of the realpath cache to be used by PHP | 120 | +| `CC_WEBROOT` | Define the `DocumentRoot` of your project | `.` | +| `ENABLE_ELASTIC_APM_AGENT` | Elastic APM Agent for PHP | `true` if `ELASTIC_APM_SERVER_URL` is defined, `false` otherwise | +| `ENABLE_GRPC` | Enable the use of gRPC module | false | +| `ENABLE_PDFLIB` | Enable the use of PDFlib module | false | +| `ENABLE_REDIS` | | false | +| `HTTP_TIMEOUT` | Define a custom HTTP timeout | 180 | +| `LDAPTLS_CACERT` | | | +| `MAX_INPUT_VARS` | | | +| [`MEMORY_LIMIT`](/doc/applications/php/#memory-limit) | Set the maximum memory each PHP script can allocate, as a positive integer interpreted in MiB without a unit suffix | Depends on the scaler size | +| [`SESSION_TYPE`](/doc/applications/php/sessions-emails/#use-materia-kv-or-redis-to-store-php-sessions "Use Materia KV or Redis to store PHP sessions") | Choose `redis` to use it as session store | | +| `SOCKSIFY_EVERYTHING` | | | +| `SQREEN_API_APP_NAME` | The name of your sqreen application. | | +| `SQREEN_API_TOKEN` | organisation token. | | ## Python [Python Documentation](/doc/applications/python) -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|`CC_HTTP_BASIC_AUTH` | Restrict HTTP access to your application. Example: `login:password`. You can define multiple credentials using additional `CC_HTTP_BASIC_AUTH_n` (where `n` is a number) environment variables. | | -|[`CC_NGINX_PROXY_BUFFERS`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers "Nginx documentation") | Sets the number and size of the buffers used for reading a response from the proxied server, for a single connection. | | -|[`CC_NGINX_PROXY_BUFFER_SIZE`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size "Nginx documentation") | Sets the size of the buffer used for reading the first part of the response received from the proxied server.| | -|`CC_PIP_REQUIREMENTS_FILE` | Allows you to define a custom requirements.txt file | requirements.txt | -|`CC_PYTHON_BACKEND` | Choose the Python backend to use between daphne, gunicorn, uvicorn and uwsgi | uwsgi | -|`CC_PYTHON_CELERY_LOGFILE` | Relative path to your Celery logfile: /path/to/logdir | | -|`CC_PYTHON_CELERY_MODULE` | Specify the Celery module you want to start | | -|`CC_PYTHON_CELERY_USE_BEAT` | Set to "true" to activate Beat support | | -|[`CC_PYTHON_MANAGE_TASKS`](/guides/python-django-sample/#manage-py-tasks) | Comma-separated list of Django manage tasks | | -|`CC_PYTHON_MODULE` | Select which module you want to start with the path to the folder containing the app object. For example, a module called **server.py** in a folder called **/app** would be used here as **app.server:app** | | -|`CC_PYTHON_USE_GEVENT` | Set to true to enable Gevent | | -|`CC_PYTHON_VERSION` | Choose the Python version among [those supported](/doc/applications/python/#python-version) | 3 | -|`ENABLE_GZIP_COMPRESSION` | Set to `true` to gzip-compress through Nginx | | -|`GZIP_TYPES` | Set the mime types to compress. | text/plain text/css text/xml text/javascript application/json application/xml application/javascript image/svg+xml | -|`HARAKIRI` | Timeout (in seconds) after which an unresponding process is killed | 180 | -|`NGINX_READ_TIMEOUT` | Read timeout in seconds | 300 | -|`PYTHON_SETUP_PY_GOAL` | Custom setup goal to be launch after requirements.txt have been installed | | -|`STATIC_FILES_PATH` | Relative path to where your static files are stored: path/to/static | | -|[`STATIC_URL_PREFIX`](/doc/applications/python/#configure-your-python-application "Configure your Python application") | The URL path under which you want to serve static file, usually /public | | -|`STATIC_WEBROOT` | | | -|[`UWSGI_ASYNC`](/doc/applications/python/#configure-your-python-application "Configure your Python application" ) | Number of cores to use for uWSGI asynchronous/non-blocking modes | | -|`UWSGI_ASYNC_ENGINE` | Select the asynchronous engine for uWSGI (optional) | | -|`UWSGI_INTERCEPT_ERRORS` | | -|`WSGI_BUFFER_SIZE` | Buffer size (in bytes) for uploads. | 4096 | -|`WSGI_POST_BUFFERING` | Maximal size (in bytes) for the headers of a request. | 4096 | -|`WSGI_THREADS` | Number of threads per worker. (Default: automatically setup with the scaler size) | | -|`WSGI_WORKERS` | Number of workers. (Default: automatically setup with the scaler size) | | +| Name | Description | Default value | +| --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | +| `CC_HTTP_BASIC_AUTH` | Restrict HTTP access to your application. Example: `login:password`. You can define multiple credentials using additional `CC_HTTP_BASIC_AUTH_n` (where `n` is a number) environment variables. | | +| [`CC_NGINX_PROXY_BUFFERS`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers "Nginx documentation") | Sets the number and size of the buffers used for reading a response from the proxied server, for a single connection. | | +| [`CC_NGINX_PROXY_BUFFER_SIZE`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size "Nginx documentation") | Sets the size of the buffer used for reading the first part of the response received from the proxied server. | | +| `CC_PIP_REQUIREMENTS_FILE` | Allows you to define a custom requirements.txt file | requirements.txt | +| `CC_PYTHON_BACKEND` | Choose the Python backend to use between daphne, gunicorn, uvicorn and uwsgi | uwsgi | +| `CC_PYTHON_CELERY_LOGFILE` | Relative path to your Celery logfile: /path/to/logdir | | +| `CC_PYTHON_CELERY_MODULE` | Specify the Celery module you want to start | | +| `CC_PYTHON_CELERY_USE_BEAT` | Set to "true" to activate Beat support | | +| [`CC_PYTHON_MANAGE_TASKS`](/guides/python-django-sample/#manage-py-tasks) | Comma-separated list of Django manage tasks | | +| `CC_PYTHON_MODULE` | Select which module you want to start with the path to the folder containing the app object. For example, a module called **server.py** in a folder called **/app** would be used here as **app.server:app** | | +| `CC_PYTHON_USE_GEVENT` | Set to true to enable Gevent | | +| `CC_PYTHON_VERSION` | Choose the Python version among [those supported](/doc/applications/python/#python-version) | 3 | +| `ENABLE_GZIP_COMPRESSION` | Set to `true` to gzip-compress through Nginx | | +| `GZIP_TYPES` | Set the mime types to compress. | text/plain text/css text/xml text/javascript application/json application/xml application/javascript image/svg+xml | +| `HARAKIRI` | Timeout (in seconds) after which an unresponding process is killed | 180 | +| `NGINX_READ_TIMEOUT` | Read timeout in seconds | 300 | +| `PYTHON_SETUP_PY_GOAL` | Custom setup goal to be launch after requirements.txt have been installed | | +| `STATIC_FILES_PATH` | Relative path to where your static files are stored: path/to/static | | +| [`STATIC_URL_PREFIX`](/doc/applications/python/#configure-your-python-application "Configure your Python application") | The URL path under which you want to serve static file, usually /public | | +| `STATIC_WEBROOT` | | | +| [`UWSGI_ASYNC`](/doc/applications/python/#configure-your-python-application "Configure your Python application" ) | Number of cores to use for uWSGI asynchronous/non-blocking modes | | +| `UWSGI_ASYNC_ENGINE` | Select the asynchronous engine for uWSGI (optional) | | +| `UWSGI_INTERCEPT_ERRORS` | | | +| `WSGI_BUFFER_SIZE` | Buffer size (in bytes) for uploads. | 4096 | +| `WSGI_POST_BUFFERING` | Maximal size (in bytes) for the headers of a request. | 4096 | +| `WSGI_THREADS` | Number of threads per worker. (Default: automatically setup with the scaler size) | | +| `WSGI_WORKERS` | Number of workers. (Default: automatically setup with the scaler size) | | When your Python application doesn't use one of the supported backends, with `CC_RUN_COMMAND` for example, it must listen on port `9000`, not `8080`. @@ -353,51 +353,51 @@ When your Python application doesn't use one of the supported backends, with `CC - [Ruby Guide](/guides/ruby-rack-app-tutorial) - [Ruby Documentation](/doc/applications/ruby) -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|[`CC_ENABLE_SIDEKIQ`](/doc/applications/ruby/#configure-sidekiq) | Enable Sidekiq background process | false | -|`CC_HTTP_BASIC_AUTH` | Restrict HTTP access to your application. Example: `login:password`. You can define multiple credentials using additional `CC_HTTP_BASIC_AUTH_n` (where `n` is a number) environment variables. | | -|`CC_NGINX_PROXY_BUFFERS` | Sets the number and size of the buffers used for reading a response from the proxied server, for a single connection. [Nginx documentation](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers "Nginx documentation") | | -|`CC_NGINX_PROXY_BUFFER_SIZE` | Sets the size of the buffer used for reading the first part of the response received from the proxied server. [Nginx documentation](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size "Nginx documentation") | | -|`CC_RACKUP_SERVER` | The server to use for serving the ruby application | puma | | -|[`CC_RAKEGOALS`](/doc/applications/ruby/#configure-rake-goals) | A list of comma-separated rake goals to execute e.g. db:migrate, assets:precompile | | -|`CC_RUBY_VERSION` | Choose the Ruby version to use but we strongly advise to set Ruby version in your Gemfile | | | -|`CC_SIDEKIQ_FILES` | Specify a list of Sidekiq configuration files e.g. "./config/sidekiq_1.yml,./config/sidekiq_2.yml" | | -|`ENABLE_GZIP_COMPRESSION` | Set to `true` to gzip-compress through Nginx | | -|`GZIP_TYPES` | Set the mime types to compress. | text/plain text/css text/xml text/javascript application/json application/xml application/javascript image/svg+xml | -|`NGINX_READ_TIMEOUT` | Read timeout in seconds | 300 | -|`RACK_ENV` | | | -|`RAILS_ENV` | | | | -|`STATIC_FILES_PATH` | Relative path to where your static files are stored: path/to/static | | -|[`STATIC_URL_PREFIX`](/doc/applications/ruby/#manage-your-static-files-and-assets) | The URL path under which you want to serve static file, usually /public | | -|`STATIC_WEBROOT` | | | +| Name | Description | Default value | +| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | +| [`CC_ENABLE_SIDEKIQ`](/doc/applications/ruby/#configure-sidekiq) | Enable Sidekiq background process | false | +| `CC_HTTP_BASIC_AUTH` | Restrict HTTP access to your application. Example: `login:password`. You can define multiple credentials using additional `CC_HTTP_BASIC_AUTH_n` (where `n` is a number) environment variables. | | +| `CC_NGINX_PROXY_BUFFERS` | Sets the number and size of the buffers used for reading a response from the proxied server, for a single connection. [Nginx documentation](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers "Nginx documentation") | | +| `CC_NGINX_PROXY_BUFFER_SIZE` | Sets the size of the buffer used for reading the first part of the response received from the proxied server. [Nginx documentation](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size "Nginx documentation") | | +| `CC_RACKUP_SERVER` | The server to use for serving the ruby application | puma | +| [`CC_RAKEGOALS`](/doc/applications/ruby/#configure-rake-goals) | A list of comma-separated rake goals to execute e.g. db:migrate, assets:precompile | | +| `CC_RUBY_VERSION` | Choose the Ruby version to use but we strongly advise to set Ruby version in your Gemfile | | +| `CC_SIDEKIQ_FILES` | Specify a list of Sidekiq configuration files e.g. "./config/sidekiq_1.yml,./config/sidekiq_2.yml" | | +| `ENABLE_GZIP_COMPRESSION` | Set to `true` to gzip-compress through Nginx | | +| `GZIP_TYPES` | Set the mime types to compress. | text/plain text/css text/xml text/javascript application/json application/xml application/javascript image/svg+xml | +| `NGINX_READ_TIMEOUT` | Read timeout in seconds | 300 | +| `RACK_ENV` | | | +| `RAILS_ENV` | | | +| `STATIC_FILES_PATH` | Relative path to where your static files are stored: path/to/static | | +| [`STATIC_URL_PREFIX`](/doc/applications/ruby/#manage-your-static-files-and-assets) | The URL path under which you want to serve static file, usually /public | | +| `STATIC_WEBROOT` | | | ## Rust [Rust Documentation](/doc/applications/rust) -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|`CC_RUSTUP_CHANNEL` | The rust channel to use. Use a specific channel version with stable, beta, nightly or a specific version like 1.13.0 | stable | -|`CC_RUST_BIN` | The name of the binary to launch once built | | -|`CC_RUST_FEATURES` | The list of features to enable | | -|`CC_RUN_COMMAND` | Custom command to run your application. | | +| Name | Description | Default value | +| ------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------- | +| `CC_RUSTUP_CHANNEL` | The rust channel to use. Use a specific channel version with stable, beta, nightly or a specific version like 1.13.0 | stable | +| `CC_RUST_BIN` | The name of the binary to launch once built | | +| `CC_RUST_FEATURES` | The list of features to enable | | +| `CC_RUN_COMMAND` | Custom command to run your application. | | ## Static [Static Documentation](/doc/applications/static) -| Name | Description | Default value | -|------|-------------|---------------| -| `CC_HUGO_VERSION` | Set the Hugo version, for example `0.161` | | -| `CC_BUILD_COMMAND` | The command to run during the build phase | | -| `CC_OVERRIDE_BUILDCACHE` | Files and path to put in the build cache, separated by a `:` | | +| Name | Description | Default value | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------ | ---------------------- | +| `CC_HUGO_VERSION` | Set the Hugo version, for example `0.161` | | +| `CC_BUILD_COMMAND` | The command to run during the build phase | | +| `CC_OVERRIDE_BUILDCACHE` | Files and path to put in the build cache, separated by a `:` | | | `CC_STATIC_AUTOBUILD_OUTDIR` | The output directory of the static site generator (SSG) auto-build, relative to the root of your application | `/cc_static_autobuilt` | -| `CC_STATIC_CADDYFILE` | Path to the Caddyfile, as expected by `caddy run --config` command | `./Caddyfile` | -| `CC_STATIC_FLAGS` | Command line flags to pass to the static web server | | -| `CC_STATIC_PORT` | The port on which the static web server listens for HTTP requests | `8080` | -| `CC_STATIC_SERVER` | The server to use to serve your static website, can be `caddy` | `static-web-server` | -| `CC_WEBROOT` | Path to the web content to serve, relative to the root of your application, used as default build cache | `/` | +| `CC_STATIC_CADDYFILE` | Path to the Caddyfile, as expected by `caddy run --config` command | `./Caddyfile` | +| `CC_STATIC_FLAGS` | Command line flags to pass to the static web server | | +| `CC_STATIC_PORT` | The port on which the static web server listens for HTTP requests | `8080` | +| `CC_STATIC_SERVER` | The server to use to serve your static website, can be `caddy` | `static-web-server` | +| `CC_WEBROOT` | Path to the web content to serve, relative to the root of your application, used as default build cache | `/` | > [!NOTE] Static Site Generators (SSG) Auto-build > If no `CC_BUILD_COMMAND` is provided, Clever Cloud tries to detect and configure Static Site Generator (SSG), any provided `CC_WEBROOT` is ignored. See [Static Site Generators (SSG) Auto-build](/doc/applications/static/#static-site-generators-ssg-auto-build) for more information. @@ -406,10 +406,10 @@ When your Python application doesn't use one of the supported backends, with `CC [V (Vlang)](/doc/applications/v) -| Name | Description | Default value | -|------|-------------|---------------| -| `CC_V_BINARY` | The name of the output binary file. | `${APP_HOME}/v_bin_${APP_ID}` | -| `ENVIRONMENT` | Set to `development` to compile without the `-prod` flag | | +| Name | Description | Default value | +| ------------- | -------------------------------------------------------- | ----------------------------- | +| `CC_V_BINARY` | The name of the output binary file. | `${APP_HOME}/v_bin_${APP_ID}` | +| `ENVIRONMENT` | Set to `development` to compile without the `-prod` flag | | ## Add-ons environment variables @@ -417,196 +417,196 @@ When your Python application doesn't use one of the supported backends, with `CC [FS Bucket Documentation](/doc/addons/fs-bucket) -| Name | Description | Read Only | -|-----------------------|------------------------------|--------------------------------| -|`BUCKET_HOST` | Hostname of the bucket | ✓ | -|`CC_FS_BUCKET` | Defines which bucket to mount on which path | | +| Name | Description | Read Only | +| -------------- | ------------------------------------------- | --------- | +| `BUCKET_HOST` | Hostname of the bucket | ✓ | +| `CC_FS_BUCKET` | Defines which bucket to mount on which path | | ### MongoDB [MongoDB Documentation](/doc/addons/mongodb) -| Name | Description | Default value | Read Only | -|-----------------------|------------------------------|--------------------------------|--------------------------------| -|`MONGODB_ADDON_HOST` | | Generated upon creation | ✓ | -|`MONGODB_ADDON_PORT` | | Generated upon creation | ✓ | -|`MONGODB_ADDON_DIRECT_HOST` | Points directly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | -|`MONGODB_ADDON_DIRECT_PORT` | Points to ectly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | -|`MONGODB_ADDON_DB` | | Generated upon creation | ✓ | -|`MONGODB_ADDON_PASSWORD` | | Generated upon creation | ✓ | -|`MONGODB_ADDON_USER` | | Generated upon creation | ✓ | +| Name | Description | Default value | Read Only | +| --------------------------- | ---------------------------------------------------- | ------------------------------------- | --------- | +| `MONGODB_ADDON_HOST` | | Generated upon creation | ✓ | +| `MONGODB_ADDON_PORT` | | Generated upon creation | ✓ | +| `MONGODB_ADDON_DIRECT_HOST` | Points directly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | +| `MONGODB_ADDON_DIRECT_PORT` | Points to ectly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | +| `MONGODB_ADDON_DB` | | Generated upon creation | ✓ | +| `MONGODB_ADDON_PASSWORD` | | Generated upon creation | ✓ | +| `MONGODB_ADDON_USER` | | Generated upon creation | ✓ | ### MySQL [MySQL Documentation](/doc/addons/mysql) -| Name | Description | Default value | Read Only | -|-----------------------|------------------------------|--------------------------------|--------------------------------| -|`MYSQL_ADDON_HOST` | | Generated upon creation | ✓ | -|`MYSQL_ADDON_PORT` | | Generated upon creation | ✓ | -|`MYSQL_ADDON_DIRECT_HOST` | Points directly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | -|`MYSQL_ADDON_DIRECT_PORT` | Points to ectly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | -|`MYSQL_ADDON_DB` | | Generated upon creation | ✓ | -|`MYSQL_ADDON_PASSWORD` | | Generated upon creation | ✓ | -|`MYSQL_ADDON_ROLE` | | Generated upon creation | ✓ | -|`MYSQL_ADDON_USER` | | Generated upon creation | ✓ | +| Name | Description | Default value | Read Only | +| ------------------------- | ---------------------------------------------------- | ------------------------------------- | --------- | +| `MYSQL_ADDON_HOST` | | Generated upon creation | ✓ | +| `MYSQL_ADDON_PORT` | | Generated upon creation | ✓ | +| `MYSQL_ADDON_DIRECT_HOST` | Points directly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | +| `MYSQL_ADDON_DIRECT_PORT` | Points to ectly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | +| `MYSQL_ADDON_DB` | | Generated upon creation | ✓ | +| `MYSQL_ADDON_PASSWORD` | | Generated upon creation | ✓ | +| `MYSQL_ADDON_ROLE` | | Generated upon creation | ✓ | +| `MYSQL_ADDON_USER` | | Generated upon creation | ✓ | ### ProxySQL [ProxySQL Documentation](/guides/proxysql) -| Name | Description | Default value | Read Only | -|-----------------------|------------------------------|--------------------------------|--------------------------------| -|`CC_ENABLE_MYSQL_PROXYSQL` | Enable the ProxySQL feature | false | | -|`CC_MYSQL_PROXYSQL_MAX_CONNECTIONS` | Defines the maximum number of connections the local ProxySQL will open to your MySQL add-on | 10 | | -|`CC_MYSQL_PROXYSQL_USE_TLS` | Enable or disable secured connection using TLS to your MySQL add-on | true | | -|`CC_MYSQL_PROXYSQL_SOCKET_PATH` | Contains the path to the Unix Datagram Socket to connect to ProxySQL | | ✓ | +| Name | Description | Default value | Read Only | +| ----------------------------------- | ------------------------------------------------------------------------------------------- | ------------- | --------- | +| `CC_ENABLE_MYSQL_PROXYSQL` | Enable the ProxySQL feature | false | | +| `CC_MYSQL_PROXYSQL_MAX_CONNECTIONS` | Defines the maximum number of connections the local ProxySQL will open to your MySQL add-on | 10 | | +| `CC_MYSQL_PROXYSQL_USE_TLS` | Enable or disable secured connection using TLS to your MySQL add-on | true | | +| `CC_MYSQL_PROXYSQL_SOCKET_PATH` | Contains the path to the Unix Datagram Socket to connect to ProxySQL | | ✓ | ### PostgreSQL [PostgreSQL Documentation](/doc/addons/postgresql) -| Name | Description | Default value | Read Only | -|-----------------------|------------------------------|--------------------------------|--------------------------------| -|`POSTGRESQL_ADDON_URI` | Complete URI to connect to the PostgreSQL database | Generated upon creation | ✓ | -|`POSTGRESQL_ADDON_HOST` | | Generated upon creation | ✓ | -|`POSTGRESQL_ADDON_PORT` | | Generated upon creation | ✓ | -|`POSTGRESQL_ADDON_DIRECT_HOST` | Points directly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | -|`POSTGRESQL_ADDON_DIRECT_PORT` | Points to ectly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | -|`POSTGRESQL_ADDON_DB` | | Generated upon creation | ✓ | -|`POSTGRESQL_ADDON_PASSWORD` | | Generated upon creation | ✓ | -|`POSTGRESQL_ADDON_ROLE` | | Generated upon creation | ✓ | -|`POSTGRESQL_ADDON_USER` | | Generated upon creation | ✓ | +| Name | Description | Default value | Read Only | +| ------------------------------ | ---------------------------------------------------- | ------------------------------------- | --------- | +| `POSTGRESQL_ADDON_URI` | Complete URI to connect to the PostgreSQL database | Generated upon creation | ✓ | +| `POSTGRESQL_ADDON_HOST` | | Generated upon creation | ✓ | +| `POSTGRESQL_ADDON_PORT` | | Generated upon creation | ✓ | +| `POSTGRESQL_ADDON_DIRECT_HOST` | Points directly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | +| `POSTGRESQL_ADDON_DIRECT_PORT` | Points to ectly to the VM, bypassing reverse proxies | Generated on demand via the dashboard | ✓ | +| `POSTGRESQL_ADDON_DB` | | Generated upon creation | ✓ | +| `POSTGRESQL_ADDON_PASSWORD` | | Generated upon creation | ✓ | +| `POSTGRESQL_ADDON_ROLE` | | Generated upon creation | ✓ | +| `POSTGRESQL_ADDON_USER` | | Generated upon creation | ✓ | ### Pgpool-II [Pgpool-II Documentation](/guides/pgpool) -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -|`CC_ENABLE_PGPOOL` | Enables the Pgpool-II feature | false | -|`CC_PGPOOL_SOCKET_PATH` | Contains the path to the Unix Datagram Socket to connect to Pgpool-II | true | -|`CC_PGPOOL_PCP_SOCKET_PATH` | Contains the path to the Unix Datagram Socket to connect to PCP | true | -|`CC_PGPOOL_EXTRA_USERS` | Add new user/password pairs to the pool_passwd file, separated by commas (user1:password,user2:password…) | ' ' | -|`CC_PGPOOL_RESERVED_CONNECTIONS` | Number of reserved connections | 0 | -|`CC_PGPOOL_LISTEN_BACKLOG_MULTIPLIER` | Specifies the length of connection queue from frontend to Pgpool-II | 2 | -|`CC_PGPOOL_LEADER_WEIGHT` | Weight for backend 0 (Leader) | 1 | -|`CC_PGPOOL_NUM_INIT_CHILDREN` | Number of concurrent sessions allowed | 16 | -|`CC_PGPOOL_MAX_POOL` | Number of connection pool caches per connection | 1 | -|`CC_PGPOOL_CHILD_LIFE_TIME` | Pool exits after being idle for this many seconds | 300 | -|`CC_PGPOOL_CHILD_MAX_CONNECTIONS` | Pool exits after receiving that many connections | 0 (no exit) | -|`CC_PGPOOL_CONNECTION_LIFE_TIME` | Connection to backend closes after being idle for this many seconds | 0 (no close) | -|`CC_PGPOOL_CLIENT_IDLE_LIMIT` | Client is disconnected after being idle for that many seconds (even inside an explicit transactions!) | 0 (no disconnection) | | -|`CC_PGPOOL_LOG_CONNECTIONS` | Log connections | off | -|`CC_PGPOOL_LOG_DISCONNECTIONS` | Log disconnections | off | -|`CC_PGPOOL_LOG_HOSTNAME` | Hostname will be shown in ps status and in logs if connections are logged | off | -|`CC_PGPOOL_LOG_STATEMENT` | Log all statements | off | -|`CC_PGPOOL_LOG_PER_NODE_STATEMENT` | Log all statements with node and backend informations | off | -|`CC_PGPOOL_LOG_CLIENT_MESSAGES` | Log any client messages | off | -|`CC_PGPOOL_LOG_STANDBY_DELAY` | Log standby delay. Valid values are combinations of always, if_over_threshold and none | if_over_threshold | -|`CC_PGPOOL_CONNECTION_CACHE` | Activate connection pools | on | -|`CC_PGPOOL_REPLICATE_SELECT` | Replicate SELECT statements in replication mode | off | -|`CC_PGPOOL_INSERT_LOCK` | Automatically locks a dummy row or a table with INSERT statements to keep SERIAL data consistency | on | -|`CC_PGPOOL_LOBJ_LOCK_TABLE` | When rewriting lo_creat command in replication mode, specify table name to lock | ' ' | -|`CC_PGPOOL_REPLICATION_STOP_ON_MISMATCH` | On disagreement with the packet kind sent from backend, degenerate the node which is most likely "minority" If off, just force to exit this session | off | -|`CC_PGPOOL_FAILOVER_IF_AFFECTED_TUPLES_MISMATCH` | On disagreement with the number of affected tuples in UPDATE/DELETE queries, then degenerate the node which is most likely "minority". If off, just abort the transaction to keep the consistency | off | -|`CC_PGPOOL_LOAD_BALANCE_MODE` | Activate load balancing mode | on | -|`CC_PGPOOL_IGNORE_LEADING_WHITE_SPACE` | Ignore leading white spaces of each query | on | -|`CC_PGPOOL_READ_ONLY_FUNCTION_LIST` | Comma separated list of function names that don't write to database (regexp are accepted) | ' ' | -|`CC_PGPOOL_WRITE_FUNCTION_LIST` | Comma separated list of function names that write to database (regexp are accepted) | ' ' | -|`CC_PGPOOL_PRIMARY_ROUTING_QUERY_PATTERN_LIST` | Semicolon separated list of query patterns that should be sent to primary node (regexp are accepted) | ' ' | -|`CC_PGPOOL_DATABASE_REDIRECT_PREFERENCE_LIST` | Comma separated list of pairs of database and node id | ' ' | -|`CC_PGPOOL_APP_NAME_REDIRECT_PREFERENCE_LIST` | Comma separated list of pairs of app name and node id | ' ' | -|`CC_PGPOOL_ALLOW_SQL_COMMENTS` | If on, ignore SQL comments when judging if load balance or query cache is possible | off | -|`CC_PGPOOL_DISABLE_LOAD_BALANCE_ON_WRITE` | Load balance behavior when write query is issued in an explicit transaction. Valid values are "transaction", "trans_transaction", "dml_adaptive" or "always" | transaction | -|`CC_PGPOOL_DML_ADAPTIVE_OBJECT_RELATIONSHIP_LIST` | Comma separated list of object pairs | ' ' | -|`CC_PGPOOL_STATEMENT_LEVEL_LOAD_BALANCE` | Enables statement level load balancing | off | -|`CC_PGPOOL_SR_CHECK_PERIOD` | Streaming replication check period | 10 | -|`CC_PGPOOL_DELAY_THRESHOLD` | Threshold before not dispatching query to standby node Unit is in bytes | 10000000 | -|`CC_PGPOOL_HEALTH_CHECK_PERIOD` | Health check period | 20 | -|`CC_PGPOOL_HEALTH_CHECK_TIMEOUT` | Health check timeout | 20 | -|`CC_PGPOOL_HEALTH_CHECK_MAX_RETRIES` | Maximum number of times to retry a failed health check before giving up | 0 | -|`CC_PGPOOL_HEALTH_CHECK_RETRY_DELAY` | Amount of time to wait (in seconds) between retries | 1 | -|`CC_PGPOOL_CONNECT_TIMEOUT` | Timeout value in milliseconds before giving up to connect to backend | 10000 | -|`CC_PGPOOL_MEMORY_CACHE_ENABLED` | Use the memory cache functionality | off | -|`CC_PGPOOL_MEMQCACHE_TOTAL_SIZE` | Total memory size in megabytes for storing memory cache | 64 | -|`CC_PGPOOL_MEMQCACHE_MAX_NUM_CACHE` | Total number of cache entries | 1000000 | -|`CC_PGPOOL_MEMQCACHE_EXPIRE` | Memory cache entry life time specified in seconds | 0 | -|`CC_PGPOOL_MEMQCACHE_AUTO_CACHE_INVALIDATION` | Invalidation of query cache is triggered by corresponding DDL/DML/DCL | on | -|`CC_PGPOOL_MEMQCACHE_MAXCACHE` | Maximum SELECT result size in kilobytes (must be smaller than MEMQCACHE_CACHE_BLOCK_SIZE) | 400 | -|`CC_PGPOOL_MEMQCACHE_CACHE_BLOCK_SIZE` | Cache block size in megabytes | 1 | -|`CC_PGPOOL_CACHE_SAFE_MEMQCACHE_TABLE_LIST` | Comma separated list of table names to memcache that don't write to database (regexp are accepted) | ' ' | -|`CC_PGPOOL_CACHE_UNSAFE_MEMQCACHE_TABLE_LIST` | Comma separated list of table names not to memcache that don't write to database (regexp are accepted) | ' ' | +| Name | Description | Default value | +| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `CC_ENABLE_PGPOOL` | Enables the Pgpool-II feature | false | +| `CC_PGPOOL_SOCKET_PATH` | Contains the path to the Unix Datagram Socket to connect to Pgpool-II | true | +| `CC_PGPOOL_PCP_SOCKET_PATH` | Contains the path to the Unix Datagram Socket to connect to PCP | true | +| `CC_PGPOOL_EXTRA_USERS` | Add new user/password pairs to the pool_passwd file, separated by commas (user1:password,user2:password…) | ' ' | +| `CC_PGPOOL_RESERVED_CONNECTIONS` | Number of reserved connections | 0 | +| `CC_PGPOOL_LISTEN_BACKLOG_MULTIPLIER` | Specifies the length of connection queue from frontend to Pgpool-II | 2 | +| `CC_PGPOOL_LEADER_WEIGHT` | Weight for backend 0 (Leader) | 1 | +| `CC_PGPOOL_NUM_INIT_CHILDREN` | Number of concurrent sessions allowed | 16 | +| `CC_PGPOOL_MAX_POOL` | Number of connection pool caches per connection | 1 | +| `CC_PGPOOL_CHILD_LIFE_TIME` | Pool exits after being idle for this many seconds | 300 | +| `CC_PGPOOL_CHILD_MAX_CONNECTIONS` | Pool exits after receiving that many connections | 0 (no exit) | +| `CC_PGPOOL_CONNECTION_LIFE_TIME` | Connection to backend closes after being idle for this many seconds | 0 (no close) | +| `CC_PGPOOL_CLIENT_IDLE_LIMIT` | Client is disconnected after being idle for that many seconds (even inside an explicit transactions!) | 0 (no disconnection) | +| `CC_PGPOOL_LOG_CONNECTIONS` | Log connections | off | +| `CC_PGPOOL_LOG_DISCONNECTIONS` | Log disconnections | off | +| `CC_PGPOOL_LOG_HOSTNAME` | Hostname will be shown in ps status and in logs if connections are logged | off | +| `CC_PGPOOL_LOG_STATEMENT` | Log all statements | off | +| `CC_PGPOOL_LOG_PER_NODE_STATEMENT` | Log all statements with node and backend informations | off | +| `CC_PGPOOL_LOG_CLIENT_MESSAGES` | Log any client messages | off | +| `CC_PGPOOL_LOG_STANDBY_DELAY` | Log standby delay. Valid values are combinations of always, if_over_threshold and none | if_over_threshold | +| `CC_PGPOOL_CONNECTION_CACHE` | Activate connection pools | on | +| `CC_PGPOOL_REPLICATE_SELECT` | Replicate SELECT statements in replication mode | off | +| `CC_PGPOOL_INSERT_LOCK` | Automatically locks a dummy row or a table with INSERT statements to keep SERIAL data consistency | on | +| `CC_PGPOOL_LOBJ_LOCK_TABLE` | When rewriting lo_creat command in replication mode, specify table name to lock | ' ' | +| `CC_PGPOOL_REPLICATION_STOP_ON_MISMATCH` | On disagreement with the packet kind sent from backend, degenerate the node which is most likely "minority" If off, just force to exit this session | off | +| `CC_PGPOOL_FAILOVER_IF_AFFECTED_TUPLES_MISMATCH` | On disagreement with the number of affected tuples in UPDATE/DELETE queries, then degenerate the node which is most likely "minority". If off, just abort the transaction to keep the consistency | off | +| `CC_PGPOOL_LOAD_BALANCE_MODE` | Activate load balancing mode | on | +| `CC_PGPOOL_IGNORE_LEADING_WHITE_SPACE` | Ignore leading white spaces of each query | on | +| `CC_PGPOOL_READ_ONLY_FUNCTION_LIST` | Comma separated list of function names that don't write to database (regexp are accepted) | ' ' | +| `CC_PGPOOL_WRITE_FUNCTION_LIST` | Comma separated list of function names that write to database (regexp are accepted) | ' ' | +| `CC_PGPOOL_PRIMARY_ROUTING_QUERY_PATTERN_LIST` | Semicolon separated list of query patterns that should be sent to primary node (regexp are accepted) | ' ' | +| `CC_PGPOOL_DATABASE_REDIRECT_PREFERENCE_LIST` | Comma separated list of pairs of database and node id | ' ' | +| `CC_PGPOOL_APP_NAME_REDIRECT_PREFERENCE_LIST` | Comma separated list of pairs of app name and node id | ' ' | +| `CC_PGPOOL_ALLOW_SQL_COMMENTS` | If on, ignore SQL comments when judging if load balance or query cache is possible | off | +| `CC_PGPOOL_DISABLE_LOAD_BALANCE_ON_WRITE` | Load balance behavior when write query is issued in an explicit transaction. Valid values are "transaction", "trans_transaction", "dml_adaptive" or "always" | transaction | +| `CC_PGPOOL_DML_ADAPTIVE_OBJECT_RELATIONSHIP_LIST` | Comma separated list of object pairs | ' ' | +| `CC_PGPOOL_STATEMENT_LEVEL_LOAD_BALANCE` | Enables statement level load balancing | off | +| `CC_PGPOOL_SR_CHECK_PERIOD` | Streaming replication check period | 10 | +| `CC_PGPOOL_DELAY_THRESHOLD` | Threshold before not dispatching query to standby node Unit is in bytes | 10000000 | +| `CC_PGPOOL_HEALTH_CHECK_PERIOD` | Health check period | 20 | +| `CC_PGPOOL_HEALTH_CHECK_TIMEOUT` | Health check timeout | 20 | +| `CC_PGPOOL_HEALTH_CHECK_MAX_RETRIES` | Maximum number of times to retry a failed health check before giving up | 0 | +| `CC_PGPOOL_HEALTH_CHECK_RETRY_DELAY` | Amount of time to wait (in seconds) between retries | 1 | +| `CC_PGPOOL_CONNECT_TIMEOUT` | Timeout value in milliseconds before giving up to connect to backend | 10000 | +| `CC_PGPOOL_MEMORY_CACHE_ENABLED` | Use the memory cache functionality | off | +| `CC_PGPOOL_MEMQCACHE_TOTAL_SIZE` | Total memory size in megabytes for storing memory cache | 64 | +| `CC_PGPOOL_MEMQCACHE_MAX_NUM_CACHE` | Total number of cache entries | 1000000 | +| `CC_PGPOOL_MEMQCACHE_EXPIRE` | Memory cache entry life time specified in seconds | 0 | +| `CC_PGPOOL_MEMQCACHE_AUTO_CACHE_INVALIDATION` | Invalidation of query cache is triggered by corresponding DDL/DML/DCL | on | +| `CC_PGPOOL_MEMQCACHE_MAXCACHE` | Maximum SELECT result size in kilobytes (must be smaller than MEMQCACHE_CACHE_BLOCK_SIZE) | 400 | +| `CC_PGPOOL_MEMQCACHE_CACHE_BLOCK_SIZE` | Cache block size in megabytes | 1 | +| `CC_PGPOOL_CACHE_SAFE_MEMQCACHE_TABLE_LIST` | Comma separated list of table names to memcache that don't write to database (regexp are accepted) | ' ' | +| `CC_PGPOOL_CACHE_UNSAFE_MEMQCACHE_TABLE_LIST` | Comma separated list of table names not to memcache that don't write to database (regexp are accepted) | ' ' | ### Elastic Stack [Elastic Stack Documentation](/doc/addons/elastic) -| Name | Description | Default value | Read Only | -|-----------------------|------------------------------|--------------------------------|--------------------------------| -|`ELASTIC_APM_SERVER_URL` | URI to connect APM Server | Generated upon creation | ✓ | -|`ES_ADDON_APM_HOST` | APM Server hostname | Generated upon creation | ✓ | -|`ES_ADDON_APM_AUTH_TOKEN` | Authentication token to send metrics to APM Server | Generated upon creation | ✓ | -|`ELASTIC_APM_SECRET_TOKEN` | Authentication token to send metrics to APM Server | Generated upon creation | ✓ | -|`ES_ADDON_APM_USER` | Username credential used by APM Server to send metrics to Elasticsearch | Generated upon creation | ✓ | -|`ES_ADDON_APM_PASSWORD` | Password credential used by APM Server to send metrics to Elasticsearch | Generated upon creation | ✓ | -|`ES_ADDON_KIBANA_HOST` | Kibana hostname | Generated upon creation | ✓ | -|`ES_ADDON_KIBANA_USER` | Username credential used by Kibana to query Elasticsearch | Generated upon creation | ✓ | -|`ES_ADDON_KIBANA_PASSWORD` | Password credential used by Kibana to query Elasticsearch | Generated upon creation | ✓ | -|`ES_ADDON_URI` | URI to query Elasticsearch | Generated upon creation | ✓ | -|`ES_ADDON_HOST` | Elasticsearch hostname | Generated upon creation | ✓ | -|`ES_ADDON_USER` | Username credential to authenticate to Elasticsearch | Generated upon creation | ✓ | -|`ES_ADDON_PASSWORD` | Password credential to authenticate to Elasticsearch | Generated upon creation | ✓ | -|`ES_ADDON_VERSION` | ElasticSearch Version | 7 | ✓ | +| Name | Description | Default value | Read Only | +| -------------------------- | ----------------------------------------------------------------------- | ----------------------- | --------- | +| `ELASTIC_APM_SERVER_URL` | URI to connect APM Server | Generated upon creation | ✓ | +| `ES_ADDON_APM_HOST` | APM Server hostname | Generated upon creation | ✓ | +| `ES_ADDON_APM_AUTH_TOKEN` | Authentication token to send metrics to APM Server | Generated upon creation | ✓ | +| `ELASTIC_APM_SECRET_TOKEN` | Authentication token to send metrics to APM Server | Generated upon creation | ✓ | +| `ES_ADDON_APM_USER` | Username credential used by APM Server to send metrics to Elasticsearch | Generated upon creation | ✓ | +| `ES_ADDON_APM_PASSWORD` | Password credential used by APM Server to send metrics to Elasticsearch | Generated upon creation | ✓ | +| `ES_ADDON_KIBANA_HOST` | Kibana hostname | Generated upon creation | ✓ | +| `ES_ADDON_KIBANA_USER` | Username credential used by Kibana to query Elasticsearch | Generated upon creation | ✓ | +| `ES_ADDON_KIBANA_PASSWORD` | Password credential used by Kibana to query Elasticsearch | Generated upon creation | ✓ | +| `ES_ADDON_URI` | URI to query Elasticsearch | Generated upon creation | ✓ | +| `ES_ADDON_HOST` | Elasticsearch hostname | Generated upon creation | ✓ | +| `ES_ADDON_USER` | Username credential to authenticate to Elasticsearch | Generated upon creation | ✓ | +| `ES_ADDON_PASSWORD` | Password credential to authenticate to Elasticsearch | Generated upon creation | ✓ | +| `ES_ADDON_VERSION` | ElasticSearch Version | 7 | ✓ | ### Blackfire -| Name | Description | Default value | Read Only | -|-----------------------|------------------------------|--------------------------------|--------------------------------| -|`ENABLE_BLACKFIRE` | Enable the Blackfire extension | false | | -|`CC_BLACKFIRE_SERVER_TOKEN` | The server token used to authenticate with Blackfire | ' ' | ✓ | -|`CC_BLACKFIRE_SERVER_ID` | The server id used to authenticate with Blackfire | ' ' | ✓ | -|`CC_BLACKFIRE_LOG_LEVEL` | Sets the verbosity of Agent’s log output | 1 | ✓ | -|`CC_BLACKFIRE_MEMORY_LIMIT` | Sets the maximum allowed RAM usage (megabytes) when ingesting traces | 500 | ✓ | -|`CC_BLACKFIRE_COLLECTOR` | Sets the URL of Blackfire’s data collector | | ✓ | -|`CC_BLACKFIRE_TIMEOUT` | Sets the Blackfire API connection timeout | 15 | ✓ | -|`CC_BLACKFIRE_STATSD` | Sets the statsd server to send agent’s statistics | ' ' | ✓ | -|`CC_BLACKFIRE_STATSD_PREFIX` | Sets the statsd prefix to use when sending data | blackfire | ✓ | +| Name | Description | Default value | Read Only | +| ---------------------------- | -------------------------------------------------------------------- | ---------------------- | --------- | +| `ENABLE_BLACKFIRE` | Enable the Blackfire extension | false | | +| `CC_BLACKFIRE_SERVER_TOKEN` | The server token used to authenticate with Blackfire | ' ' | ✓ | +| `CC_BLACKFIRE_SERVER_ID` | The server id used to authenticate with Blackfire | ' ' | ✓ | +| `CC_BLACKFIRE_LOG_LEVEL` | Sets the verbosity of Agent’s log output | 1 | ✓ | +| `CC_BLACKFIRE_MEMORY_LIMIT` | Sets the maximum allowed RAM usage (megabytes) when ingesting traces | 500 | ✓ | +| `CC_BLACKFIRE_COLLECTOR` | Sets the URL of Blackfire’s data collector | | ✓ | +| `CC_BLACKFIRE_TIMEOUT` | Sets the Blackfire API connection timeout | 15 | ✓ | +| `CC_BLACKFIRE_STATSD` | Sets the statsd server to send agent’s statistics | ' ' | ✓ | +| `CC_BLACKFIRE_STATSD_PREFIX` | Sets the statsd prefix to use when sending data | blackfire | ✓ | ### New Relic -| Name | Description | Default value | Read Only | -|-----------------------|------------------------------|--------------------------------|--------------------------------| -|[`NEW_RELIC_APP_NAME`](https://docs.newrelic.com/docs/apm/agents/java-agent/configuration/java-agent-configuration-config-file/#ev-NEW_RELIC_APP_NAME "New Relic documentation") | Contains the application name | | -|[`NEW_RELIC_LICENSE_KEY`](https://docs.newrelic.com/docs/apm/agents/java-agent/configuration/java-agent-configuration-config-file/#ev-NEW_RELIC_LICENSE_KEY "New Relic documentation" ) | Contains your New Relic account license | | -|[`CC_NEWRELIC_BROWSER_MONITORING_AUTO_INSTRUMENT`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-autorum "New Relic documentation" ) | | | -|[`CC_NEWRELIC_DISTRIBUTED_TRACING_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-distributed-enabled "New Relic documentation" ) | | | -|[`CC_NEWRELIC_ERROR_COLLECTOR_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-err-enabled "New Relic documentation" ) | | | -|[`CC_NEWRELIC_TRANSACTION_TRACER_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-tt-enable "New Relic documentation" ) | | | -|[`CC_NEWRELIC_TRANSACTION_TRACER_RECORD_SQL`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-tt-sql "New Relic documentation" ) | obfuscated | | +| Name | Description | Default value | Read Only | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------------- | --------- | +| [`NEW_RELIC_APP_NAME`](https://docs.newrelic.com/docs/apm/agents/java-agent/configuration/java-agent-configuration-config-file/#ev-NEW_RELIC_APP_NAME "New Relic documentation") | Contains the application name | | | +| [`NEW_RELIC_LICENSE_KEY`](https://docs.newrelic.com/docs/apm/agents/java-agent/configuration/java-agent-configuration-config-file/#ev-NEW_RELIC_LICENSE_KEY "New Relic documentation" ) | Contains your New Relic account license | | | +| [`CC_NEWRELIC_BROWSER_MONITORING_AUTO_INSTRUMENT`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-autorum "New Relic documentation" ) | | | | +| [`CC_NEWRELIC_DISTRIBUTED_TRACING_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-distributed-enabled "New Relic documentation" ) | | | | +| [`CC_NEWRELIC_ERROR_COLLECTOR_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-err-enabled "New Relic documentation" ) | | | | +| [`CC_NEWRELIC_TRANSACTION_TRACER_ENABLED`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-tt-enable "New Relic documentation" ) | | | | +| [`CC_NEWRELIC_TRANSACTION_TRACER_RECORD_SQL`](https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-tt-sql "New Relic documentation" ) | obfuscated | | | ### Pulsar -| Name | Description | Default value | Read Only | -| ------------------------ | ----------------------------------------- | ------------------------------ | -------------------------- | -|`ADDON_PULSAR_BINARY_URL` | The complete URL to use in your application | Generated upon creation | ✓ | -|`ADDON_PULSAR_BINARY_PORT` | The port to connect to the Pulsar Cluster | Generated upon creation | ✓ | -|`ADDON_PULSAR_HOSTNAME` | The host to connect to the Pulsar Cluster | Generated upon creation | ✓ | -|`ADDON_PULSAR_HTTP_URL` | The complete URL to connect with WebSocket | Generated upon creation | ✓ | -|`ADDON_PULSAR_HTTP_PORT` | The port to connect with WebSocket | Generated upon creation | ✓ | -|`ADDON_PULSAR_NAMESPACE` | Your add-on Pulsar ID | Generated upon creation | ✓ | -|`ADDON_PULSAR_TENANT` | Your Clever Cloud tenant ID | Generated upon creation | ✓ | -|`ADDON_PULSAR_TOKEN` | Your Biscuit authentication token | Generated upon creation | ✓ | +| Name | Description | Default value | Read Only | +| -------------------------- | ------------------------------------------- | ----------------------- | --------- | +| `ADDON_PULSAR_BINARY_URL` | The complete URL to use in your application | Generated upon creation | ✓ | +| `ADDON_PULSAR_BINARY_PORT` | The port to connect to the Pulsar Cluster | Generated upon creation | ✓ | +| `ADDON_PULSAR_HOSTNAME` | The host to connect to the Pulsar Cluster | Generated upon creation | ✓ | +| `ADDON_PULSAR_HTTP_URL` | The complete URL to connect with WebSocket | Generated upon creation | ✓ | +| `ADDON_PULSAR_HTTP_PORT` | The port to connect with WebSocket | Generated upon creation | ✓ | +| `ADDON_PULSAR_NAMESPACE` | Your add-on Pulsar ID | Generated upon creation | ✓ | +| `ADDON_PULSAR_TENANT` | Your Clever Cloud tenant ID | Generated upon creation | ✓ | +| `ADDON_PULSAR_TOKEN` | Your Biscuit authentication token | Generated upon creation | ✓ | ### Redis [Redis Documentation](/doc/addons/redis) -| Name | Description | Default value | Read Only | -|-----------------------|------------------------------|--------------------------------|--------------------------------| -|`REDIS_HOST` | | Generated upon creation | ✓ | -|`REDIS_PORT` | | Generated upon creation | ✓ | -|`REDIS_PASSWORD` | | Generated upon creation | ✓ | +| Name | Description | Default value | Read Only | +| ---------------- | ----------- | ----------------------- | --------- | +| `REDIS_HOST` | | Generated upon creation | ✓ | +| `REDIS_PORT` | | Generated upon creation | ✓ | +| `REDIS_PASSWORD` | | Generated upon creation | ✓ | ### VPN @@ -619,15 +619,15 @@ to be routed through the exit node. > [!NOTE] > New setups use the `CC_VPN_*` names listed below. The previous `VPN_ADDON_*` names (and `VPN_TARGETS`) are deprecated and kept only for backward compatibility with existing setups. -| Name | Description | Default value | Read Only | -| --------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------ | -------------------------- | -| `CC_VPN_DNS_OVERRIDES` | Comma-separated list of DNS IP | | | -| `CC_VPN_CACRT` | Server CA certificate | | | -| `CC_VPN_CIPHER`| Cipher to use CIPHER, can be either {cipher_suite}:{hmac_alg} or only {cipher_suite} | DES-EDE3-CBC:SHA1 | | -| `CC_VPN_CRT` | Client certificate | | | -| `CC_VPN_DEVTYPE` | Kernel virtual interface kind to use ("tap" or "tun") | tap | | -| `CC_VPN_HOST` | Server host or IP address | | | -| `CC_VPN_KEY` | Client certificate private key | | | -| `CC_VPN_PORT` | Server port | | | -| `CC_VPN_TAKEY` | Pre-shared secret | | | -| `CC_VPN_TARGETS` | Comma-separated list of CIDRs for which you want the traffic to be routed through the exit node | | | +| Name | Description | Default value | Read Only | +| ---------------------- | ----------------------------------------------------------------------------------------------- | ----------------- | --------- | +| `CC_VPN_DNS_OVERRIDES` | Comma-separated list of DNS IP | | | +| `CC_VPN_CACRT` | Server CA certificate | | | +| `CC_VPN_CIPHER` | Cipher to use CIPHER, can be either {cipher_suite}:{hmac_alg} or only {cipher_suite} | DES-EDE3-CBC:SHA1 | | +| `CC_VPN_CRT` | Client certificate | | | +| `CC_VPN_DEVTYPE` | Kernel virtual interface kind to use ("tap" or "tun") | tap | | +| `CC_VPN_HOST` | Server host or IP address | | | +| `CC_VPN_KEY` | Client certificate private key | | | +| `CC_VPN_PORT` | Server port | | | +| `CC_VPN_TAKEY` | Pre-shared secret | | | +| `CC_VPN_TARGETS` | Comma-separated list of CIDRs for which you want the traffic to be routed through the exit node | | | diff --git a/content/guides/astro.md b/content/guides/astro.md index 87e929579..7160654fb 100644 --- a/content/guides/astro.md +++ b/content/guides/astro.md @@ -22,13 +22,16 @@ aliases: ## Overview Clever Cloud supports deploying both [fully static and on-demand rendered](https://docs.astro.build/en/basics/rendering-modes/) Astro projects: + - The `static` output mode is ideal for most content-oriented website, for which you have no need for per-visitor server-side customization. Consider using a [Static runtime](/doc/applications/static/) when using this output mode, with the automatic site generation. -- The `server` or `hybrid` output modes: consider using a [Node.js runtime](/doc/applications/nodejs) with [Astro’s Node adapter](https://docs.astro.build/en/guides/integrations-guide/node/) +- The `server` or `hybrid` output modes: consider using a [Node.js runtime](/doc/applications/nodejs) with [Astro’s Node adapter](https://docs.astro.build/en/guides/integrations-guide/node/) If you need an example source code, get [Astrowind](https://github.com/onwidget/astrowind) (you'll need [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [Node.js](https://nodejs.org/en/download)): + ```bash git clone https://github.com/onwidget/astrowind myStaticApp ``` + To deploy your Astro project to Clever Cloud, you need to **create a new application**. {{% steps %}} diff --git a/content/guides/docs.md b/content/guides/docs.md index bdf7cbb58..def109982 100644 --- a/content/guides/docs.md +++ b/content/guides/docs.md @@ -110,7 +110,7 @@ LOGIN_REDIRECT_URL="https://" LOGOUT_REDIRECT_URL="https:///*" ``` -#### Push your code +#### Push the backend code If you push using git, add the remote as `clever-backend`, for example. @@ -120,7 +120,7 @@ If you push using git, add the remote as `clever-backend`, for example. {{% steps %}} -#### Create a Node.js application +#### Create the frontend Node.js application Select at least a `M` instance for the build, and inject the following environment variables: @@ -139,7 +139,7 @@ NODE_OPTIONS="--max-old-space-size=4096" - Select **Domain names** and set the base domain for Docs. The frontend doesn't need any route. - Add the domain to the environment variables: inject `NEXT_PUBLIC_API_ORIGIN="https://"` to the list of the frontend environment variables. -#### Push your code +#### Push the frontend code If you push using git, add the remote as `clever-frontend`, for example. @@ -149,7 +149,7 @@ If you push using git, add the remote as `clever-frontend`, for example. {{% steps %}} -#### Create a Node.js application +#### Create the y-provider Node.js application Inject the following environment variables: @@ -187,7 +187,7 @@ COLLABORATION_SERVER_SECRET="" Then select the **backend** application > **Service dependencies** > **Link applications** and choose the y-provider application. -#### Push your code +#### Push the y-provider code If you push using git, add the remote as `clever-y-provider`, for example. @@ -245,7 +245,7 @@ Find it in **Clients > impress > credentials**, named **Client secret*. You can choose among different identity providers (GitHub, Google, etc, and even Clever Cloud). -#### Inject the variables in the **backend** application +#### Inject the Keycloak variables in the **backend** application ```env OIDC_OP_AUTHORIZATION_ENDPOINT="https:///realms/impress/protocol/openid-connect/auth" @@ -275,7 +275,7 @@ Docs uses s3 compatible storage to store uploaded files by users. #### Create a bucket -#### Inject the variables in the **backend** application +#### Inject the Cellar variables in the **backend** application ```env AWS_S3_ACCESS_KEY_ID="" @@ -292,5 +292,5 @@ AWS_RESPONSE_CHECKSUM_VALIDATION="when_required" ## 🎓 Further Help {{< cards >}} - {{< card link="https://github.com/suitenumerique/docs/blob/main/docs/installation/kubernetes.md#preparation" title="Docs documentation" subtitle="Installation instructions" icon="adjustments-horizontal" >}} + {{< card link="" title="Docs documentation" subtitle="Installation instructions" icon="adjustments-horizontal" >}} {{< /cards >}} diff --git a/content/guides/docusaurus.md b/content/guides/docusaurus.md index 5b7f00be2..fe9c756d3 100644 --- a/content/guides/docusaurus.md +++ b/content/guides/docusaurus.md @@ -45,5 +45,5 @@ clever scale --build-flavor M {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="https://docusaurus.io/docs" title="Learn Docusaurus" subtitle="How to write and organize your content" icon="docusaurus" >}} + {{< card link="" title="Learn Docusaurus" subtitle="How to write and organize your content" icon="docusaurus" >}} {{< /cards >}} diff --git a/content/guides/ekg-statsd-haskell-metrics.md b/content/guides/ekg-statsd-haskell-metrics.md index 476207a05..17b488e0d 100644 --- a/content/guides/ekg-statsd-haskell-metrics.md +++ b/content/guides/ekg-statsd-haskell-metrics.md @@ -26,10 +26,10 @@ If you're using [warp](https://hackage.haskell.org/package/warp), you can use `w You need the following packages in your [dependencies](/doc/applications/haskell#dependencies): -* ekg-core -* ekg-statsd -* scotty -* wai-middleware-metrics +- ekg-core +- ekg-statsd +- scotty +- wai-middleware-metrics Then add this Hello World code to your application and modify it to fit your needs: diff --git a/content/guides/eleventy.md b/content/guides/eleventy.md index 38e874910..ab4bded01 100644 --- a/content/guides/eleventy.md +++ b/content/guides/eleventy.md @@ -47,5 +47,5 @@ clever env set CC_BUILD_COMMAND "npx @11ty/eleventy" {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="https://www.11ty.dev/docs/" title="Learn Eleventy (11ty)" subtitle="How to write and organize your content" icon="11ty" >}} + {{< card link="" title="Learn Eleventy (11ty)" subtitle="How to write and organize your content" icon="11ty" >}} {{< /cards >}} diff --git a/content/guides/fluentd.md b/content/guides/fluentd.md index b846365df..371f1844c 100644 --- a/content/guides/fluentd.md +++ b/content/guides/fluentd.md @@ -19,11 +19,11 @@ aliases: Since you deploy microservices on Clever Cloud, you may need some data pipes between your services to: -* collect data from your PostgreSQL to create Elasticsearch indexes for your website search engine -* collect application logs to analyze them with Elasticsearch, then archive them with S3 -* collect Apache access logs to analyze them in MongoDB -* extract data from the database of your PHP/MySQL application to transform then load them in your other node.js/PostgreSQL application -* and many more … +- collect data from your PostgreSQL to create Elasticsearch indexes for your website search engine +- collect application logs to analyze them with Elasticsearch, then archive them with S3 +- collect Apache access logs to analyze them in MongoDB +- extract data from the database of your PHP/MySQL application to transform then load them in your other node.js/PostgreSQL application +- and many more … Fluentd is an open source data collector written in Ruby, which lets you unify the data collection and consumption for a better use and understanding of data. @@ -41,12 +41,12 @@ Fluentd is an open source data collector written in Ruby, which lets you unify t To follow this tutorial, you will need: -* Ruby >= 2.4.4 (w/ Rubygems) -* Bundler -* Docker -* Git -* curl -* a Ruby versions manager +- Ruby >= 2.4.4 (w/ Rubygems) +- Bundler +- Docker +- Git +- curl +- a Ruby versions manager {{< callout type="info" >}} To manage your gems and ruby versions, we recommend [rbenv](https://github.com/sstephenson/rbenv). diff --git a/content/guides/ghost.md b/content/guides/ghost.md index 629f8ac8f..9220aa68d 100644 --- a/content/guides/ghost.md +++ b/content/guides/ghost.md @@ -273,7 +273,7 @@ The rebuild downloads the selected release and installs dependencies for the con ## Learn more {{< cards >}} - {{< card link="https://docs.ghost.org/" title="Ghost documentation" subtitle="Configure and manage a Ghost publication" icon="ghost" >}} + {{< card link="" title="Ghost documentation" subtitle="Configure and manage a Ghost publication" icon="ghost" >}} {{< card link="/developers/doc/applications/linux" title="Linux application runtime" subtitle="Configure and deploy any application" icon="linux" >}} {{< card link="/developers/doc/addons/mysql" title="MySQL" subtitle="Explore managed MySQL databases" icon="mysql" >}} {{< card link="/developers/doc/addons/cellar" title="Cellar" subtitle="Explore S3-compatible object storage" icon="cellar" >}} diff --git a/content/guides/go-echoip.md b/content/guides/go-echoip.md index 18dc402ed..3acf76c65 100644 --- a/content/guides/go-echoip.md +++ b/content/guides/go-echoip.md @@ -19,14 +19,13 @@ This doc explains how to install and configure EchoIP from source, and how to de ## How to Configure and Deploy EchoIP on Clever Cloud - ### Download EchoIP You can download EchoIP from and create a new origin. - First clone EchoIP's repository: -``` + +```bash ~ $ git clone https://github.com/mpolden/echoip.git ~ $ cd echoip ``` @@ -34,7 +33,8 @@ First clone EchoIP's repository: ### Configure `clevercloud/go.json` Create the necessary files to build and run the application: -``` + +```text echoip/ ~ $ mkdir clevercloud echoip/ ~ $ cat << EOF > clevercloud/go.json { @@ -48,33 +48,31 @@ echoip/ ~ $ git add clevercloud/ echoip/ ~ $ git commit -m "add clevercloud files" clevercloud/ ``` - {{% content "set-env-vars" %}} - - Define necessary environment variables (this is specific to EchoIP): -``` + +```text echoip/ ~ $ clever env set CC_RUN_COMMAND "~/go_home/bin/echoip -H X-Forwarded-For" Your environment variable has been successfully saved ``` - {{% content "deploy-git" %}} - - Add the clevercloud git remote: -``` + +```text echoip/ ~ $ git remote add clevercloud $(jq -r '.apps[0].git_ssh_url' < .clever.json) ``` Push the app for deployment: -``` + +```text echoip/ ~ $ git push clevercloud master ``` Check the deployment logs: -``` + +```text echoip/ ~ $ clever logs ``` diff --git a/content/guides/hexo.md b/content/guides/hexo.md index 733f7df51..358fee64c 100644 --- a/content/guides/hexo.md +++ b/content/guides/hexo.md @@ -18,6 +18,7 @@ keywords: ## Requirements If you need an example source code, initialize an Hexo project with [Cactus theme](https://github.com/probberechts/hexo-theme-cactus) (you'll need [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [Node.js](https://nodejs.org/en/learn/getting-started/how-to-install-nodejs)): + ```bash npx hexo init myStaticApp --no-install ``` @@ -51,5 +52,5 @@ clever env set CC_BUILD_COMMAND "npm run build" {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="https://hexo.io/docs/" title="Learn Hexo" subtitle="How to write and organize your content" icon="hexo" >}} + {{< card link="" title="Learn Hexo" subtitle="How to write and organize your content" icon="hexo" >}} {{< /cards >}} diff --git a/content/guides/hono.md b/content/guides/hono.md index cbb46bb2c..6b4662123 100644 --- a/content/guides/hono.md +++ b/content/guides/hono.md @@ -32,7 +32,7 @@ To deploy your Hono project to Clever Cloud, adapt its entry point, then create ### Adapt the entry point -The `nodejs` template's `src/index.ts` starts a server on port 3000 and has no shutdown handling. Adapt both behaviours before deploying. +The `nodejs` template's `src/index.ts` starts a server on port 3000 and has no shutdown handling. Adapt both behaviours before deploying. Clever Cloud sets `PORT` environment variable to `8080` by default and expects the application to listen on every network interface. Read it rather than hardcoding this value to remain compatible with [Request Flow port allocation](/developers/doc/develop/request-flow/#port-management), keep port 3000 as a local fallback, and set the hostname to `0.0.0.0`. Also close the server on `SIGINT` and `SIGTERM` so in-flight requests can finish during a restart or zero-downtime deployment: @@ -125,5 +125,5 @@ clever domain add your.website.tld {{< cards >}} {{< card link="/developers/doc/applications/nodejs" title="Deploy a Node.js application" subtitle="Learn more on deploying a Node.js application" icon="node" >}} - {{< card link="https://hono.dev/docs" title="Hono documentation" subtitle="Learn more about the Hono framework" icon="hono" >}} + {{< card link="" title="Hono documentation" subtitle="Learn more about the Hono framework" icon="hono" >}} {{< /cards >}} diff --git a/content/guides/hugo-static-s3.md b/content/guides/hugo-static-s3.md index 9704809f8..772cd5543 100644 --- a/content/guides/hugo-static-s3.md +++ b/content/guides/hugo-static-s3.md @@ -52,7 +52,7 @@ To make your bucket publicly accessible, you have to apply a policy to the bucke To set your bucket as public, you have to apply the following policy which you can save in a file named `policy.json`: -```json{filename="policy.json"} +```json {filename="policy.json"} { "Id": "Policy1587216857769", "Version": "2012-10-17", diff --git a/content/guides/hugo.md b/content/guides/hugo.md index ec655a365..36f1115a9 100644 --- a/content/guides/hugo.md +++ b/content/guides/hugo.md @@ -54,5 +54,5 @@ clever scale --build-flavor M {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="https://gohugo.io/documentation/" title="Learn Hugo" subtitle="How to write and organize your content" icon="hugo" >}} + {{< card link="" title="Learn Hugo" subtitle="How to write and organize your content" icon="hugo" >}} {{< /cards >}} diff --git a/content/guides/kibana.md b/content/guides/kibana.md index 6368fdacc..5d4f0fcbd 100644 --- a/content/guides/kibana.md +++ b/content/guides/kibana.md @@ -32,7 +32,7 @@ Kibana can be enabled at the add-on creation. Choose "Create an add-on" > "Elast You can customize the Kibana configuration file by setting the `CC_PRE_RUN_HOOK` environment variable. This variable will be executed before the Kibana instance starts. By default, it is: -``` +```text CC_PRE_RUN_HOOK` = `curl https://api.clever-cloud.com/v2/providers/es-addon/kibana-setup/ | sh` ``` @@ -47,7 +47,7 @@ Check other available configuration file on [GitHub](https://github.com/CleverCl To disable SSO authentication and use elastic users instead, you need to modify Kibana's configuration file. We provide an example configuration file for Kibana 8.3.3: -* https://raw.githubusercontent.com/CleverCloud/custom-kibana-config/master/8.3.3/no-sso-8.3.3 +- Remember, you need to ask Clever Cloud Support team to grant superuser permissions to your user. After that, you will be able to add additional users via Kibana. @@ -55,7 +55,7 @@ Remember, you need to ask Clever Cloud Support team to grant superuser permissio If you need to allow for multiple authentication methods to your Kibana, you need to modify Kibana's configuration. We provide an example configuration file for Kibana 8.10.2: -* https://raw.githubusercontent.com/CleverCloud/custom-kibana-config/master/8.10.2/sso-basic-8.10.2 +- ### Add custom domain name @@ -69,9 +69,9 @@ Follow these steps : 1. Download/unzip Kibana in version which match with your Elastic Stack version 2. Edit kibana.yml : - * line 43 : `elasticsearch.host: :443` - * line 49 : `elasticsearch.username: kibana` - * line 50 : `elasticsearch.password: ` - * Launch Kibana (`/bin/kibana`) + - line 43 : `elasticsearch.host: :443` + - line 49 : `elasticsearch.username: kibana` + - line 50 : `elasticsearch.password: ` + - Launch Kibana (`/bin/kibana`) 3. Go to Kibana through the dedicated local address: `http://localhost:5601` 4. Connect to ElasticSearch with your Elastic username and password diff --git a/content/guides/lume-deno.md b/content/guides/lume-deno.md index 78bd57ad9..a816b4aa9 100644 --- a/content/guides/lume-deno.md +++ b/content/guides/lume-deno.md @@ -22,6 +22,7 @@ If you need an example source code, use the [Lume website](https://github.com/lu ```bash git clone https://github.com/lumeland/lume.land myStaticApp ``` + {{% content "static-create" %}} ### Environment variables @@ -58,5 +59,5 @@ It uses [Mise package manager](/doc/reference/reference-environment-variables/#i {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="https://lume.land/docs/overview/about-lume/" title="Learn Lume" subtitle="How to write and organize your content" icon="deno" >}} + {{< card link="" title="Learn Lume" subtitle="How to write and organize your content" icon="deno" >}} {{< /cards >}} diff --git a/content/guides/mdbook.md b/content/guides/mdbook.md index 16d4cd569..54b7eebd8 100644 --- a/content/guides/mdbook.md +++ b/content/guides/mdbook.md @@ -43,5 +43,5 @@ clever scale --build-flavor M {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="https://rust-lang.github.io/mdBook/" title="Learn mdBook" subtitle="How to write and organize your content" icon="mdbook" >}} + {{< card link="" title="Learn mdBook" subtitle="How to write and organize your content" icon="mdbook" >}} {{< /cards >}} diff --git a/content/guides/mkdocs.md b/content/guides/mkdocs.md index f1a82d3fb..c7683aedb 100644 --- a/content/guides/mkdocs.md +++ b/content/guides/mkdocs.md @@ -24,6 +24,7 @@ pipx mkdocs new myStaticApp ``` You can also use [uvx](https://docs.astral.sh/uv/guides/tools/): + ```bash uvx mkdocs new myStaticApp ``` @@ -47,5 +48,5 @@ clever scale --build-flavor M {{< cards >}} {{< card link="/developers/doc/applications/static" title="Static runtime documentation" subtitle="How to configure your website" icon="static" >}} - {{< card link="https://www.mkdocs.org/getting-started/" title="MkDocs documentation" subtitle="How to write and organize your content" icon="docs" >}} + {{< card link="" title="MkDocs documentation" subtitle="How to write and organize your content" icon="docs" >}} {{< /cards >}} diff --git a/content/guides/moodle.md b/content/guides/moodle.md index 9313c46d2..845d95cce 100644 --- a/content/guides/moodle.md +++ b/content/guides/moodle.md @@ -136,7 +136,6 @@ Create a `clevercloud/cron.json` file with a string to run `cron.sh`every minute You might encounter errors when the Cron tries to access `moodledata` in your FS Bucket. For FS Bucket backups, look for a dedicated tool like [rclone](https://rclone.org). - ## 🎓 Further Help {{< cards >}} @@ -144,7 +143,7 @@ You might encounter errors when the Cron tries to access `moodledata` in your FS {{< card link="/developers/doc/administrate/cron" title="CRON" subtitle="Set up a CRON job for your app" icon="code-bracket" >}} {{< card link="/developers/doc/addons/fs-bucket" title="FS Bucket" subtitle="External File System for your apps" icon="fsbucket" >}} {{< card link="/developers/doc/addons/mysql" title="MySQL" icon="mysql" subtitle="Your self-hosted managed relational database" >}} - {{< card link="https://docs.moodle.org/en/Installation_quick_guide" title="Moodle Documentation" subtitle="Check Moodle installation guide" icon="moodle" >}} + {{< card link="" title="Moodle Documentation" subtitle="Check Moodle installation guide" icon="moodle" >}} {{< /cards >}} See [Moodle installation documentation](https://docs.moodle.org/en/Installation_quick_guide) for further help and development configuration. diff --git a/content/guides/node-js-mongo-db.md b/content/guides/node-js-mongo-db.md index a4d39910b..617141307 100644 --- a/content/guides/node-js-mongo-db.md +++ b/content/guides/node-js-mongo-db.md @@ -19,7 +19,7 @@ aliases: The goal of this article is to show you how to deploy a Node.js + MongoDB application on Clever Cloud. The application is a very simple todo list. You can add and delete values. More information about the application: -* [GitHub repo](https://github.com/CleverCloud/demo-nodejs-mongodb-rest) +- [GitHub repo](https://github.com/CleverCloud/demo-nodejs-mongodb-rest) {{% content "create-application" %}} diff --git a/content/guides/nuxt.md b/content/guides/nuxt.md index 21d796ccc..901797471 100644 --- a/content/guides/nuxt.md +++ b/content/guides/nuxt.md @@ -33,7 +33,7 @@ git clone https://github.com/renegadevi/nuxt-boilerplate myStaticApp Clever Tools targets your personal organisation by default. To use another organisation, add `--org ORGANISATION` or `-o ORGANISATION` when you create or link the application. -### Automatic build +## Automatic build The Static runtime automatically detects `nuxt.config.ts`, runs the Nuxt static generation command and serves the generated files. @@ -95,5 +95,5 @@ clever domain add your.website.tld {{< cards >}} {{< card link="/developers/doc/applications/nodejs" title="Deploy a Node.js application" subtitle="Learn more on deploying a Node.js application" icon="node" >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="Learn more on deploying a Static application" icon="static" >}} - {{< card link="https://nuxt.com/docs/4.x/getting-started/introduction" title="Learn Nuxt" subtitle="How to write and organize your content" icon="nuxt" >}} + {{< card link="" title="Learn Nuxt" subtitle="How to write and organize your content" icon="nuxt" >}} {{< /cards >}} diff --git a/content/guides/outline.md b/content/guides/outline.md index 4e17dd356..430676072 100644 --- a/content/guides/outline.md +++ b/content/guides/outline.md @@ -205,14 +205,14 @@ clever scale --build-flavor M Outline needs at least one authentication method before users can sign in and supports the following methods: -| Authentication method | Required variables | Callback URL | -| --- | --- | --- | -| Discord | `DISCORD_CLIENT_ID`, `DISCORD_CLIENT_SECRET` | `$URL/auth/discord.callback` | -| Email magic links | `SMTP_HOST` or `SMTP_SERVICE`, `SMTP_FROM_EMAIL` | — | -| Google | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | `$URL/auth/google.callback` | -| Microsoft Entra ID | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET` | `$URL/auth/azure.callback` | -| OpenID Connect | `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `OIDC_ISSUER_URL` | `$URL/auth/oidc.callback` | -| Slack | `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET` | `$URL/auth/slack.callback` | +| Authentication method | Required variables | Callback URL | +| --------------------- | --------------------------------------------------------- | ---------------------------- | +| Discord | `DISCORD_CLIENT_ID`, `DISCORD_CLIENT_SECRET` | `$URL/auth/discord.callback` | +| Email magic links | `SMTP_HOST` or `SMTP_SERVICE`, `SMTP_FROM_EMAIL` | — | +| Google | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | `$URL/auth/google.callback` | +| Microsoft Entra ID | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET` | `$URL/auth/azure.callback` | +| OpenID Connect | `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `OIDC_ISSUER_URL` | `$URL/auth/oidc.callback` | +| Slack | `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET` | `$URL/auth/slack.callback` | Email magic links require a complete [SMTP configuration](https://docs.getoutline.com/s/hosting/doc/smtp-cqCJyZGMIB), including the credentials and connection settings required by your email provider. Configure the matching callback URL in your provider, then set its variables. For OpenID Connect, also allow the application URL (`$URL`) as a post-logout redirect URI if the provider exposes a logout endpoint. For example: @@ -267,5 +267,5 @@ Replace the example values with the versions you selected. Outline applies pendi {{< card link="/developers/doc/addons/postgresql" title="PostgreSQL" subtitle="Explore managed PostgreSQL databases" icon="pg" >}} {{< card link="/developers/doc/addons/redis" title="Redis" subtitle="Explore managed Redis databases" icon="redis" >}} {{< card link="/developers/doc/addons/cellar" title="Cellar" subtitle="Explore S3-compatible object storage" icon="fsbucket" >}} - {{< card link="https://docs.getoutline.com/s/hosting" title="Outline hosting documentation" subtitle="Learn more about self-hosting Outline" icon="outline" >}} + {{< card link="" title="Outline hosting documentation" subtitle="Learn more about self-hosting Outline" icon="outline" >}} {{< /cards >}} diff --git a/content/guides/pgpool.md b/content/guides/pgpool.md index cde7f3642..87ca4bde7 100644 --- a/content/guides/pgpool.md +++ b/content/guides/pgpool.md @@ -111,7 +111,7 @@ For the `HOST` and `PORT`, you must use the values of the `POSTGRESQL_ADDON_DIRE An example of the `CC_PGPOOL_FOLLOWERS` variable with two followers: -```json{linenos=table} +```json {linenos=table} [ { "hostname": "", diff --git a/content/guides/ruby-rack-app-tutorial.md b/content/guides/ruby-rack-app-tutorial.md index 83a769a37..dacc41f75 100644 --- a/content/guides/ruby-rack-app-tutorial.md +++ b/content/guides/ruby-rack-app-tutorial.md @@ -24,10 +24,10 @@ Created in 2007, Rack has become the de-facto standard for ruby web applications To follow this tutorial, you will need: -* Ruby >= 1.9.2 (w/ Rubygems) -* Bundler (`gem install bundler` and you're good to go!) -* Your preferred editor -* Git (for the deploy part) +- Ruby >= 1.9.2 (w/ Rubygems) +- Bundler (`gem install bundler` and you're good to go!) +- Your preferred editor +- Git (for the deploy part) {{< callout type="info">}} To manage your gems and ruby versions, we recommend [rbenv](https://github.com/sstephenson/rbenv). If you use a system-wide installation of ruby, You will have to use `sudo` with the `gem` and `bundle` commands, or use arguments that will make gem and bundle install the gem in directories you have write-permissions in. diff --git a/content/guides/ruby-rack.md b/content/guides/ruby-rack.md index 4323d5493..2a507035c 100644 --- a/content/guides/ruby-rack.md +++ b/content/guides/ruby-rack.md @@ -29,10 +29,10 @@ Created in 2007, Rack has become the de-facto standard for ruby web applications Be sure that: -* Bundler is installed locally (`gem install bundler`) -* you have a `config.ru` file -* Git (for the deploy part) -* you have a `gems.rb` or `Gemfile` containing your dependencies +- Bundler is installed locally (`gem install bundler`) +- you have a `config.ru` file +- Git (for the deploy part) +- you have a `gems.rb` or `Gemfile` containing your dependencies ### Tutorial and sample app diff --git a/content/guides/sftpgo.md b/content/guides/sftpgo.md index e7789347e..f9f0082d8 100644 --- a/content/guides/sftpgo.md +++ b/content/guides/sftpgo.md @@ -164,15 +164,15 @@ A new Cellar add-on does not contain a bucket. Create one with Cellar Explorer i Create a user in the SFTPGo web administration interface and select **S3-compatible** as its storage provider: -| Setting | Value | -| ------- | ----- | -| Bucket | Your Cellar bucket name | -| Home Dir | `/tmp/sftpgo` | -| Region | `default` | -| Access Key | The `CELLAR_ADDON_KEY_ID` value | -| Access Secret | The `CELLAR_ADDON_KEY_SECRET` value | -| Endpoint | `https://` followed by the `CELLAR_ADDON_HOST` value | -| Use path-style addressing | Enabled | +| Setting | Value | +| ------------------------- | ---------------------------------------------------- | +| Bucket | Your Cellar bucket name | +| Home Dir | `/tmp/sftpgo` | +| Region | `default` | +| Access Key | The `CELLAR_ADDON_KEY_ID` value | +| Access Secret | The `CELLAR_ADDON_KEY_SECRET` value | +| Endpoint | `https://` followed by the `CELLAR_ADDON_HOST` value | +| Use path-style addressing | Enabled | SFTPGo requires a local home directory for temporary files when using S3-compatible storage. The startup task creates `/tmp/sftpgo` on every application instance. The open-source edition [uses unlinked local files for transfers to and from object storage](https://github.com/drakkan/sftpgo/discussions/1968), so a transfer can temporarily consume its full size on the instance disk. Account for the largest expected files and simultaneous transfers when choosing the run instance; completed files remain stored in Cellar, but in-progress transfers can fail if local disk is exhausted. @@ -271,5 +271,5 @@ Use any SFTP client with the following settings: {{< card link="/developers/doc/applications/linux" title="Linux applications" subtitle="Deploy any application" icon="linux" >}} {{< card link="/developers/doc/addons/cellar" title="Cellar object storage" subtitle="Store files with an S3 API" icon="database" >}} {{< card link="/developers/doc/addons/fs-bucket" title="FS Buckets" subtitle="Store files with SFTP access" icon="fsbucket" >}} - {{< card link="https://docs.sftpgo.com/latest/" title="SFTPGo documentation" subtitle="Configure users and storage" icon="book-open" >}} + {{< card link="" title="SFTPGo documentation" subtitle="Configure users and storage" icon="book-open" >}} {{< /cards >}} diff --git a/content/guides/sveltekit.md b/content/guides/sveltekit.md index 54e28dd2b..f8d57b06f 100644 --- a/content/guides/sveltekit.md +++ b/content/guides/sveltekit.md @@ -228,5 +228,5 @@ clever domain add your.website.tld {{< cards >}} {{< card link="/developers/doc/applications/nodejs/" title="Node.js applications" subtitle="Configure and deploy Node.js applications" icon="node" >}} {{< card link="/developers/doc/applications/static/" title="Static applications" subtitle="Configure and deploy static applications" icon="static" >}} - {{< card link="https://svelte.dev/docs/kit/adapters" title="SvelteKit adapters" subtitle="Choose and configure a SvelteKit adapter" icon="svelte" >}} + {{< card link="" title="SvelteKit adapters" subtitle="Choose and configure a SvelteKit adapter" icon="svelte" >}} {{< /cards >}} diff --git a/content/guides/tutorial-drupal.md b/content/guides/tutorial-drupal.md index 520eb884b..a102a4054 100644 --- a/content/guides/tutorial-drupal.md +++ b/content/guides/tutorial-drupal.md @@ -39,9 +39,9 @@ Make sure you have created a MySQL database add-on in the Clever Cloud console, We at this point assume you have downloaded the source files of drupal from [drupal.org](https://new.drupal.org/download) and already have linked your MySQL add-on. -* Open `.gitignore` file and delete `sites/*/settings*.php` line -* Copy the file `sites/default/default.settings.php` to `sites/default/settings.php` -* Open `sites/default/settings.php` and line 213, replace +- Open `.gitignore` file and delete `sites/*/settings*.php` line +- Copy the file `sites/default/default.settings.php` to `sites/default/settings.php` +- Open `sites/default/settings.php` and line 213, replace ```php{linenos=table} $databases = array(); @@ -67,12 +67,12 @@ by ); ``` -* Replace the line `$settings['hash_salt'] = ''` (`$drupal_hash_salt` for Drupal 7) with `$settings['hash_salt'] = getenv('DRUPAL_SALT')`. You can generate salts with [this link](https://www.passwordtool.hu/). Add a new `DRUPAL_SALT` [environment variable](/doc/applications/php#configure-your-php-application) to the application with the salt you have generated. -* As mentioned in this [article](/doc/addons/fs-bucket), with Git deployments, files that are uploaded by users must be +- Replace the line `$settings['hash_salt'] = ''` (`$drupal_hash_salt` for Drupal 7) with `$settings['hash_salt'] = getenv('DRUPAL_SALT')`. You can generate salts with [this link](https://www.passwordtool.hu/). Add a new `DRUPAL_SALT` [environment variable](/doc/applications/php#configure-your-php-application) to the application with the salt you have generated. +- As mentioned in this [article](/doc/addons/fs-bucket), with Git deployments, files that are uploaded by users must be persisted in a File System Bucket. In order to do so, [add a File Bucket](/doc/addons/fs-bucket) via the console. -* At the root of your application, create a `clevercloud/buckets.json` file (create a `clevercloud` +- At the root of your application, create a `clevercloud/buckets.json` file (create a `clevercloud` folder in which you create a `buckets.json` file). -* Copy the `bucket.json` content from the FS bucket addon dashboard (make sure to edit the `folder` field): +- Copy the `bucket.json` content from the FS bucket addon dashboard (make sure to edit the `folder` field): ```javascript{linenos=table} [ @@ -83,8 +83,8 @@ folder in which you create a `buckets.json` file). ] ``` -* Send these Drupal files via Git. -* When finished, get the url that you can find in the *domains* panel in the left sidebar. Then open the following link: +- Send these Drupal files via Git. +- When finished, get the url that you can find in the *domains* panel in the left sidebar. Then open the following link: `https://yourapplication.cleverapps.io/install.php` diff --git a/content/guides/tutorial-laravel.md b/content/guides/tutorial-laravel.md index f2b3de230..b78f58781 100644 --- a/content/guides/tutorial-laravel.md +++ b/content/guides/tutorial-laravel.md @@ -176,5 +176,5 @@ This environment variable exists in any Clever Cloud instance. This configuratio {{< card link="/developers/doc/metrics/new-relic" title="Monitor your App with New Relic" subtitle="Connect your application to New Relic." icon="new-relic" >}} {{< card link="/developers/doc/addons/fs-bucket" title="FS Bucket" subtitle="External File System for your apps" icon="fsbucket" >}} {{< card link="/developers/doc/develop/build-hooks" title="Deployment hooks" subtitle="Learn about custom commands used in this guide." icon="rocket-launch" >}} - {{< card link="https://laravel.com/docs/10.x/deployment" title="Laravel Documentation" subtitle="Read Laravel documentation on deployments." icon="laravel" >}} + {{< card link="" title="Laravel Documentation" subtitle="Read Laravel documentation on deployments." icon="laravel" >}} {{< /cards >}} diff --git a/content/guides/tutorial-symfony.md b/content/guides/tutorial-symfony.md index b60d1404d..012316916 100644 --- a/content/guides/tutorial-symfony.md +++ b/content/guides/tutorial-symfony.md @@ -58,7 +58,7 @@ You can anyway add your environment with any of the methods mentioned in [Settin For your application logs to be collected and available in the console and CLI, you need to configure monolog to use its `error_log` output. That does not mean that it will only output error level logs, you can set it to use any level, here is an example with the info level (and above): -```yaml{filename="config_prod.yml"} +```yaml {filename="config_prod.yml"} monolog: handlers: filter_for_errors: @@ -82,7 +82,7 @@ You can use the `CC_REVERSE_PROXY_IPS` [environment variable](#setting-up-enviro TRUSTED_PROXIES=127.0.0.1,${CC_REVERSE_PROXY_IPS} ``` -```yaml{filename="config/packages/framework.yaml"} +```yaml {filename="config/packages/framework.yaml"} framework: # … trusted_proxies: '%env(TRUSTED_PROXIES)%' @@ -113,7 +113,7 @@ To manage your connection pool towards your MySQL add-on, you can set-up a [Prox Once you have activated the ProxySQL (through the environment variable), a configuration example would be: -```yaml{filename="doctrine.yaml"} +```yaml {filename="doctrine.yaml"} dbal: unix_socket: '%env(CC_MYSQL_PROXYSQL_SOCKET_PATH)%' url: 'mysql://%env(MYSQL_ADDON_USER)%:%env(MYSQL_ADDON_PASSWORD)%@localhost/%env(MYSQL_ADDON_DB)%?serverVersion=%env(MYSQL_ADDON_VERSION)%' diff --git a/content/guides/tutorial-wordpress.md b/content/guides/tutorial-wordpress.md index 44b5a328e..b89ed3bcc 100644 --- a/content/guides/tutorial-wordpress.md +++ b/content/guides/tutorial-wordpress.md @@ -51,7 +51,7 @@ define( 'DB_HOST', getenv("MYSQL_ADDON_HOST").':'.getenv("MYSQL_ADDON_PORT") ); ``` {{< callout type="warning" >}} -**Make sure you use ** in `wp-config.php` the port the add-on dashboard provides. Use the `MYSQL_ADDON_PORT` environment variable for that. We **don't** use the default MySQL port. +**Make sure you use** in `wp-config.php` the port the add-on dashboard provides. Use the `MYSQL_ADDON_PORT` environment variable for that. We **don't** use the default MySQL port. {{< /callout >}} ### SSL Configuration diff --git a/content/postmortem/2024-08-02.md b/content/postmortem/2024-08-02.md index 3a6e08826..a2b5a6bf2 100644 --- a/content/postmortem/2024-08-02.md +++ b/content/postmortem/2024-08-02.md @@ -14,8 +14,8 @@ On Friday, August 2nd, 2024 Clever Cloud’s platform became unstable, leading t These events occurred because: -* A planned minor maintenance of the Messaging component has locked the cluster causing an incident ([www.clevercloudstatus.com/incidents/880](https://www.clevercloudstatus.com/incidents/880)) between **2:00 PM CEST** and **2:29 PM CEST** -* As an indirect consequence, the infrastructure experienced I/O and memory pressure between **3:40 PM CEST** and **4:16 PM CEST** causing some hypervisors to crash. +- A planned minor maintenance of the Messaging component has locked the cluster causing an incident ([www.clevercloudstatus.com/incidents/880](https://www.clevercloudstatus.com/incidents/880)) between **2:00 PM CEST** and **2:29 PM CEST** +- As an indirect consequence, the infrastructure experienced I/O and memory pressure between **3:40 PM CEST** and **4:16 PM CEST** causing some hypervisors to crash. Impacts were observed for customers relying on the EU-FR-1 (PAR) region, and remote zones depending on the EU-FR-1 control plane (OVHcloud, Scaleway, and Oracle). Privates and on-premise zones weren’t impacted. @@ -593,17 +593,17 @@ Some of our hypervisors had processes stuck in `TASK_UNINTERRUPTIBLE` for too lo During the event, the monitoring infrastructure triggered a lot of events for both infrastructure and customer services. We observed almost x3 deployments as usual during that day. Multiple reasons can explain this observation: -* The loss of hypervisors due to kernel panics made a lot of instances unreachable, leading to lots of deployments to honor the contract (e.g. number of minimum instances) -* VMs that were under memory pressure were usually unresponsive and so they were (correctly) seen as unreachable -* VMs that were on overloaded hypervisors might have also been slowed down due to the high CPU usage of the hypervisor. Those VMs had less CPU time to do their usual operations, making their load average increase. Our monitoring took that as an increase of CPU usage and they were ordered to upscale if they were configured to -* Some of our monitoring instances took more time to do their checks because they were overloaded as well. Because the monitoring data was missing due to late checks, it was interpreted as lack of data and so as unreachable VMs, triggering more Monitoring/Unreachable events -* Customers seeing their service unavailable are trying to trigger redeployment of their applications, which adds more scheduling tasks on the infrastructure +- The loss of hypervisors due to kernel panics made a lot of instances unreachable, leading to lots of deployments to honor the contract (e.g. number of minimum instances) +- VMs that were under memory pressure were usually unresponsive and so they were (correctly) seen as unreachable +- VMs that were on overloaded hypervisors might have also been slowed down due to the high CPU usage of the hypervisor. Those VMs had less CPU time to do their usual operations, making their load average increase. Our monitoring took that as an increase of CPU usage and they were ordered to upscale if they were configured to +- Some of our monitoring instances took more time to do their checks because they were overloaded as well. Because the monitoring data was missing due to late checks, it was interpreted as lack of data and so as unreachable VMs, triggering more Monitoring/Unreachable events +- Customers seeing their service unavailable are trying to trigger redeployment of their applications, which adds more scheduling tasks on the infrastructure Our monitoring infrastructure, by observation of many key metrics (CPU Loads, CPU Steal, Availability, health checks, etc.) triggered a significantly higher rate of deployments, which at the time, wasn’t helping both to chill down the control plane already processing at the best it could and the overall infrastructure already overloaded. ### Soothing the control plane -Once we understood some Virtual Machines (VMs) were inducing an abnormal high load on Hypervisors (HVs), we started to filter out machines that could help to free some resources. All non critical services have been shut down like the Observability platform: We stopped the _Long Term Storage for Observability_ metrics data (our Warp10/FoundationDB cluster). Critical services benefit from In Memory Observability (Warp10 in memory standalones), so this was acceptable to preserve all available resources. +Once we understood some Virtual Machines (VMs) were inducing an abnormal high load on Hypervisors (HVs), we started to filter out machines that could help to free some resources. All non critical services have been shut down like the Observability platform: We stopped the *Long Term Storage for Observability* metrics data (our Warp10/FoundationDB cluster). Critical services benefit from In Memory Observability (Warp10 in memory standalones), so this was acceptable to preserve all available resources. Overloaded VMs were collected, sorted and it appeared they shared a common pattern: they were small VMs with few memory resources. The reason has been covered a few lines above. The process after identifying them is obviously to kill them one by one by the SRE team. Nothing fancy here, but soon we started to regain control over all hypervisors. @@ -611,34 +611,34 @@ Overloaded VMs were collected, sorted and it appeared they shared a common patte We’ve learnt many lessons this Friday and we already identified many enhancements we will give to the platform. Sure this kind of incident occurring during a summer holiday period is tricky, but we escalated the problem quickly to call people on holiday as soon as 13:00 CEST. We identified two groups of enhancements. A first one, measurable, and identified as a key infrastructure management where some of the measurement are : -* Pulsar Broker health -* Pulsar Cluster health -* Hypervisor load -* Hypervisor I/O -* Hypervisor reboot (Kernel Panic) -* Zombies VM -* RabbitMQ Broker health -* RabbitMQ Cluster health -* Deployment queue consumption +- Pulsar Broker health +- Pulsar Cluster health +- Hypervisor load +- Hypervisor I/O +- Hypervisor reboot (Kernel Panic) +- Zombies VM +- RabbitMQ Broker health +- RabbitMQ Cluster health +- Deployment queue consumption These measurements give us KPIs to measure where we've been operationally good, and where we have lacked some visibility or reaction. We qualified them with four inputs: -* Time of event -* Time of detection -* Time of decision -* Time of resolution +- Time of event +- Time of detection +- Time of decision +- Time of resolution This factual approach helped to challenge ourselves on established rules and showed we can improve or rethink some part of the infrastructure. Other topics raised but without KPI analysis: -* Dealing with too many monitoring alerts -* Backup Bastion — a regional bastion is vulnerable -* Control Plane recovery process -* Correlation between monitoring and Orchestration -* Fault domain separation vs multi tenancy -* Rethink for runtime images and the role of the hypervisor -* Isolation for waved release upgrades (Pulsar) +- Dealing with too many monitoring alerts +- Backup Bastion — a regional bastion is vulnerable +- Control Plane recovery process +- Correlation between monitoring and Orchestration +- Fault domain separation vs multi tenancy +- Rethink for runtime images and the role of the hypervisor +- Isolation for waved release upgrades (Pulsar) All the above questions and KPIs convert to actionable actions for teams that you may question at any time. @@ -646,17 +646,17 @@ All the above questions and KPIs convert to actionable actions for teams that yo Following immediate actions, we created a lot of issues to avoid the same behavior in the future: -* Runtime image redesign / better hypervisor integration -* Regionalized observability for redundancy -* Better profiling for small VMs : - * Vector configuration - * `buffer.max_events` / `buffer.max_size` (must be at least 256Mo if `type=disk`) - * `buffer.type` `memory` (default) → switch to `disk` - * `buffer.when_full` `block` (default) → `drop_newest` - * Journald verbosity and `SystemMaxUse` - * Cgroups restrictions for better process control - * I/O restrictions for VM manager -* Better zombies VM detection +- Runtime image redesign / better hypervisor integration +- Regionalized observability for redundancy +- Better profiling for small VMs : + - Vector configuration + - `buffer.max_events` / `buffer.max_size` (must be at least 256Mo if `type=disk`) + - `buffer.type` `memory` (default) → switch to `disk` + - `buffer.when_full` `block` (default) → `drop_newest` + - Journald verbosity and `SystemMaxUse` + - Cgroups restrictions for better process control + - I/O restrictions for VM manager +- Better zombies VM detection We don’t face a lot of outages and big issues, because by design, we strive to do a good job of running production applications for our customers. As we grow, challenges grow, and we’re committed to achieve great production SLA because it’s our DNA, our mission: running your production workloads. diff --git a/content/postmortem/2025-03-03.md b/content/postmortem/2025-03-03.md index 3ebc4c38c..2d2dc24cd 100644 --- a/content/postmortem/2025-03-03.md +++ b/content/postmortem/2025-03-03.md @@ -13,111 +13,111 @@ On Monday, March 3rd, 2025 Clever Cloud’s platform became unstable, leading to These events occurred because: -* A power outage on one of our data center providers caused a temporary disruption of our services on the PAR6 Availability Zone (AZ) from EU-FR-1 at 14:55 CET -* As an indirect consequence, networking traffic was perturbed, the infrastructure experienced I/O and memory pressure between 14:58 and 16:30 CET leading to instabilities and downtime. +- A power outage on one of our data center providers caused a temporary disruption of our services on the PAR6 Availability Zone (AZ) from EU-FR-1 at 14:55 CET +- As an indirect consequence, networking traffic was perturbed, the infrastructure experienced I/O and memory pressure between 14:58 and 16:30 CET leading to instabilities and downtime. Impacts were observed for customers relying on the EU-FR-1 (PAR) region, and remote zones depending on the EU-FR-1 control plane (GOV, OVHcloud, Scaleway, and Oracle) and some privates zones. On-premise zones weren’t impacted. -Status were communicated through : https://www.clevercloudstatus.com/incidents/959 +Status were communicated through : -| Product | Impact | -|---------|--------| -| Runtimes | Applications may have experienced performance degradation and traffic issues due to impacted hypervisors and load balancers | -| Runtimes deployment | The incident prevented new deployments, upscaling and downscaling operations from succeeding due to the Deployment API being unreachable | -| Databases (MySQL, PostgreSQL, Redis, MongoDB) | The incident may have caused performance degradation or unavailability for customers whose databases were running on affected hypervisors. Data loss did not occur | +| Product | Impact | +| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Runtimes | Applications may have experienced performance degradation and traffic issues due to impacted hypervisors and load balancers | +| Runtimes deployment | The incident prevented new deployments, upscaling and downscaling operations from succeeding due to the Deployment API being unreachable | +| Databases (MySQL, PostgreSQL, Redis, MongoDB) | The incident may have caused performance degradation or unavailability for customers whose databases were running on affected hypervisors. Data loss did not occur | | Cluster services (Elastic, Couchbase, Cassandra, …) | The service may have been maintained on some nodes, depending on the infrastructure pressure and the technology used. While some clusters were impacted during the incident, others were not | -| VPN / IPSec | Most of the VPN endpoints were unavailable during the incident | -| Observability | The service has successfully recovered from the electrical issue, and logs were available | +| VPN / IPSec | Most of the VPN endpoints were unavailable during the incident | +| Observability | The service has successfully recovered from the electrical issue, and logs were available | ## Timeline -| Timeline | Component | Description | -|-----------|-----------|-------------| -| 14:55 CET | Infrastructure | Power outage at PAR6 (Green Data) data center | -| 14:56 CET | Load Balancers | Monitoring advertises the loss of a load balancer - 1st event | -| 14:56 CET | Infrastructure | Monitoring shows a global incident reporting many unavailabilities | -| 14:57 CET | Infrastructure | Infrastructure team opens a crisis conference | -| 14:58 CET | Infrastructure | Power is back, servers and network equipment are restarting (confirmed later by data center incident report) | -| 14:58 CET | Customers | Support team received notification from external monitoring and customers that some websites are down (Console, admin, etc.) | -| 14:58 CET | Customers | Tech team reported that GitLab is also unavailable | -| 14:58 CET | Infrastructure | Tech team created an incident canal #incident-03-03-2025 | -| 15:00 CET | Infrastructure | Infrastructure team summoned others on call teams and members on canal #incident-03-03-2025 | -| 15:02 CET | Infrastructure | Hypervisors and network equipment have rebooted | -| 15:02 CET | Infrastructure | Several PAR6 hypervisors (12 of them) are indicating that their RAID array are rebuilding | -| 15:05 CET | Infrastructure | Reporting that AZ Monitoring is under heavy load | -| 15:06 CET | Infrastructure | Infrastructure team confirmed that we have retrieved every hypervisors on PAR6 since at least 4 minutes to 6 minutes | -| 15:08 CET | Network | A network provider hosted in PAR6 reports 2 powerline cuts | -| 15:10 CET | Infrastructure | Report from one of our network provider confirming the electrical outage | -| 15:14 CET | Messaging | Pulsar is back up online | -| 15:14 CET | Observability | Pulsar in-memory observability didn't restart properly | -| 15:18 CET | Observability | Pulsar in-memory observability is online | -| 15:19 CET | Infrastructure | A RabbitMQ node came back to the cluster after we fixed the communication between the hypervisor and the queue | -| 15:27 CET | DBaaS | Main addon databases clusters is correctly restarting | -| 15:27 CET | DBaaS | Check the availability of internal databases clusters | -| 15:29 CET | DBaaS | DBaaS team start to handle manually all ciphered databases which are still down (due to an unavailabilty of the addon provider APIs) | -| 15:30 CET | Infrastructure | Seeing a lot of WireGuard connectivity issues on multiple distributed clusters | -| 15:30 CET | Infrastructure | Asked to priorise GitLab databases restarts | +| Timeline | Component | Description | +| --------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 14:55 CET | Infrastructure | Power outage at PAR6 (Green Data) data center | +| 14:56 CET | Load Balancers | Monitoring advertises the loss of a load balancer - 1st event | +| 14:56 CET | Infrastructure | Monitoring shows a global incident reporting many unavailabilities | +| 14:57 CET | Infrastructure | Infrastructure team opens a crisis conference | +| 14:58 CET | Infrastructure | Power is back, servers and network equipment are restarting (confirmed later by data center incident report) | +| 14:58 CET | Customers | Support team received notification from external monitoring and customers that some websites are down (Console, admin, etc.) | +| 14:58 CET | Customers | Tech team reported that GitLab is also unavailable | +| 14:58 CET | Infrastructure | Tech team created an incident canal #incident-03-03-2025 | +| 15:00 CET | Infrastructure | Infrastructure team summoned others on call teams and members on canal #incident-03-03-2025 | +| 15:02 CET | Infrastructure | Hypervisors and network equipment have rebooted | +| 15:02 CET | Infrastructure | Several PAR6 hypervisors (12 of them) are indicating that their RAID array are rebuilding | +| 15:05 CET | Infrastructure | Reporting that AZ Monitoring is under heavy load | +| 15:06 CET | Infrastructure | Infrastructure team confirmed that we have retrieved every hypervisors on PAR6 since at least 4 minutes to 6 minutes | +| 15:08 CET | Network | A network provider hosted in PAR6 reports 2 powerline cuts | +| 15:10 CET | Infrastructure | Report from one of our network provider confirming the electrical outage | +| 15:14 CET | Messaging | Pulsar is back up online | +| 15:14 CET | Observability | Pulsar in-memory observability didn't restart properly | +| 15:18 CET | Observability | Pulsar in-memory observability is online | +| 15:19 CET | Infrastructure | A RabbitMQ node came back to the cluster after we fixed the communication between the hypervisor and the queue | +| 15:27 CET | DBaaS | Main addon databases clusters is correctly restarting | +| 15:27 CET | DBaaS | Check the availability of internal databases clusters | +| 15:29 CET | DBaaS | DBaaS team start to handle manually all ciphered databases which are still down (due to an unavailabilty of the addon provider APIs) | +| 15:30 CET | Infrastructure | Seeing a lot of WireGuard connectivity issues on multiple distributed clusters | +| 15:30 CET | Infrastructure | Asked to priorise GitLab databases restarts | | 15:33 CET | Infrastructure | Some hypervisors are overloaded, probably due to Vector/Telegraf not being able to push data to Warp10/Pulsar. Started to list all VMs with CPU load > 1 to relieve the infrastructure | -| 15:37 CET | Infrastructure | Check if Ceph/Cellar are okay. Some daemons seem to hang and 1/4 of OSD are still down on PAR6, requests are served correctly | -| 15:38 CET | DBaaS | Asked DBaaS team to prioritize Clever Cloud's GitLab databases | -| 15:38 CET | Infrastructure | Listed all applications with VMs CPU load > 1, starting to kill them to relieve the infrastructure | -| 15:42 CET | DBaaS | Databases reboot are still lock on some Hypervisor due to a network issue | -| 15:42 CET | Infrastructure | Fixed a network setup issue on a specific Hypervisor | -| 15:45 CET | Messaging | Listed all GitLab and Premium services databases for DBaaS team | -| 15:45 CET | Observability | A global maintenance is set on all monitoring servers in EU-FR-1 to avoid flooding the Orchestration core API with redeploy events | -| 15:45 CET | DBaaS | Asked to reboot PostgreSQL add-on provider in priority | -| 15:49 CET | Deployments | We lacked 2.8k VMs on the infrastructure | -| 15:52 CET | Infrastructure | Some deployments are failing on PAR6 due to unbound on some HV not restarted, no DNS available | -| 15:54 CET | Observability | See timeouts on Vector logs when connecting to Pulsar | -| 15:55 CET | Infrastructure | Unlock first HVs to allow databases reboot (HV iptables rules) | -| 15:56 CET | Messaging | We hit the max connections threshold on Pulsar | -| 15:56 CET | Infrastructure | Vector logs timeouts fixed, by corrective iptables on hypervisor | -| 15:59 CET | Infrastructure | All Hypervisor iptables generated are restored on PAR6 HVs and services have been restarted | -| 16:00 CET | DBaaS | Can now repair databases down impacted by hypervisors network issues | -| 16:03 CET | Infrastructure | Connectivity issues due to conntrack issue (need to purge conntrack table) | -| 16:05 CET | Customers | Some load balancers are unsynced due to RabbitMQ crash | -| 16:05 CET | Load Balancers | Start the rolling restart of unsynced load balancers | -| 16:06 CET | Infrastructure | Some deployments are still failing on PAR6 due to WireGuard problems with the DNS recursor of the AZ, the recursor is dropped from unbound / resolv.conf of all PAR6 hypervisors | -| 16:07 CET | Load Balancers | For some applications it's not a load balancer issue, but the application have no instances running | -| 16:08 CET | Infrastructure | Dropped UDP conntracks on the hypervisor of PAR6 DNS recursor to recover WireGuard mesh topologies | -| 16:19 CET | Messaging | WireGuard issues on BookKeeper cluster for Pulsar | -| 16:28 CET | Deployments | Purge delayed alerts on Zabbix monitoring | -| 16:30 CET | Deployments | Restart all applications without any VMs | -| 16:34 CET | DBaaS | Elasticsearch add-ons repair is locked due to the unavailability of our LDAP | -| 16:34 CET | Deployments | Reboot of Keycloack | -| 16:42 CET | Customers | Nodes of Couchbase have been reintroduced in their cluster | -| 16:45 CET | Infrastructure | Finished killing overloaded VMs | -| 16:47 CET | Deployments | Stop instances that are blocked and have failed their deployments and redeploy the application | -| 16:47 CET | Deployments | Fix a Ruby error on bastion that prevent to redeploy application | -| 16:58 CET | Deployments | Stacking semaphores in BDS Orchestrator | -| 16:58 CET | Infrastructure | Network issue on Warp10 FoundationDB | -| 17:00 CET | Deployments | Disabled HA replication of some queues to speed up RabbitMQ | -| 17:17 CET | DBaaS | Recovery of our LDAP enable an Elasticsearch add-ons recovery | -| 17:18 CET | Load Balancers | Restart all add-on providers to be able to properly reload last load balancers | -| 17:20 CET | Load Balancers | End the rolling restart of all impacted load balancers at Clever Cloud | -| 17:28 CET | Observability | Zabbix on PAR8 back in action | -| 17:31 CET | Deployments | Still 1.3k VMs to deploy | -| 17:35 CET | Infrastructure | Two FoundationDB's VMs could not be started because the NVMe was unavailable | -| 17:37 CET | Deployments | Increased concurrent deployments from 300 to 400 to increase recovery speed | -| 17:50 CET | Observability | Cleaning up old hosts in Paris Monitoring to avoid sending too much outdated monitoring events | -| 17:57 CET | Observability | Zabbix on PAR7 back in action | -| 18:00 CET | Deployments | Started to restart all applications still seen as unavailable by Monitoring | -| 18:05 CET | Infrastructure | Restart Sydney orchestration that are unsynced | -| 18:05 CET | Observability | Zabbix on PAR6 back in action | -| 18:18 CET | Infrastructure | Force to stop all VMs in stopping status | -| 18:45 CET | Observability | Remove the maintenance mode of Monitoring | -| 18:53 CET | Deployments | Deploy last application in failing deployment state | -| 18:54 CET | Infrastructure | Investigating under-replicated Kafka partitions on Warp10 | -| 18:55 CET | DBaaS | All databases are up and running | -| 19:00 CET | DBaaS | Some Elasticsearch are down again (due to an heavy resources usage on recovery) | -| 19:11 CET | Deployments | Finished to restart all applications still seen as unavailable by Zabbix | -| 19:12 CET | Infrastructure | Starting to recover the Ceph cluster, 2 physical machines don't have any network, one has a network configuration issue | -| 19:16 CET | Infrastructure | Start the recovery of Ceph cluster | -| 19:23 CET | Core APIs | Restart of Logs API | -| 19:35 CET | DBaaS | All add-ons are OK | -| 20:25 CET | Infrastructure | All Ceph machines are correctly restarted, cluster is recovering 0.3% of degraded objects | -| 20:48 CET | Infrastructure | Ceph cluster has recovered degraded objects, HEALTH_OK | -| 21:20 CET | DBaaS | Last replica down identified was rebuid | +| 15:37 CET | Infrastructure | Check if Ceph/Cellar are okay. Some daemons seem to hang and 1/4 of OSD are still down on PAR6, requests are served correctly | +| 15:38 CET | DBaaS | Asked DBaaS team to prioritize Clever Cloud's GitLab databases | +| 15:38 CET | Infrastructure | Listed all applications with VMs CPU load > 1, starting to kill them to relieve the infrastructure | +| 15:42 CET | DBaaS | Databases reboot are still lock on some Hypervisor due to a network issue | +| 15:42 CET | Infrastructure | Fixed a network setup issue on a specific Hypervisor | +| 15:45 CET | Messaging | Listed all GitLab and Premium services databases for DBaaS team | +| 15:45 CET | Observability | A global maintenance is set on all monitoring servers in EU-FR-1 to avoid flooding the Orchestration core API with redeploy events | +| 15:45 CET | DBaaS | Asked to reboot PostgreSQL add-on provider in priority | +| 15:49 CET | Deployments | We lacked 2.8k VMs on the infrastructure | +| 15:52 CET | Infrastructure | Some deployments are failing on PAR6 due to unbound on some HV not restarted, no DNS available | +| 15:54 CET | Observability | See timeouts on Vector logs when connecting to Pulsar | +| 15:55 CET | Infrastructure | Unlock first HVs to allow databases reboot (HV iptables rules) | +| 15:56 CET | Messaging | We hit the max connections threshold on Pulsar | +| 15:56 CET | Infrastructure | Vector logs timeouts fixed, by corrective iptables on hypervisor | +| 15:59 CET | Infrastructure | All Hypervisor iptables generated are restored on PAR6 HVs and services have been restarted | +| 16:00 CET | DBaaS | Can now repair databases down impacted by hypervisors network issues | +| 16:03 CET | Infrastructure | Connectivity issues due to conntrack issue (need to purge conntrack table) | +| 16:05 CET | Customers | Some load balancers are unsynced due to RabbitMQ crash | +| 16:05 CET | Load Balancers | Start the rolling restart of unsynced load balancers | +| 16:06 CET | Infrastructure | Some deployments are still failing on PAR6 due to WireGuard problems with the DNS recursor of the AZ, the recursor is dropped from unbound / resolv.conf of all PAR6 hypervisors | +| 16:07 CET | Load Balancers | For some applications it's not a load balancer issue, but the application have no instances running | +| 16:08 CET | Infrastructure | Dropped UDP conntracks on the hypervisor of PAR6 DNS recursor to recover WireGuard mesh topologies | +| 16:19 CET | Messaging | WireGuard issues on BookKeeper cluster for Pulsar | +| 16:28 CET | Deployments | Purge delayed alerts on Zabbix monitoring | +| 16:30 CET | Deployments | Restart all applications without any VMs | +| 16:34 CET | DBaaS | Elasticsearch add-ons repair is locked due to the unavailability of our LDAP | +| 16:34 CET | Deployments | Reboot of Keycloack | +| 16:42 CET | Customers | Nodes of Couchbase have been reintroduced in their cluster | +| 16:45 CET | Infrastructure | Finished killing overloaded VMs | +| 16:47 CET | Deployments | Stop instances that are blocked and have failed their deployments and redeploy the application | +| 16:47 CET | Deployments | Fix a Ruby error on bastion that prevent to redeploy application | +| 16:58 CET | Deployments | Stacking semaphores in BDS Orchestrator | +| 16:58 CET | Infrastructure | Network issue on Warp10 FoundationDB | +| 17:00 CET | Deployments | Disabled HA replication of some queues to speed up RabbitMQ | +| 17:17 CET | DBaaS | Recovery of our LDAP enable an Elasticsearch add-ons recovery | +| 17:18 CET | Load Balancers | Restart all add-on providers to be able to properly reload last load balancers | +| 17:20 CET | Load Balancers | End the rolling restart of all impacted load balancers at Clever Cloud | +| 17:28 CET | Observability | Zabbix on PAR8 back in action | +| 17:31 CET | Deployments | Still 1.3k VMs to deploy | +| 17:35 CET | Infrastructure | Two FoundationDB's VMs could not be started because the NVMe was unavailable | +| 17:37 CET | Deployments | Increased concurrent deployments from 300 to 400 to increase recovery speed | +| 17:50 CET | Observability | Cleaning up old hosts in Paris Monitoring to avoid sending too much outdated monitoring events | +| 17:57 CET | Observability | Zabbix on PAR7 back in action | +| 18:00 CET | Deployments | Started to restart all applications still seen as unavailable by Monitoring | +| 18:05 CET | Infrastructure | Restart Sydney orchestration that are unsynced | +| 18:05 CET | Observability | Zabbix on PAR6 back in action | +| 18:18 CET | Infrastructure | Force to stop all VMs in stopping status | +| 18:45 CET | Observability | Remove the maintenance mode of Monitoring | +| 18:53 CET | Deployments | Deploy last application in failing deployment state | +| 18:54 CET | Infrastructure | Investigating under-replicated Kafka partitions on Warp10 | +| 18:55 CET | DBaaS | All databases are up and running | +| 19:00 CET | DBaaS | Some Elasticsearch are down again (due to an heavy resources usage on recovery) | +| 19:11 CET | Deployments | Finished to restart all applications still seen as unavailable by Zabbix | +| 19:12 CET | Infrastructure | Starting to recover the Ceph cluster, 2 physical machines don't have any network, one has a network configuration issue | +| 19:16 CET | Infrastructure | Start the recovery of Ceph cluster | +| 19:23 CET | Core APIs | Restart of Logs API | +| 19:35 CET | DBaaS | All add-ons are OK | +| 20:25 CET | Infrastructure | All Ceph machines are correctly restarted, cluster is recovering 0.3% of degraded objects | +| 20:48 CET | Infrastructure | Ceph cluster has recovered degraded objects, HEALTH_OK | +| 21:20 CET | DBaaS | Last replica down identified was rebuid | ## Analysis @@ -134,13 +134,16 @@ We're expecting a better postmortem from our data center operator. Our network relies on multiple transits to ensure both a good Internet connectivity and a good resilience. These transits are spread among three Points of Presence (PoP). During the restart of networking routers, there appears to be an issue with accessing the region via public connectivity, despite these multiple transits. Our observability system was unfortunately located on the lost AZ, so we lost the flows to analyze the traffic during the power cut. Known Issues: + - In some cases, when a router reboots, it may start receiving traffic before it knows where to route it. A specific starting sequence may be enforced to avoid this behavior. #### Possible Causes of Downtime + - A transit partner did not notice that the session was down before the BGP session timed out (a few minutes), so traffic continued to be routed through them even though we were no longer there to handle it. Another transit partner continued to announce our prefixes even though they couldn't route the traffic to our network. - There is a 3-minutes timeout on the BGP sessions of the routers, with no Bidirectional Forwarding Detection (BFD) to accelerate convergence. #### Unclear Areas + - In the nominal situation, most of our traffic is gathered at TH2 POP, so we shouldn't have seen such a significant impact. However, most of our traffic exits through another transit partner through the incriminated AZ (correlate with the one of the possible cause of downtime) - Did the other routers still have announcements (received from the power cut AZ routers) when they received traffic to send to the internet, because the BGP sessions hadn't yet timed out? (correlate with the one of the possible cause of downtime) @@ -172,6 +175,7 @@ Also, a few hours before the incident, we deployed multiple enhanced images, wit Initially, we implemented an orchestration system based on an offering model (similar to Apache Mesos), which provided a solid foundation for managing our services. In an offering model, an orchestrator manages the allocation and deallocation of resources, such as virtual machines (VMs), to ensure efficient utilization and meet service demands. However, the orchestrator can become stuck due to semaphore locking issues during VM assignment for several reasons: + - **Resource Contention:** Semaphores are used to control access to shared resources, ensuring that only a limited number of processes can access them simultaneously. If multiple VMs are attempting to acquire the same resource concurrently, contention can occur, leading to semaphore locks. This can cause the orchestrator to wait indefinitely if the locks are not released promptly. - **Deadlocks:** A deadlock situation arises when two or more processes are each holding a resource and waiting for the other to release a resource they need. In the context of VM assignment, if the orchestrator and other processes are waiting for each other to release semaphores, it can result in a deadlock, causing the orchestrator to become stuck. - **Improper Semaphore Management:** If semaphores are not properly initialized, acquired, or released, it can lead to locking issues. For instance, if a semaphore is not released after a VM assignment operation completes, other processes waiting for that semaphore will remain blocked, including the orchestrator. @@ -193,22 +197,22 @@ However, recognizing the need for enhanced capabilities and a broader range of p ### Runtimes - - #856 Enforce guard I/O rules at Hypervisor level - - #857 Enhance observability for small profile VM memory pressure +- #856 Enforce guard I/O rules at Hypervisor level +- #857 Enhance observability for small profile VM memory pressure - ### Networking +### Networking - - #832 Ensure OSPF/BGP convergence times on routers - - #898 Enhance boot sequence process on routers - - #899 Ensure a good resiliency for border routing BGP announces +- #832 Ensure OSPF/BGP convergence times on routers +- #898 Enhance boot sequence process on routers +- #899 Ensure a good resiliency for border routing BGP announces - ### Orchestration +### Orchestration actions - - #900 Ensure a failsafe VM restart capability - - #901 Enhance hypervisor sequence of start process - - #902 Ensure a better network configuration compliance across upgrades - - #864 Better observability for unresponsive VM - - #903 Improve AZ monitoring resiliency +- #900 Ensure a failsafe VM restart capability +- #901 Enhance hypervisor sequence of start process +- #902 Ensure a better network configuration compliance across upgrades +- #864 Better observability for unresponsive VM +- #903 Improve AZ monitoring resiliency ### Conclusion diff --git a/content/postmortem/2025-10-09.md b/content/postmortem/2025-10-09.md index a6661bddc..218ab5d32 100644 --- a/content/postmortem/2025-10-09.md +++ b/content/postmortem/2025-10-09.md @@ -14,43 +14,43 @@ We lost a first hypervisor due to high memory pressure and at the same time ther Then, this put pressure on the Paris region, which caused another hypervisor to enter the same state. We lost critical services in the meantime due to infrastructure that was already under heavy load. -Status were communicated through : https://www.clevercloudstatus.com/incidents/1020 - -### Timeline - -| Time | Description | -| ---------------- | ------------------------------------------------------------ | -| 2025-10-09 07:10 | Monitoring of time series systems fails to work properly, distributed systems oncall operator is paged | -| 2025-10-09 07:40 | Time series systems fails to receive ingress traffic | -| 2025-10-09 07:59 | ALL time series systems load balancers are stuck due to too much connections | -| 2025-10-09 08:01 | Distributed systems operator raises the alert to Level 2 | -| 2025-10-09 08:03 | On of the hypervisor is detected as down | -| 2025-10-09 08:12 | Orchestration operations are limited to limit a potential domino effect and reduce deployment pressure on infrastructure | -| 2025-10-09 08:15 | Restart of time series systems ingresses / an hypervisor experiencing high load (2300), memory pressure identified | -| 2025-10-09 08:17 | Passing the faulty hypervisor to CLI for management | -| 2025-10-09 08:18 | Metrics are getting ingested by time series systems again (1/5 of nominal traffic) | -| 2025-10-09 08:23 | Enable time series systems load balancer datapoints sampling (blackhole) on 50% of traffic | -| 2025-10-09 08:35 | Root cause identified: RAM capacity issue causing load spike on hypervisors | -| 2025-10-09 08:37 | Faulty hypervisor is rebooted successfully (uptime: 2025-10-09 06:37:06 UTC) | -| 2025-10-09 08:40 | Domino effect detected: an hypervisor is showing signs of stress | -| 2025-10-09 08:43 | Multiple databases impacted (Down), the full Database Team is escalated | -| 2025-10-09 08:46 | Time series systems is at 75% of nominal ingress traffic | -| 2025-10-09 09:00 | Time series systems is fully operational & back to nominal traffic | -| 2025-10-09 09:09 | Addon provider Mongo is back online | -| 2025-10-09 09:10 | On a faulty hypervisor , all databases are up again | -| 2025-10-09 09:14 | On the second faulty hypervisor, all databases are up again | +Status were communicated through : + +## Timeline + +| Time | Description | +| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 2025-10-09 07:10 | Monitoring of time series systems fails to work properly, distributed systems oncall operator is paged | +| 2025-10-09 07:40 | Time series systems fails to receive ingress traffic | +| 2025-10-09 07:59 | ALL time series systems load balancers are stuck due to too much connections | +| 2025-10-09 08:01 | Distributed systems operator raises the alert to Level 2 | +| 2025-10-09 08:03 | On of the hypervisor is detected as down | +| 2025-10-09 08:12 | Orchestration operations are limited to limit a potential domino effect and reduce deployment pressure on infrastructure | +| 2025-10-09 08:15 | Restart of time series systems ingresses / an hypervisor experiencing high load (2300), memory pressure identified | +| 2025-10-09 08:17 | Passing the faulty hypervisor to CLI for management | +| 2025-10-09 08:18 | Metrics are getting ingested by time series systems again (1/5 of nominal traffic) | +| 2025-10-09 08:23 | Enable time series systems load balancer datapoints sampling (blackhole) on 50% of traffic | +| 2025-10-09 08:35 | Root cause identified: RAM capacity issue causing load spike on hypervisors | +| 2025-10-09 08:37 | Faulty hypervisor is rebooted successfully (uptime: 2025-10-09 06:37:06 UTC) | +| 2025-10-09 08:40 | Domino effect detected: an hypervisor is showing signs of stress | +| 2025-10-09 08:43 | Multiple databases impacted (Down), the full Database Team is escalated | +| 2025-10-09 08:46 | Time series systems is at 75% of nominal ingress traffic | +| 2025-10-09 09:00 | Time series systems is fully operational & back to nominal traffic | +| 2025-10-09 09:09 | Addon provider Mongo is back online | +| 2025-10-09 09:10 | On a faulty hypervisor , all databases are up again | +| 2025-10-09 09:14 | On the second faulty hypervisor, all databases are up again | | 2025-10-09 09:14 | DBaaS team is now fixing random databases that wen't down on the par8 datacenter (manly small encrypted plans). Reboot failing due to a local Out Of Memory (oom) | -| 2025-10-09 09:18 | On of four time series systems loadbalancer is not rebooting, due to missing base image | -| 2025-10-09 09:25 | Issue to reboot some databases (OOM before start). We restarted them in rescue and deactivated the logs to enable the reboot. | -| 2025-10-09 09:46 | All four time series systems loadbalancer are up again | -| 2025-10-09 09:55 | The rebooted databases without logs were correctly migrated, logs are now collected again | -| 2025-10-09 09:56 | An automated system reported an expired certificate on time series systems customer endpoint for ingress, half the traffic fails to reach time series systems | -| 2025-10-09 10:30 | two of the four time series systems load balancers are exposing expired certificates | -| 2025-10-09 10:39 | Time series systems expired certificates issue is fixed, back to nominal | -| 2025-10-09 10:43 | All databases impacted by the incident are up and running | -| 2025-10-09 10:46 | mass restart of supernova/supernova-http on all hypervisors via Ansible - RabbitMQ connection flapping detected | -| 2025-10-09 10:52 | Some databases were going down again, they are now fixed and migrated to resolve the issue | -| 2025-10-09 11:10 | proxy-manager / hayxorp / rabbitfrs restart across the infrastructure - verification that all services reconnected to RabbitMQ successfully | +| 2025-10-09 09:18 | On of four time series systems loadbalancer is not rebooting, due to missing base image | +| 2025-10-09 09:25 | Issue to reboot some databases (OOM before start). We restarted them in rescue and deactivated the logs to enable the reboot. | +| 2025-10-09 09:46 | All four time series systems loadbalancer are up again | +| 2025-10-09 09:55 | The rebooted databases without logs were correctly migrated, logs are now collected again | +| 2025-10-09 09:56 | An automated system reported an expired certificate on time series systems customer endpoint for ingress, half the traffic fails to reach time series systems | +| 2025-10-09 10:30 | two of the four time series systems load balancers are exposing expired certificates | +| 2025-10-09 10:39 | Time series systems expired certificates issue is fixed, back to nominal | +| 2025-10-09 10:43 | All databases impacted by the incident are up and running | +| 2025-10-09 10:46 | mass restart of supernova/supernova-http on all hypervisors via Ansible - RabbitMQ connection flapping detected | +| 2025-10-09 10:52 | Some databases were going down again, they are now fixed and migrated to resolve the issue | +| 2025-10-09 11:10 | proxy-manager / hayxorp / rabbitfrs restart across the infrastructure - verification that all services reconnected to RabbitMQ successfully | ## Analysis @@ -58,23 +58,25 @@ An mechanical incident in the Paris region created an unexpected memory pressure ### Actions -* Complete the deployment of oomd which will help to better handle memory pressure -* Add a monitoring disaster trigger to detect when a hypervisor stays under pressure for too long -* Fix small MySQL databases that were on error after the reboot during the incident -* Add TLS check on each warp10 load balancers for c2-warp10-clevercloud-customers.services.clever-cloud.com +- Complete the deployment of oomd which will help to better handle memory pressure +- Add a monitoring disaster trigger to detect when a hypervisor stays under pressure for too long +- Fix small MySQL databases that were on error after the reboot during the incident +- Add TLS check on each warp10 load balancers for c2-warp10-clevercloud-customers.services.clever-cloud.com -* New hardware installation will reduce pressure on infrastructure -* Configure time series systems ingress thresholds to deny traffic before instances become stuck +- New hardware installation will reduce pressure on infrastructure +- Configure time series systems ingress thresholds to deny traffic before instances become stuck ### Conclusion During the incident, our actions demonstrated a good reactivity, but also some potential enhancements. The infrastructure congestion has already been resolved on two stages: + - immediate capacity addition (done) - accelerate the two new AZ project with a shipment for january We also learnt on the behavior of machine health in case of cooling issue on a given availability zone (AZ), which never occurred before. Databases management is being enhanced with two strategic actions: + - volume capability that enable arbitrary restart on any other AZ - automatic failover for leader/follower setups diff --git a/content/postmortem/2026-03-19.md b/content/postmortem/2026-03-19.md index 3131f7045..9a2f19744 100644 --- a/content/postmortem/2026-03-19.md +++ b/content/postmortem/2026-03-19.md @@ -14,18 +14,18 @@ A memory pressure spike on ~15 Paris hypervisors, amplified by a placement algor The overloaded servers triggered OS memory reclaim (OOM), which consumed CPU and destabilized HAProxy load balancers — causing connectivity loss for hosted services and paralyzing internal automation (deployments, monitoring). Full recovery at 21:41 UTC. -Status updates were communicated through: https://www.clevercloudstatus.com/ +Status updates were communicated through: -### Timeline +## Timeline -| Time | Description | -| ---------------- | ------------------------------------------------------------ | -| 2026-03-19 15:20 | First degradation signals on internal services (VM registration, deployment service database access). No client impact yet. | -| 2026-03-19 15:50 | Degradations and outages visible for some clients. Services hosted on the most impacted hypervisors become unreachable. Deployment pipeline stops. | +| Time | Description | +| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 2026-03-19 15:20 | First degradation signals on internal services (VM registration, deployment service database access). No client impact yet. | +| 2026-03-19 15:50 | Degradations and outages visible for some clients. Services hosted on the most impacted hypervisors become unreachable. Deployment pipeline stops. | | 2026-03-19 16:03 | Incident response team mobilized. Mitigation actions begin: stabilizing hypervisors under pressure, progressive restart of internal clusters (messaging, observability), partial deployment resumption. | -| 2026-03-19 17:30 | Full restoration of the deployment pipeline and observability. Continued recovery of impacted client services. | -| 2026-03-19 18:09 | All impacted client services restored. Residual alert cleanup begins. | -| 2026-03-19 21:41 | Service fully operational. All residual alerts cleared. | +| 2026-03-19 17:30 | Full restoration of the deployment pipeline and observability. Continued recovery of impacted client services. | +| 2026-03-19 18:09 | All impacted client services restored. Residual alert cleanup begins. | +| 2026-03-19 21:41 | Service fully operational. All residual alerts cleared. | ## Analysis @@ -37,13 +37,13 @@ The memory saturation triggered the OS memory reclaim mechanism, which itself is ### Actions -* Placement scoring function modified to smooth load ramp-up and eliminate the threshold effect -* Dedicated monitoring added to detect any recurrence of this behavior -* Temporary fixes deployed immediately during the incident to mitigate effects -* Partial algorithm redesign to guarantee smooth and optimal resource allocation under high load -* Enhanced observability for non-VM processes running on hypervisors (especially HAProxy instrumentation) -* Memory pressure resilience improvements prioritized and delivered within the following week -* Two new datacenters planned for the Paris region in Q2 2026 to increase capacity and reduce sensitivity to load spikes +- Placement scoring function modified to smooth load ramp-up and eliminate the threshold effect +- Dedicated monitoring added to detect any recurrence of this behavior +- Temporary fixes deployed immediately during the incident to mitigate effects +- Partial algorithm redesign to guarantee smooth and optimal resource allocation under high load +- Enhanced observability for non-VM processes running on hypervisors (especially HAProxy instrumentation) +- Memory pressure resilience improvements prioritized and delivered within the following week +- Two new datacenters planned for the Paris region in Q2 2026 to increase capacity and reduce sensitivity to load spikes ### Conclusion diff --git a/drafts/community.md b/drafts/community.md index 53c25b0ca..661cd1bc7 100644 --- a/drafts/community.md +++ b/drafts/community.md @@ -14,11 +14,11 @@ Engage in our Developer Community by seeking or providing advice on application ## Gitter -* English room: -* French room: +- English room: +- French room: ## Public IRC Channel We’re also available on IRC. You can join our channel: -* [#clevercloud on irc.freenode.net](irc://irc.freenode.net:6667/clevercloud) +- [#clevercloud on irc.freenode.net](irc://irc.freenode.net:6667/clevercloud) diff --git a/shared/kv-explorer.md b/shared/kv-explorer.md index 29ce77bec..730ab3fc4 100644 --- a/shared/kv-explorer.md +++ b/shared/kv-explorer.md @@ -16,6 +16,6 @@ At the bottom of the page, you'll find an integrated terminal that works like a KV Explorer is in Beta testing phase and we'll improve it over the coming months, thanks to your feedback and suggestions. -- [ Share your feedback on KV Explorer](https://github.com/CleverCloud/Community/discussions/categories/kv-explorer) +- [Share your feedback on KV Explorer](https://github.com/CleverCloud/Community/discussions/categories/kv-explorer) ![KV Explorer](/images/kv-explorer.webp "The KV Explorer tool in the Console") diff --git a/shared/redirectionio.md b/shared/redirectionio.md index 04dbcaa2d..e0450d95f 100644 --- a/shared/redirectionio.md +++ b/shared/redirectionio.md @@ -2,10 +2,10 @@ [Redirection.io](https://redirection.io) can help reduce HTTP traffic issues on your website. It gives complete control over how HTTP requests are handled, which helps make it SEO-friendly. You can link any application to a Redirection.io project by setting the following environment variables. Port allocation is managed automatically by [Request Flow](/doc/develop/request-flow/). -| Name | Description | Default value | -|-----------------------|------------------------------|--------------------------------| -| `CC_REDIRECTIONIO_PROJECT_KEY` | The Redirection.io project key | | -| `CC_REDIRECTIONIO_FORWARD_PORT` | Override the port Redirection.io forwards traffic to (optional) | | -| `CC_REDIRECTIONIO_INSTANCE_NAME` | The name of your application (optional) | | +| Name | Description | Default value | +| -------------------------------- | --------------------------------------------------------------- | ------------- | +| `CC_REDIRECTIONIO_PROJECT_KEY` | The Redirection.io project key | | +| `CC_REDIRECTIONIO_FORWARD_PORT` | Override the port Redirection.io forwards traffic to (optional) | | +| `CC_REDIRECTIONIO_INSTANCE_NAME` | The name of your application (optional) | | - [Learn more about Redirection.io](https://redirection.io/) diff --git a/shared/ruby.md b/shared/ruby.md index c2c192a5a..663dcc4e1 100644 --- a/shared/ruby.md +++ b/shared/ruby.md @@ -4,10 +4,10 @@ Be sure that: -* you push to the **master branch** -* you commit your `gems.locked` or `Gemfile.lock` file -* you have a `config.ru` file (this one is most of the time generated by rails) -* you have `gem puma` in your `Gemfile` (`puma` is the default application server from rails, when creating a new ruby application, an [environment variable](#setting-up-environment-variables-on-clever-cloud) is automatically added: `CC_RACKUP_SERVER=puma`) +- you push to the **master branch** +- you commit your `gems.locked` or `Gemfile.lock` file +- you have a `config.ru` file (this one is most of the time generated by rails) +- you have `gem puma` in your `Gemfile` (`puma` is the default application server from rails, when creating a new ruby application, an [environment variable](#setting-up-environment-variables-on-clever-cloud) is automatically added: `CC_RACKUP_SERVER=puma`) You need to provide a `gems.locked` or `Gemfile.lock` file. To do that ensure you have at least once run `bundle install` in your terminal at the root of your rails project. @@ -15,9 +15,9 @@ You need to provide a `gems.locked` or `Gemfile.lock` file. To do that ensure yo You can specify a Ruby version in your `gems.rb` or `Gemfile`, or set `CC_RUBY_VERSION=`, where `` can be, for example: -* "4" will select the greatest "4.x.y" version available. -* "4.0" will select the greatest "4.0.y" version available. -* "4.0.1" will select the "4.0.1" version. +- "4" will select the greatest "4.x.y" version available. +- "4.0" will select the greatest "4.0.y" version available. +- "4.0.1" will select the "4.0.1" version. If the given `` does not match any available version, your deployment will fail. If no version is specified, the latest 4.x version available on the image is used. Versions from the 4.x, 3.x and 2.x branches are available, but we recommend using an [officially supported version](https://www.ruby-lang.org/en/downloads/branches/). @@ -97,10 +97,10 @@ For other Rack applications, `STATIC_FILES_PATH` specifies the static files dire Only for Rails >= 5.2. -* Enable Active Storage for your application: `$ rails active_storage:install` then `$ rake db:migrate` -* Add `gem "aws-sdk-s3", require: false` to your Gemfile, run `$ bundle install` -* Add `config.active_storage.service = :clevercloud` in `config/environments/production.yml` -* Add in `config/storage.yml`: +- Enable Active Storage for your application: `$ rails active_storage:install` then `$ rake db:migrate` +- Add `gem "aws-sdk-s3", require: false` to your Gemfile, run `$ bundle install` +- Add `config.active_storage.service = :clevercloud` in `config/environments/production.yml` +- Add in `config/storage.yml`: ```yaml clevercloud: @@ -113,8 +113,8 @@ Only for Rails >= 5.2. force_path_style: true ``` -* In the clever cloud console create a Cellar S3 storage add-on, name it, link it to your rails application and create a bucket. -* In the environment variables section of your Ruby on Rails application on Clever Cloud add the following environment variables: +- In the clever cloud console create a Cellar S3 storage add-on, name it, link it to your rails application and create a bucket. +- In the environment variables section of your Ruby on Rails application on Clever Cloud add the following environment variables: ```bash CELLAR_ADDON_BUCKET_NAME="" @@ -130,7 +130,7 @@ Also, you are able to use a Filesystem Bucket to store your static files. Please NGINX settings can be configured with [environment variables](#setting-up-environment-variables-on-clever-cloud): -* `NGINX_READ_TIMEOUT`: the response timeout in seconds. (Default: 300) +- `NGINX_READ_TIMEOUT`: the response timeout in seconds. (Default: 300) #### Basic authentication @@ -140,11 +140,11 @@ If you need basic authentication, you can enable it using [environment variables NGINX settings can be configured further in `clevercloud/http.json`. All its fields are optional. -* `languages`: configure a default language and redirections -* `error_pages`: configure custom files for error pages -* `force_https`: automatically redirect HTTP traffic to HTTPS -* `aliases`: set up redirections -* `charset`: force a specific charset +- `languages`: configure a default language and redirections +- `error_pages`: configure custom files for error pages +- `force_https`: automatically redirect HTTP traffic to HTTPS +- `aliases`: set up redirections +- `charset`: force a specific charset ```json { @@ -170,8 +170,8 @@ Puma reads its configuration from the `config/puma.rb` file. See [the puma docum You can override this configuration with [environment variables](#setting-up-environment-variables-on-clever-cloud). Each of them, when specified, will be preferred over the setting from `config/puma.rb`. -* `CC_PUMA_WORKERS` overrides the number of workers (for example, `CC_PUMA_WORKERS=2`) -* `CC_PUMA_THREADS` overrides the number of threads per worker, can be a raw number or a range (for example, `CC_PUMA_THREADS=6` or `CC_PUMA_THREADS=4:8`) +- `CC_PUMA_WORKERS` overrides the number of workers (for example, `CC_PUMA_WORKERS=2`) +- `CC_PUMA_THREADS` overrides the number of threads per worker, can be a raw number or a range (for example, `CC_PUMA_THREADS=6` or `CC_PUMA_THREADS=4:8`) If they are not defined in the environment nor in `config/puma.rb` we will setup the values depending on the size of the scaler your application is running on. We also fill the `WEB_CONCURRENCY` and `RAILS_MAX_THREADS` environment variable if they are not present as they may be used by rails' puma configuration. diff --git a/shared/warp10-concepts.md b/shared/warp10-concepts.md index 65cce033d..8017cbe35 100644 --- a/shared/warp10-concepts.md +++ b/shared/warp10-concepts.md @@ -6,5 +6,5 @@ A GeoTime Serie (GTS) is defined by a `class` and some `labels`. They're indexed Warp 10 uses Warp Script. It's a stack based language using reverse polish notation. -* [Warp 1O documentation](https://www.warp10.io/doc/reference) -* [Warp Script documentation](https://www.warp10.io/content/03_Documentation/04_WarpScript) +- [Warp 1O documentation](https://www.warp10.io/doc/reference) +- [Warp Script documentation](https://www.warp10.io/content/03_Documentation/04_WarpScript) diff --git a/shared/warp10-content.md b/shared/warp10-content.md index 1087bfaaa..b582599ce 100644 --- a/shared/warp10-content.md +++ b/shared/warp10-content.md @@ -2,8 +2,8 @@ The platform's time unit is in **microsecond**. -* [Learn more about date functions](https://www.warp10.io/tags/date) -* [Learn more about time functions](https://www.warp10.io/tags/time) +- [Learn more about date functions](https://www.warp10.io/tags/date) +- [Learn more about time functions](https://www.warp10.io/tags/time) #### Duration is set by the followings symbols @@ -32,18 +32,18 @@ Builtin function: The followings limits are defined in Warp 10. The **soft** limit can be passed over by an [`AUTHENTICATE`](https://www.warp10.io/doc/AUTHENTICATE) operation. Operations over **soft limits** may be intensive. The **hard** limit is unsurpassable. -| WarpScript Operator | Warp 10 limit description | soft limit | hard limit | -| ------------------- | ------------------------------------------------------------- | ---------- | ---------- | -| MAXGTS | Maximum number of GTS which can be fetched | 10e5 | 5e7 | -| LIMIT | Maximum number of datapoints which can be fetched during a script execution | 10e6 | 10e7 | -| MAXBUCKETS | Maximum number of buckets which can be created by a call to BUCKETIZE | 10e5 | 50e5 | -| MAXDEPTH | Maximum depth (number of levels) of the execution stack | 5e3 | 5e3 | -| MAXLOOP | Maximum number of milliseconds which can be spent in a loop | 5e3 | 10e3 | -| MAXOPS | Maximum number of operations which can be performed during a single WarpScript execution | 5e6 | 5e7 | -| MAXSYMBOLS | Maximum number of simultaneous symbols which can be defined on the stack during a single WarpScript execution | 64 | 256 | -| MAXGEOCELLS | Maximum number of cells a GEOSHAPE | 10e3 | 10e4 | -| MAXPIXELS | Maximum size (in pixels) of images which can be created by PGraphics | 10e5 | 10e5 | -| MAXRECURSION | Maximum nesting depth of macro calls | 16 | 32 | +| WarpScript Operator | Warp 10 limit description | soft limit | hard limit | +| ------------------- | ------------------------------------------------------------------------------------------------------------- | ---------- | ---------- | +| MAXGTS | Maximum number of GTS which can be fetched | 10e5 | 5e7 | +| LIMIT | Maximum number of datapoints which can be fetched during a script execution | 10e6 | 10e7 | +| MAXBUCKETS | Maximum number of buckets which can be created by a call to BUCKETIZE | 10e5 | 50e5 | +| MAXDEPTH | Maximum depth (number of levels) of the execution stack | 5e3 | 5e3 | +| MAXLOOP | Maximum number of milliseconds which can be spent in a loop | 5e3 | 10e3 | +| MAXOPS | Maximum number of operations which can be performed during a single WarpScript execution | 5e6 | 5e7 | +| MAXSYMBOLS | Maximum number of simultaneous symbols which can be defined on the stack during a single WarpScript execution | 64 | 256 | +| MAXGEOCELLS | Maximum number of cells a GEOSHAPE | 10e3 | 10e4 | +| MAXPIXELS | Maximum size (in pixels) of images which can be created by PGraphics | 10e5 | 10e5 | +| MAXRECURSION | Maximum nesting depth of macro calls | 16 | 32 | ### Usage @@ -74,7 +74,7 @@ For a complete list of Telegraf classes and their descriptions, see [the classes Warp 10 provide a server side macro manager. It is a way to release some ready to use WarpScript. Hence, Clever Cloud provides some macros as helpers to avoid redundant and often need code. -* [Warp 10' macros documentations](https://www.warp10.io/content/03_Documentation/07_Extending_Warp_10/01_Server_side_macros) +- [Warp 10' macros documentations](https://www.warp10.io/content/03_Documentation/07_Extending_Warp_10/01_Server_side_macros) ### Consumption diff --git a/update-cli-reference.sh b/update-cli-reference.sh index 1f7d1446b..23899dec7 100755 --- a/update-cli-reference.sh +++ b/update-cli-reference.sh @@ -23,6 +23,8 @@ aliases: - /reference/clever-tools - /reference/clever-tools/getting_started --- + + """ echo "${front_matter}" > "${FILE}" From 469d235125a3abb19f7148ac79c49c37de0298e6 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 26 Aug 2026 18:34:12 +0200 Subject: [PATCH 02/73] addons(cellar): document Object Lock --- content/doc/addons/cellar.md | 148 +++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/content/doc/addons/cellar.md b/content/doc/addons/cellar.md index d495ea348..12efd2cf4 100644 --- a/content/doc/addons/cellar.md +++ b/content/doc/addons/cellar.md @@ -841,6 +841,154 @@ When versioning is enabled, the newly added object is automatically provided wit {{< /tabs >}} +## Object Lock + +Cellar supports [S3 Object Lock](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html), which protects individual object versions from permanent deletion or modification with a [write-once-read-many (WORM)](https://en.wikipedia.org/wiki/Write_once_read_many) model. It can reduce the risk of accidental or malicious deletion and enforce data-retention policies. + +Using Object Lock requires two steps. First, enable the feature when you create the bucket; Cellar doesn't allow you to add it later. This automatically activates [versioning](#versioning), which you can no longer suspend. Second, choose how to protect object versions: + +- Set a default retention period for every new version +- Apply a retention period or legal hold only to selected versions + +Until you complete this second step, Object Lock doesn't protect any objects. + +### Create a bucket with Object Lock + +The following examples create `my-locked-bucket` with Object Lock enabled. Replace the bucket name with your own value. + +{{< tabs >}} + + {{< tab name="s3cmd" icon="terminal" >}} + + This command assumes you have [configured s3cmd](#with-s3cmd). s3cmd doesn't provide a dedicated option for Object Lock at bucket creation, but you can add a specific header to enable it: + + ```bash + s3cmd --add-header=x-amz-bucket-object-lock-enabled:true mb s3://my-locked-bucket + ``` + + {{< /tab >}} + + {{< tab name="MinIO" icon="minio" >}} + + This command assumes you have [configured a MinIO alias](#activate-versioning-with-minio) named `my-cellar`: + + ```bash + mc mb --with-lock my-cellar/my-locked-bucket + ``` + + See the MinIO documentation for [`mc mb`](https://docs.min.io/community/minio-object-store/reference/minio-mc/mc-mb.html). + + {{< /tab >}} + + {{< tab name="AWS CLI" icon="aws" >}} + + This command assumes you have [configured your AWS CLI credentials](#with-aws-cli): + + ```bash + aws s3api create-bucket \ + --bucket my-locked-bucket \ + --object-lock-enabled-for-bucket \ + --endpoint-url https://cellar-c2.services.clever-cloud.com + ``` + + See the AWS CLI documentation for [`create-bucket`](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-bucket.html). + + {{< /tab >}} + +{{< /tabs >}} + +### Set a default retention period + +The following examples complete the configuration by protecting every new object version for 30 days in Governance mode. s3cmd can't configure a default retention period, so use MinIO or AWS CLI for this step. + +{{< tabs >}} + + {{< tab name="MinIO" icon="minio" >}} + + ```bash + mc retention set --default governance 30d my-cellar/my-locked-bucket + mc retention info --default my-cellar/my-locked-bucket + ``` + + See the MinIO documentation for [`mc retention`](https://docs.min.io/community/minio-object-store/reference/minio-mc/mc-retention.html). + + {{< /tab >}} + + {{< tab name="AWS CLI" icon="aws" >}} + + ```bash + aws s3api put-object-lock-configuration \ + --bucket my-locked-bucket \ + --object-lock-configuration '{"ObjectLockEnabled":"Enabled","Rule":{"DefaultRetention":{"Mode":"GOVERNANCE","Days":30}}}' \ + --endpoint-url https://cellar-c2.services.clever-cloud.com + + aws s3api get-object-lock-configuration \ + --bucket my-locked-bucket \ + --endpoint-url https://cellar-c2.services.clever-cloud.com + ``` + + See the AWS CLI documentation for [`put-object-lock-configuration`](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object-lock-configuration.html). + + {{< /tab >}} + +{{< /tabs >}} + +Object Lock provides two retention modes: + +- **Governance** prevents deletion or retention changes unless a client with the required permission explicitly bypasses the protection. Use it when authorized operators must retain an override capability. +- **Compliance** can't be bypassed through the S3 API and prevents deletion or retention-period reductions before expiry. Use it only after validating the policy and duration. + +The default rule applies to object versions uploaded after you configure it. To protect an existing version, set retention directly on that version. Overwriting an object creates another version, while deleting it without a version ID can add a delete marker. The protected version remains stored and recoverable. + +### Hold an object without an expiration date + +A legal hold protects one object version until an authorized user explicitly removes the hold. It is independent of any fixed retention period. The following examples enable and disable a legal hold on the current version of `report.pdf`. + +{{< tabs >}} + + {{< tab name="s3cmd" icon="terminal" >}} + + ```bash + s3cmd setobjectlegalhold ON s3://my-locked-bucket/report.pdf + s3cmd setobjectlegalhold OFF s3://my-locked-bucket/report.pdf + ``` + + {{< /tab >}} + + {{< tab name="MinIO" icon="minio" >}} + + ```bash + mc legalhold set my-cellar/my-locked-bucket/report.pdf + mc legalhold info my-cellar/my-locked-bucket/report.pdf + mc legalhold clear my-cellar/my-locked-bucket/report.pdf + ``` + + Use `--version-id` to target a specific version. See the [`mc legalhold` documentation](https://docs.min.io/community/minio-object-store/reference/minio-mc/mc-legalhold.html) for recursive and version-specific operations. + + {{< /tab >}} + + {{< tab name="AWS CLI" icon="aws" >}} + + ```bash + aws s3api put-object-legal-hold \ + --bucket my-locked-bucket \ + --key report.pdf \ + --legal-hold Status=ON \ + --endpoint-url https://cellar-c2.services.clever-cloud.com + + aws s3api put-object-legal-hold \ + --bucket my-locked-bucket \ + --key report.pdf \ + --legal-hold Status=OFF \ + --endpoint-url https://cellar-c2.services.clever-cloud.com + ``` + + See the AWS CLI documentation for [`put-object-legal-hold`](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object-legal-hold.html). + + {{< /tab >}} + +{{< /tabs >}} + ## Uploading objects with presigned URLs and checksum validation Pre-signed URLs allow the client to upload files directly to S3 without ever exposing your credentials. You simply generate a temporary, time-limited URL and the client uses it to upload their file to your cellar. From 5ce22ad217289ee51a022f98de37bee3a9f2b144 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 26 Aug 2026 22:28:26 +0200 Subject: [PATCH 03/73] guides: add Maudit --- .../styles/config/vocabularies/Doc/accept.txt | 1 + content/guides/_index.md | 1 + content/guides/maudit.md | 92 +++++++++++++++++++ data/icons.yaml | 1 + shared/static-guides.md | 1 + 5 files changed, 96 insertions(+) create mode 100644 content/guides/maudit.md diff --git a/.github/styles/config/vocabularies/Doc/accept.txt b/.github/styles/config/vocabularies/Doc/accept.txt index 0d0a918c5..793b02ac8 100644 --- a/.github/styles/config/vocabularies/Doc/accept.txt +++ b/.github/styles/config/vocabularies/Doc/accept.txt @@ -62,6 +62,7 @@ LTS Lume Materia Matomo +Maudit Maven Metabase middleware diff --git a/content/guides/_index.md b/content/guides/_index.md index 3a9c7df5f..63fd1b931 100644 --- a/content/guides/_index.md +++ b/content/guides/_index.md @@ -44,6 +44,7 @@ llmsTxtOptional: true {{< card link="/developers/doc/kubernetes/operator" title="Kubernetes Operator" subtitle="Manage Clever Cloud add-ons from Kubernetes" icon="kubernetes" >}} {{< card link="/developers/guides/tutorial-laravel" title="Laravel" subtitle="Deploy a Laravel application" icon="laravel" >}} {{< card link="/developers/guides/lume-deno" title="Lume (Deno)" subtitle="Deploy a static Lume website with Deno" icon="deno" >}} + {{< card link="/developers/guides/maudit" title="Maudit" subtitle="Deploy a static Maudit website with Rust" icon="maudit" >}} {{< card link="/developers/guides/mdbook" title="mdBook" subtitle="Deploy a static mdBook website" icon="mdbook" >}} {{< card link="/developers/guides/mkdocs" title="MkDocs" subtitle="Deploy a static MkDocs website" icon="docs" >}} {{< card link="/developers/guides/moodle" title="Moodle" subtitle="Deploy and configure a Moodle learning platform" icon="moodle" >}} diff --git a/content/guides/maudit.md b/content/guides/maudit.md new file mode 100644 index 000000000..a1716dfd2 --- /dev/null +++ b/content/guides/maudit.md @@ -0,0 +1,92 @@ +--- +type: docs +linkTitle: Maudit +title: Deploy a Maudit website +description: Deploy a Maudit static website built with Rust on Clever Cloud +keywords: +- maudit +- rust +- static site generator +- static website +- website deployment +--- + +{{< hextra/hero-subtitle >}} + Deploy a static website built with Maudit and Rust on Clever Cloud. +{{< /hextra/hero-subtitle >}} + +[Maudit](https://maudit.org/) is an open source Rust library for generating static websites. A Maudit project is a regular Rust program that generates its pages and assets during the build phase. + +## Create a Maudit project + +You need [Git](https://git-scm.com/downloads) and [Rust](https://www.rust-lang.org/tools/install) to follow this guide. Install the Maudit CLI and start its interactive project generator: + +```bash +cargo install maudit-cli +maudit init +``` + +Enter `myMauditSite` as the project directory, select the `Basics` template and decline the Git repository initialization. Then move into the generated project: + +```bash +cd myMauditSite +``` + +If you already have a Maudit project, run the following commands from its root directory. + +## Create a Static application + +Install [Clever Tools](/developers/doc/cli/), log in and create a Static application linked to your project folder: + +```bash +npm i -g clever-tools +clever login + +clever create -t static + +# Or link an existing Clever Cloud application: +clever link your_app_name_or_ID +``` + +Clever Tools targets your personal organisation by default. To use another organisation, add `--org ORGANISATION` or `-o ORGANISATION` when you create or link the application. + +## Configure the application + +Use a dedicated S build instance, then set the generated website directory and the command Clever Cloud runs during the build phase: + +```bash +clever scale --build-flavor S +clever env set CC_WEBROOT "/dist" +clever env set CC_BUILD_COMMAND "cargo run --jobs 1 --config profile.dev.debug=0" +``` + +Some Maudit dependencies require significant memory to compile. On an S build instance, a plain `cargo run` can compile several dependencies in parallel and exhaust the available memory. The `--jobs 1` option compiles them sequentially, while `--config profile.dev.debug=0` omits debug information that is unnecessary for generating a static website. + +These options allow the build to use the smallest tested instance size. The command then runs the Maudit project to generate the website in `dist/`, whose contents are served by the Static runtime from its default XS instance. + +## Deploy the website + +Commit the project and deploy it: + +```bash +git init +git add . +git commit -m "First deploy" + +clever deploy +clever open +``` + +You can display your website's URL or add a custom domain. A custom domain also requires [DNS configuration](/developers/doc/administrate/domain-names/): + +```bash +clever domain +clever domain add your.website.tld +``` + +## Learn more + +{{< cards >}} + {{< card link="/developers/doc/applications/static/" title="Static applications" subtitle="Configure and deploy static applications" icon="static" >}} + {{< card link="" title="Maudit documentation" subtitle="Build static websites with Maudit and Rust" icon="maudit" >}} +{{< /cards >}} diff --git a/data/icons.yaml b/data/icons.yaml index 308d742eb..a11779ed2 100644 --- a/data/icons.yaml +++ b/data/icons.yaml @@ -125,6 +125,7 @@ docusaurus: hugo: html: +maudit: mdbook: nuxt: diff --git a/shared/static-guides.md b/shared/static-guides.md index 97e1ce716..b5f1a0c89 100644 --- a/shared/static-guides.md +++ b/shared/static-guides.md @@ -5,6 +5,7 @@ {{< card link="/developers/guides/hexo" title="Hexo" subtitle= "Build and deploy a static Hexo based website on Clever Cloud" icon="hexo" >}} {{< card link="/developers/guides/hugo" title="Hugo" subtitle= "Build and deploy a static Hugo based website on Clever Cloud" icon="hugo" >}} {{< card link="/developers/guides/lume-deno" title="Lume (Deno)" subtitle= "Build and deploy a static Lume (Deno) based website on Clever Cloud" icon="deno" >}} + {{< card link="/developers/guides/maudit" title="Maudit" subtitle= "Build and deploy a static Maudit website with Rust on Clever Cloud" icon="maudit" >}} {{< card link="/developers/guides/mdbook" title="mdBook" subtitle= "Build and deploy a static mbBook based website on Clever Cloud" icon="mdbook" >}} {{< card link="/developers/guides/mkdocs" title="MkDocs" subtitle= "Build and deploy a static MkDocs based website on Clever Cloud" icon="docs" >}} {{< card link="/developers/guides/nuxt" title="Nuxt" subtitle= "Build and deploy a Nuxt application on Clever Cloud" icon="nuxt" >}} From 39a836ed78f6b6f69e77b737bb091bfe86c1acaf Mon Sep 17 00:00:00 2001 From: David Legrand Date: Thu, 27 Aug 2026 02:07:49 +0200 Subject: [PATCH 04/73] addons(metabase): document the official CLI --- content/doc/addons/metabase.md | 37 +++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/content/doc/addons/metabase.md b/content/doc/addons/metabase.md index 47a528d76..63a01aeba 100644 --- a/content/doc/addons/metabase.md +++ b/content/doc/addons/metabase.md @@ -55,7 +55,7 @@ Real ID: metabase_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Name: myMetabase Your Metabase is starting: - - Access it: https://xxxxxxxxxxxxxxxxxxxx-metabase.services.clever-cloud.com + - Access it: https://your-metabase.services.clever-cloud.com - Manage it: https://console.clever-cloud.com/addon_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ``` @@ -75,6 +75,41 @@ Once you created your add-on, open the management URL or look for `MB_SITE_URL` - [Learn how to use Metabase](https://www.metabase.com/learn/metabase-basics/getting-started/find-data) +## Manage content with the Metabase CLI + +The official Metabase CLI (`mb`) interacts with your instance through its API to manage questions, dashboards, collections, transforms, and other content. It differs from the `clever metabase` commands, which manage the Clever Cloud add-on, its version, and lifecycle. + +The CLI requires Metabase 0.58 or later and Node.js 20.6 or later. Install the [official npm package](https://www.npmjs.com/package/@metabase/cli) globally: + +```bash +npm i -g @metabase/cli +``` + +Authenticate with the URL displayed when you create the add-on or available from its [Clever Cloud Console](https://console.clever-cloud.com/) dashboard: + +```bash +mb auth login --url https://your-metabase.services.clever-cloud.com +``` + +On Metabase 0.63 and later, select the recommended browser authentication to sign in with your password or single sign-on (SSO) and approve access. Metabase versions 0.58 to 0.62 require an [API key](https://www.metabase.com/docs/latest/people-and-groups/api-keys), as do automated environments. API keys inherit the permissions of their Metabase group, so select one with only the access required for your tasks. + +Once authenticated, you can check the active profile and manage your instance: + +```bash +mb auth status +mb collection list +mb dashboard list +``` + +Credentials are stored in a local profile. Name profiles when you manage multiple instances: + +```bash +mb auth login --profile production --url https://your-instance-metabase.services.clever-cloud.com +mb dashboard list --profile production +``` + +Some command groups require a newer Metabase version or a Pro or Enterprise feature. The CLI checks these requirements before sending a request. Run `mb --help` to list available commands and refer to the [Metabase CLI documentation](https://www.metabase.com/docs/latest/installation-and-operation/metabase-cli) for complete usage details. + ## Password reset > [!WARNING] From fff643020dd191b94dec45a2d9703329237a9acd Mon Sep 17 00:00:00 2001 From: Mathieu Santostefano Date: Fri, 28 Aug 2026 11:30:33 +0200 Subject: [PATCH 05/73] develop(build-hooks): fix Pre Build hook behavior on deployments from cache --- content/doc/develop/build-hooks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/doc/develop/build-hooks.md b/content/doc/develop/build-hooks.md index 099613657..ee06d6567 100644 --- a/content/doc/develop/build-hooks.md +++ b/content/doc/develop/build-hooks.md @@ -77,7 +77,7 @@ If you need support for other hooks, please reach out to our support and explain This hook is ran before the dependencies are fetched. If it fails, the deployment fails. -This hook is ran every time. +This hook is not ran during deployments from cache. This hook is perfect for: From 643bc2866dace0b4f3cec27dc8680da440b56469 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Fri, 28 Aug 2026 23:31:23 +0200 Subject: [PATCH 06/73] develop(build-hooks): use active voice for hook execution --- content/doc/develop/build-hooks.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/doc/develop/build-hooks.md b/content/doc/develop/build-hooks.md index ee06d6567..f0038c9e1 100644 --- a/content/doc/develop/build-hooks.md +++ b/content/doc/develop/build-hooks.md @@ -74,10 +74,10 @@ If you need support for other hooks, please reach out to our support and explain **By using `CC_PRE_BUILD_HOOK`**. -This hook is ran before the dependencies are fetched. If it fails, the +This hook runs before the dependencies are fetched. If it fails, the deployment fails. -This hook is not ran during deployments from cache. +This hook doesn't run during deployments from cache. This hook is perfect for: @@ -88,10 +88,10 @@ This hook is perfect for: **By using `CC_POST_BUILD_HOOK`.** -This hook is ran after the project is built, and before the cache archive is +This hook runs after the project is built, and before the cache archive is generated. If it fails, the deployment fails. -This hook is not ran during deployments from cache. +This hook doesn't run during deployments from cache. This hook is perfect for: @@ -104,10 +104,10 @@ This hook is perfect for: **By using `CC_PRE_RUN_HOOK`.** -This hook is ran before the application is started, but after the cache archive +This hook runs before the application is started, but after the cache archive has been generated. If it fails, the deployment fails. -This hook is ran every time. +This hook runs every time. This hook is perfect for: @@ -117,10 +117,10 @@ This hook is perfect for: **By using `CC_RUN_SUCCEEDED_HOOK` or `CC_RUN_FAILED_HOOK`.** -These hooks are ran once the application has started (or has failed starting). +These hooks run once the application has started (or has failed starting). Their failure doesn't cause the deployment to fail. -One of these hooks is ran every time. +One of these hooks runs every time. These hooks are perfect for: From 60b5d4b39f139f84c9d697959b48fa2f2a8954b6 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Mon, 31 Aug 2026 20:26:12 +0200 Subject: [PATCH 07/73] changelog: Keycloak 26.7.3 --- .../changelog/2026/08-31-keycloak-26.7.3.md | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 content/changelog/2026/08-31-keycloak-26.7.3.md diff --git a/content/changelog/2026/08-31-keycloak-26.7.3.md b/content/changelog/2026/08-31-keycloak-26.7.3.md new file mode 100644 index 000000000..766ed3260 --- /dev/null +++ b/content/changelog/2026/08-31-keycloak-26.7.3.md @@ -0,0 +1,39 @@ +--- +title: Keycloak 26.7.3 (security update) +description: Keycloak 26.7.3 fixes twenty vulnerabilities affecting token exchange, OIDC and fine-grained admin permissions, and corrects performance regressions introduced in 26.7.1 +date: 2026-08-31 +tags: + - addons + - keycloak +authors: + - name: Sébastien Allemand + link: https://github.com/allemas + image: https://github.com/allemas.png?size=40 + - name: David Legrand + link: https://github.com/davlgd + image: https://github.com/davlgd.png?size=40 +excludeSearch: true +--- + +[The release 26.7.3](https://github.com/keycloak/keycloak/releases/tag/26.7.3) of Keycloak is available on Clever Cloud. It's a security update that addresses twenty vulnerabilities, without any critical one, unlike [26.7.2](/changelog/2026/08-24-keycloak-26.7.2/) published last week. + +Two issues stand out. [CVE-2026-18215](https://nvd.nist.gov/vuln/detail/CVE-2026-18215) and [CVE-2026-18214](https://nvd.nist.gov/vuln/detail/CVE-2026-18214), both rated 8.1, let external token exchanges bypass the configured Microsoft tenant and Google hosted domain. [CVE-2026-18571](https://nvd.nist.gov/vuln/detail/CVE-2026-18571), rated 7.2, allows a delegated administrator to assign groups they don't manage when creating a user. + +[CVE-2026-35563](https://nvd.nist.gov/vuln/detail/CVE-2026-35563) carries the highest score of the release, 8.5, but it doesn't affect running instances. The vulnerable Apache Directory client is a test dependency, used by the embedded LDAP server of the Keycloak test suite. The upgrade to ApacheDS 2.0.0.AM27 that closes it leaves the LDAP user federation code untouched. + +The other fixes address medium and low severity issues, mostly in fine-grained admin permissions (FGAP v2) and OIDC edge cases: [CVE-2026-16093](https://nvd.nist.gov/vuln/detail/CVE-2026-16093), [CVE-2026-16072](https://nvd.nist.gov/vuln/detail/CVE-2026-16072), [CVE-2026-16089](https://nvd.nist.gov/vuln/detail/CVE-2026-16089), [CVE-2026-16104](https://nvd.nist.gov/vuln/detail/CVE-2026-16104), [CVE-2026-16105](https://nvd.nist.gov/vuln/detail/CVE-2026-16105), [CVE-2026-16106](https://nvd.nist.gov/vuln/detail/CVE-2026-16106), [CVE-2026-16108](https://nvd.nist.gov/vuln/detail/CVE-2026-16108), [CVE-2026-17059](https://nvd.nist.gov/vuln/detail/CVE-2026-17059), [CVE-2026-18201](https://nvd.nist.gov/vuln/detail/CVE-2026-18201), [CVE-2026-18209](https://nvd.nist.gov/vuln/detail/CVE-2026-18209), [CVE-2026-18218](https://nvd.nist.gov/vuln/detail/CVE-2026-18218), [CVE-2026-18570](https://nvd.nist.gov/vuln/detail/CVE-2026-18570), [CVE-2026-18572](https://nvd.nist.gov/vuln/detail/CVE-2026-18572), [CVE-2026-18573](https://nvd.nist.gov/vuln/detail/CVE-2026-18573), [CVE-2026-79652](https://nvd.nist.gov/vuln/detail/CVE-2026-79652) and [CVE-2026-19729](https://github.com/keycloak/keycloak/issues/51745), an incomplete fix for a path traversal reported in 26.6.4. + +The release also corrects performance issues of the 26.7 branch. Admin API requests no longer resolve every role across all realms, their cost stops growing super-linearly with the number of realms, and an upgrade no longer causes sustained high CPU usage on every node. It fixes an Admin UI regression introduced in 26.7.2, a `NullPointerException` on composite roles referencing a deleted role and offline client session errors. + +Update through the add-on's dashboard in the [Clever Cloud Console](https://console.clever-cloud.com). You can also set `CC_KEYCLOAK_VERSION` of the underlying Java application to `26.7.3` and rebuild it, or use [Clever Tools](/doc/cli/operators/): + +```bash +clever features enable operators + +clever keycloak version check yourKeycloakNameOrId +clever keycloak version update yourKeycloakNameOrId +clever keycloak version update yourKeycloakNameOrId --target 26.7.3 +``` + +- [Read the Keycloak 26.7.3 release notes](https://www.keycloak.org/2026/08/keycloak-2673-released) +- [Learn more about Keycloak on Clever Cloud](/doc/addons/keycloak) From dbc14b5ebb5722ce611ded2a75cc5024b2039b0e Mon Sep 17 00:00:00 2001 From: David Legrand Date: Tue, 1 Sep 2026 14:48:36 +0200 Subject: [PATCH 08/73] postmortem: 2026-08-07 --- content/postmortem/2026-08-27.md | 75 ++++++++++++++++++++++++++++++++ content/postmortem/_index.md | 1 + 2 files changed, 76 insertions(+) create mode 100644 content/postmortem/2026-08-27.md diff --git a/content/postmortem/2026-08-27.md b/content/postmortem/2026-08-27.md new file mode 100644 index 000000000..c7dd0b269 --- /dev/null +++ b/content/postmortem/2026-08-27.md @@ -0,0 +1,75 @@ +--- +title: '2026-08-27' +description: Malformed domain name crash-looping the Sōzu public load balancers, causing a platform-wide outage in every region +date: 2026-08-31 +excludeSearch: true +type: docs +--- + +{{< hextra/hero-subtitle >}} + +A malformed domain name propagated to the public load balancers crash-looped them, making applications, the Console and the APIs unreachable for around 20 minutes. + +{{< /hextra/hero-subtitle >}} + +On August 27, 2026, between 15:55 and 16:15 CEST, the public load balancers of Clever Cloud stopped serving traffic in every public region. Applications hosted on the platform, the Console, and our APIs were unreachable for up to 19 minutes, with traffic progressively recovering from 16:06. No data was lost, and applications themselves kept running throughout: the outage was confined to the routing layer. + +The incident was limited to the public load balancers, which run Sōzu, in every region. Dedicated load balancers weren't affected. Status updates were communicated through: + +## Timeline (CEST) + +| Time | Description | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| 2026-08-27 15:55 | Malformed routing update propagated; load balancer workers crash-loop in all public regions; traffic stops being served | +| 2026-08-27 15:55–15:57 | External probes alert the on-call teams | +| 2026-08-27 16:00 | Incident published on the status page | +| 2026-08-27 16:05 | Load balancers fully restarted in the Paris region | +| 2026-08-27 16:06 | Traffic recovers in Paris | +| 2026-08-27 16:09–16:14 | Remaining public regions restarted | +| 2026-08-27 16:15 | All public regions nominal, incident resolved | +| 2026-08-27 16:35 | Root cause reproduced locally; fixes opened the same day | + +## Analysis + +At 15:55 CEST, a call to our self-service API added a domain name to an application, which triggered the propagation of the corresponding ACLs to our load balancers. The update contained an application hostname with a trailing slash (of the form `example.com/`): the faulty control-plane component published the domain name as-is, without stripping the path portion, when adding it to the load balancer configuration. + +Sōzu, the open-source load balancer we develop and operate, interprets a `/` in a hostname as the opening of a regular-expression pattern. Inserting this malformed entry into its routing table failed an internal assertion, which crashed the worker processes. + +Sōzu's main process automatically restarts crashed workers and replays the current routing state to them. Since that state still contained the malformed entry, every new worker crashed within milliseconds, and the load balancers never re-bound their listening ports. Because routing configuration is propagated to all public regions, every public load balancer was affected within seconds. From the outside, connections were accepted by the layer in front and then failed to reach a backend, which surfaced as connection errors and 525 errors on sites behind Cloudflare. + +### Root cause + +Two defects combined: + +- **A control-plane defect**: a component published an application's domain name including its path (`example.com/`) as the load balancer frontend hostname, instead of splitting host and path first +- **A robustness defect in Sōzu**: a malformed frontend hostname made the routing table insertion panic the worker instead of being rejected as an invalid configuration change + +Two factors turned a bad configuration entry into a global outage: + +- Routing configuration is propagated to all public regions at once, with no canary stage +- The worker auto-restart mechanism replays the faulty state, turning a single crash into a persistent crash loop + +### Detection and response + +Our external end-to-end probes fired within seconds and paged the on-call teams at 15:55. Our process-level monitoring of the load balancers reported them as healthy: the main process was alive, only its workers were crash-looping. + +The incident was published on our status page at 16:00. At around 16:05 we fully restarted the load balancer services in the Paris region. A full restart fetches a complete routing configuration from our API, which publishes correctly formed hostnames, so the restarted load balancers came back clean. Traffic in Paris recovered from 16:06, the remaining regions were restarted between 16:09 and 16:14, and all regions were nominal at 16:15. By 16:35 the root cause had been identified and reproduced locally, and fixes were opened the same day. + +### Actions + +**Done:** + +- The faulty control-plane component was taken out of production, fixed and redeployed. It now strips the path from domain names before publishing them to the load balancers +- Our load balancer monitoring now checks the actual listening ports, so a main process with dead workers can no longer report as healthy + +**In progress:** + +- Update Sōzu to reject a malformed frontend hostname as an invalid configuration change instead of panicking: [sozu-proxy/sozu#1312](https://github.com/sozu-proxy/sozu/pull/1312) + +**Longer term:** + +- Per-region routing configuration propagation with a canary region, to reduce the blast radius of faulty updates + +### Conclusion + +A single malformed domain name stopped traffic in every public region for 19 minutes, because two layers that should have contained it did not: the control plane published the entry without validating it, and Sōzu crashed on it instead of rejecting it. We have fixed the component at fault, closed the monitoring blind spot that hid the crash loop, and are hardening Sōzu and our propagation model so that a bad configuration entry stays a local, recoverable event. We apologize to our customers for the disruption. diff --git a/content/postmortem/_index.md b/content/postmortem/_index.md index 20c65c1af..fc2986d62 100644 --- a/content/postmortem/_index.md +++ b/content/postmortem/_index.md @@ -10,3 +10,4 @@ type: docs - [2025-03-03](/postmortem/2025-03-03) - [2025-10-09](/postmortem/2025-10-09) - [2026-03-19](/postmortem/2026-03-19) +- [2026-08-27](/postmortem/2026-08-27) From 457ec857214d7700e480f890703e2f53c7243c77 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Tue, 1 Sep 2026 17:00:00 +0200 Subject: [PATCH 09/73] changelog: MySQL 9.7 --- content/changelog/2026/09-01-mysql-9.7.md | 39 +++++++++++++++++++++ content/doc/addons/mysql.md | 2 +- data/software_versions_shared_dedicated.yml | 1 + 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 content/changelog/2026/09-01-mysql-9.7.md diff --git a/content/changelog/2026/09-01-mysql-9.7.md b/content/changelog/2026/09-01-mysql-9.7.md new file mode 100644 index 000000000..6e6a9fd65 --- /dev/null +++ b/content/changelog/2026/09-01-mysql-9.7.md @@ -0,0 +1,39 @@ +--- +title: MySQL 9.7 is available on Clever Cloud +description: The first MySQL 9 branch supported on Clever Cloud, based on Percona Server 9.7.1-1, the first long term support release since 8.4 +date: 2026-09-01 +tags: + - addons + - update +authors: + - name: David Legrand + link: https://github.com/davlgd + image: https://github.com/davlgd.png?size=40 +excludeSearch: true +--- + +MySQL 9.7 is available on Clever Cloud for add-ons creation and migration, based on [Percona Server for MySQL 9.7.1-1](https://docs.percona.com/percona-server/9.7/release-notes/9.7.1-1.html) released on 5 August 2026. MySQL 8.4 remains the default version for now, so pick 9.7 explicitly from [the Console](https://console.clever-cloud.com) or with Clever Tools: + +```bash +clever addon create mysql-addon myDatabase -p xxs_sml --addon-version 9.7 +``` + +## Why no MySQL 9 branch until now + +MySQL now alternates quarterly innovation releases and long term support (LTS) ones. Each innovation release is only supported until the next one lands, which doesn't match the stability expected from a managed database. Percona, whose server we deploy, [decided not to package any 9.x innovation release](https://www.percona.com/blog/no-mysql-9-x-innovation-releases-from-percona/) and to wait for the next LTS. MySQL 9.7 is that release, and the first one of the branch you can run on Clever Cloud. + +Percona also skipped 9.7.0, [which shipped with higher severity CVEs](https://www.percona.com/blog/inside-mysql-9-7-lts-features/), and started the series at 9.7.1 with those fixes already applied. + +## What MySQL 9.7 brings + +The [Hypergraph Optimizer](https://www.percona.com/blog/inside-mysql-9-7-lts-features/) reaches the community edition and rewrites how complex joins are planned. JSON duality views expose relational data as JSON documents you can read and write through a single format. + +Group replication gets flow control monitoring, extended multi-threaded applier statistics, automatic eviction and rejoin of unhealthy nodes, and an up-to-date aware primary election that picks the most synchronized secondary. A lower-version replica can also connect to a higher-version source, which allows phased upgrades across a replication topology. + +## End of life of previous versions + +MySQL 5.7 and 8.0 are end-of-life, and Percona [published its final 8.0 release in June 2026](https://docs.percona.com/new/2026/06/10/percona-server-for-mysql-8046-37-has-been-released/). Neither branch receives regular security updates anymore. If you still run a 5.7 or 8.0 add-on, migrate it to 8.4 or 9.7 through our migration process. + +- [Learn more about MySQL on Clever Cloud](/doc/addons/mysql/) +- [Learn more about MySQL 9.7 features](https://docs.percona.com/percona-server/9.7/whats-new-mysql-9.html) +- [Percona Server for MySQL 9.7 documentation](https://docs.percona.com/percona-server/9.7/index.html) diff --git a/content/doc/addons/mysql.md b/content/doc/addons/mysql.md index 142ca3d18..95820279b 100644 --- a/content/doc/addons/mysql.md +++ b/content/doc/addons/mysql.md @@ -24,7 +24,7 @@ MySQL is an open source relational database management system (RDBMS). Clever Cl ## Supported Versions -Use the 8.4 long term support (LTS) branch for new add-ons. MySQL 8.0 [reached its end of life on 30 April 2026](https://www.mysql.com/support/eol-notice.html) and [Percona Server 8.0 had its final release in June 2026](https://docs.percona.com/new/2026/06/10/percona-server-for-mysql-8046-37-has-been-released/), so we recommend you migrate your existing 8.0 add-ons to 8.4. +Two long term support (LTS) branches are available for new add-ons: 8.4, used by default, and [9.7](/changelog/2026/09-01-mysql-9.7/). MySQL 5.7 and 8.0 are end-of-life and [Percona Server 8.0 had its final release in June 2026](https://docs.percona.com/new/2026/06/10/percona-server-for-mysql-8046-37-has-been-released/), so we recommend you migrate your existing add-ons on these branches to 8.4 or 9.7. {{< software_versions_shared_dedicated mysql>}} diff --git a/data/software_versions_shared_dedicated.yml b/data/software_versions_shared_dedicated.yml index 2e90e282f..fc8358c7d 100644 --- a/data/software_versions_shared_dedicated.yml +++ b/data/software_versions_shared_dedicated.yml @@ -17,6 +17,7 @@ mysql: - 5.7 (EOL) - 8.0.46 (EOL) - 8.4.10 + - 9.7.1 dev: - 8.0.46 (EOL) From 9259965d733efee08f7f08a1e51c815bfe93c96f Mon Sep 17 00:00:00 2001 From: David Legrand Date: Tue, 1 Sep 2026 17:08:00 +0200 Subject: [PATCH 10/73] changelog: PostgreSQL 18 by default --- .../2026/09-01-postgresql-18-default.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 content/changelog/2026/09-01-postgresql-18-default.md diff --git a/content/changelog/2026/09-01-postgresql-18-default.md b/content/changelog/2026/09-01-postgresql-18-default.md new file mode 100644 index 000000000..ed8d7a2de --- /dev/null +++ b/content/changelog/2026/09-01-postgresql-18-default.md @@ -0,0 +1,30 @@ +--- +title: PostgreSQL 18 becomes the default version on 15 September +description: New PostgreSQL add-ons created without an explicit version will run PostgreSQL 18 +date: 2026-09-01 +tags: + - addons + - update +authors: + - name: David Legrand + link: https://github.com/davlgd + image: https://github.com/davlgd.png?size=40 +excludeSearch: true +--- + +[PostgreSQL 18 is available on Clever Cloud](/changelog/2025/10-08-postgresql-18/) since October 2025, and [PostgreSQL 17 has been the default](/changelog/2025/03-27-postgresql-default/) for new add-ons since March 2025. **Starting 15 September 2026**, a new PostgreSQL add-on created without an explicit version runs PostgreSQL 18. + +This affects add-ons creation only. Existing databases keep the version they run today and are never upgraded without your action. When you're ready, use Clever Cloud's automatic migration process to move them to PostgreSQL 18. + +You can still create an add-on on any other supported version, from the Console or with Clever Tools: + +```bash +clever addon create postgresql-addon myDatabase -p xxs_sml --addon-version 17 +``` + +PostgreSQL 18 uses the same default extensions as PostgreSQL 17. It brings asynchronous I/O with `io_uring`, [virtual generated columns](https://www.postgresql.org/docs/18/sql-createtable.html#SQL-CREATETABLE-PARMS-GENERATED-STORED), UUIDv7 generation, improved text processing and multiple authentication and security features. + +Keep in mind that PostgreSQL 14 reaches its end of life on 12 November 2026. Plan a migration to a newer version before that date to keep receiving security updates. + +- [Learn more about PostgreSQL on Clever Cloud](/doc/addons/postgresql/) +- [PostgreSQL versioning policy](https://www.postgresql.org/support/versioning/) From fb51560b5a558efe309d64f8562db5cfb6ae650e Mon Sep 17 00:00:00 2001 From: David Legrand Date: Tue, 1 Sep 2026 17:15:00 +0200 Subject: [PATCH 11/73] changelog: PHP 8.5 by default --- .../changelog/2026/09-01-php-8.5-default.md | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 content/changelog/2026/09-01-php-8.5-default.md diff --git a/content/changelog/2026/09-01-php-8.5-default.md b/content/changelog/2026/09-01-php-8.5-default.md new file mode 100644 index 000000000..869456c2c --- /dev/null +++ b/content/changelog/2026/09-01-php-8.5-default.md @@ -0,0 +1,39 @@ +--- +title: PHP 8.5 becomes the default version in October +description: Set CC_PHP_VERSION to 8.4 before the October image release if you want to keep your current PHP version +date: 2026-09-01 +tags: + - images + - update +authors: + - name: David Legrand + link: https://github.com/davlgd + image: https://github.com/davlgd.png?size=40 +excludeSearch: true +--- + +[PHP 8.5 is available](/changelog/2026/01-15-images-update/) on Clever Cloud since January 2026, and [on the FrankenPHP runtime](/changelog/2026/02-25-images-update/) since February 2026, through the `CC_PHP_VERSION=8.5` environment variable. PHP 8.4 is still the default version for both runtimes. + +In the image release that follows **1 October 2026**, PHP 8.5 becomes that default. From then on, a PHP or FrankenPHP application deployed without `CC_PHP_VERSION`, or with `CC_PHP_VERSION=8`, runs PHP 8.5. + +## Keep your current version + +If you want to stay on PHP 8.4 or an earlier version, set `CC_PHP_VERSION` explicitly **before that date**, from the Console or with Clever Tools: + +```bash +clever env set CC_PHP_VERSION 8.4 +``` + +Applications that already pin a version, such as `CC_PHP_VERSION=8.3`, are not affected. + +## Prepare the move + +Deploy a review app or a test application with `CC_PHP_VERSION=8.5` to validate your code before October. Check that the extensions you rely on are [available for PHP 8.5](/doc/applications/php/extensions/), as a few of them aren't packaged for this version yet. + +PHP 8.4 [leaves active support on 31 December 2026](https://www.php.net/supported-versions.php), but keeps receiving security fixes until 31 December 2028. Pinning `CC_PHP_VERSION=8.4` is a supported choice for the next two years, not a temporary workaround. PHP 8.5 gets active support until the end of 2027 and security fixes until the end of 2029, so moving now gives you a full extra year of upstream bug fixes. + +Take this opportunity to check your older applications: PHP 8.2 reaches its end of life on 31 December 2026 and stops receiving security fixes then. If you run `CC_PHP_VERSION=8.2`, plan an upgrade before the end of the year. + +- [Learn more about PHP on Clever Cloud](/doc/applications/php/) +- [Learn more about FrankenPHP on Clever Cloud](/doc/applications/frankenphp/) +- [PHP migration guide from 8.4 to 8.5](https://www.php.net/migration85) From 9dca32ed85fafba14f1dfe763e3612a3043fa913 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 07:27:31 +0200 Subject: [PATCH 12/73] docs(contributing): align commit conventions with changelog practice --- AGENTS.md | 9 +++++++-- CONTRIBUTING.md | 12 +++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1a2b8ee7b..8ddc0021f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -109,15 +109,20 @@ For changelog entries, also include: - For content updates, use `section(page): commit message`, for example: - `addons(postgresql): document pg_partman support` - `applications(nodejs): clarify pnpm configuration` - - `changelog(metabase): announce 0.63.14 security update` - `guides: add SvelteKit` for a new deployment guide +- For changelog entries, use `changelog: what you announce`. Name the product and its version, or the change itself, instead of starting with a verb: + - `changelog: Keycloak 26.7.3` + - `changelog: MySQL 8.0.46 and 8.4.10` + - `changelog: PostgreSQL 18 by default` + - `changelog: images updates, 2026W34` +- Commit a changelog entry with the documentation pages and data files it relies on, so an announcement never lands before the pages it links to - For documentation structure, Hugo, deployment, CI, tooling, or dependency changes, use standard Conventional Commits, for example: - `feat(hugo): add a shortcode for version tables` - `fix(ci): run Vale on shared content` - `refactor(layouts): simplify changelog rendering` - `chore(deps): update the Hextra theme` - Split content and structural changes into separate commits when possible -- Start the subject with a lowercase imperative verb +- Start the subject with a lowercase imperative verb, except for changelog entries ### Code and Technical Examples diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b0fd3b86e..30e56fa97 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,12 +107,22 @@ For content updates, use `section(page): commit message`. The section and page i ```text addons(postgresql): document pg_partman support applications(nodejs): clarify pnpm configuration -changelog(metabase): announce 0.63.14 security update guides: add SvelteKit ``` Use `guides: add Product` when adding a deployment guide. Start the subject with a lowercase imperative verb. +Changelog entries are the exception. Use `changelog: what you announce`, naming the product and its version or the change itself rather than starting with a verb: + +```text +changelog: Keycloak 26.7.3 +changelog: MySQL 8.0.46 and 8.4.10 +changelog: PostgreSQL 18 by default +changelog: images updates, 2026W34 +``` + +Commit a changelog entry together with the documentation pages and data files it relies on, so an announcement never lands before the pages it links to. + For changes to the documentation structure, Hugo configuration or templates, deployment, CI, tooling, or dependencies, use the standard Conventional Commits format `type(scope): commit message`: ```text From 65145e584ae540fde351fb75d67beee2c1ddda94 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 07:49:07 +0200 Subject: [PATCH 13/73] chore: remove dead files, drafts and stale lint configuration --- .github/styles/Guides/ellipsis.yml | 10 -- .gitignore | 1 - .gitlab-ci.yml | 7 - .markdownlintignore | 2 - .vale.ini | 4 +- README.md | 2 +- content/_index.md | 1 - drafts/community.md | 24 ---- drafts/elastic.md | 16 --- drafts/medusajs.md | 46 ------- drafts/mysql.md | 12 -- drafts/notifications.md | 151 ---------------------- drafts/postgresql.md | 20 --- drafts/pricing.md | 12 -- drafts/shortcodes.md | 87 ------------- drafts/ssh-access.md | 83 ------------ layouts/docs/single.html | 19 --- layouts/partials/components/feedback.html | 42 ------ layouts/shortcodes/imgproc.html | 60 --------- shared/git-push.md | 21 --- static/cloud-synccloud-icon.png | Bin 3736 -> 0 bytes static/favicon.ico.png | Bin 1480 -> 0 bytes static/images/open_the_app_ico.png | Bin 663 -> 0 bytes static/images/pg-studio.png | Bin 741685 -> 0 bytes 24 files changed, 3 insertions(+), 617 deletions(-) delete mode 100644 .github/styles/Guides/ellipsis.yml delete mode 100644 .gitlab-ci.yml delete mode 100644 .markdownlintignore delete mode 100644 drafts/community.md delete mode 100644 drafts/elastic.md delete mode 100644 drafts/medusajs.md delete mode 100644 drafts/mysql.md delete mode 100644 drafts/notifications.md delete mode 100644 drafts/postgresql.md delete mode 100644 drafts/pricing.md delete mode 100644 drafts/shortcodes.md delete mode 100644 drafts/ssh-access.md delete mode 100644 layouts/docs/single.html delete mode 100644 layouts/partials/components/feedback.html delete mode 100644 layouts/shortcodes/imgproc.html delete mode 100644 shared/git-push.md delete mode 100644 static/cloud-synccloud-icon.png delete mode 100644 static/favicon.ico.png delete mode 100644 static/images/open_the_app_ico.png delete mode 100644 static/images/pg-studio.png diff --git a/.github/styles/Guides/ellipsis.yml b/.github/styles/Guides/ellipsis.yml deleted file mode 100644 index 305d64fb4..000000000 --- a/.github/styles/Guides/ellipsis.yml +++ /dev/null @@ -1,10 +0,0 @@ -extends: existence -message: "Include the framework in the title!" -nonword: true -level: error -scope: heading -action: - name: remove -tokens: - - '\[\.\.\.\]' - diff --git a/.gitignore b/.gitignore index 9463fbde0..e2bd9db11 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ Thumbs.db # Configuration files .clever.json -.vale.ini # Build/cache files/folders /.hugo_build.lock diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index c2c88abe7..000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,7 +0,0 @@ -include: - - component: $CI_SERVER_HOST/pipelines/clever-cloud-pipeline/deploy-to-prod@~latest - inputs: - stage: deploy - when: always - - diff --git a/.markdownlintignore b/.markdownlintignore deleted file mode 100644 index a6cb7ebc9..000000000 --- a/.markdownlintignore +++ /dev/null @@ -1,2 +0,0 @@ -/public/** -/resources diff --git a/.vale.ini b/.vale.ini index ebc876a2e..b39f99934 100644 --- a/.vale.ini +++ b/.vale.ini @@ -7,11 +7,11 @@ MinAlertLevel = suggestion Packages = Hugo, Google [*.md] -BasedOnStyles = Clever, Vale, Google, Guides +BasedOnStyles = Clever, Vale, Google Google.Headings = NO Vale.Terms = NO Google.Parens = NO Google.Ellipses = NO [*.xml] -Transform = docbook-xsl-snapshot/html/docbook.xsl \ No newline at end of file +Transform = docbook-xsl-snapshot/html/docbook.xsl diff --git a/README.md b/README.md index 1f5f26cf5..39afbe9a4 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ Run a production build before submitting a change: hugo ``` -The repository provides [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) rules in [`.markdownlint.jsonc`](./.markdownlint.jsonc), CLI configuration in [`.markdownlint-cli2.jsonc`](./.markdownlint-cli2.jsonc) and editor exclusions in [`.markdownlintignore`](./.markdownlintignore). Run the version installed by Mise: +The repository provides [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) rules in [`.markdownlint.jsonc`](./.markdownlint.jsonc) and CLI configuration in [`.markdownlint-cli2.jsonc`](./.markdownlint-cli2.jsonc), which excludes the paths listed in [`.gitignore`](./.gitignore). Run the version installed by Mise: ```bash markdownlint-cli2 "**/*.md" diff --git a/content/_index.md b/content/_index.md index a3018df56..dae236a18 100644 --- a/content/_index.md +++ b/content/_index.md @@ -1,5 +1,4 @@ --- -type: docs title: Clever Cloud Documentation description: Documentation and guides to deploy, manage, and monitor your services on Clever Cloud layout: hextra-home diff --git a/drafts/community.md b/drafts/community.md deleted file mode 100644 index 661cd1bc7..000000000 --- a/drafts/community.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -type: docs -title: Community -weight: 6 -keywords: -- support -- community -- gitter -- irc -draft: true ---- - -Engage in our Developer Community by seeking or providing advice on application and development level questions. We have a community of developers using our platform and you can help and be helped there. - -## Gitter - -- English room: -- French room: - -## Public IRC Channel - -We’re also available on IRC. You can join our channel: - -- [#clevercloud on irc.freenode.net](irc://irc.freenode.net:6667/clevercloud) diff --git a/drafts/elastic.md b/drafts/elastic.md deleted file mode 100644 index 59edd88a3..000000000 --- a/drafts/elastic.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -type: docs -title: Elastic -description: Elastic guides -keywords: -- elastic -- kibana -- APM -aliases: -- /doc/deploy/addon/elastic/kibana -draft: true ---- -{{< cards >}} - {{< card link="/developers/guides/elastic/kibana" title="Customize Kibana" subtitle= "Deploy and customize a Kibana server on Clever Cloud" icon="kibana" >}} - -{{< /cards >}} diff --git a/drafts/medusajs.md b/drafts/medusajs.md deleted file mode 100644 index eed0a3bbd..000000000 --- a/drafts/medusajs.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: 'Medusa.js' -date: 2023-11-13T11:00:11+01:00 -draft: true -type: docs ---- - -## Create your Medusa.js project from scratch - -1. Deploy a PostgreSQL add-on and a Redis add-on -2. Copy the value of `POSTGRESQL_ADDON_URI` -3. In your terminal, run `npx create-medusa-app@latest --db-url ` -4. Follow the steps to configure your Medusa project -5. In your code, replace `DB_URL` by `POSTGRESQL_ADDON_URI` -6. Create a Node.js app in Clever Cloud -7. Inject your environment variables -8. Set a domain name and inject it as an environment variable: `MEDUSA_URL`=`}} - {{< card link="/developers/guides/proxysql" title="ProxySQL" subtitle= "Configure and use ProxySQL for MySQL add-ons" icon="mysql" >}} -{{< /cards >}} diff --git a/drafts/notifications.md b/drafts/notifications.md deleted file mode 100644 index 10fe9fc8b..000000000 --- a/drafts/notifications.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -type: docs -title: Notifications -description: How to setup and configure notifications via clever-tools -keywords: -- notification -- webhook -- e-mail -- email -- slack -- flowdock -aliases: -- /doc/administrate/clever-tools/notifications -- /doc/cli/notifications/ -draft: true ---- - -The *Notifications* service allows you to choose the events of interest to you -and decide where to send corresponding notifications. - -## E-mails - -Historically and by default, deployment result e-mails (deployment succeeded or -failed) were always sent to the owners of an application, namely the user -themselves or the organisation's members. - -Using the `notify-email` command of *clever-tools*, you can choose to disable -this or to restrict it to only some applications. - -To do this, you need to delete the hook named *Default deployment result -e-mails*, then add a new one and set it to your liking. - -Issue this command to learn more about this: `clever help notify-email`. - -In the future, this service will also handle credits warning notifications and -others to come. You will be able to choose wether or not to receive an e-mail -and/or for these events to be forwarded to a web service via a *webhook*. - -## Webhooks - -Webhooks are defined as follows: - -> A webhook in web development is a method of augmenting or altering the -> behavior of a web page, or web application, with custom callbacks. These -> callbacks may be maintained, modified, and managed by third-party users and -> developers who may not necessarily be affiliated with the originating website -> or application. -> — Wikipedia[^1] - -[^1]: Excerpted from Wikipedia's [webhook page](https://en.wikipedia.org/wiki/Webhook) - -In practical terms, this means that you can choose to receive all deployment -result events on an endpoint of your application without having to listen to -all events via the Websocket API. No more lost events and having to reconnect -to the websocket if and when it fails. - -*clever-tools* has a `webhooks` command which allows you to list existing -webhooks, remove one or add a new one. - -You can issue this command to learn more about it: `clever help webhooks`. - -### Example: Slack deployment results Webhook - -First, you will have to create the *Incoming WebHooks* integration on Slack: - -Let's go to the [custom integrations -page](https://slack.com/apps/manage/custom-integrations), once there go to -*Incoming WebHooks*. - -You will find an *Add Configuration* button on the left which will take you to -the page where you need to configure the integration. You just need to select -the channel where you want the notifications to be posted, then it will show -you the Webhook URL, it starts with `https://hooks.slack.com/services/`. Copy -that URL. - -Now, let's create the Webhook! - -Go into the application directory for which you want to receive notifications -and there issue this command: - -```shell -clever webhooks add "deployment results on Slack" https://hooks.slack.com/services/xxxxxx/yyyyyy/zzzzzzzzzzzzz --format slack --event META_DEPLOYMENT_RESULT -``` - -#### Events available - -The list of values that can be assigned to `--event` option: - -**Account:** - -- `ACCOUNT_CREATION` -- `ACCOUNT_DELETION` -- `ACCOUNT_EDITION` - -**Addon:** - -- `ADDON_CREATION` -- `ADDON_DELETION` - -**Application:** - -- `APPLICATION_CREATION` -- `APPLICATION_DELETION` -- `APPLICATION_EDITION` -- `APPLICATION_REDEPLOY` -- `APPLICATION_STOP` - -**Deployment:** - -- `DEPLOYMENT_ACTION_BEGIN` -- `DEPLOYMENT_ACTION_END` -- `DEPLOYMENT_FAIL` -- `DEPLOYMENT_SUCCESS` -- `GIT_PUSH` - -**Organisation:** - -- `ORGANISATION_CREATION` -- `ORGANISATION_DELETION` -- `ORGANISATION_EDITION` -- `ORGANISATION_USER_ADDITION` - -**Meta:** - -- `META_SERVICE_LIFECYCLE` = APPLICATION_STOP, DEPLOYMENT_ACTION_BEGIN, DEPLOYMENT_FAIL, DEPLOYMENT_SUCCESS -- `META_DEPLOYMENT_RESULT` = DEPLOYMENT_FAIL, DEPLOYMENT_SUCCESS -- `META_SERVICE_MANAGEMENT` = ADDON_CREATION, ADDON_DELETION APPLICATION_CREATION, APPLICATION_EDITION, APPLICATION_DELETION` -- `META_CREDITS` = CREDITS_ADDED - -**Others:** - -- `CLEVER_TOOLS_REQUEST` -- `CREDITS_ADDED` - -##### Examples - -Get a message in a Slack channel when the deployment for an application failed: - -```shell -clever webhooks add "The application failed to deploy" https://hooks.slack.com/services/xxxxxx/ --format slack --event DEPLOYMENT_FAIL -``` - -Notify your accounting service when credits are added: - -```shell -clever webhooks add "credits added" https://hooks.slack.com/services/xxxxxx/yyyyyy/zzzzzzzzzzzzz --format raw --event META_CREDITS -``` - -All done! You can now push your application (`clever deploy`) or restart it -(`clever restart`) and you will see the result of the deployment in your Slack -channel. diff --git a/drafts/postgresql.md b/drafts/postgresql.md deleted file mode 100644 index 14cf692a3..000000000 --- a/drafts/postgresql.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -type: docs -title: PostgreSQL -description: Configure and manage your PostgreSQL add-ons -keywords: -- balancing -- connection -- limit -- load -- pgpool -- pool -- postgres -- proxy -- sql -draft: true ---- - -{{< cards >}} - {{< card link="/developers/guides/pgpool" title="Pgpool-II" subtitle= "How to configure and use Pgpool-II for PostgreSQL add-ons" icon="pg" >}} -{{< /cards >}} diff --git a/drafts/pricing.md b/drafts/pricing.md deleted file mode 100644 index 194ed299a..000000000 --- a/drafts/pricing.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -type: docs -title: Pricing -draft: true -description: Pricing table of Clever Cloud's runtimes -keywords: -- pricing -aliases: - - /clever-cloud-overview/pricing/ ---- - -Our up-to-date prices (as well as a pricing calculator) is available on the [pricing page](https://www.clever.cloud/pricing). diff --git a/drafts/shortcodes.md b/drafts/shortcodes.md deleted file mode 100644 index dd27d6755..000000000 --- a/drafts/shortcodes.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -type: docs -weight: 150 -title: Shortcode -description: Learn about the available shortcodes to write new documentation. -keywords: -- contribution -- shortcode -- writing -draft: true ---- - -To call a shortcode you need to write `{{}}`. - -## Alert shortcode - -Use the `alert` shortcode when you want to outline something in particular. The first parameter is the level of the alert, the second is an optional title. Everything inside the shortcode will be the message. The list of alert level is available on [Bootstrap documentation](https://getbootstrap.com/docs/4.0/components/alerts/). - -Here's an example for a warning alert: - -```go -{{}} -This is the message of the warning. -{{}}. -``` - -This will render: - -{{< callout type="warning" >}} -This is the message of the warning. -{{< /callout >}}. - -## image shortcode - -Use the `image` shortcode if you want to embed an image. The first parameter is the link to the image. The second is the title/caption of the image. - -```go -{{}} -``` - -## readfile shortcode - -Use the `readfile` shortcode to include a partial document in your content. It acts as a templating solution to enable reuse of common content. - -```go -{{}} -``` - -It's possible to search and replace variable during templating. Make sure you have a dictionary called `str_replace_dict` in the frontmatter section of the page. - -```go -str_replace_dict: - "@application-type@": "Go" -``` - -## githubReadme shortcode - -Use the `githubReadme` shortcode to embed the Readme of an existing Github project in a page. The first parameter is the group and name of the repository. - -This shortcode will embed the clever-tools readme. - -```go -{{}} -``` - -## tooltip shortcode - -Use the `tooltip` shortcode to provide a definition of the a term in a tooltip. All terms definitions are fetched from the glossary under `/data/glossary.json`. -the `title` parameter is the identifier of the object from `glossary.json`. - -This tooltip - -```go -{{}}PaaS{{}} -``` - -will produce {{< tooltip title="paas" >}}PaaS{{< /tooltip >}} - -## ref shortcode - -This is a default Hugo shortcode to link to another content page. - -This will output the relative link to the common configuration page: `reference/common-configuration/#private-ssh-key` - -```go -{{}} -``` diff --git a/drafts/ssh-access.md b/drafts/ssh-access.md deleted file mode 100644 index 8f840db48..000000000 --- a/drafts/ssh-access.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -type: docs -title: SSH access -weight: 5 -description: SSH access to running instances -keywords: -- ssh -- shell -- console -aliases: -- /doc/administrate/clever-tools/ssh-access -draft: true ---- - -While direct SSH access to instances is not recommended in an [immutable infrastructure](https://boxfuse.com/blog/no-ssh.html) setup, it can be useful for debugging purposes. Clever Cloud allows you to connect to running instances via SSH. - -{{< callout type="warning" >}} -Clever Cloud instances are to be seen as *read-only* resources. Any change made on an instance **will not be persisted**. You can use SSH access for quick tests, but if you want to persist changes, you need to commit them in your repository. Changes made on instances are not kept across deployments. -{{< /callout >}} - -{{< callout type="info" >}} -SSH on docker instances will attach to the running container. You must have `/bin/bash` installed (usually from the `bash` package) otherwise attaching to the container will fail. -{{< /callout >}} - -## Requirements - -You need to have the Clever Tools CLI installed locally. - -[//]: # (ref "/doc/quickstartclever-tools-intro") - -### Make sure you have a properly configured SSH key - -To use SSH access, you need to have an SSH key properly configured in your Clever Cloud account. Please refer to [the SSH keys section of the documentation](/doc/account/ssh-keys-management) to know how to set up your SSH keys. - -## Accessing your machine with Clever Tools CLI - -In order to access the machine via SSH using the Clever Tools CLI - -[//]: # (ref "/doc/quickstartclever-tools-intro) - -you need to have an application running on Clever Cloud and have linked it with your local repository using the Clever Tools CLI with `clever link --org ` - -### Accessing your machine - -You can access running instances of a linked application with `$ clever ssh` in the linked application's repository locally. - -```shell -$ clever ssh -> Opening an ssh shell -> bas@67fbf787-3518-47bb-abd9-2c2575844edd ~ $ -``` - -If multiple instances are running, you will be asked which one to use: - -```shell -$ clever ssh -> 1) Sleepy Ponita - Instance 0 - UP (11281f38-31ff-43a7-8595-a2d82630c32b) -> 2) Tense Caterpie - Instance 1 - UP (b10d19d9-5238-408b-b038-3e32c7a301c2) -> Your choice: 1 -> Opening an ssh shell -> bas@11281f38-31ff-43a7-8595-a2d82630c32b ~ $ -``` - -You are now connected to the machine. - -### Note for Windows users - -`$ clever ssh` command will fail on PowerShell or cmd.exe if there is no `ssh.exe` in your path. -The most straightforward solution is to start `$ clever ssh` from `git-bash` but you can also add `ssh.exe` in your path.. - -## Access your application's folder - -No matter wich way you've decided to use to SSH to the machine, your application's folder is located at: `/home/bas/`. - -## Show your application's logs - -If you want to show your application's logs while you debug: - -```shell -journalctl -efa -u bas-deploy.service -``` - -You can also use `journalctl` [with other options](https://www.commandlinux.com/man-page/man1/journalctl.1.html) if you need to. diff --git a/layouts/docs/single.html b/layouts/docs/single.html deleted file mode 100644 index 4a60b0c77..000000000 --- a/layouts/docs/single.html +++ /dev/null @@ -1,19 +0,0 @@ -{{ define "main" }} -
- {{ partial "sidebar.html" (dict "context" .) }} - {{ partial "toc.html" . }} -
-
- {{ partial "breadcrumb.html" (dict "page" . "enable" true) }} -
- {{ if .Title }}

{{ .Title }}

{{ end }} - {{ .Content }} -
- {{ partial "components/last-updated.html" . }} - {{ partial "components/feedback.html" . }} - {{ partial "components/pager.html" . }} - {{ partial "components/comments.html" . }} -
-
-
-{{ end }} diff --git a/layouts/partials/components/feedback.html b/layouts/partials/components/feedback.html deleted file mode 100644 index ad10d0030..000000000 --- a/layouts/partials/components/feedback.html +++ /dev/null @@ -1,42 +0,0 @@ -
-

Did this documentation help you ?

-
-

- - -

-

- - - - \ No newline at end of file diff --git a/layouts/shortcodes/imgproc.html b/layouts/shortcodes/imgproc.html deleted file mode 100644 index 37e0e181b..000000000 --- a/layouts/shortcodes/imgproc.html +++ /dev/null @@ -1,60 +0,0 @@ -{{- $context := . -}} -{{- $caption := .Get "caption" -}} -{{- $image := .Get "image" -}} -{{- $width := 0 -}} -{{- $height := 0 -}} -{{- $imageStyle := .Get "imageStyle" -}} - -{{/* Image processing options */}} -{{- $method := .Get "method" | default "Resize" | humanize -}} -{{- $options := .Get "options" | default "900x webp q95" -}} - -{{- if and $image (not (urls.Parse $image).Scheme) -}} - {{/* Process images in assets */}} - {{- with resources.Get $image -}} - {{- $processed := "" -}} - {{- if eq $method "Resize" -}} - {{- $processed = (.Resize $options) -}} - {{- else if eq $method "Fit" -}} - {{- $processed = (.Fit $options) -}} - {{- else if eq $method "Fill" -}} - {{- $processed = (.Fill $options) -}} - {{- else if eq $method "Crop" -}} - {{- $processed = (.Crop $options) -}} - {{- else -}} - {{- errorf "Invalid image processing command: Must be one of Crop, Fit, Fill or Resize." -}} - {{- end -}} - {{- $width = $processed.Width -}} - {{- $height = $processed.Height -}} - {{- $image = $processed.RelPermalink -}} - {{- else -}} - {{/* Otherwise, use relative link of the image */}} - {{- if hasPrefix $image "/" -}} - {{- $image = relURL (strings.TrimPrefix "/" $image) -}} - {{- end -}} - {{- end -}} -{{- end -}} - - - - -{{- $padding := "p-4" -}} -{{- with $caption -}} - {{- $padding = "pt-4 px-4" -}} -{{- end -}} - -{{- with $caption -}} -
{{- $caption | markdownify -}}
-{{- end -}} - -
\ No newline at end of file diff --git a/shared/git-push.md b/shared/git-push.md deleted file mode 100644 index bba67c947..000000000 --- a/shared/git-push.md +++ /dev/null @@ -1,21 +0,0 @@ -## Push your code - -Once you complete these steps, commit your content to the local repository and deploy it: - -```bash -git add . -git commit -m "First deploy" -clever deploy -clever open -``` - -You can display your website's URL or add a custom domain to it (you'll need to configure DNS): - -```bash -clever domain -clever domain add your.website.tld -``` - -## 404 page location - -If you need to use a specific page for 404 errors, define its location with `SERVER_ERROR_PAGE_404` environment variable from Static Web Server, used as default in `static` runtime. For example : `SERVER_ERROR_PAGE_404=404.html`. diff --git a/static/cloud-synccloud-icon.png b/static/cloud-synccloud-icon.png deleted file mode 100644 index eb8f9f65f3ec75cefe6bcf1a6c87929c4e47cce1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3736 zcmV;J4rlR+P)n`pP#k!GX&SY+wv2XNouR4SR#r#6077bt#B-cI@zzY* z1MFc*L}8N(ByBg;ZD?^2TZc5st`KO0q1;ML&Hk{sP}VH={SN1Rf3BUbNt4*u$=d#; z0#uT7pG{V}{jmzH0<@i|$#gFHG0fyB zz%CW26e&uRf|LpfARtnTka(9g5R{COJReX^l8T+JAxtEcSH64dv=41WTZo#>~6P7f0;7IfN!Eko!DW9*r%tm#A-&4_K=~>8^P0*o`QtYde zOi~x~(y6V8%+Sp~TbDU4X>t*JcTAlgffl3XM4j9D-NS(j2F-LbK1T?G`nJd%ov6;x zSod2?`}SYkyfYmDq*1{kCT_a|YkA=Q%#`GrnQt{&EhTDlXD-c$ENPPXibB6*9CeYO z8`$>d3q@!F#y38YVp{r{mpp(z4T?KcdWtgQUiYqde_w_cp|wPPyJwQ;gDm-=8m1TX zc4XV@r-mT{FkyMN)uTM+I<%t)&smuN@y%7qk8%rBV||GJ7N$YP zvQd#FVCOxIamw;(FQES3oyUUIEg#Puh8CeEL`~*$>~QrIKp8BCRKbz2ygt@4^Pdmd zcV8*xB4=Fu99n)NdLKLsZA(N8g5!(aO2$(FA^^WlEBEDxcmPfhy2 zES||Vmp;iu3(yjxVjdoH``Vs3isl1H8US7ifjuYbDBg^PSIB+P0yIq&PdhQ~?QT`D zUuJP@amc8RXKph+}Ml*cKC-6gQT0d9rJSGxHSpIKXW zi=K4@z;WElTNGDi!~=IlSE<&$usSq`DQeEg8A)=GS|3|UFcQR0?e^Ay&j zO|FnYto^CW<=`Bzz(Xs_z86e}!u_S?o(P*tVlx9#nl@0eHgycd4-M1N3I z1=8ZbRwlvf+n}6;8_5^-r--`v<0lSR0~&PI5hLN6A^>wXAu8pj=btaaXBeX!_KJ_{=L<^NxuUB) zO3z8LgIMqW%IF-wHHWC_zI+PV1ev6yuCs|s$tgM0Ua8e+VB@cz8-!~Jqde8P+;LQs zWi86gRIISP-~DK%?z86jsFQF^G2~nMhv4IOHTR zkwcB|4T<_sUp^07eABd&UHic!%HBTw>lMr0qDD_;tc=Rb@&#X>c4eMhpUb!hAyI62 zT3@Dycd~~%(s>P&&V87$jJ%?W;z%}w zrX@ld+vJHb&6PIq6=Zr-Gb&<`7z)Z(t=iuam^d`|Le}08c+!( zZEI3YMv}v%crw&+!DQF0-AuxD3PSIk*)fTYkirs6ivMaxbwHCL3TFzbtum!v(Lrh*7C|Ux^m9Of2q|l?nDgeM5o_+CH3@U*_u+f77 zVG1I`U(>tOY|=+5P#N7VN3K^vHvxxFSU*9xVIe(IU~;k~ z$H`Ag{{b`!4^&DyPi@pu(FH2r%|9FV`3Ym@{!D1iy$T+&VT z5)L^BYMybFiHwUnVlMq@)2^fP?D*!LX$}WV{23-(*X@R0+4w*PngpMyOHPJ%JKP`)30uuY9g6Vz zp~#ndPM0h^7SxoK!6jpW4kP8FQ+~)pOe@>0X?aH5nYaa-0Bh%YuFfP~BdC?SbxavI zXND78p6II&U+?ro3yAv1y$>Db+Fw2_MAR*V7ZH4lF5Nu1(CT((^L=@KpLFx3>=A4v z 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 diff --git a/static/images/pg-studio.png b/static/images/pg-studio.png deleted file mode 100644 index 188a9bfce94d76c7bbdab821f3cd48c2a70eeb7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 741685 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 k#KRlXkf#v@5vmqGN4DJg zedH=>Gx1XARS;L{_OQ?GB1SpMAc z8Xv0}P*S36IsHkmvXrAj={#zANovEIMZ8$i3*ot0{~(IQKj{Q!Rjl!tyz2bnQ^kb@ zmgH^B9$7*2kYpYf+$R7}?0XQ1FtJG-^|YF%8Ksm>_V#7-IH_sGZjNvVmZ=R7+P{tW z1+w^o5^!Cx4S8vzr8yUbP?Nc1l1|GjLYE&zgMGd0Lz(v{kk0~wt{mj7;TQ2NTBGo$ z;G{Cvdl{#eDU5}Ek#{=nS8BviS4DE%h3oa+Qcg(E;TuPMxV@~`RH*T)SHmz-uGEuI zvEz7#`wS;fOpZje+%rI^h1Fvs9D~_$vZ;c0e3cLAp%u*dpsb@A+X2O1kb*o0?MDEz12p_NOB`7&#eCzl> zSCq8H>9EhJr8L_RG2DG!sP4lz5Bdg&ewxW+FT+&$5D-G7Irs zj(8NNE_=Sg!KY;q9iP6Lwb{+#vGF?b z(VJek5m+3^JX}&3(!n$oe&n=Vv6xM3AxT3R`p$|i_z8;)t$Q8AtI7!9W&O%iOE&fr z!TD=uAx|{-TVIC(r;i>nHC|f#C*_zjhhKN^95W7`9b3}lQP+or#1`dtg`8SKQrme! z3`37aHb~5pG(J3~|MQpZql+cvqkSoTLj~JU!QqRxA7vQvb|+YdjJ`61IxYr z`v<}FcN+zBlT{~m|bE?VQ(^N{)2g&4Yld)+tNZNFHg;stXrffX*L~ zp6@Cm3A&5CFFgR@?EI`8WV;H@<}KG;>du8MPhZ|kaTX+>}_JJ zNWi;J?9fkJptyy$lV#Q9u`MC=V7c25&?ktkkJ%?mbVf4XZ&=fquJ*(!u?5r#IIWir zjkkF5JDqKDWRhui%*<%Tq^gx__;p6GKz}A*B>aOsz^V4dBRol5FG}%vYaR<79lcQS z$5UpFhKD0LvOEpm=jNoI^To*u;~YcOs2ZC&Oo0a1iG+96ToMqu&oth<$~P;$k$~te zy2+hxaXB}uU2eYA@oxBMoJWt`VLbii(;lA}f2ODpsy{{?@`|+~mt8ewz zh_W6N-tn|k%XowcA0@j)r(CMt#;AEvB+M0VW6gAg*Q#2gFR7G+#Gwlzn)r22xi*k4 zF;lY*j8};?A=_~BUX5dNge=)7b@g(^Gbh1TFyhzL?kR^7O9 zBTo%>17sztMb_sUi8MKFZOG(|f?zb-JZ6)>vFSFAc5Kho;s}}#fB)2$^7Efm-(tor zuH*}tt-BV6i*~{{Py%V@um3$drp_7hi(hVx=N`- zM0EY!{ccs;n4>T~FGBXfvqFpwH3{>0M{DDpQAE5j-1h0&| zJhNrf-t)}R?@6V8x)CRny&`5nkf@@FO&8Ct>}&q!=awwgYSz~MabA;7jhc>h+0*)3 z9x=%Rj|!qxRolwiaH;(Xvcwm(`zMRr3=i^E6)~N6_bQWKEtV##;k8qx2d=PWw0@Mn zb2Thx>26qfcgzE`^pqdk$gm?+b9*`ZfNrfn1t?38JD>9$CC`qKzbGpq?-cjSiQVhs z#aBLGXrz%`jxn3epiGNKDx7Q_-`P@)(@ieD`sRpf>9d}40esSSJ$*q}J5r?g0(1P8 z3)Od}XZf~D4|@`C5ZSu@Sf-O7WzxHANOT#XgAV_3W@*p(JyjMHdHA4Cbb8KS%;ph9RMAI7Oh zdX^<8IixBX50Ds+@6wqH#$f6pR!IBe>5c~=g{OqeouDB$8QZbc8IdVHQ4&x`mb6Ev zus;!>U;gQ?5iO$woI-%644umNM+gB^*}ES!L7%MU3_Cm{LI@ZisccWzc1~5kin^&* zsu>(c%mQsCP5l=2JTz_ival5Gv%Vi%>v0(N{)Fl%C)>t#THwr{B|LGoRI~nOBD*nr zgVV+=F(~00?!jxX2DDM}WKpLQl}2s~0go_R$>@cNV%Y7*mau_R4#(Aj_9pj(>geY6 z$(llG)?(N1N)y>Dbe-a^t627{j zXD%IWDM8_RSMn`@h_F}L)IT2;m(W0PC{d~QPok(%sBF=BL8)P@&oG0uaX;{lGcvPtkV zWUlwuoq3m7fQo;X9qSW6iu7j~Wil*+&2~FSa)=BTYR^XVes+=Ug`a?G+N0nV$~yqW z4({0?kn@8(d>3_>S26nKGCy=i){DC{r+So)NRW`49-?j!gGpxe2fX zr^7LOD)M6iu?=JWHlnv{jq!&CcPr8scN?>M%l~_mj6aM~-cUJR2Ps55dmkn;g{|K@ z#!jt3b{9GXLL*eQ#URC2A;%VtH>1Q7b{edeT}xAO@#xf#6YLL13vK8LP8rr)(se0^ zxj{@-4fXgjOx}Ar68Rk=?RvB9SYG-8h1UK=A5+#+c`?zex;0Bl&1pbDV12u`HNWY2 z4CWxbz_cZ}<2S;C+*gE>mv7VPC4e=yT%`wL1uk?c-%Jv}(<_{jK-%K&l@hf)T~Dd# zMY#0Snh+ReLVv`uvvlUz!kG)*{P9uG=U4u(AMsh@J3z8t?Ke?OU$N=7eCuz-*=vs| zd>uw;B?!yLG-|C)A8QwZF}&GX&O1J8mF5zcA~LO`lP_2yJxUMm{1FR9h$E}x2>Unh zGhNNpSU=+4(#q5V^it|?MsA8;ba&>PE!_=X-*niSuVxax;cx;#WZ=GIQwkcmu7eol zUB@ADD{VV~!`M$x3_ISn1%!9J#EWwRyhG*DIc+x-lGg=PetM@oyMgkKe_~C;0#D+- zb*A#r00M&JQWhnMVSvg+zLJE~#^m!N8<&|ZQT*lj35{>Vikl zJ?r8Vgs`6kH=DwBHS10KNlslRpJlRS^~LLXw+7)pu3iO-Y=CO2r*_7woM-Nw4uO^G zHv4Lq(r`&o^rNWfu4bJkyN|ZU#OOB%zas#pQh&8iV;T?mR-rx!PeWT?&D67` z?syhbK#Vdt48Onc3W|xI8E+_C_Z6rVzFQ8$?KrI=2H~b?QSWM3-8c(%LW^}W<n)|VpSQ~enY z?S`XSH(54!#dkfg7UgdIFA|qzb}}i#g&w~S?*y<2=JPym_>LIbaD0MS{kyW2+#gt1 zW=ej(1^oOX8ZuI>QjYYAULR(2X8C=Jm%Dy(xNdo0U5dJ%Fa%xQIOp683j6W`?eFQf zk;1nzK%YqEy*(6$6-+YeAc$lZ1(H2sda z&6u>&KoAqfC5^UCfDj3k2Mh-O@ECG6_Hq@ZY~BET@yGW5K}n{1^&DT1Rk6d_P^CHD zVPYMcY00c=>8@OueKRQ&?*c|kax<~eq0NWPHCqEzfKc1Za6dlJuuWIbvgL%!u2fzu z_H26U4)L1d$7dX$&rURaJ4)Kd7oI+5@JD$@u#Vz+^uht(U_uAAm$rM-H zLy4Z~eaYBQf&{ZR*=$coHjo~HO!Q#ZtZXumIj&MTT3mMw1CPnTCw)2`7@%l4?5@p0 z7QSOhKNR)C4jwp1x>M;+iaPK7(lD)3!?hEU0_F@3Na+APByQs}9~PBtA`f$LW3Lz& z4aW1&Eu0gCG7+Ch)2(bg^*TS)eE7EcrSk?Svrdf+TZT<4-y=@5&kES`;u%a6wu6I= z4R&v${0uWrXEG(^gOH5opYhr@$BHe7Q^J$`E_zHO=WoB-%0ig*^GW!lT44Bl4tEer17Y<+1`VsPio+Sj|k&c`X{hYt_CS zQokgNjHS}Qxut+3*>wv&8hEYbycQ3+ZRaz>K^SpOAQbDJx$s*o6<~~S;1|5H&U27A z^yM|R>-U&k&8;lM1d6X~)#|7Ff#yR67AD0LO?s^Q6AHbzo{KrweTFl^JF$vpm38 z{YW4=&Rw6sKCQJ!Vleubu znaXpP;YJOzjBN=oyXES`M1kVRByr`pEjeV3jo^7f<;ke#+_-)PD>2s8nw5Z|Qdznq zarcQmeyPp?DDrmD5%z z<^31|DE66lC1Fo=sF;q)1S5VHo_t_(C=--)3WoXk_~fbQS5WUwi)W5bm^Q`*rQ@9` z$=Bc-ADu`3PA6HUlP-HB)*suI;X%Uha-T7lt(0h=ezBBnghSBP7tQG8R7MQLF3Sak1}QsTYw!qm|@Ih7z_Md;C;lo!4tmVT_=!cpM?}XW2}8JQQk?&szjUlJpX2); zH&+iK!iuG3d#c;yHdzTF!lReTi+cvX^q^Ze^?IIB(^tM>O6^my>tEbWThg6G zM&!=fqt$fXJ8OD_DH$o7pK%X5*4F}PaOJ!FXc$9USIyz65-g>^%2NlMba`t4@tqQ{ zGQ8lWTdVy`NQrQh9Kf^Qmhx7-tSevI(?PoI)yx}JSCgC0kN3WSwEbF{DKLCUh*uDZ z53`DVifOv6{NEFYfA*QrXDsc3$cc32wNWRENm^XSjZXs>xDR(^@dA$2=H*L_#t^z<#gJf?Nu9`d>E42#=^ zre{`x|J+;7WXG~OgOF3max_~FW%Zs^-0Y3*!T@;YbIL&gwENfE)ygW3x)1FRsj@8w zeADo&3=cXbjeg5=5a6PH4SC~1t-o}(J6I6{#Xhvs#h@e@__!}!(?*y0xW!E2P9+p| zi*mKs_kO<8yWJo6PB$m%Qd%4&nloNd2e_1EPO}?s>M`uM(MUh+j2tKw`F470ZDFge zgbP)ALDw3S>$B&*91)Z7a;$Dmh4TkL^)`ut7f{fO&j86?I(H7uqeX2FXG=%1SdKrK zV8psd$o#cv$}vpPTIlj2D9hsN`O%N8^5jLGz@Cbqs1|Exm_|^DPpKj=&kIXqg^6fM zNyudraUV+<^b&%k7a4CwW)2=J4y9mNqps_Z_4T}uETk2nGKyr(@@w~0cUA7Cm1w&j zu~?Q_R3<23<2Ss7Z-xbxYZ~9asw@273YZe+!|&W&ypA^F=qW>Qvq;j80Z4kxVnQyJ ze`&c}Nqi1878nvW%cO}76a8Kcup7~e(UC}MKZQnBmS(f+aG=%UNnGK1BfYU@R*-(Z z1}6+q`!e(~vo6{oS1#3eBp3c!r1PU@szy*X-{b?#)w6FQ4@kc~&~!F)C<>aVNricy z;o)(epODYAdG&uY?*^NE96|WK)G>9)nZQ zPTz*&nE&+az&#UnaL)TyTuiiD_PVs=YkjBP)euK9HA^OLlMo3}gJNbZRweDhGMvRO(xO=c9MIkb+RdC;>$qPaIi;3nW{ zk#LY41e3&P5Qd}ij^fwumm8dLu~d}JwW=6{I-9qAr7I*SDy7N9Er(e{)n4JuU7Jzb zOnP-Ip;KC{#MY}au1CDxDbsi=SAfZ?-m;lguOaY`2xq&%^wl-(%Ay|^nq8?u;f-A8 z1=%(dHoe3&W{7}6_@cQ&b>2$lG5w&AULWXUFcvc^^JfO+zyDo9p6cb|uAwu`dIWZ2-^;%~uXpfk zgXJ(EkM!R0p?g4fqp$CX^3&xIgDJn8=s(H5#;oo1d1mi=o7md zt5J}C9Sf7UH|!RF_J6TaL)oj{VW^nZV$1kGY9aNOi=keq=1lnQvZi@xNf4~IDP4bR zhf0@{NILi?qpyvqqM2`zd&(XDm-f3+?IRUL7=Tp@c>x)5KnP0kNpLc6+suygC zJ*2Boj&4XL_d|coS;_zl#J3>8aljMpB7CkTPs10wXT_G-`81XPj$jWFEzOLsDImPy zhP67E>mb8RGZ?u`b;+zP622K;{nn>>g6@5F!aP035}uO8?(f`nI<+Mi(G#Q4fMKT@xEYr<5Hqp%qV`Jl7hw; z^dI6hn;eX!&tCepE0Jl?9zwl?uju#B%ogX2IQIPh#qOh*Zb3s7s+`ieI&>8ULHW_~ ztQtkMh^-EkZL~Z7zH8Uum&q2dz~?%keas+CPbiZts_*Q8XfWGSZFwM-6ye2xe`jZ0 z=yW^W8I+?qZ6DVUDK|Jhl}UNl`b64fcV6h3aPX*yRMIG}Qm)Law3n}Nj}EyHR5RvL zPloI!O1KK<=9KhP83P|)a_0oYK%I^lAgop&Npl(nf8AJkfMja`C97@0F$~pDI+D3< zzQZ@69oGQXrHM>>0F7A4qx;`_JcUf|b6ZX3IZH>;_|y9_$N}cJhWf?kwtjbczgE@P zu|h&~i|$1+K&S|8vHVb@=XHq%`0kn89FTFDHy^eDU16kWMd_FO)O*jKL<$M5_9a@|-Yx#PSn9=DyMw+^I3*F@F+_fk zX2cSAD6gvfFv;PrU`xE-bRm(vpM2b>Q)D~Sp#t8v-^39h?2AGPvN;_|LPwv71byc9 zUeR##&}z9WN#3saWzR-Y8z1Vg*gX7mU%`jUo&T*^mQM2tpPaV45nUr6o#cB>${dkk z?Rd65nlvd<&|0mwVJeEtdN5(GnNf2$UF!8jsq2(p##X%2P4`sApJ6|YQ0+6NkBloH zlI01Kwh^X&4Nch4YLT_jQIV|BV9}#l;o!8N`bl)Qm8SQYMCFrieLmp@L^ z^;^2<-Co?BHdQ>1nphZRilH!;r9lCU^-b(_{pSWKhf!Xvz8WFYjPvlu{&n!#Vu;g& z23Au5JvM_GDKh zbAe8eeLuYW&EVaayJ%>6K?WJ`opPN*A5De?hZ}^3v@kN#Q&Y{c%-MatK(3|KC)PL5 zG&dUCp6u|qu<`Hrz2ry_o@>7B=SbD$iSu-K&?vq=V|=Tb`$eYjeaM1leT(VqNT#=m zqaS;_7D{VmW{!_t3~I3pUv>SUzwfyc7wn@Afh;a98OLH2d+oO;96td?-!(6u z3{&K@3}BOSzUfI|V>>~(reAkfNLzMyt}Q6QN3x(;)ystWUhaM7fZrj~rizeBTEBk* z@xIvR`8iyj%yGV5i-?vY7$I_aBfZCypWk&Gzpt_DHhs({=i5fei4D^`^Mt7y>*QGo z;wqG(GY$6Ha2yY&*>)>2J|EAx=u@?*covhj)I;~C?l z4Xyz*YdV+N$@1Ym1rgJfMv0TFpr}kE!2jGC8m{gY8LqL`g1F-zZa{UjmqYgMi^lp^s!^NHkL0S-gCr>vJFCey z(EtpmZM-i)neM$xY;J!vmbPb8X16sM7|46E=1VUt^9G`rSGfN4WX=^Kd3EDfvAu^b zA)Bgpn%gf)OE+L|9nOps+O02Pk{XRS@7(KR9$|O=NES?)<%}Fi<_v)N<%d|tB(-sC{&)Tymn4ld zKo6qpHFm~hCG_N6pwhD&sY-tAB#^^Z*66sa0Ey)+QF(3SP@U2|PIeVKzV%$bw~K|h zf9=2(re_-`kSlIqe-!;4ZqZOgw|Oi@jjvr|;9En&e(Z``D79I8KQmCZTHd=e2@zGb znYN{{j-A8AE(~szmfllavmL3*z|R@ixBltYuX@=g&OJmJ-`h@yQV`3Pbu*Rxs_NrB z|HkDu^l`qd&Rweazuo+kAMe$^k|SA6y!BXBpXFklrNu(~cP&ZA4_)Krdl^{Zp)og0 zs7iE9;685d`-S0hnfyry!|%;nUQQKL{j88hmu=(f++K{^S2#5l{C5np=A=O(bmOH|S6=}1_2PtBeA!T4mgJmwv#zECUmGjR%L z28|^hoNr5HDfE9+tgw6C7SvkPyDh#qQA}~`GLh~ynZyDMMc9`hLEp52#dV%A)Ff$L zzdwvNtnaiCPkgx|LOcL0ObJ4oO*UpN4LV<0aFVoVwmHrdS|e95H|@MB!<3G{4026Q zJ?6r)A|@zRvAJF*wUU&>oiU{WffMcSIHu=L<<6U`KPO-?q&@hZB=-v+R_}E2LWz3$>*+cBTqRw<2vE^q>6)+P|srjs;KL^sH{%)i_8IEFIS z0KU^?ajyjc?g-wJmAtn=JT5r0@B{clE0@H(kYgCDv=(%XDi4Ba*c|kB z9aIgxINpAo8^@gA{HifJ$A5{#V)U-2+`T%#q-o5}$X37Ts#E0DT6*#kxnbhZmrwmE zL0JwBOKH6-XQXC<@>9bm71O90n?{ue=WUCl+|_jRk(};II9-~ltn7O&E&JnIWMOA> zO%o*%Z{BD3VCLH%oEHaz3C(%Z)-atw-`a!G_|=uK5)C~Xx84< zW0pm`?(G2ICi96|t{%LYkfpSIW5n?VYsrVcbeM3}09@#T^W7(*X6MFQS$I?_OzKQ? ztH|nonw@%ML@w~g-e`>^RWy?FTEu#u|1=%X!zAeGedt&c&!jf~G~<=Kwbvx8QiiC# z`$ci>%QYBU>k)~e>tl)g2`2qXQ+~g8Vf;mdrDz|v2PlzaUilZZ*l3&mk76j@MGwVq zG>#Z*z}sw1;58E2Zd?5R6>sFzP1iJhBp5rj`AdYyL09VclZ)8Z5ySdwj5>=`ZuMLiZ29zNRl;IfY7z|6}IYPZJ+zq?|8tHVf}ott+Gm?(?VlQ)hEogdb-`7=121{f9QU! zsq;$0_+gnazEFx*YTH;9T`jm{d~xBrD@1SGr~BBl=7Y&jy3lN!dmn0DJQViB#Mu2$ zEY|O)O!&>sodsJdj&)nBgmD&n(0)lO{}VG0^&tFe68D+WW}1Q)WNe|7jopBN*KN6O zY-2OYI#|BY8E$!E`CGL=2K7ua+(P6P99pm7az(^i-CM7hJj!fwCvaOekc0iSa5I~F z6%M_cz+i8j7(+le+q1I`y1$Em^1WlUedc!udc-qqDugi8G&&A&b@t}k@zA-WQGOQb zd3wMNiIUXiI#cSX8fY>%eLYU~cJBlpcd@+b?sI@CD_d6=g>lo8sK;fhlekqcl-UK< z9ny-x=Fz3K7sKrNWS*W|m$}nY60H1`ltCo@>`A*re&VO0Rs^WI?@ry`Wp6G2u8O&R z1lTH{oK1butS&*fnc7~FRDOu~E}~Yi#AZs-DRGC@v?RsB<7h*%-obcC)%*zegoL$< zA1l$Kw-xo9`3Z#punXShp&Bi`|9`iXqkTxm2`gTyOG=sdp#$ zON(?G2bS!BtI&OmobN@Y*;`xWDMp2>?Q6%~fe%+6oOuxN`^e37che*1X`1cPe0eFq z^CK@MJoE%sEqVY&)!rNpHpD-#$~Kv^-Fa8m*tbHTC17w`M#~c0&}#-0I^9f98!oGH z<9Aw*j174)GW$xFJiqnOvb0`&K=8tf*Bq66(W^bQP&zkOs5ZgtvSp8&kc^OtKaqJf zGbaoADVDEN7!Of?b4k+TS!O7qQL#*!+l02s<*C(poanH;hnr}tS&srmaVvX2+Ej@J zTykZ+l{dzV4Y4e{4l+WM`C5&!dU*BG1b0EhlDYhlo==M;Fe%nEo z#K{h5yGziiQW{)4>rq&rMwgP@z-DVcqRFVjK2g^US$1?RnkwGhka-+{gEJZJ0jN?d zr7%=Qd@{eQO?}%3x89`R_M2d<-8e$1Ps_81=ul_zX1V($oRgXXsLWT(suQ)*fb|HS3$$GVS7-j$lq$F|8GB&>PcZr}BDKL66RlnLY2yKnQH zC0=(XD}`gm)RCtfJ%>Oai)cF4JF&n*^I3DIhVfL>LD|cTeN0Qm&kMVSm8!i(h+6d# zuAm|xBWNylN18kx8NWyFe5e=6S*Uv3lB}@%7Ys(riAGu3e7)vRW2IMHTzVZ89!Q)` zduk8#wMqd}kCwwb$u?~3C)xbQJr~l&udK~ozTN7E?M@zuE^=x5!j1|E0b%N1?520} zsodg)um>6E*7RY~NLI@83E_gqkw&H3#Lg3D^=2)Tt7?_QPqMPPK69&UaZwE_A+)6P zmzM3UXUK_uRm-nF@j4A|y7iSB1Viyvb2?4+md6T?O?mz-lF#V^Wf9%sf}>jiWzgI?t>Y&(d)~rym{Su%M2F;@UjI*Ijhl zl{D`3ivM=w_5N4r-djnDs+dFWq&^U?UJK^HdY9_zp`Wi+|GA0BG`VQn;jKd=gOf$x*kzXd<>gMk zJdgTjG0f1J3uZ`1->{V(JodVzCbn>nj{d=1nfPlnuJR9E9pnfCgJT^FIg#XM5{c+4p0C0ESfCk3PIi$At)s0pP zR7^BtVydu7%gTuJeR!?Ms+usqpEsTztZA|6c62fXeM=sL)6>r8 z%2P^~G(mJ-VK$&2LuwZ2dbTrUj*Z%QUBv}w$d!vD<}i5yx-)7q8uqz`_Q_6W z(eV4WIcg&8F3O_LW2xf<58u`KdKp>==*B>__sKC~V&Qmud&f@P{M|*fE5bfNX(rQW zFJCD=x^~{1f4xYhKsg>`sWbV3=^gp0n%deJl~uCJMrsi>X=!}7T7In2&3fdIzQp4^ zBfZjw4XKfhy|VWsS4lkbd@hF+p&;_32`AyYudXYRle=RFP7R%5%S#Y9_q_Mf|@9}jotIt6-0^r|gXe%f7m z4MV>QTY7#5-ozDG-sO-)Hw^H#f_H&;mmg#OipBB5jo$$)Btw#Q1 z@@kv=_iC6^VMaqQS3}Kohfq2f5j_D=96F4h4WctV{{waBpF}fbIoaA5xSXvUd-4;i zP%csJqIWh^RZEd)er;bO1q06#@O#P{Vk1CB1Ud%Rp)D6TNyEpQj|;X{+qmQCf2HVm zBi^Iv>%8C!Ofs5ZISG|}KIk2+V5hC@PqbW>p|IUXEvO`JHIazA1Ug@?91)cZpf46T zIFt8uuEhDeH-{6Ptpx|@Uy?&}-92)X%$LIL{T&hmLL4+<#^MH-vqzio5dVXf2UyIT zwplK@;nda$$3A3@M<1q60!viq?L7S4nH5D30nft^Rva^RYwwztc{)Wf4j>LgzF+)% zE_>-tH;ICO{U~~bv>w?aGgr1D$!@zQd!F?goUKC-E@OsYrU1{c9@W)J z=|yXAZ*N{QBa|61m*#P9t^xD*gGP^?TV7UfNW)sZqCeoqJmh|C0!OLlz<71y+4QKV zZ|1^A#*M&1D8AFO$toY3jdGa2x$(Kx&v-~u|Jv}G@Y}^;S^Hn!toe>OJ&n(T(LYPV-8>ee|if<%1!#55s%XTZ_ zf-&;_S8M&rwy)_VwHijg-N9T=7^iQVMGf$$KC7yXeCWZMg>1tS>M1HU>1LyUM+RjU zlr*=#tZyG?ZXUAJqQ&P_hv4F}ZYDYQTnhhL;q+6H*X^18 zrIWdb%qAa@ak>S;QAa0$hs)LJv@Pn$+RY%qTT=^V+^s^2G%D#O7bLZOtz9p+hritp za9q8Q>?rA+#p0Q#)vBSb;?o52$fgIr)FeNPvn5k!g5FS{MZdb=X1aH@XV4g|_$gNI z7@we^?lt7atlKoHfvl~BNmj^L-8qnu=^aFPpQPqyJ2t18eQnZ1c*}+M5BPct=y{%H zhjFydwdIVNHZoahK7}p#(hv7md9+-8^)`1F`4&z%{cDeRTy!y~Wj z=HI@pwbA)G(wKm8VjDvt0MR&jfIJ#}9w~XJLUE5LX6H3Glg!O?H!80Wc;tVEVf+i+ zh$Ok;3(Fr0@vYE!emYZR&tmS_&g*cMHxV;;D=9Vo%#6YPG%;eOG*6rfC^(N;DGw-b4#)AEp@(`Zzh4P zbdHO3b1Pv1^-HX08-|-WCpzhjgGOJ)gDVsCR37iHZseYu^p`|NJr;k__G4>k{Ha>RtWLG?A(Wo%W3ze*y1*O?Vdnf3Wp6jtg zjoN}&TS|q_CZJ~;Nwq3#)9vl)#Q2;EO+aS+@nslzKkD<~1r^}z>QcOU z8(KNKV`8ZEpeyll@}ZT=Q-3^}*MH`_{>!P2#(aR3wZI!QtN>jcT;Cx0OJkE%q@)8C zN~Mwe_-S6FzrHm9T(CE*_XCgdRD*Sz`A>4H(`4OOQ75K-k)U@h@4fTor3gBJ)^Ma~ z!@=t#vYnH)Qo4B%PBG>`suMU;#vnQJ>8ue#`$l*HFWrB=0eX`q8vJ5J)1k>~vg{Qm z5i3n;(@Pe~DRmP2^+D=x(9dQI0n?+G_f{6XKss6;^@5autsGPY32t(v6YFO=T%)BPJsd~jC-e4$HuNa0x_8uT7P7n9P(JmZnu-X){}zsnZr zmBH8B;Jldv67XROp{xyE#5oenkMT3op4n%7rwo;k5-EnA|B`;Hp7$yLf`GD1qd|1|LFb z<<^a_0oM}z7m^w&4m8yKLvP+xg~gs)^TA3tU9GNj+GxJ2Y6uZ4)n?6BY&v04)lJw1 z4h1h=+-?qtg%C!y-a^MiiwG9zlDghOT`*K#oPdfFU?Pedcc&cwW(S8K3-9p=co09c zRmDb`{8sw_i4}3aHHGMj{35b)y1$fm2c%R*LWtN{-G41d6>HT7qrJS;0hLq6Tc3vH zgeQekf86!~h^-dOqRnjCD{iaVC)ZgY(4#{dV@V5)I3Hx2`$#OzknKcz(c#J5Qc>T; zvH(Wtu-{Ik(TROQdA%`I$G7jII_3op!{x(;T}BpdZ8ebsTy@L@f8{?4|K=mZ3`XDK z!rF@H+Ii*+`*DCmoFIBLBjlo3v}!(74T7pysSEyH&KvMhL+&z?;Q+s<!q{DBL$Zq4#3FQ^^Y2I5L# zXW}(BQ;ah;wh83?u5Wa~G^Q$6vH(S05x`5l7h9DpvyN~K+ZE>Dg%Q}0jMw04%3Elv zG?=$55*KVKePIe^4C;6OX3q?Oa@tyLvr(UtPLYd)fy|Ev{8NAv^}wZ7M5mR$8L(U; zju{XCZc1)ixT!9sc{k^b{LM&3Y}5}}lp{$DVRINHx=m3gba#s0nV zLjj{sY8ZI)pSu!ul*9ec8FeASs5q_!P40;ht%EqliTQV-{R`cD{~jEQJRR7#ePK~^ z`XK4EDQo@D+au4w&`nTYeS`t5;2tNYzkQal@AbjSk9QX(?h=TL3@_rTrv8WO3$GFZ z^LuvkTpgh% zXM1oD=;mBV^j|I3^_U~6t{3d%hcIkZ$0MS`(0|S2fiW0Ord41WA2B1iMdU1>>~GZT z)5GhHYz$wp4cmUEO7yS0zXGE%(bg(Vc)e)tIKOfKuEc+SDEe@M`N`hW6d!oK$Mg6o zpY&f(qG|?X8e!@}CQ1UqHJMJfy7xD06@?4NM7&lu1|DS<%lr?0zJ4CnEnq`Te&bUS zF9ti9H^)`<=x-jSzyy}T!c}&G;PENxq<{IpSGJrQT;V>(wylQfU<~>^Uqb|B4v4~@BPbD zdC(>7gGktoo4V&>vOw~d>*f%(oksJb!_H6tOhaS!dw(^t`eVPc`=c78ASE zb&NCbA=boNi*(bMx9%Fz`JAiV>u#?Om7JfQsvI_{EdKWd|M=4bH1K?V;jm>IFn-14 zhJOQxa{liFpjWz$da5?Ow3fBxd;}_GeGhL}{H(GXhpFa&7bLg6gp=%|81yMl9B`xviQvSOTjsV9myj%y^whos^|4sS+VP^iNi+}d(hif(X zMD@7(5fHoR9E!hN{eN%cKR!`403{HgK;3QNz76%mQ~2xA{=wC**lV+9Rf`8^LEf=( z?Na>lzWm7reLSF^^j&XQ0v2quvhx2D0Q#SUzaCByE789{T)sb;U6#VNX8vHe;0BsW zC*S-ZEep6=xC4krzxtK(gxns_m{H#!{ENRshp^ z>-@*EEdxZe?KW|KJ5aG$&Z9s04}ZNUL)WfE!?DC*HSnBbgZ?wYzTUx{f1HPL|I^U@ zfgb(Q=G?tLB%Zwzw|EZx7&=*jzaH)XeO1^A>|l7wC9ae8T@)H!#(%njRFO}?A?2Vx1mtpnQQy$XKvpR0h> z?<%16zbf#*D)7H5@c;P~pa+H=B-s)&B_cvv&~_^%Kc?`~xt3_>tV>$9#4yN9v2vu0 zgu&xkl1*_tBhn)c_dA!DgYn0m8p8(gDJj_iNizoDB*_JIT99|)P4iFkc{|R_)qB8} zt`Cs6mp6S%h?K0RHE)`2q}xKl}d%vyW1_?(n&s*l$wL7FW6)SYVZ9F5QP7CiZs zmu}GGw&w8{k-+8jZ0VIWvuTR1&Om{hJSHLYqrAGwqW}+`!C%)gJpy_q4eDnZ zLDQQkM>wz6;-b`T?G}OI5(%$*!b!%a0^!dmTo(d8sG`)A*o(RfAwP6R()E;k$~%K! z+A7TU@ib0PXf`3Q01IL{1r009sJl+MJ=J+4*k>MrLUp%t{cZYU^ z8l7yw`f?bUGL>$}Tq%Y-?3~?7mEQR|k6K3P&921_;ICJvHOfe>rRkV{cAVDLV~LqP zGla2OY6wI)>)iBmkqwV&mTNMRyCI;eTB^Ztum(@?Tjdxc&P``^-W-ntFZ@NDeRuI< zRITxzQ`7XwZ0VOY^wxR5Ef@#6{Eq|EJm;xRA~VvP)`dFr-dLP^!woSo@5$aD0F-IE zdF&oL?8h<$3Ns+gp3W~GLzt=W2|kDtDl z&CR)8Iy=l&vuwZOb=&)VxHY1OP070$)|k0%ea*VH<%z?lG2RKnQB&a5jUPH+Wl*@f*U8G6#^>0FV z2B5_S`rdabCrfJ^-wdK`TQ22vAxpCI_2WGAR4iJYCt;Q7NM{qC9|&9=oG9?N=_xUz z7>tVhWPE+Z<7wt_p_t{>d-6BX9=y17)3*5_&GY#tlWDiVjQa7u1Opu}q0m`h(=Pmt zCnADL;Wd3YCH~>T`^tAChH%4(gLI~2w-d{fl=`e!ewA5AvOI6PU)Vmd2jc(hTa}t| zx6oCcsr@?l&0Xk=OikUnSq~g1@lR=^eD!PD zLI-!j>)u|ac^}`IYBF~G8qTPh6*TMW3c04Tn>JkW?IfC^(d<)mG#_6|o>H3Q83fDNJY>uLTe>Bd#3j5)W_Dhpqa@#*~a2>vY|83V$ z1x&NjfxY2D-U7==#yN(BbN62Rz8qMgvhZ?vzQv!VOuj2gXb45W3K{A4?|(`<9<{X& z+X(RPPySwSHf^#L*(>1nn=syNTQ8u4tl?YR76;ET9fb4lEE!nzX1F4lYZ_YEJvW9` z)`7he!+4nnS8NB;+W0MZ_Tl@$!{{c`EP(^lRN9Lg+l70r@zo;BZ$CMfvbK~f(XTCK z@Pb(a%8|Ill_IVY8aqQ$^qOlLbAo1JgT`dvXkGp6{r<{^KAsgsj1)c9!6$;ut1`nq zq|RMAd-wP$n9OMRJ}CPj%ftA2@$@+Am4u`%76 z+j5|KTO`{W+V$I^p_4x`b8D){CPi2zmKY;8Lfzw{`+M8P$*b8Eq@j=_&?qo+A~@x*U9Y_*~8mg3yFVR%S}|Owz8Kgq{aG z-!>OAmNy}9j#bBQqU(`HNsh**{9>4ip1ZU4V1(z!&@{ckPvi^AF5BuwGu!7aS&Pf4 zE;)*bYnFXK?)GDD8|1P}!R{6alY&G*Y_x9De)RI&33_Zu$UI@m8##Qs3Jj@DVKA^* zn#@{UuVpNZg|LcSr#hkQ`q^w`-jgb&u-|^uB1N)2f)dwUn;&rXgT0Hy&Ru1f{BwzM z!v`$mZB%)oPH`+yV>{4!Wx#CjvqT;FcwdVy2K}x$=78OxL}JC0tgN0BIFE^{8DC2` z_sm5(%)5CEG!c6o_g0!t^1?yDnv;Hi2e~r6K==pu4HvBy;!jQ=jp$%m`$9F`Y!)`w z7FF?h3)^58!zRV6o9(AB>NNEbpQZOh{_KXzWngrNnvPO2CKN4HxKy1bgP;V!h{I~- z`g2=r+vD>557doSgw_4zR))C$VmW_b!IGOOPtJA$6 zFAUtrcV9JKEIE1%)ktxr;1CaYqM1b#FG|g1SU34AIt)l;3N|`>2@1Ui=irPFNseTN zlezY^s@?!)PmqDBcUq03f0X|%AoTf$$gjjv9yw7YrqDAJx;2JwC&K|qg3Y#T7S@Dm zkX_F2`*}YKa&O|yKcQ+xMIezYrnVcXyr(0Vj&6)#lA*Rp??KfhX^r2}cR4(Q@ROHk zCg_2@$(6wM^>!diV1oUF$St8Q)cEFPg|emG{-TxshnLEDN`vFYFOa*d&jIL3rhm2O zmn+6|z%2g8dvj*qr?zF6+I}*xQG{jFc&RT@9cf^J6y+$dKd0%1xjHW}2OY`MeSLJ19dinr-yXlpODMSv-}Rw~eX_s`oGo6k?yRxB198H*&^x4WJaVsWFNu7~!+ zE$1=MPJVJh{AyQ9y4aJ5%a_grPc9{?OkZLo-C|PR#o41;s9a27YqHwlG9xdyQWS&6 z({CFVE3WUsTu=@0h*9#9T@-rC7>Xv5yR!FyNIw-i<{0jeO@6c@=KcGm9+}lz+nW3b z2IXmnmh^lXTChf~qpp3Eoo(2va4vsKaa)oL%1om==*vLJ7fL@x2^9pwr94_8Ev&L5ci_;hd^)dz)E??LqUY5$9J!1{Zow;Y3vhhP?iuig3ivx7)SAs^P4+*`CJU`*Nf-9&HBR5^--o9G?n(9*PK2 za9((sHuhAFOPX4$KyF(yY4DV`x)WkK9#xd(YaT=*fx1eyf&OBva6mVoh_g4pn z{5H=UW%Vr#_NF}M%KuEK@hkF!QoYF5pZKF2aWC>t;LDzu-|53SGjY+K)& zEJCcVJb;gMb>p^&`q@0qNo}dm3e-&IgW$mkHvgs;cm5BK*3D!~tmBA!8Jt3xSHAe0 zw0QOOF1SK~yKwccsLq({hcKWS7u6oXuXi!EUx;@C=0WypxI?3DN&XnNx4NL^r>eyw zWvrSEWQZ%G-~Myp8*%B^--!c~r+d|S_V@(-@fJ?bdR++VtKX!B+}0uV8E3ii(4L3K zWS8RZnH4ETrTppW)`g&Y(;kGMn7sL$kjM5693_c^RA;V{vqm8vlCD3T4+Sx7*N)7~ zDqL~vQm?PE%334u(;{WMqyzIph1BV&jLhy$_cba^b z<#zR-BFDY!mjK2l?)5b*RwIt%GE=fLzr$nB?LlZ=(=*?{;yjkd6V-4_aI0C%yMnK5 zVr>F0&6l*kr|Pc8GO!^1&XQtOkR)?;pnj3r}j&%WqlR26)m;|R3aXU zRcS35E_R&!l`TEKuwbE~@dTab@UPFi1kf@bp8mxN!o}cZTgWv#HCMr=gDN3elRBq8 z;)s@Uh2O?2u#D#Ok@niwinv33XfrhWKLuT@spoV0M%?z%*bhp>ARfm%|$TfXvfa>qR?BZGU1``i-}rP$0& z_|XB8b{Y8pgt9G=y|5on692#l%6|qp%l;?$8a;^KN5pAsN6WeJ)DK$kQv3PG_STn& z@rBGY`SG8Oh`FIf+5XR$$@mN*Ez^jb&+LhJY$qsPW`T(xwr3hM*MN581V68Jpc)cQ zde_+$d&m3o5O6n)6k5T}gV$d*!@SC!$GhYldb77T#seR*c;#MFv1jaw)zEJ{Ljmxb zqwhv0D3fPuy=W}|ts>mf3oSCd4(k{j^lCzAHrxLVw!hu8Ezq( zAnsH4ZtnIYQ3;=HN&7H4HM=PI!XxSX0Eqxv7tl79Q~O$H{Cn0};oZ55bV4DE9Uf{| z)@>uops-T80NzRzb5N(uubJ@}ixE?1EYsdG_wW5NU_&KSKskpHFes zfxJ7`5l@3NvIumRNh^!P@ES{tkPKL&}*O-@!1=}FA z(07%AaAO2qwm;w)7-h_A`fyF|RUL%@m9dkF*34E_4*v(R7A*h$ROK|5&OEdMO6zCM z2YY3Eq*#ymFKcvy03LfBcA4QoeV=l+-Y)L`qi=(XKrf#FCH3{pY#>2;3EMytZ3JpH zh#MKmH1q*7C4o)_uHMu)UYc#D+tiDwQ=#}i-%eLHxSL)}W??k_v8_NF{@6NgcV2m~vm6T9J={Pg zY@10*wUZanX>%JA&3;~YM-j2M<>1-P<(WatUAK|H`BHsQAsZoz%;?&4iIq+Kz%$`n z#AAA`?#~(-5I65wfeqsC=*8qQF*U%g4RmIfA6}`{Js$V;qwyFJSGuv?Z2wC0*FNbQcPj%4s`UcrujmGDNV2 zs5%=6{(LAqXYnZr;{@*7QgONOmZIjoBUX`pxGAYiuW;31$6!Mfn$S#c`kmF9!_jWN zu-rcoc@d^EotCN|OOa%Y08(927+CP8jP0i8iw3-P$#yfor-ek=8XE3CpT?Xn?~x-Q zvH}^vV#efqN8QK>sS}JNI{WsPja@HsO0o)`A?{LR=eXnvv{4*j?}rRLph&EfP3@Uu zvV|u-_75+tWDDXj{wXqP2LFKU&Yr)2+E(;#biRc9@ddDm^ayzHHF7~uPurxRskXmg zMV=)0=^@V!hK9DG)-Fgdo*|S3p6RzYRtDxg{kBv zR0dQ0;%1U>3F@o+9j@{&^*pLGUq$F&!2jeK+#{1f;RoAtgF-6cR9Snfh-SQRS1gn0 z8^G?rl6W|7L@D=+@2XLd#MNUmpCvukOB8V&muR1Q@vrWUPZwg+e^{h!H$w)q^)bzA zw!Q>3&SpQEe_*P?gbfu(UNFPpJks@pwgmi-oPZYLw~fR-wF-TotzG7xta3F2p5PRR>Cd?GV_(JqcR=FHVq} zfzp<}9&qn1(bz)l3ZH@hjGR89J{BMjc-81W?X@JM0|ds#HeBHawT)?<(1j(rN(Gq} zste#PD*`|Xq+nYpZ6)n!-8%KVcZJ+jg?bR%+g4foU2pTaSgDxK5P_m;aT*)+&4>Oo z4iwFtWlJRoGO2LH7Zp4@&d5Ugc{iVCN1@}g!=kQkbFjIURx3Nv`E8c_VBw)g$<%d< zm-JxYd=TBRqfvfswii*4u=2h|ZA(QuT#`%Ng;A8^} z&Xp{WI+1~jrGMR~ZnN2K%4U?{QYP;GMCe!<`AlUdJnSuNOP$S?#M@-8JoBiN{}Vz%*j7h+(X=$t={`=KH z><;MP>5uf8_L+4mZh}pO_?E|_vK)Y3tqzkW$Xs9%Y0vzF@Jt6?dg2n%ZDRFOsC+;` zQvju%WrI5LfpV-*@&x`j^LLx5+x(jVp~m_5QA?+x`N}*t_ishR#pi@CjHS*;}#Lhuj{+%F%fR zwBEf|!1Z7@^gw)TsyY_f+B0aRL=q^XWJ>$$9LT{(iZrF4+QcvRXZVan$?%_ss|6rj z&BC1=+FAEWeG3`Zdw`qTzUspIe=aO@>>6S}$8yDz( zOhseu9CBbPIP6!!Br!#EEZ_tn*akU@6xZ;pfmD8v<`1s&rR;LQG<%Y^$aZ%xe0+FKi^9)JM9Msw31 zo_S!EWzyr1hnAeZajtrUN~;CkI8``rFYdgbg-Lx-bCcM@i>{ZUN2f^erX-HtAUDf{ zNirZumr<)>{key^i0DcR+{DTF31rTp?TJX61pvSwlICxU1N#NOvPfx)I!|r#RRQy$ zp1B;**iLM#XaF6vKu*HzFe_{h=htse1K{6m8?oZjn4@B4Yv?bW1AQI{hZ6>*zOQvM zPK9>26#nL!412<{e&OJ^B5lRA*?-D`BgG}^`m>To*+IVPG30CCB)#_r7&rP>_iIn3)f3ElmJ& zU24X{P1kFK8LS6|7bX8WL-7L{YWVM3dF-5E8^)7Op$}la-(IIVvU;tm_i4{60ZewD zu2;jH4VB3k@v)P0AkDSC*z1KNd<*H=B@KD?$}OY!$L+&OF>Epp{Nw2K5`T{KU^LT# z?Wf?nUxm5ffzj+2%Ub}>W3lJ408V|M9h>|4x)(=xKVgfao^w>&AzzWqI*Ndv>Ip}m zN4+*C4URT7oFtAvZ$Ohapv}M2#Txy#F3{Z}{&1SD>SRkCDbq`Mehx3$K9yfFLdzy; zD(a$nHBYb7Q2R42>tf>mH~^?}yZ2;5X2%^+(l79|EPw5X%8$})RkO3u(&j)Y5LuaN z1*!$z%U$LAiCJ^d0pv;kWzTtr9faU2{d@C(qmqaGj-Q!`8dzHye*$o-EE4aV?2~+w zWZ=gp`!YeqPtv0mMJ$p5e|Scq26TYIx=;wBqgAZQ!yjrt#J|%!gIP>lvDhiMF0PoE z60+&=|2At_D3&^z`5A{S_xdcu4HhIT1KQ#8RWb1mzO}J}1R*Ef_an%anu>XV3BfhW zlBm0X9$Ouis*FSlB*LdL^H)bg<@Fh9mV_LCc)VdQ8hpvSsfnR*rE@hVKGEvUdGSxJ z8~26*t>OWH)&QP{e3PiL!qKrwbMHEJh@~8L!5bxRInk399CE>R$e{@I>Z zyM*d503<2HcJj&Ak8Dk%%{Fwo3(uH&G9&ZvV@+&*5GyNig^~ZVA?X4AZ&hHCtjq|p z%ilraOLxEj-;PUnB?A(jCK`rH%HlsegkSYkFc*@A@PG$01Ob;!96%6n`M$ybwCYm- zP@2-fPK$NXdkP$I4^?K7nWPN&3IyFMa9@rnu52D4vAa7UnLGU=^ZRpBHRRc8%_%Ny z)WX$>tHlISUKGmiL%NC_S7O|~L-7OR6t|>w4}rlwQbk0e*m3X4!X~eu4#y9-kw?Cm z8lPsH4bct1AjgahPSEzuz)e~Fv2NPa{Rg%U)}|137O|d#5Si zKL6r#^v+C&c5Z;g26YKQ)Jab7pH@2W=nMIMjUlVFUzMUBvAi(8H;jFbZ&Y{XlL|Qg zQ5{5PSUGGO+;87@KgE&KlHD^tX-GDk=E5V0nv03d71}3rh?fl*$HVsnC0cS^`-}pf z%Y8{gDPP&8bRroaFMrLy7*a0qZP?d(`nzWgx!N;LU05qu+@*zi3Vl1p?9tW~uqJme z@*hEx;weZSccJ~0b>eT@f+Tws2-6a} zhd&UrK1{D2I5-XIK(6N$5XiMDPFzQ&)rerimA~$pUaYd|eN>-zZ|Z`^K*}jSdzyYU z(msHa{)%A0HT_ z)du9|mcEk{TU);q_oecTqD@@fE5t?8$+)yHP*@D$S68aI*!?@`*U|ryU?#gfT>d49 z=bp?gZR_|C6x38~FX0L2n#X0WU8ph$)2@5nwibUv&RvwQu7Pbc*?XaDPuaU~s0&n? z$}cX`?ff`K4hdvRs*Kj zWe&NFa-iMu>!Fs{RvOPSVRRvun&>tf{cK~y)f#Vt70;)V z*&EF&mJ@CULQmz9=Q3fb${)Du-rvgkBD6kSs8K*-b5BiB4A)L z$tUgO<KMEEO{GhCf)YJ18mT)^V{^b$VYyV9QHMbF>T@`(c6 zufJ!!$EXF=3~*^#J<2&O>^oUY34U7xk#O(f)DWzqV)uURchrPm$H-P*aLFu3vu_6W zQ`q8wAtxKn#le>(@v&u=@!K8)0%aA^K?mKody|Y7k#H|Q!?U0GcOjT)xeM zg0rMZBqjq_tAKp{Z<2wjfU~Q!m6qnwVL1EBpT|%H&+cv)Rk8$N+w$EZ`xhAg%u^{0 zZ|CV&xO*dk%CAX|K#c01{r;W9m&EesRASh=;>}98;y-8=tNtx0^mBSf-8HF=!4~wE z`x+;sRJ%8lvAQL>e%5!KEs>@0Hohp^N8Np8VCk#cmc$B1-}d=gzZrlBwBVZQJTy+^ za%C$qD2h2mL*JB)%p|NSp9!IyC$4DcU`=^4^YLQw4L3QzD@Bzp{=FhN=gP@q^iLt^ z?x_{19rS!%|DJv*qGVcC^?$GC&&St+uCvDg!3n5)8P^w{mgv+*LX7sWK5n>ESuxe< zn8Ih=WLQUnzfjHgPQRTu^y3aI)lY#BfP3;Zk(8VM)TzpNLP!HVWhmYx&ey3j71KQ@ z3HpuYQW#)fmQC9)giZVJXq^sI#|=~oKj2KQ{TQ64wDjHHNbao^V>&~Fm}(0V@DfxQ z>!6y#?I+|C1s;os{r!gOU8U728!J!fjABS*PSSi;kuK6VqFSm_X&MnSS?%~Km6>!zJUMw0{&}_`L8wRzt))ly2JiIa)(`iZ8@^cUj@R- z0t8*e-YiL5v^?;oxY+Gf0c%a!U^}??}87ber@5E-i zh*fvc*6agdB1H0OP41E@RA3kP>#eyzLrU8DUv7MCGT!RIl9h!Y5bb=}A=}E=FKt<@ zQr5TojsS6yh!zW#@&8amZar;c8II|Lkh=fC{lj*pRl zMkVw<=>8S5xsyio@vr@*szOFi-DfamIk_#7$p-uC+W3k}XAVFzkJ!Hbeha{ln^f~n zS*)_|inBqub4JbHX7PtklTB$5kY?z^g}Wia{MTcw+*T^h_KtOt(@}}J=Kwz4xJsh^ z=U6@mJ}o~^vbJ*jeAct1(TUYkUK5x2znnG+xD z8lSQZdi|N7Pxh8*OZ-Uff2pe>z%1k5mmU{C02);yk6sTS*IOf?sgDNcdMGf+sg`1L zs8?!eUTRQrQwM!Z0bqeM>Yb80DSRHKGDXj2JW~8`*iK;bE!OK@DC10KKNTb-0Dc90 zW3tLCqt9fgp6EEx2@I@IjbV}a?qn|mR#gkzTlx->;A)>dspqKe1*S!Pd{d?~ncg3` zo&H$~fL{YC5DAaMhCi+dinb<1oae%oTi;%;WI89Iq_S4{O&9w>vl52|A9582KICKp zK7w~>){2pVN(+O?+x$$$cNYHFlKO)NkiT99kq<$(Mz?!Xl9*6s679JM5OFt!u}aLn z3{mHw##+Njn<-usrRs8E0>g@u%p$=qn(Yi+lL28_R*?)dp#=in3Xx~CVR%Rl# zT4;Ag1aG7c2h?=cgx|EBMJHD`$WC`WIVk=9A!!D3lwq4|XGyZvwn$kC_k-e-0P~KT ztNPNbxO0@`jV5MMm-x-)D=&Tb>+^uWa1!-U3NnkY^{RGWCQJhwV>v?awxGHC-b!zZ zQ{Y`Y?GZD<>~J? zW`(TVvH*hbw|IH+Un)HOa)ZL83}Q0>v^6D!q=T;+klZa0k8|9w!Hw+ zXb-^S>VX+KYAz#ww%wF!9NUimt;rU!gwXOAs>{WxoT;~;Mn&d*q=}Tc_~zErXb)^( zAZVLHna%LWipRuASPn?!rFMSJyK^bh@{Hnz+fRcf{V;fx1Zr$;MCxey!!OY8yeBpW zg_%Xe9Z=A*s@2T(l#-5?EHNbEX^Oc6&v-Zf27}=Ixv#O!#Ykw?A`du#|B98YE9)aH z8TLr2Ro`L=c_ibE39`XD>OHhCe;VS830TNp;;bN}8b?ZPPzH{>SA_*s(DBAC$VE7K zxsg#wOXTljZrWj+1IBq>?G5HnJtlBP-vl)qp@cVjcI8dmFKI8Vv9!hQTeV8A#!=XJ z9=FN*BXwyA%Mke7-^c1)yD#zyun48WSy#;2=;Z1%RM&&goWFPGEX^C$GxM$m9Spli z{2IWDMWvLq7X<<~`cFM?26yw+9_pJk*rb>hP84duT>gFsp`|@OcO!=26xD(fh9Iufg-229grz zt#2xB{xo5igUZPnhaatWWgQ^DNv2*&8~8b%6_^QGul*s03F<-%oyRdE7jmn-nq*lL-l_s@7uP#+w%n#;tcu1~R?MWxEKftXMi{MWP#^+_}hSOKXM zzkE?+!^66U{=*!lEZ?o@`hc|2YtkDv32KEy5aR4DP=-=Syvo%NV_y<90vgKI#%W2^ zoMaY{j$BOz>v9`loK4{L7dPzv&h%E7s%*m*b=0}{x`m{3B zz1c=xu6hFm+6iVHYSqQQmqlsj(M225A30i9E1vzS^65ueEtvN&60|7Pblya;Q(#B}GUU&_?ATdoi8B=nYtiStMpMx@0S zAwR^*JpJ8|-xLxoy_)fO3PYXz%T)HsC7QCII=?Wk2-1KIdGU_e+u_9ycE*8x7-k#3 zwJD1B$^XIafv;0~8Ppe(i}QbiGLf2eUCi=7sBOKF+5Y$Ch*DtCZEmd-X0zAPjEfcR zi)f3K{MOsCCamh%)QM!ncbDoHyr&zs>S{y$yb&XH+$5LMi)OAZZ&A!POirQ)6Awm| z%GYd9st@@zbh6*B8@(o}1??V=n-mR6oIXxTJBR1|7~2&HD2@#-lz?=QZ0G=X)e7qHty|Cm!ZuG<1j?Xdu7KN7Tf3y&i;}? z7IoShEjh|e=|WT^<+#2&<3*f%(({;aWl)5~4gO@w3H=P$W$Mjl<@|o(Jwgl|yZ@k- zxuVbT$Ja{?7q_MnmdZvm&sjhUwk(lK*9{lXXFX9~-Dl`GEd;ekbg?ffe=oXHNDWM^ ze5Mq^o3L^d2V(sYgTZhTC$r?*7C#9z;-#QDtYPlx8f0#xImlT>N2F7 zp>XAVdyL>zNj4`D)pGMWLV8=IACCzZ(qtVAPO;FYtRzoky|K-5D6r1=y|Ar`Xk>rD z$jxsF2Wz%jAoieRw{t}>)gi~I{-%c9*AWlPhh2f4gJBV0E*@d3AsUm^|B882+#wq- zO{l=*-2-X^IpX()KrWBau)FM!jDCN)$i}p_ENI8F#A)RrcV_?FIb1J4k^hZr)U+wn z9lw2N5NGEdzrGusLYf`#-r5w4Zx^={$!oB;?t}M*Xuwge_GilyyBB_PWw~2zZ0v?b zHZ9&%gXLe7E4K7sCY7)^OmD;LbD#=CPIPjMtuOD_H?0`JP|ED!sb)N$IV>`Z4`Z{! zIx`^UloC++zHn+|wDFB#%ij7%REzS%Uy=toBo7;HokbD!m89BlCDnd|vLqqhZBadm zD@oBy*X{bxKQgHkmdUO%^R5ELM=1YTzci`*pa{TTh6~%!6|+>xS`J638IE>bOSVf0)iRyP z`Em=1&1*MYMTN9pEbG3ge#Vl&-@^x|)c zs=Y;CUNgBq*W{crG^Tv)9>|_cO>>pmm^`-|<{m1+{jYonJdld`Gruql-Xb{Ko$qhWanEJ9Q z{L7STW--TYz+6A$hn z!3P;QXnzPXnM)gL0i!i2}*|j;d zM(ZKB#FV0-S;dxqw4Q&aWJ(sitg^YgA0pD5ZG27*R0l$qvQEPrJrLeVY0A5Jlzr#z zWL!&%!vp164-7ZEwzz3NQK8I8O7DK~agd9xk@3+h8+-d6_s@Gz!{klw@4%E+5t#dj zz1PXhi2d5@TuHoPdGm4-%ahhZ7rG4nD=J+&lk{tX;*jWz3|q2_jdGTVz%86>yY;lY z?d3~g5li#u7lr>Q6@IBOtB7gT9~Xgi1V&oly@I_~vyXd~3I0gBhVjLoQ_((PojO(zsmyG_Eo;oydcCt0q|3t2luUKq>3`jh1h zpAf7+wi#>AN_qbmyfqFosCULz#5;>r7ZY9f94&%SUbNI-`PJvKI1Cb$65S+PlCVAn z_uO98uc!2wi*1F{W#XxeIC$^+4q3__r-LU`PKvAqTy?g}U_DGlwL}K6-6?B1EnJYLO;cnXHhyPO@*Qip_ zfK4Wxox6WoDDh1V>PQ!AB&|qc8!;L++^^cmAC^mG72Y2=6&Hd}Hhf!lXPNGkgAP%q zptb^oN8EIELooESmm304x-#>w_hpg7V*fk{`QRkjOf2;uy^lXXB7+9+$jT1e8Zs1G zW%;*7`yPeuJdH3-;w#RMkovNqxq9Fo@LAr2V`u$XY^Hc9ma|jh=+BGh9T~na`6{mt zKI}zwiN1>P#**k7#V~1eVk!Br3AP1Lov!uvWF2Ex$&Az-@3-j?W6JofZ=0qhdA0A= z@3+l`z_U-@2=s+WEL|>u@I54=$f~;{F2oJ;>)wo4`!(}ikM1vgAYLp_a102PTt@-p z+i#>q6{OJ;o;s(Uf8PgL0w*Y}txV<6N90%+d_t^uz*a)SiFFwVoAXD^!mY^ti~q(K zuX#dJx}xhh&wH)i6{~8yfAc|)WQ|21H_iCKtcj$}~_v7SJuEFK9r$DST6HU#IWMtQ}$+b#mv(v-reXN@C|Sn&Y0`oTES!o zRhi73XKqU`h0F)2a}18rG+9m-vDNdvdG-l$f(_#DQ0Y_!7SUP2dMlem@5<+$eG<+p z{P1pTUZ5Oc83TzAr`#&9CFMUm;eSj5EpND2W2+X#TjQwcS zaaQ&rIq(mV&lgj)q(`mxWzUg6*^q&Bu6`p@TZ~#@myI%;_cxO+YPC03r_c2;Ac?n{nk;L*b#L z-|P+J07ge1V*g0}>!`YDY6H7(Vd_Jz^_V(bUP~v0{XZBsME?~4VXweTDzuNwOmcpY zT2O-C{-u%nr6XPmA25#Ij$sk4=4blKlp{yn$v5#rUDITZTzW~P^X7iEvECws$S|td z6a{gKWJwT>_MuFlFcLa%R*}eGb(x&c5%J&1CtO#-J>JPFI0<4ZvSNp-t~uZ)xEjXT}tnNTs*zYs6pOxDL@ZU* z7brC{ee&-@<2aSXJvx4TZ z4VYa@h8ZO`@WJu04D>;o5UJEt(f$(W0DLZ9apLjwQT#^5$lQ}%Txq7#E0(wK_IIR` za74+tpt7JE%=1ghReTI^?^@@FebCW8b6Y+ZZQ)l+Vd^G)Y_B{tT}@W^_XT6Tv?k7+ zPoplrCbRs7I-@kYtWVSerTm1s202Ts0~gbiV7?Vecbz*yJ{MNl5fy1yQSP}{;=MN9 z&Ex0WnA~Mh@hlKOX&dydU3!0aowcY>ZA;&n#}^sqzA6n2tM(jbOa5RDclHZI1r2)Y ze|J6623(0AVzvV*-s&s*RUX_KZ>EZx6HgjNyH1@L(eCZKfI*b!q|LlA=QiiDlB4Ue7>4kxJ8UZL7e!ZbuCbQG;-?-*GMGi^4cC9Gcg`nxZ)D;ca7AM_e}?XjJb5iz z2@2ce!gU|e`PElgj~8DRTqg(?WnGVHzx6+%u}=A4p>d@`@3?F_=f)04XYV%r=x3a( z*P24D=Iz-ObGDVNpk-e{>A@; zh9B-`W*`yARn7#b;Z(Zmf}%CM)X2V)m+g#?@Q-cW6Yanf4;EhbF+BRP;aVb__}OvK zUpKz}k3cTb17xFS1)|*HlzX zdAo35$b!t;Cs^4YF_Y_>rqTJ*Om+!aIyLdvrgCJG9QV{q~kNH?2rZ#9-22+Zu^>#fl@Nj z*QTH51r5#049r3BWzx$PZ`lpeSl-JbVaE;kC&mSp1If~DTt z4+#!^g7`V>C6jGT(p~M@nH7yn%mPmIG|7)9*_IznyJT39 z+~*Br(|2BzB_@rNpOIJF>8_QjpE+=}ZVfXUSo{RgepFO$W*#HaelWE6WVZ})m0s4^ z-Usoiy&H3nU2CeIY0NQw+@NA~Bv$t5&0proSfDMD>0!(6OBv!{iu4Lm(eSP-BN8MA z9(}IAZ0QG*b;eqt`d>^P{19-2xy5eF=4Xs`I)@5ru`XZSLpz2_x71rvt3_c-cl9<5 zlRnU_T+_YK-!M&FfYsYiJM8y26{{HKTN|a(ENt-UXREQpA;{9QOhT;MO?D$h3moR` z@2WRY8C}QYnYkCPA}`!~{wq70zgJeNMy0^=#3u*7KYKA? z@<93)J$YTKG6-SYr**7FnC&WTk-YR8#h!K~)D@aH${>xVe#JmP@VkrOwq-)-^#J*8 z#&KX>?|@W8lE#zc;{+?y2iY+fwkJBPBsMKE;}fIE+&|yfFzr7yR*|NY&zcu~>+R1N zt;)&lHsllKqd&wv(F5n@MTZj-$+KZwksAAB%~7mU<&O^o!nUdk*D0A#?5iva?ADpo zQ*2N{t_xN?AEEa_;g*`aFac4Yw{yYGOp0a$1k)9gKxu$mrUr7+=z->u(NiuHU>hCi z&0P*X+mW2_?&a|FT8@Quf8K-9!_Z3T6&abcSfxc(TC)5%(IAMfPzE3jH}4&&#)GS27j;j66JFoGSBi`mas6F*=P@E z#jLXGsvZ+iGmT`k+YoU-+!`zQ^B%drHAczw&sV3qoJXtu6MoD;><^dc9B3RGiy-Wk zEdY&7y~%k}W6-bD0rvCm5(LMLrty-H z`AA^_-EioX(ORE@L%0kf0DZ5!<&mBG6-nZN5}CUcLpi~E(C?0adHX_0DHh+1IQk8H z^?|n+>-Z)RY~pwm;gx@-$UB%eF=~F!-DsJLpI!|T;?Ax@hn>RuA2om{y8s5~Uk>rAK$gG9I z9?(f~J68AET-hhq@=_K-MGXYy=(^4GSDryR_%}Ms_OGun~NptGS zoHHo6;$KS{TR&Iw+U5xJ@tO2tY@uHdY8fjA2 zEs~hAf<6M1H)b9_Nm&0D_UY>bXk#07#@GcJo!>(WX%fRWSF?ej((V?ip(bMyc7($1 z;4@tI%L1Ec6>*WXS#{DF6IM0E^kufg$_SgNwDlKVCdqUsz;LGQjV6pz5=UkAS~ZoG z&83uD&BDXWq6IXq1$-^81yz@p?Wa3JA650-S~vT9cqEl@lU;4B&bW|f#o-)7q^7x@ zT=I+mh@XR^H1_}}Gp@1rGI&W`V*Gx?C%Yy$<6;6^KtsrN{rv0xo|r+9`=5xTdl4#PGM_+Qx8**ooulpVAk0mh3<*{R=i6jw&=?I3eC%$!odJQW zKFAX`Nr?e~eMHgk&a7lj(={>K8WQT;|HafF)0CWQL`mJZI*d;xL5ZF;xwrF(J zEk%|hPM8kjE|10?k=eZTmtso>(v9`FO$+8Q^9{A@&&s%@^J_G*CC4%F3J9;Y^R2q+ zEiv$>=Tts5nFvCpp2+`HRgx>UcmBy^TI+aZRA~$|?8=Q&nr=?I(xc^A2j9E2f`~)2 zw<)oy(;B&v=4Y@%A1@c{`0J`3F7MakSg`}RJ|it2keDWt3_(}fsjTUXAc zREcyyTt-m1Id^b%x~mGVKg!-kJd9i~T zWF2UMfevVq(Nd#R!t8wUEaUSp&Do`Ot3S6r;2qr8}`%^cG&A4v_elUHavC zN9X-UIi3<#o}Lb{QKcO7z4=orcmUDqdnLIO%i`3;&`_AOHn)1AyA{!7*>QjyAtVA{ z$ah{PzDDzm-0o1d6V#j{SpP# zSien22C~S{?-zYuQ9h+Da;g`dW6Wlx-mWu#e{K+HKe{4BK!^BCB(I|qPH?bDYI43h z=Q@*eHyBg5-QMXjGIA-FcKb_z22n}Dn|sKV67->PAjy9}yCqT*N2^`3V~vmH#+d!u zkx*Phbd|kXP`*C@rk%>C>ZhF0kx;6M!cmlP$F7_}2yNWUSi@gf`KO7gUXArnSg z20Af2gfD0ATKTDIgPtR}8;-S~vJ;|zAVxbMv!-DF<(*QiXJ}n>)?)_o=bX-Kb`ebhMmbZ>#R!Gs4>3bz~)_WEi| z6XL%MQiFtd1V=@XHN|yb`V>yjn05)sA5@_?D+}L!g&E)(!kZ|cyNb{$xr1q<9OWST zWImu*_Uc%5FI?s4&)JA;^t2SN5TE_y`k`=vwB?r8xafJ2EHl-tHBcGSh6l{$uDV2M z>xhK*J^kuaoQ3a;)&c@LeF`dsk{2iXP~i)*!n z8EhARL<`EuG!oxRJy5f~!H)w``i_2A8KdwfY!~TZn4%KqgyMa3*>-g6T*O%_^MrZm z--YW%=&l2%RfE@T<-!luY{k3N4~oAG1{rts2PPX;QI~NP*U2HqT1OM}p0zg_3c55? z{gnY{lp{_}t5HtmZG9uOT`8;YgMwE-*$P6xh~Wl4rbPa+l|SQ&UqQP%P#<+R)YAjd z(iZn8C0gLk&HI253Y03jik`wwZhX)01x#NhOH0LJ=2)HVUB=_xgp$lU!ma956p_7V z>P4YhFWVaz%is4G_B_`%@Nb7{Sl+}13JEQ3+x5x`kkpW4R_K)`Hs*%WGo3491u^(%@P-(pPR|23D)vCf#9gCMo@2koN?=m`suR z+ZkS7cN5b(va1phNlkdINKO~Zth7VeINl~jjs(nV+b<;z85(mL+T!>jBWo3FMykIp zSHEkxGF4nLg}a47qErHYZ)nqfvGX)w!d%ie4m^kx^8UN*G#SHpdUk88|BTUfWXTU| zxQwCm^&8dDMFU|e=|J%N?<@o|LYvd`O{2@cyb*$VGU9x?^_lF==8AhdVwc6;q$cV& z>KNhY1|`en(0Uv(H$I)7K9l$2uSB)g=&%v&p})Flai71U4!aAEH2n~g%r8-iYR=eY z<=`rPJt5Cxd+=*=b-HEqYzA8Uv1O;TIb1ghsEjMyL&px)Z1bOJJGze3MSj2Lm7Nza z*P}7O{Z0M|v)q$Fg*Waw8+rQ2cui{uvPg!*?LYXID1v}V@%Hy0LR80a&)&j<5sIU- zr!(M;(e+H{j*IN!HJCTlkI9%e)4>!El8o6zTGs2yxcWC6z6gGiW;|1CWJ}p}Yhjnz z!DE`orpMu`Ra4t9%8qp}0OVe{_)?ws0`=>86)hK(plJGY8!xs@F@xkVe(Yu73ou4O zP|u%D!u9gzb$+<6=c2WE&K#2Ro*;b{?yzgOzu(I`OSHZgf35QU2}zBt!c`{hzVF#@ zNRIa28YmJ~+=lXF%H4E`-CMzuFX}SoMEZVNhAerL7YeJ$qc<^;Rb2LeTgBcd2NKfw7_?vMLG;^> zX8PNC?-eNo&hvM;ep0r5KwJ{{)<#osgNd-3wPtnq@y+nso_)qgLXCd+Q{KjBp@g_$ z?&E3=1Lodc{u`y9_1&{8;|Dh&-uNff=Uy*K?2<|LBSiTjAm%oHH*?}lOP2RbnrZH} z+%CIrKfQI}1>Ta!UN%;UC4LWMZADIg*>s#mo^|9G&G6@V@4K(fL``)+={<*J)`l=1 zOQDAm)cz{D1zeg*Yn}6hJ?9hTB+W)-R2&ZxUk`f~1(C8(R+i)kEyD93dpWV1Z!%Gs zFbf4o$zD$hj~`wm05#8jSh=F}+o`{UWBT#>P}NkF2y!wRQvldj>}awkV2c04$9Lcn z(lQ~*$rzSOoYEzP^QCZq3Vey!`efkdZoFj*%m`DB;5K$}F)?WL7QN3N`t%U)n3)%Y zH&RgYh0oAsC;9$5VeHbwx2o@AyV^15s3Mlbe3O~ttRCyv`ppY2X=o5xM|=J z>R8vHA8>8FclxhAz_sUq(8+eZ!}sKk<_A{_h3;WZ%H0sxD=#-H-Wo10-BLiEp+bbc z%0v|>0V8w#4UzmVL+{$#>qjxRB-tqt4>{tZ5ALMsv)dO&M`BZ}4ez$C|oj zQnv+;`z{HWB&{l44^VEK;gQh?m4A^tLQ)Xo6gAKYXk~8;vdQE~x$)F`8L0j|MPMng zR*>DlvPXw#CGgJf@4Osd`XdQ5!_ zacwY>fF{5w-`f(7dyO4>?V4&nrkjeq5Jt}A@)>e&pFPLW1p`-vkjQr}@`EV1^2Tgt zrVYEr%Cpx**ZIYM{p8aw$KvtBy3-OEJv;Hxs@f=_>kxC&D?uqEb5%C$;ZyC@OM;$M zGV2GG@T$DsWOHDIQM?l|5hzdmtB8!#COHo4YIQ4WXdU5aG?-~2vUT0Ak*1FST-V4@ z?=Xm%ET6n)h3Lhv5QbKK+cCtQIAEOA&_l0hAJQ#WU=9~&K-vMSrfD00+ad454~3%x z$UD}eUI^HL+Y`I{A<5HMr8Kxn?0h;4%48|lismOWZ&#{%0-|tP)$9Aj(rx6w^v+Rd zOnVOS>Np#Mw%;TA%M2HJ$D)E+kgR5e*yE~N^|0|n7}Q*<%~b!cMRe(QRb2@_zdrBw zVa)F9p8?qvMpm!h$6a|x4f=e(9-P%_cdu^mbU$>)mm>uVMz5TxaoGsmy)6)BuddTdCIhQ zP~-3(|I!Gw<|ymWyr;AC70WcU@VHIZAfN$d8snmOZqy+5SUax;UgZBb`e&$RnYv1D z{SH~Gj>Q)HU#1s!QGt9@bS0v79HT$K33KhNZNC~n8M;_Y{e(Kv&vq#gu(f`&)8n6~ z+XcH4p8g4a!xcCYy{Vn>o5J_%EgJ7jLLjsC>TnZ!==9C8be5QS+qTLWS%hc}cV@cu zkUTauCk5eG0QbH9&2bo7Q+3sQ0upF9e4Hjk(V*!R0mmy0CFGpJ8XyC3OI~u>_EOB3 z(Y?X5v3#%Mhx6NgaFHXy>{4wAWQ8oW(3RH^tK)iYzKCQYY2$yx0H*(h0fvF80CQ7e zI*k^@{qWHsrWmW_1$@DrPi&WEkN>RWy3f$%gh;kNB;UaTws4_}w;W)d*M_)P{p}QG zS5{14K&JA~FyQmLy4-6k!+1$5r8*Y5HhA}bb71dHq|s!|%Yu4sJ4Ai&yExyufjwlF z3iA}%km7-#oH0(q6FNT>V+9J_e8x%Bjpykn>mwml62*0VbC2nYt*k)RtL+IqwgjSA zT%_q&fy`72)%EW<4k=luFvu@0fmt9$Sr+W=OK{JaAuUiiMbb6*Mv~yZ(ukz+XERPF!J_jn)|}u&OfaIXr#W?-mM)+5~3yEH}R7kv;a* z@UUuhgCbHg{}y$5s)>AjLSrMW4$I*7PB2;`o zjcsP9;^r^x-qrQgNlWlo1GAe9gF0hB8*}pCMA{Gyv{Hp}W(^3AmQyyr!zdw=;(L>I z9zGqqv!Z(q{JUazuC$(KTYA11sW+X*wkt|xSS2%5vp+8yB^)cYSwgRXpv1L&QkpEe zLua9$29xAPB7^x?!JbJ-rfVDPzP62?J#FYn_o<{bC2@ZlVK{|D2lkK?K2$O_MuC%< z+?4zwl&YY&U#+Lqd>>wv)QhlzmY?QrLoM{7 z5LZTcvjRCwhRv2zSu5Kx1zV7Q^s^RB|ORP5|$I-^Ss=Dn0z&U9hCHH}VHx@ALPrb&Sjl02#2Q7q zGY6S5v;g{b$G>~a4IEVMUt)W^Tscr=4smu(Nx6c*mA}e_FVTV%mhav&wm+LDouY#s z?9UrFk6Mj7d6YyImha~$>)ax0i=i)b7k3ly+Ag30&d8rFTmxn2Xcf-DDOp~Qwg-%0) z-v1Y^|Gy=o0$3uHf#BX?(Hs52P0Jk(LAi^Lg;Mh8%LUOaEPgIpz4_k)uU61N(+zw) zFEy*Ad_d7NwV?$I2|8~NrY2-prJOicjuOpt+(+A0ww?@;@|16<+S!Dmw-sf18w5}F zZ}6I}#+nQ8C5>OX4Os)D^cEVTp~8THmS8bL*)><%?4rJ*XQYI*fubNU2!0 z9^RSr^qX$XvAnql)3QY)ttPH$uDMFv)hz1h+AEfG`F|v9&Q5PgDdJ+F%PE_>)t`a9n%_}kdg(r&hPW#1U>s9 zCxs+jJGv@z(>epW+&^!W`U4mwFYo6CE$bYnW6ANsvdeo({HtM^PM|u`vgiz$Ps8+L zVdlBVr%j2%WRDrVq?=(I0S+O8x5 zXPK@<+x9vnGI41ME|T_wDjLCM=aZfL;)I*HsSNgE9*t&OF*8IuO88n;3KG<)sj(yC z$X>J?Y0AC`ez-!Qj^9o8Pi++n2IicK-43iBCeIqdd$qq2qu4X_4_3S;6x8DJOuN!a z-hT+2es@T55fNun=Gy{f-i1)+e1?#ALPROa^*i)M?8$ebC@0sYCvD04eAkO#Ea~mP zJxk=2q|;71H36?%Q?6W}Q*foC|I(7J*${!20 zeXSCa(9y7wqT844v%r9YmJ$-2eD*@))Q}P0UU5cp_CIUM&m-P!a`s$qAHz+m*3UO&mCYeiB{mZcHqai=CO}?o5Tny?a}4v>7H#kXBiR*HO#HFm zx%)p0Z0}zSY&He3zgKz1LV zExvF(!Bi%8`uoTY(c@9h{V z@bk2|z2LTs`QHaXeK7{Uh_akvu}9U)9k^U!nDSQf>56&XJ6!2h#v&Ke??05%OkCxp z8XoRb3l^}+drUL!ih%n^?}EXsPSUTqJ?OA&|CD5^Ve$`1@|CK@Nd0)FJb`T{_(K1C z(x0ev*2!O%*Rtnde;hOl9W{&$GX$LcYDZjm&hI#$`~0b6Yvvej|EpbaC$e+EBoO!s zc2)P0mcS7=FU0Y=gLsQV9*iJXgb~mEwg@Yhm0C|l<5wV$SPJuzr|8vK{vi(m%@DWu z9WFr!{dAc^p3$}2D&Z+WCuL%l!zQY<3yb>qn_9jxKodjQ@o^s$xB*-R*2cy&Y^cl51&%NRRvX__L-`#=~HT& zS+kUbXp$;eKQ^4xHHkgWk7I2p`G8`OF1^GAapUdKe2<>60=qO3Z)z1q7O zZtH;|!s0ib>=rQzcD8*ga#;h5m1qPOlBlst2Vc$$|7{RElLV|CM|geN&-V*V>Aff_ z&i>Jsy-)W2=W+0(O&i)|I_^blwrJiYx?-MRvJ7uc;e&nZXAnvaQ5k$ulXJ1p_U%-=qBh{NL!d2U;DPa$?Rdwgj z7`zN_TJo%7i@iDe!ml3`N=>E+sT*Qx${X6fJ=^qO8)@6FwP@1G0yEdA11-%HhGwG2 zlmTJ~Nd)^X#th3pI{jKk#c5y#ZZIgL3UqL_1m|skfTaD>dCy^I8TvnCrmV7V9=;88JeK7s`{A5R?3menNF12D##y?2eO@<; zfX#XP%m{bEm>HRa|D^)OA7euZ?0Sopqqk^>Ta%4R(ZWmOs^PLV9&$Awn9JVDD814A zo?N??A6JNo|KqCbwd5mR#LeIN&#qD>wIn-rb8_B#ZXkE@F1#eGPO$H47A7|`4FqT$ zma10Kv&$Bx6!sk^0(!I1^w`uthP$bm%s3wS^~b2O1Jvn|scP^*hbtq{O36&sbB~~f z5@p6m0M*`md1nLh=a4_9Z=%6Fl&n&5p2NwX$-t>bK92ade$u{;LY{iVORjK#+4wk- zQ}!kxf|)Ry{D)rca(Z?t>!Ykfk$&a6&W1y#ws->Z{ce`qUlDx@JVWeNJUW~P^lfbc zNxqcc?4E%4ec*=&wm|vi+p_C-?&G|)v7!w-m?%*J<0&X$=>vF(u6?R+J#3%?8qxPF|kIKEf(x33+h34oSxuX>UHw$slGY{<18xln6j*qei`y8A~yLSZ9C>^?x7>XxO+>Dy*v z6Sn%!J&veDa1`@imctf#<5@7)gyqDY8gC=6XRVGQOS|(`)&_{F$SDuKz_otK<)>TW zimn_mM|PAaPiR7poTzL>=pNuzTQqp#ntW>H3`3R8yEoKa-FV?-+sNdWj@rMuRDOd> z7U7M9ga{8*o#P)B%n@qU&C1;W+T&$7^PW!uku*fD zyd=b`pH_8#jfv=;yy6p%H6wG*zy1k>p5NQWSzrmvf}0XXbw@qtAjGiV(me-a2ZcMu z-txtcP`w7nRYVTWt^a**jZ%Dhux#{L!yah>Wf*F9r3td*c{@(nG2b^6%>Qya3cv(W z$Vd6pM6=>7NF$pi%D$&%8*)mvXOJAK+M)}!O_y5fFe{J8hA#19{`0~Xx}9&yG3J|Y#DrvVpMe4)}^zHU7&jX&kL>H?6QMZYd-m_vTbb= zV?j>5h!S<(qa^`jzZK=+W4j30kTE?v!Lu z-JBKy1~+g_G`%-wFRXVYzJ=?#zVOqAJI$sHK;~K3le@NBmFai{HS*PHg`~M=m%Z&1 zto$el=p9~R5O!HjXNm3W+mRwNrwZpA;aUY=w$-Aeo=OQaWuh6`d7rVFRg9BuROU5% z-g|Y`NVksgvNsqYHb@AXZs9Gm^{sf_VXev9PO~;}{`^F>!0?faLPqO+q?#v4mj7%S z-3;_y?zBDMJPpk~L4V@IZ>~c(%2Kv%6WWD5l`KUu3%75gYAKkBRvaK z$Uv(C=D0~$mzA?($BZ5bLEQTq^I`U1b*C5cl5XS95M>zI1UTLW3`AkAe+|aRsVtj>9wU9<@I0_>9&w6=z}%5*}WLxN%a`%V8Q8ahVKvluMyhknUax-VxQmt$0I zv}LDL?TNutqZ(&^mgFBU&e;dHz9BQq%%JWS@STBy8wTX=u#FnC4V!-o6^{YQi=|@D z-4G}PnD*p--E6>!tF@oH-w=vLxxnQ6M73f8&@h0^R<^n7IUB&S{J1Ls%?2PYK?lrT zKGi7C16&^N;Lp3H!Iq3niAuFkx&BuMmHn5Aa+dEhUdnKPaFxYBaEn{=;=r@3`Xj^( z-}5=_lCM$_)QoFH-P2PI=5eRfr?)O8Gs^93u&0Q=X}fC-IBSk)>RbXpXpr<$@9DT= zHpCu4+XQA*%dw3jp8zl4{LL@&fSTNu8x9fQ$NC<4g3Z*>bf;ql9JV>q`f;aV>-#O)9tq6NRs)~ML`HHu& zG6$FykIz5Yc?lwA4E8b>e(22&|#+1nu(+nXU6B9?v{(@yCz&57tp*v+WZTkQePZvK%(|R*or>wjjUE^)BMb09zr6feX5oLXz=^uSqY=w)rA$eQbeM1rczDQsDbakFYOQ41 zvlXjr*3)u6kMLdz%rW^J!kWmo{}r#B)BkhSy^sFgU+jVwz*KLIfHeG6N?u9S1!n}F zc=5q*(>X76w+#-ob>{;sFGs&n1h{M&dZ#1C^PUV{zMg|Q*1C>Lh3ijkIct2sLFpZQ zs6~l+b*E#9+FhVX=D%>97-f~u>=CQ>$VitiJwWcgf+WQ%5u$`c^#Z1=79ils$*Un7 z$RMNBm27`<>krhuwN}Z306vVPfO0nT;NY3StLrV}MP$`qU*99|ecT#itt;1eUTV10 zssXQlzeBs0>Co+GtY?nxFmyPc-FU~M|7Qz~=vw4 z5FZ%OM%!B$l~Q@x>|jYC9?O3nVwP!LIiwDc#nCx9Bck|lhFR;;5t$xLL;wY1l`yFL zeLyZEpc5&uRSh{*BAqdv*tgRD#IRg5n`JL!wNZg%#reO95woXyQwg^4zn5q3@D4V6 zckB2$80Wv~Ku8JXbDyMbwl-G)dP34$H;o*xL5xGt=D9*IL+F8HP~~) z1sHJtjGNW>*z#z^R9EzaJ9sIZZWpZCUAw62F|6&K6Mm@i;KN9=Y&X&#DKuAw;Oi7| z%GiL4qlRTgc|B=Q_5$5(PS1>o;;G1P4A`aat;n>{%lshs$ z?bJ);ud(71tEUX8q5yw;fvxqa@)dZ>GpT<=>gx5RNe9{Eq?j5n*`@@7rHY+O;*R;B zq^iwXq9!wlhk>UxfV)Jcx#*#AT>fpry9C0h0emppinIQ0VMCU^)>QIX*iPN#W#wor zl!V!DQJ^$t6-Hng*3yHj6n5SmMe1EGS;&-Rr;e;QEviX)16(~+kF$V10g%FKj&+fB zU;wo}DKJg^5L_SxygmHI%dk^_rc}GQsHzCZ>s*{{2)1XFP8v+niMhKT{0+!d|9;T#lQrt(~_%FpJX;&hw z+QQ&1!L`mQIe4j!yRN}TxFFD@f}f&`w9~Ah3xHGpy&{+EFCmOfzA=9GB)aQuRUP*W z&UFtR$O#}#^%SnMedb`mP2IRL-WZBkrqdC``UEHmpXdll(eDqMh)a&X$an25+0uGr z#={OdPnLveyAnNN0DC|7?fq}Bldq_|vWo?vUfrVXeGTVXA%%_;iTe}phvtztI396L z<9`2Wn`U@0VJ24ix;Ol*jO|o?N5dyevz#3KR-@8%bmD~5$&4Q zOejV1wk`#nn#8B?d+4fq|5-5rA64Q#`l>y1lXI??W2RXbjNkps&CT={xRE=0(h(OE zFK{yH>c15KWBxs837aikZau4D{zx|;ccm^b*Nc#$P35#P-?UBWgS^x|;ia=R^B z%g1+l;z#@O#E=sx`epf``{Mh&zAKcOAOf|zzI=-5f!iwgK*d~DdPz%R#;T0-ik&C~ z_`%z&Qwqk?1Up#v4J?JQ#&Ar%u%vK3sYh~r|rm2wf%MBCrxfwEOhjv$~ghQwgUYu4X~3c(ybw4-=f5h z&yih493fjCSS2}#6<@*2anc`f`G<{ph>4Pc`c~6tW3g55$PGdA8c3m_o^9aL_X`x! zWA6S<{QMEA>@5Q8Ts3xejcFoG@I&{}gBx*>b%?0>L&uY|QhF)$$4o!+~5yD#!c83Na;K6|_bEd9|AYv3H(S*4G z_S{87xbU|ZyHl+a!TPIrwVP$_N`?r5KnT69JW`Faj&jvCLwAL|HN@_bIXAfA5iAhMWrow)z*$OIOpFa`unmWEfTF##?K#!KX6}VtF9|t?*+q@b%}X* z=a;~(TC?dRUd6D`?ig)>bbL)*EVDL%p~#{dVLCH*V2kq|7BPeU{)<=~4*-MeU^{dF zK;RF81f%{sY&q(826rE9pI)~C-3>Y3yRVLX2Qf(r&VUlADN~QEpNPHXn2JEK%o9PN z3n?qlrvGxd2_`66iZAx!;&8=?beG|ICKfng)hQ_gY*-MBUM0L0bvYtk!E<ef$~etXmTJ!Yd+D(m5|w+P}+eL32L?6m60ZCuu<2w1L@qdJ$xTYI(AC2zRS z)83KR=hBF3J(vs#mb$&YB|>@eA7#n?Gz4NxHGJ!?4`5neJ^9P$y6@a)4U1ScM@ftW z(!b743&ymHZ2VXwSczqPz{f5NV%?i)Nz?}&G#K<_A1skUwXs+w_pwr9Bl5-z+=vIc zIn~G&tx{9Q(x<-j5TaCM+zbP?)#H-zUaF?q5M_LKOerApbw<;)fhErPGb-bx`KHI zKa}dne4}uRMH5Ml6FsSaZNH;uj#vKil3cKSRjUb<t^6^bZGzR>WNXmMo;ZbDcTmOeD51*VAoo z4Jm1-Oy0H3$6TY?hLvrJ*t51XQ4*>ZoD9O6K)Cj$5>L&CJMy64eupSB=#+i^z)1YB3uvBRb9B-S^-=_5?Z1ZTp%^fgxx#q0-`vyw&gj${+kZ~64u?vBTMY?~z5c|$to^bk!DK`V=Wuwii8 z@M5#5{j?ly!p?$c%tsxv*w;;1au|VS7n)luxY7BVn=Ta427Bv+yU}b^b=$vE4nT~o z`JT3BxsrIe!8*?A#HnSIhyV0Znm`RNiJ2ODR)3RyJ+~Xc7UNHIeK6^~#UV|WFh$|H z3NRZma>?=-lnpmJ72JKN2K!ciW>;Mhyx9|n*uV#w?iY+*Q{Td>~Q zIrv2f_sRJb>V?yEizd8srYBIfo}+f~wJ}JKET^G8rC^UVIl%d-@?96YaFamT(nH!Ara-W#_>TRS`#hLb=a#b&gqi)1%R38V?p`m6y38J*%8t3^v zxT9YTooLakcZ|Xaq*MAdyW~20x8iXRvgpQ|t@||Ze0LO0#oq6z=@@a$*V+5xzZNe% zVCdp~O<{);1CAoD7c4kG5j{QhFj3Gl{KcDXA?0pfH&Hv|7#C*C$L#(NImo_xo@vG< zm4JQd=CHO76jq#DMkrA8ncp5!t&rVz#~h_6Lzm;!^N8BMi~>jyLv@>^&^0T?xW;-z z(`OK}9Ma+9kvTVqJI~pZ_~I|>{OzLvQ|4B@GU2hIYEN%mS}11Mmb{=v`D9LZS~0u5&GxY>1tn>oJU86 zqq9^7*S)9FuOzzS)DWp{q5ua9d^H9?PrBUixA}_%L=TUYpo@oVJ6wxA#CL@TlTVT! z-3Y$GoekH+-$h`>9Ee2!*iiyiN>BVBOvfQN^m;2K-Pmi1S*Du2XOTNLQi%@YO8~v0 zZ^LJdqamUb+--p#_&m?7mx|WqWJ5diZv(5uVq=P;lw*?`??G_fB39F4j)PY{2H#BS zXh&WsK3<8Tu9Ch&yd8FJY?H_O`1)Vo#HM8}Ao>Z(A8qI76{uJ+fi%@O3^CVv)G~`a zPB#RTdl;vU2}|Oyhx<_oO+4mMJ5uCZ>Zl0E!71BAFM^e@M)jXcXLbbSuG>#}U0U3O zHGM`OHlas4MK=VI1C^bf>J-%8f;R&n z_ub^YH8mOLo1b5ZNIw=758T`nabl4Q4fq9q{lJIBm1)WKF?&h^GK`mSR3v%^&#$t@=5M(XyJ`$nKBD6hBY|g z(uXZ1HnnJL@*v~qsQArQuW0{~BNihDvP|tI!}{cS;|6+QgJHuFucTDRR!8{0&&~Vr z-`rS~V{PRsVEIiY6k;uXcxCSy5eY-=e(5j5{srI0q>Z~}x%w&?E>;+WRjJsET2WRk z>e7ENiw4%}v;-o-Zv_Kp00^dTV@H3?$8Nk4@cO1tsyZ%d;lQ7vD!bMY?Nzgh>qEY`AsU43S3ToS3&j%YGkO#9lK9_9c$9}oXxZx z^U=S%dL&mX=9W+$U<vC8~pVOR(m)NVVOQ&MBbKivjunbgmliiV$xxt{uBN!1~eFQt{Hhk2I=4i>EYOV#y4&6BxeP^cOAY`a;=e@FtK z|4E&`+*R3{u>Fy#rwdA%#+A?_Rcn!uL|08(qbL$-a^Uae*(86{T?WfhSbcyd3coF1hLOOkD0^t7nC(Sya3t%*o8;eDOVqlDS(c|9o z7nR&aF#W+_CZ(Bj$7NG3rQL=$!QvLSE6zNgt1j4uxWzgFmaSrZoqvo;%p5-sES)U~v|qUZU}BfHpYAEAC1zGt3L3MZR3l zkKfjYPObiv)3_5QU}<;1MGy^Ag5#;w?Zw?2%obdj70X(b4(J|YsBpzB8B8Zt&l>_z z2x5OXHOv>jPCaL^MVJ+W{shy0i+`Xe7L=td=05j57;lPyU?!_#7X8-Pb4uekW{E1hNr|y%hY!Uo;xBn zwr2Sl{;6p1cF-UN+vq#z9-s8ZayhIY*mIu#R=>Y8qHq3F98Phj8moB}r`WY;=(RlF z~-D9I5A{65_E=G1t@fOX?dbw~Zs^4@!%*(tFeWO#ExTO0oYr<Ub0YvtZ-gt zTT!0T3aZGda=}v83yioavMe>0kuk2^xL)2RFMiKDDhxNvzo+x3;57&|JPM4cQ`q!> z)WW~s1-G-P-S?$%SWRt9zea&EYFZCLo4)%dH95M2Q65zNRa1z1^^OScI%Iyl$wWnw zy{$B%!HNCU(+&V{#xciyg+0RmtuH}<1}2^d6iQ_rgG@~{r(|M2BTm98mP$7V)EWC= zw^lW^N(Cd)qlz*=Jl@D>3}_+MCjYU0`(A=0(|Hv|^8D^*&u1C0=)6ykfz@|l;`VD@ zU!p@|j>zI=3cf6~>^xTb>KblT(K{%{%K}@ipWb^nAC|K+;FZvLE zsZ`QXo8`FUZqrl5Kk&O$bxAIKrsHlTtW7(b34)~Ut$0auw0R*Wb z_$mll)zIWvJ;$bvRO69o4Z`e4jhya#tP#djVlFY|S)Li2TEWZ^;oOm8-Ua7Cxc(8B zo@*$P+jHBxLt9`+sFl4cgKeSE(&`T`#GN{pthLR3pDO1}(klc_GoL|9%2z}*4+S!6 zvkEGMFK}^zU$AWS!8E<++<)eb+kKOnKtSMid1J;TmvPC)iDp^0;9lM6A`Y*&Ovk3? zz7H!clIHxmA4*^~l0mu6mj)$Tq~t4YsW6HP4_21I$MG%eH}o@LEQfoEanwXuTI#F=kd z=(3%EvYq{BY(3I}Hiyq9x?qpgMxN**0H=ozl1LLV6M2~J*5fPzPqeP!(2OrUCY-Gp zjF>zs3V?3{n~taeW+v*}VL{Y@rvE=+_dnthkeB%`fDddmWJhxGoNsSgkgV~_KONnb z90G0Em)2T#mB`^Q7;RnVpB1{05+4YR|wNHie zZyoRGF8isK{8)GHFl@M^(-u!=`X#<`OQx^<+_;Xew0X*eYzwv*{GH(6;AA9c|*5tPI4O>7I1XP-Wh#dhDRC=TcTTziBkf3x#dT$9W zL{Pwns0auciV8>|bO=2Z0qJPy0YZ^Z2t6TIy_t*RFf4Fjm+_UaA zGizqnZ_S!<+Au&b3Sdo~Huks+|6bxhcS#8D(fzrMTH{_sLNBKQF9B=eoeXDE)g5(IXi-4g3YWtb-c;N0&T5{0l=ctb)peel}U-(aw&sv$?2sx z&vM0Bn54P9R9QZN>3XAemR1xN=NO8m3>nuAO$q*b$NyK_E|0bjX`o35nQ~a6w7vV} z2LsC!u$EVwYQ@ACv*A!r;1Ykuk7BgVqa@~rt~?otop4DAX1yeqp6?2jQ+Ae&ZS?u= zMlJsq2cKg@O@AE#C{urMm&-MZ#6{9>Zsjp^#0v4GOpsYo46EJYOTNh_uBA2zv%XuC zfT9(@X_>n8$5%XHzk5rEa}!xobO< zYE~W%@l-Bz8!5h2Lwcii{@WF)5dB{->+IZHcypIQnvU02nqLn5@gn_NIE z(F6|3LSpUpwRek+(7V)%)Sl!73l~&t}nIu+L^`TQz#aMRYMYu&QT+9BqP) zzwNr@ZH)eix1BS0jpznpjJd2W{JPtK{CjLw;!t_ftdmQT{A-S1b8dg9zUP1ybZton z8x5!&LHTCvbgTul5l$Y0wM$M8Zl&eNINLaU|K8hT_pjOvzhmofAMJx!f}}@Dx~j|{ z*E(9HuboAT4lf%bGNhhmzzW?27`o%*0JGt+-5&qpopInVYNp84J5|Ndw!_p=3Io&XB;$iEo-)kJNFSg;^aufpWi zD{Y^{kFna<;#dAS%&(&TpJx<2c@5Cql`@etT8|bnr%%fLams&%?k_dxF++|n@{V1* zC9}GC1%8wFHW;jSTngZg-#)n|CZHRK71IAief|Quw#UHww)H&KEV&1Oly2q;|EA~v zGc*3cetWZ@S0L@_R!uhPXB>a{!C&E)<4*vGBh=)&t$><)d=Blq{}z>a0e~%Sb3t#< zbJh~xJn8!jJotm52h6~~3w~eQf*20hhi-!xzfD#4BoLQeKb|lv4M^yj%vA8-qSE#p zkkF)$>aCbPqi#2Ua{kS~{sp!Dm4(J5QFP3l#O$)STnf5i~|LFa-YH-8Q;fXK_FkMm>6 zAAazwD1ROJk5f&)4y?nTy$=k80bMb8J$dEtQSsZV@Kdp%+4TK5UGnJ@&i^vv|Gd1^ zGXHfy4Twx6=fm!p{;9Y5-zKGZ3UDJ%EcqE+fYr^o;dSh9QR%GMD)DAc{`kP*05j&N zFMIwTTfkfKd95oDPx3?S&RzIhmh$t~d4=q*e#7vq6ujXlMee^v#oio{vs@1CPQJ`u zgx1OXyZ;_r#J6HeD-7RO*>tPF>4&>oGuI}QKG4gHxx{{J|j`^OFa&J+COhW^yA{o{uIoGt(F z+)(wVHA&?tzN9^nB=Y8@*quu9{gyXp@Sbj-q)NQUAv@&YP$h|xxv((oEcbL=;iYwB zCHbU$f6V!o*-CQlNqy1^Xk;h1=8nCGH1?WY!}d@5(yRT+cc0Ji3<0V>iR{+ltRd`tdiYO%@@J3z_TA^3 z00D3hngx-WRrk(xo5QOeKLb22b~VOHh6T}brj52Wr=KVGSN}wxQCr01Q?08rPEbI{ z5ANPJ0a-DCKyz92h+DMJ;i%`^9DeVo(?E;kGhaO;!baRmKlzDlmjTK7EPI&{2x7m2 zEDM6|^!**%CUBM&AaDp(Zvi3aqn`r*hr{K51_-QQnvcDamOUBBO9&MKahA}&8 z2+gyRJJZ8PNDqJ7zg+?D?fL`|5TAo=sgc#~3)>U_R^wgZ@wdlYWCcU86K^KrzceHM zt1BV6`OtBS$vwu!k*))D;a5*~Zks?nFF?R%=oX+xN-vtOZFdRj1LG$gdQf^@V-aKe zy@GqY4A8p=bgP!gRNeC);K1%f7q=_G<9bm5fy^wEeSjK;Uo8ErEAN-zsoeq|HwZc3 zYrmHnqZLoSx?Ki{Ydsusvsr6=XrQqOQ#-lmFX`>?#p|dK5Qz4X*is|uvjV^W*IyCl zjhn#Zw_Z&M0w&P&=8DQM6Z@--RI>q$FglBQ*xhk2lk3Kp9or_L%?=RAcRd5Bk#NJ0 zliOWF|2TnvoWMU$;2$UOj}!R6#RhJ@f|gVJ~wM zlaX$BJu(Ssy@;G?(2W~4Hpb67^u!r$FD?xOCl`!A235Glf(l{jpddA&Ri>-4tvT%o9z8fc>kOm8Ts>$oXK0zlzK9XG zGpn`7(}G7x$8#N>J1>rlmS=c%_>7Boe9lv}hW?dk;J4`GvuSW04OUudB41)1PEJ~T zdYTf@Q*P;+}mRj>iS6E>)o#8w4#OSno2vL z_?A?k_KVbz>)de4=aJtsNlM4 zq5N42NCpF>_&u5Am$zHGByZK6<%ncW6WSL2;P`_Ig>K>a;`IO+Dsv^Pl?R|+tFkJ8 zh63^~cMP0Z-FQCO%BqF(_#S7wJ)St~TTZ3Px{@c8I+`mE(v>CVHGt3(tAWWZHYx@d z!lZ?JsFQF%#3ibI^}mKm8`Mg%UupsTAso{y*d?Ut-~P%6|f zS8RMXZswYLxLUN~Hgw>NFbaI`G~r(@H-MIK267W&H1-X7w#QiaA{ysbCu< zECg#aae>hWY!6)Ta#|~p$D9UBp5jn{hw8}J8fDiySW>LdFu>mE@>O}jbd_1jz8DR0 za)U{tUH%paI{Q6p(ad>bemkg!knb7Gv}HkP$!CRKJYPO)-rFVfLGWy}!!`wWfwin$ zx0IynUzD|?vxvzWOvN6lA$;e|wAvp#Ot+N1eHQoRukJ8@{+*f`M<9)x(Nzv?n*A+y?Rf_f+r6XvD~<)>^yyR_=XRtV9M2DojTLjU>B|5d4FC4sTi$}y{3u53#m zf=AqBR}XEE#d;)QCp!n^ z9^PF;aGXAqc5pjJHhCBb=zC~~q^s#Xbm1MJuP2@b@gBias7!CShQME;YX|CRYg=K&Rr36KxLx!|v)U1Y4TU>S+yiKSk7{Mxj(bs)+|r$iVQs5n z0A+l5m-Qn+lNI^p^!BV(C7>Z?7A)+$0gQ6qK%xV{I-?UGsQhlq|2uyi?*THFB)hV& zTwj!D{UUyt6@ZJTPoLf1vRv3wH^xc5!vHa>BxApr5jXVe>6PH^SaQ7_T2LS5kgWb!!2O!p$4oL)XED7bN!2h~h{&TKf`GAa#7lwEz zfgqm!30RsPz=Jz)-Ud?j{yH7Cp)GZzT}zh!$E5tKk^h*KKMC2p{xKE-=JAM+v_e?fK6eFw$ z27PJrR;~8(LGy>@J?8D@2NK;Jj*S{$f05fOS9Z|SsHRLrE@HHZpQX50Vt>|Dt-@O1;p;oC zLm&F!yFQyJ+eP-nMfU6PJoh;9n_m5|pL{L=vuYQ37;Kv~LQ+#NTDk&2PrZ@CW@Zat zmv|PcM?bofgX>&7f;E_g;YZ={uSPY53z^gS{!~l%Sk}kof!8cUL(7RtA$7|9)V41{ zv=D5ZV+90hWM!K9T}ZvOtc?X0;0EvORj;hPYR2lzx9qYOJj!oz(YNa>zdS0HTooFQ zpC=VVI5_ZVarVfr+{)-sO|iSqn}#k5hWk_k$|^2zBVf@p*@^@+RSlAaLa-T8kRN*i zPy=J~1ATyWFmo{TRu%ikf|7eDaRAmyEJjrYa3AxeN$w3CnZ5}7j-onJ4$KQLhynVs zSThncc~FI(xg&?0JljLSjO2s{@+}J6oUjD5_ei_2(@`P0VD4j1;Kyt6wwb(HOAnYf z<|5*IB`j}m3v@mF9tf;z{JMuafnCbS7T|4jl5B=t!2W!TW<^#7CRmqrd=(7Ky?IOp zS}UyDzo2B;-z!dsCeG%gs+5Dqn)&E1xiFl7#zz#3yiD13j%k#jyTycMCf6YCojCR7 zH2Of6S`KO#ZMK?!?=c559|e5C_j^g6Yx83d*V!*iuFDh;*Rhg|D$=G4Qpw9}mq?HQ z#60~^YP3I6t<=kibA{g=ERBWIeQArWV%EZ2`2#2Nz(dc0!&^kG4{{bN3Q`*UHZD4J zBJ)SNU+*#UP)EXG1F?MYSmt78XAWvd((J-9=F^*_!n_9{94AH(^6y&b3;HOI^}h{% zC>jAUpEW35=e_05kvtVjW}|H2CaM}DTtd#9Jji}nUJ-me?GGxiX0?-uR}A_vBn%3w zMdn65^Es2~Vcl5r4XW;13fm!&sGoRkM{qEUPJhssgT-zy!v2q0f7wOjI_jx8|Ex9w zdK6wW7`J5L8J&m3BESc z!%s`6@h=F==66R34NW#g9w9!eiOOQn72lmHn0pN8^-;5kYUwWPD-Gnb|DQs6&l&tE z{AGzO^#0NSr-`Yi=G2j>6y*OOj2njv|h3(zzy5pmZ<2` zIexB}<7JY*a{5r4$7A={hq~ z)i8vQM<&=`)4Yy}5VY4z>^P;TO-S&wwdy-&3s>?T zkc6yGN5E89q~5Feya`xbNZ6x#$oyim8d_lmDQ9U!78KSM6s9c7e^;Yg#$1|vT^WrAzbRU26<$1A3GQabB_c&O+|njp18U z+9UY>XOThzu`npo6N{KUlg`-bWv5FPW#$sQ2$3%7%wy5Z0(hP1?>ya#!pJ!tfY_bDtkMT>4uokY;G8LE8?*Qrx@V7MDd`ku{o=B6xyS_U0lb! zaJ7PRVj=x>t`E(XASH;TrWilMMoWvVc`o`h8eA5Tkr2vmvem_-L$D{^H@9$cmWK0UC#EC;YIzOMwAC3c~06Ldb>f zlI+p{JhBV+KSY@>a2uR05-KRT(vbbxYolIkXe@MvF6ZN`zH=1p)I)2o9xysMup2fs zZQEZgCutT;dFbTBhM=K{iRg_dl1@cqIpTEYM5w%}rdz6oSt4^iAsc#m{s#;wgP9Fp z87#AgL9fEUqi*Qt>TS5og<$LFg387~WJcs1onx{!elq4gCVAxfR9oE4^|yKNc3v$C z8S>~!`Z408WVToC;!G@kZU8Y%4DrTB)Ltev-F30cJgZriIv-E7Jat(jsiyD zzxaKVx`=Zdj8wH-XPri!8-U!$KXpkTi%l+&KaJP1>!{)%j&n(`t-P^?W)7(WXr>B3 zfELZH6^JvSP@hsss8|tSW>1+&j~i5Ie)%ztOE^y)YqnqrgZaBb9$D)z8flLb4r)hK z?Q+L|g~<0@(3JmHTU9Xc>C53F>PM0PCTDN|pU$Q0xmuu}?n>5fIQOtml)>H;7SFjq zIUZ*1S|}e63w*RfIlwwrrDzh|FFliblsDt?#*_3E$Rn%;n*MDjDZVyY_lj>gm?|t> z)=6*_8Nb|tUC^lZ9~qE{EqyL^x6AEa;U)ldRZOcAD4k-anb1nGX?dr3Hdr4xdbnBX zFd05iXL>Fku_nODX$@Ou*Nf$4nMPmCG2 zoHFZ1-LgDjXOJUO-iUqWlKw&juTw9jX=i<-7}*}?PplBd>x9zYY@v>22mp12p9exm z+>D(f>I3NlsE!W!@4-d_V_Jf7Ou@4YIgcKG-45y|+>K9&A3VpgL$}BgyJDvUo9aj+ zUdR_0MD4i}1Z+U^fr1I>_c$H?o*&4)dY~<3fCI z$ckcZMA(!6I=@o$ChQWanU3ZXkP6bzs zhOu2N<9b0FPq3_;BNBROZK0BF@M)Cj(3hq0!B02GiGDOr;|B(z#SAEG8jt9}5DUjm z-FTUlk-*cM0rQl7u*J?h=}Xfn4R%|d+?g8?;(WeC@6KL~3Z*vkeg(3EKD`^WL2Kim zZN>0Zy`7o6NCM)B(o>p|G;*A+s8;yMv>x}f{WdCL`4y*;QHUv!FWN@G1-I9vAx%4O z+VG6Lg#@oYww)#0b>8;9qY{rgnp0|F#;QBsAi;Wmnj$d0PTG|&Uu z{_gCO2N|2ON3SCg_Iy=7_qtvKo2{8KuR)uZcGxVYmxa_58LJ>DyH!q^2lgTSPU|nY6l+x~5q*F@SYg74Z|f;@u~l+wn#P6y*Z{ zpa!er?_u>1O3s95d{x)gwXKs4?D1U7xw78h-M=oPFn?C(@LZZs;=2O3uJCg50=eZ~ z51f5zDxrg*y7Fc&*XQlPDe~~x>XDcb%9*K~!p0C7v42WK z#JIgM=ve=NXM>3V4?QCGOoSQ(_nFV{L+D!DH)~PnQl$wjtSdZJ<&+h#amP%#+KK3I z&^OJ68Bu0Vq$<<4=RGGPA~^ef0zBhuec6W^!j{~F%FrE=1OEB=b=d8^Aa1xI;(BfV z$KJ4@n?XtSuZSaC8lT9J#^#M$_SjgN*P&6- zPG)G2!n>-v#S+wrA_jRwMRU}rtQ%HkE+Hi;z|#=9L?|uo**)sT{O&}ek^Cx|lXKbb zQ+*!0CF`0<4$7);C$8qS2(AUGbcuqX3rj2VF3q3bCmB>`za>#>?oL;}(I&yGgEk+; z3MI5#9_pbrks{Rz2~A4^R1-L&uS!d|Po}UREVNdB6AONRZ;#AyO_1HR?C!NYndnn% zAh4u)4`cV!P5XYFor$Emd?@*eh*m|{<`EUL#yty1melj|sRL8-NtC>rR=nk|j7Kvo zi~YUcoJCUOe%~1>@4_ce1iJB;o8PE{Wn;rz{LalyNhdX}UGpq^F6>%@#mSgGTGDE7 z)GKzXy>w*L_3%pqG9CigRG~%6Gagu2;#uWQ1LCk9#Zh*Pn^yP?H;dazw+PBxe)aqJ zS0oxPN3|b1ORF~gR(T&`moBTdwZr0TWNSZ60*?6Xt~Bhn(|tHX>MxL*0?o0VL(A+u zGE0EqFVZ%+RZF9xaS=rcm~v${?hPcDRl2$ZNgtcj)2`%l*D-z39)C{;4|TtwY?oN> zJ{pK=-BpbvRtx{^TrH({tq-}eY3jlfy@wjPOA~oCO@ZKRlRT6Ca`<>|ZC)I5ET~m! zJv}!^_<`HuZ)1Y-nq>_=-?H;uOeYEFK*t9HCu~AG4<@Rtde< zl`8`?kE&G`j|Op1yz2<-k?ZYpQ!xp5(mw)R1^m}e=9Q7!Xt$~g`PTYi7Du}((8sea z)h|3UNl$HcBbMO7{;B<)T)$c1x052DBErAvFiA!^UKR*U16%pnl()r+hJ+Z4g|r`i zdk`~g+<|ws>liIk3tkdL@f)g)3NfKCo#T$|j>Db|KG*eDhd4I>O(C|f3xylT_t`EH z81|u|ke91MI-mjpB&eeUwl{ZGD486Y)Z+rR2xL48y;Z=nvq4&>+-I!NRtd4W;UI30Z&3KUk&xG zVDEMqR$&IFat}?H(nuAf`$-hpQKse8$F~z_D(tH8KWd!725=x+>zLM+)b)3*skmqN z0;Ts*%-lRFkfH-b`h;>xJd6epSb8$qft-mki8c!*j`2(7OyPqvHoR;p4_!U|3`S=3 zIcCk@erCy3+el)r8$;h>{lvQfj^Q%>t~Lh2kp7zQ`D(dremgL2jizNFI11uk9V1S=r(oli-vGxH5Wti_~iH zzz;8Wx7mUshnAP~WXR#`DU*1&iUGzqRF6Ya8N13AmzE^sz#}8lbT!PB3D#*y024TO zGjt>;Z_P8jt%Kb}uFJJ#T_096=EYF55bb+>wjglS7I|)o&{5@lqW-qpVj@1rYsI!> zuawWmFt%^4kgjqW+qO@YD5}~U6MN4#rz3X2n`SO@tDfL{(d#I_CvxaGrSTxHxUUsizfz94JOu(#YG3 z`(P5Ptx8)izpMg_*V#luyX*T&B8+2!=TN+6(*c)*A_K|2E`76Arlm>&>iSnqqe8o5 zFBp$xm)^fO>@%TPb$Rtz{VGtD?_)(oSZ{t%fu!!nz%w^Uxm%URcv8>Jlaa%SOuS7a z!@O`UHD0HL()|%eqb(tB0T%em&lb3G<@Fp>Zxa1(grrBMU*n+7!O8~osFxD4De(dY zt!H{UmS~gZs;2E4W~y!jWw^?vh4diLwSei@G}ku884nB5UWrlG35t%;GmCds`o&Jo zOXZhurx$mt7Wq^Rm;qZ}4rh~V5iX(~ugI#-ptWzg#J7qbF)pIT$gq537x^ZtB48=# zq33O3;2y)dbjmRxBjQWe$Q>X#r_#%CXml}ee4$a>WGKKQhy-!zn_r)OF?*El-7N%$ zDy;EY{$dR@yEW-zn_0#5QP@Y~XES>c7~Fqf8jSd^-!-KPhIsFL4K?8^^wI(C7#Ci2 zsEA#ka$+;Hj#BT`4r06aoG1hC{=^UJ`!IV!sq+KSQ$jP-bSH9e^5tY*sCVDh0cfv7 zi`HOQ_`p^4tsbRw=_bUZsTS5}7Pxhi<$vItvU_e$7)v?WIBe>K`xR}>f1?|B8m-Lk zZWldI$)sJ9=1zasi1NF6zy5zfeZ@O9A_LUR)Iu;x2f?o?pj{G^I6I=m2hw8LO|josADtNt3}*acq8XR$^^-DW=f{ih6$-xdAJhZfTc;hD+Jl7z)yxTDNCd0im;>{qK^x$z#ncXR=t?FBeGaE(vlu3CZXCsq`?;`TF9`HNaP z2zwk}U>foj-p~3xKMIwc7lTs|61+QyVZeXY=no* zIdEn=5@5rg+Sn*D!+YSAjNq8d+6gh=p3h&-Oyl8|VU)&)F*Xx}WN2M_v1}2RE5*o# zHQ1#ZOrXkWfx#?{t|wXhf`6qHw@+A;s1Os6;#2h`NHVLK27sLe=_P{Z;Fn;M!cG9(f<@{Vr5uO4| zZ}44w8bI_kQ5`sQ*=T^PUdkxP$0Tbxq_#SJtlIF}Z3iFSpD4}xeLh*>yn9y=FU#xO z4`IKGZ?@+OZ&jw628!*HKo3-NeKtzmGiqdpO-QM` z_n$IJ7&=#8VVxi>bJ&e-PulGAlj1tpx5A&l2R}T>uY%)(nRz~g#O)F#?&#bJdV;Cr znnYuejcoo>#Qublf=4W;0ylLMq=zMQo0V~Ab#ia@qW!o#jV4Vmfum1#3Oxq9cZpM> zBK=c3#G%P!rDNP%;g+5Xj!&0at3F^`wenJpNe&S^_+`zZI;Sp~jVAyJouDi?wL5ue^#wDI0%MX`=8 zq+lg(Y)_Aac6x0~BX^mBoYasecVFP$9d{WMqJ3!uYNkimVR?1jWveo6{7=1>HBN&6 zj<35CABH$c7%|=>^Gx}!6zFm-zpO>D?+i8r4E4vQAupP4 zy=Fg{xywGm#USH;#-s+#iB2KH5^C$BoXs`x>9dtN6|tOB4pXJ#H^m?N0q}r@tf449 zEG>6t1ET2K9lutkpU(9vQ_K>+6dJb!8Gl>3GP+#{Wx>U9JB^UX` z_~P{^@_z(X-G78-$MS6(6h8gCp@Vy%txz!zEjag&#=vE~9oY&U&#DA_r_njEtqPfvq&k zC#VuXLyAe%qv6RJ;xKXV&(9h_=nu)_FYC2y1`^QUp-127pJQUt`fi8i`Wub+1Z}oz zF~kQQ6}2G>hG1e6TK%K(Ufrp9`TiD7Q9*mvcPg45cl}GjuM8i`$$%FFCPRA*VsG`% z3E-Qb}EHT}sAm32GH}W_PsJ;h_e$b5q9G1_LCM(J`5bB9-sb zWrMVMpM=00E!;;LnxlPQ0!#HE6l0w$n zgG)b-up#*N;BCPlyyOz(;XPF(w6Ad3Q!ICnara&1jzjTO%cr5FqWwpujlfP3*bW)f zz0BDvo!oCvkKo8LWGFtNik0+YS4msJAbA+r`Z9dtYA=AKn{ zxSJy-P&>&9J~jP=PZn-B`$Zf)L9jcqj^;0k=#@uNg{Yc!u~g)p+ak)$5#r4~&2NfLX)~B*akj(qo^s>bONcO_a z+u`u73%-0R@wokO1lB)h&dl*<5FP!Z)923qlDDykxLmCXPH2HcfcImNnCHyq@@QSMhnV zzS&3F>~!O3lhEts+zXy&v|?NJPwaIAUKuhXuZnoM8*aC*O9* z{uWZ~Wm>@cK0zkQT9mfvGXC`�S$B(kU5p`&`PdT;be1B}OmWBUY!<=Uyi8W4 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'qlOS9}IB)55xc8pud9(LB9U%G{uJz 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

Le|(QdL=W^37FJ*|hz|0-wDpTN-h) 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 z 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%0AT{TQJSFy^OkzwmKgjT`5WI-XnvTCickO0@k z{`BmJ=4U&_&OYl!hd>q^>CRN)of}W~E%Shfwh5_4^u_U⁣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

RM~1?zj`!*sUPMb@S6f*vrQs@xswTNN) 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 From 2edaa2ea5ac9cf51fe1df476b3bfe44b103ec4bb Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 09:13:29 +0200 Subject: [PATCH 14/73] api: merge the how-to page into the section index --- content/api/_index.md | 342 ++++++++++++++++- content/api/howto.md | 345 ------------------ content/changelog/2025/03-07-rust-sdk-0.13.md | 2 +- .../05-28-oauth-consumer-new-interface.md | 2 +- .../2025/06-05-api-tokens-console-tips.md | 2 +- .../2025/06-05-oauth-tokens-new-interface.md | 2 +- .../changelog/2026/04-09-clever-tools-4.8.md | 4 +- content/doc/kubernetes/operator.md | 4 +- hugo.yaml | 2 +- 9 files changed, 342 insertions(+), 363 deletions(-) delete mode 100644 content/api/howto.md diff --git a/content/api/_index.md b/content/api/_index.md index cedd7de49..a42cc5cdd 100644 --- a/content/api/_index.md +++ b/content/api/_index.md @@ -1,15 +1,19 @@ --- type: docs linkTitle: API -title: API -description: Clever Cloud API documentation. Learn how to use our API, endpoints, authentication methods, and how to access it from multiple tools. +title: How to use Clever Cloud API +description: Learn how to use the Clever Cloud API, its authentication methods with API tokens or OAuth 1, available endpoints, and how to access it from multiple tools. keywords: - rest api - authentication - endpoints - documentation - integration +- oauth +- tokens +- developer guide aliases: +- /api/howto - /doc/api/ - /doc/openapi - /doc/clever-cloud-addons-api/add-ons-api @@ -21,13 +25,333 @@ aliases: - /openapi --- -{{< hextra/hero-subtitle >}} - Automate your workflows and connect your services to Clever Cloud using its API. -{{< /hextra/hero-subtitle >}} +The [Clever Cloud Console](https://console.clever-cloud.com) and [Clever Tools](https://github.com/CleverCloud/clever-tools) allow you to manage your account and products with the same public API you can use for your own services and integrations. This article will explain how to connect to this API and use it. {{< cards >}} - {{< card link="/developers/api/howto" title="API overview" subtitle="Understand Clever Cloud APIs, authentication and available tools" icon="api" >}} - {{< card link="/developers/api/v2" title="APIv2 reference" subtitle="API endpoints for users, organisations, applications and add-ons" icon="endpoints" >}} - {{< card link="/developers/api/v4" title="APIv4 reference" subtitle="API endpoints for billing, deployments, load balancers and logs" icon="endpoints" >}} - + {{< card link="/developers/api/v2/" title="Base v2 Endpoints" subtitle="Our base API endpoints with users, organisations, applications, add-ons, etc." icon="endpoints" >}} + {{< card link="/developers/api/v4/" title="New v4 Endpoints" subtitle="More recent API endpoints with billing, deployments, load balancers, logs, etc." icon="new" >}} {{< /cards >}} + +## Request the API + +Clever Cloud's REST API offers two authentication mechanisms to meet different integration needs: + +- **API tokens** provide a straightforward way to authenticate requests on behalf of a specific user. These tokens operate similarly to passwords and should be handled with appropriate security measures. API tokens are ideal for personal scripts, CLI tools, and scenarios where you're accessing your own resources. Use them to request the API Bridge: + +- **OAuth 1** is designed for third-party applications that need to access Clever Cloud resources on behalf of their users. This authentication flow allows applications to request permissions from users without requiring direct access to their credentials. OAuth 1 is recommended for public applications, services that integrate with multiple user accounts, or any scenario where user delegation is required. + +Choose the authentication method that best aligns with your specific integration requirements and security considerations. + +### API tokens + +Clever Cloud Console allows you to easily create and manage API tokens. + +![Manage API tokens in Clever Cloud Console](/images/console-api-tokens.webp) + +[Clever Tools](https://github.com/CleverCloud/clever-tools) provides a `clever tokens` set of commands. This feature needs to be enabled: + +```bash +clever features enable tokens +clever tokens create "CI job Foobar" +clever tokens create "Quick local test" --expiration 1h +``` + +You can also list or revoke tokens: + +```bash +clever tokens -F json +clever tokens revoke api_tokens_xxx +``` + +Once created, API tokens must be used through the bridge URL: + +```bash +curl https://api-bridge.clever-cloud.com/v2/self -H "Authorization: Bearer [API_TOKEN]" +``` + +### clever curl + +`clever curl` is a wrapper around `curl`, it supports the same arguments and handles the authentication automatically for you using the CLI account you're currently logged in with. It's a simple way to make requests to the Clever Cloud API if [Clever Tools](https://github.com/CleverCloud/clever-tools) are installed on your system. + +```bash +clever curl https://api.clever-cloud.com/v2/self +clever curl https://api.clever-cloud.com/v2/summary +clever curl https://api.clever-cloud.com/v4/products/zones +clever curl https://api.clever-cloud.com/v2/organisations//applications | jq '.[].id' +clever curl https://api.clever-cloud.com/v4/billing/organisations//.pdf > invoice.pdf +``` + +### Official clients/SDKs + +You can request the Clever Cloud API from multiple languages through our official clients/SDKs: + +- [Go](https://github.com/CleverCloud/clevercloud-client-go) +- [JavaScript](https://github.com/CleverCloud/clever-client.js) +- [Rust](https://github.com/CleverCloud/clevercloud-sdk-rust) + +### OAuth1 + +If you have an application that needs to access Clever Cloud resources on behalf of your users, you can use OAuth1. This is the recommended way to authenticate third-party applications. + +- To manage OAuth tokens linked to your account, use the [Clever Cloud Console](https://console.clever-cloud.com/users/me/oauth-tokens) +- A complete working example (Node.js) is available at [github.com/CleverCloud/oauth1-example](https://github.com/CleverCloud/oauth1-example) + +#### Create an OAuth consumer + +First, you'll need to create an OAuth consumer for your application. This can be done in the [Clever Cloud Console](https://console.clever-cloud.com). Go to your organisation, click on **Create…**, then on **an OAuth consumer** and fill the form. You will get: + +- A **consumer key** (public identifier for your application) +- A **consumer secret** (private key, never expose it client-side) + +You can also manage OAuth consumers from the CLI with the `clever oauth-consumers` command set, which covers the full lifecycle (list, create, get, update, open and delete). Use `--with-secret` on the `get` subcommand to retrieve the consumer secret: + +```bash +clever oauth-consumers create my-app \ + --description "My application" \ + --url https://my-app.example.com \ + --base-url https://my-app.example.com/oauth/callback \ + --rights access-personal-information,access-organisations + +clever oauth-consumers get my-app --with-secret +``` + +> [!NOTE] +> The **base URL** you set when creating the consumer is important: the callback URL you use during the OAuth flow must match this base URL's domain. For local development, register a separate consumer with `http://localhost:` as the base URL. + +#### The OAuth1 flow + +Your application must implement the [OAuth 1.0a flow](https://oauth.net/core/1.0a/) (also known as the "OAuth dance"). It consists of three steps: obtaining a request token, redirecting the user for authorization, and exchanging for an access token. + +{{% steps %}} + +##### Get a request token + +Request a temporary token from the API. OAuth parameters can be sent as query string parameters or as a form-encoded body: + +- `POST https://api.clever-cloud.com/v2/oauth/request_token_query` — parameters as query string +- `POST https://api.clever-cloud.com/v2/oauth/request_token` — parameters as `application/x-www-form-urlencoded` body + +**Required parameters:** + +| Parameter | Description | +| ------------------------ | ------------------------------------------------------------- | +| `oauth_consumer_key` | Your consumer key | +| `oauth_signature_method` | `HMAC-SHA512`, `HMAC-SHA1`, or `PLAINTEXT` | +| `oauth_signature` | Request signature (see [Signing requests](#signing-requests)) | +| `oauth_timestamp` | Current Unix timestamp (seconds) | +| `oauth_nonce` | Unique random string for this request | +| `oauth_version` | Must be `1.0` | +| `oauth_callback` | URL to redirect the user to after authorization | + +**Example request** (see [Signing requests](#signing-requests) for how to compute the signature): + +```javascript +const url = "https://api.clever-cloud.com/v2/oauth/request_token_query"; + +const params = { + oauth_consumer_key: CONSUMER_KEY, + oauth_signature_method: "HMAC-SHA512", + oauth_timestamp: Math.floor(Date.now() / 1000).toString(), + oauth_nonce: crypto.randomUUID().replace(/-/g, ""), + oauth_version: "1.0", + oauth_callback: "http://localhost:8080/auth/callback", +}; + +// buildBaseString and sign are defined in the "Signing requests" section +const baseString = buildBaseString("POST", url, params); +params.oauth_signature = sign(baseString); + +const qs = new URLSearchParams(params).toString(); +const res = await fetch(`${url}?${qs}`, { method: "POST" }); +``` + +> [!TIP] +> For quick testing, you can use `PLAINTEXT` with curl (percent-encode your consumer secret if it contains non-alphanumeric characters): +> +> ```bash +> curl -X POST "https://api.clever-cloud.com/v2/oauth/request_token_query?\ +> oauth_consumer_key=&oauth_signature_method=PLAINTEXT&\ +> oauth_signature=%26&oauth_timestamp=$(date +%s)&\ +> oauth_nonce=$(uuidgen)&oauth_version=1.0&\ +> oauth_callback=http%3A%2F%2Flocalhost%3A8080%2Fauth%2Fcallback" +> ``` + +**Response** (`application/x-www-form-urlencoded`) + +```text +oauth_token=&oauth_token_secret=&oauth_callback_confirmed=true +``` + +Store the `oauth_token_secret` securely server-side — you will need it in step 3. + +##### Redirect the user to authorize + +Redirect the user's browser to the authorization page with the request token: + +```text +https://api.clever-cloud.com/v2/oauth/authorize?oauth_token= +``` + +The user logs into Clever Cloud (if not already) and is presented with a permissions form. Available permissions are: + +| Permission | Description | +| --------------------------------------------- | -------------------------------------------- | +| `access_organisations` | Access organisations | +| `access_organisations_bills` | Access organisations' bills | +| `access_organisations_consumption_statistics` | Access organisations' consumption statistics | +| `access_organisations_credit_count` | Access organisations' credit count | +| `access_personal_information` | Access personal information | +| `manage_organisations` | Manage organisations | +| `manage_organisations_applications` | Manage organisations' applications | +| `manage_organisations_members` | Manage organisations' members | +| `manage_organisations_services` | Manage organisations' add-ons | +| `manage_personal_information` | Manage personal information | +| `manage_ssh_keys` | Manage SSH keys | + +You can retrieve this list programmatically with `GET https://api.clever-cloud.com/v2/oauth/rights`. + +Once the user approves, the browser is redirected to your `oauth_callback` URL with the following **query string** parameters: + +| Parameter | Description | +| ---------------- | -------------------------------------------------- | +| `oauth_token` | The request token (must match the one from step 1) | +| `oauth_verifier` | Verification code to exchange for an access token | + +##### Exchange for an access token + +Exchange the request token and verifier for an access token. As with step 1, parameters can be sent as query string or form body: + +- `POST https://api.clever-cloud.com/v2/oauth/access_token_query` — parameters as query string +- `POST https://api.clever-cloud.com/v2/oauth/access_token` — parameters as `application/x-www-form-urlencoded` body + +**Required parameters:** + +| Parameter | Description | +| ------------------------ | -------------------------------------------------------------------- | +| `oauth_consumer_key` | Your consumer key | +| `oauth_signature_method` | Same method as step 1 | +| `oauth_signature` | Request signature (signed with the request token secret from step 1) | +| `oauth_timestamp` | Current Unix timestamp (seconds) | +| `oauth_nonce` | Unique random string | +| `oauth_version` | `1.0` | +| `oauth_token` | The request token from step 1 | +| `oauth_verifier` | The verifier from the callback redirect | + +**Response** (`application/x-www-form-urlencoded`) + +```text +oauth_token=&oauth_token_secret=&expiration_date= +``` + +Store both `oauth_token` and `oauth_token_secret` securely — you will need them to sign every subsequent API request. + +> [!NOTE] +> Access tokens expire after **3 months** by default. The response includes an `expiration_date` field (ISO 8601 format). + +{{% /steps %}} + +#### Making authenticated API requests + +Once you have the four credentials (consumer key, consumer secret, user token, user token secret), sign every API request using the `Authorization` header: + +```text +Authorization: OAuth oauth_consumer_key="", oauth_token="", oauth_signature_method="HMAC-SHA512", oauth_signature="", oauth_timestamp="", oauth_nonce="", oauth_version="1.0" +``` + +**Example** — Fetching the authenticated user's profile: + +```javascript +// buildBaseString, sign and authorizationHeader are defined in the "Signing requests" section +const params = { + oauth_consumer_key: CONSUMER_KEY, + oauth_signature_method: "HMAC-SHA512", + oauth_timestamp: Math.floor(Date.now() / 1000).toString(), + oauth_nonce: crypto.randomUUID().replace(/-/g, ""), + oauth_version: "1.0", + oauth_token: ACCESS_TOKEN, +}; + +const baseString = buildBaseString("GET", "https://api.clever-cloud.com/v2/self", params); +params.oauth_signature = sign(baseString, ACCESS_TOKEN_SECRET); + +const res = await fetch("https://api.clever-cloud.com/v2/self", { + headers: { Authorization: authorizationHeader(params) }, +}); +const user = await res.json(); +``` + +#### Signing requests + +Three signature methods are supported. `HMAC-SHA512` is recommended for production use. + +##### PLAINTEXT + +The simplest method. The signature is the consumer secret and token secret, percent-encoded per RFC 3986 and joined with `&`: + +```javascript +const signature = percentEncode(consumerSecret) + "&" + percentEncode(tokenSecret); +``` + +For the request token step (where no token secret exists yet), leave the second part empty: + +```javascript +const signature = percentEncode(consumerSecret) + "&"; +``` + +> [!NOTE] +> The `percentEncode` function is defined in the [HMAC section below](#hmac-sha1sha512). For secrets containing only alphanumeric characters, `encodeURIComponent` produces the same result. + +##### HMAC-SHA1/SHA512 + +These methods sign a **base string** to ensure the request has not been tampered with. The code snippets below are a JavaScript/Node.js implementation example. + +**1.** Define a `percentEncode` helper per RFC 3986: + +```javascript +// Like encodeURIComponent, but also encodes !'()* +function percentEncode(str) { + return encodeURIComponent(str) + .replace(/[!'()*]/g, c => "%" + c.charCodeAt(0).toString(16).toUpperCase()); +} +``` + +**2.** Define `buildBaseString` — it concatenates the HTTP method, URL, and sorted parameters, all percent-encoded and joined with `&`: + +```javascript +function buildBaseString(method, url, params) { + const sorted = Object.keys(params) + .filter(k => k !== "oauth_signature") + .sort() + .map(k => percentEncode(k) + "=" + percentEncode(params[k])) + .join("&"); + return method.toUpperCase() + "&" + percentEncode(url) + "&" + percentEncode(sorted); +} +``` + +The three components are: + +- The HTTP method in uppercase (`GET`, `POST`, etc.) +- The base URL (without query string), percent-encoded +- All request parameters (OAuth parameters excluding `oauth_signature`, plus any query string or form body parameters), sorted alphabetically by key — then by value in case of duplicates — formatted as `key=value` pairs joined by `&`, then percent-encoded as a single string + +**3.** Define `sign` — it computes an HMAC with the chosen algorithm and returns the base64-encoded result: + +```javascript +const { createHmac } = await import("node:crypto"); + +function sign(baseString, tokenSecret = "") { + const signingKey = percentEncode(consumerSecret) + "&" + percentEncode(tokenSecret); + return createHmac("sha512", signingKey).update(baseString).digest("base64"); +} +``` + +**4. Build the Authorization header** with all OAuth parameters (including the signature): + +```javascript +function authorizationHeader(params) { + const pairs = Object.entries(params) + .map(([k, v]) => percentEncode(k) + '="' + percentEncode(v) + '"') + .join(", "); + return "OAuth " + pairs; +} +``` diff --git a/content/api/howto.md b/content/api/howto.md deleted file mode 100644 index 3c3ca229b..000000000 --- a/content/api/howto.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -type: docs -weight: 1 -linkTitle: Clever Cloud API Overview -title: Clever Cloud API Overview -description: Getting started with the Clever Cloud API -keywords: -- rest api -- authentication -- integration -- oauth -- tokens -- developer guide ---- - -The [Clever Cloud Console](https://console.clever-cloud.com) and [Clever Tools](https://github.com/CleverCloud/clever-tools) allow you to manage your account and products with the same public API you can use for your own services and integrations. This article will explain how to connect to this API and use it. - -{{< cards >}} - {{< card link="/developers/api/v2/" title="Base v2 Endpoints" subtitle="Our base API endpoints with users, organisations, applications, add-ons, etc." icon="endpoints" >}} - {{< card link="/developers/api/v4/" title="New v4 Endpoints" subtitle="More recent API endpoints with billing, deployments, load balancers, logs, etc." icon="new" >}} -{{< /cards >}} - -## Request the API - -Clever Cloud's REST API offers two authentication mechanisms to meet different integration needs: - -- **API tokens** provide a straightforward way to authenticate requests on behalf of a specific user. These tokens operate similarly to passwords and should be handled with appropriate security measures. API tokens are ideal for personal scripts, CLI tools, and scenarios where you're accessing your own resources. Use them to request the API Bridge: - -- **OAuth 1** is designed for third-party applications that need to access Clever Cloud resources on behalf of their users. This authentication flow allows applications to request permissions from users without requiring direct access to their credentials. OAuth 1 is recommended for public applications, services that integrate with multiple user accounts, or any scenario where user delegation is required. - -Choose the authentication method that best aligns with your specific integration requirements and security considerations. - -### API tokens - -Clever Cloud Console allows you to easily create and manage API tokens. - -![Manage API tokens in Clever Cloud Console](/images/console-api-tokens.webp) - -[Clever Tools](https://github.com/CleverCloud/clever-tools) provides a `clever tokens` set of commands. This feature needs to be enabled: - -```bash -clever features enable tokens -clever tokens create "CI job Foobar" -clever tokens create "Quick local test" --expiration 1h -``` - -You can also list or revoke tokens: - -```bash -clever tokens -F json -clever tokens revoke api_tokens_xxx -``` - -Once created, API tokens must be used through the bridge URL: - -```bash -curl https://api-bridge.clever-cloud.com/v2/self -H "Authorization: Bearer [API_TOKEN]" -``` - -### clever curl - -`clever curl` is a wrapper around `curl`, it supports the same arguments and handles the authentication automatically for you using the CLI account you're currently logged in with. It's a simple way to make requests to the Clever Cloud API if [Clever Tools](https://github.com/CleverCloud/clever-tools) are installed on your system. - -```bash -clever curl https://api.clever-cloud.com/v2/self -clever curl https://api.clever-cloud.com/v2/summary -clever curl https://api.clever-cloud.com/v4/products/zones -clever curl https://api.clever-cloud.com/v2/organisations//applications | jq '.[].id' -clever curl https://api.clever-cloud.com/v4/billing/organisations//.pdf > invoice.pdf -``` - -### Official clients/SDKs - -You can request the Clever Cloud API from multiple languages through our official clients/SDKs: - -- [Go](https://github.com/CleverCloud/clevercloud-client-go) -- [JavaScript](https://github.com/CleverCloud/clever-client.js) -- [Rust](https://github.com/CleverCloud/clevercloud-sdk-rust) - -### OAuth1 - -If you have an application that needs to access Clever Cloud resources on behalf of your users, you can use OAuth1. This is the recommended way to authenticate third-party applications. - -- To manage OAuth tokens linked to your account, use the [Clever Cloud Console](https://console.clever-cloud.com/users/me/oauth-tokens) -- A complete working example (Node.js) is available at [github.com/CleverCloud/oauth1-example](https://github.com/CleverCloud/oauth1-example) - -#### Create an OAuth consumer - -First, you'll need to create an OAuth consumer for your application. This can be done in the [Clever Cloud Console](https://console.clever-cloud.com). Go to your organisation, click on **Create…**, then on **an OAuth consumer** and fill the form. You will get: - -- A **consumer key** (public identifier for your application) -- A **consumer secret** (private key, never expose it client-side) - -You can also manage OAuth consumers from the CLI with the `clever oauth-consumers` command set, which covers the full lifecycle (list, create, get, update, open and delete). Use `--with-secret` on the `get` subcommand to retrieve the consumer secret: - -```bash -clever oauth-consumers create my-app \ - --description "My application" \ - --url https://my-app.example.com \ - --base-url https://my-app.example.com/oauth/callback \ - --rights access-personal-information,access-organisations - -clever oauth-consumers get my-app --with-secret -``` - -> [!NOTE] -> The **base URL** you set when creating the consumer is important: the callback URL you use during the OAuth flow must match this base URL's domain. For local development, register a separate consumer with `http://localhost:` as the base URL. - -#### The OAuth1 flow - -Your application must implement the [OAuth 1.0a flow](https://oauth.net/core/1.0a/) (also known as the "OAuth dance"). It consists of three steps: obtaining a request token, redirecting the user for authorization, and exchanging for an access token. - -{{% steps %}} - -##### Get a request token - -Request a temporary token from the API. OAuth parameters can be sent as query string parameters or as a form-encoded body: - -- `POST https://api.clever-cloud.com/v2/oauth/request_token_query` — parameters as query string -- `POST https://api.clever-cloud.com/v2/oauth/request_token` — parameters as `application/x-www-form-urlencoded` body - -**Required parameters:** - -| Parameter | Description | -| ------------------------ | ------------------------------------------------------------- | -| `oauth_consumer_key` | Your consumer key | -| `oauth_signature_method` | `HMAC-SHA512`, `HMAC-SHA1`, or `PLAINTEXT` | -| `oauth_signature` | Request signature (see [Signing requests](#signing-requests)) | -| `oauth_timestamp` | Current Unix timestamp (seconds) | -| `oauth_nonce` | Unique random string for this request | -| `oauth_version` | Must be `1.0` | -| `oauth_callback` | URL to redirect the user to after authorization | - -**Example request** (see [Signing requests](#signing-requests) for how to compute the signature): - -```javascript -const url = "https://api.clever-cloud.com/v2/oauth/request_token_query"; - -const params = { - oauth_consumer_key: CONSUMER_KEY, - oauth_signature_method: "HMAC-SHA512", - oauth_timestamp: Math.floor(Date.now() / 1000).toString(), - oauth_nonce: crypto.randomUUID().replace(/-/g, ""), - oauth_version: "1.0", - oauth_callback: "http://localhost:8080/auth/callback", -}; - -// buildBaseString and sign are defined in the "Signing requests" section -const baseString = buildBaseString("POST", url, params); -params.oauth_signature = sign(baseString); - -const qs = new URLSearchParams(params).toString(); -const res = await fetch(`${url}?${qs}`, { method: "POST" }); -``` - -> [!TIP] -> For quick testing, you can use `PLAINTEXT` with curl (percent-encode your consumer secret if it contains non-alphanumeric characters): -> -> ```bash -> curl -X POST "https://api.clever-cloud.com/v2/oauth/request_token_query?\ -> oauth_consumer_key=&oauth_signature_method=PLAINTEXT&\ -> oauth_signature=%26&oauth_timestamp=$(date +%s)&\ -> oauth_nonce=$(uuidgen)&oauth_version=1.0&\ -> oauth_callback=http%3A%2F%2Flocalhost%3A8080%2Fauth%2Fcallback" -> ``` - -**Response** (`application/x-www-form-urlencoded`) - -```text -oauth_token=&oauth_token_secret=&oauth_callback_confirmed=true -``` - -Store the `oauth_token_secret` securely server-side — you will need it in step 3. - -##### Redirect the user to authorize - -Redirect the user's browser to the authorization page with the request token: - -```text -https://api.clever-cloud.com/v2/oauth/authorize?oauth_token= -``` - -The user logs into Clever Cloud (if not already) and is presented with a permissions form. Available permissions are: - -| Permission | Description | -| --------------------------------------------- | -------------------------------------------- | -| `access_organisations` | Access organisations | -| `access_organisations_bills` | Access organisations' bills | -| `access_organisations_consumption_statistics` | Access organisations' consumption statistics | -| `access_organisations_credit_count` | Access organisations' credit count | -| `access_personal_information` | Access personal information | -| `manage_organisations` | Manage organisations | -| `manage_organisations_applications` | Manage organisations' applications | -| `manage_organisations_members` | Manage organisations' members | -| `manage_organisations_services` | Manage organisations' add-ons | -| `manage_personal_information` | Manage personal information | -| `manage_ssh_keys` | Manage SSH keys | - -You can retrieve this list programmatically with `GET https://api.clever-cloud.com/v2/oauth/rights`. - -Once the user approves, the browser is redirected to your `oauth_callback` URL with the following **query string** parameters: - -| Parameter | Description | -| ---------------- | -------------------------------------------------- | -| `oauth_token` | The request token (must match the one from step 1) | -| `oauth_verifier` | Verification code to exchange for an access token | - -##### Exchange for an access token - -Exchange the request token and verifier for an access token. As with step 1, parameters can be sent as query string or form body: - -- `POST https://api.clever-cloud.com/v2/oauth/access_token_query` — parameters as query string -- `POST https://api.clever-cloud.com/v2/oauth/access_token` — parameters as `application/x-www-form-urlencoded` body - -**Required parameters:** - -| Parameter | Description | -| ------------------------ | -------------------------------------------------------------------- | -| `oauth_consumer_key` | Your consumer key | -| `oauth_signature_method` | Same method as step 1 | -| `oauth_signature` | Request signature (signed with the request token secret from step 1) | -| `oauth_timestamp` | Current Unix timestamp (seconds) | -| `oauth_nonce` | Unique random string | -| `oauth_version` | `1.0` | -| `oauth_token` | The request token from step 1 | -| `oauth_verifier` | The verifier from the callback redirect | - -**Response** (`application/x-www-form-urlencoded`) - -```text -oauth_token=&oauth_token_secret=&expiration_date= -``` - -Store both `oauth_token` and `oauth_token_secret` securely — you will need them to sign every subsequent API request. - -> [!NOTE] -> Access tokens expire after **3 months** by default. The response includes an `expiration_date` field (ISO 8601 format). - -{{% /steps %}} - -#### Making authenticated API requests - -Once you have the four credentials (consumer key, consumer secret, user token, user token secret), sign every API request using the `Authorization` header: - -```text -Authorization: OAuth oauth_consumer_key="", oauth_token="", oauth_signature_method="HMAC-SHA512", oauth_signature="", oauth_timestamp="", oauth_nonce="", oauth_version="1.0" -``` - -**Example** — Fetching the authenticated user's profile: - -```javascript -// buildBaseString, sign and authorizationHeader are defined in the "Signing requests" section -const params = { - oauth_consumer_key: CONSUMER_KEY, - oauth_signature_method: "HMAC-SHA512", - oauth_timestamp: Math.floor(Date.now() / 1000).toString(), - oauth_nonce: crypto.randomUUID().replace(/-/g, ""), - oauth_version: "1.0", - oauth_token: ACCESS_TOKEN, -}; - -const baseString = buildBaseString("GET", "https://api.clever-cloud.com/v2/self", params); -params.oauth_signature = sign(baseString, ACCESS_TOKEN_SECRET); - -const res = await fetch("https://api.clever-cloud.com/v2/self", { - headers: { Authorization: authorizationHeader(params) }, -}); -const user = await res.json(); -``` - -#### Signing requests - -Three signature methods are supported. `HMAC-SHA512` is recommended for production use. - -##### PLAINTEXT - -The simplest method. The signature is the consumer secret and token secret, percent-encoded per RFC 3986 and joined with `&`: - -```javascript -const signature = percentEncode(consumerSecret) + "&" + percentEncode(tokenSecret); -``` - -For the request token step (where no token secret exists yet), leave the second part empty: - -```javascript -const signature = percentEncode(consumerSecret) + "&"; -``` - -> [!NOTE] -> The `percentEncode` function is defined in the [HMAC section below](#hmac-sha1sha512). For secrets containing only alphanumeric characters, `encodeURIComponent` produces the same result. - -##### HMAC-SHA1/SHA512 - -These methods sign a **base string** to ensure the request has not been tampered with. The code snippets below are a JavaScript/Node.js implementation example. - -**1.** Define a `percentEncode` helper per RFC 3986: - -```javascript -// Like encodeURIComponent, but also encodes !'()* -function percentEncode(str) { - return encodeURIComponent(str) - .replace(/[!'()*]/g, c => "%" + c.charCodeAt(0).toString(16).toUpperCase()); -} -``` - -**2.** Define `buildBaseString` — it concatenates the HTTP method, URL, and sorted parameters, all percent-encoded and joined with `&`: - -```javascript -function buildBaseString(method, url, params) { - const sorted = Object.keys(params) - .filter(k => k !== "oauth_signature") - .sort() - .map(k => percentEncode(k) + "=" + percentEncode(params[k])) - .join("&"); - return method.toUpperCase() + "&" + percentEncode(url) + "&" + percentEncode(sorted); -} -``` - -The three components are: - -- The HTTP method in uppercase (`GET`, `POST`, etc.) -- The base URL (without query string), percent-encoded -- All request parameters (OAuth parameters excluding `oauth_signature`, plus any query string or form body parameters), sorted alphabetically by key — then by value in case of duplicates — formatted as `key=value` pairs joined by `&`, then percent-encoded as a single string - -**3.** Define `sign` — it computes an HMAC with the chosen algorithm and returns the base64-encoded result: - -```javascript -const { createHmac } = await import("node:crypto"); - -function sign(baseString, tokenSecret = "") { - const signingKey = percentEncode(consumerSecret) + "&" + percentEncode(tokenSecret); - return createHmac("sha512", signingKey).update(baseString).digest("base64"); -} -``` - -**4. Build the Authorization header** with all OAuth parameters (including the signature): - -```javascript -function authorizationHeader(params) { - const pairs = Object.entries(params) - .map(([k, v]) => percentEncode(k) + '="' + percentEncode(v) + '"') - .join(", "); - return "OAuth " + pairs; -} -``` diff --git a/content/changelog/2025/03-07-rust-sdk-0.13.md b/content/changelog/2025/03-07-rust-sdk-0.13.md index 2e34b64ff..df46a1e67 100644 --- a/content/changelog/2025/03-07-rust-sdk-0.13.md +++ b/content/changelog/2025/03-07-rust-sdk-0.13.md @@ -15,4 +15,4 @@ description: New Auth solutions for your Rust applications excludeSearch: true --- -[Rust SDK v0.13](https://github.com/CleverCloud/clevercloud-sdk-rust/releases/tag/v0.13.1) is available, uses Rust 1.85 and can now use [API tokens](/api/howto/) or get credentials from [Clever Tools](https://github.com/CleverCloud/clever-tools/) configuration file if present in the system. +[Rust SDK v0.13](https://github.com/CleverCloud/clevercloud-sdk-rust/releases/tag/v0.13.1) is available, uses Rust 1.85 and can now use [API tokens](/api/) or get credentials from [Clever Tools](https://github.com/CleverCloud/clever-tools/) configuration file if present in the system. diff --git a/content/changelog/2025/05-28-oauth-consumer-new-interface.md b/content/changelog/2025/05-28-oauth-consumer-new-interface.md index 74045e3f5..d396db259 100644 --- a/content/changelog/2025/05-28-oauth-consumer-new-interface.md +++ b/content/changelog/2025/05-28-oauth-consumer-new-interface.md @@ -17,6 +17,6 @@ excludeSearch: true A new interface is available [in Clever Cloud Console to create](https://console.clever-cloud.com/users/me/oauth-consumers/new) and manage OAuth consumers. It's better, clearer, simpler, and uses our open source [web components](https://clever.cloud/developers/clever-components/). -- [Learn more about OAuth consumers](/api/howto/#oauth1) +- [Learn more about OAuth consumers](/api/#oauth1) ![New OAuth consumers interface](/images/new-oauth-consumer.webp) diff --git a/content/changelog/2025/06-05-api-tokens-console-tips.md b/content/changelog/2025/06-05-api-tokens-console-tips.md index 6bc6d22c6..f98a7ccd0 100644 --- a/content/changelog/2025/06-05-api-tokens-console-tips.md +++ b/content/changelog/2025/06-05-api-tokens-console-tips.md @@ -15,7 +15,7 @@ description: API tokens and tips everywhere! excludeSearch: true --- -With [Clever Tools 3.12](/changelog/2025/03-07-clever-tools-3.12/), we've introduced a new way to query Clever Cloud's API, with [the API bridge and API tokens](/api/howto/#api-tokens). Starting today, you can create, edit and revoke API tokens directly [from your Clever Cloud profile page](https://console.clever-cloud.com/users/me/api-tokens). +With [Clever Tools 3.12](/changelog/2025/03-07-clever-tools-3.12/), we've introduced a new way to query Clever Cloud's API, with [the API bridge and API tokens](/api/#api-tokens). Starting today, you can create, edit and revoke API tokens directly [from your Clever Cloud profile page](https://console.clever-cloud.com/users/me/api-tokens). ## API tokens in the Clever Cloud Console diff --git a/content/changelog/2025/06-05-oauth-tokens-new-interface.md b/content/changelog/2025/06-05-oauth-tokens-new-interface.md index fc3db4d7e..736fb6f20 100644 --- a/content/changelog/2025/06-05-oauth-tokens-new-interface.md +++ b/content/changelog/2025/06-05-oauth-tokens-new-interface.md @@ -19,6 +19,6 @@ After [renewing OAuth consumers management](/changelog/2025/05-28-oauth-consumer We also added a link to Clever Cloud's OAuth tokens documentation. -- [Learn more about OAuth tokens](/api/howto/#oauth1) +- [Learn more about OAuth tokens](/api/#oauth1) ![New OAuth tokens interface](/images/console-new-oauth-tokens.webp) diff --git a/content/changelog/2026/04-09-clever-tools-4.8.md b/content/changelog/2026/04-09-clever-tools-4.8.md index e29d9a55a..723ad8414 100644 --- a/content/changelog/2026/04-09-clever-tools-4.8.md +++ b/content/changelog/2026/04-09-clever-tools-4.8.md @@ -19,7 +19,7 @@ excludeSearch: true ## OAuth consumers management -You can now create and manage [OAuth consumers](/api/howto/#create-an-oauth-consumer) directly from the CLI. The new `clever oauth-consumers` command set covers the full lifecycle: list, create, get details, update, open in the Console and delete. Consumers can be referenced by name (when unambiguous) or by their consumer key, and the `get` command supports a `--with-secret` flag when you need to retrieve the consumer secret for application configuration. +You can now create and manage [OAuth consumers](/api/#create-an-oauth-consumer) directly from the CLI. The new `clever oauth-consumers` command set covers the full lifecycle: list, create, get details, update, open in the Console and delete. Consumers can be referenced by name (when unambiguous) or by their consumer key, and the `get` command supports a `--with-secret` flag when you need to retrieve the consumer secret for application configuration. ```bash # List OAuth consumers @@ -47,7 +47,7 @@ clever oauth-consumers delete my-app --yes These commands target the current profile's organisation by default. The `create` command accepts the `--org` option to specify the consumer's organisation. For other commands, the consumer key is enough to identify the resource. -- [Learn more about OAuth consumers](/api/howto/#create-an-oauth-consumer) +- [Learn more about OAuth consumers](/api/#create-an-oauth-consumer) ## Drains on add-ons diff --git a/content/doc/kubernetes/operator.md b/content/doc/kubernetes/operator.md index da1a35460..2524b0df7 100644 --- a/content/doc/kubernetes/operator.md +++ b/content/doc/kubernetes/operator.md @@ -82,7 +82,7 @@ Before you begin, ensure that you have the following tools and resources based o - **Kubernetes Cluster:** Ensure you have access to a running Kubernetes cluster. - **Kubectl:** Install Kubernetes command-line tool for managing cluster resources Installation guide available at . -- **Clever Cloud Account Credentials:** [Obtain API tokens and secrets from your Clever Cloud](/api/howto) account to configure the operator. +- **Clever Cloud Account Credentials:** [Obtain API tokens and secrets from your Clever Cloud](/api/) account to configure the operator. These prerequisites are essential for getting started with the Clever Kubernetes Operator, whether you're contributing to its development or deploying it in production. @@ -99,7 +99,7 @@ This is the most complete authentication method, requiring all four OAuth1 param - _Token_ - _Secret_ -To obtain these credentials, you need to connect to the Clever Cloud API, which uses OAuth1-based authentication. As explained in the [Clever Cloud API Overview](/api/howto), you need to create an OAuth consumer token in the Clever Cloud console, use it to obtain the _Consumer key_ and the _Consumer Secret_, and complete the OAuth authentication process to get the _Token_ and _Secret_. +To obtain these credentials, you need to connect to the Clever Cloud API, which uses OAuth1-based authentication. As explained in the [Clever Cloud API Overview](/api/), you need to create an OAuth consumer token in the Clever Cloud console, use it to obtain the _Consumer key_ and the _Consumer Secret_, and complete the OAuth authentication process to get the _Token_ and _Secret_. Configuration example: diff --git a/hugo.yaml b/hugo.yaml index 7ab573b17..2f93ae061 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -48,7 +48,7 @@ menu: weight: 3 - name: "How to use" parent: api - url: "/api/howto" + url: "/api/" - name: "v2 endpoints" parent: api url: "/api/v2" From 7901b306de81c965a42815f373f1083b643ecbd2 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 09:13:40 +0200 Subject: [PATCH 15/73] find-help: merge support into the index and restructure the FAQ --- content/doc/find-help/_index.md | 40 ++++- content/doc/find-help/faq.md | 219 ++++++++++++++--------- content/doc/find-help/support.md | 42 ----- content/doc/find-help/troubleshooting.md | 4 +- shared/ask-for-help.md | 1 + shared/more-config.md | 2 +- 6 files changed, 176 insertions(+), 132 deletions(-) delete mode 100644 content/doc/find-help/support.md create mode 100644 shared/ask-for-help.md diff --git a/content/doc/find-help/_index.md b/content/doc/find-help/_index.md index d122b8fd6..20850a529 100644 --- a/content/doc/find-help/_index.md +++ b/content/doc/find-help/_index.md @@ -11,12 +11,46 @@ keywords: - troubleshooting - resources - assistance +- technical assistance +- email support +- ticket center aliases: - /doc/administrate/find-help +- /doc/find-help/support +- /doc/get-help/support +- /doc/support +- /support --- +The base offer includes support at no extra cost, operated by Clever Cloud's own teams in France, even those who are not paying customers. + +## Ticket Center + +You can find in the console a button to start a conversation with our engineers. For each new ticket it will create a new thread, on a specific subject. Therefore, you can create several tickets for each issue. + +If you open a ticket inside an organisation with members, they will be added to the discussion by email. + +Feel free to use it when this service is available, from 9 a.m to 6 p.m CEST+2 during open business days. + +- [Access Clever Cloud Ticket Center](https://console.clever-cloud.com/ticket-center-choice) + +## Email + +Seek help by querying us by email, allowing you to quickly gain answers to your Clever Cloud specific questions and open a ticket directly with our support staff. We will respond to your email within a few hours, or two business days in the worst case. + +- + +## Critical application support + +Clever Cloud offers a premium support option providing 24/7 a direct line to our team of support engineers. Our team’s focus is investigating and solving new problems, getting feedback on the service and working hard to improve the core service. + +Get more information and contact our sales team at: + +- + +## Learn more + {{< cards >}} - {{< card link="/developers/doc/find-help/faq" title="FAQ" icon="question-mark-circle" >}} - {{< card link="/developers/doc/find-help/support" title="Support" icon="lifebuoy" >}} - {{< card link="/developers/doc/find-help/troubleshooting" title="Troubleshooting" icon="magnifying-glass" >}} + {{< card link="/developers/doc/find-help/faq" title="FAQ" subtitle="Find answers to the most common questions" icon="question-mark-circle" >}} + {{< card link="/developers/doc/find-help/troubleshooting" title="Troubleshooting" subtitle="Diagnose and fix common deployment issues" icon="magnifying-glass" >}} {{< /cards >}} diff --git a/content/doc/find-help/faq.md b/content/doc/find-help/faq.md index 2a6a19594..86676b697 100644 --- a/content/doc/find-help/faq.md +++ b/content/doc/find-help/faq.md @@ -14,7 +14,15 @@ aliases: - /doc/get-help/faq --- -## What is a Scaler? +{{< hextra/hero-subtitle style="margin:.3rem 0 2rem 0">}} + Answers to the questions asked most often about the platform, from scalers and supported runtimes to domains, security, add-ons and backups. If you're facing a specific error message, start with the [troubleshooting page](/doc/find-help/troubleshooting). +{{< /hextra/hero-subtitle >}} + +{{% content "ask-for-help" %}} + +## Platform and plans + +{{% details title="What is a Scaler?" closed="true" %}} A _scaler_ is an individual instance hosting your application. You can allocate one or more scalers to each application. Available flavors are `pico`, `nano`, `XS`, `S`, `M`, `L`, `XL`, `2XL` and `3XL`, depending on the runtime. @@ -25,8 +33,9 @@ When enabling auto-scalability, you have to set a minimum and a maximum of activ {{< callout type="warning" >}} Nano and pico instances operate with **reduced CPU priority** on the host system. As a result, during periods of high load on the hypervisor, these instances may experience performance degradation (since they yield processing power to higher-priority workloads). {{< /callout >}} +{{% /details %}} -## Which application runtimes are supported by Clever Cloud? +{{% details title="Which application runtimes are supported by Clever Cloud?" closed="true" %}} Currently, Clever Cloud supports: @@ -48,89 +57,55 @@ Currently, Clever Cloud supports: - V (Vlang) See the full list in the [applications documentation](/doc/applications/), or browse the [guides](/guides/) for frameworks and services you can deploy on Clever Cloud. +{{% /details %}} -## How many applications can I create? +{{% details title="How many applications can I create?" closed="true" %}} As many as you want. We've not set a limited number of apps by developer. +{{% /details %}} -## How to setup domain names I own? - -You can bind custom domain names to your applications. Please have a look at [Custom Domain Names](/doc/administrate/domain-names). - -## How can I disable one of my existing applications? - -Log in with your account to [console.clever-cloud.com](https://console.clever-cloud.com), and select the appropriate organisation and app in the left column. Then click on the application name and select **Overview**. Click on the **Stop** button to stop your app. - -## What type of content can I deploy? +{{% details title="What type of content can I deploy?" closed="true" %}} Please refer to the Acceptable Use Policy, article 2, [_Reasonable use of the Platform_](https://www.clever.cloud/acceptable-use-policy/). +{{% /details %}} -## How do I add or remove members in my organisations? - -Log in with your account to [console.clever-cloud.com](https://console.clever-cloud.com), and select the appropriate organisation in the left panel. Then click on **Members** in the mid pane. You'll see a list of the organisation's members. If your are an admin, you can revoke or grant permissions. - -## How do I report an application that infringes your Terms and Conditions? +{{% details title="Where are my applications and add-ons located?" closed="true" %}} -To report an application that infringes Clever Cloud's Terms and Conditions, please contact the legal team at . +Applications and add-ons are deployed in multiple regions across Europe, North America and Asia-Pacific, including Paris, Roubaix, Gravelines, London, Warsaw, Montreal, Singapore and Sydney, plus HDS-certified zones in France for healthcare data. When creating an application or an add-on, you can choose among the deployment zones available for that product. -We will investigate and contact the application's owner over the violation if needed. +Clever Cloud is based in Nantes, France. +{{% /details %}} -## Does Clever Cloud support TLS/SSL (HTTPS)? +{{% details title="I want to run Kubernetes on top of Clever Cloud, is that possible?" closed="true" %}} -Yes. For testing purposes, `cleverapps.io` domains support TLS out of the box. For custom SSL certificates, you can either generate one automatically with Let's Encrypt while adding a domain, or [use an existing one](/doc/administrate/ssl/#uploading-my-own-certificates). -Have a look at [installing TLS certificates](/doc/administrate/ssl), and feel free to contact the support team in the [Ticket Center](https://console.clever-cloud.com/ticket-center-choice) if you have questions. +Yes. [Clever Kubernetes Engine](/doc/kubernetes/) (CKE), currently in public beta, provides a managed Kubernetes control plane. See the [product page](https://www.clever.cloud/product/kubernetes/) for more information. +{{% /details %}} -## What are the supported ciphers ? +{{% details title="I want to use Clever Cloud on my own premises, is that possible?" closed="true" %}} -As this information can change over time with security updates, here's the nmap command to look up SSL/TLS ciphers on a Clever Cloud configured domain: +Yes, since 2016 Clever Cloud is packaged for private data center. This offer called "Clever Cloud On Premises" is available upon request: you can send a mail to [sales@clever-cloud.com](mailto:sales@clever-cloud.com) or visit [https://www.clever.cloud/on-premises](https://www.clever.cloud/on-premises) for more info. +{{% /details %}} -```shell -nmap --script ssl-enum-ciphers -p 443 example.com -``` +## Applications and deployments -## I'd like to have two applications available on the same domain name +{{% details title="How can I disable one of my existing applications?" closed="true" %}} -Refer to [prefix routing](/doc/administrate/domain-names/#prefix-routing) to learn how to have two applications share a domain name. +Log in with your account to [console.clever-cloud.com](https://console.clever-cloud.com), and select the appropriate organisation and app in the left column. Then click on the application name and select **Overview**. Click on the **Stop** button to stop your app. +{{% /details %}} -## How do I define cron jobs for my application? +{{% details title="How do I define cron jobs for my application?" closed="true" %}} See [Cron Configuration File](/doc/administrate/cron) for more information. +{{% /details %}} -## How to know if a user comes from a secure connection? - -Load-balancers handles all connections ahead of your applications and forward them in plain HTTP, you can't rely on the server port to know the scheme used by the user. - -Instead, you can use the `X-Forwarded-Proto` HTTP header to get the information, it's set to either '_http_' or '_https_'. - -{{< callout type="info" >}} -In order to use `request.secure` instead of using the header, you must add `XForwardedSupport=all` in your `application.conf`. -{{< /callout >}} - -{{< callout type="warning" >}} -In order to use `request.secure` instead of accessing the header, you must add `trustxforwarded=true` in your `application.conf`. -{{< /callout >}} - -## PHP: `$_SERVER` auth variables are always empty, how do I make this work? - -- [Learn more about the $_SERVER variable on Clever Cloud](/doc/applications/php/apache/#using-http-authentication) - -## How to get the user's IP address? - -Load-balancers ahead of your applications handle all connections and forward them in plain HTTP. -So if you get the `REMOTE_ADDR` or `Client-IP` header, you get only the IP of the load balancer that forwarded the user request. - -To get the original client's IP address, use the `X-Forwarded-For` HTTP header. The load balancer automatically adds this header to each request. - -The `X-Forwarded-For` header contains a comma-separated list of IP addresses. The first address in this list is your end user's original IP address. Any subsequent addresses represent the proxies that the request passed through before reaching your application. -[Read the Wikipedia page for more details](https://en.wikipedia.org/wiki/X-Forwarded-For). - -## How do I identify different instances of my application? +{{% details title="How do I identify different instances of my application?" closed="true" %}} If your application needs to differentiate all the running nodes internally, you can use the `INSTANCE_NUMBER` environment variable. For example, if 3 instances are running for your application, this environment variable will contain `0` on the first, `1` on the second and `2` on the third. +{{% /details %}} -## I need a private ssh key to fetch my private dependencies. How do I do that? +{{% details title="I need a private ssh key to fetch my private dependencies. How do I do that?" closed="true" %}} If your company manages its own artifacts in a private repository (like, you can only access them via git+ssh or sFTP), and you need a private key to connect to the server, you @@ -138,8 +113,9 @@ can commit them in your application's Clever Cloud repository and then add a `clevercloud/ssh.json` file. - [Learn more about ssh.json](/doc/reference/common-configuration/#private-ssh-key) +{{% /details %}} -## I get a `java.lang.UnsupportedClassVersionError: Unsupported major.minor version` error. How can I fix it? +{{% details title="I get a `java.lang.UnsupportedClassVersionError: Unsupported major.minor version` error. How can I fix it?" closed="true" %}} If you get this error on a Java (or any JVM language) application, it means that your application was compiled with a newer Java version than the one used to run it. @@ -161,43 +137,111 @@ For reference, the table below lists the class file version for each major Java | 17 | 61.0 | | 21 | 65.0 | -## I want SSH access to my server +{{% /details %}} + +{{% details title="I want SSH access to my server" closed="true" %}} Clever Cloud does not give you access to a server or a VPS, it makes your application run. Each instance is started and configured automatically, and can be stopped at any moment. If however, you still need SSH access for debugging purposes, please have a look at [SSH access](/doc/cli/applications/deployment-lifecycle/#ssh), but keep in mind that changes made on an instance are not persistent across deployments. +{{% /details %}} -## I want to use Clever Cloud on my own premises, is that possible? +{{% details title="Can I `scp` something in a VM?" closed="true" %}} -Yes, since 2016 Clever Cloud is packaged for private data center. This offer called "Clever Cloud On Premises" is available upon request: you can send a mail to [sales@clever-cloud.com](mailto:sales@clever-cloud.com) or visit [https://www.clever.cloud/on-premises](https://www.clever.cloud/on-premises) for more info. +You cannot `scp` something to the VM, you can however easily `scp` something from the VM to the outside. +{{% /details %}} -## Where are my applications and add-ons located? +{{% details title="I need to convert something to PDF with `wkhtmltopdf`" closed="true" %}} -Applications and add-ons are deployed in multiple regions across Europe, North America and Asia-Pacific, including Paris, Roubaix, Gravelines, London, Warsaw, Montreal, Singapore and Sydney, plus HDS-certified zones in France for healthcare data. When creating an application or an add-on, you can choose among the deployment zones available for that product. +`wkhtmltopdf` is available and fully functional but we deeply recommend to use `chromium headless` instead. +{{% /details %}} -Clever Cloud is based in Nantes, France. +{{% details title="What is the timezone used by my application/add-on?" closed="true" %}} -## I want to run Kubernetes on top of Clever Cloud, is that possible? +All instances on Clever Cloud run on the UTC timezone. We recommend to handle all your dates in UTC internally, and only handle timezones when reading or displaying dates. +{{% /details %}} -Yes. [Clever Kubernetes Engine](/doc/kubernetes/) (CKE), currently in public beta, provides a managed Kubernetes control plane. See the [product page](https://www.clever.cloud/product/kubernetes/) for more information. +## Domains, network and security -## How to setup a firewall on Clever Cloud? +{{% details title="How to setup domain names I own?" closed="true" %}} + +You can bind custom domain names to your applications. Please have a look at [Custom Domain Names](/doc/administrate/domain-names). +{{% /details %}} + +{{% details title="I'd like to have two applications available on the same domain name" closed="true" %}} + +Refer to [prefix routing](/doc/administrate/domain-names/#prefix-routing) to learn how to have two applications share a domain name. +{{% /details %}} + +{{% details title="Does Clever Cloud support TLS/SSL (HTTPS)?" closed="true" %}} + +Yes. For testing purposes, `cleverapps.io` domains support TLS out of the box. For custom SSL certificates, you can either generate one automatically with Let's Encrypt while adding a domain, or [use an existing one](/doc/administrate/ssl/#uploading-my-own-certificates). +Have a look at [installing TLS certificates](/doc/administrate/ssl), and feel free to contact the support team in the [Ticket Center](https://console.clever-cloud.com/ticket-center-choice) if you have questions. +{{% /details %}} + +{{% details title="What are the supported ciphers?" closed="true" %}} + +As this information can change over time with security updates, here's the nmap command to look up SSL/TLS ciphers on a Clever Cloud configured domain: + +```shell +nmap --script ssl-enum-ciphers -p 443 example.com +``` + +{{% /details %}} + +{{% details title="How to know if a user comes from a secure connection?" closed="true" %}} + +Load-balancers handles all connections ahead of your applications and forward them in plain HTTP, you can't rely on the server port to know the scheme used by the user. + +Instead, you can use the `X-Forwarded-Proto` HTTP header to get the information, it's set to either '_http_' or '_https_'. + +{{< callout type="info" >}} +In order to use `request.secure` instead of using the header, you must add `XForwardedSupport=all` in your `application.conf`. +{{< /callout >}} + +{{< callout type="warning" >}} +In order to use `request.secure` instead of accessing the header, you must add `trustxforwarded=true` in your `application.conf`. +{{< /callout >}} +{{% /details %}} + +{{% details title="PHP: `$_SERVER` auth variables are always empty, how do I make this work?" closed="true" %}} + +- [Learn more about the $_SERVER variable on Clever Cloud](/doc/applications/php/apache/#using-http-authentication) +{{% /details %}} + +{{% details title="How to get the user's IP address?" closed="true" %}} + +Load-balancers ahead of your applications handle all connections and forward them in plain HTTP. +So if you get the `REMOTE_ADDR` or `Client-IP` header, you get only the IP of the load balancer that forwarded the user request. + +To get the original client's IP address, use the `X-Forwarded-For` HTTP header. The load balancer automatically adds this header to each request. + +The `X-Forwarded-For` header contains a comma-separated list of IP addresses. The first address in this list is your end user's original IP address. Any subsequent addresses represent the proxies that the request passed through before reaching your application. +[Read the Wikipedia page for more details](https://en.wikipedia.org/wiki/X-Forwarded-For). +{{% /details %}} + +{{% details title="How to setup a firewall on Clever Cloud?" closed="true" %}} Specific firewall rules can be enabled on demand to the support or in case of attack. +{{% /details %}} -## Can I `scp` something in a VM +{{% details title="I get unknown regular requests, is there a problem?" closed="true" %}} -You cannot `scp` something to the VM, you can however easily `scp` something from the VM to the outside. +The platform performs routine health checks to applications every 2 minutes. You may notice these periodic HTTP requests in your logs, with `X-Clevercloud-Monitoring` header. They're part of Clever Cloud's standard monitoring process. +{{% /details %}} -## I need to convert something to PDF with `wkhtmltopdf` +## Add-ons and data -`wkhtmltopdf` is available and fully functional but we deeply recommend to use `chromium headless` instead. +{{% details title="What is a DEV plan?" closed="true" %}} -## What is the timezone used by my application/add-on? +DEV plan is a free-tier plan available for some databases, designed to let customers explore and test these products. They operate on shared clusters, which may result in variable performance; they also have no backups nor SLA guarantees. -All instances on Clever Cloud run on the UTC timezone. We recommend to handle all your dates in UTC internally, and only handle timezones when reading or displaying dates. +Some features such as extensions, simultaneous connections numbers, functions… might be reduced or unavailable. + +Support is not able to provide help in case of DEV plan. +{{% /details %}} -## I received an email saying "Add-on [my add-on] disk is nearly full". What do I do? +{{% details title="I received an email saying 'Add-on [my add-on] disk is nearly full'. What do I do?" closed="true" %}} A full disk can cause your database to crash or become unresponsive. Consider upgrading your add-on plan. @@ -214,26 +258,31 @@ Then you can remove records from your database, re-index your tables and try to You can buy more disk space by migrating your add-on to a higher plan. If a VACUUM operation needs more disk that there is remaining, migrating to the same plan cleans up the file on disk and regains space. +{{% /details %}} -## Where are the backups stored? +{{% details title="Where are the backups stored?" closed="true" %}} Clever Cloud stores all backups on [Cellar](https://www.clever.cloud/product/cellar-object-storage/), a replicated object storage service with three copies distributed across datacenters in the PAR region to ensure durability. Even if one datacenter fails, your backups remain safe. For custom configurations (for example, multiple retention policies), contact Support. To locate backups not visible in the Console, use [Clever Tools](https://github.com/CleverCloud/clever-tools) with: `clever database backups DATABASE-ID [--format, -F] FORMAT`. Find more [documentation on restoring backups with the CLI](/doc/cli/addons/#database-backups). +{{% /details %}} -## I can't create my add-on +{{% details title="I can't create my add-on" closed="true" %}} To create add-ons, you need to complete your account information, including your city and ZIP code. For instance, you cannot create a Matomo add-on until you provide these details. +{{% /details %}} -## I get unknown regular requests, is there a problem ? +## Account and organisations -The platform performs routine health checks to applications every 2 minutes. You may notice these periodic HTTP requests in your logs, with `X-Clevercloud-Monitoring` header. They're part of Clever Cloud's standard monitoring process. +{{% details title="How do I add or remove members in my organisations?" closed="true" %}} -## What is a DEV plan ? +Log in with your account to [console.clever-cloud.com](https://console.clever-cloud.com), and select the appropriate organisation in the left panel. Then click on **Members** in the mid pane. You'll see a list of the organisation's members. If your are an admin, you can revoke or grant permissions. +{{% /details %}} -DEV plan is a free-tier plan available for some databases, designed to let customers explore and test these products. They operate on shared clusters, which may result in variable performance; they also have no backups nor SLA guarantees. +{{% details title="How do I report an application that infringes your Terms and Conditions?" closed="true" %}} -Some features such as extensions, simultaneous connections numbers, functions… might be reduced or unavailable. +To report an application that infringes Clever Cloud's Terms and Conditions, please contact the legal team at . -Support is not able to provide help in case of DEV plan. +We will investigate and contact the application's owner over the violation if needed. +{{% /details %}} diff --git a/content/doc/find-help/support.md b/content/doc/find-help/support.md deleted file mode 100644 index 54409b27d..000000000 --- a/content/doc/find-help/support.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -type: docs -weight: 7 -linkTitle: Support -title: Support -description: Learn how to contact Clever Cloud support through email or ticket center for technical assistance, available during business hours -keywords: -- support -- technical assistance -- email support -- ticket center -- clever cloud help -- customer service -aliases: -- /doc/get-help/support -- /doc/support -- /support ---- - -We provide basic support free-of-charge to all our users, even those who are not paying customers. - -## Email - -Seek help by querying us by email, allowing you to quickly gain answers to your Clever Cloud specific questions and open a ticket directly with our support staff. We will respond to your email within a few hours, or two business days in the worst case. - -- - -## Ticket Center - -You can find in the console a button to [start a conversation](https://console.clever-cloud.com/ticket-center-choice) with our engineers. For each new ticket it will create a new thread, on a specific subject. Therefore, you can create several tickets for each issue. - -If you open a ticket inside an organisation with members, they will be added to the discussion by e-mail. - -Feel free to use it when this service available, from 9 a.m to 6 p.m CEST+2 during open business days. - -## Critical application support - -Clever Cloud offers a premium support option providing 24/7 a direct line to our team of support engineers. Our team’s focus is investigating and solving new problems, getting feedback on the service and working hard to improve the core service. - -Get more information and contact our sales team at: - -- diff --git a/content/doc/find-help/troubleshooting.md b/content/doc/find-help/troubleshooting.md index 7dc8019d5..78f375024 100644 --- a/content/doc/find-help/troubleshooting.md +++ b/content/doc/find-help/troubleshooting.md @@ -15,9 +15,11 @@ aliases: --- {{< hextra/hero-subtitle style="margin:.3rem 0 2rem 0">}} - If you're having trouble deploying applications or with with git, this section is for you. From git issues to configuration errors, problems can arise at different stages of your deployments. + If you're having trouble deploying applications or with git, this section is for you. From git issues to configuration errors, problems can arise at different stages of your deployments. For general questions about the platform, see the [FAQ](/doc/find-help/faq). {{< /hextra/hero-subtitle >}} +{{% content "ask-for-help" %}} + ## Git-related issues {{% details title="Some files disappear after an application restart" closed="true" %}} diff --git a/shared/ask-for-help.md b/shared/ask-for-help.md new file mode 100644 index 000000000..50224262d --- /dev/null +++ b/shared/ask-for-help.md @@ -0,0 +1 @@ +Can't find what you're looking for? Contact the [support team](/doc/find-help/), or [open an issue](https://github.com/CleverCloud/documentation/issues) to suggest an addition to this page. diff --git a/shared/more-config.md b/shared/more-config.md index e1fa63df6..7143ba58d 100644 --- a/shared/more-config.md +++ b/shared/more-config.md @@ -6,4 +6,4 @@ Go check the [Common configuration page](/doc/reference/common-configuration). You may want to have an advanced usage of your application, in which case we recommend you to read the **Administrate** documentation section. -If you can't find something or have a specific need like using a non supported version of a particular software, please reach out to the [support](/doc/find-help/support). +If you can't find something or have a specific need like using a non supported version of a particular software, please reach out to the [support](/doc/find-help/). From 9b26b8e1bbb4114b46a55537dedeab949bbdf8eb Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 09:13:59 +0200 Subject: [PATCH 16/73] doc: reorder the sidebar and give each page a distinct weight --- content/doc/account/_index.md | 2 +- content/doc/addons/_index.md | 2 +- content/doc/administrate/_index.md | 2 +- content/doc/applications/_index.md | 2 +- content/doc/best-practices/_index.md | 2 +- content/doc/billing/_index.md | 2 +- content/doc/ci-cd/_index.md | 2 +- content/doc/cli/_index.md | 2 +- content/doc/contribute.md | 2 +- content/doc/develop/_index.md | 2 +- content/doc/find-help/_index.md | 2 +- content/doc/functions/_index.md | 2 +- content/doc/kubernetes/_index.md | 2 +- content/doc/marketplace.md | 2 +- content/doc/metrics/_index.md | 2 +- content/doc/reference/_index.md | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/content/doc/account/_index.md b/content/doc/account/_index.md index 46a66dad8..f5082dfd1 100644 --- a/content/doc/account/_index.md +++ b/content/doc/account/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 11 +weight: 14 linkTitle: User Account title: User Account description: Learn how to manage your account on Clever Cloud. Discover detailed instructions for account creation, organisation administration in our PaaS platform. diff --git a/content/doc/addons/_index.md b/content/doc/addons/_index.md index 901834b8e..ac5505aae 100644 --- a/content/doc/addons/_index.md +++ b/content/doc/addons/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 3 +weight: 4 linkTitle: Add-ons title: Add-ons description: Discover and configure add-ons on Clever Cloud including databases, storage services, and managed tools for your applications diff --git a/content/doc/administrate/_index.md b/content/doc/administrate/_index.md index be3531369..c1ea9820a 100644 --- a/content/doc/administrate/_index.md +++ b/content/doc/administrate/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 5 +weight: 8 linkTitle: Administrate title: Administrate description: Manage and administrate your Clever Cloud applications including scaling, monitoring, SSL configuration, and platform operations diff --git a/content/doc/applications/_index.md b/content/doc/applications/_index.md index 26f5c42b9..1fbda2588 100644 --- a/content/doc/applications/_index.md +++ b/content/doc/applications/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 2 +weight: 3 linkTitle: Applications title: Applications description: Deploy applications on Clever Cloud with support for popular languages, frameworks, and deployment configurations across modern runtimes diff --git a/content/doc/best-practices/_index.md b/content/doc/best-practices/_index.md index c4955a8a9..17d3fbcad 100644 --- a/content/doc/best-practices/_index.md +++ b/content/doc/best-practices/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 9 +weight: 11 linkTitle: Best practices title: Best practices description: Learn best practices for deploying and managing applications on Clever Cloud including security, performance, and scalability tips diff --git a/content/doc/billing/_index.md b/content/doc/billing/_index.md index 2b886776a..fb1d5bd03 100644 --- a/content/doc/billing/_index.md +++ b/content/doc/billing/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 12 +weight: 15 linkTitle: Billing title: Billing description: Manage billing and payment information for your Clever Cloud account including invoices, consumption tracking, and pricing details diff --git a/content/doc/ci-cd/_index.md b/content/doc/ci-cd/_index.md index 5883fe8b8..8c2f21c0c 100644 --- a/content/doc/ci-cd/_index.md +++ b/content/doc/ci-cd/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 9 +weight: 12 linkTitle: CI/CD title: CI/CD description: Deploy to Clever Cloud from GitLab or GitHub with complete setup and configuration, configuration options, and deployment best practices diff --git a/content/doc/cli/_index.md b/content/doc/cli/_index.md index c97f6ee39..9fabcb610 100644 --- a/content/doc/cli/_index.md +++ b/content/doc/cli/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 8 +weight: 10 linkTitle: Clever Tools (CLI) title: Clever Tools (CLI) description: Use Clever Tools CLI to manage applications, add-ons, and deployments from the command line with powerful automation and monitoring features diff --git a/content/doc/contribute.md b/content/doc/contribute.md index 555734b50..0def99fef 100644 --- a/content/doc/contribute.md +++ b/content/doc/contribute.md @@ -1,7 +1,7 @@ --- type: docs linkTitle: Contribute -weight: 14 +weight: 17 title: Contribute description: Learn how to contribute to Clever Cloud documentation including available shortcodes, writing guidelines, and submission process keywords: diff --git a/content/doc/develop/_index.md b/content/doc/develop/_index.md index c59fd4718..f79c3f468 100644 --- a/content/doc/develop/_index.md +++ b/content/doc/develop/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 6 +weight: 9 linkTitle: Develop title: Develop description: Development guides and best practices for building applications on Clever Cloud including environment variables, build hooks, and deployment strategies diff --git a/content/doc/find-help/_index.md b/content/doc/find-help/_index.md index 20850a529..5f4988d43 100644 --- a/content/doc/find-help/_index.md +++ b/content/doc/find-help/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 13 +weight: 2 linkTitle: Find Help title: Find Help description: Access support resources including professional support options, FAQ, and troubleshooting guides for Clever Cloud platform issues diff --git a/content/doc/functions/_index.md b/content/doc/functions/_index.md index af7f9a471..13f1e73e7 100644 --- a/content/doc/functions/_index.md +++ b/content/doc/functions/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 3 +weight: 5 linkTitle: Functions title: Functions (FaaS) description: Deploy serverless functions using any language that compiles to WebAssembly for automatic scaling and event-driven execution diff --git a/content/doc/kubernetes/_index.md b/content/doc/kubernetes/_index.md index 3520f359b..9b7341a5d 100644 --- a/content/doc/kubernetes/_index.md +++ b/content/doc/kubernetes/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 4 +weight: 6 linkTitle: Kubernetes title: Clever Kubernetes Engine (CKE) description: Create and manage Kubernetes clusters on Clever Cloud, with managed control plane, Materia etcd and vanilla Kubernetes experience diff --git a/content/doc/marketplace.md b/content/doc/marketplace.md index 65f701e7b..5cd8db040 100644 --- a/content/doc/marketplace.md +++ b/content/doc/marketplace.md @@ -1,7 +1,7 @@ --- type: docs linkTitle: Marketplace APIs & Tools -weight: 13 +weight: 16 title: Marketplace APIs & Tools description: Integrate your own service as an add-on on Clever Cloud marketplace with comprehensive developer tools and partnership opportunities keywords: diff --git a/content/doc/metrics/_index.md b/content/doc/metrics/_index.md index 8b13fcfec..2fe4f3914 100644 --- a/content/doc/metrics/_index.md +++ b/content/doc/metrics/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 4 +weight: 7 linkTitle: Metrics title: Metrics description: Learn to monitor application performance and resource usage on Clever Cloud with built-in metrics, dashboards, alerting, and analytics diff --git a/content/doc/reference/_index.md b/content/doc/reference/_index.md index 92ba39323..415af41df 100644 --- a/content/doc/reference/_index.md +++ b/content/doc/reference/_index.md @@ -1,6 +1,6 @@ --- type: docs -weight: 10 +weight: 13 linkTitle: Reference title: Reference description: Explore technical reference documentation for Clever Cloud including environment variables, API endpoints, and configuration options From cfd81e3493e5c5f19c61ed2c62a0c9f984533537 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 09:14:06 +0200 Subject: [PATCH 17/73] doc(getting-started): rename the quickstart page and update its labels --- content/_index.md | 2 +- content/doc/_index.md | 2 +- content/doc/account/ssh-keys-management.md | 2 +- content/doc/applications/frankenphp.md | 2 +- content/doc/applications/linux.md | 2 +- content/doc/applications/nodejs.md | 2 +- content/doc/applications/php/_index.md | 2 +- content/doc/applications/python/_index.md | 2 +- content/doc/applications/static.md | 2 +- content/doc/applications/v.md | 2 +- content/doc/best-practices/_index.md | 1 - content/doc/billing/_index.md | 1 - content/doc/{quickstart.md => getting-started.md} | 6 +++--- content/guides/hugo-static-s3.md | 4 ++-- content/guides/tutorial-laravel.md | 2 +- shared/create-application.md | 2 +- shared/deploy-ftp.md | 2 +- shared/deploy-git.md | 2 +- 18 files changed, 19 insertions(+), 21 deletions(-) rename content/doc/{quickstart.md => getting-started.md} (99%) diff --git a/content/_index.md b/content/_index.md index dae236a18..9ff1d24d7 100644 --- a/content/_index.md +++ b/content/_index.md @@ -29,7 +29,7 @@ aliases:

diff --git a/content/doc/_index.md b/content/doc/_index.md index 2bfb82022..713fa69b6 100644 --- a/content/doc/_index.md +++ b/content/doc/_index.md @@ -29,7 +29,7 @@ aliases: {{< /hextra/hero-subtitle >}} {{< cards >}} - {{< card link="/developers/doc/quickstart" title="Getting started" subtitle="Deploy an application in five minutes" icon="arrow-circle-right" >}} + {{< card link="/developers/doc/getting-started" title="Getting started" subtitle="Deploy an application in five minutes" icon="arrow-circle-right" >}} {{< card link="/developers/doc/applications" title="Applications" subtitle="Deploy applications with supported runtimes" icon="rocket-launch" >}} {{< card link="/developers/doc/addons" title="Add-ons" subtitle="Connect managed databases, storage and services" icon="plug" >}} {{< card link="/developers/doc/functions" title="Functions" subtitle="Deploy serverless functions compiled to WebAssembly" icon="code-bracket" >}} diff --git a/content/doc/account/ssh-keys-management.md b/content/doc/account/ssh-keys-management.md index d8177a0ac..eb55dc3ed 100644 --- a/content/doc/account/ssh-keys-management.md +++ b/content/doc/account/ssh-keys-management.md @@ -135,7 +135,7 @@ Add the key by entering a name and the public SSH key. The key is the entire con Your public SSH key must be associated with only one account. {{< /callout >}} -If you see "*access denied*" or "*password:*" when you [push on Clever Cloud](/doc/quickstart/#choose-how-to-deploy), your SSH keys may be invalid or not available on Clever Cloud. Please check that you SSH key is present and valid in your profile. +If you see "*access denied*" or "*password:*" when you [push on Clever Cloud](/doc/getting-started/#choose-how-to-deploy), your SSH keys may be invalid or not available on Clever Cloud. Please check that you SSH key is present and valid in your profile. ### Through CC API or Clever cURL diff --git a/content/doc/applications/frankenphp.md b/content/doc/applications/frankenphp.md index d98c04e83..14ab9fcbc 100644 --- a/content/doc/applications/frankenphp.md +++ b/content/doc/applications/frankenphp.md @@ -34,7 +34,7 @@ clever create --type frankenphp ``` - [Learn more about Clever Tools](/doc/cli/) -- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) +- [Learn more about Clever Cloud application deployment](/doc/getting-started/#create-an-application-step-by-step) > [!NOTE] FrankenPHP applications can't be deployed on a pico instance, XS is the default instance type diff --git a/content/doc/applications/linux.md b/content/doc/applications/linux.md index 2f2d6a206..b67f23168 100644 --- a/content/doc/applications/linux.md +++ b/content/doc/applications/linux.md @@ -32,7 +32,7 @@ clever create --type linux ``` - [Learn more about Clever Tools](/doc/cli/) -- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) +- [Learn more about Clever Cloud application deployment](/doc/getting-started/#create-an-application-step-by-step) ## Configure your Linux application diff --git a/content/doc/applications/nodejs.md b/content/doc/applications/nodejs.md index 698e08d05..6b9db12aa 100644 --- a/content/doc/applications/nodejs.md +++ b/content/doc/applications/nodejs.md @@ -47,7 +47,7 @@ clever create --type node ``` - [Learn more about Clever Tools](/doc/cli/) -- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) +- [Learn more about Clever Cloud application deployment](/doc/getting-started/#create-an-application-step-by-step) ## Configure your Node.js & Bun application diff --git a/content/doc/applications/php/_index.md b/content/doc/applications/php/_index.md index 10dd56e56..23d0fd00a 100644 --- a/content/doc/applications/php/_index.md +++ b/content/doc/applications/php/_index.md @@ -42,7 +42,7 @@ clever create --type php ``` - [Learn more about Clever Tools](/doc/cli/) -- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) +- [Learn more about Clever Cloud application deployment](/doc/getting-started/#create-an-application-step-by-step) ## Configure your PHP application diff --git a/content/doc/applications/python/_index.md b/content/doc/applications/python/_index.md index a7c2b5d02..42e792272 100644 --- a/content/doc/applications/python/_index.md +++ b/content/doc/applications/python/_index.md @@ -42,7 +42,7 @@ clever create --type python ``` - [Learn more about Clever Tools](/doc/cli/) -- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) +- [Learn more about Clever Cloud application deployment](/doc/getting-started/#create-an-application-step-by-step) ## Configure your Python application diff --git a/content/doc/applications/static.md b/content/doc/applications/static.md index bc98ce195..a63909ca1 100644 --- a/content/doc/applications/static.md +++ b/content/doc/applications/static.md @@ -43,7 +43,7 @@ clever create --type static ``` - [Learn more about Clever Tools](/doc/cli/) -- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) +- [Learn more about Clever Cloud application deployment](/doc/getting-started/#create-an-application-step-by-step) ## Configure your Static application diff --git a/content/doc/applications/v.md b/content/doc/applications/v.md index 0cae3c86d..0a114c955 100644 --- a/content/doc/applications/v.md +++ b/content/doc/applications/v.md @@ -28,7 +28,7 @@ clever create --type v ``` - [Learn more about Clever Tools](/doc/cli/) -- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step) +- [Learn more about Clever Cloud application deployment](/doc/getting-started/#create-an-application-step-by-step) ## Configure your V (Vlang) application diff --git a/content/doc/best-practices/_index.md b/content/doc/best-practices/_index.md index 17d3fbcad..1a76d84ef 100644 --- a/content/doc/best-practices/_index.md +++ b/content/doc/best-practices/_index.md @@ -12,7 +12,6 @@ keywords: - scalability - applications aliases: -- /doc/quickstart - /doc/develop/best-practices --- diff --git a/content/doc/billing/_index.md b/content/doc/billing/_index.md index fb1d5bd03..8da782544 100644 --- a/content/doc/billing/_index.md +++ b/content/doc/billing/_index.md @@ -17,7 +17,6 @@ aliases: - /doc/administrate/log-management/billing - /doc/billing - /doc/doc/billing -- /doc/quickstart --- {{< cards >}} diff --git a/content/doc/quickstart.md b/content/doc/getting-started.md similarity index 99% rename from content/doc/quickstart.md rename to content/doc/getting-started.md index 0b14c6cb5..66df441c5 100644 --- a/content/doc/quickstart.md +++ b/content/doc/getting-started.md @@ -1,8 +1,8 @@ --- type: docs -linkTitle: Quickstart +linkTitle: Getting started weight: 1 -title: Quickstart +title: Deploy your first application and resources description: Get started with Clever Cloud by creating an account, deploying your first application, and learning essential platform concepts keywords: - quickstart @@ -17,8 +17,8 @@ aliases: - /deploy - /doc/addons/add-an-addon - /doc/clever-cloud-overview/add-application -- /doc/getting-started - /doc/getting-started/quickstart +- /doc/quickstart - /getting-started/authentication - /getting-started/quickstart - /quickstart diff --git a/content/guides/hugo-static-s3.md b/content/guides/hugo-static-s3.md index 772cd5543..98481b7a4 100644 --- a/content/guides/hugo-static-s3.md +++ b/content/guides/hugo-static-s3.md @@ -17,10 +17,10 @@ You can also use Cellar, a S3-compatible object storage. This hosting method sav To do so, you need: -- a [Clever Cloud account](/doc/quickstart/) +- a [Clever Cloud account](/doc/getting-started/) - [Hugo](https://gohugo.io/) on your machine - to have [created your website](https://gohugo.io/getting-started/quick-start/) files with Hugo -- a Cellar add-on; if you have never created an add-on, you can follow [this guide](/doc/quickstart/#create-your-first-add-on) +- a Cellar add-on; if you have never created an add-on, you can follow [this guide](/doc/getting-started/#create-your-first-add-on) ## Bucket creation and management diff --git a/content/guides/tutorial-laravel.md b/content/guides/tutorial-laravel.md index b78f58781..d9692b4fe 100644 --- a/content/guides/tutorial-laravel.md +++ b/content/guides/tutorial-laravel.md @@ -36,7 +36,7 @@ The following sections explain how to set up each instance step by step: ### Create a PHP application -From the Clever Cloud Console, create a new PHP application and choose your deployment method: [git, GitHub or FTP](/doc/quickstart/#choose-how-to-deploy). +From the Clever Cloud Console, create a new PHP application and choose your deployment method: [git, GitHub or FTP](/doc/getting-started/#choose-how-to-deploy). ### Add `DocumentRoot` variable diff --git a/shared/create-application.md b/shared/create-application.md index f64071aaf..eb241e853 100644 --- a/shared/create-application.md +++ b/shared/create-application.md @@ -3,7 +3,7 @@ ### With the web console -Refer to [Quickstart](/doc/quickstart) for more details on application creation via the console. +Refer to [Quickstart](/doc/getting-started) for more details on application creation via the console. ### With the Clever Tools CLI diff --git a/shared/deploy-ftp.md b/shared/deploy-ftp.md index 18b019489..737342c79 100644 --- a/shared/deploy-ftp.md +++ b/shared/deploy-ftp.md @@ -10,4 +10,4 @@ Just follow the instructions of your FTP Software to send code to Clever Cloud. ⚠️ **An FTP application automatically starts once you create the application, even if you don't send any code yet.** -Refer to [Quick Start - FTP deployment](/doc/quickstart#ftp-deployment) for more details. +Refer to [Quick Start - FTP deployment](/doc/getting-started#choose-how-to-deploy) for more details. diff --git a/shared/deploy-git.md b/shared/deploy-git.md index bed2a8ef4..dc5fcda27 100644 --- a/shared/deploy-git.md +++ b/shared/deploy-git.md @@ -16,4 +16,4 @@ 5. Now push your application on Clever Cloud with `git push master` -Refer to [git deployments](/doc/quickstart) for more details. +Refer to [git deployments](/doc/getting-started) for more details. From ccb4e7fcee2e2d68225fd4f721b17373a0e52f98 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 09:14:10 +0200 Subject: [PATCH 18/73] docs(agents): require aliases and link updates when content moves --- AGENTS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 8ddc0021f..027829c95 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -57,6 +57,15 @@ For changelog entries, also include: - `tags` - Array of product tags (lowercase) - `authors` - Array with `name`, `link`, `image` fields +### Moving or Merging Content + +When a page moves to another URL, or when its content is merged into another page: + +- Always add the old URL to the destination page's `aliases`, so Hugo keeps serving a redirect +- Carry over every alias the removed page already declared; they must keep resolving +- Update internal links to target the new URL directly instead of relying on the redirect, especially in `shared/` blocks included by many pages +- Check each redirect in the build output before committing + ### Shared Content System - Include shared content: `{{% content "filename" %}}` From 5ffd27cc17753b41645d7fac477eaf0152d9a37c Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 09:27:09 +0200 Subject: [PATCH 19/73] feat(hugo): shorten the edit page link and reuse the external link arrow --- assets/css/custom.css | 15 +++++++++++++++ i18n/en.yaml | 1 + 2 files changed, 16 insertions(+) create mode 100644 i18n/en.yaml diff --git a/assets/css/custom.css b/assets/css/custom.css index fc936d9c8..679489777 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -698,3 +698,18 @@ html[class~="dark"] .content table:not(.code-block table) tbody tr:nth-child(odd html[class~="dark"] .swagger-ui .responses-wrapper .response-header .response-toggle svg { fill: rgb(209 213 219); } + +/* "Edit this page" link: reuse the same arrow as external links. + The i18n string can only carry text, so the icon is appended here. + A mask keeps it on currentColor, so hover and dark mode follow the link. */ +.hextra-toc a[rel="noreferrer"]::after { + content: ""; + display: inline-block; + width: 1em; + height: 1em; + margin-left: 0.15em; + vertical-align: baseline; + background-color: currentColor; + -webkit-mask: url('data:image/svg+xml;utf8,') no-repeat center / contain; + mask: url('data:image/svg+xml;utf8,') no-repeat center / contain; +} diff --git a/i18n/en.yaml b/i18n/en.yaml new file mode 100644 index 000000000..71deab0c7 --- /dev/null +++ b/i18n/en.yaml @@ -0,0 +1 @@ +editThisPage: "Edit this page" From 0d8b51d830dc967279f9e9b3b549ff770e9c781e Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 09:27:09 +0200 Subject: [PATCH 20/73] fix(hugo): make the navbar span the full page width --- hugo.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hugo.yaml b/hugo.yaml index 2f93ae061..d75c07c02 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -168,7 +168,7 @@ params: dark: images/logo-dark.svg link: /developers width: 175 - width: wide + width: full page: # full (100%), wide (90rem), normal (1280px) From 4e68eb68b753a0465b3add33d5b868358b44cbfd Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 11:01:51 +0200 Subject: [PATCH 21/73] guides: fix external card links broken by angle brackets --- .markdownlint.jsonc | 5 +++++ content/doc/billing/_index.md | 2 +- content/doc/ci-cd/custom-scripts.md | 4 ++-- content/doc/ci-cd/github.md | 2 +- content/doc/ci-cd/gitlab.md | 2 +- content/guides/docs.md | 2 +- content/guides/docusaurus.md | 2 +- content/guides/eleventy.md | 2 +- content/guides/ghost.md | 2 +- content/guides/hexo.md | 2 +- content/guides/hono.md | 2 +- content/guides/hugo.md | 2 +- content/guides/lume-deno.md | 2 +- content/guides/maudit.md | 2 +- content/guides/mdbook.md | 2 +- content/guides/mkdocs.md | 2 +- content/guides/moodle.md | 2 +- content/guides/nuxt.md | 2 +- content/guides/outline.md | 2 +- content/guides/sftpgo.md | 2 +- content/guides/sveltekit.md | 2 +- content/guides/tutorial-laravel.md | 2 +- 22 files changed, 27 insertions(+), 22 deletions(-) diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc index 25a9920da..d19c533f2 100644 --- a/.markdownlint.jsonc +++ b/.markdownlint.jsonc @@ -12,6 +12,11 @@ "cite" ] }, + // MD034/no-bare-urls : shortcode attributes such as {{< card link="https://..." >}} + // are not Markdown, but markdownlint reads them as bare URLs. Wrapping the value in + // <> silences the rule and makes Go reject the URL, rendering href="#ZgotmplZ". + // Keep URLs bare in shortcode attributes. + "MD034": false, "MD041": false, "MD051": false, "MD055": { diff --git a/content/doc/billing/_index.md b/content/doc/billing/_index.md index 8da782544..5e24ee8e5 100644 --- a/content/doc/billing/_index.md +++ b/content/doc/billing/_index.md @@ -22,6 +22,6 @@ aliases: {{< cards >}} {{< card link="/developers/doc/billing/analytics-consumption" title="Analytics and consumption" icon="chart-bar" >}} {{< card link="/developers/doc/billing/payments-invoicing" title="Payments & invoicing" icon="banknotes" >}} - {{< card link="" title="Pricing" icon="currency-euro" >}} + {{< card link="https://www.clever.cloud/pricing/" title="Pricing" icon="currency-euro" >}} {{< card link="/developers/doc/billing/unified-invoices" title="Unified invoicing" icon="user-group" >}} {{< /cards >}} diff --git a/content/doc/ci-cd/custom-scripts.md b/content/doc/ci-cd/custom-scripts.md index 9d7957c41..3e2ef919b 100644 --- a/content/doc/ci-cd/custom-scripts.md +++ b/content/doc/ci-cd/custom-scripts.md @@ -61,7 +61,7 @@ before_script: # Download clever-tools before any script executes ## 🎓 Go further {{< cards >}} - {{< card link="" title="GitHub variables" subtitle="List of GitHub default CI/CD variables" icon="github" >}} - {{< card link="" title="GitLab variables" subtitle="List of GitLab predefined variables" icon="gitlab" >}} + {{< card link="https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables" title="GitHub variables" subtitle="List of GitHub default CI/CD variables" icon="github" >}} + {{< card link="https://docs.gitlab.com/ee/ci/variables/predefined_variables.html" title="GitLab variables" subtitle="List of GitLab predefined variables" icon="gitlab" >}} {{< card link="/developers/doc/cli" title="Clever Tools CLI" subtitle="Deploy and manage your applications and dependencies from your terminal." icon="command-line" >}} {{< /cards >}} diff --git a/content/doc/ci-cd/github.md b/content/doc/ci-cd/github.md index 32328fa6e..8a9070f91 100644 --- a/content/doc/ci-cd/github.md +++ b/content/doc/ci-cd/github.md @@ -84,6 +84,6 @@ If you encounter troubles or bugs using the GitHub Action, feel free to open an ## 🎓 Go further {{< cards >}} - {{< card link="" title="GitHub Actions documentation" subtitle="Find help in GitHub Actions documentation" icon="github" >}} + {{< card link="https://docs.github.com/en/actions" title="GitHub Actions documentation" subtitle="Find help in GitHub Actions documentation" icon="github" >}} {{< card link="/developers/doc/cli" title="Clever Tools CLI" subtitle="Deploy and manage your applications and dependencies from your terminal." icon="command-line" >}} {{< /cards >}} diff --git a/content/doc/ci-cd/gitlab.md b/content/doc/ci-cd/gitlab.md index f58af701a..ae5ed726f 100644 --- a/content/doc/ci-cd/gitlab.md +++ b/content/doc/ci-cd/gitlab.md @@ -86,6 +86,6 @@ If you encounter troubles or bugs using the GitLab component, feel free to open ## 🎓 Go further {{< cards >}} - {{< card link="" title="GitLab Components" subtitle="Learn how to use GitLab components" icon="gitlab" >}} + {{< card link="https://docs.gitlab.com/ee/ci/components" title="GitLab Components" subtitle="Learn how to use GitLab components" icon="gitlab" >}} {{< card link="/developers/doc/cli" title="Clever Tools CLI" subtitle="Deploy and manage your applications and dependencies from your terminal." icon="command-line" >}} {{< /cards >}} diff --git a/content/guides/docs.md b/content/guides/docs.md index def109982..eb49145bc 100644 --- a/content/guides/docs.md +++ b/content/guides/docs.md @@ -292,5 +292,5 @@ AWS_RESPONSE_CHECKSUM_VALIDATION="when_required" ## 🎓 Further Help {{< cards >}} - {{< card link="" title="Docs documentation" subtitle="Installation instructions" icon="adjustments-horizontal" >}} + {{< card link="https://github.com/suitenumerique/docs/blob/main/docs/installation/kubernetes.md#preparation" title="Docs documentation" subtitle="Installation instructions" icon="adjustments-horizontal" >}} {{< /cards >}} diff --git a/content/guides/docusaurus.md b/content/guides/docusaurus.md index fe9c756d3..5b7f00be2 100644 --- a/content/guides/docusaurus.md +++ b/content/guides/docusaurus.md @@ -45,5 +45,5 @@ clever scale --build-flavor M {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="" title="Learn Docusaurus" subtitle="How to write and organize your content" icon="docusaurus" >}} + {{< card link="https://docusaurus.io/docs" title="Learn Docusaurus" subtitle="How to write and organize your content" icon="docusaurus" >}} {{< /cards >}} diff --git a/content/guides/eleventy.md b/content/guides/eleventy.md index ab4bded01..38e874910 100644 --- a/content/guides/eleventy.md +++ b/content/guides/eleventy.md @@ -47,5 +47,5 @@ clever env set CC_BUILD_COMMAND "npx @11ty/eleventy" {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="" title="Learn Eleventy (11ty)" subtitle="How to write and organize your content" icon="11ty" >}} + {{< card link="https://www.11ty.dev/docs/" title="Learn Eleventy (11ty)" subtitle="How to write and organize your content" icon="11ty" >}} {{< /cards >}} diff --git a/content/guides/ghost.md b/content/guides/ghost.md index 9220aa68d..629f8ac8f 100644 --- a/content/guides/ghost.md +++ b/content/guides/ghost.md @@ -273,7 +273,7 @@ The rebuild downloads the selected release and installs dependencies for the con ## Learn more {{< cards >}} - {{< card link="" title="Ghost documentation" subtitle="Configure and manage a Ghost publication" icon="ghost" >}} + {{< card link="https://docs.ghost.org/" title="Ghost documentation" subtitle="Configure and manage a Ghost publication" icon="ghost" >}} {{< card link="/developers/doc/applications/linux" title="Linux application runtime" subtitle="Configure and deploy any application" icon="linux" >}} {{< card link="/developers/doc/addons/mysql" title="MySQL" subtitle="Explore managed MySQL databases" icon="mysql" >}} {{< card link="/developers/doc/addons/cellar" title="Cellar" subtitle="Explore S3-compatible object storage" icon="cellar" >}} diff --git a/content/guides/hexo.md b/content/guides/hexo.md index 358fee64c..e85fd50f3 100644 --- a/content/guides/hexo.md +++ b/content/guides/hexo.md @@ -52,5 +52,5 @@ clever env set CC_BUILD_COMMAND "npm run build" {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="" title="Learn Hexo" subtitle="How to write and organize your content" icon="hexo" >}} + {{< card link="https://hexo.io/docs/" title="Learn Hexo" subtitle="How to write and organize your content" icon="hexo" >}} {{< /cards >}} diff --git a/content/guides/hono.md b/content/guides/hono.md index 6b4662123..193015f4b 100644 --- a/content/guides/hono.md +++ b/content/guides/hono.md @@ -125,5 +125,5 @@ clever domain add your.website.tld {{< cards >}} {{< card link="/developers/doc/applications/nodejs" title="Deploy a Node.js application" subtitle="Learn more on deploying a Node.js application" icon="node" >}} - {{< card link="" title="Hono documentation" subtitle="Learn more about the Hono framework" icon="hono" >}} + {{< card link="https://hono.dev/docs" title="Hono documentation" subtitle="Learn more about the Hono framework" icon="hono" >}} {{< /cards >}} diff --git a/content/guides/hugo.md b/content/guides/hugo.md index 36f1115a9..ec655a365 100644 --- a/content/guides/hugo.md +++ b/content/guides/hugo.md @@ -54,5 +54,5 @@ clever scale --build-flavor M {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="" title="Learn Hugo" subtitle="How to write and organize your content" icon="hugo" >}} + {{< card link="https://gohugo.io/documentation/" title="Learn Hugo" subtitle="How to write and organize your content" icon="hugo" >}} {{< /cards >}} diff --git a/content/guides/lume-deno.md b/content/guides/lume-deno.md index a816b4aa9..399a83141 100644 --- a/content/guides/lume-deno.md +++ b/content/guides/lume-deno.md @@ -59,5 +59,5 @@ It uses [Mise package manager](/doc/reference/reference-environment-variables/#i {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="" title="Learn Lume" subtitle="How to write and organize your content" icon="deno" >}} + {{< card link="https://lume.land/docs/overview/about-lume/" title="Learn Lume" subtitle="How to write and organize your content" icon="deno" >}} {{< /cards >}} diff --git a/content/guides/maudit.md b/content/guides/maudit.md index a1716dfd2..57c89696f 100644 --- a/content/guides/maudit.md +++ b/content/guides/maudit.md @@ -88,5 +88,5 @@ clever domain add your.website.tld {{< cards >}} {{< card link="/developers/doc/applications/static/" title="Static applications" subtitle="Configure and deploy static applications" icon="static" >}} - {{< card link="" title="Maudit documentation" subtitle="Build static websites with Maudit and Rust" icon="maudit" >}} + {{< card link="https://maudit.org/docs/" title="Maudit documentation" subtitle="Build static websites with Maudit and Rust" icon="maudit" >}} {{< /cards >}} diff --git a/content/guides/mdbook.md b/content/guides/mdbook.md index 54b7eebd8..16d4cd569 100644 --- a/content/guides/mdbook.md +++ b/content/guides/mdbook.md @@ -43,5 +43,5 @@ clever scale --build-flavor M {{< cards >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="How to configure your website" icon="static" >}} - {{< card link="" title="Learn mdBook" subtitle="How to write and organize your content" icon="mdbook" >}} + {{< card link="https://rust-lang.github.io/mdBook/" title="Learn mdBook" subtitle="How to write and organize your content" icon="mdbook" >}} {{< /cards >}} diff --git a/content/guides/mkdocs.md b/content/guides/mkdocs.md index c7683aedb..14eea59dd 100644 --- a/content/guides/mkdocs.md +++ b/content/guides/mkdocs.md @@ -48,5 +48,5 @@ clever scale --build-flavor M {{< cards >}} {{< card link="/developers/doc/applications/static" title="Static runtime documentation" subtitle="How to configure your website" icon="static" >}} - {{< card link="" title="MkDocs documentation" subtitle="How to write and organize your content" icon="docs" >}} + {{< card link="https://www.mkdocs.org/getting-started/" title="MkDocs documentation" subtitle="How to write and organize your content" icon="docs" >}} {{< /cards >}} diff --git a/content/guides/moodle.md b/content/guides/moodle.md index 845d95cce..d05265990 100644 --- a/content/guides/moodle.md +++ b/content/guides/moodle.md @@ -143,7 +143,7 @@ You might encounter errors when the Cron tries to access `moodledata` in your FS {{< card link="/developers/doc/administrate/cron" title="CRON" subtitle="Set up a CRON job for your app" icon="code-bracket" >}} {{< card link="/developers/doc/addons/fs-bucket" title="FS Bucket" subtitle="External File System for your apps" icon="fsbucket" >}} {{< card link="/developers/doc/addons/mysql" title="MySQL" icon="mysql" subtitle="Your self-hosted managed relational database" >}} - {{< card link="" title="Moodle Documentation" subtitle="Check Moodle installation guide" icon="moodle" >}} + {{< card link="https://docs.moodle.org/en/Installation_quick_guide" title="Moodle Documentation" subtitle="Check Moodle installation guide" icon="moodle" >}} {{< /cards >}} See [Moodle installation documentation](https://docs.moodle.org/en/Installation_quick_guide) for further help and development configuration. diff --git a/content/guides/nuxt.md b/content/guides/nuxt.md index 901797471..fefcab028 100644 --- a/content/guides/nuxt.md +++ b/content/guides/nuxt.md @@ -95,5 +95,5 @@ clever domain add your.website.tld {{< cards >}} {{< card link="/developers/doc/applications/nodejs" title="Deploy a Node.js application" subtitle="Learn more on deploying a Node.js application" icon="node" >}} {{< card link="/developers/doc/applications/static" title="Deploy a Static application" subtitle="Learn more on deploying a Static application" icon="static" >}} - {{< card link="" title="Learn Nuxt" subtitle="How to write and organize your content" icon="nuxt" >}} + {{< card link="https://nuxt.com/docs/4.x/getting-started/introduction" title="Learn Nuxt" subtitle="How to write and organize your content" icon="nuxt" >}} {{< /cards >}} diff --git a/content/guides/outline.md b/content/guides/outline.md index 430676072..51525e4cc 100644 --- a/content/guides/outline.md +++ b/content/guides/outline.md @@ -267,5 +267,5 @@ Replace the example values with the versions you selected. Outline applies pendi {{< card link="/developers/doc/addons/postgresql" title="PostgreSQL" subtitle="Explore managed PostgreSQL databases" icon="pg" >}} {{< card link="/developers/doc/addons/redis" title="Redis" subtitle="Explore managed Redis databases" icon="redis" >}} {{< card link="/developers/doc/addons/cellar" title="Cellar" subtitle="Explore S3-compatible object storage" icon="fsbucket" >}} - {{< card link="" title="Outline hosting documentation" subtitle="Learn more about self-hosting Outline" icon="outline" >}} + {{< card link="https://docs.getoutline.com/s/hosting" title="Outline hosting documentation" subtitle="Learn more about self-hosting Outline" icon="outline" >}} {{< /cards >}} diff --git a/content/guides/sftpgo.md b/content/guides/sftpgo.md index f9f0082d8..ece810004 100644 --- a/content/guides/sftpgo.md +++ b/content/guides/sftpgo.md @@ -271,5 +271,5 @@ Use any SFTP client with the following settings: {{< card link="/developers/doc/applications/linux" title="Linux applications" subtitle="Deploy any application" icon="linux" >}} {{< card link="/developers/doc/addons/cellar" title="Cellar object storage" subtitle="Store files with an S3 API" icon="database" >}} {{< card link="/developers/doc/addons/fs-bucket" title="FS Buckets" subtitle="Store files with SFTP access" icon="fsbucket" >}} - {{< card link="" title="SFTPGo documentation" subtitle="Configure users and storage" icon="book-open" >}} + {{< card link="https://docs.sftpgo.com/latest/" title="SFTPGo documentation" subtitle="Configure users and storage" icon="book-open" >}} {{< /cards >}} diff --git a/content/guides/sveltekit.md b/content/guides/sveltekit.md index f8d57b06f..54e28dd2b 100644 --- a/content/guides/sveltekit.md +++ b/content/guides/sveltekit.md @@ -228,5 +228,5 @@ clever domain add your.website.tld {{< cards >}} {{< card link="/developers/doc/applications/nodejs/" title="Node.js applications" subtitle="Configure and deploy Node.js applications" icon="node" >}} {{< card link="/developers/doc/applications/static/" title="Static applications" subtitle="Configure and deploy static applications" icon="static" >}} - {{< card link="" title="SvelteKit adapters" subtitle="Choose and configure a SvelteKit adapter" icon="svelte" >}} + {{< card link="https://svelte.dev/docs/kit/adapters" title="SvelteKit adapters" subtitle="Choose and configure a SvelteKit adapter" icon="svelte" >}} {{< /cards >}} diff --git a/content/guides/tutorial-laravel.md b/content/guides/tutorial-laravel.md index d9692b4fe..ef50ed4dc 100644 --- a/content/guides/tutorial-laravel.md +++ b/content/guides/tutorial-laravel.md @@ -176,5 +176,5 @@ This environment variable exists in any Clever Cloud instance. This configuratio {{< card link="/developers/doc/metrics/new-relic" title="Monitor your App with New Relic" subtitle="Connect your application to New Relic." icon="new-relic" >}} {{< card link="/developers/doc/addons/fs-bucket" title="FS Bucket" subtitle="External File System for your apps" icon="fsbucket" >}} {{< card link="/developers/doc/develop/build-hooks" title="Deployment hooks" subtitle="Learn about custom commands used in this guide." icon="rocket-launch" >}} - {{< card link="" title="Laravel Documentation" subtitle="Read Laravel documentation on deployments." icon="laravel" >}} + {{< card link="https://laravel.com/docs/10.x/deployment" title="Laravel Documentation" subtitle="Read Laravel documentation on deployments." icon="laravel" >}} {{< /cards >}} From b6c6ef2191a93915f4e58b3b876aafa90db78c08 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 11:03:13 +0200 Subject: [PATCH 22/73] fix(layouts): restore the skip-link anchor and copy-page block in changelog --- layouts/404.html | 2 +- layouts/changelog/list.html | 2 +- layouts/changelog/single.html | 9 +++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/layouts/404.html b/layouts/404.html index 24e760c53..1fc8a84dc 100644 --- a/layouts/404.html +++ b/layouts/404.html @@ -2,7 +2,7 @@
-
Clever Cloud 404 Logo diff --git a/layouts/changelog/list.html b/layouts/changelog/list.html index 980000851..8052f78b9 100644 --- a/layouts/changelog/list.html +++ b/layouts/changelog/list.html @@ -4,7 +4,7 @@
{{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" true) }}
-
+

{{ if .Title }}

{{ .Title }}

{{ end }}
diff --git a/layouts/changelog/single.html b/layouts/changelog/single.html index bfc300bb6..422bc669d 100644 --- a/layouts/changelog/single.html +++ b/layouts/changelog/single.html @@ -3,9 +3,14 @@ {{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" false) }} {{ partial "toc.html" . }}
-
+
{{ partial "breadcrumb.html" (dict "page" . "enable" true) }} - {{ if .Title }}

{{ .Title }}

{{ end }} + {{ if .Title }} +
+

{{ .Title }}

+ {{ partial "components/page-context-menu" . }} +
+ {{ end }}
{{- with $date := .Date }}{{ partial "utils/format-date" $date }}{{ end -}} {{- $lazyLoading := site.Params.enableImageLazyLoading | default true -}} From 070255654b8426018020b6f9378ea8bb387dfa66 Mon Sep 17 00:00:00 2001 From: David Legrand Date: Wed, 2 Sep 2026 11:27:57 +0200 Subject: [PATCH 23/73] feat(ci): add an offline internal link and anchor checker --- check-internal-links.py | 1118 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1118 insertions(+) create mode 100755 check-internal-links.py diff --git a/check-internal-links.py b/check-internal-links.py new file mode 100755 index 000000000..ce1751b63 --- /dev/null +++ b/check-internal-links.py @@ -0,0 +1,1118 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.9" +# dependencies = [] +# /// +"""Check internal hyperlinks in a built Hugo site. + +Scope: only. Assets (img/src, srcset, link, script) have different +semantics and exemptions and are deliberately left to the deployed +`linkchecker` job. + +Complements that job, which follows redirects and checks external URLs but +never validates URL fragments. This one runs offline on the build output +and reports what it cannot see: + + broken the target page does not exist + dead-alias the link lands on an alias whose chain ends nowhere + alias-loop the redirect chain loops back on itself + lost-anchor the link lands on an alias AND carries a fragment; a Hugo + alias is a with no JavaScript, + which drops the fragment, so the reader lands at the top + anchor the target exists but has no matching id + redirect the link lands on an alias, so it costs an extra hop (note) + +Same-origin links outside this build are served by another application and +are simply set aside: `linkchecker` already covers them in CI. + +`source_locations` are heuristic candidates: the Markdown lines whose text +contains the offending URL. They can miss a link produced by a template or +by hugo.yaml, so `rendered_pages` is always reported as well. + +Notes are summarised as counts by default and only listed with -d: they +need no action here. `--format json` emits a stable machine-readable report +on stdout for tooling and agents; diagnostics go to stderr. + +Resolution runs against an exact, case-sensitive index of the files in the +build. macOS is case-insensitive and Linux is not, so an `is_file()` probe +would accept /doc/Foo locally and 404 in CI; the index makes both agree. +URL paths are percent-decoded and normalised before the prefix boundary is +tested, so a link climbing out of the prefix with `..` cannot be validated +against the wrong file. + +Ownership: a path under the baseURL prefix belongs to this build and must +resolve, unless it is declared with --external-prefix (other applications +are deployed under the same prefix). + +The HTML element is not honoured; the build contains none, and +supporting it would need its own same-origin and ownership checks. + +Usage: + hugo # writes to publishDir + ./check-internal-links.py # defaults to public/developers + uv run check-internal-links.py -d # also list the non-blocking notes + uv run check-internal-links.py --format json # machine-readable, stdout only + uv run check-internal-links.py --root some/dir --prefix /developers + +Exit codes: 0 clean, 1 problems found, 2 bad invocation or missing build. +""" + +from __future__ import annotations + +import argparse +import difflib +import json +import os +import posixpath +import re +import shutil +import sys +from collections import Counter, defaultdict +from concurrent.futures import ProcessPoolExecutor +from concurrent.futures.process import BrokenProcessPool +from html.parser import HTMLParser +from pathlib import Path +from time import perf_counter +from typing import TYPE_CHECKING, NamedTuple, NoReturn + +if TYPE_CHECKING: + from collections.abc import Iterable, Sequence + + Attrs = Sequence[tuple[str, str | None]] +from urllib.parse import unquote, urljoin, urlsplit, urlunsplit + +# Paths served under the baseURL prefix by something other than this build. +DEFAULT_EXTERNAL = ("/developers/clever-components",) +# Pages whose anchors are generated client-side, absent from static HTML. +DEFAULT_SKIP_ANCHORS = ("api/v2",) +DEFAULT_SOURCES = ("content", "shared") +DEFAULT_CONFIGS = ("hugo.yaml",) + +SKIPPED_SCHEMES = ("mailto:", "tel:", "javascript:", "data:") +DEFAULT_PORTS = {"http": "80", "https": "443"} +ALIAS_HOP_LIMIT = 10 # a Hugo alias chain is normally one hop +MAX_SUGGESTIONS = 5 # near-miss anchors offered as a fix +SUGGESTION_CUTOFF = 0.4 # loose enough to catch prefix- -> path-routing +MAX_SOURCE_LINES = 4 # source lines printed per finding +MAX_PAGES_LISTED = 2 # rendered pages printed before "+N more" +CHUNKS_PER_WORKER = 4 # how finely the page list is split across workers +CHUNK_CEILING = 64 # never hand a worker more than this in one go +HELP_WIDTH = 96 # usage and help never wrap wider than this + +EXIT_OK, EXIT_FINDINGS, EXIT_MISUSE = 0, 1, 2 +GLYPHS = "✓✗·→" # dropped together when the stream cannot encode them + + +class Kind(NamedTuple): + """A category of finding: how to name it, explain it, and how bad it is.""" + + name: str + title: str + explanation: str + blocking: bool + + +KINDS: tuple[Kind, ...] = ( + Kind( + "broken", + "Broken targets", + "The target does not exist in the build.", + blocking=True, + ), + Kind( + "dead-alias", + "Redirects to missing pages", + "The link lands on a redirect whose own destination is missing.", + blocking=True, + ), + Kind( + "alias-loop", + "Redirect loops", + "The chain of redirects comes back on itself and never lands.", + blocking=True, + ), + Kind( + "lost-anchor", + "Fragments lost in redirects", + "A redirect cannot carry a #fragment: the reader lands at the top.", + blocking=True, + ), + Kind( + "anchor", + "Missing anchors", + "The page exists but has no element with that id, usually a renamed heading.", + blocking=True, + ), + Kind( + "redirect", + "Redirects", + "These resolve through an alias. Point them at the destination to save a hop.", + blocking=False, + ), +) +KIND_ORDER = [kind.name for kind in KINDS] +BLOCKING = frozenset(kind.name for kind in KINDS if kind.blocking) +NOTE_LABEL = {"redirect": "redirecting"} + + +# -------------------------------------------------------------------------- +# Small pure helpers +# -------------------------------------------------------------------------- + + +def canon_origin(scheme: str, netloc: str) -> str: + """Canonical scheme://host, lowercased and without a default port.""" + scheme = (scheme or "").lower() + host = (netloc or "").lower() + port = DEFAULT_PORTS.get(scheme) + if port and host.endswith(f":{port}"): + host = host[: -len(port) - 1] + return f"{scheme}://{host}" if host else "" + + +def parse_refresh(content: str) -> str | None: + """Target of a zero-delay meta refresh, else None. + + Only a zero delay is a Hugo alias. A page with a real timed refresh is + a normal page and must still be crawled. + """ + delay, separator, rest = content.partition(";") + if not separator: + return None + try: + if float(delay.strip()) != 0: + return None + except ValueError: + return None + rest = re.sub(r"^url\s*=\s*", "", rest.strip(), count=1, flags=re.IGNORECASE) + if rest[:1] == rest[-1:] and rest[:1] in ("'", '"'): + rest = rest[1:-1] + return rest.strip() or None + + +def wanted_anchor(fragment: str) -> str | None: + """The id a fragment targets, or None when it targets no id. + + `#top` scrolls to the top of the document with no element of that name, + and a `:~:` text directive is not an id at all. + """ + frag = unquote(fragment) + if ":~:" in frag: + frag = frag.split(":~:", 1)[0] + if not frag or frag.lower() == "top": + return None + return frag + + +def under(path: str, prefix: str) -> bool: + """True if `path` equals `prefix` or lives under it. Never a raw startswith.""" + return path == prefix or path.startswith(prefix.rstrip("/") + "/") + + +def display_path(path: str) -> str: + """Path relative to the invocation directory, in POSIX form. + + Always relative when it can be computed: an absolute path would leak + the local layout into a published JSON artifact and make the report + differ between runners. + """ + try: + return os.path.relpath(path, Path.cwd()).replace(os.sep, "/") + except ValueError: # different volume on Windows + return path.replace(os.sep, "/") + + +def plural(count: int, singular: str, many: str | None = None) -> str: + return f"{count:,} {singular if count == 1 else (many or singular + 's')}" + + +def cpu_limit() -> int: + return os.cpu_count() or 1 + + +# -------------------------------------------------------------------------- +# Parsing +# -------------------------------------------------------------------------- + + +class Page(HTMLParser): + """Collect hyperlinks, anchor ids and any meta refresh from one page. + + A real parser rather than a regex: it handles uppercase attributes, + single or unquoted values and character references. It also puts +