From fd154c8a3a37712d93342d8c57685bc27313084e Mon Sep 17 00:00:00 2001 From: Thibault Genaitay Date: Wed, 16 Oct 2024 12:31:33 +0200 Subject: [PATCH 01/68] feat(genapi): getting ready for public beta --- .../api-cli/understanding-errors.mdx | 2 ++ .../how-to/query-text-models.mdx | 12 ++++++- ai-data/generative-apis/quickstart.mdx | 12 ++++++- .../reference-content/rate-limits.mdx | 31 ++++++++++++++----- .../reference-content/supported-models.mdx | 6 +++- 5 files changed, 52 insertions(+), 11 deletions(-) diff --git a/ai-data/generative-apis/api-cli/understanding-errors.mdx b/ai-data/generative-apis/api-cli/understanding-errors.mdx index 1b134fb5ad..3c3e4a54fd 100644 --- a/ai-data/generative-apis/api-cli/understanding-errors.mdx +++ b/ai-data/generative-apis/api-cli/understanding-errors.mdx @@ -32,6 +32,8 @@ Below are usual HTTP error codes: - 404 - **Route Not Found**: The requested resource could not be found. Check your request is being made to the correct endpoint. - 422 - **Model Not Found**: The `model` key is present in the request payload, but the corresponding model is not found. - 422 - **Missing Model**: The `model` key is missing from the request payload. +- 429 - **Too Many Requests**: You are exceeding your current quota for the requested model, calculated in requests per minute. Find rate limits in [this page](/ai-data/generative-apis/reference-content/rate-limits/) +- 429 - **Too Many Tokens**: You are exceeding your current quota for the requested model, calculated in tokens per minute. Find rate limits in [this page](/ai-data/generative-apis/reference-content/rate-limits/) - 500 - **API error**: An unexpected internal error has occurred within Scaleway's systems. If the issue persists, please [open a support ticket](https://console.scaleway.com/support/tickets/create). For streaming responses via SSE, 5xx errors may occur after a 200 response has been returned. \ No newline at end of file diff --git a/ai-data/generative-apis/how-to/query-text-models.mdx b/ai-data/generative-apis/how-to/query-text-models.mdx index 7194ab4a7d..0eeeceeca3 100644 --- a/ai-data/generative-apis/how-to/query-text-models.mdx +++ b/ai-data/generative-apis/how-to/query-text-models.mdx @@ -27,7 +27,17 @@ There are several ways to interact with text models: ## Accessing the Playground -Scaleway's Playground is in development, stay tuned! +Scaleway provides a web playground for instruct-based models hosted on Generative APIs. + +1. Navigate to Generative APIs under the AI section of the [Scaleway console](https://console.scaleway.com/) side menu. The list of models you can query displays. +2. Click the name of the chat model you want to try. Alternatively, click next to the chat model, and click **Try model** in the menu. + +The web playground displays. + +1. Enter a prompt at the bottom of the page, or use one of the suggested prompts in the conversation area. +2. Edit the hyperparameters listed on the right column, for example the default temperature for more or less randomness on the outputs. +3. Switch model at the top of the page, to observe the capabilities of chat models offered via Generative APIs. +4. Click **View code** to get code snippets configured according to your settings in the playground. ## Querying text models via API diff --git a/ai-data/generative-apis/quickstart.mdx b/ai-data/generative-apis/quickstart.mdx index 0eabad417b..ae0a516aa8 100644 --- a/ai-data/generative-apis/quickstart.mdx +++ b/ai-data/generative-apis/quickstart.mdx @@ -32,7 +32,17 @@ Hosted in European data centers and priced competitively per million tokens used ## Start with the Generative APIs Playground -Scaleway's Playground is in development, stay tuned! +Scaleway provides a web playground for instruct-based models hosted on Generative APIs. + +1. Navigate to Generative APIs under the AI section of the [Scaleway console](https://console.scaleway.com/) side menu. The list of models you can query displays. +2. Click the name of the chat model you want to try. Alternatively, click next to the chat model, and click **Try model** in the menu. + +The web playground displays. + +1. Enter a prompt at the bottom of the page, or use one of the suggested prompts in the conversation area. +2. Edit the hyperparameters listed on the right column, for example the default temperature for more or less randomness on the outputs. +3. Switch model at the top of the page, to observe the capabilities of chat models offered via Generative APIs. +4. Click **View code** to get code snippets configured according to your settings in the playground. ## Install the OpenAI Python SDK diff --git a/ai-data/generative-apis/reference-content/rate-limits.mdx b/ai-data/generative-apis/reference-content/rate-limits.mdx index 78839ecbd8..3f18ff0c28 100644 --- a/ai-data/generative-apis/reference-content/rate-limits.mdx +++ b/ai-data/generative-apis/reference-content/rate-limits.mdx @@ -13,16 +13,31 @@ dates: ## What are the limits? - - This service has no rate limits while in closed beta. Limits will be set at a later stage. - - -Any given model served through Scaleway Generative APIs will ultimately get limited by: +Any model served through Scaleway Generative APIs gets limited by: - Tokens per minute -- Queries per second +- Queries per minute + +### Chat models + +| Model string | Requests per minute | Tokens per minute | +|-----------------|-----------------|-----------------| +| `llama-3.1-8b-instruct` | 300 | 100K | +| `llama-3.1-70b-instruct` | 300 | 100K | +| `mistral-nemo-instruct-2407`| 300 | 100K | +| `pixtral-12b-2409`| 300 | 100K | -We welcome feedback from early testers to set proper rates according to future use. +### Embedding models + +| Model string | Requests per minute | Tokens per minute | +|-----------------|-----------------|-----------------| +| `sentence-t5-xxl` | 600 | 1M | +| `bge-multilingual-gemma2` | 600 | 1M | ## Why do we set rate limits? -These limits will safeguard against abuse or misuse of Scaleway Generative APIs, helping to ensure fair access to the API with consistent performance. \ No newline at end of file +These limits safeguard against abuse or misuse of Scaleway Generative APIs, helping to ensure fair access to the API with consistent performance. + +## How can I increase the rate limits? + +We actively monitor usage and will improve rates based on feedback. +If you need to increase your rate limits, please contact us via the support, providing details on the model used and specific use case. \ No newline at end of file diff --git a/ai-data/generative-apis/reference-content/supported-models.mdx b/ai-data/generative-apis/reference-content/supported-models.mdx index 9975b24969..049fcc09a9 100644 --- a/ai-data/generative-apis/reference-content/supported-models.mdx +++ b/ai-data/generative-apis/reference-content/supported-models.mdx @@ -21,8 +21,11 @@ Our [Chat API](/ai-data/generative-apis/how-to/query-text-models) has built-in s | Provider | Model string | Context window | License | Model card | |-----------------|-----------------|-----------------|-----------------|-----------------| -| Meta | `llama-3.1-8b-instruct` | 128k | [Llama 3.1 Community License Agreement](https://llama.meta.com/llama3_1/license/) | [HF](https://huggingface.co/meta-llama/Meta-Llama-3.1-8B-Instruct) | +| Meta | `llama-3.1-8b-instruct` | 128k | [Llama 3.1 Community License Agreement](https://llama.meta.com/llama3_1/license/) | [HF](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) | +| Meta | `llama-3.1-70b-instruct` | 128k | [Llama 3.1 Community License Agreement](https://llama.meta.com/llama3_1/license/) | [HF](https://huggingface.co/meta-llama/Llama-3.1-70B-Instruct) | | Mistral | `mistral-nemo-instruct-2407` | 128k | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) | [HF](https://huggingface.co/mistralai/Mistral-Nemo-Instruct-2407) | +| Mistral | `pixtral-12b-2409` | 128k | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) | [HF](https://huggingface.co/mistralai/Pixtral-12B-2409) | + If you are unsure which chat model to use, we currently recommend Llama 3.1 8B Instruct (`llama-3.1-8b-instruct`) to get started. @@ -39,6 +42,7 @@ Our [Embeddings API](/ai-data/generative-apis/how-to/query-embedding-models) pro | Provider | Model string | Model size | Embedding dimension | Context window | License | Model card | |-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------| | SBERT | `sentence-t5-xxl` | 5B | 768 | 512 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) | [HF](https://huggingface.co/sentence-transformers/sentence-t5-xxl) | +| BAAI | `bge-multilingual-gemma2` | 9B | 3584 | 8192 | [Gemma](https://ai.google.dev/gemma/terms) | [HF](https://huggingface.co/BAAI/bge-multilingual-gemma2) | ## Request a model From c1263e8a2bec48bbc98bf930d3fe569171ecd766 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Wed, 16 Oct 2024 13:38:55 +0200 Subject: [PATCH 02/68] Apply suggestions from code review Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> --- ai-data/generative-apis/api-cli/understanding-errors.mdx | 4 ++-- ai-data/generative-apis/how-to/query-text-models.mdx | 1 + ai-data/generative-apis/quickstart.mdx | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ai-data/generative-apis/api-cli/understanding-errors.mdx b/ai-data/generative-apis/api-cli/understanding-errors.mdx index 3c3e4a54fd..4b298ae6a2 100644 --- a/ai-data/generative-apis/api-cli/understanding-errors.mdx +++ b/ai-data/generative-apis/api-cli/understanding-errors.mdx @@ -32,8 +32,8 @@ Below are usual HTTP error codes: - 404 - **Route Not Found**: The requested resource could not be found. Check your request is being made to the correct endpoint. - 422 - **Model Not Found**: The `model` key is present in the request payload, but the corresponding model is not found. - 422 - **Missing Model**: The `model` key is missing from the request payload. -- 429 - **Too Many Requests**: You are exceeding your current quota for the requested model, calculated in requests per minute. Find rate limits in [this page](/ai-data/generative-apis/reference-content/rate-limits/) -- 429 - **Too Many Tokens**: You are exceeding your current quota for the requested model, calculated in tokens per minute. Find rate limits in [this page](/ai-data/generative-apis/reference-content/rate-limits/) +- 429 - **Too Many Requests**: You are exceeding your current quota for the requested model, calculated in requests per minute. Find rate limits on [this page](/ai-data/generative-apis/reference-content/rate-limits/) +- 429 - **Too Many Tokens**: You are exceeding your current quota for the requested model, calculated in tokens per minute. Find rate limits on [this page](/ai-data/generative-apis/reference-content/rate-limits/) - 500 - **API error**: An unexpected internal error has occurred within Scaleway's systems. If the issue persists, please [open a support ticket](https://console.scaleway.com/support/tickets/create). For streaming responses via SSE, 5xx errors may occur after a 200 response has been returned. \ No newline at end of file diff --git a/ai-data/generative-apis/how-to/query-text-models.mdx b/ai-data/generative-apis/how-to/query-text-models.mdx index 0eeeceeca3..e863101f35 100644 --- a/ai-data/generative-apis/how-to/query-text-models.mdx +++ b/ai-data/generative-apis/how-to/query-text-models.mdx @@ -34,6 +34,7 @@ Scaleway provides a web playground for instruct-based models hosted on Generativ The web playground displays. +## Using the Playground 1. Enter a prompt at the bottom of the page, or use one of the suggested prompts in the conversation area. 2. Edit the hyperparameters listed on the right column, for example the default temperature for more or less randomness on the outputs. 3. Switch model at the top of the page, to observe the capabilities of chat models offered via Generative APIs. diff --git a/ai-data/generative-apis/quickstart.mdx b/ai-data/generative-apis/quickstart.mdx index ae0a516aa8..ec0ec90434 100644 --- a/ai-data/generative-apis/quickstart.mdx +++ b/ai-data/generative-apis/quickstart.mdx @@ -34,11 +34,13 @@ Hosted in European data centers and priced competitively per million tokens used Scaleway provides a web playground for instruct-based models hosted on Generative APIs. +### Accessing the Playground 1. Navigate to Generative APIs under the AI section of the [Scaleway console](https://console.scaleway.com/) side menu. The list of models you can query displays. 2. Click the name of the chat model you want to try. Alternatively, click next to the chat model, and click **Try model** in the menu. The web playground displays. +### Using the Playground 1. Enter a prompt at the bottom of the page, or use one of the suggested prompts in the conversation area. 2. Edit the hyperparameters listed on the right column, for example the default temperature for more or less randomness on the outputs. 3. Switch model at the top of the page, to observe the capabilities of chat models offered via Generative APIs. From 99a7f1065b5d754b146e2a17e84b9cbd94c85b33 Mon Sep 17 00:00:00 2001 From: Thibault Genaitay Date: Wed, 30 Oct 2024 10:10:36 +0100 Subject: [PATCH 03/68] feat(ai): reduced due to sliding attention window --- .../generative-apis/reference-content/supported-models.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ai-data/generative-apis/reference-content/supported-models.mdx b/ai-data/generative-apis/reference-content/supported-models.mdx index 049fcc09a9..f35a361ea7 100644 --- a/ai-data/generative-apis/reference-content/supported-models.mdx +++ b/ai-data/generative-apis/reference-content/supported-models.mdx @@ -42,7 +42,7 @@ Our [Embeddings API](/ai-data/generative-apis/how-to/query-embedding-models) pro | Provider | Model string | Model size | Embedding dimension | Context window | License | Model card | |-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------| | SBERT | `sentence-t5-xxl` | 5B | 768 | 512 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) | [HF](https://huggingface.co/sentence-transformers/sentence-t5-xxl) | -| BAAI | `bge-multilingual-gemma2` | 9B | 3584 | 8192 | [Gemma](https://ai.google.dev/gemma/terms) | [HF](https://huggingface.co/BAAI/bge-multilingual-gemma2) | +| BAAI | `bge-multilingual-gemma2` | 9B | 3584 | 4096 | [Gemma](https://ai.google.dev/gemma/terms) | [HF](https://huggingface.co/BAAI/bge-multilingual-gemma2) | ## Request a model @@ -50,4 +50,4 @@ Our [Embeddings API](/ai-data/generative-apis/how-to/query-embedding-models) pro ## Deprecated models -This section will list models retired and no longer accessible for use. All models are currently in `Active` status. \ No newline at end of file +This section will list models retired and no longer accessible for use. All models are currently in `Active` status. From a701da25c634df01e7ccd411bb45e2c29d92ad13 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Wed, 16 Oct 2024 17:11:57 +0200 Subject: [PATCH 04/68] fix(aps): update quotas (#3847) --- .../additional-content/organization-quotas.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/identity-and-access-management/organizations-and-projects/additional-content/organization-quotas.mdx b/identity-and-access-management/organizations-and-projects/additional-content/organization-quotas.mdx index 3f8b85c27c..300539094d 100644 --- a/identity-and-access-management/organizations-and-projects/additional-content/organization-quotas.mdx +++ b/identity-and-access-management/organizations-and-projects/additional-content/organization-quotas.mdx @@ -7,7 +7,7 @@ content: paragraph: This page shows you the quotas associated with your Organization. tags: account-quotas quotas security-rule security rule dates: - validation: 2024-04-10 + validation: 2024-10-16 posted: 2021-02-10 categories: - console @@ -154,7 +154,7 @@ At Scaleway, quotas are applicable per [Organization](/identity-and-access-manag |-------------|:----------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------:| | Apple silicon M1-M | 1 per [Availability Zone](/compute/instances/concepts/#availability-zone) | 3 per [Availability Zone](/compute/instances/concepts/#availability-zone) | | Apple silicon M2-M | To use this product, you must [validate your identity](/console/account/how-to/verify-identity/). | 5 per [Availability Zone](/compute/instances/concepts/#availability-zone) | -| Apple silicon M2-L | To use this product, you must [validate your identity](/console/account/how-to/verify-identity/). | 5 per [Availability Zone](/compute/instances/concepts/#availability-zone) | +| Apple silicon M2-L | 1 per [Availability Zone](/compute/instances/concepts/#availability-zone) | 5 per [Availability Zone](/compute/instances/concepts/#availability-zone) | ## Elastic Metal From 2bf08d6f1191db7f301aeb4160b212d321358a93 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 17 Oct 2024 10:57:04 +0200 Subject: [PATCH 05/68] chore(dbaas): review docs 2024-10-16 (#3842) --- managed-databases/postgresql-and-mysql/concepts.mdx | 2 +- .../postgresql-and-mysql/how-to/change-volume-type.mdx | 2 +- .../postgresql-and-mysql/reference-content/autohealing.mdx | 2 +- .../reference-content/security-and-reliability.mdx | 2 +- .../postgresql-and-mysql/troubleshooting/extension-errors.mdx | 2 +- .../redis/api-cli/managing-username-and-password.mdx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/managed-databases/postgresql-and-mysql/concepts.mdx b/managed-databases/postgresql-and-mysql/concepts.mdx index 9e261a9415..a528341d8a 100644 --- a/managed-databases/postgresql-and-mysql/concepts.mdx +++ b/managed-databases/postgresql-and-mysql/concepts.mdx @@ -7,7 +7,7 @@ content: paragraph: Understand key concepts for Scaleway Managed Databases for PostgreSQL and MySQL. tags: endpoint allowed-ip clone-feature engine read-replica dates: - validation: 2024-04-08 + validation: 2024-10-16 categories: - managed-databases - postgresql-and-mysql diff --git a/managed-databases/postgresql-and-mysql/how-to/change-volume-type.mdx b/managed-databases/postgresql-and-mysql/how-to/change-volume-type.mdx index 5905a95c47..778be44b1d 100644 --- a/managed-databases/postgresql-and-mysql/how-to/change-volume-type.mdx +++ b/managed-databases/postgresql-and-mysql/how-to/change-volume-type.mdx @@ -7,7 +7,7 @@ content: paragraph: This page explains how to change the volume type of your Database tags: managed-database database volume-type dates: - validation: 2024-04-06 + validation: 2024-10-16 posted: 2021-03-10 categories: - managed-databases diff --git a/managed-databases/postgresql-and-mysql/reference-content/autohealing.mdx b/managed-databases/postgresql-and-mysql/reference-content/autohealing.mdx index d4c248f2b1..bf1c81c2f0 100644 --- a/managed-databases/postgresql-and-mysql/reference-content/autohealing.mdx +++ b/managed-databases/postgresql-and-mysql/reference-content/autohealing.mdx @@ -7,7 +7,7 @@ content: paragraph: Understand the autohealing feature for PostgreSQL and MySQL databases. tags: databases ha high-availability autohealing database-nodes dates: - validation: 2024-04-08 + validation: 2024-10-16 categories: - managed-databases - postgresql-and-mysql diff --git a/managed-databases/postgresql-and-mysql/reference-content/security-and-reliability.mdx b/managed-databases/postgresql-and-mysql/reference-content/security-and-reliability.mdx index 6f92b70c90..58ddeebc37 100644 --- a/managed-databases/postgresql-and-mysql/reference-content/security-and-reliability.mdx +++ b/managed-databases/postgresql-and-mysql/reference-content/security-and-reliability.mdx @@ -7,7 +7,7 @@ content: paragraph: Learn more about shared responsibility in security and reliability practices for Managed Databases for PostgreSQL and MySQL tags: databases postgresql shared responsibility security reliability dates: - validation: 2024-04-08 + validation: 2024-10-16 categories: - managed-databases - postgresql-and-mysql diff --git a/managed-databases/postgresql-and-mysql/troubleshooting/extension-errors.mdx b/managed-databases/postgresql-and-mysql/troubleshooting/extension-errors.mdx index 72116ccfd7..30abc60517 100644 --- a/managed-databases/postgresql-and-mysql/troubleshooting/extension-errors.mdx +++ b/managed-databases/postgresql-and-mysql/troubleshooting/extension-errors.mdx @@ -7,7 +7,7 @@ content: paragraph: Troubleshoot extension errors for PostgreSQL databases. tags: disk-full databases dates: - validation: 2024-04-09 + validation: 2024-10-16 posted: 2024-04-09 categories: - managed-databases diff --git a/managed-databases/redis/api-cli/managing-username-and-password.mdx b/managed-databases/redis/api-cli/managing-username-and-password.mdx index 52bd89a5b1..df72712900 100644 --- a/managed-databases/redis/api-cli/managing-username-and-password.mdx +++ b/managed-databases/redis/api-cli/managing-username-and-password.mdx @@ -7,7 +7,7 @@ content: paragraph: Learn to manage Redis™ usernames and passwords using API/CLI. tags: databases user redis username password dates: - validation: 2024-04-08 + validation: 2024-10-16 categories: - managed-databases - redis From 48c7c98b0b397e18c84b53ea2f8dfb36bc0d0d4a Mon Sep 17 00:00:00 2001 From: Camille Bouvat Date: Thu, 17 Oct 2024 10:57:14 +0200 Subject: [PATCH 06/68] doc(tem): indicates encryption is mandatory (#3840) --- .../reference-content/smtp-configuration.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/managed-services/transactional-email/reference-content/smtp-configuration.mdx b/managed-services/transactional-email/reference-content/smtp-configuration.mdx index 8a2b0be1a2..b6f5c11d61 100644 --- a/managed-services/transactional-email/reference-content/smtp-configuration.mdx +++ b/managed-services/transactional-email/reference-content/smtp-configuration.mdx @@ -35,7 +35,7 @@ Your Scaleway SMTP username is the Project ID of the Project in which the TEM do Your password is the secret key of the API key of the project used to manage your TEM domain. Follow this procedure to [generate API keys for API and SMTP sending with IAM](https://www.scaleway.com/en/docs/managed-services/transactional-email/how-to/generate-api-keys-for-tem-with-iam/). -4 - **Encryption method** - If you want to encrypt the connection between your application and the SMTP server, there are usually two methods available: +4 - **Encryption method** - An encrypted connection between your application and the SMTP server is **mandatory**, and two methods are available: - **SSL/TLS**: Also known as SMTPS, it allows you to directly define a secure connection on a secure port. Directly creates a secure connection on a port such as `465` and `2465`. - **STARTTLS**: This type will upgrade any insecure connections to secure connections on a non-secure port, such as 587. From b4285db4d920599a5fcd1103ec5f8325a45ca248 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 17 Oct 2024 11:00:10 +0200 Subject: [PATCH 07/68] fix(ddx): fix migration macro (#3843) --- macros/bare-metal/dedibox-scaleway-migration.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/macros/bare-metal/dedibox-scaleway-migration.mdx b/macros/bare-metal/dedibox-scaleway-migration.mdx index 300670c9a1..805e506cf2 100644 --- a/macros/bare-metal/dedibox-scaleway-migration.mdx +++ b/macros/bare-metal/dedibox-scaleway-migration.mdx @@ -1,5 +1,6 @@ --- macro: dedibox-scaleway-migration --- - -Only users who **have completed** the linking of their the Dedibox account to the Scaleway console are granted access to the Dedibox section within the Scaleway console. For detailed information on the migration process, please refer to our [account linking documentation](/bare-metal/dedibox/how-to/link-dedibox-account/). **If you cannot locate the Dedibox link in Scaleway's console side menu, you can use the [Dedibox console](https://console.online.net)** to place orders, manage your Dediboxes, and access the [related documentation](/dedibox/dedicated-servers/quickstart/). + + Only users who **have completed** the linking of their the Dedibox account to the Scaleway console are granted access to the Dedibox section within the Scaleway console. For detailed information on the migration process, please refer to our [account linking documentation](/bare-metal/dedibox/how-to/link-dedibox-account/). **If you cannot locate the Dedibox link in Scaleway's console side menu, you can use the [Dedibox console](https://console.online.net)** to place orders, manage your Dediboxes, and access the [related documentation](/dedibox/dedicated-servers/quickstart/). + \ No newline at end of file From 1ee06d56d3774e414ac0505d2eca299db4806c6f Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 17 Oct 2024 14:15:17 +0200 Subject: [PATCH 08/68] feat(tem): update quota information (#3848) --- .../tem-capabilities-and-limits.mdx | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx b/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx index dbc78ad6be..eeff48c158 100644 --- a/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx +++ b/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx @@ -13,27 +13,38 @@ categories: - managed-services --- -This page provides information about the capabilities and limits of Scaleway Transactional Email service, depending on user quotas. +Scaleway's Transactional Email service allows users to send automated emails triggered by specific actions like account notifications, password resets, and order confirmations. This service is optimized for high-volume email sending, ensuring fast and reliable delivery of critical messages to end users. -Every [Organization](/identity-and-access-management/iam/concepts/#organization) has quotas, which are limits on the number of Scaleway resources they can use. Below is a list of basic quotas available for Transactional Email. +The service is built on scalable infrastructure capable of handling substantial email volumes. However, sending capacities are evaluated on a case-by-case basis, depending on factors such as: - - - Additional quotas can be added on a case-by-case basis. If you have already validated your payment method and your identity and want to increase your quota beyond the values shown on this page, [contact our support team](https://console.scaleway.com/support/create) - - Starting from December 1st 2023, Transactional Email no longer applies an hourly quota for your email sending. Find out more about Transactional Email's pricing on the [product pricing page](https://www.scaleway.com/en/pricing/?tags=available,managedservices-transactionalemail-transactionalemail). - +- Usage patterns +- Sender reputation +- Adherence to best practices + +New users may face stricter initial limits, while well-known customers can benefit from higher limits, potentially sending up to millions of emails. These quotas are subject to validation by the Scaleway support team. + + + Customers must adhere to industry standards and our [General Terms of Services](https://www-uploads.scaleway.com/General_Terms_of_Services_v17072024_45d4879c08.pdf), including compliance with [Scaleway's anti-spam policy](https://tem.s3.fr-par.scw.cloud/antispam_policy.pdf). Failure to comply may result in temporary or permanent restrictions to the service. +## Transactional Email service quotas -| | [Payment method validated](/console/billing/how-to/add-payment-method/#how-to-add-a-credit-card) | Payment method and [identity validated](/console/account/how-to/verify-identity/) | -|-------------------------------------|-------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------| -| Max. of recipients | 3 | 3 | -| Domains per Organization | 2 | 5 | -| Emails sent per month | 500 | 5000 | -| Max. of attachments | 2 | 2 | -| Max. size of an email (Mo) for API | 2* | 2* | -| Max. size of an email (Mo) for SMTP | 2* | 2* | +| **Quota** | **Minimum Quota** | **Maximum Quota** | **Upgradable** | +|------------------------------------------------|-------------------|-------------------|----------------| +| Maximum number of emails per month | 10,000 | Unlimited | Yes | +| Maximum number of attachments per email | 10 | Custom defined | Yes | +| Maximum number of recipients per email | 10 | Custom defined | Yes | +| Maximum email size (API) | 2 MB* | 2 MB* | No | +| Maximum email size (SMTP) | 50 MB* | Custom defined | Yes | + +*Including the email and all attachments in the email. + + + Quotas can be increased on a case-by-case basis. If you have validated your payment method and identity and want to increase your limits beyond the values shown, [contact our support team](https://console.scaleway.com/support/create). + -*Including the email and the attachments in the email. +As of **December 1st, 2023**, the Transactional Email service no longer applies an hourly quota for email sending. +For more information on pricing, visit the [Transactional Email pricing page](https://www.scaleway.com/fr/tarifs/managed-services/#transactional-email). ### Types of attachments available From 19c3a8be67f9c82481ed8bb4ef3f6ccde110cc4f Mon Sep 17 00:00:00 2001 From: SamyOubouaziz Date: Thu, 17 Oct 2024 14:38:14 +0200 Subject: [PATCH 09/68] chore(gen): review documentation MTA-5152 (#3837) * chore(gen): review documentation MTA-5152 * chore(gen): update --- .../cockpit/api-cli/configuring-grafana-agent.mdx | 6 +----- .../cockpit/reference-content/cockpit-limitations.mdx | 2 +- .../containers/how-to/add-trigger-to-a-container.mdx | 8 +++----- serverless/functions/how-to/add-trigger-to-a-function.mdx | 6 ++---- serverless/functions/how-to/test-a-function.mdx | 2 -- .../functions/reference-content/functions-handlers.mdx | 3 +-- serverless/messaging/api-cli/connect-aws-cli.mdx | 1 + serverless/messaging/api-cli/nats-cli.mdx | 1 + serverless/messaging/api-cli/python-node-sns.mdx | 1 + serverless/messaging/how-to/monitor-mnq-cockpit.mdx | 1 + serverless/messaging/reference-content/nats-overview.mdx | 1 + serverless/messaging/reference-content/sns-overview.mdx | 1 + serverless/messaging/reference-content/sqs-overview.mdx | 1 + 13 files changed, 15 insertions(+), 19 deletions(-) diff --git a/observability/cockpit/api-cli/configuring-grafana-agent.mdx b/observability/cockpit/api-cli/configuring-grafana-agent.mdx index 18880ce763..508c1a43b0 100644 --- a/observability/cockpit/api-cli/configuring-grafana-agent.mdx +++ b/observability/cockpit/api-cli/configuring-grafana-agent.mdx @@ -7,7 +7,7 @@ content: paragraph: This page provides information on how to configure the Grafana agent, push data sources, and visualize them in Grafana tags: cockpit observability grafana-agent dates: - validation: 2024-04-02 + validation: 2024-10-15 posted: 2023-01-10 categories: - observability @@ -32,7 +32,6 @@ This page explains how to configure the Grafana agent and the Zipkin collector t It is not currently possible to collect logs if you are using OSX. - 1. [Create a token](/observability/cockpit/how-to/create-token/) and select the push permission for metrics, traces, and logs. 2. Create a folder where you will keep your configuration files. 3. Create a configuration file inside your folder and name it `config.yaml`. This file will contain the Grafana agent configuration. @@ -263,6 +262,3 @@ This page explains how to configure the Grafana agent and the Zipkin collector t Refer to the [Grafana documentation](https://grafana.com/docs/grafana/latest/panels-visualizations/visualizations/traces/#add-a-panel-with-tracing-visualizations) to learn more about how to visualize your traces. - - - diff --git a/observability/cockpit/reference-content/cockpit-limitations.mdx b/observability/cockpit/reference-content/cockpit-limitations.mdx index 0156aa125f..1c60d6e170 100644 --- a/observability/cockpit/reference-content/cockpit-limitations.mdx +++ b/observability/cockpit/reference-content/cockpit-limitations.mdx @@ -88,7 +88,7 @@ Refer to our [documentation on understanding Cockpit usage and pricing](/observa | Messaging and Queuing SNS | **Integrated*** | Not integrated | Not integrated | | Instances | **Integrated*** | Not integrated | Not integrated | | Cockpit | **Integrated*** | Not integrated | Not integrated | -| Object Storage | **Integrated*** | Planned | Not integrated | +| Object Storage | **Integrated*** | **Integrated*** | Not integrated | | Serverless Containers | **Integrated*** | **Integrated*** | Not integrated | | Serverless Functions | **Integrated*** | **Integrated*** | Not integrated | | Serverless Jobs | **Integrated*** | **Integrated*** | Not integrated | diff --git a/serverless/containers/how-to/add-trigger-to-a-container.mdx b/serverless/containers/how-to/add-trigger-to-a-container.mdx index b2a0383771..ea2ebd38b0 100644 --- a/serverless/containers/how-to/add-trigger-to-a-container.mdx +++ b/serverless/containers/how-to/add-trigger-to-a-container.mdx @@ -7,7 +7,7 @@ content: paragraph: How to add triggers to Scaleway Serverless Containers. tags: containers dates: - validation: 2024-04-09 + validation: 2024-10-15 posted: 2023-04-27 categories: - serverless @@ -44,7 +44,7 @@ You can create triggers on private containers, but to update the privacy of a co SQS queues of the [Scaleway Messaging and Queuing](/serverless/messaging/quickstart/) product are compatible with Serverless Containers. -The configuration of the queue retention may affect the behavior of the trigger. Refer to the [Considerations to configure event retention for SQS trigger inputs](/serverless/containers/reference-content/configure-trigger-inputs/) page for more information. +The configuration of the queue retention can affect the behavior of the trigger. Refer to the [Considerations to configure event retention for SQS trigger inputs](/serverless/containers/reference-content/configure-trigger-inputs/) page for more information. 1. Click **Containers** in the **Serverless** section of the side menu. The containers page displays. 2. Click the relevant containers namespace. @@ -85,7 +85,5 @@ NATS subjects of the [Scaleway Messaging and Queuing](/serverless/messaging/quic The container will be invoked at the indicated time. - Refer to our [cron schedules reference](/serverless/containers/reference-content/cron-schedules/) for more information. + Refer to the [cron schedules reference](/serverless/containers/reference-content/cron-schedules/) for more information. - - diff --git a/serverless/functions/how-to/add-trigger-to-a-function.mdx b/serverless/functions/how-to/add-trigger-to-a-function.mdx index 757524c873..aaddb08b43 100644 --- a/serverless/functions/how-to/add-trigger-to-a-function.mdx +++ b/serverless/functions/how-to/add-trigger-to-a-function.mdx @@ -7,7 +7,7 @@ content: paragraph: Learn how to add triggers to your Serverless Functions in Scaleway. tags: functions dates: - validation: 2024-04-09 + validation: 2024-10-15 posted: 2023-04-27 categories: - serverless @@ -82,7 +82,5 @@ NATS subjects of the [Scaleway Messaging and Queuing](/serverless/messaging/quic 8. Click **Create trigger** to launch trigger creation. - Refer to our [cron schedules reference](/serverless/functions/reference-content/cron-schedules/) for more information. + Refer to the [cron schedules reference](/serverless/functions/reference-content/cron-schedules/) for more information. - - diff --git a/serverless/functions/how-to/test-a-function.mdx b/serverless/functions/how-to/test-a-function.mdx index 66987120a5..be4f554437 100644 --- a/serverless/functions/how-to/test-a-function.mdx +++ b/serverless/functions/how-to/test-a-function.mdx @@ -38,5 +38,3 @@ This page shows you how to execute Serverless Functions from the [Scaleway conso 8. Click **Run**. The **Output** section displays the response from your function and the status code. - - diff --git a/serverless/functions/reference-content/functions-handlers.mdx b/serverless/functions/reference-content/functions-handlers.mdx index faa8c30732..c0ce632b2a 100644 --- a/serverless/functions/reference-content/functions-handlers.mdx +++ b/serverless/functions/reference-content/functions-handlers.mdx @@ -7,7 +7,7 @@ content: paragraph: Discover how to implement function handlers for Serverless Functions in Scaleway. tags: serverless functions cron crontab schedule cronjob dates: - validation: 2024-04-09 + validation: 2024-10-15 posted: 2024-04-09 categories: - serverless @@ -81,4 +81,3 @@ categories: - diff --git a/serverless/messaging/api-cli/connect-aws-cli.mdx b/serverless/messaging/api-cli/connect-aws-cli.mdx index f865a7ab00..52c7e2e486 100644 --- a/serverless/messaging/api-cli/connect-aws-cli.mdx +++ b/serverless/messaging/api-cli/connect-aws-cli.mdx @@ -11,6 +11,7 @@ categories: dates: validation: 2024-04-09 posted: 2023-01-04 +validation_frequency: 8 --- The AWS-CLI is an open-source tool built on top of the AWS SDK for Python (Boto) that provides commands for interacting with AWS services. With minimal configuration, you can start using the AWS-CLI with Scaleway Messaging and Queuing SQS and/or SNS. This allows you to create, list and manage your queues and topics, send messages and much more, all from your command line. diff --git a/serverless/messaging/api-cli/nats-cli.mdx b/serverless/messaging/api-cli/nats-cli.mdx index b013786dac..f98fe2ef1b 100644 --- a/serverless/messaging/api-cli/nats-cli.mdx +++ b/serverless/messaging/api-cli/nats-cli.mdx @@ -11,6 +11,7 @@ categories: dates: validation: 2024-04-09 posted: 2023-01-20 +validation_frequency: 8 --- The NATS CLI (`nats`) is the official NATS tool for managing your NATS resources. It allows you to simply create and manage your streams, consumers and more. diff --git a/serverless/messaging/api-cli/python-node-sns.mdx b/serverless/messaging/api-cli/python-node-sns.mdx index fd2b34dda7..37b900b061 100644 --- a/serverless/messaging/api-cli/python-node-sns.mdx +++ b/serverless/messaging/api-cli/python-node-sns.mdx @@ -11,6 +11,7 @@ categories: dates: validation: 2024-04-09 posted: 2023-01-04 +validation_frequency: 8 --- AWS provides a number of **S**oftware **D**evelopment **K**its (SDKs) which provide language-specific APIs for AWS services, including [SNS](/serverless/messaging/concepts/#sns). diff --git a/serverless/messaging/how-to/monitor-mnq-cockpit.mdx b/serverless/messaging/how-to/monitor-mnq-cockpit.mdx index 3359fc4cd5..fb5e6a80c6 100644 --- a/serverless/messaging/how-to/monitor-mnq-cockpit.mdx +++ b/serverless/messaging/how-to/monitor-mnq-cockpit.mdx @@ -11,6 +11,7 @@ categories: dates: validation: 2024-04-09 posted: 2023-09-07 +validation_frequency: 8 --- You can view your Messaging and Queuing metrics via [Scaleway Cockpit](/observability/cockpit/quickstart/). This allows you to monitor your queues/streams and messages at a glance. There are two steps to complete to view your Messaging and Queuing metrics for the first time with Cockpit: diff --git a/serverless/messaging/reference-content/nats-overview.mdx b/serverless/messaging/reference-content/nats-overview.mdx index 373dc27e96..563ba97f16 100644 --- a/serverless/messaging/reference-content/nats-overview.mdx +++ b/serverless/messaging/reference-content/nats-overview.mdx @@ -11,6 +11,7 @@ categories: dates: validation: 2024-04-09 posted: 2023-01-04 +validation_frequency: 8 --- ## What is NATS? diff --git a/serverless/messaging/reference-content/sns-overview.mdx b/serverless/messaging/reference-content/sns-overview.mdx index bec9dcf06f..4318f12b7d 100644 --- a/serverless/messaging/reference-content/sns-overview.mdx +++ b/serverless/messaging/reference-content/sns-overview.mdx @@ -11,6 +11,7 @@ categories: dates: validation: 2024-04-09 posted: 2023-01-04 +validation_frequency: 8 --- ## What is SNS? diff --git a/serverless/messaging/reference-content/sqs-overview.mdx b/serverless/messaging/reference-content/sqs-overview.mdx index cd3cdcd732..01aa050265 100644 --- a/serverless/messaging/reference-content/sqs-overview.mdx +++ b/serverless/messaging/reference-content/sqs-overview.mdx @@ -11,6 +11,7 @@ categories: dates: validation: 2024-04-09 posted: 2023-01-04 +validation_frequency: 8 --- ## What is SQS? From e98228df26972f14500a8d59ffce349ac420082a Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 17 Oct 2024 14:42:32 +0200 Subject: [PATCH 10/68] feat(k8s): add information about routed ip migration completed (#3849) --- .../reference-content/move-kubernetes-nodes-routed-ip.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/containers/kubernetes/reference-content/move-kubernetes-nodes-routed-ip.mdx b/containers/kubernetes/reference-content/move-kubernetes-nodes-routed-ip.mdx index 814921080d..26060364f2 100644 --- a/containers/kubernetes/reference-content/move-kubernetes-nodes-routed-ip.mdx +++ b/containers/kubernetes/reference-content/move-kubernetes-nodes-routed-ip.mdx @@ -7,12 +7,16 @@ content: paragraph: Safely moving Kubernetes nodes to routed IPs tags: routed-ip ip-mobility kubernetes kapsule kosmos dates: - validation: 2024-06-03 + validation: 2024-10-17 posted: 2024-04-22 categories: - kubernetes --- + + The migration of all Kubernetes nodes to routed IP has been successfully completed. No further action is required on your part. This documentation is retained **for reference purposes only**. + + As part of our ongoing efforts to enhance infrastructure capabilities and provide better services to our customers, Scaleway is [introducing routed IPs for all products](https://www.scaleway.com/en/news/routed-ips-are-coming-to-all-scaleway-products/), including Kubernetes (K8s) worker nodes. One of the standout benefits of routed IPs is their support for [IP mobility](/compute/instances/concepts/#ip-mobility), streamlining IP management and movement within the Scaleway ecosystem. By simplifying the process of reallocating IPs across different products, routed IPs empower users with unprecedented flexibility and control over their network infrastructure. From c031a64ef112fd5d82f4f24fda040e63bb341701 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 17 Oct 2024 14:45:52 +0200 Subject: [PATCH 11/68] feat(ins): update create instance (#3850) * feat(ins): update create instance * Update compute/instances/how-to/create-an-instance.mdx Co-authored-by: SamyOubouaziz * Update compute/instances/quickstart.mdx Co-authored-by: SamyOubouaziz --------- Co-authored-by: SamyOubouaziz --- .../instances/how-to/create-an-instance.mdx | 25 ++++----- compute/instances/quickstart.mdx | 55 +++++++++---------- 2 files changed, 39 insertions(+), 41 deletions(-) diff --git a/compute/instances/how-to/create-an-instance.mdx b/compute/instances/how-to/create-an-instance.mdx index 876e07de7e..1df85f2987 100644 --- a/compute/instances/how-to/create-an-instance.mdx +++ b/compute/instances/how-to/create-an-instance.mdx @@ -31,29 +31,28 @@ Select a tab below for instructions on how to create an Instance via either our 1. Click **Instances** in the **Compute** section of the side menu. The [Instance dashboard](https://console.scaleway.com/instance/servers) displays. 2. Click **Create Instance**. The [Instance creation page](https://console.scaleway.com/instance/servers) displays. 3. Complete the following steps: - - Choose an **Availability Zone**, which represents the geographical region where your Instance will be deployed. - - Choose an **Instance type**.
+ - **Choose an Availability Zone**, which represents the geographical region where your Instance will be deployed. + - **Choose an Instance type**.
Instance offers vary in pricing, processing power, memory, storage, and bandwidth. [Discover the best Instance type for your needs](/compute/instances/reference-content/choosing-instance-type/). - - Choose an **Image** to run on your Instance.
+ - ***Choose an Image** to run on your Instance.
This can be an operating system, an InstantApp, or a custom image. [Check all available Linux distributions and InstantApps](/compute/instances/reference-content/images-and-instantapps/). - - Add **Volumes**, which are storage spaces used by your Instances. - - For **GP1 Instances** you can leave the default settings of maximum local storage, or choose how much [local](/compute/instances/concepts/#local-volumes) and/or [block](/compute/instances/concepts/#block-volumes) storage you want. Your **system volume** is the volume on which your Instance will boot. The system volume can be either a local or a block volume. - - **PLAY2**, **PRO2**, and **Enterprise** Instances boot directly [on block volumes](/compute/instances/concepts/#boot-on-block). You can add several block volumes and define how much storage you want for each. + - **Name** your Instance, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. + - **Add Volumes**, which are storage spaces used by your Instances. A block volume with a default name and 5,000 IOPS is automatically provided for your system volume. You can customize this volume and attach up up to 16 local and/or block type volumes as needed. - - Ensure that a volume with an OS image has a minimum capacity of 10 GB. For a GPU OS, the recommended size is 125 GB. + - Ensure that the volume containing your OS image has a minimum size of 10 GB. For a GPU OS, the recommended size is 125 GB. - When multiple Block Storage volumes are linked to your Instance, the primary volume will host the OS and is essential for booting the Instance. Once the Instance is created can [modify your boot volume](/compute/instances/how-to/use-boot-modes/#how-to-change-the-boot-volume). - Booting from a volume that either lacks an OS or is among multiple volumes with identical operating systems can lead to inconsistent boot outcomes. - - Configure the network of the Instance. You can either select to use **Routed public IP** (a dedicated public IP address routed to your Instance that allows direct communication between the Instance and the Internet) or a **NAT public IP** (a public IP address that uses a carrier-grade NAT to translate the Instances NAT IP address). If you are unsure which to use, we recommend a routed public IP for ease of use and improved performance. + - **Configure network** of the Instance. - Leave the checkbox ticked to assign a **Public IPv4** to the Instance. You can either allocate a new IPv4 address or select one or multiple existing IPv4s. Alternatively, uncheck the box if you do not want an IPv4. - Leave the checkbox ticked to assign a **Public IPv6** to the Instance. You can either allocate a new IPv6 address or select one or multiple existing IPv6s. Alternatively, uncheck the box if you do not want an IPv6. - You can attach up to 5 IPs to an Instance, combining IPv4 and IPv6 addresses. + You can attach up to 5 IPs to an Instance, combining IPv4 and IPv6 addresses, which is useful for running different services or applications on the same Instance. - - Enter a **Name** for your Instance, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. - - Click **Advanced options** if you want to configure a [cloud-init configuration](/compute/instances/concepts/#cloud-init). Otherwise, leave these options at their default values. - - Verify the [SSH keys](/console/account/concepts/#ssh-key) that will give you access to your Instance. - - Verify the **Estimated cost** of your Instance, based on the specifications you chose. + - (Optional) Click **Advanced options** to configure a [cloud-init configuration](/compute/instances/concepts/#cloud-init). Otherwise, leave these options at their default values. + You can configure a cloud-init script to automate instance setup, such as setting up software, users, and system configurations at the first boot. + - **Verify the [SSH keys](/console/account/concepts/#ssh-key)** that will give you access to your Instance. + - **Verify the Estimated cost** of your Instance, based on the specifications you chose. 4. Click **Create Instance**. The creation of your Instance begins, and you will be informed when the Instance is ready. Your Instance is now created, and you are redirected to the **Overview** tab. From here, you can see information including your Instance's Public IP, the SSH command to use to [connect to it](/compute/instances/how-to/create-an-instance/), and other information, settings, and actions for the Instance. diff --git a/compute/instances/quickstart.mdx b/compute/instances/quickstart.mdx index 8e6413c72d..d3a60ef806 100644 --- a/compute/instances/quickstart.mdx +++ b/compute/instances/quickstart.mdx @@ -23,34 +23,33 @@ Scaleway [Instances](/compute/instances/concepts/#instance) are computing units ## How to create an Instance -1. Click **Instances** in the **Compute** section of the side menu. The [Instance dashboard](https://console.scaleway.com/instance/servers) displays. -2. Click **Create Instance**. The [Instance creation page](https://console.scaleway.com/instance/servers) displays. -3. Complete the following steps: - - Choose an **Availability Zone**, which represents the geographical region where your Instance will be deployed. - - Choose an **Instance type**.
- Instance offers vary in pricing, processing power, memory, storage, and bandwidth. [Discover the best Instance type for your needs](/compute/instances/reference-content/choosing-instance-type/). - - Choose an **Image** to run on your Instance.
- This can be an operating system, an InstantApp, or a custom image. [Check all available Linux distributions and InstantApps](/compute/instances/reference-content/images-and-instantapps/). - - Add **Volumes**, which are storage spaces used by your Instances. - - For **GP1 Instances** you can leave the default settings of maximum local storage, or choose how much [local](/compute/instances/concepts/#local-volumes) and/or [block](/compute/instances/concepts/#block-volumes) storage you want. Your **system volume** is the volume on which your Instance will boot. The system volume can be either a local or a block volume. - - **PLAY2**, **PRO2**, and **Enterprise** Instances boot directly [on block volumes](/compute/instances/concepts/#boot-on-block). You can add several block volumes and define how much storage you want for each. - - - Ensure that a volume with an OS image has a minimum capacity of 10 GB. For a GPU OS, the recommended size is 125 GB. - - The minimum volume size for Microsoft Windows OS is 25 GB. - - When multiple Block Storage volumes are linked to your Instance, the primary volume will host the OS and is essential for booting the Instance. Once the Instance is created can [modify your boot volume](/compute/instances/how-to/use-boot-modes/#how-to-change-the-boot-volume). - - Booting from a volume that either lacks an OS or is among multiple volumes with identical operating systems can lead to inconsistent boot outcomes. - - - Configure the network of the Instance. You can either select to use **Routed public IP** (a dedicated public IP address routed to your Instance that allows direct communication between the Instance and the Internet) or a **NAT public IP** (a public IP address that uses a carrier-grade NAT to translate the Instances NAT IP address). If you are unsure which to use, we recommend a routed public IP for ease of use and improved performance. - - Leave the checkbox ticked to assign a **Public IPv4** to the Instance. You can either allocate a new IPv4 address or select one or multiple existing IPv4s. Alternatively, uncheck the box if you do not want an IPv4. - - Leave the checkbox ticked to assign a **Public IPv6** to the Instance. You can either allocate a new IPv6 address or select one or multiple existing IPv46. Alternatively, uncheck the box if you do not want an IPv4. - - You can attach up to 5 IPs to an Instance, combining IPv4 and IPv6 addresses. - - - Enter a **Name** for your Instance, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. - - Click **Advanced options** if you want to configure a [cloud-init configuration](/compute/instances/concepts/#cloud-init). Otherwise, leave these options at their default values. - - Verify the [SSH keys](/console/account/concepts/#ssh-key) that will give you access to your Instance. - - Verify the **Estimated cost** of your Instance, based on the specifications you chose. -4. Click **Create Instance**. The creation of your Instance begins, and you will be informed when the Instance is ready. + 1. Click **Instances** in the **Compute** section of the side menu. The [Instance dashboard](https://console.scaleway.com/instance/servers) displays. + 2. Click **Create Instance**. The [Instance creation page](https://console.scaleway.com/instance/servers) displays. + 3. Complete the following steps: + - **Choose an Availability Zone**, which represents the geographical region where your Instance will be deployed. + - **Choose an Instance type**.
+ Instance offers vary in pricing, processing power, memory, storage, and bandwidth. [Discover the best Instance type for your needs](/compute/instances/reference-content/choosing-instance-type/). + - ***Choose an Image** to run on your Instance.
+ This can be an operating system, an InstantApp, or a custom image. [Check all available Linux distributions and InstantApps](/compute/instances/reference-content/images-and-instantapps/). + - **Name** your Instance, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. + - **Add Volumes**, which are storage spaces used by your Instances. A block volume with a default name and 5,000 IOPS is automatically provided for your system volume. You can customize this volume and attach up up to 16 local and/or block type volumes as needed. + + - Ensure that the volume containing your OS image has a minimum size of 10 GB. For a GPU OS, the recommended size is 125 GB. + - When multiple Block Storage volumes are linked to your Instance, the primary volume will host the OS and is essential for booting the Instance. Once the Instance is created can [modify your boot volume](/compute/instances/how-to/use-boot-modes/#how-to-change-the-boot-volume). + - Booting from a volume that either lacks an OS or is among multiple volumes with identical operating systems can lead to inconsistent boot outcomes. + + - **Configure network** of the Instance. + - Leave the checkbox ticked to assign a **Public IPv4** to the Instance. You can either allocate a new IPv4 address or select one or multiple existing IPv4s. Alternatively, uncheck the box if you do not want an IPv4. + - Leave the checkbox ticked to assign a **Public IPv6** to the Instance. You can either allocate a new IPv6 address or select one or multiple existing IPv6s. Alternatively, uncheck the box if you do not want an IPv6. + + You can attach up to 5 IPs to an Instance, combining IPv4 and IPv6 addresses, which is useful for running different services or applications on the same Instance. + + - (Optional) Click **Advanced options** to configure a [cloud-init configuration](/compute/instances/concepts/#cloud-init). Otherwise, leave these options at their default values. + You can configure a cloud-init script to automate instance setup, such as setting up software, users, and system configurations at the first boot. + - **Verify the [SSH keys](/console/account/concepts/#ssh-key)** that will give you access to your Instance. + - **Verify the Estimated cost** of your Instance, based on the specifications you chose. + 4. Click **Create Instance**. The creation of your Instance begins, and you will be informed when the Instance is ready. + Once the Instance is created, you can connect to it using the SSH keys you have configured, and begin setting up your applications ## How to connect to an Instance From f8af3611158a057d5c896d1969b4490ac4176f23 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 17 Oct 2024 14:58:51 +0200 Subject: [PATCH 12/68] fix(tem): fix missing closing tag (#3851) --- .../reference-content/tem-capabilities-and-limits.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx b/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx index eeff48c158..eec3d1b6f0 100644 --- a/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx +++ b/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx @@ -25,6 +25,7 @@ New users may face stricter initial limits, while well-known customers can benef Customers must adhere to industry standards and our [General Terms of Services](https://www-uploads.scaleway.com/General_Terms_of_Services_v17072024_45d4879c08.pdf), including compliance with [Scaleway's anti-spam policy](https://tem.s3.fr-par.scw.cloud/antispam_policy.pdf). Failure to comply may result in temporary or permanent restrictions to the service. + ## Transactional Email service quotas From 9189c884aa97a454245a76fb680f5f269fced9c7 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 17 Oct 2024 15:11:31 +0200 Subject: [PATCH 13/68] chore(gen): review iam and labs 2024-10-16 (#3845) --- .../iam/reference-content/overview.mdx | 2 +- .../iam/reference-content/policy.mdx | 2 +- .../reference-content/reproduce-roles-project-api-keys.mdx | 2 +- .../iam/reference-content/users-groups-and-applications.mdx | 2 +- .../organizations-and-projects/concepts.mdx | 6 +++--- labs/ipfs-naming/concepts.mdx | 2 +- labs/ipfs-pinning/concepts.mdx | 2 +- .../ipfs-pinning/reference-content/install-ipfs-desktop.mdx | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/identity-and-access-management/iam/reference-content/overview.mdx b/identity-and-access-management/iam/reference-content/overview.mdx index f18c4a683f..7cb9d1a04f 100644 --- a/identity-and-access-management/iam/reference-content/overview.mdx +++ b/identity-and-access-management/iam/reference-content/overview.mdx @@ -7,7 +7,7 @@ content: paragraph: High-level overview of Scaleway IAM features. tags: iam dates: - validation: 2024-04-01 + validation: 2024-10-16 categories: - iam - console diff --git a/identity-and-access-management/iam/reference-content/policy.mdx b/identity-and-access-management/iam/reference-content/policy.mdx index a9bd3e1715..25344af96f 100644 --- a/identity-and-access-management/iam/reference-content/policy.mdx +++ b/identity-and-access-management/iam/reference-content/policy.mdx @@ -7,7 +7,7 @@ content: paragraph: Detailed additional content for policies within Scaleway IAM. tags: iam dates: - validation: 2024-04-01 + validation: 2024-10-16 categories: - iam - console diff --git a/identity-and-access-management/iam/reference-content/reproduce-roles-project-api-keys.mdx b/identity-and-access-management/iam/reference-content/reproduce-roles-project-api-keys.mdx index bb92ff5e8f..420707f26c 100644 --- a/identity-and-access-management/iam/reference-content/reproduce-roles-project-api-keys.mdx +++ b/identity-and-access-management/iam/reference-content/reproduce-roles-project-api-keys.mdx @@ -7,7 +7,7 @@ content: paragraph: This page explains how to generate an access system similar to Scaleway's roles feature and Project-scoped API keys, that existed before IAM. tags: iam dates: - validation: 2024-04-01 + validation: 2024-10-16 categories: - iam - console diff --git a/identity-and-access-management/iam/reference-content/users-groups-and-applications.mdx b/identity-and-access-management/iam/reference-content/users-groups-and-applications.mdx index 79ac30568b..12c99168dd 100644 --- a/identity-and-access-management/iam/reference-content/users-groups-and-applications.mdx +++ b/identity-and-access-management/iam/reference-content/users-groups-and-applications.mdx @@ -6,7 +6,7 @@ content: h1: Users, groups, and applications paragraph: Manage users, groups, and applications within Scaleway IAM. dates: - validation: 2024-04-01 + validation: 2024-10-16 --- IAM users, groups, and applications are principals in Scaleway Organizations. A principal is an entity that can be attached to policy. diff --git a/identity-and-access-management/organizations-and-projects/concepts.mdx b/identity-and-access-management/organizations-and-projects/concepts.mdx index fc7bdc0d3b..8d119e1394 100644 --- a/identity-and-access-management/organizations-and-projects/concepts.mdx +++ b/identity-and-access-management/organizations-and-projects/concepts.mdx @@ -7,7 +7,7 @@ content: paragraph: This page explains all the concepts related to Organizations and Projects tags: access-key organization secret-key ssh-key owner dates: - validation: 2024-04-01 + validation: 2024-10-16 categories: - console --- @@ -30,9 +30,9 @@ The Organization ID identifies the [Organization](#organization) created with yo A Project is a grouping of Scaleway [resources](#resource). Each Scaleway Organization comes with a default Project, and you can create new Projects if necessary. Projects are cross-region, meaning resources located in different [regions](/compute/instances/concepts/#region) can be grouped in one single Project. When grouping resources into different Projects, you can use [IAM](/identity-and-access-management/iam/concepts/#iam) to define custom access rights for each Project. -## Project Dashboard +## Project dashboard -The Project Dashboard can be viewed within the [console](https://console.scaleway.com/project). On this dashboard, you can see an overview of the Project's [resources](#resources), along with the Project's settings and credentials ([SSH keys](#ssh-key)). +The Project dashboard can be viewed within the [console](https://console.scaleway.com/project). On this dashboard, you can see an overview of the Project's [resources](#resources), along with the Project's settings and credentials ([SSH keys](#ssh-key)). ## Resource diff --git a/labs/ipfs-naming/concepts.mdx b/labs/ipfs-naming/concepts.mdx index 4979846163..672fbd6739 100644 --- a/labs/ipfs-naming/concepts.mdx +++ b/labs/ipfs-naming/concepts.mdx @@ -7,7 +7,7 @@ content: paragraph: This page explains all concepts related to IPFS Naming tags: ipfs-naming naming ipfs versioning labs web3 cid dates: - validation: 2024-04-08 + validation: 2024-10-16 categories: - labs - naming diff --git a/labs/ipfs-pinning/concepts.mdx b/labs/ipfs-pinning/concepts.mdx index 3444a8a9e7..0939f180b8 100644 --- a/labs/ipfs-pinning/concepts.mdx +++ b/labs/ipfs-pinning/concepts.mdx @@ -7,7 +7,7 @@ content: paragraph: This page explains all concepts related to IPFS Pinning tags: ipfs-pinning storage pinning volume ipfs versioning labs web3 cid dates: - validation: 2024-04-08 + validation: 2024-10-16 categories: - labs - storage diff --git a/labs/ipfs-pinning/reference-content/install-ipfs-desktop.mdx b/labs/ipfs-pinning/reference-content/install-ipfs-desktop.mdx index 87c5b5d720..3e5753351e 100644 --- a/labs/ipfs-pinning/reference-content/install-ipfs-desktop.mdx +++ b/labs/ipfs-pinning/reference-content/install-ipfs-desktop.mdx @@ -7,7 +7,7 @@ content: paragraph: This page shows you how to use Scaleway IPFS Pinning with IPFS Desktop tags: ipfs pinning storage ipfs-storage volume desktop labs web3 dates: - validation: 2024-04-03 + validation: 2024-10-16 posted: 2023-09-26 categories: - labs From f7ee3a3193e87ed9899c85d42a4fb51e8c0d02c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oc=C3=A9ane?= Date: Fri, 18 Oct 2024 10:54:17 +0200 Subject: [PATCH 14/68] feat(changelog): transactional-email-changed-increase-in-minimum-quotas 2024-10-17 (#3853) * feat(changelog): add new entry * Apply suggestions from code review * Update changelog/october2024/2024-10-17-transactional-email-changed-increase-in-minimum-quotas.mdx * Update changelog/october2024/2024-10-17-transactional-email-changed-increase-in-minimum-quotas.mdx * Apply suggestions from code review Co-authored-by: SamyOubouaziz * Apply suggestions from code review --------- Co-authored-by: Changelog bot Co-authored-by: Benedikt Rollik Co-authored-by: SamyOubouaziz --- ...al-email-changed-increase-in-minimum-quotas.mdx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 changelog/october2024/2024-10-17-transactional-email-changed-increase-in-minimum-quotas.mdx diff --git a/changelog/october2024/2024-10-17-transactional-email-changed-increase-in-minimum-quotas.mdx b/changelog/october2024/2024-10-17-transactional-email-changed-increase-in-minimum-quotas.mdx new file mode 100644 index 0000000000..5454431049 --- /dev/null +++ b/changelog/october2024/2024-10-17-transactional-email-changed-increase-in-minimum-quotas.mdx @@ -0,0 +1,14 @@ +--- +title: Increase in default email sending quotas +status: changed +author: + fullname: 'Join the #transactional-email channel on Slack.' + url: 'https://slack.scaleway.com' +date: 2024-10-17 +category: managed-services +product: transactional-email +--- + +We have updated the default email sending quotas to better align with your needs. The new limits are available on the [capabilities and limits](/managed-services/transactional-email/reference-content/tem-capabilities-and-limits/) page. These changes offer greater flexibility and optimization capabilities for managing your email volumes. + + From caa3b33246318f3b3d8ae6c2f50e4ab961b15450 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Fri, 18 Oct 2024 11:01:15 +0200 Subject: [PATCH 15/68] fix(tem): fix wrong validation date (#3852) * fix(tem): fixed note content * fix(tem): fix typo * fix(tem): fix validation date * fix(tem): typo * fix(tem): typo * Apply suggestions from code review --- .../reference-content/tem-capabilities-and-limits.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx b/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx index eec3d1b6f0..00e988ada6 100644 --- a/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx +++ b/managed-services/transactional-email/reference-content/tem-capabilities-and-limits.mdx @@ -7,7 +7,7 @@ content: paragraph: Understand the capabilities and limits of Scaleway Transactional Email. tags: transactional email-capabilities transactional-email quotas dates: - validation: 2024-05-21 + validation: 2024-10-17 posted: 2022-11-07 categories: - managed-services @@ -29,7 +29,7 @@ New users may face stricter initial limits, while well-known customers can benef ## Transactional Email service quotas -| **Quota** | **Minimum Quota** | **Maximum Quota** | **Upgradable** | +| Quota | Default Quota | Maximum Quota | Upgradable | |------------------------------------------------|-------------------|-------------------|----------------| | Maximum number of emails per month | 10,000 | Unlimited | Yes | | Maximum number of attachments per email | 10 | Custom defined | Yes | From eaa21f7153d9a144c7211d01a77e47df072ec821 Mon Sep 17 00:00:00 2001 From: Pierre Ozoux Date: Fri, 18 Oct 2024 15:21:47 +0200 Subject: [PATCH 16/68] fix: clarify partition labels (#3855) * fix: clarify partition labels * Update bare-metal/elastic-metal/how-to/configure-disk-partitions.mdx Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> --------- Co-authored-by: Benedikt Rollik Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> --- bare-metal/elastic-metal/how-to/configure-disk-partitions.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bare-metal/elastic-metal/how-to/configure-disk-partitions.mdx b/bare-metal/elastic-metal/how-to/configure-disk-partitions.mdx index 3838afbdf5..25788b95a0 100644 --- a/bare-metal/elastic-metal/how-to/configure-disk-partitions.mdx +++ b/bare-metal/elastic-metal/how-to/configure-disk-partitions.mdx @@ -163,7 +163,7 @@ Below is an example of how to define a partitioning schema with RAID and NVMe di - Disks: - Each disk is specified with its device path (e.g., `/dev/nvme0n1` or `/dev/nvme1n1`). - - Partitions are defined with labels like `swap`, `boot`, `root`, `data`, and an optional `uefi` partition for systems using UEFI. + - Partitions are defined with labels. The default value is `unknown_partition_label`, and possible values are: `uefi`, `legacy`, `root`, `boot`, `swap`, `data`, `home`, `raid`. Refer to the [API documentation](https://www.scaleway.com/en/developers/api/elastic-metal/#path-servers-install-an-elastic-metal-server) for full details. - Each partition has a `number` and `size` in bytes. - RAID (Optional): @@ -224,4 +224,4 @@ If you prefer a simpler configuration without RAID or ZFS, you can remove the `r "lvm": null } } -``` \ No newline at end of file +``` From b03b49cda9b427ea9bcfb31fa2ba78c78c534a4d Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Mon, 21 Oct 2024 10:51:36 +0200 Subject: [PATCH 17/68] fix(ins): fix create doc for windows and typos (#3854) * fix(ins): fix create doc for windows and typos * Update compute/instances/how-to/create-an-instance.mdx * docs(ins): fix typo * Apply suggestions from code review Co-authored-by: ldecarvalho-doc <82805470+ldecarvalho-doc@users.noreply.github.com> --------- Co-authored-by: ldecarvalho-doc <82805470+ldecarvalho-doc@users.noreply.github.com> --- .../instances/how-to/create-an-instance.mdx | 27 ++++++++++--------- compute/instances/quickstart.mdx | 8 +++--- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/compute/instances/how-to/create-an-instance.mdx b/compute/instances/how-to/create-an-instance.mdx index 1df85f2987..0694ea47ac 100644 --- a/compute/instances/how-to/create-an-instance.mdx +++ b/compute/instances/how-to/create-an-instance.mdx @@ -34,10 +34,10 @@ Select a tab below for instructions on how to create an Instance via either our - **Choose an Availability Zone**, which represents the geographical region where your Instance will be deployed. - **Choose an Instance type**.
Instance offers vary in pricing, processing power, memory, storage, and bandwidth. [Discover the best Instance type for your needs](/compute/instances/reference-content/choosing-instance-type/). - - ***Choose an Image** to run on your Instance.
+ - **Choose an image** to run on your Instance.
This can be an operating system, an InstantApp, or a custom image. [Check all available Linux distributions and InstantApps](/compute/instances/reference-content/images-and-instantapps/). - - **Name** your Instance, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. - - **Add Volumes**, which are storage spaces used by your Instances. A block volume with a default name and 5,000 IOPS is automatically provided for your system volume. You can customize this volume and attach up up to 16 local and/or block type volumes as needed. + - **Name your Instance**, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. + - **Add volumes**, which are storage spaces used by your Instances. A block volume with a default name and 5,000 IOPS is automatically provided for your system volume. You can customize this volume and attach up to 16 local and/or block type volumes as needed. - Ensure that the volume containing your OS image has a minimum size of 10 GB. For a GPU OS, the recommended size is 125 GB. - When multiple Block Storage volumes are linked to your Instance, the primary volume will host the OS and is essential for booting the Instance. Once the Instance is created can [modify your boot volume](/compute/instances/how-to/use-boot-modes/#how-to-change-the-boot-volume). @@ -50,7 +50,7 @@ Select a tab below for instructions on how to create an Instance via either our You can attach up to 5 IPs to an Instance, combining IPv4 and IPv6 addresses, which is useful for running different services or applications on the same Instance. - (Optional) Click **Advanced options** to configure a [cloud-init configuration](/compute/instances/concepts/#cloud-init). Otherwise, leave these options at their default values. - You can configure a cloud-init script to automate instance setup, such as setting up software, users, and system configurations at the first boot. + You can configure a cloud-init script to automate Instance setup, such as setting up software, users, and system configurations at the first boot. - **Verify the [SSH keys](/console/account/concepts/#ssh-key)** that will give you access to your Instance. - **Verify the Estimated cost** of your Instance, based on the specifications you chose. 4. Click **Create Instance**. The creation of your Instance begins, and you will be informed when the Instance is ready. @@ -71,23 +71,24 @@ Select a tab below for instructions on how to create an Instance via either our 2. Click **Create Instance**. The [Instance creation page](https://console.scaleway.com/instance/servers) displays. 3. Complete the following steps: - Choose an **Availability Zone**, which represents the geographical region where your Instance will be deployed. - - Choose a **POP2-WIN** Instance type from the **Production-Optimized** range. - - Choose a **Windows Server** Image to run on your Instance. - - Add **Volumes**, which are storage spaces used by your Instances. You can add several block volumes and define how much storage you want for each. + - **Choose a POP2-WIN** Instance type from the **Production-Optimized** range. + - **Choose a Windows Server image** to run on your Instance. + - **Name your Instance**, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. + - **Add volumes**, which are storage spaces used by your Instances. A block volume with a default name and 5,000 IOPS is automatically provided for your system volume. You can customize this volume and attach up to 16 local and/or block type volumes as needed. - - Ensure that a volume with a Windows image has a minimum capacity of 25 GB. + - Ensure that a volume containing a Windows Server image has a minimum capacity of 25 GB. - When multiple Block Storage volumes are linked to your Instance, the primary volume will host the OS and is essential for booting the Instance. Once the Instance is created can [modify your boot volume](/compute/instances/how-to/use-boot-modes/#how-to-change-the-boot-volume). - Booting from a volume that either lacks an OS or is among multiple volumes with identical operating systems can lead to inconsistent boot outcomes. - - Configure the network of the Instance. You can either select to use **Routed public IP** (a dedicated public IP address routed to your Instance that allows direct communication between the Instance and the Internet) or a **NAT public IP** (a public IP address that uses a carrier-grade NAT to translate the Instances NAT IP address). If you are unsure which to use, we recommend a routed public IP for ease of use and improved performance. + - **Configure network** of the Instance. - Leave the checkbox ticked to assign a **Public IPv4** to the Instance. You can either allocate a new IPv4 address or select one or multiple existing IPv4s. Alternatively, uncheck the box if you do not want an IPv4. - Leave the checkbox ticked to assign a **Public IPv6** to the Instance. You can either allocate a new IPv6 address or select one or multiple existing IPv6s. Alternatively, uncheck the box if you do not want an IPv6. - You can attach up to 5 IPs to an Instance, combining IPv4 and IPv6 addresses. + You can attach up to 5 IPs to an Instance, combining IPv4 and IPv6 addresses, which is useful for running different services or applications on the same Instance. - - Enter a **Name** for your Instance, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. - - Click **Advanced options** if you want to configure a [cloud-init configuration](/compute/instances/concepts/#cloud-init). Otherwise, leave these options at their default values. - - Choose the [RSA SSH key](/identity-and-access-management/organizations-and-projects/how-to/create-ssh-key/#how-to-generate-a-rsa-ssh-key-pair) that will give you access to your Instance. If you do not have an RSA SSH key yet, click **Add RSA SSH key** and follow the steps indicated. + - (Optional) Click **Advanced options** to configure a [cloud-init configuration](/compute/instances/concepts/#cloud-init). Otherwise, leave these options at their default values. + You can configure a cloud-init script to automate Instance setup, such as setting up software, users, and system configurations at the first boot. + - **Choose the [RSA SSH key](/identity-and-access-management/organizations-and-projects/how-to/create-ssh-key/#how-to-generate-a-rsa-ssh-key-pair)** that will give you access to your Instance. If you do not have an RSA SSH key yet, click **Add RSA SSH key** and follow the steps indicated. - Verify the **Estimated cost** of your Instance, based on the specifications you chose. 4. Click **Create Instance**. The creation of your Instance begins, and you will be informed when the Instance is ready. diff --git a/compute/instances/quickstart.mdx b/compute/instances/quickstart.mdx index d3a60ef806..2fd268fd79 100644 --- a/compute/instances/quickstart.mdx +++ b/compute/instances/quickstart.mdx @@ -29,10 +29,10 @@ Scaleway [Instances](/compute/instances/concepts/#instance) are computing units - **Choose an Availability Zone**, which represents the geographical region where your Instance will be deployed. - **Choose an Instance type**.
Instance offers vary in pricing, processing power, memory, storage, and bandwidth. [Discover the best Instance type for your needs](/compute/instances/reference-content/choosing-instance-type/). - - ***Choose an Image** to run on your Instance.
+ - ***Choose an image** to run on your Instance.
This can be an operating system, an InstantApp, or a custom image. [Check all available Linux distributions and InstantApps](/compute/instances/reference-content/images-and-instantapps/). - - **Name** your Instance, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. - - **Add Volumes**, which are storage spaces used by your Instances. A block volume with a default name and 5,000 IOPS is automatically provided for your system volume. You can customize this volume and attach up up to 16 local and/or block type volumes as needed. + - **Name your Instance**, or leave the randomly-generated name in place. Optionally, you can add [tags](/compute/instances/concepts/#tags) to help you organize your Instance. + - **Add Volumes**, which are storage spaces used by your Instances. A block volume with a default name and 5,000 IOPS is automatically provided for your system volume. You can customize this volume and attach up to 16 local and/or block type volumes as needed. - Ensure that the volume containing your OS image has a minimum size of 10 GB. For a GPU OS, the recommended size is 125 GB. - When multiple Block Storage volumes are linked to your Instance, the primary volume will host the OS and is essential for booting the Instance. Once the Instance is created can [modify your boot volume](/compute/instances/how-to/use-boot-modes/#how-to-change-the-boot-volume). @@ -45,7 +45,7 @@ Scaleway [Instances](/compute/instances/concepts/#instance) are computing units You can attach up to 5 IPs to an Instance, combining IPv4 and IPv6 addresses, which is useful for running different services or applications on the same Instance. - (Optional) Click **Advanced options** to configure a [cloud-init configuration](/compute/instances/concepts/#cloud-init). Otherwise, leave these options at their default values. - You can configure a cloud-init script to automate instance setup, such as setting up software, users, and system configurations at the first boot. + You can configure a cloud-init script to automate Instance setup, such as setting up software, users, and system configurations at the first boot. - **Verify the [SSH keys](/console/account/concepts/#ssh-key)** that will give you access to your Instance. - **Verify the Estimated cost** of your Instance, based on the specifications you chose. 4. Click **Create Instance**. The creation of your Instance begins, and you will be informed when the Instance is ready. From 9ccb191b93f8fa76c2bddbd4f1fb4cc9c79be45a Mon Sep 17 00:00:00 2001 From: Pierre Ozoux Date: Mon, 21 Oct 2024 11:01:49 +0200 Subject: [PATCH 18/68] feat: add warning about limitations of kosmos upgrade (#3857) --- containers/kubernetes/how-to/edit-kosmos-cluster.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/containers/kubernetes/how-to/edit-kosmos-cluster.mdx b/containers/kubernetes/how-to/edit-kosmos-cluster.mdx index 46c8ac7ce2..1128a4d8a9 100644 --- a/containers/kubernetes/how-to/edit-kosmos-cluster.mdx +++ b/containers/kubernetes/how-to/edit-kosmos-cluster.mdx @@ -104,6 +104,10 @@ In order to add external nodes to your multi-cloud cluster, you must first [crea ## How to upgrade nodes in a multi-cloud pool in your Kosmos cluster + + Note that the node will reappear with a different node ID. If your automation uses this ID (for instance when you use local PVCs), it will be broken. + + The Kubernetes version of the existing nodes in your multi-cloud pool can be upgraded in place. Your workload will theoretically keep running during the upgrade, but it is best to drain the node before the upgrade. 1. In the Pools section of your Kosmos cluster, click **Upgrade** next to the node pool. This will not cause any of your existing nodes to upgrade, but will instead ensure that any new nodes added to the pool will start up with the newer version. From 8bc10ce4e2633e9204f25eb375adfaabd83f54dc Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Mon, 21 Oct 2024 11:45:25 +0200 Subject: [PATCH 19/68] chore(tuto): review tutorials (#3860) * chore(tuto): review tutorials * docs(tuto): remove outdated content --- .../index.mdx | 16 +- .../grafana-node-exporter-dashboard.webp | Bin 88102 -> 0 bytes .../scaleway-cockpit-token-permissions.webp | Bin 40998 -> 0 bytes .../k8s-fluentbit-observability/index.mdx | 240 ------------------ tutorials/k8s-kapsule-multi-az/index.mdx | 16 +- 5 files changed, 16 insertions(+), 256 deletions(-) delete mode 100644 tutorials/k8s-fluentbit-observability/assets/grafana-node-exporter-dashboard.webp delete mode 100644 tutorials/k8s-fluentbit-observability/assets/scaleway-cockpit-token-permissions.webp delete mode 100644 tutorials/k8s-fluentbit-observability/index.mdx diff --git a/tutorials/deploying-qdrant-vectordb-kubernetes/index.mdx b/tutorials/deploying-qdrant-vectordb-kubernetes/index.mdx index ed7a98b684..1495b57a7f 100644 --- a/tutorials/deploying-qdrant-vectordb-kubernetes/index.mdx +++ b/tutorials/deploying-qdrant-vectordb-kubernetes/index.mdx @@ -7,7 +7,7 @@ content: paragraph: This page explains how to deploy Qdrant Hybrid Cloud on Scaleway Kubernetes Kapsule. tags: vectordb qdrant database dates: - validation: 2024-04-16 + validation: 2024-10-21 posted: 2024-04-16 categories: - kubernetes @@ -21,10 +21,10 @@ Qdrant Hybrid Cloud on Scaleway offers a secure and scalable solution that meets Key benefits of running Qdrant Hybrid Cloud on Scaleway include: -- **AI-Focused resources:** Scaleway provides dedicated resources and infrastructure tailored for AI and machine learning workloads, complementing Qdrant Hybrid Cloud to empower advanced AI applications. -- **Scalable vector search:** Qdrant Hybrid Cloud's fully managed vector database facilitates seamless scaling, whether vertically or horizontally. Deployed on Scaleway, it ensures robust scalability for projects of any scale, from startups to enterprises. -- **European roots and focus:** Scaleway's presence in Europe aligns well with Qdrant's European roots, offering local expertise and infrastructure that adhere to European regulatory standards. -- **Sustainability commitment:** Scaleway focuses on sustainability with eco-conscious data centers and an extended hardware lifecycle, reducing the environmental impact. +- AI-Focused resources: Scaleway provides dedicated resources and infrastructure tailored for AI and machine learning workloads, complementing Qdrant Hybrid Cloud to empower advanced AI applications. +- Scalable vector search: Qdrant Hybrid Cloud's fully managed vector database facilitates seamless scaling, whether vertically or horizontally. Deployed on Scaleway, it ensures robust scalability for projects of any scale, from startups to enterprises. +- European roots and focus: Scaleway's presence in Europe aligns well with Qdrant's European roots, offering local expertise and infrastructure that adhere to European regulatory standards. +- Sustainability commitment: Scaleway focuses on sustainability with eco-conscious data centers and an extended hardware lifecycle, reducing the environmental impact. @@ -36,8 +36,8 @@ Key benefits of running Qdrant Hybrid Cloud on Scaleway include: Setting up Qdrant Hybrid Cloud on Scaleway is straightforward, thanks to its Kubernetes-native architecture. -1. **Activate Hybrid Cloud:** Log into your Qdrant account and activate **Hybrid Cloud**. -2. **Integrate your clusters:** Add your Scaleway Kubernetes clusters as a private region in the Hybrid Cloud settings. -3. **Simplified Management:** Use the Qdrant Management Console for seamless creation and oversight of Qdrant clusters on Scaleway. +1. Log into your Qdrant account and activate **Hybrid Cloud**. +2. Add your Scaleway Kubernetes clusters as a private region in the Hybrid Cloud settings. +3. Use the Qdrant Management Console for seamless creation and oversight of Qdrant clusters on Scaleway. For detailed deployment instructions on how to build a RAG system that combines blog content ingestion with the capabilities of semantic search, refer to the [official Qdrant on Scaleway documentation](https://qdrant.tech/documentation/examples/rag-chatbot-scaleway/) or the [Qdrant product documentation](https://qdrant.tech/documentation/). \ No newline at end of file diff --git a/tutorials/k8s-fluentbit-observability/assets/grafana-node-exporter-dashboard.webp b/tutorials/k8s-fluentbit-observability/assets/grafana-node-exporter-dashboard.webp deleted file mode 100644 index 7d90e4c0e4a940e3fe0525ae17d274c046683b4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88102 zcmb??1yo#HvS=g0-Q8V+yK9i(?(XjHZh-*79fG^N2X}(Ihu{tYx<9!yZ|ADEo~C$BfvWV1^^mB3V=2;adDJWkyQQ7{qL{)MF7}u$~@!m zy8b=Se~CpjHFGfm0KiDzID}0con7Bx!#9}I!`1OOoc0D|m{=N_zQL7mFoW}(f^YEh zZ@lr};M3o*#UJn=jlytNRTg_|8^#-+#Nsco@n2vQOJ}<`9`-jL3R64#xB9^~{|1}> zhJAm-cD8PBy8UteZXtr1y_(9~lj7|r0DJ&Q1LOdT01|*Pzztvpum!jR7~h`uZx|PV z@*7?BzmUiKLtgPs%J@yn3SjakAr5c=*a3|GkO%x8gEyYH>(9P*F=u1_0|ka43IM#@ z1c7cS0RZSE0N^zN1bWT~fnEy$0El$}px6FSd51gzfcx$ZpYSJ+A{PKa4g~<32mizw zrvd;i5dZ+rildRU(I3A9@%9aFZVmukmjD2WS^xn03;+P9^S6F`qy44>3YP!?)wjO- zI0*oxX8-_H7H@Uy{uk|rc@y|Yzx}s7fA7DynM-2J3k33@nPeBp)La!jnMz32if8Hqn zc_7=f`5^A>&~X=N_XpEPk|4+q6ttjwn9EYr&)>^`s3iJBuzQ6#ra9!v<}7SMQ0Le9 zrBHRidk`Zidvob$K>4-Zea%|WVL-@B!P6cH{WbTg<_dJ*GY|j*9X-0-C_HUl^t9#n zfIuLT00p5*kOS})r0~M^RtEV5oPf?isTUo;j(%;uZk+_2`l0}XUXxy19xgTmvU(m3 z>iy3^{h;dCT#&~#>1)LE5-?Yv7z8}pY9|K04uH&rUY}(_u^s?mu+7?;{ zoq!~sL02rGidTn=h!JRzkS+2y@$0XHSEgs72jZcCbtW~TQjj?a8i@b=@PG`=-S5hO z(K!^V3a|pv1F4?_fJ}D=0R{#EAFhMWhI8L)%)TRjf?gu756}m}11+AJ&WN{(*M%kn z;y}0{`j>$7o(7>z|3V89w7B1TW&$~U=@9`o0kNM!XDyEg zAW)#tH=!?}5a7wP&FeG>^vj?tU==h5qTfGzAifQ_7aH-m_6vN|zXDkJ40_6a1?~Rs z;}=Vy15oI(=BDR0U^W2s(DU?mKL+duOo9$UOm7U>Ke(h5Vf#VDakI!iU2@@|$5}1%PC~@wA*7{g8Dde8nysbAJF;oEopnnd7;@wd zmyDASFq;?}glK54nu}of7f&l@YJq+oKzA)Q!#4#}8kp#wM$P9jP}-Mv*oo%p{mJX> z*=KqRZz0)|87Dj(V^VlE-!rkHbPfwRhJ=ER%?g$hfx(RU{)|AjAXppG%K0*}Pz);g-PS!ZJWN`NQvy}>5*YwAM~$n14H;BN@FU!lWxb%HgYsqScQ+i=CFjm8vfQO8HA4MJ8mM zC|*s-c?}5c77_hp2)^ufY`q-!eQl)F=kB*ip%)h10P!)D*CMwBOpObbfL((xfBeuU zOplm805vC^-5`Z0gCTAVq=V(HrncJf3uQADoG1N4&-rzMv;z;-4cc;5gzaGtqbbKH zhEC#@H%}qCw1J3EH2h$PD$Y-bywg{QA~{C((QK~Z#oiPySK){1wyA)m9P1`*-+R4y z{>A0m`>gfZ8uJ5XM{rF+lGm>9>*{!`oitdjl%?qn-#qisrjo>M>5&e+Eb^FKmkGCJ zFAV}I)I%39ibgO@D1(~%g(iIYy~8Eh8a=D)#)4q%dkga6plDHv?4GXNG5N|>K5sId zpxBTZD}g^h?NV4$K+_ddc}?|9Z+2U$ zLbrY>b9J=V4Gur|Z#Um}b5IWdSp#QL@~Xo`y_gQUNuQu{K3#-Va>rwTB+kj?`%S$b zB{svu8ksU*1!4J*$wgNQakh2cPMOel+IhXCZ5T`8qK)C6!F~;z{0Y@2iJe=ASin1# zDJ*yh`Q#Tk8U+C<6(a;i#h;BSywj7;!0m7-i-iA_I1mmrt^IEiBd^rQLPCfyqecS( zteTEn6Db5-HBKjxC_B$#6tBN=EV-^4`BL zjz9GOO$6iOaLmIH9=56FKM20~7Fw7R6%#wsOD1<8fF!fF0&py2d9cKs#&oeFKO5JQ z2^qCi9pHRx`~O(+pTAmrkhD~>Y4$^GRdNjfnq`xnBOY3NJ3*%K;UX@+{cS_ zq!rTVmkDE2fE1P9L%A8>4j#TkuK5QS{x*V%41Q>w@o$vKh7F-n*ImqohI+5!I)x1i z1{W;e;5)>A$=c0dL&?8^IxsQE&y~XeO#Nph45Lr2&Bj-9kxuQiSpns*R%_nY0i;KN zvG%_`_(ss*r#M>1-+k799*tYmCi@-$87EM+>>+x^oK9rFkGBN{`SAs;_pNarGx_(Z4#STmcw9Xwj5F^>Hp&j>{*vc%@<2&RRzZ0>U(~;Ot0~7 zN2?2|Ij6o_80|)1l=-hr!#}kx*A4&RFX2i7;wxD^7loZ}U@`i{|7t}j=Ry5d_x2;8 zy*B{@OEo2)!O~Q1KqG$YpML$XvD&{b3-*JK;l!D;aNEBb59Qpti2{1)F|8OS%Y!{c z4yM(OAFadO|Em$7jX~@bP54J;CV?miP#iK4;4#mU4VWa?+L+9ffzR&nzk`W?8PmTT z)0ClnmcQE7LdpuaM=;cROjgyVcSzZ#4Ic2t?LTxhxDm>Ue866N4DO4kEvIZJdW&4 z*I$-yrf@)s>x_Qg5nBkTLW`%S(4yZ~ta3W#^s_V=8<;1?rxSwPApEfUbGa+(xHcD- z$WC{%lr{lFqRywz>@gzV#4o&QN_zM8WSx-v(`(_r-fa(-@xI$-&6o|T<_vVSQxfqx z7y2{dvq{NU$rIp~mUjEY6S~u^C^E4s`a&%A#_i89pv~kg7n6S3PWINKUEqG2 zYRg3wVdg5RjjKo*=rJUF!qc?sG0^E)6!U9KXH=YTgRRxfO7Hb*i&p+DSi6jtG4IN= z8HzoAWVZ5ysAx~J?FmIzR*gGP^%q*?*$?wPQ@qdDQdeAC2C@pP;TQ7${yO3YwPtw= z?V|bd21j}HrkyJHOv(vczx<*vS9-E##|R!k3?23tpvQL$ooTTi3saG3CodQI12ucc zpCzrIF9Ocus`;3`b3j>~3WHmd!&Wz`Tjh`b0`FyCZ7y|`| z*TwumPl733eYn`i!-HjRde5%LftY?mU16cSKZRgKzf4z=UmK=*GR@ZVUPQtH$&k6D zX!!1<<9)zRzDV-C*Ld2(o!({*;F1USCsXlWDpewhk!Jn8wI@gQn}}> zk$@F>&gy_Jx7TzQ|)^gDs-qZ4X%YDEZvl{jIJj;OHaoyVc z3z4Yj9pT<|6L;8N27U@B9q(p+1*#|46DNPf50v7bY-!M`gAJXdxBut0^-VA{NI7WE z5jPJWM1f(;!U{4-SvzwH_O|h5RtYN1lrk!4bY;SA_$2@_{lD=}80Ojlfa3K_hpE`y!OX!63|EenKqR_N~-GN4Dj;TmD1 zf}piT>#NXTBMX>{M>aKC`JlIW6mx>>d*}AK^z5iX`fFQhRTCpB$2r_RIBL|e)G^Lg zDkA-J))rM6cm{7u(t4+`>HywSsW^8lfD=- zeEYLzZqE-b#1rx2?BCJy7|J0Ya#hAXgv=Eyqyp9FSlre;@s829-KoARS8Mc8PeYm! zeZ>-;DO>-zsb(~Wbn28;x;8?B*gD=2=H}bs0c7}{EO5N}A`}wewuTtul$l$Pi!4RZrkhodZd5DC zQ?sm)5H6p_iVhrvV#ItaXzjjH8V2F2ei#0O?f*~^k7N$b^R+Gb6ln1OIY|HKke}zu zG?1EFS+;kd1ij%PLCtV?1i``2xYVbmZ$LYiaFJtTU$Kbde-#@1H8{Z(hUtP44y+ z)U9Hl1v+iOqawF9B>0Sa($azs$KSFl_G*>JgbM>saq1qd?gIfV%=_cNcbhiNQ95tA z7}7%`8SH#9m~AHk0;ZL^XsM%|jgC)KR5?U6zR+ZR1)r%odWl1#N+P0(!A3s)oC>Y? zp^QKfR}7Eh|L9EKPK*8-QQSj<8*@X10*<`|6JKiZp;SQRC$ge<$akW=JLtE-p9126c!D_KKf?L~LL z(2$n?qQ@6C5V{<(-Y_^R_-v_oU`S(+QW-5b`Vp?ee3=OB)f1;f*g!-t0anraq74D+ zZ7bw#Xs07a+<7ANxBX28?-xsz0E-cIXu8m7m!=yBHeao#O zs9i#A>1C^;HU+hy_xMCUPEjLZ@>~R{sGhOq1Q^vq^^^(zjo$aJz6$MC;I!~Rw&_Wi zx0-MHL`*7$U1p4+k^-1myG!6_8u*}T`>oiNDg;+EdUR%0O1-?X5~>ARb>OP}e3h#r zwrltD*SFJdcUNKZEi1%>uSW?(WeY;Fc|e4oKWZer@u17?vTHY9E_-k>XGLs2aQ0s< zk(0Kct!&9ljQ{c|X&Bb7PEbxss%qsB7LUtsZrj9gvil@Y_s9CSLFI$)df=v^8)jho&3@)N>*@#c3Ub(Wk z7#+>BS@jSLQkx99AIz`sl$jeA_226XkRI;^Kd$mCmUiPMK0ACWCZM8NNcn2m7cwhE zqpAuO5M_?$w~Ci%IY@}lAC{n94i6w^T%@{HEKPq^|dHXEC2WS zIbG~N{{HJ3F+3w0_v(zy?w%*NN(B6-k*_utmum!px~z*9tL99T$b>0Q0es>c_p9>@ z!@>S=xBeS%5&xPm`~gQV*w=x6pTMd0SQN{ltnAS>@AUX*4mkzN8LSc_xR-vt%+>+W zzB)alXf7SW3rP!vf#m1=>zNChZn1Cyp6|;02r8LL&W1@nAC0}L<~n$+2UXIdOdms~ zhp$LIPrQI7>l)A|kP}+wvSj41y$1`3!eQ9K%4&PvBaN_qlSA8GMYVbxKkKFkXnh`t!iNw>NA0B)>cE94GSa)V9FS z8dCk`*)X<6KdU-O6p50+8bdDYV2K?QrbiE5PpCZZh~eR0Gd5gdD5?qW1gi9L+`^{A z%|u0)dM?E*z8uq_xPCTjAv!IV^8CZXh4})f)@NPBx>qpnlaO@wSij7YHYTf3UHI_l zoZHtPQ&%>e8NuCNk4ZcFdWRQ&=;UaHz|FTn+!YdcgJA#grf%dlBl^j;oH_GeHjQ5! z9V&_s+zq?WidR3*VMAahu-|I)X~=q~OY5dwl8txHRMpr2aoD$X5Y#+xUP4*6ZVr|&w0F5x6}s@F)tl6h_=-cIn9F+2*V!+8F< zif9I!t>5$rAIQOJ#?)C=Kv<^c`TBf+Ch&m*jXqFyC7Z}1YP2};q*8sOKj5G3o&pSzb zD;E-|S@gb7rVY6O1E=^*P6C}%tojEzq-C~mbveVFEj0RLBO~cQWE7XeD#4LiFu}KJ z?9tfS&Y1Gvo*a>I_%44-g=q$+q7WFHXM&vA%p5>HTQ_2k;2H6)YtdM_(1YeB3Loo` zV^Z_(n}u9M-*<|JpkTm7{mzuN4ZZ1PXn=q7$LQ_AI=$*Z{QRSp1NWloz09xv=u84V z<$w4WB$<~EYD?o!$PvF&Z=8n;Y)Q=SuL-4Z`8JsYh|E21 zBe{FmmUl>*+86V0PLLONk+|M&iX-BE`;*bgc;b4hVr_Rk!)}w0H%yQEz2L}-sydc3 zo2?1~B%0Jq#1d8yXBo0TYA_ad-}J6#{yl3T=#BsRT%J_{$}^0*}Ju>%&RHiM)_TT z9h=#8w4a@K&pp(_@5`VT*|vu|uYLTFPpzexmtTO~z|Pz#;+422xEF)2$mg+1>F@8~#1|#((7ZXe zkZ!h%%>?C0ZWt82U$8hkta{*2t7Gg!L{vUj*H$+Cvu>C8q-J##N_-~UOWBTN9Aj*02ULoV*7aEFDu-cAgzaDzehLpV_U3qQ23#` zzf#S2ds_6B_lv)qCuMRVa^UW%lx@VNYKz~RRoLPqt04TjAMy^dtc<`KD*D;Sv{@o{ ze{OLeE41rUBYG#p;+db?)fG}ar~4A01EIE5L)X2tkDG1Sf_J0fQ(bAOXW+niXEn=v z53G-Q2_6mPl1$P8{GahOTaJf5E&$X!22C-d2jP>+*s(6U#yI9o5ZlW+o~8Y7KxM

2_{E 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 !|Y53=J_Mhz9MA^_{kBEh};HrAQU7!=9 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 NE%++O4Sa*~e*y9`q-y{G diff --git a/tutorials/k8s-fluentbit-observability/assets/scaleway-cockpit-token-permissions.webp b/tutorials/k8s-fluentbit-observability/assets/scaleway-cockpit-token-permissions.webp deleted file mode 100644 index 1ea2e4b0b97fa27ef62f6434d669d70c63c44667..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40998 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 diff --git a/tutorials/k8s-fluentbit-observability/index.mdx b/tutorials/k8s-fluentbit-observability/index.mdx deleted file mode 100644 index d3ef96e669..0000000000 --- a/tutorials/k8s-fluentbit-observability/index.mdx +++ /dev/null @@ -1,240 +0,0 @@ ---- -meta: - title: Send Kapsule logs and metrics to the Observability Cockpit with Fluent Bit - description: Learn to configure Fluent Bit on a Kapsule cluster to forward logs and metrics to the Observability Cockpit for Grafana visualization. -content: - h1: Send Kapsule logs and metrics to the Observability Cockpit with Fluent Bit - paragraph: Learn to configure Fluent Bit on a Kapsule cluster to forward logs and metrics to the Observability Cockpit for Grafana visualization. -tags: fluentbit grafana kubernetes metrics logs -categories: - - cockpit - - kubernetes -dates: - validation: 2023-06-17 - posted: 2023-06-01 ---- - -In this tutorial you will learn how to forward the applicative logs and the usage metrics of your [Kubernetes Kapsule](https://www.scaleway.com/en/kubernetes-kapsule/) containers into the [Observability Cockpit](/observability/cockpit/quickstart/). - -This process will be done using Fluent Bit, a lightweight logs and metrics processor that acts as a gateway between containers and the Cockpit endpoints, when configured in a Kubernetes cluster. - - - - - -- A Scaleway account logged into the [console](https://console.scaleway.com) -- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization -- [Retrieved your Grafana credentials](/observability/cockpit/how-to/retrieve-grafana-credentials/) -- [Created a Kapsule cluster](/containers/kubernetes/how-to/create-cluster/) -- Set up [kubectl](/containers/kubernetes/how-to/connect-cluster-kubectl/) on your machine -- Installed `helm`, the Kubernetes [package manager](https://helm.sh/), on your local machine (version 3.2+) - - - - Having the default configuration on your agents might lead to more of your resources' metrics being sent, a high consumption, and a high bill at the end of the month. - - Sending metrics and logs for Scaleway resources or personal data using an external path is a billable feature. In addition, any data that you push yourself is billed, even if you send data from Scaleway products. Refer to the [product pricing](https://www.scaleway.com/en/pricing/?tags=available,managedservices-observability-cockpit) for more information. - - -## Configuring the Fluent Bit service - -Fluent Bit will be installed as a Helm package configured to target your Kubernetes resources as inputs and your Observability cockpit as an output. - -1. Add the Helm repository for Fluent Bit to your machine: - - ```bash - helm repo add fluent https://fluent.github.io/helm-charts - helm repo update - ``` - -2. Create a [values file for Helm](https://helm.sh/docs/chart_template_guide/values_files/) named `values.yaml` that we will use to configure Fluent Bit. -3. Create a first section `config.service` in the `values.yaml` file to configure the Fluent Bit master process: - - ```yaml - config: - service: | - [SERVICE] - Flush 1 - Log_level info - Daemon off - Parsers_File custom_parsers.conf - HTTP_Server on - HTTP_Listen 0.0.0.0 - HTTP_PORT 2020 - ``` - -- `Flush 1`: Collects logs every second. -- `Log_level info`: Displays informational logs in the Fluent Bit pods. -- `Daemon off`: Run Fluent Bit as the foreground process in its pods. -- `Parsers_File custom_parsers.conf`: Loads additional log parsers that we will define later on. -- `HTTP_Server on`: Enables Fluent Bit's built-in HTTP server. -- `HTTP_Listen 0.0.0.0`: Listen on all interfaces exposed by your pod. -- `HTTP_PORT 2020`: Listen to port 2020. - - - You need to enable Fluent Bit's HTTP server for it to communicate with your Cockpit. - - -## Configuring observability inputs - -We will configure Fluent Bit to retrieve the metrics (e.g.: CPU, memory, disk usage) from your Kubernetes nodes and the applicative logs from your running pods. - -Create a new section `config.inputs` in the `values.yaml` file: - -```yaml - inputs: | - [INPUT] - Name node_exporter_metrics - Tag node_metrics - Scrape_interval 60 - [INPUT] - Name tail - Path /var/log/containers/*.log - Parser docker - Tag logs.* -``` - -The first subsection adds an input to Fluent Bit to retrieve the usage metrics from your containers: -- `Name node_exporter_metrics`: This input plugin is used to collect various system-level metrics from your nodes. -- `Tag node_metrics`: The `Tag` parameter assigns a tag to the incoming data from the `node_exporter_metrics` plugin. In this case, the tag `node_metrics` is assigned to the collected metrics. -- `Scrape_interval 60`: The frequency at which metrics are retrieved. Metrics are collected every 60 seconds. - - - Increasing the scrape interval allows you to push fewer metrics samples per minute to your Cockpit and thus, pay less. - For instance, if your application exposes 100 metrics every 60 seconds, these 100 metrics are collected and pushed to the server. If you configure your scrape interval to 1 second, you will push 6000 samples per minute. - - -The second subsection adds an input to Fluent Bit to retrieve the logs from your containers: -- `Name tail`: The tail input plugin is used to read logs from files. -- `Path /var/log/containers/*.log`: The tail plugin reads logs from `/var/log/containers/*.log` which are the log dumps from your containers. -- `Parser docker`: The `Parser` parameter specifies the parser to be used for parsing log records. The `docker` parser is a custom parser that will be defined below. -- `Tag logs.*`: The `Tag` parameter assigns a tag to the incoming data from the tail plugin. The tag "logs.*" indicates that the collected logs will have a tag prefix of "logs" followed by any additional subtag. - -## Configuring logs processing - -The inputs collected by Fluent Bit should be structured before sending them to the Cockpit to enable further filtering and better visualization. - -1. Create a `config.customParsers` section to define the `docker` parser which is referenced by the log parsing input: - - ```yaml - customParsers: | - [PARSER] - Name docker - Format json - Time_Key time - Time_Format %Y-%m-%dT%H:%M:%S.%L - ``` - - This parser expects log records in JSON format. It assumes that the timestamp information is located under the key "time" in the JSON log record, and that the timestamp format is in ISO 8601 date format. - -2. Define a section named `config.filters` to filter incoming log files from the containers: - - ```yaml - filters: | - [FILTER] - Name kubernetes - Match logs.* - Merge_Log on - Keep_Log off - K8S-Logging.Parser on - K8S-Logging.Exclude on - ``` - - This sets up a filter plugin which will be applied to log records with tags starting with `logs.`. It enables log merging, extracts and parses Kubernetes log metadata, and allows log exclusion based on Kubernetes log metadata filters. - -3. Define a section named `config.extraFiles.'labelmap.json'`: - - ```yaml - extraFiles: - labelmap.json: | - { - "kubernetes": { - "container_name": "container", - "host": "node", - "labels": { - "app": "app", - "release": "release" - }, - "namespace_name": "namespace", - "pod_name": "instance" - }, - "stream": "stream" - } - ``` - - This defines a map for various Kubernetes labels and metadata to specific Fluent Bit field names to parse and structure the logs. - -## Configuring observability outputs - -The last step in the Fluent Bit configuration is to define where the logs and metrics will be pushed. - -1. [Create a token](/observability/cockpit/how-to/create-token/) and select push permissions for both logs and metrics. - - - -2. Create a section named `config.outputs` in the `values.yaml` file: - - ```yaml - outputs: | - [OUTPUT] - Name prometheus_remote_write - Match node_metrics - Host <...> - Port 443 - Uri /api/v1/push - Header Authorization Bearer <...> - Log_response_payload false - Tls on - Tls.verify on - Add_label job kapsule-metrics - [OUTPUT] - Match logs.* - Name loki - Host <...> - Port 443 - Tls on - Tls.verify on - Label_map_path /fluent-bit/etc/labelmap.json - Auto_kubernetes_labels on - Http_user nologin - Http_passwd <...> - ``` - -3. Fill in the blanks as follows: -- `Host` from the first subsection: paste your Metrics API URL defined in the **API and Tokens tab** section from the Cockpit. Remove the `https://` protocol. -- `Header`: Next to `Bearer`, paste the token generated in the previous step. -- `Host` from the second subsection: paste your Logs API URL defined in the **API and Tokens tab** section from the Cockpit. Remove the `https://` protocol. -- `Http_passwd`: paste the token generated in the previous step. - -In the first subsection, the `prometheus_remote_write` plugin is used to send metrics to the [Prometheus](https://prometheus.io/) server of your Cockpit using the remote write protocol. -In the second subsection, the `loki` plugin is used to send logs to the [Loki](https://grafana.com/oss/loki/) server of your Cockpit, using the field mapping from `labelmap.json` defined above. - -## Installing Fluent Bit - -Run the following command in the same directory as your `values.yaml` file to install Fluent Bit: - -``` -helm upgrade --install fluent-bit fluent/fluent-bit -f ./values.yaml -``` - -You should see a `DeamonSet` named `fluent-bit` with running pods on all of your nodes. - -## Visualizing Kapsule logs and metrics - -You can find the logs and metrics from your Kubernetes cluster in your Cockpit's [dashboard in Grafana](/observability/cockpit/how-to/access-grafana-and-managed-dashboards/). - -### Exploring metrics - -Grafana has a built-in dashboard for visualizing node metrics. - -1. Go to **Dashboards** in your Grafana instance. -2. Click **New**, **Folder** and name it `Kapsule`. -3. Click **New**, **Import** and paste the following URL in the **Import via grafana.com** field: - ``` - https://grafana.com/grafana/dashboards/1860-node-exporter-full/ - ``` -4. Click **Load** to access the new dashboard named **Node Exporter Server Metrics**. - - - -### Exploring logs - -Your Kapsule logs index can be queried in the **Explore** section of your Cockpit's dashboard in Grafana. In the data source selector, pick the **Logs** index. The Kubernetes labels are already mapped and can be used as filters in queries. \ No newline at end of file diff --git a/tutorials/k8s-kapsule-multi-az/index.mdx b/tutorials/k8s-kapsule-multi-az/index.mdx index af7cfe2dab..7b61a9df08 100644 --- a/tutorials/k8s-kapsule-multi-az/index.mdx +++ b/tutorials/k8s-kapsule-multi-az/index.mdx @@ -11,7 +11,7 @@ categories: - kubernetes - domains-and-dns dates: - validation: 2024-04-15 + validation: 2024-10-21 posted: 2023-04-15 --- @@ -97,7 +97,7 @@ Start by creating a multi-AZ cluster on `fr-par` region, in a dedicated VPC and tags = ["multi-az"] type = "kapsule" - version = "1.28" + version = "1.30.2" cni = "cilium" delete_additional_resources = true @@ -163,12 +163,12 @@ Start by creating a multi-AZ cluster on `fr-par` region, in a dedicated VPC and kubectl get nodes NAME STATUS ROLES AGE VERSION - scw-kapsule-multi-az-pool-fr-par-1-61e22198f8c Ready 89s v1.28.0 - scw-kapsule-multi-az-pool-fr-par-1-8334e772ced Ready 82s v1.28.0 - scw-kapsule-multi-az-pool-fr-par-2-1bcf90f3683 Ready 90s v1.28.0 - scw-kapsule-multi-az-pool-fr-par-2-33265e85597 Ready 86s v1.28.0 - scw-kapsule-multi-az-pool-fr-par-3-44b14b7bbbd Ready 84s v1.28.0 - scw-kapsule-multi-az-pool-fr-par-3-863491657c7 Ready 80s v1.28.0 + scw-kapsule-multi-az-pool-fr-par-1-61e22198f8c Ready 89s v1.30.2 + scw-kapsule-multi-az-pool-fr-par-1-8334e772ced Ready 82s v1.30.2 + scw-kapsule-multi-az-pool-fr-par-2-1bcf90f3683 Ready 90s v1.30.2 + scw-kapsule-multi-az-pool-fr-par-2-33265e85597 Ready 86s v1.30.2 + scw-kapsule-multi-az-pool-fr-par-3-44b14b7bbbd Ready 84s v1.30.2 + scw-kapsule-multi-az-pool-fr-par-3-863491657c7 Ready 80s v1.30.2 ``` ## Nginx ingress controller as a stateless multi-AZ application From 0f6f8ebdc78a5c23fb94b37f57f5027639a92413 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Mon, 21 Oct 2024 11:46:26 +0200 Subject: [PATCH 20/68] chore(ddx): review docs compute (#3859) --- bare-metal/dedibox/how-to/configure-failover-ip.mdx | 10 +++++----- bare-metal/dedibox/how-to/install-dedibox.mdx | 6 +++--- .../fix-long-delays-booting-without-public-ip.mdx | 6 +++--- dedibox-network/ipv6/how-to/configure-ipv6-linux.mdx | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bare-metal/dedibox/how-to/configure-failover-ip.mdx b/bare-metal/dedibox/how-to/configure-failover-ip.mdx index 0891d36a0e..bf7941f960 100644 --- a/bare-metal/dedibox/how-to/configure-failover-ip.mdx +++ b/bare-metal/dedibox/how-to/configure-failover-ip.mdx @@ -1,13 +1,13 @@ --- meta: - title: How to configure a failover IP - description: This page explains configure a failover IP + title: How to configure a failover IP on a Scaleway Dedibox + description: This page explains configure a failover IP on a Scaleway Dedibox content: - h1: How to configure a failover IP - paragraph: This page explains configure a failover IP + h1: How to configure a failover IP on a Scaleway Dedibox + paragraph: This page explains configure a failover IP on a Scaleway Dedibox tags: dedibox failover ip failover-ip failover-ip dates: - validation: 2024-04-08 + validation: 2024-10-21 posted: 2022-04-13 --- diff --git a/bare-metal/dedibox/how-to/install-dedibox.mdx b/bare-metal/dedibox/how-to/install-dedibox.mdx index 3b4b7744e6..2b617df5e7 100644 --- a/bare-metal/dedibox/how-to/install-dedibox.mdx +++ b/bare-metal/dedibox/how-to/install-dedibox.mdx @@ -1,13 +1,13 @@ --- meta: title: How to install a Dedibox - description: This page explains how to install a Dedibox + description: This page explains how to install a Scaleway Dedibox content: h1: How to install a Dedibox - paragraph: This page explains how to install a Dedibox + paragraph: This page explains how to install a Scaleway Dedibox tags: dedibox install dates: - validation: 2024-04-08 + validation: 2024-10-21 posted: 2022-01-31 --- diff --git a/compute/instances/troubleshooting/fix-long-delays-booting-without-public-ip.mdx b/compute/instances/troubleshooting/fix-long-delays-booting-without-public-ip.mdx index b09a303030..2f2514f63e 100644 --- a/compute/instances/troubleshooting/fix-long-delays-booting-without-public-ip.mdx +++ b/compute/instances/troubleshooting/fix-long-delays-booting-without-public-ip.mdx @@ -1,13 +1,13 @@ --- meta: title: Fix long delays when booting without a public IP - description: This page explains how to avoid long delays when booting without a public IP + description: This page explains how to avoid long delays when booting a Scaleway Instance without a public IP content: h1: Fix long delays when booting without a public IP - paragraph: This page explains how to avoid long delays when booting without a public IP + paragraph: This page explains how to avoid long delays when booting a Scaleway Instance without a public IP tags: centos-stream rockylinux almalinux network-manager ipv6 routed ip dates: - validation: 2024-04-17 + validation: 2024-10-21 posted: 2024-04-17 categories: - compute diff --git a/dedibox-network/ipv6/how-to/configure-ipv6-linux.mdx b/dedibox-network/ipv6/how-to/configure-ipv6-linux.mdx index 2500805050..012c684894 100644 --- a/dedibox-network/ipv6/how-to/configure-ipv6-linux.mdx +++ b/dedibox-network/ipv6/how-to/configure-ipv6-linux.mdx @@ -1,13 +1,13 @@ --- meta: title: How to configure IPv6 connectivity using systemd-networkd - description: This page explains how to configure IPv6 connectivity using systemd-networkd. + description: This page explains how to configure IPv6 connectivity on a Scaleway Dedibox using systemd-networkd. content: h1: How to configure IPv6 connectivity using systemd-networkd - paragraph: This page explains how to configure IPv6 connectivity using systemd-networkd. + paragraph: This page explains how to configure IPv6 connectivity on a Scaleway Dedibox using systemd-networkd. tags: dedibox ipv6 systemd-networkd dates: - validation: 2024-04-15 + validation: 2024-10-21 posted: 2021-08-03 categories: - dedibox-network From c0cb1ba482c625e8a06b3359fc258b94d12706a9 Mon Sep 17 00:00:00 2001 From: Emilie BOUIN <48752456+Bemilie@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:51:47 +0200 Subject: [PATCH 21/68] docs(serverless): add entries in serverless FAQ (#3858) --- faq/serverless-containers.mdx | 10 ++++++++++ faq/serverless-functions.mdx | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/faq/serverless-containers.mdx b/faq/serverless-containers.mdx index 8e6ec6e08d..39399c6298 100644 --- a/faq/serverless-containers.mdx +++ b/faq/serverless-containers.mdx @@ -126,3 +126,13 @@ Scaleway Serverless Containers does not currently support Scaleway VPC or Privat To add network restrictions on your resource, consult the [list of prefixes used at Scaleway](https://www.scaleway.com/en/peering/). Serverless resources do not have dedicated or predictable IP addresses. +## How can I attach Block Storage to a Serverless Container? + +Scaleway Serverless Containers do not currently support attaching block storage. These containers are designed to be +stateless, meaning they do not retain data between invocations. For persistent storage, we recommend using external +solutions like Scaleway Object Storage. + +# Why does my container have an instance running after deployment, even with min-scale 0? + +Currently, a new container instance will always start after each deployment, even if there is no traffic and the minimum +scale is set to 0. This behavior is not configurable at this time. diff --git a/faq/serverless-functions.mdx b/faq/serverless-functions.mdx index 73a18eacbd..b4702d3727 100644 --- a/faq/serverless-functions.mdx +++ b/faq/serverless-functions.mdx @@ -173,3 +173,14 @@ Upgrading a runtime is highly recommended in case of deprecation, and for runtim Scaleway Serverless Functions does not currently support Scaleway VPC or Private Networks, though this feature is under development. To add network restrictions on your resource, consult the [list of prefixes used at Scaleway](https://www.scaleway.com/en/peering/). Note that Serverless resources do not have dedicated or predictable IP addresses. + +## How can I attach Block Storage to a Serverless Function? + +Scaleway Serverless Functions do not currently support attaching block storage. These functions are designed to be +stateless, meaning they do not retain data between invocations. For persistent storage, we recommend using external +solutions like Scaleway Object Storage. + +# Why does my function have an instance running after deployment, even with min-scale 0? + +Currently, a new function instance will always start after each deployment, even if there is no traffic and the minimum +scale is set to 0. This behavior is not configurable at this time. From fafe37f6574cc4c79896bad157b9705e6413759c Mon Sep 17 00:00:00 2001 From: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:13:27 +0200 Subject: [PATCH 22/68] fix(pgw): add more troubleshooting (#3862) * fix(pgw): add more troubleshooting * Apply suggestions from code review Co-authored-by: Benedikt Rollik * Update compute/instances/troubleshooting/cant-connect-ssh.mdx --------- Co-authored-by: Benedikt Rollik --- .../troubleshooting/cant-connect-ssh.mdx | 6 +++++- network/public-gateways/concepts.mdx | 4 ++++ ...nt-connect-to-instance-with-pn-gateway.mdx | 21 ++++++++++++------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/compute/instances/troubleshooting/cant-connect-ssh.mdx b/compute/instances/troubleshooting/cant-connect-ssh.mdx index da2e7b2dd2..514104c8e7 100644 --- a/compute/instances/troubleshooting/cant-connect-ssh.mdx +++ b/compute/instances/troubleshooting/cant-connect-ssh.mdx @@ -133,4 +133,8 @@ You must upload the content of the public part of the SSH key pair to the Scalew If you have any difficulties connecting to an Instance after uploading a new public SSH key to your Project, try the following: - If you cannot connect to your Instance at all via SSH, reboot your Instance from the console and try again. - If you can connect to your Instance using a previously uploaded SSH key but not the new one, go ahead and connect to your Instance with the old key. Once connected, run the `scw-fetch-ssh-keys --upgrade` command, which launches a script on your Instance to update your SSH keys. You can then check that the new key has been added to the `authorized_keys` file (`~/.ssh/authorized_keys`). Note that this command works only for Instances. - \ No newline at end of file + + +## Timeout when trying to connect + +You may find the SSH connection attempt times out without connecting. This may be expected behavior if the Instance is attached to a Private Network on which there is also a Public Gateway advertising the default route. See our [dedicated troubleshooting](/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway/) page for more help with this issue. \ No newline at end of file diff --git a/network/public-gateways/concepts.mdx b/network/public-gateways/concepts.mdx index 40f1f32dc4..506135d558 100644 --- a/network/public-gateways/concepts.mdx +++ b/network/public-gateways/concepts.mdx @@ -18,6 +18,10 @@ The Public Gateway can advertise a default route to resources on an attached Pri You can choose to activate the advertisement of the default route when attaching a Private Network to a Public Gateway. The default route is propagated through DHCP. + +After activating the default route, all outbound and inbound traffic for resources attached to the Private Network is directed through the Public Gateway. This includes SSH traffic destined for Instances, which means you will need to [manage SSH connections differently](/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway/). + + ## DHCP DHCP was previously a functionality of Scaleway Public Gateways, but has now been moved and is integrated directly into Private Networks. [Read more about DHCP on Private Networks](/network/vpc/concepts#dhcp). diff --git a/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway.mdx b/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway.mdx index 25a5ee6e31..87fe56eab3 100644 --- a/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway.mdx +++ b/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway.mdx @@ -1,24 +1,29 @@ --- meta: - title: I cannot connect to my Instance using SSH after attaching it to a Private Network which has a Public Gateway + title: I cannot connect to my Instance using SSH after attaching it to a Private Network with a Public Gateway description: This page explains how troubleshoot connection problems after attaching an Instance to a Private Network which has a Public Gateway content: - h1: I cannot connect to my Instance using SSH after attaching it to a Private Network which has a Public Gateway + h1: I cannot connect to my Instance using SSH after attaching it to a Private Network with a Public Gateway paragraph: This page explains how troubleshoot connection problems after attaching an Instance to a Private Network which has a Public Gateway tags: troubleshoot error private-network private network vpc public-gateway dates: - validation: 2024-05-24 + validation: 2024-10-21 posted: 2021-05-26 categories: - network --- - +If you are having trouble [connecting to your Instance via SSH](/compute/instances/how-to/connect-to-instance/), when the Instance is attached to a Private Network which also has an attached Public Gateway, read on for help and solutions. -- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization +The action to take depends on whether: -The action to take depends on whether the Private Network(s) your Instance is on have DHCP enabled, and whether your Public Gateway is set to advertise a default route (true by default). +- The Private Network(s) attached to your Instance have [DHCP enabled](/network/vpc/how-to/activate-dhcp/), and +- Your Public Gateway is set to [advertise a default route](/network/public-gateways/concepts/#default-route) (true by default). -If it is not the case, disconnect the Instance from the Private Network, as there may be other factors impacting your Instance, like one of your Instances running a DHCP server. +If the above two conditions are not true, there may be other factors impacting your Instance, like one of your Instances running a DHCP server. Try disconnecting and reconnecting the Instance from the Private Network. -If DHCP is activated and your Public Gateway is set to advertise a default route, this is expected behavior as all the traffic towards your Instance now goes through the Public Gateway. To access your Instance using SSH, first create a static NAT association between a port of your Public Gateway (eg 2222) and the private IP assigned to your Instance, on the SSH port (22 by default). Then, SSH to the Public Gateway's IP on port 2222. \ No newline at end of file +If DHCP **is** activated and your Public Gateway **is** set to advertise a default route, not being able to connect to your Instance via SSH is **expected behavior**. All the traffic towards your Instance now goes through the Public Gateway. + +To access your Instance using SSH, either: +- Use [SSH bastion](/network/public-gateways/how-to/use-ssh-bastion/), or +- Create a static NAT association between a port of your Public Gateway (eg 2222) and the private IP assigned to your Instance, on the SSH port (22 by default). Then, SSH to the Public Gateway's IP on port 2222. \ No newline at end of file From 21a256b88666445f9c5c2dad0d21df34d6f54559 Mon Sep 17 00:00:00 2001 From: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Date: Tue, 22 Oct 2024 17:39:15 +0200 Subject: [PATCH 23/68] fix(vpc): review doc (#3861) --- network/vpc/how-to/attach-resources-to-pn.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/vpc/how-to/attach-resources-to-pn.mdx b/network/vpc/how-to/attach-resources-to-pn.mdx index 08b6354dcd..2d9b13a684 100644 --- a/network/vpc/how-to/attach-resources-to-pn.mdx +++ b/network/vpc/how-to/attach-resources-to-pn.mdx @@ -7,7 +7,7 @@ content: paragraph: This page explains how to attach resources to a Private Network in a Scaleway VPC tags: regional-private-network private-network vpc virtual-private-cloud attach detach resources regional dates: - validation: 2024-04-02 + validation: 2024-10-21 posted: 2023-03-21 categories: - network From 00d36e74e2c0568c59973c3644d6a0b6323775ce Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Tue, 22 Oct 2024 17:41:15 +0200 Subject: [PATCH 24/68] fix(ddx): update ip addresses of ntp servers (#3863) * fix(ddx): update ip addresses of ntp servers * fix(ddx): update review date --- .../reference-content/scaleway-network-information.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/console/account/reference-content/scaleway-network-information.mdx b/console/account/reference-content/scaleway-network-information.mdx index 00e8a9ee76..c3257afee9 100644 --- a/console/account/reference-content/scaleway-network-information.mdx +++ b/console/account/reference-content/scaleway-network-information.mdx @@ -7,7 +7,7 @@ content: paragraph: Access detailed network information for Scaleway services. tags: scaleway ip-range ntp rpn vpn dns dates: - validation: 2024-05-14 + validation: 2024-10-22 posted: 2021-08-20 categories: - console @@ -90,15 +90,15 @@ IPv6: Generic: `ntp.online.net` -- Primary NTP server: `62.210.16.53` (`ntp1.online.net`) -- Seconday NTP server: `62.210.16.54` (`ntp2.online.net`) +- Primary NTP server: `51.159.47.151` (`ntp1.online.net`) +- Seconday NTP server: `51.158.192.3` (`ntp2.online.net`) ### Rdate server Generic: `rdate.dedibox.com` -- Primary rdate server: `62.210.16.53` (`ntp1.online.net`) -- Seconday rdate server: `62.210.16.54` (`ntp2.online.net`) +- Primary rdate server: `51.159.47.151` (`ntp1.online.net`) +- Seconday rdate server: `51.158.192.3` (`ntp2.online.net`) Backup server: `dedibackup.dedibox.fr` From e43cbce93b142b049c0d84b1531ba0f4759a395b Mon Sep 17 00:00:00 2001 From: SamyOubouaziz Date: Wed, 23 Oct 2024 15:32:01 +0200 Subject: [PATCH 25/68] docs(SRV): add note on external container registries MTA-5165 (#3866) * docs(SRV): add note on external container registries MTA-5165 * docs(SRV): update * chore(GEN): update * Update faq/containerregistry.mdx * Update faq/containerregistry.mdx * Update faq/containerregistry.mdx * Update serverless/containers/troubleshooting/common-errors.mdx Co-authored-by: Thomas TACQUET * Update serverless/jobs/how-to/create-job-from-external-registry.mdx Co-authored-by: Thomas TACQUET * Update serverless/jobs/troubleshooting/common-errors.mdx Co-authored-by: Thomas TACQUET --------- Co-authored-by: Thomas TACQUET --- faq/containerregistry.mdx | 14 +++++++++++++ faq/serverless-containers.mdx | 21 +++++++++++++++++++ faq/serverless-jobs.mdx | 21 +++++++++++++++++++ macros/serverless/container-registry-note.mdx | 6 ++++++ ...ainer-from-external-container-registry.mdx | 6 +++++- serverless/containers/quickstart.mdx | 6 +++++- .../troubleshooting/common-errors.mdx | 10 +++++++++ .../create-job-from-external-registry.mdx | 8 ++++--- serverless/jobs/quickstart.mdx | 11 ++++++---- .../jobs/troubleshooting/common-errors.mdx | 10 +++++++++ 10 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 macros/serverless/container-registry-note.mdx diff --git a/faq/containerregistry.mdx b/faq/containerregistry.mdx index 1972da2813..ab404ad2a4 100644 --- a/faq/containerregistry.mdx +++ b/faq/containerregistry.mdx @@ -16,6 +16,20 @@ Scaleway Container Registry is a fully managed mutualized Container Registry, de You can store any docker container image on the Namespace and it is possible to set the visibility of each image towards your needs. It can either be private or public. The Service is currently available in our `nl-ams` (Amsterdam, The Netherlands), `fr-par` (Paris, France), and `pl-waw` (Poland, Warsaw) Availability Zones. +## How am I billed for Scaleway Container Registry? + +Scaleway Container Registry is billed based on stored images size, and outgoing data transfer. + +| | Stored Images | Outgoing data transfer | Incoming data transfert | +|----------------|-----------------|--------------------------------------------------|-------------------------| +| Private images | €0.027/GB/month | Inter-regional: €0.033/GB - Intra-regional: free | Free | +| Public images | Free up to 75GB | Inter-regional: free - Intra-regional: free | Free | + + +- Inter-regional traffic: AMS ↔ PAR, WAW ↔ PAR, or AMS ↔ WAW +- Intra-regional traffic: PAR ↔ PAR, WAW ↔ WAW, or AMS ↔ AMS + + ## Why do I get a message that the namespace is not available? Each namespace has a unique name in each Availability Zone. If the namespace's name is already taken, it will no longer be available. diff --git a/faq/serverless-containers.mdx b/faq/serverless-containers.mdx index 39399c6298..3d27192425 100644 --- a/faq/serverless-containers.mdx +++ b/faq/serverless-containers.mdx @@ -97,6 +97,27 @@ Ensure that your code avoids heavy computations or long-running initialization a Refer to our dedicated page about [Serverless Containers limitations and configuration restrictions](/serverless/containers/reference-content/containers-limitations/) for more information. +# Where should I host my container images for deployment ? + + + +# How can I copy an image from an external registry to Scaleway Container Registry? + +You can copy an image from an external registry by [logging in to the Scaleway Container Registry](/containers/container-registry/how-to/connect-docker-cli/) using the Docker CLI, and by copying the image as shown below: + +```sh +docker pull alpine:latest +docker tag alpine:latest rg.fr-par.scw.cloud/example/alpine:latest +docker push rg.fr-par.scw.cloud/example/alpine:latest +``` + +Alternatively, you can use tools such as [Skopeo](https://github.com/containers/skopeo) to copy the image: + +```sh +skopeo login rg.fr-par.scw.cloud -u nologin -p $SCW_SECRET_KEY +skopeo copy --override-os linux docker://docker.io/alpine:latest docker://rg.fr-par.scw.cloud/example/alpine:latest +``` + ## Can I whitelist the IPs of my containers? Serverless Containers does not yet support Private Networks. However, you can use the Scaleway IP ranges defined at [https://www.scaleway.com/en/peering/](https://www.scaleway.com/en/peering/) on Managed Databases and other products that allow IP filtering. diff --git a/faq/serverless-jobs.mdx b/faq/serverless-jobs.mdx index 554909feb5..fb7baf3451 100644 --- a/faq/serverless-jobs.mdx +++ b/faq/serverless-jobs.mdx @@ -94,6 +94,27 @@ Scaleway Serverless Jobs is part of the Scaleway ecosystem, it can therefore be When starting a job, you can use contextual options to define the number of jobs to execute at the same time. Refer to the [dedicated documentation](/serverless/jobs/how-to/run-job/#how-to-run-a-job-with-contextual-options) for more information. +# Where should I host my jobs images for deployment ? + + + +# How can I copy an image from an external registry to Scaleway Container Registry? + +You can copy an image from an external registry by [logging in to the Scaleway Container Registry](/containers/container-registry/how-to/connect-docker-cli/) using the Docker CLI, and by copying the image as shown below: + +```sh +docker pull alpine:latest +docker tag alpine:latest rg.fr-par.scw.cloud/example/alpine:latest +docker push rg.fr-par.scw.cloud/example/alpine:latest +``` + +Alternatively, you can use tools such as [Skopeo](https://github.com/containers/skopeo) to copy the image: + +```sh +skopeo login rg.fr-par.scw.cloud -u nologin -p $SCW_SECRET_KEY +skopeo copy --override-os linux docker://docker.io/alpine:latest docker://rg.fr-par.scw.cloud/example/alpine:latest +``` + ## How can I configure access to a Private Network? Scaleway Serverless Jobs does not currently support Scaleway VPC or Private Networks, though this feature is under development. diff --git a/macros/serverless/container-registry-note.mdx b/macros/serverless/container-registry-note.mdx new file mode 100644 index 0000000000..e407cb12c2 --- /dev/null +++ b/macros/serverless/container-registry-note.mdx @@ -0,0 +1,6 @@ +--- +macro: container-registry-note +--- + +[Scaleway's Container Registry](/containers/container-registry/) allows for a seamless integration with Serverless Containers and Jobs at a [competitive price](/faq/containerregistry/#how-am-i-billed-for-scaleway-container-registry). +Serverless products support external public registries (such as [Docker Hub](https://hub.docker.com/search?q=)), but we do not recommend using them due to uncontrolled rate limiting, which can lead to failures when starting resources, unexpected usage conditions, and pricing changes. diff --git a/serverless/containers/how-to/deploy-a-container-from-external-container-registry.mdx b/serverless/containers/how-to/deploy-a-container-from-external-container-registry.mdx index c27e4e33d0..49b2041071 100644 --- a/serverless/containers/how-to/deploy-a-container-from-external-container-registry.mdx +++ b/serverless/containers/how-to/deploy-a-container-from-external-container-registry.mdx @@ -20,6 +20,10 @@ A container is a package of software that includes all dependencies: code, runti For now, Serverless Containers only supports public images. + + + + - A Scaleway account logged into the [console](https://console.scaleway.com) @@ -33,7 +37,7 @@ For now, Serverless Containers only supports public images. 4. Complete the following steps in the wizard: - Select the **External** container registry. - Enter the public container **image URL** provided by the external registry. For example: - - `nginx:latest` to deploy the latest nginx image from [Docker Hub](https://hub.docker.com/search?q=) + - `nginx:latest` to deploy the latest nginx image from [Docker Hub](https://hub.docker.com/) - `ghcr.io/namespace/image` to deploy an image from [GitHub Container Registry](https://github.com/features/packages) - Choose the [port](/serverless/containers/concepts/#port) your container is listening on. We recommend configuring your container to listen on the `$PORT` environment variable. - Choose a **name** for your container and, optionally, a **description**. The name must only contain alphanumeric characters and dashes. diff --git a/serverless/containers/quickstart.mdx b/serverless/containers/quickstart.mdx index 38e3f03420..890f701770 100644 --- a/serverless/containers/quickstart.mdx +++ b/serverless/containers/quickstart.mdx @@ -34,7 +34,7 @@ You can deploy a container from the Scaleway Container Registry or any other pub If you have no existing Serverless Containers resources in your current Project, the creation process will guide you through the creation of a namespace, and then a container. - Make sure that you have [created a Container Registry namespace](/containers/container-registry/how-to/create-namespace/) and [pushed the latest NGINX Docker image](/containers/container-registry/how-to/push-images/) to it. + Make sure that you have [created a Container Registry namespace](/containers/container-registry/how-to/create-namespace/) and [pushed the latest NGINX Docker image](/containers/container-registry/how-to/push-images/) (or any other image with a web server) to it. 1. Click **Containers** in the **Serverless** section of the side menu. The containers page displays. @@ -70,6 +70,10 @@ If you have no existing Serverless Containers resources in your current Project, If you have no existing Serverless Containers resources in your current Project, the creation process will guide you through the creation of a namespace, and then a container. + + + + 1. Click **Containers** in the **Serverless** section of the side menu. The containers page displays. 2. Click **Deploy container**. The containers namespace creation wizard displays. 3. Complete the following steps in the wizard: diff --git a/serverless/containers/troubleshooting/common-errors.mdx b/serverless/containers/troubleshooting/common-errors.mdx index 83931eceb9..4dc75d96f3 100644 --- a/serverless/containers/troubleshooting/common-errors.mdx +++ b/serverless/containers/troubleshooting/common-errors.mdx @@ -56,3 +56,13 @@ The new deploy failed, and the [fallback mechanism has been triggered](/serverle ### Possible solution Identify the element that caused the deployment to fail, fix the error, and deploy the container again. + +## Issues when retrieving an external image + +### Cause + +Serverless products support external public registries (such as [Docker Hub](https://hub.docker.com/)), but we do not recommend using them due to uncontrolled rate limiting, which can lead to failures when starting resources, unexpected usage conditions, and pricing changes. + +### Solution + +We recommend using [Scaleway's Container Registry](/containers/container-registry/) instead, as it allows for a seamless integration with Serverless Containers and Jobs at a [competitive price](/faq/containerregistry/#how-am-i-billed-for-scaleway-container-registry). \ No newline at end of file diff --git a/serverless/jobs/how-to/create-job-from-external-registry.mdx b/serverless/jobs/how-to/create-job-from-external-registry.mdx index 6868d88319..f3dd7d73ef 100644 --- a/serverless/jobs/how-to/create-job-from-external-registry.mdx +++ b/serverless/jobs/how-to/create-job-from-external-registry.mdx @@ -14,10 +14,12 @@ categories: - jobs --- -Scaleway allows you to create jobs from external public [container registries](/containers/container-registry/concepts/#registry), such as Docker Hub, AWS container registries, GitLab container registry, etc. +Scaleway Serverless Jobs allows you to create jobs from external public [container registries](/containers/container-registry/concepts/#registry), such as Docker Hub, AWS container registries, GitLab container registry, etc. - - Private container registries are currently not supported. +Private external container registries are currently not supported. + + + diff --git a/serverless/jobs/quickstart.mdx b/serverless/jobs/quickstart.mdx index 0dec7783cc..8ddc856c50 100644 --- a/serverless/jobs/quickstart.mdx +++ b/serverless/jobs/quickstart.mdx @@ -26,18 +26,17 @@ This page explains how to create a job definition with the latest Alpine Linux i - A Scaleway account logged into the [console](https://console.scaleway.com) - [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization +- [Created a Container Registry namespace](/containers/container-registry/how-to/create-namespace/) and [pushed a container image](/containers/container-registry/how-to/push-images/) to it ## How to create a job definition -To keep this quickstart simple, we will create a job from a public external registry. To create a job from the Scaleway Container Registry, refer to [this documentation](/serverless/jobs/how-to/create-job-from-scaleway-registry/). - 1. Click **Jobs** in the **Serverless** section of the side menu. The Jobs page displays. 2. Click **+ Create job**. 3. Complete the following steps in the wizard: - - Select the **External** container registry. - - Enter `docker.io/library/alpine:latest` in the image URL field. + - Select the **Scaleway** Container Registry. + - Select the appropriate **Registry namespace** from the drop-down list, then select the desired **container** and **tag**. - Enter a **name** or use the automatically generated one. The name can only contain lowercase alphanumeric characters and dashes. - Enter a **description** (optional). - Select the region in which your job will be created. @@ -51,6 +50,10 @@ To keep this quickstart simple, we will create a job from a public external regi 6. Click **Create a job definition** to finish. + + + + ## How to run a job 1. Click **Jobs** in the **Serverless** section of the side menu. The jobs page displays. diff --git a/serverless/jobs/troubleshooting/common-errors.mdx b/serverless/jobs/troubleshooting/common-errors.mdx index 09a1d162d7..db3a79a95c 100644 --- a/serverless/jobs/troubleshooting/common-errors.mdx +++ b/serverless/jobs/troubleshooting/common-errors.mdx @@ -20,3 +20,13 @@ categories: - Make sure you built your image for an `amd64` architecture, as `arm64` is not supported. See [Architecture](/serverless/jobs/reference-content/jobs-limitations/#Architecture) documentation. - Make sure your deployment does not exceed the limitations of [Serverless Jobs](/serverless/jobs/reference-content/jobs-limitations/). + +## Issues when retrieving an external image + +### Cause + +Serverless products support external public registries (such as [Docker Hub](https://hub.docker.com/)), but we do not recommend using them due to uncontrolled rate limiting, which can lead to failures when starting resources, unexpected usage conditions, and pricing changes. + +### Solution + +We recommend using [Scaleway's Container Registry](/containers/container-registry/) instead, as it allows for a seamless integration with Serverless Containers and Jobs at a [competitive price](/faq/containerregistry/#how-am-i-billed-for-scaleway-container-registry). \ No newline at end of file From 85220f11650a25122e96c22bb0f71c689796a101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oc=C3=A9ane?= Date: Wed, 23 Oct 2024 15:43:57 +0200 Subject: [PATCH 26/68] feat(changelog): elastic-metal-added-disk-partitioning-configuration-now 2024-10-23 (#3868) --- ...al-added-disk-partitioning-configuration-now.mdx | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 changelog/october2024/2024-10-23-elastic-metal-added-disk-partitioning-configuration-now.mdx diff --git a/changelog/october2024/2024-10-23-elastic-metal-added-disk-partitioning-configuration-now.mdx b/changelog/october2024/2024-10-23-elastic-metal-added-disk-partitioning-configuration-now.mdx new file mode 100644 index 0000000000..0147009e42 --- /dev/null +++ b/changelog/october2024/2024-10-23-elastic-metal-added-disk-partitioning-configuration-now.mdx @@ -0,0 +1,13 @@ +--- +title: Disk partitioning configuration now available! +status: added +author: + fullname: 'Join the #elastic-metal channel on Slack.' + url: 'https://slack.scaleway.com' +date: 2024-10-23 +category: bare-metal +product: elastic-metal +--- + +You can now partition the disk capacity of your server as needed during server setup by directly editing the JSON file in the Scaleway console. Eligible servers are marked with the green 'NEW' badge. +Refer to the [dedicated page](/bare-metal/elastic-metal/how-to/configure-disk-partitions/) for more details on custom partitioning. From d497214955c8ee19e09b1839cff63c0b8ec3457d Mon Sep 17 00:00:00 2001 From: nerda-codes <87707325+nerda-codes@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:49:39 +0200 Subject: [PATCH 27/68] docs(cpt): add gpu instanceXCockpit tuto (#3865) --- observability/cockpit/index.mdx | 5 + .../monitor-gpu-instance-cockpit/index.mdx | 214 ++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 tutorials/monitor-gpu-instance-cockpit/index.mdx diff --git a/observability/cockpit/index.mdx b/observability/cockpit/index.mdx index e367704732..709fc715e4 100644 --- a/observability/cockpit/index.mdx +++ b/observability/cockpit/index.mdx @@ -61,6 +61,11 @@ meta: url="/observability/cockpit/how-to/send-metrics-with-grafana-alloy/" label="Read more" /> + diff --git a/tutorials/monitor-gpu-instance-cockpit/index.mdx b/tutorials/monitor-gpu-instance-cockpit/index.mdx new file mode 100644 index 0000000000..d43ea26f12 --- /dev/null +++ b/tutorials/monitor-gpu-instance-cockpit/index.mdx @@ -0,0 +1,214 @@ +--- +meta: + title: Monitor GPU Instances using Cockpit and the NVIDIA Data Center GPU Manager (DCGM) Exporter + description: This page explains how to visualize metrics and logs from GPU Instances using Cockpit and the NVIDIA Data Center GPU Manager (DCGM) Exporter +content: + h1: Monitor GPU Instances using Cockpit and the NVIDIA Data Center GPU Manager (DCGM) Exporter + paragraph: This page explains how to visualize metrics and logs from GPU Instances using Cockpit and the NVIDIA Data Center GPU Manager (DCGM) Exporter +dates: + validation: 2024-10-21 + posted: 2024-10-21 +--- + +This tutorial guides you through the process of monitoring your [GPU Instances](/compute/instances/concepts/#gpu-instance) using Cockpit and the [NVIDIA Data Center GPU Manager (DCGM) Exporter](https://docs.nvidia.com/datacenter/cloud-native/gpu-telemetry/latest/dcgm-exporter.html). Visualize your GPU Instances' metrics and ensure optimal performance and usage of your resources. + + + +- A Scaleway account logged into the [console](https://console.scaleway.com) +- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization +- Created a [GPU Instance](/compute/gpu/how-to/create-manage-gpu-instance/) +- [Connected to your Instance via SSH](/compute/gpu/how-to/create-manage-gpu-instance/#how-to-connect-to-a-gpu-instance) +- Installed [Docker Engine](https://docs.docker.com/engine/install/) and [Docker Compose](https://docs.docker.com/compose/install/linux/#install-using-the-repository) on your GPU Instance. + +## Create a Cockpit data source and credentials + +### Create a Cockpit data source + +We are creating a Cockpit data source because your GPU Instance's metrics will be stored in it and the exporter agent needs data source configuration information to then export your Instance's metrics. + +1. Create a metrics [custom data source in Cockpit](/observability/cockpit/how-to/create-external-data-sources/). For the sake of this tutorial, we will name it `gpu-instance-metrics`. + + + - To fill in the cost estimator, you can assume that **1 metric sent without [specific cardinality](https://grafana.com/docs/tempo/latest/metrics-generator/cardinality/)** (ie. without labels or value duplication for a same metric) **every minute will generate around 50 000 samples per month** (60 minutes x 730 hours per month = 43 800 samples). By default, DCGM and node exporter will send multiple metrics and add labels to these metrics leading to a higher number of samples. + - **We recommend that you complete this tutorial first** to visualize your data, and **then review your configuration to optimize the number of metrics or labels sent**. + +2. Click your metrics data source to view information such as its **URL** and **push path**. + +### Create a token + +1. Create a [Cockpit token](/observability/cockpit/how-to/create-token/) from the [Scaleway console](https://console.scaleway.com/cockpit/tokens). +2. Select a region for the data source. +3. Tick the **Push Metrics** box and click **Create token** to confirm. + + + Copy and store your token securely. We will use it to allow the Grafana Alloy agent to push your metrics to the metrics data source you have created earlier. + + +## Collect metrics from your GPU Instance + +### Install the NVIDIA DCGM Exporter, node exporter and Grafana Alloy agent on your GPU Instance + +1. [Connect to your GPU Instance through SSH](/compute/gpu/how-to/create-manage-gpu-instance/#how-to-connect-to-a-gpu-instance). +2. Copy and paste the following command to create a configuration file named `config.alloy` in your Instance: + ```sh + touch config.alloy + ``` +3. Copy and paste the following template inside `config.alloy`: + ```json + prometheus.remote_write "cockpit" { + endpoint { + url = "https://example-afc6-4d02-a2fd-bc020bbaa7d0.metrics.cockpit.fr-par.scw.cloud/api/v1/push" + headers = { + "X-TOKEN" = "example_bKNpXZZP6BSKiYzV8fiQL1yR_kP_VLB-h0tpYAkaNoVTHVm8q", + } + } + } + + prometheus.scrape "dcgm_exporter" { + scrape_interval = "60s" + targets = [{__address__ = "dcgm_exporter:9400"}] + forward_to = [prometheus.remote_write.cockpit.receiver] + } + + prometheus.exporter.unix "node_exporter" { + set_collectors = [ + "uname", + "cpu", + "cpufreq", + "loadavg", + "meminfo", + "filesystem", + "netdev", + ] + } + + prometheus.scrape "node_exporter" { + scrape_interval = "60s" + targets = prometheus.exporter.unix.node_exporter.targets + forward_to = [prometheus.remote_write.cockpit.receiver] + } + ``` +4. Replace the values of `cockpit.endpoint.url` (`https://example-afc6-4d02-a2fd-bc020bbaa7d0.metrics.cockpit.fr-par.scw.cloud/api/v1/push`) and `cockpit.endpoint.headers.X-TOKEN` (`example_bKNpXZZP6BSKiYzV8fiQL1yR_kP_VLB-h0tpYAkaNoVTHVm8q`) with the ones of your `gpu-instance-metrics`[Cockpit data source](https://console.scaleway.com/cockpit/dataSource). + + This configuration allows you to: + - collect performance data (using `dcgm_exporter`) from your GPU Instance. This includes information like GPU load (how much of the GPU's processing power is being used), temperature, and other relevant metrics. + - collect standard Instance metrics with `node_exporter` (CPU load, disk size, etc.) + - push the collected data to your Cockpit data source (using `cockpit`). + + + - The current configuration is set to send only a limited number of metrics from `node_exporter` (the tool collecting CPU, disk, memory, etc. data). Because of this, some data might not show up on your Cockpit dashboards in Grafana when you import them. + - If you want to send all available data from `node_exporter`, you need to edit its configuration. Specifically, you need to remove the `set_collectors` list from the configuration. This list defines which metrics are being collected, and removing it will allow all metrics to be sent. + - While removing the `set_collectors` list will provide more detailed metrics, it may come with **higher resource usage and associated costs**, especially if you are using a paid service for data monitoring or storage. + + +5. Copy and paste the following command to create a `docker-compose.yaml` file in your Instance: + ```sh + touch docker-compose.yaml + ``` +6. Copy and paste the following configuration inside `docker-compose.yaml`, save it and exit the file. + ```yaml + services: + dcgm_exporter: + image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.0-3.2.0-ubuntu22.04 + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [ gpu ] + cap_add: + - SYS_ADMIN + ports: + - "9400:9400" + + agent: + image: grafana/alloy:latest + ports: + - "12345:12345" + volumes: + - "./config.alloy:/etc/alloy/config.alloy" + command: [ + "run", + "--server.http.listen-addr=0.0.0.0:12345", + "/etc/alloy/config.alloy", + ] + ``` + This configuration will: + - deploy the DCGM exporter + - deploy the Grafana Alloy agent + +7. Run docker services using the following command: + ```yaml + docker compose up + ``` + +## Create Cockpit dashboards in Grafana + +### Create a GPU metrics dashboard + +1. Access the **Overview** tab of your [Cockpit](https://console.scaleway.com/cockpit/overview) and click **Open dashboards** to open your Cockpit dashboards in Grafana. + +2. Click the **+** icon in the top-right-hand corner, then click **Import dashboard**. + +3. Copy the ID (`12219`) of the [Grafana NVIDIA DCGM Exporter dashboard](https://grafana.com/grafana/dashboards/12219-nvidia-dcgm-exporter-dashboard/) and paste it in the **Import via grafana.com** field. + +4. Click **Load**. + +5. Select your Prometheus data source named `gpu-instance-metrics`, then click **Import** + +You should see your dashboard with data such as **GPU Temperature** or **GPU Power Usage**. + + + If you see only an empty dashboard with the "Dashboard not Found" and "Access denied to this dashboard" error, wait a few seconds and refresh the page. Your dashboard should then display. + Alternatively, you can also click the **Menu** icon on the left, then on **Dashboards** and search through your dashboards. You should see your newly created dashboard. + + +### Create a CPU and disk metrics Cockpit dashboard in Grafana + +1. Access the **Overview** tab of your [Cockpit](https://console.scaleway.com/cockpit/overview) and click **Open dashboards** to open your Cockpit dashboards in Grafana. + +2. Click the **+** icon in the top-right-hand corner, then click **Import dashboard**. + +3. Copy the ID (`1860`) of the [Node Exporter Full dashboard](https://grafana.com/grafana/dashboards/1860-node-exporter-full/) and paste it in the **Import via grafana.com** field. + +4. Click **Load**. + +5. Select your Prometheus data source named `gpu-instance-metrics`, then click **Import** + +You should now see your dashboard with data such as **CPU usage** and **Memory Usage**. + + + If you see only an empty dashboard with the "Dashboard not Found" and "Access denied to this dashboard" error, wait a few seconds and refresh the page. Your dashboard should then display. + If you still do not see any data, make sure that you select the `gpu-instance-metrics` in the **Datasource** dropdown list located in the top-left-hand corner. + + + + The current configuration of the Node Exporter agent does not include certain metrics, such as: + - Swap used: How much swap space (virtual memory) is currently being used by the system. + - Root FS used: How much of the root file system (main storage partition) is being used. + + +You can now find your newly created dashboards in your list of Cockpit dashboards in Grafana. This allows you to access your GPU Instances data to monitor and optimize your resources. + +### Going further + +- **Add more metrics to your dashboards** + - Connect to your GPU Instance via SSH + - Edit the `config.alloy` file and restart the agents using the `docker compose up` command + - Update your Cockpit dashboards in Grafana + +- **Create custom dashboards** + - In Grafana explore the metrics you have sent by clicking the **Menu** icon on the left, then **Explore**. + - Select your custom data source named `gpu-instance-metrics` in the **Datasource** dropdown list located in the top-left-hand corner. + - Click **Metrics browser**. You should see a list of metrics appear (for example, `DCGM_FI_DEV_GPU_TEMP` or `node_cpu_seconds_total`). + - Write the desired query, click **Run query** to visualize data, and then **Add to dashboard** to add it to a new or existing dashboard. + +## Troubleshooting + +If you encounter any issues, make sure that you meet all the requirements listed at the beginning of this tutorial. + +You can run `docker -v` in your terminal to check your docker version. You should see an output similar to the following: + ``` + Docker version 24.0.6, build ed223bc820 + ``` \ No newline at end of file From 9fbab81a0abc2da328e96f4e4107f5de398e6d60 Mon Sep 17 00:00:00 2001 From: Thibault Genaitay Date: Wed, 23 Oct 2024 16:34:58 +0200 Subject: [PATCH 28/68] fix(inference): changed to full names everywhere (#3871) --- .../how-to/managed-inference-with-private-network.mdx | 2 +- .../reference-content/llama-3-70b-instruct.mdx | 3 +-- .../reference-content/llama-3-8b-instruct.mdx | 3 +-- .../reference-content/llama-3.1-70b-instruct.mdx | 5 ++--- .../reference-content/llama-3.1-8b-instruct.mdx | 3 +-- .../reference-content/mistral-7b-instruct-v0.3.mdx | 5 ++--- .../reference-content/mistral-nemo-instruct-2407.mdx | 5 ++--- .../reference-content/mixtral-8x7b-instruct-v0.1.mdx | 3 +-- .../managed-inference/reference-content/pixtral-12b-2409.mdx | 1 - .../managed-inference/reference-content/sentence-t5-xxl.mdx | 3 +-- .../reference-content/wizardlm-70b-v1.0.mdx | 3 +-- 11 files changed, 13 insertions(+), 23 deletions(-) diff --git a/ai-data/managed-inference/how-to/managed-inference-with-private-network.mdx b/ai-data/managed-inference/how-to/managed-inference-with-private-network.mdx index 8979e9e81d..ca4f2c65da 100644 --- a/ai-data/managed-inference/how-to/managed-inference-with-private-network.mdx +++ b/ai-data/managed-inference/how-to/managed-inference-with-private-network.mdx @@ -91,7 +91,7 @@ Using a Private Network for communications between your Instances hosting your a import requests PAYLOAD = { - "model": "", # EXAMPLE= meta/llama-3-8b-instruct:bf16 + "model": "", # EXAMPLE= meta/llama-3.1-8b-instruct:fp8 "messages": [ {"role": "system", "content": "You are a helpful, respectful and honest assistant."}, diff --git a/ai-data/managed-inference/reference-content/llama-3-70b-instruct.mdx b/ai-data/managed-inference/reference-content/llama-3-70b-instruct.mdx index 909171c226..543a8e0158 100644 --- a/ai-data/managed-inference/reference-content/llama-3-70b-instruct.mdx +++ b/ai-data/managed-inference/reference-content/llama-3-70b-instruct.mdx @@ -17,7 +17,6 @@ categories: | Attribute | Details | |-----------------|------------------------------------| | Provider | [Meta](https://llama.meta.com/llama3/) | -| Model Name | `llama-3-70b-instruct` | | Compatible Instances | H100 (FP8) | | Context size | 8192 tokens | @@ -62,7 +61,7 @@ curl -s \ -H "Content-Type: application/json" \ --request POST \ --url "https://.ifr.fr-par.scaleway.com/v1/chat/completions" \ ---data '{"model":"llama-3-70b-instruct", "messages":[{"role": "user","content": "Sing me a song about Xavier Niel"}], "max_tokens": 500, "top_p": 1, "temperature": 0.7, "stream": false}' +--data '{"model":"meta/llama-3-70b-instruct:fp8", "messages":[{"role": "user","content": "Sing me a song about Xavier Niel"}], "max_tokens": 500, "top_p": 1, "temperature": 0.7, "stream": false}' ``` Make sure to replace `` and `` with your actual [IAM API key](/identity-and-access-management/iam/how-to/create-api-keys/) and the Deployment UUID you are targeting. diff --git a/ai-data/managed-inference/reference-content/llama-3-8b-instruct.mdx b/ai-data/managed-inference/reference-content/llama-3-8b-instruct.mdx index cd23ecf682..6970e05524 100644 --- a/ai-data/managed-inference/reference-content/llama-3-8b-instruct.mdx +++ b/ai-data/managed-inference/reference-content/llama-3-8b-instruct.mdx @@ -17,7 +17,6 @@ categories: | Attribute | Details | |-----------------|------------------------------------| | Provider | [Meta](https://llama.meta.com/llama3/) | -| Model Name | `llama-3-8b-instruct` | | Compatible Instances | L4, H100 (FP8, BF16) | | Context size | 8192 tokens | @@ -66,7 +65,7 @@ curl -s \ -H "Content-Type: application/json" \ --request POST \ --url "https://.ifr.fr-par.scaleway.com/v1/chat/completions" \ ---data '{"model":"llama-3-8b-instruct", "messages":[{"role": "user","content": "There is a llama in my garden, what should I do?"}], "max_tokens": 500, "top_p": 1, "temperature": 0.7, "stream": false}' +--data '{"model":"meta/llama-3-8b-instruct:fp8", "messages":[{"role": "user","content": "There is a llama in my garden, what should I do?"}], "max_tokens": 500, "top_p": 1, "temperature": 0.7, "stream": false}' ``` Make sure to replace `` and `` with your actual [IAM API key](/identity-and-access-management/iam/how-to/create-api-keys/) and the Deployment UUID you are targeting. diff --git a/ai-data/managed-inference/reference-content/llama-3.1-70b-instruct.mdx b/ai-data/managed-inference/reference-content/llama-3.1-70b-instruct.mdx index 26266b795c..eb6695e46b 100644 --- a/ai-data/managed-inference/reference-content/llama-3.1-70b-instruct.mdx +++ b/ai-data/managed-inference/reference-content/llama-3.1-70b-instruct.mdx @@ -17,8 +17,7 @@ categories: | Attribute | Details | |-----------------|------------------------------------| | Provider | [Meta](https://llama.meta.com/llama3/) | -| License | [Llama 3.1 community](https://llama.meta.com/llama3_1/license/) | -| Model Name | `llama-3.1-70b-instruct` | +| License | [Llama 3.1 community](https://llama.meta.com/llama3_1/license/) | | | Compatible Instances | H100 (FP8), H100-2 (FP8, BF16) | | Context Length | up to 128k tokens | @@ -61,7 +60,7 @@ curl -s \ -H "Content-Type: application/json" \ --request POST \ --url "https://.ifr.fr-par.scaleway.com/v1/chat/completions" \ ---data '{"model":"llama-3.1-70b-instruct", "messages":[{"role": "user","content": "There is a llama in my garden, what should I do?"}], "max_tokens": 500, "temperature": 0.7, "stream": false}' +--data '{"model":"meta/llama-3.1-70b-instruct:fp8", "messages":[{"role": "user","content": "There is a llama in my garden, what should I do?"}], "max_tokens": 500, "temperature": 0.7, "stream": false}' ``` Make sure to replace `` and `` with your actual [IAM API key](/identity-and-access-management/iam/how-to/create-api-keys/) and the Deployment UUID you are targeting. diff --git a/ai-data/managed-inference/reference-content/llama-3.1-8b-instruct.mdx b/ai-data/managed-inference/reference-content/llama-3.1-8b-instruct.mdx index c7f943c185..1e45a0dcdb 100644 --- a/ai-data/managed-inference/reference-content/llama-3.1-8b-instruct.mdx +++ b/ai-data/managed-inference/reference-content/llama-3.1-8b-instruct.mdx @@ -18,7 +18,6 @@ categories: |-----------------|------------------------------------| | Provider | [Meta](https://llama.meta.com/llama3/) | | License | [Llama 3.1 community](https://llama.meta.com/llama3_1/license/) | -| Model Name | `llama-3.1-8b-instruct` | | Compatible Instances | L4, H100, H100-2 (FP8, BF16) | | Context Length | up to 128k tokens | @@ -62,7 +61,7 @@ curl -s \ -H "Content-Type: application/json" \ --request POST \ --url "https://.ifr.fr-par.scaleway.com/v1/chat/completions" \ ---data '{"model":"llama-3.1-8b-instruct", "messages":[{"role": "user","content": "There is a llama in my garden, what should I do?"}], "max_tokens": 500, "temperature": 0.7, "stream": false}' +--data '{"model":"meta/llama-3.1-8b-instruct:fp8", "messages":[{"role": "user","content": "There is a llama in my garden, what should I do?"}], "max_tokens": 500, "temperature": 0.7, "stream": false}' ``` Make sure to replace `` and `` with your actual [IAM API key](/identity-and-access-management/iam/how-to/create-api-keys/) and the Deployment UUID you are targeting. diff --git a/ai-data/managed-inference/reference-content/mistral-7b-instruct-v0.3.mdx b/ai-data/managed-inference/reference-content/mistral-7b-instruct-v0.3.mdx index 3b448ef6c6..f4ff7ba4a6 100644 --- a/ai-data/managed-inference/reference-content/mistral-7b-instruct-v0.3.mdx +++ b/ai-data/managed-inference/reference-content/mistral-7b-instruct-v0.3.mdx @@ -17,14 +17,13 @@ categories: | Attribute | Details | |-----------------|------------------------------------| | Provider | [Mistral](https://mistral.ai/technology/#models) | -| Model Name | `mistral-7b-instruct-v0.3` | | Compatible Instances | L4 (BF16) | | Context size | 32K tokens | ## Model name ```bash -mistral-7b-instruct-v0.3:bf16 +mistral/mistral-7b-instruct-v0.3:bf16 ``` ## Compatible Instances @@ -55,7 +54,7 @@ curl -s \ -H "Content-Type: application/json" \ --request POST \ --url "https://.ifr.fr-par.scaleway.com/v1/chat/completions" \ ---data '{"model":"mistral-7b-instruct-v0.3", "messages":[{"role": "user","content": "Explain Public Cloud in a nutshell."}], "top_p": 1, "temperature": 0.7, "stream": false}' +--data '{"model":"mistral/mistral-7b-instruct-v0.3:bf16", "messages":[{"role": "user","content": "Explain Public Cloud in a nutshell."}], "top_p": 1, "temperature": 0.7, "stream": false}' ``` Make sure to replace `` and `` with your actual [IAM API key](/identity-and-access-management/iam/how-to/create-api-keys/) and the Deployment UUID you are targeting. diff --git a/ai-data/managed-inference/reference-content/mistral-nemo-instruct-2407.mdx b/ai-data/managed-inference/reference-content/mistral-nemo-instruct-2407.mdx index 7662863fb3..83c5472988 100644 --- a/ai-data/managed-inference/reference-content/mistral-nemo-instruct-2407.mdx +++ b/ai-data/managed-inference/reference-content/mistral-nemo-instruct-2407.mdx @@ -17,14 +17,13 @@ categories: | Attribute | Details | |-----------------|------------------------------------| | Provider | [Mistral](https://mistral.ai/technology/#models) | -| Model Name | `mistral-nemo-instruct-2407` | | Compatible Instances | H100 (FP8) | | Context size | 128K tokens | ## Model name ```bash -mistral-nemo-instruct-2407:fp8 +mistral/mistral-nemo-instruct-2407:fp8 ``` ## Compatible Instances @@ -61,7 +60,7 @@ curl -s \ -H "Content-Type: application/json" \ --request POST \ --url "https://.ifr.fr-par.scaleway.com/v1/chat/completions" \ ---data '{"model":"mistral-nemo-instruct-2407", "messages":[{"role": "user","content": "Sing me a song about Xavier Niel"}], "top_p": 1, "temperature": 0.35, "stream": false}' +--data '{"model":"mistral/mistral-nemo-instruct-2407:fp8", "messages":[{"role": "user","content": "Sing me a song about Xavier Niel"}], "top_p": 1, "temperature": 0.35, "stream": false}' ``` Make sure to replace `` and `` with your actual [IAM API key](/identity-and-access-management/iam/how-to/create-api-keys/) and the Deployment UUID you are targeting. diff --git a/ai-data/managed-inference/reference-content/mixtral-8x7b-instruct-v0.1.mdx b/ai-data/managed-inference/reference-content/mixtral-8x7b-instruct-v0.1.mdx index f48a258257..4f5fc07f5f 100644 --- a/ai-data/managed-inference/reference-content/mixtral-8x7b-instruct-v0.1.mdx +++ b/ai-data/managed-inference/reference-content/mixtral-8x7b-instruct-v0.1.mdx @@ -17,7 +17,6 @@ categories: | Attribute | Details | |-----------------|------------------------------------| | Provider | [Mistral](https://mistral.ai/technology/#models) | -| Model Name | `mixtral-8x7b-instruct-v0.1` | | Compatible Instances | H100 (FP8) - H100-2 (FP16) | | Context size | 32k tokens | @@ -57,7 +56,7 @@ curl -s \ -H "Content-Type: application/json" \ --request POST \ --url "https://.ifr.fr-par.scaleway.com/v1/chat/completions" \ ---data '{"model":"mixtral-8x7b-instruct-v0.1", "messages":[{"role": "user","content": "Sing me a song about Scaleway"}], "max_tokens": 200, "top_p": 1, "temperature": 1, "stream": false}' +--data '{"model":"mistral/mixtral-8x7b-instruct-v0.1:fp8", "messages":[{"role": "user","content": "Sing me a song about Scaleway"}], "max_tokens": 200, "top_p": 1, "temperature": 1, "stream": false}' ``` Make sure to replace `` and `` with your actual [IAM API key](/identity-and-access-management/iam/how-to/create-api-keys/) and the Deployment UUID you are targeting. diff --git a/ai-data/managed-inference/reference-content/pixtral-12b-2409.mdx b/ai-data/managed-inference/reference-content/pixtral-12b-2409.mdx index fd7c14bda1..c8193c38c4 100644 --- a/ai-data/managed-inference/reference-content/pixtral-12b-2409.mdx +++ b/ai-data/managed-inference/reference-content/pixtral-12b-2409.mdx @@ -17,7 +17,6 @@ categories: | Attribute | Details | |-----------------|------------------------------------| | Provider | [Mistral](https://mistral.ai/technology/#models) | -| Model Name | `pixtral-12b-2409` | | Compatible Instances | H100, H100-2 (bf16) | | Context size | 128k tokens | diff --git a/ai-data/managed-inference/reference-content/sentence-t5-xxl.mdx b/ai-data/managed-inference/reference-content/sentence-t5-xxl.mdx index 79015fba5e..c9aefbb111 100644 --- a/ai-data/managed-inference/reference-content/sentence-t5-xxl.mdx +++ b/ai-data/managed-inference/reference-content/sentence-t5-xxl.mdx @@ -15,11 +15,10 @@ categories: | Attribute | Details | |-----------------|------------------------------------| | Provider | [sentence-transformers](https://www.sbert.net/) | -| Model Name | `sentence-t5-xxl` | | Compatible Instances | L4 (FP32) | | Context size | 512 tokens | -## Model names +## Model name ```bash sentence-transformers/sentence-t5-xxl:fp32 diff --git a/ai-data/managed-inference/reference-content/wizardlm-70b-v1.0.mdx b/ai-data/managed-inference/reference-content/wizardlm-70b-v1.0.mdx index d9957b5e48..b58bf15854 100644 --- a/ai-data/managed-inference/reference-content/wizardlm-70b-v1.0.mdx +++ b/ai-data/managed-inference/reference-content/wizardlm-70b-v1.0.mdx @@ -17,7 +17,6 @@ categories: | Attribute | Details | |-----------------|------------------------------------| | Provider | [WizardLM](https://wizardlm.github.io/) | -| Model Name | `wizardlm-70B-V1.0` | | Compatible Instances | H100 (FP8) - H100-2 (FP16) | | Context size | 4,096 tokens | @@ -55,7 +54,7 @@ curl -s \ -H "Content-Type: application/json" \ --request POST \ --url "https://.ifr.fr-par.scaleway.com/v1/chat/completions" \ ---data '{"model":"wizardlm-70B-V1.0", "messages":[{"role": "user","content": "Say hello to Scaleway's Inference"}], "max_tokens": 200, "top_p": 1, "temperature": 1, "stream": false}' +--data '{"model":"wizardlm/wizardlm-70b-v1.0:fp8", "messages":[{"role": "user","content": "Say hello to Scaleway's Inference"}], "max_tokens": 200, "top_p": 1, "temperature": 1, "stream": false}' ``` Make sure to replace `` and `` with your actual [IAM API key](/identity-and-access-management/iam/how-to/create-api-keys/) and the Deployment UUID you are targeting. From 37a73908df069d939273dd9f7e207e67eb0e14cb Mon Sep 17 00:00:00 2001 From: Justine Sudraud <124775951+jsudraud@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:41:15 +0200 Subject: [PATCH 29/68] fix(bil): added guideflow (#3864) * fix(bil): added guideflow * Apply suggestions from code review Co-authored-by: Benedikt Rollik --------- Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> Co-authored-by: Benedikt Rollik --- console/billing/quickstart.mdx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/console/billing/quickstart.mdx b/console/billing/quickstart.mdx index d88004b8fa..a97bc40952 100644 --- a/console/billing/quickstart.mdx +++ b/console/billing/quickstart.mdx @@ -13,8 +13,13 @@ categories: - billing --- -Before you can order Scaleway resources, you must add your payment method to your account. +## Console overview + +Follow this guided tour to discover how to use the Billing Space. + + +Before you can order Scaleway resources, you must add your payment method to your account. - A Scaleway account logged into the [console](https://console.scaleway.com) From df41c7b6aa91a627cadb4f0983656aa5eda3f2ba Mon Sep 17 00:00:00 2001 From: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:42:35 +0200 Subject: [PATCH 30/68] fix(edge): fix duplicate anchors (#3869) * fix(edge): fix duplicate anchors * fix(anchors): improve * fix(edge): fix typo --- .../edge-services/reference-content/ssl-tls-certificate.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/network/edge-services/reference-content/ssl-tls-certificate.mdx b/network/edge-services/reference-content/ssl-tls-certificate.mdx index 611338c16c..d5de0e82f7 100644 --- a/network/edge-services/reference-content/ssl-tls-certificate.mdx +++ b/network/edge-services/reference-content/ssl-tls-certificate.mdx @@ -54,9 +54,9 @@ This is the hassle-free option if you do not want to create or manage your own S You must ensure that you have correctly set the [CNAME record](/network/edge-services/reference-content/cname-record/) for your domain. Without having done this, the Let's Encrypt certificate option in the console will not be available. It is also important to check the CNAME is correctly set up so that the certificate is properly generated and reviewed. -Note that you will not have access to the generated certificate itself in Secret Manager or elsewhere. It is ent pipelineirely generated and managed "behind the scenes", and is not configurable by the user. If you reset your domain, or delete your Edge Services, Scaleway automatically deletes the generated Let's Encrypt certificate. +Note that you will not have access to the generated certificate itself in Secret Manager or elsewhere. It is entirely generated and managed "behind the scenes", and is not configurable by the user. If you reset your domain, or delete your Edge Services, Scaleway automatically deletes the generated Let's Encrypt certificate. -### Troubleshooting +### Troubleshooting Let's Encrypt certificate errors #### Errors @@ -194,7 +194,7 @@ If you change your customized subdomain to something new, you will need to gener -### Troubleshooting +### Troubleshooting certificate errors #### Errors From eb7f7eff669ebb3d8ffb70756001306bfa8d6304 Mon Sep 17 00:00:00 2001 From: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:42:59 +0200 Subject: [PATCH 31/68] fix(pgw): note recommended solution (#3867) * fix(pgw): ssh bastion info * fix(pgw): more * Update network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway.mdx Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> --------- Co-authored-by: Benedikt Rollik Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> --- .../cant-connect-to-instance-with-pn-gateway.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway.mdx b/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway.mdx index 87fe56eab3..d7c14450e2 100644 --- a/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway.mdx +++ b/network/public-gateways/troubleshooting/cant-connect-to-instance-with-pn-gateway.mdx @@ -24,6 +24,8 @@ If the above two conditions are not true, there may be other factors impacting y If DHCP **is** activated and your Public Gateway **is** set to advertise a default route, not being able to connect to your Instance via SSH is **expected behavior**. All the traffic towards your Instance now goes through the Public Gateway. -To access your Instance using SSH, either: -- Use [SSH bastion](/network/public-gateways/how-to/use-ssh-bastion/), or -- Create a static NAT association between a port of your Public Gateway (eg 2222) and the private IP assigned to your Instance, on the SSH port (22 by default). Then, SSH to the Public Gateway's IP on port 2222. \ No newline at end of file +To access your Instance using SSH in this scenario, the recommended solution is to use [SSH bastion](/network/public-gateways/how-to/use-ssh-bastion/). + + +SSH bastion is the recommended solution. For advanced users only, another manual workaround is to create a static NAT association between a port of your Public Gateway (e.g. `2222`) and the private IP assigned to your Instance, on the SSH port (`22` by default). Then, SSH to the Public Gateway's IP on port `2222`. + \ No newline at end of file From fa7ed16a31fb723df5eb3d37976ef585df51e6bf Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Wed, 23 Oct 2024 17:00:29 +0200 Subject: [PATCH 32/68] feat(wbh): add low level doc (#3783) --- .../webhosting/how-to/manage-databases.mdx | 65 +++++++++++++++++++ .../how-to/manage-email-accounts.mdx | 55 ++++++++++++++++ .../webhosting/how-to/manage-ftp-accounts.mdx | 48 ++++++++++++++ managed-services/webhosting/quickstart.mdx | 27 +++++++- menu/navigation.json | 12 ++++ 5 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 managed-services/webhosting/how-to/manage-databases.mdx create mode 100644 managed-services/webhosting/how-to/manage-email-accounts.mdx create mode 100644 managed-services/webhosting/how-to/manage-ftp-accounts.mdx diff --git a/managed-services/webhosting/how-to/manage-databases.mdx b/managed-services/webhosting/how-to/manage-databases.mdx new file mode 100644 index 0000000000..94e92f57b1 --- /dev/null +++ b/managed-services/webhosting/how-to/manage-databases.mdx @@ -0,0 +1,65 @@ +--- +meta: + title: How to manage databases + description: Discover how to manage databases for Scaleway Web Hosting plans from the console. + h1: How to manage databases + paragraph: Discover how to manage databases for Scaleway Web Hosting plans from the console. +tags: webhosting +dates: + validation: 2024-10-02 + posted: 2024-10-02 +categories: + - managed-services +--- + +You can create and manage databases for your website and applications, including user creation and password updates directly from the Scaleway console. + + + + +- A Scaleway account logged into the [console](https://console.scaleway.com) +- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization +- [Registered a domain name](/network/domains-and-dns/how-to/register-internal-domain/) at Scaleway or another registrar +- A Web Hosting plan + +## How to create a database + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **Databases** tab to display information related to your databases. +4. Click **Create database** in the **Database** section of the page. A pop-up displays. +5. Enter a name for the database, select an existing database user from the drop-down list or create a new one by entering a username and password. Click **Create database** to create the database. +6. Enter the username and password for your FTP account. Then click **Create FTP account** to submit the form and create the account. + +## How to delete a database + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **Databases** tab to display information related to your databases. +4. Click next to the database you want to delete. A pop-up displays. +5. Click **Delete database** to confirm the action and delete the database. + +## How to create a database user + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **Databases** tab to display information related to your databases. +4. Click **Create database user** in the **Database users** section of the page to create a new one. A pop-up displays. +5. Enter a username and password. Then click **Create database user** to create the user. + +## How to update the password of a database user + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **Databases** tab to display information related to your databases. +4. Click > **Change password** next to the database user whose password you want to change. A pop-up displays. +5. Enter the new password and click **Update database user** to submit the form and update the password. + + +## How to delete a database user + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **Databases** tab to display information related to your databases. +4. Click > **Delete** next to the database user you want to delete. A pop-up displays. +5. Click **Delete database user** to confirm the action and delete the user. diff --git a/managed-services/webhosting/how-to/manage-email-accounts.mdx b/managed-services/webhosting/how-to/manage-email-accounts.mdx new file mode 100644 index 0000000000..e6cb7a3e23 --- /dev/null +++ b/managed-services/webhosting/how-to/manage-email-accounts.mdx @@ -0,0 +1,55 @@ +--- +meta: + title: How to manage email accounts + description: Discover how to manage email accounts for Scaleway Web Hosting plans from the console. + h1: How to manage email accounts + paragraph: Discover how to manage email accounts for Scaleway Web Hosting plans from the console. +tags: webhosting +dates: + validation: 2024-10-02 + posted: 2024-10-02 +categories: + - managed-services +--- + +Send, receive, and store electronic messages through the internet. Email accounts can be accessed via POP3 and IMAP protocols and managed from the Scaleway console. + + + +- A Scaleway account logged into the [console](https://console.scaleway.com) +- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization +- [Registered a domain name](/network/domains-and-dns/how-to/register-internal-domain/) at Scaleway or another registrar +- A Web Hosting plan + +## How to create an email account + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **Emails** tab to display information related to your email accounts. +4. Click **Create email account** to create a new one. A pop-up displays. +5. Select the domain you want to associate the email account with from the drop-down list, then enter a username and password. + + The username is the part of your email address in front of the @. + +6. Click **Create email account** to confirm the action and create the account. + + + To access webmail for the email account, click **Access webmail** next to the email account. + + + +## How to update the password of an email account + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **Emails** tab to display information related to your email accounts. +4. Click > **Change password** next to the email account whose password you want to change. A pop-up displays. +5. Enter the new password and click **Change password** to submit the form and update the password. + +## How to delete an email account + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **Emails** tab to display information related to your email accounts. +4. Click > **Delete** next to the email account you want to delete. A pop-up displays. +5. Type **DELETE** in the pop-up and click **Delete email account** to confirm the action and delete the account. diff --git a/managed-services/webhosting/how-to/manage-ftp-accounts.mdx b/managed-services/webhosting/how-to/manage-ftp-accounts.mdx new file mode 100644 index 0000000000..3952704570 --- /dev/null +++ b/managed-services/webhosting/how-to/manage-ftp-accounts.mdx @@ -0,0 +1,48 @@ +--- +meta: + title: How to manage FTP accounts + description: Discover how to manage FTP accounts for Scaleway Web Hosting plans from the console. + h1: How to manage FTP accounts + paragraph: Discover how to manage FTP accounts for Scaleway Web Hosting plans from the console. +tags: webhosting +dates: + validation: 2024-10-02 + posted: 2024-10-02 +categories: + - managed-services +--- + +FTP (File Transfer Protocol) is used to tranfer data from your computer to your Web Hosting account and vice versa. This allows you to manage the content of your website. + +You can create and manage FTP accounts directly from the Scaleway console. + + + +- A Scaleway account logged into the [console](https://console.scaleway.com) +- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization +- [Registered a domain name](/network/domains-and-dns/how-to/register-internal-domain/) at Scaleway or another registrar +- A Web Hosting plan + +## How to create an FTP account + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **FTP** tab to display information related to your FTP accounts. +4. Click **Create FTP account** to create a new one. A pop-up displays. +5. Enter the username and password for your FTP account. Then click **Create FTP account** to submit the form to create the account. + +## How to update the password of an FTP account + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **FTP** tab to display information related to your FTP accounts. +4. Click > **Change password** next to the FTP account whose password you want to change. A pop-up displays. +5. Enter the new password and click **Change password** to submit the form to update the password. + +## How to delete an FTP account + +1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. +2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. +3. Click the **FTP** tab to display information related to your FTP accounts. +4. Click > **Delete** next to the FTP account you want to delete. A pop-up displays. +5. Click **Delete FTP account** to confirm the action and delete the FTP account. diff --git a/managed-services/webhosting/quickstart.mdx b/managed-services/webhosting/quickstart.mdx index 089e71f6a8..11e5ba2ed3 100644 --- a/managed-services/webhosting/quickstart.mdx +++ b/managed-services/webhosting/quickstart.mdx @@ -7,7 +7,7 @@ content: paragraph: This page shows you how to get started with Web Hosting. tags: webhosting cpanel dates: - validation: 2024-07-03 + validation: 2024-10-02 posted: 2021-05-26 categories: - webhosting @@ -46,6 +46,10 @@ Scaleway provides Web Hosting plans with [cPanel](/managed-services/webhosting/r ## How to access the Web Hosting control panel from the Scaleway console + + You can manage your [email accounts](/managed-services/webhosting/how-to/manage-email-accounts/), [databases](/managed-services/webhosting/how-to/manage-databases/), and [FTP accounts](/managed-services/webhosting/how-to/manage-ftp-accounts/) directly from the Scaleway console. + + 1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. @@ -130,6 +134,21 @@ Scaleway's Web Hosting control panels are a multi-language solution and you can ## How to create a mailbox + + 1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. + 2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. + 3. Click the **Emails** tab to display information related to your email accounts. + 4. Click **Create email account** to create a new one. A pop-up displays. + 5. Select the domain you want to associate the email account with from the drop-down list, then enter a username and password. + + The username is the part of your email address in front of the @. + + 6. Click **Create email account** to confirm the action and create the account. + + + To access webmail for the email account, click **Access webmail** next to the email account. + + 1. Open the [Web Hosting control panel](#how-to-access-the-web-hosting-control-panel-from-the-scaleway-console) and log in using your panel user and password. The Web Hosting panel dashboard displays. 2. Click **Email accounts** in the **Email** section of the dashboard. A list of your mailboxes displays. @@ -171,6 +190,12 @@ Scaleway's Web Hosting control panels are a multi-language solution and you can You can access the webmail platform for your Web Hosting directly from your Scaleway console. + + 1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. + 2. Click or the domain name of the Web Hosting service you want to configure. The **Hosting information** page displays. + 3. Click the **Emails** tab to display information related to your email accounts. + 4. Click **Access webmail** next to the email address you want to access. The webmail interface displays in a new browser tab. + 1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. 2. Click or the domain name of the Web Hosting plan you want to configure. The **Hosting information** page displays. diff --git a/menu/navigation.json b/menu/navigation.json index 9dd909be3d..675d7d68b9 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -2732,6 +2732,18 @@ "label": "Manage a Web Hosting plan", "slug": "manage-webhosting" }, + { + "label": "Manage FTP accounts", + "slug": "manage-ftp-accounts" + }, + { + "label": "Manage databases", + "slug": "manage-databases" + }, + { + "label": "Manage email accounts", + "slug": "manage-email-accounts" + }, { "label": "Order a dedicated IP for Web Hosting", "slug": "order-dedicated-ip" From f1e7375d954a3fb88bdd52685aa60a7efb369a84 Mon Sep 17 00:00:00 2001 From: SamyOubouaziz Date: Wed, 23 Oct 2024 17:04:58 +0200 Subject: [PATCH 33/68] chore(GEN): documentation review MTA-5176 (#3870) --- .../functions/how-to/package-function-dependencies-in-zip.mdx | 2 +- serverless/messaging/api-cli/python-node-sqs.mdx | 1 + serverless/messaging/api-cli/sqs-sns-aws-cli.mdx | 1 + serverless/messaging/reference-content/limitations.mdx | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/serverless/functions/how-to/package-function-dependencies-in-zip.mdx b/serverless/functions/how-to/package-function-dependencies-in-zip.mdx index 3250c01264..cc7e88332e 100644 --- a/serverless/functions/how-to/package-function-dependencies-in-zip.mdx +++ b/serverless/functions/how-to/package-function-dependencies-in-zip.mdx @@ -7,7 +7,7 @@ content: paragraph: Package function dependencies in a ZIP file for Scaleway Serverless Functions. tags: functions zip-file dates: - validation: 2024-04-16 + validation: 2024-10-23 posted: 2021-05-26 categories: - serverless diff --git a/serverless/messaging/api-cli/python-node-sqs.mdx b/serverless/messaging/api-cli/python-node-sqs.mdx index 08dc496826..a3467542fc 100644 --- a/serverless/messaging/api-cli/python-node-sqs.mdx +++ b/serverless/messaging/api-cli/python-node-sqs.mdx @@ -11,6 +11,7 @@ categories: dates: validation: 2024-04-09 posted: 2023-01-04 +validation_frequency: 8 --- AWS provides a number of SDKs (**S**oftware **D**evelopment **K**its) which provide language-specific APIs for AWS services, including [SQS](/serverless/messaging/concepts#sqs). diff --git a/serverless/messaging/api-cli/sqs-sns-aws-cli.mdx b/serverless/messaging/api-cli/sqs-sns-aws-cli.mdx index 5c7ce1164b..3b89ef6a95 100644 --- a/serverless/messaging/api-cli/sqs-sns-aws-cli.mdx +++ b/serverless/messaging/api-cli/sqs-sns-aws-cli.mdx @@ -11,6 +11,7 @@ categories: dates: validation: 2024-04-16 posted: 2023-04-04 +validation_frequency: 8 --- The AWS-CLI is an open-source tool built on top of the AWS SDK for Python (Boto) that provides commands for interacting with AWS services. Once you have [connected Scaleway Messaging and Queuing SQS and/or SNS to the AWS-CLI](/serverless/messaging/api-cli/connect-aws-cli/), you can start creating, listing and managing your queues and topics, sending messages and much more, all from your command line. diff --git a/serverless/messaging/reference-content/limitations.mdx b/serverless/messaging/reference-content/limitations.mdx index 74d8937cb0..7faa70262d 100644 --- a/serverless/messaging/reference-content/limitations.mdx +++ b/serverless/messaging/reference-content/limitations.mdx @@ -9,6 +9,7 @@ tags: messaging limitations space size storage payload max-streams max-consumers dates: validation: 2024-04-19 posted: 2023-01-04 +validation_frequency: 8 categories: - serverless --- From 4dae4edb39f7658ac7557cb1fe539958529ecf4b Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 24 Oct 2024 10:51:20 +0200 Subject: [PATCH 34/68] feat(wbh): add tip to howto pages (#3876) * feat(wbh): add low level doc * feat(wbh): update quickstart * Apply suggestions from code review Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> * feat(wbh): add tip * fix(wbh): validation date * Update managed-services/webhosting/how-to/manage-email-accounts.mdx --------- Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> --- managed-services/webhosting/how-to/manage-databases.mdx | 8 ++++++-- .../webhosting/how-to/manage-email-accounts.mdx | 8 ++++++-- .../webhosting/how-to/manage-ftp-accounts.mdx | 8 ++++++-- managed-services/webhosting/quickstart.mdx | 2 +- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/managed-services/webhosting/how-to/manage-databases.mdx b/managed-services/webhosting/how-to/manage-databases.mdx index 94e92f57b1..e9f476f044 100644 --- a/managed-services/webhosting/how-to/manage-databases.mdx +++ b/managed-services/webhosting/how-to/manage-databases.mdx @@ -6,8 +6,8 @@ meta: paragraph: Discover how to manage databases for Scaleway Web Hosting plans from the console. tags: webhosting dates: - validation: 2024-10-02 - posted: 2024-10-02 + validation: 2024-10-24 + posted: 2024-10-24 categories: - managed-services --- @@ -22,6 +22,10 @@ You can create and manage databases for your website and applications, including - [Registered a domain name](/network/domains-and-dns/how-to/register-internal-domain/) at Scaleway or another registrar - A Web Hosting plan + + This guide focuses on managing your databases through the Scaleway console. For advanced configurations, you can access your [Web Hosting control panel (cPanel or Plesk)](/managed-services/webhosting/quickstart/#how-to-access-the-web-hosting-control-panel-from-the-scaleway-console). + + ## How to create a database 1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. diff --git a/managed-services/webhosting/how-to/manage-email-accounts.mdx b/managed-services/webhosting/how-to/manage-email-accounts.mdx index e6cb7a3e23..9a7b204c5f 100644 --- a/managed-services/webhosting/how-to/manage-email-accounts.mdx +++ b/managed-services/webhosting/how-to/manage-email-accounts.mdx @@ -6,8 +6,8 @@ meta: paragraph: Discover how to manage email accounts for Scaleway Web Hosting plans from the console. tags: webhosting dates: - validation: 2024-10-02 - posted: 2024-10-02 + validation: 2024-10-24 + posted: 2024-10-24 categories: - managed-services --- @@ -21,6 +21,10 @@ Send, receive, and store electronic messages through the internet. Email account - [Registered a domain name](/network/domains-and-dns/how-to/register-internal-domain/) at Scaleway or another registrar - A Web Hosting plan + + This guide focuses on managing your email accounts through the Scaleway console. For advanced configurations, you can access your [Web Hosting control panel (cPanel or Plesk)](/managed-services/webhosting/quickstart/#how-to-access-the-web-hosting-control-panel-from-the-scaleway-console). + + ## How to create an email account 1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. diff --git a/managed-services/webhosting/how-to/manage-ftp-accounts.mdx b/managed-services/webhosting/how-to/manage-ftp-accounts.mdx index 3952704570..6ee18d4ad0 100644 --- a/managed-services/webhosting/how-to/manage-ftp-accounts.mdx +++ b/managed-services/webhosting/how-to/manage-ftp-accounts.mdx @@ -6,8 +6,8 @@ meta: paragraph: Discover how to manage FTP accounts for Scaleway Web Hosting plans from the console. tags: webhosting dates: - validation: 2024-10-02 - posted: 2024-10-02 + validation: 2024-10-24 + posted: 2024-10-24 categories: - managed-services --- @@ -23,6 +23,10 @@ You can create and manage FTP accounts directly from the Scaleway console. - [Registered a domain name](/network/domains-and-dns/how-to/register-internal-domain/) at Scaleway or another registrar - A Web Hosting plan + + This guide focuses on managing your FTP accounts through the Scaleway console. For advanced configurations, you can access your [Web Hosting control panel (cPanel or Plesk)](/managed-services/webhosting/quickstart/#how-to-access-the-web-hosting-control-panel-from-the-scaleway-console). + + ## How to create an FTP account 1. Click **Web Hosting** in the **Managed Services** section of the [console](https://console.scaleway.com/) side menu. The **Web Hosting** overview page displays. diff --git a/managed-services/webhosting/quickstart.mdx b/managed-services/webhosting/quickstart.mdx index 11e5ba2ed3..43564f8e02 100644 --- a/managed-services/webhosting/quickstart.mdx +++ b/managed-services/webhosting/quickstart.mdx @@ -7,7 +7,7 @@ content: paragraph: This page shows you how to get started with Web Hosting. tags: webhosting cpanel dates: - validation: 2024-10-02 + validation: 2024-10-24 posted: 2021-05-26 categories: - webhosting From 75f3e609dd14ac0e69fcd12dd2296b8dc785c7e0 Mon Sep 17 00:00:00 2001 From: nerda-codes <87707325+nerda-codes@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:21:36 +0200 Subject: [PATCH 35/68] docs(cpt): mention grafana agent deprecation (#3872) --- observability/cockpit/api-cli/configuring-grafana-agent.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/observability/cockpit/api-cli/configuring-grafana-agent.mdx b/observability/cockpit/api-cli/configuring-grafana-agent.mdx index 508c1a43b0..d52d9934cb 100644 --- a/observability/cockpit/api-cli/configuring-grafana-agent.mdx +++ b/observability/cockpit/api-cli/configuring-grafana-agent.mdx @@ -15,6 +15,10 @@ categories: This page explains how to configure the Grafana agent and the Zipkin collector to push your metrics, logs, and traces. You can use it to **push your data from Scaleway resources or external resources**. + + [The Grafana agent has been deprecated by Grafana](https://grafana.com/docs/agent/latest/). Find out [how to configure Grafana Alloy](/observability/cockpit/how-to/send-metrics-with-grafana-alloy/#configuring-grafana-alloy) which is Grafana's new telemetry collector. + + - [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization From 39e9b7bb4ea970b1f301f610b93426162c2c1b9c Mon Sep 17 00:00:00 2001 From: Cyril Petel <100215794+crlptl@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:59:06 +0200 Subject: [PATCH 36/68] feat(IAM): Add undocumented permission sets (#3878) --- .../iam/reference-content/permission-sets.mdx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/identity-and-access-management/iam/reference-content/permission-sets.mdx b/identity-and-access-management/iam/reference-content/permission-sets.mdx index e602197404..885481098d 100644 --- a/identity-and-access-management/iam/reference-content/permission-sets.mdx +++ b/identity-and-access-management/iam/reference-content/permission-sets.mdx @@ -6,7 +6,7 @@ content: h1: Permission sets paragraph: Explore how to define and manage permission sets for user access control. dates: - validation: 2024-04-01 + validation: 2024-10-23 --- Permissions sets and their scope make up [IAM rules](/identity-and-access-management/iam/concepts/#rule), which define the access rights that a principal (user, group or application) should have. They consist of sets of one or multiple [permissions](/identity-and-access-management/iam/concepts/#permission). @@ -52,6 +52,7 @@ Below is a list of the permission sets available at Scaleway. | KubernetesReadOnly | List and read access to Kubernetes | | KubernetesFullAccess | Full access to create, read, list, edit and delete Kubernetes | | KubernetesExternalNodeRegister | Attach external nodes to a Kosmos cluster | +| KubernetesSystemMastersGroupAccess | Gives the Kubernetes system:masters role to perform any action on the cluster | | DediboxReadOnly | List and read access to Dedibox | | DediboxFullAccess | Full access to create, read, list, edit and delete Dedibox | | ContainersReadOnly | List and read access to Containers | @@ -80,6 +81,14 @@ Below is a list of the permission sets available at Scaleway. | PrivateNetworksFullAccess | Full access to create, read, list, edit and delete Private Networks | | VPCGatewayReadOnly | List and read access to Public Gateways | | VPCGatewayFullAccess | Full access to create, read, list, edit and delete Public Gateways | +| VPCFullAccess | Full access to VPC | +| VPCReadOnly | Read access to VPC | +| AutoscalingFullAccess | Full access to autoscaling | +| AutoscalingReadOnly | Read access to autoscaling | +| EdgeServicesFullAccess | Full access to Edge Services | +| EdgeServicesReadOnly | Read access to Edge Services | +| IPAMFullAccess | Full access to IPAM | +| IPAMReadOnly | Read access to IPAM | | LoadBalancersReadOnly | List and read access to Load Balancer | | LoadBalancersFullAccess | Full access to create, read, list, edit and delete Load Balancer | | DomainsDNSReadOnly | List and read access to Domains and DNS | @@ -96,6 +105,10 @@ Below is a list of the permission sets available at Scaleway. | TransactionalEmailDomainFullAccess | Full access to domains in Transactional Email. Does not include permissions for e-mails | | TransactionalEmailEmailReadOnly | Read access to e-mails in Transactional Email. Does not include permissions for domain configuration | | TransactionalEmailEmailFullAccess | Full access to e-mails in Transactional Email. Does not include permissions for domain configuration | +| TransactionalEmailWebhookFullAccess | Full access to Webhooks in Transactional Email | +| TransactionalEmailWebhookReadOnly | Read access to Webhooks in Transactional Email | +| TransactionalEmailProjectSettingsFullAccess | Full access to Project settings in Transactional Email | +| TransactionalEmailProjectSettingsReadOnly | Read access to Project settings in Transactional Email | | WebHostingReadOnly | List and read access to Web Hosting | | WebHostingFullAccess | Full access to create, read, list, edit and delete Web Hosting | | SecretManagerReadOnly | List and read secrets' metadata (name, tags, creation date, etc.). Does not include permissions for data (versions) accessing or editing | @@ -108,3 +121,6 @@ Below is a list of the permission sets available at Scaleway. | BlockStorageFullAccess | Full access to create, read, list, edit and delete in Block Storage | + + Some additional permission sets may appear on your Scaleway console if you are enrolled in beta testing for products or features. + From 60f5e99df7b18adefc559b79d1a25679758f1668 Mon Sep 17 00:00:00 2001 From: ldecarvalho-doc <82805470+ldecarvalho-doc@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:10:49 +0200 Subject: [PATCH 37/68] fix(rdb): reviews 21/10 (#3879) --- .../managed-inference/reference-content/wizardlm-70b-v1.0.mdx | 2 +- labs/ipfs-naming/quickstart.mdx | 2 +- .../mongodb/how-to/connect-database-instance.mdx | 2 +- .../postgresql-and-mysql/api-cli/verify-ca-postgresql.mdx | 2 +- .../postgresql-and-mysql/how-to/apply-maintenance.mdx | 4 ++-- managed-databases/redis/api-cli/using-pub-sub-feature.mdx | 2 +- managed-databases/redis/concepts.mdx | 2 +- .../redis/reference-content/default-user-permissions.mdx | 2 +- .../redis/reference-content/ensuring-data-persistence.mdx | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ai-data/managed-inference/reference-content/wizardlm-70b-v1.0.mdx b/ai-data/managed-inference/reference-content/wizardlm-70b-v1.0.mdx index b58bf15854..86f087c4de 100644 --- a/ai-data/managed-inference/reference-content/wizardlm-70b-v1.0.mdx +++ b/ai-data/managed-inference/reference-content/wizardlm-70b-v1.0.mdx @@ -16,7 +16,7 @@ categories: | Attribute | Details | |-----------------|------------------------------------| -| Provider | [WizardLM](https://wizardlm.github.io/) | +| Provider | [WizardLM](https://wizardlm.github.io/WizardLM2/) | | Compatible Instances | H100 (FP8) - H100-2 (FP16) | | Context size | 4,096 tokens | diff --git a/labs/ipfs-naming/quickstart.mdx b/labs/ipfs-naming/quickstart.mdx index f7a798fc5c..566c2c1c7a 100644 --- a/labs/ipfs-naming/quickstart.mdx +++ b/labs/ipfs-naming/quickstart.mdx @@ -7,7 +7,7 @@ content: paragraph: This page shows you how to get started with Scaleway IPFS Naming. tags: ipfs-naming ipfs naming labs web3 dates: - validation: 2024-04-15 + validation: 2024-04-23 posted: 2023-10-10 categories: - labs diff --git a/managed-databases/mongodb/how-to/connect-database-instance.mdx b/managed-databases/mongodb/how-to/connect-database-instance.mdx index c9d78d5089..c5e9d1f568 100644 --- a/managed-databases/mongodb/how-to/connect-database-instance.mdx +++ b/managed-databases/mongodb/how-to/connect-database-instance.mdx @@ -44,7 +44,7 @@ To connect to a public endpoint using the MongoDB® shell: 1. Replace the following variables in the command as described: ```sh - mongosh "mongodb+srv://{instance_id}.mgdb.{region}.scw.cloud" --tlsCAFile {your_certificate.pem} -u {username + mongosh "mongodb+srv://{instance_id}.mgdb.{region}.scw.cloud" --tlsCAFile {your_certificate.pem} -u {username} ``` - `{your-certificate.pem}` - the TLS certificate downloaded on **step 3**. diff --git a/managed-databases/postgresql-and-mysql/api-cli/verify-ca-postgresql.mdx b/managed-databases/postgresql-and-mysql/api-cli/verify-ca-postgresql.mdx index 69eadd66b7..523d516847 100644 --- a/managed-databases/postgresql-and-mysql/api-cli/verify-ca-postgresql.mdx +++ b/managed-databases/postgresql-and-mysql/api-cli/verify-ca-postgresql.mdx @@ -7,7 +7,7 @@ content: paragraph: Learn to verify the CA certificate for PostgreSQL using API/CLI. tags: verify-ca verify certificate authority postgresql dates: - validation: 2024-04-15 + validation: 2024-10-23 posted: 2023-04-01 categories: - managed-databases diff --git a/managed-databases/postgresql-and-mysql/how-to/apply-maintenance.mdx b/managed-databases/postgresql-and-mysql/how-to/apply-maintenance.mdx index a3242021b6..4d9392262b 100644 --- a/managed-databases/postgresql-and-mysql/how-to/apply-maintenance.mdx +++ b/managed-databases/postgresql-and-mysql/how-to/apply-maintenance.mdx @@ -7,14 +7,14 @@ content: paragraph: This page explains how to apply maintenance to a Database Instance tags: managed-database postgresql mysql database-instance maintenance dates: - validation: 2024-04-19 + validation: 2024-10-23 posted: 2024-04-19 categories: - managed-databases - postgresql-and-mysql --- -From time to time your Scaleway Managed Databases have to undergo maintenance to make sure that your nodes are up-to-date and have all the tools necessary to maintain a healthy lifecycle. For example, your engine version might need to be upgraded to the latest available minor version, or certain patches might need to be implemented. +From time to time your Scaleway Managed Databases have to undergo maintenance to ensure that your nodes are up-to-date and have all the tools necessary to maintain a healthy lifecycle. For example, your engine version might need to be upgraded to the latest available minor version, or certain patches might need to be implemented. These maintenance operations are set up, run, and scheduled by Scaleway, but you can select when to apply them to avoid interruptions during peak times. diff --git a/managed-databases/redis/api-cli/using-pub-sub-feature.mdx b/managed-databases/redis/api-cli/using-pub-sub-feature.mdx index 609d60af0c..7a143a3b97 100644 --- a/managed-databases/redis/api-cli/using-pub-sub-feature.mdx +++ b/managed-databases/redis/api-cli/using-pub-sub-feature.mdx @@ -7,7 +7,7 @@ content: paragraph: Guide to using the Pub/Sub feature in Redis™ with API/CLI. tags: databases redis pub/sub messaging broker dates: - validation: 2024-04-15 + validation: 2024-10-23 categories: - managed-databases - redis diff --git a/managed-databases/redis/concepts.mdx b/managed-databases/redis/concepts.mdx index b4b8b1341b..72ab23716a 100644 --- a/managed-databases/redis/concepts.mdx +++ b/managed-databases/redis/concepts.mdx @@ -7,7 +7,7 @@ content: paragraph: This page explains all the concepts related to Managed Database for Redis™. tags: endpoint redis allowed-ip cluster cluster-mode availability horizontal-scaling tcp tls vertical-scaling dates: - validation: 2024-04-15 + validation: 2024-10-23 categories: - managed-databases - redis diff --git a/managed-databases/redis/reference-content/default-user-permissions.mdx b/managed-databases/redis/reference-content/default-user-permissions.mdx index 026b15ef09..7c266c64ce 100644 --- a/managed-databases/redis/reference-content/default-user-permissions.mdx +++ b/managed-databases/redis/reference-content/default-user-permissions.mdx @@ -7,7 +7,7 @@ content: paragraph: Reference guide to default user permissions for Redis™ databases. tags: databases user redis username password dates: - validation: 2024-04-15 + validation: 2024-10-23 categories: - managed-databases - redis diff --git a/managed-databases/redis/reference-content/ensuring-data-persistence.mdx b/managed-databases/redis/reference-content/ensuring-data-persistence.mdx index 35e6d69f60..4442996020 100644 --- a/managed-databases/redis/reference-content/ensuring-data-persistence.mdx +++ b/managed-databases/redis/reference-content/ensuring-data-persistence.mdx @@ -7,7 +7,7 @@ content: paragraph: Learn how to ensure data persistence in your Scaleway Redis™ database. tags: databases user redis username password dates: - validation: 2024-04-15 + validation: 2024-10-23 categories: - managed-databases - redis From be0a7b63d080c5496720143fb0bfbb0f2681f189 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 24 Oct 2024 16:55:29 +0200 Subject: [PATCH 38/68] feat(aps): add troubleshooting apple id (#3877) * feat(aps): add troubleshooting apple id * Update bare-metal/apple-silicon/troubleshooting/cant-create-apple-account.mdx * Update bare-metal/apple-silicon/troubleshooting/cant-create-apple-account.mdx * Apply suggestions from code review Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> --------- Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> --- .../cant-create-apple-account.mdx | 50 +++++++++++++++++++ menu/navigation.json | 4 ++ .../index.mdx | 9 +--- 3 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 bare-metal/apple-silicon/troubleshooting/cant-create-apple-account.mdx diff --git a/bare-metal/apple-silicon/troubleshooting/cant-create-apple-account.mdx b/bare-metal/apple-silicon/troubleshooting/cant-create-apple-account.mdx new file mode 100644 index 0000000000..a303f3369d --- /dev/null +++ b/bare-metal/apple-silicon/troubleshooting/cant-create-apple-account.mdx @@ -0,0 +1,50 @@ +--- +meta: + title: Troubleshooting account creation for hosted Mac minis + description: This page suggests solutions for when you cannot create an Apple Account directly from your hosted Mac mini +content: + h1: Troubleshooting account creation for hosted Mac minis + paragraph: This page suggests solutions for when you cannot create an Apple Account directly from your hosted Mac mini +tags: apple-id apple account creation issues +dates: + validation: 2024-10-24 + posted: 2024-10-24 +categories: + - bare-metal +--- + +An Apple Account is required for accessing Apple services such as the App Store, iCloud, iMessage, FaceTime, and more. +It serves as a unique account used to authenticate your identity and connect you to the Apple ecosystem. + +However, you might encounter issues creating an Apple Account directly from your hosted Mac mini, especially if too many Apple Accounts have already been created on it. + +Apple has implemented [a limit on the number of Apple Accounts](https://support.apple.com/en-us/101661) that can be created from a single device. If you are unable to create an Apple Account on your Mac mini due to this restriction, you can still create one through the Apple website and then sign in on your machine. + +### Creating an Apple Account via the Apple website + +If you are unable to create an Apple Account on your hosted Mac mini, follow these steps to create one through the Apple website: + +1. Open your web browser and navigate to the Apple Account creation page: [https://account.apple.com/account](https://account.apple.com/account). +2. Click **Create Your Apple Account**. You will be redirected to a page where you can start the registration process. +3. Fill in your personal information: + - First and Last Name: Enter your full name. + - Country/Region: Select your country or region from the dropdown menu. + - Birthdate: Enter your date of birth. + - Email Address: Enter your existing email address. This will be your new Apple Account. + - Password: Create a strong and secure password for your account. + - Phone number: Enter your phone number. It will be used for two factor authentication and account recovery. + Verify your information and click **Continue** to proceed. + Apple will send a verification email to the address you provided. + 4. Open the email and follow the instructions to verify your account. +5. After verification, agree to Apple's terms and conditions to complete the process. Tick the checkbox and click on the corresponding button to agree. +6. Return to your hosted Mac mini and sign in using your new credentials, having successfully created your Apple Account. + + + The information provided above is for reference only. For detailed instructions or if you encounter any issues while creating your Apple Account, refer to [Apple's official documentation](https://support.apple.com/en-us/108647) on how to create a new Apple Account. + + +### Further troubleshooting + +- If you encounter errors while creating an Apple Account on your hosted Mac mini (e.g., "Too many Apple Accounts created on this device"), use the method described above to create your Apple Account through the website. +- If the problem persists after creating your Apple Account on the website, try signing in from a different device or contact [Apple Support](https://support.apple.com/) for further assistance. +- For more details, you can visit [Apple's Support Page](https://support.apple.com/en-us/108647) on Apple Accounts. diff --git a/menu/navigation.json b/menu/navigation.json index 675d7d68b9..a5a6ec0fe4 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -807,6 +807,10 @@ { "label": "I can not connect to my Mac mini through a remote SSH connection", "slug": "cant-connect-using-ssh" + }, + { + "label": "I can not create a new Apple Account on my Mac mini", + "slug": "cant-create-apple-account" } ], "label": "Troubleshooting", diff --git a/tutorials/install-github-actions-runner-mac/index.mdx b/tutorials/install-github-actions-runner-mac/index.mdx index 2805a32abe..2dce0c7c1d 100644 --- a/tutorials/install-github-actions-runner-mac/index.mdx +++ b/tutorials/install-github-actions-runner-mac/index.mdx @@ -9,17 +9,10 @@ tags: mac m1 github-actions ci/cd apple-silicon self-hosted-runner categories: - apple-silicon dates: - validation: 2024-07-17 + validation: 2024-10-24 posted: 2024-01-31 --- - - GitHub Actions is a powerful CI/CD platform that allows users to automate their software development workflows, connected to a GitHub organization or repository. While GitHub offers online runners with a pay-as-you-go model, self-hosted runners provide increased control and customization for your CI/CD setup. This tutorial guides you through setting up, configuring, and connecting a self-hosted runner on a Mac mini to execute macOS pipelines. From a82ffe156aef98285a9f385d6f8ecbab79fb9902 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 24 Oct 2024 16:55:43 +0200 Subject: [PATCH 39/68] fix(wbh): fix meta information (#3881) --- managed-services/webhosting/how-to/manage-databases.mdx | 1 + managed-services/webhosting/how-to/manage-email-accounts.mdx | 1 + managed-services/webhosting/how-to/manage-ftp-accounts.mdx | 1 + 3 files changed, 3 insertions(+) diff --git a/managed-services/webhosting/how-to/manage-databases.mdx b/managed-services/webhosting/how-to/manage-databases.mdx index e9f476f044..cfb3789f86 100644 --- a/managed-services/webhosting/how-to/manage-databases.mdx +++ b/managed-services/webhosting/how-to/manage-databases.mdx @@ -2,6 +2,7 @@ meta: title: How to manage databases description: Discover how to manage databases for Scaleway Web Hosting plans from the console. +content: h1: How to manage databases paragraph: Discover how to manage databases for Scaleway Web Hosting plans from the console. tags: webhosting diff --git a/managed-services/webhosting/how-to/manage-email-accounts.mdx b/managed-services/webhosting/how-to/manage-email-accounts.mdx index 9a7b204c5f..81885c84f9 100644 --- a/managed-services/webhosting/how-to/manage-email-accounts.mdx +++ b/managed-services/webhosting/how-to/manage-email-accounts.mdx @@ -2,6 +2,7 @@ meta: title: How to manage email accounts description: Discover how to manage email accounts for Scaleway Web Hosting plans from the console. +content: h1: How to manage email accounts paragraph: Discover how to manage email accounts for Scaleway Web Hosting plans from the console. tags: webhosting diff --git a/managed-services/webhosting/how-to/manage-ftp-accounts.mdx b/managed-services/webhosting/how-to/manage-ftp-accounts.mdx index 6ee18d4ad0..36c789ef8f 100644 --- a/managed-services/webhosting/how-to/manage-ftp-accounts.mdx +++ b/managed-services/webhosting/how-to/manage-ftp-accounts.mdx @@ -2,6 +2,7 @@ meta: title: How to manage FTP accounts description: Discover how to manage FTP accounts for Scaleway Web Hosting plans from the console. +content: h1: How to manage FTP accounts paragraph: Discover how to manage FTP accounts for Scaleway Web Hosting plans from the console. tags: webhosting From b1834d294ed58209f174dd1dfb0212c0f417a70d Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 24 Oct 2024 16:56:32 +0200 Subject: [PATCH 40/68] feat(wbh): add php version overview (#3883) * feat(wbh): add php version overview * fix(wbh): update dates * fix(wbh): fix php version availability --- .../php-version-overview.mdx | 40 +++++++++++++++++++ menu/navigation.json | 4 ++ 2 files changed, 44 insertions(+) create mode 100644 managed-services/webhosting/reference-content/php-version-overview.mdx diff --git a/managed-services/webhosting/reference-content/php-version-overview.mdx b/managed-services/webhosting/reference-content/php-version-overview.mdx new file mode 100644 index 0000000000..c9e4ccb171 --- /dev/null +++ b/managed-services/webhosting/reference-content/php-version-overview.mdx @@ -0,0 +1,40 @@ +--- +meta: + title: PHP versions on Scaleway Web Hosting platforms + description: This page provides useful information about supported PHP versions across the different Web Hosting infrastructures. +content: + h1: PHP versions on Scaleway Web Hosting platforms + paragraph: This page provides useful information about supported PHP versions across the different Web Hosting infrastructures. +tags: webhosting php version +dates: + validation: 2024-10-24 + posted: 2024-20-24 +categories: + - webhosting +--- + + +Scaleway Web Hosting is based on different infrastructures, each with varying support for PHP versions. +Below you find an overview of the available PHP versions for the existing infrastructures: [Dedibox Classic](/dedibox-console/classic-hosting/), [Dedibox cPanel](/dedibox-console/cpanel-hosting/), and [Scaleway Web Hosting](/managed-services/webhosting/) (cPanel and Plesk). + +| PHP Version | Dedibox Classic | Dedibox cPanel | Scaleway cPanel | Scaleway Plesk | +|-----------------|--------------------|-------------------|---------------------|--------------------| +| PHP 4.4 | ✔️ | ✔️ | ❌ | ❌ | +| PHP 5.2 | ✔️ | ✔️ | ❌ | ❌ | +| PHP 5.4 | ✔️ | ✔️ | ❌ | ❌ | +| PHP 5.5 | ✔️ | ✔️ | ❌ | ❌ | +| PHP 5.6 | ✔️ | ✔️ | ❌ | ❌ | +| PHP 7.0 | ✔️ | ✔️ | ❌ | ❌ | +| PHP 7.1 | ✔️ | ✔️ | ❌ | ❌ | +| PHP 7.2 | ✔️ | ✔️ | ❌ | ❌ | +| PHP 7.3 | ✔️ | ✔️ | ❌ | ❌ | +| PHP 7.4 | ❌ | ✔️ | ✔️ | ❌ | +| PHP 8.0 | ❌ | ✔️ | ✔️ | ❌ | +| PHP 8.1 | ❌ | ✔️ | ✔️ | ✔️ | +| PHP 8.2 | ❌ | ❌ | ✔️ | ✔️ | +| PHP 8.3 | ❌ | ❌ | ✔️ | ✔️ | + +**Key:** +- ✔️ = PHP version is supported +- ❌ = PHP version is not supported + diff --git a/menu/navigation.json b/menu/navigation.json index a5a6ec0fe4..7471ad4cbd 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -2788,6 +2788,10 @@ "label": "Plesk additional content", "slug": "plesk-reference-content" }, + { + "label": "PHP versions on Scaleway Web Hosting platforms", + "slug": "php-version-overview" + }, { "label": "Web Hosting Classic migration - Technical information", "slug": "classic-hosting-migration-information" From e7dcafa9632b7fd14a76ea361fa949db5665309e Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 24 Oct 2024 17:01:10 +0200 Subject: [PATCH 41/68] feat(k8s): add modifying kernel documentation (#3882) * feat(k8s): add modifying kernel documentation * docs(k8s): add docs * Update containers/kubernetes/reference-content/modifying-kernel-parameters-kubernetes-cluster.mdx Co-authored-by: ldecarvalho-doc <82805470+ldecarvalho-doc@users.noreply.github.com> --------- Co-authored-by: ldecarvalho-doc <82805470+ldecarvalho-doc@users.noreply.github.com> --- ...g-kernel-parameters-kubernetes-cluster.mdx | 123 ++++++++++++++++++ menu/navigation.json | 4 + 2 files changed, 127 insertions(+) create mode 100644 containers/kubernetes/reference-content/modifying-kernel-parameters-kubernetes-cluster.mdx diff --git a/containers/kubernetes/reference-content/modifying-kernel-parameters-kubernetes-cluster.mdx b/containers/kubernetes/reference-content/modifying-kernel-parameters-kubernetes-cluster.mdx new file mode 100644 index 0000000000..82832bb82e --- /dev/null +++ b/containers/kubernetes/reference-content/modifying-kernel-parameters-kubernetes-cluster.mdx @@ -0,0 +1,123 @@ +--- +meta: + title: Modifying kernel parameters in a Kubernetes cluster using a DaemonSet + description: This guide explains how to modify kernel parameters in a Kubernetes cluster using a DaemonSet +content: + h1: Modifying kernel parameters in a Kubernetes cluster using a DaemonSet + paragraph: This guide explains how to modify kernel parameters in a Kubernetes cluster using a DaemonSet +tags: kubernetes kernel +dates: + validation: 2024-10-24 + posted: 2024-10-24 +categories: + - kubernetes +--- + +Kernel parameters control the behavior of the operating system at runtime. They allow you to configure and fine-tune various aspects of the Linux kernel, such as networking, memory management, process handling, and security. These parameters are located in the `/proc/sys` directory on each node and can be dynamically modified at runtime using the `sysctl` command. + +This guide outlines how to modify kernel parameters across all nodes in a Kubernetes cluster using a DaemonSet. + +## Identifying the kernel parameters to modify + +Kernel parameters, managed via the `sysctl` command, are grouped into different categories depending on which part of the kernel they influence: + +- **Networking (`net.*`)**: Controls network-related settings such as buffer sizes, TCP/IP settings, and routing. + *Example*: `net.ipv4.ip_forward` enables or disables IP packet forwarding, often used in routing scenarios. + +- **Memory Management (`vm.*`)**: Manages memory and swap behaviors. + *Example*: `vm.swappiness` controls how aggressively the system swaps memory pages to disk. + +- **File System (`fs.*`)**: Configures file system-related limits and behaviors. + *Example*: `fs.file-max` sets the maximum number of file descriptors the system can allocate. + +- **General Kernel Settings (`kernel.*`)**: Configures overall kernel behaviors. + *Example*: `kernel.hostname` defines the system’s hostname. + +- **Security (`kernel.random.*`, `net.ipv4.conf.*`, etc.)**: Manages security settings such as IP forwarding, source address validation, and firewall rules. + *Example*: `net.ipv4.conf.all.rp_filter` enables reverse path filtering for added network security. + +- **Process Limits (`kernel.*`)**: Controls limits for processes, such as the maximum number of processes or threads. + *Example*: `kernel.pid_max` sets the maximum number of process IDs (PIDs) the system can allocate. + +## Creating a DaemonSet to modify kernel parameters + +To apply kernel parameter changes across all nodes in the cluster, you can create a Kubernetes DaemonSet that runs privileged pods. This will ensure the changes are applied to every node. + +Create a YAML file (e.g., `sysctl-daemonset.yaml`), copy/paste the following content into the file, save it and exit the text editor: + +```yaml +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: sysctl-tuning + namespace: kube-system + labels: + app: sysctl-tuning +spec: + selector: + matchLabels: + app: sysctl-tuning + template: + metadata: + labels: + app: sysctl-tuning + spec: + hostNetwork: true # Share the host's network namespace for network-related sysctl changes + hostPID: true # Access the host's PID namespace for sysctl commands + initContainers: + - name: sysctl-init # Init container to set sysctl parameters + image: busybox:latest + command: + - /bin/sh + - -c + - | + sysctl -w net.core.rmem_max=7500000 # Set the maximum receive buffer size + sysctl -w net.core.wmem_max=7500000 # Set the maximum send buffer size + securityContext: + privileged: true # Privileged access to modify sysctl settings on the host + containers: + - name: sleep-container # Main container to keep the pod running + image: busybox:latest + command: + - /bin/sh + - -c + - sleep infinity # Keep the pod alive indefinitely +``` + +## Applying the DaemonSet + +To apply the configuration, use the following command: + +```bash +kubectl apply -f sysctl-daemonset.yaml +``` + +This command deploys the DaemonSet, which ensures that the kernel parameters are modified on all nodes. + +## Verifying changes + +To verify that the DaemonSet is running on all nodes, use the following command: + +```bash +kubectl get daemonset -n kube-system +``` + +To check if the kernel parameters were successfully updated on a node, SSH into the node and run: + +```bash +ssh +sysctl net.core.rmem_max +sysctl net.core.wmem_max +``` + + + On Scaleway Kapsule SSH access is blocked by default. You need to enable SSH in your security group before connecting to the node. Refer to [How to enable or disable SSH ports on Kubernetes Kapsule cluster nodes](/containers/kubernetes/how-to/enable-disable-ssh/) for further information. + + +## Cleaning up (Optional) + +If the DaemonSet is no longer needed after the kernel parameters have been modified, you can delete it with the following command: + +```bash +kubectl delete -f sysctl-daemonset.yaml +``` diff --git a/menu/navigation.json b/menu/navigation.json index 7471ad4cbd..a5a6fb6625 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -1712,6 +1712,10 @@ "label": "Exposing Kubernetes services to the internet", "slug": "exposing-services" }, + { + "label": "Modifying kernel parameters in a Kubernetes cluster using a DaemonSet", + "slug": "modifying-kernel-parameters-kubernetes-cluster" + }, { "label": "Moving Kubernetes nodes to routed IPs", "slug": "move-kubernetes-nodes-routed-ip" From 71c17966fcf5b21cf0d91ab0800d04ffb305dd4a Mon Sep 17 00:00:00 2001 From: nerda-codes <87707325+nerda-codes@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:26:10 +0200 Subject: [PATCH 42/68] docs(cpt): add tags and category (#3880) --- tutorials/monitor-gpu-instance-cockpit/index.mdx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tutorials/monitor-gpu-instance-cockpit/index.mdx b/tutorials/monitor-gpu-instance-cockpit/index.mdx index d43ea26f12..7ccde487ad 100644 --- a/tutorials/monitor-gpu-instance-cockpit/index.mdx +++ b/tutorials/monitor-gpu-instance-cockpit/index.mdx @@ -5,6 +5,9 @@ meta: content: h1: Monitor GPU Instances using Cockpit and the NVIDIA Data Center GPU Manager (DCGM) Exporter paragraph: This page explains how to visualize metrics and logs from GPU Instances using Cockpit and the NVIDIA Data Center GPU Manager (DCGM) Exporter +tags: cockpit monitor grafana-alloy monitoring nvidia gpu-instance +categories: + - cockpit dates: validation: 2024-10-21 posted: 2024-10-21 @@ -211,4 +214,4 @@ If you encounter any issues, make sure that you meet all the requirements listed You can run `docker -v` in your terminal to check your docker version. You should see an output similar to the following: ``` Docker version 24.0.6, build ed223bc820 - ``` \ No newline at end of file + ``` From 1bcafafa03e22a7d7dab245f098c3f75249139fe Mon Sep 17 00:00:00 2001 From: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:26:37 +0200 Subject: [PATCH 43/68] fix(edge): correct error troubleshooting (#3884) --- network/edge-services/reference-content/ssl-tls-certificate.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/edge-services/reference-content/ssl-tls-certificate.mdx b/network/edge-services/reference-content/ssl-tls-certificate.mdx index d5de0e82f7..217c7d83c1 100644 --- a/network/edge-services/reference-content/ssl-tls-certificate.mdx +++ b/network/edge-services/reference-content/ssl-tls-certificate.mdx @@ -65,7 +65,7 @@ If there is a problem generating your managed Let's Encrypt certificate, an erro | Error | Solution | | ------------------------------------------------------------------------|---------------------------------------------------------------------| | Too many certificates already issued for this domain | Wait, before retrying. This error occurs when you hit the limit of generating 50 Let's Encrypt certificates in a rolling 7 day period for the same domain. | -| Internal managed certificate error | [Open a support ticket](https://console.scaleway.com/support/tickets/create). There has been an unspecified error in generating a managed Let's Encrypt certificate for your subdomain. | +| Internal managed certificate error | There has been an unspecified error in generating a managed Let's Encrypt certificate for your subdomain. Try [resetting your domain to the default endpoint](/network/edge-services/how-to/configure-custom-domain/#how-to-reset-your-customized-domain), and then recustomizing it again, to trigger generation of a new Let's Encrypt certificate. If that fails, [open a support ticket](https://console.scaleway.com/support/tickets/create). | | Certificate cannot be renewed - Your CNAME record is no longer accurate | Your CNAME record has either been deleted or modified. Without a correct CNAME record, we cannot renew your managed Let's Encrypt certificate. [Rectify your CNAME record](/network/edge-services/reference-content/cname-record/#how-to-create-a-cname-record), and when Edge Services detects the correct record exists, your certificate will be automatically renewed. | ## Using your own certificate From 4a6171ea66873ee88dff4ed68d4d9fe94f4812a1 Mon Sep 17 00:00:00 2001 From: fpagny Date: Fri, 25 Oct 2024 10:43:38 +0200 Subject: [PATCH 44/68] Update index.mdx (#3885) --- observability/cockpit/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observability/cockpit/index.mdx b/observability/cockpit/index.mdx index 709fc715e4..66d41d635a 100644 --- a/observability/cockpit/index.mdx +++ b/observability/cockpit/index.mdx @@ -73,7 +73,7 @@ meta: productLogo="cli" title="Cockpit API" description="Manage Cockpit using the Scaleway API." - url="https://www.scaleway.com/en/developers/api/cockpit/" + url="https://www.scaleway.com/en/developers/api/cockpit/regional-api/" label="Go to Cockpit API" /> From 1a885bc285d51fb138c90d13f1382d471b143a95 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Fri, 25 Oct 2024 14:08:39 +0200 Subject: [PATCH 45/68] fix(wbh): fix date from future (#3887) --- .../webhosting/reference-content/php-version-overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/managed-services/webhosting/reference-content/php-version-overview.mdx b/managed-services/webhosting/reference-content/php-version-overview.mdx index c9e4ccb171..7a90107b3d 100644 --- a/managed-services/webhosting/reference-content/php-version-overview.mdx +++ b/managed-services/webhosting/reference-content/php-version-overview.mdx @@ -8,7 +8,7 @@ content: tags: webhosting php version dates: validation: 2024-10-24 - posted: 2024-20-24 + posted: 2024-10-24 categories: - webhosting --- From 4cdfb318cc798c40631661849e02341f26486f6c Mon Sep 17 00:00:00 2001 From: fpagny Date: Fri, 25 Oct 2024 15:58:53 +0200 Subject: [PATCH 46/68] Update index.mdx (#3888) --- observability/cockpit/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observability/cockpit/index.mdx b/observability/cockpit/index.mdx index 66d41d635a..c9d673b66b 100644 --- a/observability/cockpit/index.mdx +++ b/observability/cockpit/index.mdx @@ -63,7 +63,7 @@ meta: /> From f6f3c6600415fe949ce4570b9e429ec477f84ff7 Mon Sep 17 00:00:00 2001 From: Thibault Genaitay Date: Fri, 25 Oct 2024 17:28:30 +0200 Subject: [PATCH 47/68] feat(ai): bring support for function calling via tools and tools_choice params (#3886) * feat(genapi): defined function calling * feat(genapi): new params and more links * feat(ai): extended support in managed inference * feat(ai): added concept * feat(genapi): parallel function call * feat(ai): better intro and image * feat(ai): added concept * feat(ifr): added reference page * Apply suggestions from code review * fix(ai): added menu items * fix(ai): fix warning box * Apply suggestions from code review Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> * Update tutorials/building-ai-application-function-calling/index.mdx * Update ai-data/generative-apis/how-to/use-function-calling.mdx Co-authored-by: Guillaume Calmettes * Update tutorials/building-ai-application-function-calling/index.mdx Co-authored-by: Guillaume Calmettes --------- Co-authored-by: Benedikt Rollik Co-authored-by: Benedikt Rollik Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Co-authored-by: Guillaume Calmettes --- .../api-cli/using-chat-api.mdx | 14 +- ai-data/generative-apis/concepts.mdx | 4 + .../how-to/use-function-calling.mdx | 331 ++++++++++++++++++ .../how-to/use-structured-outputs.mdx | 2 +- ai-data/managed-inference/concepts.mdx | 4 + .../function-calling-support.mdx | 49 +++ .../openai-compatibility.mdx | 6 +- menu/navigation.json | 8 + .../assets/function-calling.webp | Bin 0 -> 192940 bytes .../index.mdx | 272 ++++++++++++++ 10 files changed, 680 insertions(+), 10 deletions(-) create mode 100644 ai-data/generative-apis/how-to/use-function-calling.mdx create mode 100644 ai-data/managed-inference/reference-content/function-calling-support.mdx create mode 100644 tutorials/building-ai-application-function-calling/assets/function-calling.webp create mode 100644 tutorials/building-ai-application-function-calling/index.mdx diff --git a/ai-data/generative-apis/api-cli/using-chat-api.mdx b/ai-data/generative-apis/api-cli/using-chat-api.mdx index 2a2b55e64a..b1a1236731 100644 --- a/ai-data/generative-apis/api-cli/using-chat-api.mdx +++ b/ai-data/generative-apis/api-cli/using-chat-api.mdx @@ -68,23 +68,25 @@ Our chat API is OpenAI compatible. Use OpenAI’s [API reference](https://platfo - max_tokens - stream - presence_penalty -- response_format +- [response_format](/ai-data/generative-apis/how-to/use-structured-outputs) - logprobs - stop - seed +- [tools](/ai-data/generative-apis/how-to/use-function-calling) +- [tool_choice](/ai-data/generative-apis/how-to/use-function-calling) ### Unsupported parameters - frequency_penalty - n - top_logprobs -- tools -- tool_choice - logit_bias - user If you have a use case requiring one of these unsupported parameters, please [contact us via Slack](https://slack.scaleway.com/) on #ai channel. - - Go further with [Python code examples](/ai-data/generative-apis/how-to/query-text-models/#querying-text-models-via-api) to query text models using Scaleway's Chat API. - \ No newline at end of file +## Going further + +1. [Python code examples](/ai-data/generative-apis/how-to/query-text-models/#querying-text-models-via-api) to query text models using Scaleway's Chat API. +2. [How to use structured outputs](/ai-data/generative-apis/how-to/use-structured-outputs) with the `response_format` parameter +3. [How to use function calling](/ai-data/generative-apis/how-to/use-function-calling) with `tools` and `tool_choice` \ No newline at end of file diff --git a/ai-data/generative-apis/concepts.mdx b/ai-data/generative-apis/concepts.mdx index 271e06a440..8b2e247f41 100644 --- a/ai-data/generative-apis/concepts.mdx +++ b/ai-data/generative-apis/concepts.mdx @@ -20,6 +20,10 @@ API rate limits define the maximum number of requests a user can make to the Gen A context window is the maximum amount of prompt data considered by the model to generate a response. Using models with high context length, you can provide more information to generate relevant responses. The context is measured in tokens. +## Function calling + +Function calling allows a large language model (LLM) to interact with external tools or APIs, executing specific tasks based on user requests. The LLM identifies the appropriate function, extracts the required parameters, and returns the results as structured data, typically in JSON format. + ## Embeddings Embeddings are numerical representations of text data that capture semantic information in a dense vector format. In Generative APIs, embeddings are essential for tasks such as similarity matching, clustering, and serving as inputs for downstream models. These vectors enable the model to understand and generate text based on the underlying meaning rather than just the surface-level words. diff --git a/ai-data/generative-apis/how-to/use-function-calling.mdx b/ai-data/generative-apis/how-to/use-function-calling.mdx new file mode 100644 index 0000000000..7c817d3126 --- /dev/null +++ b/ai-data/generative-apis/how-to/use-function-calling.mdx @@ -0,0 +1,331 @@ +--- +meta: + title: How to use function calling + description: Learn how to implement function calling capabilities using Scaleway's Chat Completions API service. +content: + h1: How to use function calling + paragraph: Learn how to enhance AI interactions by integrating external tools and functions using Scaleway's Chat Completions API service. +tags: chat-completions-api +dates: + validation: 2024-09-24 + posted: 2024-09-24 +--- + +Scaleway's Chat Completions API supports function calling as introduced by OpenAI. + +## What is function calling? + +Function calling allows a large language model (LLM) to interact with external tools or APIs, executing specific tasks based on user requests. The LLM identifies the appropriate function, extracts the required parameters, and returns the tool call to be done as structured data, typically in JSON format. While errors can occur, custom parsers or tools like LlamaIndex and LangChain can help ensure valid results. + + + +- Access to Generative APIs. +- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization +- A valid [API key](/identity-and-access-management/iam/how-to/create-api-keys/) for API authentication +- Python 3.7+ installed on your system + +## Supported models + +* llama-3.1-8b-instruct +* llama-3.1-70b-instruct +* mistral-nemo-instruct-2407 + +## Understanding function calling + +Function calling consists of three main components: +- **Tool definitions**: JSON schemas that describe available functions and their parameters +- **Tool selection**: Automatic or manual selection of appropriate functions based on user queries +- **Tool execution**: Processing function calls and handling their responses + +The workflow typically follows these steps: +1. Define available tools using JSON schema +2. Send system and user query along with tool definitions +3. Process model's function selection +4. Execute selected functions +5. Return results to model for final response + +## Code examples + + + Before diving into the code examples, ensure you have the necessary libraries installed: + ```bash + pip install openai + ``` + + +We will demonstrate function calling using a flight scheduling system that allows users to check available flights between European airports. + +### Basic function definition + +First, let's define our flight schedule function and its schema: + +```python +from openai import OpenAI +import json + +def get_flight_schedule(departure_airport: str, destination_airport: str, departure_date: str) -> dict: + """ + Retrieves flight schedules between two European airports on a specific date. + """ + # Mock flight schedule data + flights = { + "CDG-LHR-2024-11-01": [ + {"flight_number": "AF123", "airline": "Air France", "departure_time": "08:00", "arrival_time": "09:00"}, + {"flight_number": "BA456", "airline": "British Airways", "departure_time": "10:00", "arrival_time": "11:00"}, + {"flight_number": "LH789", "airline": "Lufthansa", "departure_time": "14:00", "arrival_time": "15:00"} + ], + "AMS-MUC-2024-11-01": [ + {"flight_number": "KL101", "airline": "KLM", "departure_time": "07:30", "arrival_time": "09:00"}, + {"flight_number": "LH202", "airline": "Lufthansa", "departure_time": "12:00", "arrival_time": "13:30"} + ] + } + + key = f"{departure_airport}-{destination_airport}-{departure_date}" + return flights.get(key, {"error": "No flights found for this route and date."}) + +# Define the tool specification +tools = [{ + "type": "function", + "function": { + "name": "get_flight_schedule", + "description": "Get available flights between two European airports on a specific date", + "parameters": { + "type": "object", + "properties": { + "departure_airport": { + "type": "string", + "description": "The IATA code of the departure airport (e.g., CDG, LHR)" + }, + "destination_airport": { + "type": "string", + "description": "The IATA code of the destination airport" + }, + "departure_date": { + "type": "string", + "description": "The date of departure in YYYY-MM-DD format" + } + }, + "required": ["departure_airport", "destination_airport", "departure_date"] + } + } +}] +``` + +### Simple function call example + +Here is how to implement a basic function call: + +```python +# Initialize the OpenAI client +client = OpenAI( + base_url="https://api.scaleway.ai/v1", + api_key="" +) + +# Create a simple query +messages = [ + { + "role": "system", + "content": "You are a helpful flight assistant." + }, + { + "role": "user", + "content": "What flights are available from CDG to LHR on November 1st, 2024?" + } +] + +# Make the API call +response = client.chat.completions.create( + model="llama-3.1-70b-instruct", + messages=messages, + tools=tools, + tool_choice="auto" +) +``` + + + The model automatically decides which functions to call. However, you can specify a particular function by using the `tool_choice` parameter. In the example above, you can replace `tool_choice=auto` with `tool_choice={"type": "function", "function": {"name": "get_flight_schedule"}}` to explicitly call the desired function. + + +### Multi-turn conversation handling + +For more complex interactions, you will need to handle multiple turns of conversation: + +```python +# Process the tool call +if response.choices[0].message.tool_calls: + tool_call = response.choices[0].message.tool_calls[0] + + # Execute the function + if tool_call.function.name == "get_flight_schedule": + function_args = json.loads(tool_call.function.arguments) + function_response = get_flight_schedule(**function_args) + + # Add results to the conversation + messages.extend([ + { + "role": "assistant", + "content": None, + "tool_calls": [tool_call] + }, + { + "role": "tool", + "name": tool_call.function.name, + "content": json.dumps(function_response), + "tool_call_id": tool_call.id + } + ]) + + # Get final response + final_response = client.chat.completions.create( + model="llama-3.1-70b-instruct", + messages=messages + ) + print(final_response.choices[0].message.content) +``` + +### Parallel function calling + + + Meta models do not support parallel tool calls. + + +In addition to one function call described above, you can also call multiple functions in a single turn. +This section shows an example for how you can use parallel function calling. + +Define the tools: + +``` +def open_floor_space(floor_number: int) -> bool: + """Opens up the specified floor for party space by unlocking doors and moving furniture.""" + print(f"Floor {floor_number} is now open party space!") + return True + +def set_lobby_vibe(party_mode: bool) -> str: + """Switches lobby screens and lighting to party mode.""" + status = "party mode activated!" if party_mode else "back to business mode" + print(f"Lobby is now in {status}") + return "The lobby is ready to party!" + +def prep_snack_station(activate: bool) -> bool: + """Converts the cafeteria into a snack and drink station.""" + print(f"Snack station is {'open and stocked!' if activate else 'closed.'}") + return True +``` + +Define the specifications: + +``` +tools = [ + { + "type": "function", + "function": { + "name": "open_floor_space", + "description": "Opens up an entire floor for the party", + "parameters": { + "type": "object", + "properties": { + "floor_number": { + "type": "integer", + "description": "Which floor to open up" + } + }, + "required": ["floor_number"] + } + } + }, + { + "type": "function", + "function": { + "name": "set_lobby_vibe", + "description": "Transform lobby atmosphere into party mode", + "parameters": { + "type": "object", + "properties": { + "party_mode": { + "type": "boolean", + "description": "True for party, False for business" + } + }, + "required": ["party_mode"] + } + } + }, + { + "type": "function", + "function": { + "name": "prep_snack_station", + "description": "Set up the snack and drink station", + "parameters": { + "type": "object", + "properties": { + "activate": { + "type": "boolean", + "description": "True to open, False to close" + } + }, + "required": ["activate"] + } + } + } +] +``` + +Next, call the model with proper instructions + +``` +system_prompt = """ +You are an office party control assistant. When asked to transform the office into a party space, you should: +1. Open up a floor for the party +2. Transform the lobby into party mode +3. Set up the snack station +Make all these changes at once for an instant office party! +""" + +messages = [ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": "Turn this office building into a party!"} +] +``` + +## Best practices + +When implementing function calling, follow these guidelines for optimal results: + +1. **Function design** + - Keep function names clear and descriptive + - Limit the number of functions to 7 or fewer per conversation + - Use detailed parameter descriptions in your JSON schema + +2. **Parameter handling** + - Always specify required parameters + - Use appropriate data types and validation + - Include example values in parameter descriptions + +3. **Error handling** + - Implement robust error handling for function execution + - Return clear error messages that the model can interpret + - Handle edge cases gracefully + +4. **Performance optimization** + - Set appropriate temperature values (lower for more precise function calls) + - Cache frequently accessed data when possible + - Minimize the number of turns in multi-turn conversations + + + For production applications, always implement proper error handling and input validation. The examples above focus on the happy path for clarity. + + +## Further resources + +For more information about function calling and advanced implementations, refer to these resources: + +- [OpenAI Function Calling Guide](https://platform.openai.com/docs/guides/function-calling) +- [JSON Schema Specification](https://json-schema.org/specification) +- [Chat Completions API Reference](/ai-data/generative-apis/api-cli/using-chat-api/) + +Function calling significantly extends the capabilities of language models by allowing them to interact with external tools and APIs. + + + We can't wait to see what you will build with function calls. Tell us what you are up to, share your experiments on Scaleway's [Slack community](https://slack.scaleway.com/) #ai + \ No newline at end of file diff --git a/ai-data/generative-apis/how-to/use-structured-outputs.mdx b/ai-data/generative-apis/how-to/use-structured-outputs.mdx index f2c7b93632..35bb63f8a9 100644 --- a/ai-data/generative-apis/how-to/use-structured-outputs.mdx +++ b/ai-data/generative-apis/how-to/use-structured-outputs.mdx @@ -5,7 +5,7 @@ meta: content: h1: How to use structured outputs paragraph: Learn how to interact with powerful text models using Scaleway's Chat Completions API service. -tags: chat-completitions-api +tags: chat-completions-api dates: validation: 2024-09-17 posted: 2024-09-17 diff --git a/ai-data/managed-inference/concepts.mdx b/ai-data/managed-inference/concepts.mdx index 4745322f9c..5b84c499c3 100644 --- a/ai-data/managed-inference/concepts.mdx +++ b/ai-data/managed-inference/concepts.mdx @@ -42,6 +42,10 @@ Fine-tuning involves further training a pre-trained language model on domain-spe Few-shot prompting uses the power of language models to generate responses with minimal input, relying on just a handful of examples or prompts. It demonstrates the model's ability to generalize from limited training data to produce coherent and contextually relevant outputs. +## Function calling + +Function calling allows a large language model (LLM) to interact with external tools or APIs, executing specific tasks based on user requests. The LLM identifies the appropriate function, extracts the required parameters, and returns the results as structured data, typically in JSON format. + ## Hallucinations Hallucinations in LLMs refer to instances where generative AI models generate responses that, while grammatically coherent, contain inaccuracies or nonsensical information. These inaccuracies are termed "hallucinations" because the models create false or misleading content. Hallucinations can occur because of constraints in the training data, biases embedded within the models, or the complex nature of language itself. diff --git a/ai-data/managed-inference/reference-content/function-calling-support.mdx b/ai-data/managed-inference/reference-content/function-calling-support.mdx new file mode 100644 index 0000000000..19351f3ddb --- /dev/null +++ b/ai-data/managed-inference/reference-content/function-calling-support.mdx @@ -0,0 +1,49 @@ +--- +meta: + title: Support for function calling in Scaleway Managed Inference + description: Function calling allows models to connect to external tools. +content: + h1: Support for function calling in Scaleway Managed Inference + paragraph: Function calling allows models to connect to external tools. +tags: +categories: + - ai-data +--- + +## What is function calling? + +Function calling allows a large language model (LLM) to interact with external tools or APIs, executing specific tasks based on user requests. The LLM identifies the appropriate function, extracts the required parameters, and returns the results as structured data, typically in JSON format. While errors can occur, custom parsers or tools like LlamaIndex and LangChain can help ensure valid results. + +## How to implement function calling in Scaleway Managed Inference? + +[This tutorial](/tutorials/building-ai-application-function-calling/) will guide you through the steps of creating a simple flight schedule assistant that can understand natural language queries about flights and return structured information. + +## What are models with function calling capabilities? + +The following models in Scaleway's Managed Inference library can call tools as per the OpenAI method: + +* meta/llama-3.1-8b-instruct +* meta/llama-3.1-70b-instruct +* mistral/mistral-7b-instruct-v0.3 +* mistral/mistral-nemo-instruct-2407 + +## Understanding function calling + +Function calling consists of three main components: +- **Tool definitions**: JSON schemas that describe available functions and their parameters +- **Tool selection**: Automatic or manual selection of appropriate functions based on user queries +- **Tool execution**: Processing function calls and handling their responses + +The workflow typically follows these steps: +1. Define available tools using JSON schema +2. Send system and user query along with tool definitions +3. Process model's function selection +4. Execute selected functions +5. Return results to model for final response + +## Further resources + +For more information about function calling and advanced implementations, refer to these resources: + +- [OpenAI Function Calling Guide](https://platform.openai.com/docs/guides/function-calling) +- [JSON Schema Specification](https://json-schema.org/specification) diff --git a/ai-data/managed-inference/reference-content/openai-compatibility.mdx b/ai-data/managed-inference/reference-content/openai-compatibility.mdx index cadd000eb4..ff98d0a9de 100644 --- a/ai-data/managed-inference/reference-content/openai-compatibility.mdx +++ b/ai-data/managed-inference/reference-content/openai-compatibility.mdx @@ -48,7 +48,7 @@ chat_completion = client.chat.completions.create( "content": "Sing me a song about Scaleway" } ], - model='' #e.g 'llama-3-8b-instruct' + model='' #e.g 'meta/llama-3.1-8b-instruct:fp8' ) print(chat_completion.choices[0].message.content) @@ -71,6 +71,8 @@ print(chat_completion.choices[0].message.content) - `stop` - `seed` - `stream` +- `tools` +- `tool_choice` ### Unsupported parameters @@ -79,8 +81,6 @@ Currently, the following options are not supported: - `frequency_penalty` - `n` - `top_logprobs` -- `tools` -- `tool_choice` - `logit_bias` - `user` diff --git a/menu/navigation.json b/menu/navigation.json index a5a6fb6625..86d74e66f8 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -591,6 +591,10 @@ "label": "OpenAI API compatibility", "slug": "openai-compatibility" }, + { + "label": "Support for function calling", + "slug": "function-calling-support" + }, { "label": "Llama-3-8b-instruct model", "slug": "llama-3-8b-instruct" @@ -666,6 +670,10 @@ { "label": "Use structured outputs", "slug": "use-structured-outputs" + }, + { + "label": "Use function calling", + "slug": "use-function-calling" } ], "label": "How to", diff --git a/tutorials/building-ai-application-function-calling/assets/function-calling.webp b/tutorials/building-ai-application-function-calling/assets/function-calling.webp new file mode 100644 index 0000000000000000000000000000000000000000..befbc5094d749b251cdb4d6ef7f26a4d506d59a4 GIT binary patch literal 192940 zcmYIu19T-#(CCeA-PpEm+sTF-+qP|OY&+T58*Oak#n_~@1rCx{7p2BXN~);L`!gePv!aDey;q|*-dzm_#z>MHufgW#2fe# zIuWvnNB-1z55{f_DP?@WIfYl+=*^@J;)z%wNA;?jVDi%d-3a^SOmGj`hKI;29%1d;V zOQrlgW!F*zYStD}ZGGxUc0(;k9mpj1oQs8IU z;(9{_3Qfoq|2pe^4*UI1Y;gqtPxZ%7)KJ?`>RoyA{P&@cUczKl_#g;}CIpHmvSzUv za)hd57yuT>GGnyju2x{eGR08&6+Ue8K=+AZjSDNPG=&ZS@N>#}h&h2U9-5>fUT z{D1>kAAMTueA}P}YvgzsS&kwCM7d!U*(U?!@fjL1hu}mINl4jzCf1!K5{a6~U~SQZ z8lhoD0N|)W07w#8l7H+H4cG~|$`n8cY6&U8|4h`{6ZYVJs49G@HrjEJaLuC9C+}w3 zQ3$8F&EfiS#UNEc&7ipFd+)WN#%>`Td1zlR9NmbuHq}S)grCl$N|R}mYm>9eL_B8$ z-T40eRp}qWwhcnMkDEgpSUsyldMM0C-xPJ+6y}s9Z<0EgWyQ=MV|6#+8^U)<* zmO{;N_ZCR4B+mdB5P3Cu1{6lNmv0#pAV@~E=Z}Az0f?CBzovw*0DyKuj_YWK3O5Sc z&Yjvs*i}yuG(WgOHz>W)|0)LHB!L( z@_`Lz?qp^hE9Pb~9Sj0a0r))qS}XM(+=kcj8Is?Y7hX*3zjb@yGRjXbG=(ZnqX8J_EM$0kf3 z^qQ(~y6m@@ygZ!pRY#H+4MLy&RrCN0=tOe0

w!o?iKbTEJvgYOAD^ct=oLTH}o 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ⅇv`L6G)=Db>FBn8iILMC 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%0DTdDO6Kw*4s&`L_RrYTFI|Z2utla9eY?X8e^~ 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 c;{PZBY`(Le0YCfuRL-s3kUQ3 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∾Yd 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 + +- A Scaleway account logged into the [console](https://console.scaleway.com) +- Python 3.7 or higher +- An API key from Scaleway [Identity and Access Management](https://www.scaleway.com/en/docs/identity-and-access-management/iam/) +- Access to Scaleway [Generative APIs](/ai-data/generative-apis/quickstart/) or to Scaleway [Managed Inference](/ai-data/managed-inference/quickstart/) +- The `openai` Python library installed + +## Understanding function calling + +Function calling allows AI models to: +- Understand when to use specific functions based on user queries +- Extract relevant parameters from natural language +- Format the extracted information into structured function calls +- Process the function results and present them in a user-friendly way + +## Setting up the environment + +1. Create a new directory for your project: + ``` + mkdir flight-assistant + cd flight-assistant + ``` + +2. Create and activate a virtual environment: + ``` + python3 -m venv venv + source venv/bin/activate # On Windows, use `venv\Scripts\activate` + ``` + +3. Install the required library: + ``` + pip install openai + ``` + +## Creating the flight schedule function + +First, let's create a simple function that returns flight schedules. Create a file called `flight_schedule.py`: + +```python +def get_flight_schedule(departure_airport: str, destination_airport: str, departure_date: str) -> dict: + """ + Get available flights between two airports on a specific date. + + Args: + departure_airport (str): IATA code of departure airport (e.g., "CDG") + destination_airport (str): IATA code of destination airport (e.g., "LHR") + departure_date (str): Date in YYYY-MM-DD format + + Returns: + dict: Available flights with their details + """ + # Mock flight database - in a real application, this would query an actual database + flights = { + "CDG-LHR-2024-11-01": [ + { + "flight_number": "AF123", + "airline": "Air France", + "departure_time": "08:00", + "arrival_time": "09:00", + "price": "€150" + }, + { + "flight_number": "BA456", + "airline": "British Airways", + "departure_time": "14:00", + "arrival_time": "15:00", + "price": "€180" + } + ] + } + + key = f"{departure_airport}-{destination_airport}-{departure_date}" + return flights.get(key, {"error": "No flights found for this route and date."}) +``` + +## Setting up the AI assistant + +Create a new file called `assistant.py` to handle the AI interactions: + +```python +from openai import OpenAI +import os +import json +from flight_schedule import get_flight_schedule + +# Initialize the OpenAI client with Scaleway configuration + +MODEL="meta/llama-3.1-70b-instruct:fp8" +# use the right name according to your Managed Inference deployment or Generative APIs model + +API_KEY = os.environ.get("SCALEWAY_API_KEY") +BASE_URL = os.environ.get("SCALEWAY_INFERENCE_ENDPOINT_URL") +# use https://api.scaleway.ai/v1 for Scaleway Generative APIs + +client = OpenAI( + base_url=BASE_URL, + api_key=API_KEY +) + +# Define the tool specification +tools = [{ + "type": "function", + "function": { + "name": "get_flight_schedule", + "description": "Get available flights between two airports on a specific date", + "parameters": { + "type": "object", + "properties": { + "departure_airport": { + "type": "string", + "description": "IATA code of departure airport (e.g., CDG, LHR)" + }, + "destination_airport": { + "type": "string", + "description": "IATA code of destination airport (e.g., CDG, LHR)" + }, + "departure_date": { + "type": "string", + "description": "Date in YYYY-MM-DD format" + } + }, + "required": ["departure_airport", "destination_airport", "departure_date"] + } + } +}] + +def process_query(user_query: str) -> str: + """Process a natural language query about flights.""" + + # Initial conversation with the model + messages = [ + { + "role": "system", + "content": "You are a helpful flight assistant. Help users find flights by calling the appropriate function." + }, + { + "role": "user", + "content": user_query + } + ] + + # Get the model's response + response = client.chat.completions.create( + model=MODEL, + messages=messages, + tools=tools, + tool_choice="auto" + ) + + # Check if the model wants to call a function + response_message = response.choices[0].message + + if response_message.tool_calls: + # Get function call details + tool_call = response_message.tool_calls[0] + function_name = tool_call.function.name + function_args = json.loads(tool_call.function.arguments) + + # Execute the function + if function_name == "get_flight_schedule": + function_response = get_flight_schedule(**function_args) + + # Add the function result to the conversation + messages.append(response_message) + messages.append({ + "role": "tool", + "content": json.dumps(function_response), + "tool_call_id": tool_call.id + }) + + # Get final response + final_response = client.chat.completions.create( + model=MODEL, + messages=messages + ) + + return final_response.choices[0].message.content + + return response_message.content +``` + +## Creating the main application + +Create a file called `main.py` to run the assistant: + +```python +from assistant import process_query + +def main(): + print("Welcome to the Flight Schedule Assistant!") + print("Ask about flights using natural language (or type 'quit' to exit)") + print("Example: What flights are available from CDG to LHR on November 1st, 2024?") + + while True: + query = input("\nYour query: ") + if query.lower() == 'quit': + break + + response = process_query(query) + print("\nAssistant:", response) + +if __name__ == "__main__": + main() +``` + +## Running the application + +1. Set your Scaleway API key: + ``` + export SCALEWAY_API_KEY="your-api-key-here" + ``` + +2. Run the application: + ``` + python main.py + ``` + +3. Try some example queries: + - "What flights are available from CDG to LHR tomorrow?" + - "Show me morning flights from Paris to London on November 1st" + - "Are there any afternoon flights from CDG to LHR on 2024-11-01?" + +## How it works + +1. **User input**: The application receives a natural language query about flights. + +2. **Function recognition**: The AI model analyzes the query and determines that it needs flight schedule information. + +3. **Parameter extraction**: The model extracts key information (airports, date) from the query. + +4. **Function calling**: The model returns the function call to be made by the user, in this case the `get_flight_schedule` function with the extracted parameters provided by the model. + +5. **Response generation**: The model receives the function's response and generates a natural language reply for the user. + +## Customizing the application + +You can enhance the flight assistant in several ways: + +1. **Add real data**: Replace the mock flight database with actual flight API calls. +2. **Expand functions**: Add functions for booking flights, checking prices, or getting airport information. +3. **Improve error handling**: Add validation for airport codes and dates. +4. **Add memory**: Implement conversation history to handle follow-up questions. + +## Conclusion + +Function calling bridges the gap between natural language processing and structured data operations. This flight schedule assistant demonstrates how to implement function calling to create intuitive interfaces for your applications. + + + Remember to handle user data responsibly and validate all inputs before making actual flight queries or bookings in a production environment. + From ad89918862121ede68432650fb0d0d56e452da91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oc=C3=A9ane?= Date: Fri, 25 Oct 2024 17:30:27 +0200 Subject: [PATCH 48/68] feat(changelog): add new entry (#3892) Co-authored-by: Changelog bot --- ...rence-added-support-for-function-calling.mdx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 changelog/october2024/2024-10-25-managed-inference-added-support-for-function-calling.mdx diff --git a/changelog/october2024/2024-10-25-managed-inference-added-support-for-function-calling.mdx b/changelog/october2024/2024-10-25-managed-inference-added-support-for-function-calling.mdx new file mode 100644 index 0000000000..7de0a9ef36 --- /dev/null +++ b/changelog/october2024/2024-10-25-managed-inference-added-support-for-function-calling.mdx @@ -0,0 +1,17 @@ +--- +title: Support for function calling +status: added +author: + fullname: 'Join the #ai channel on Slack.' + url: 'https://slack.scaleway.com' +date: 2024-10-25 +category: ai-data +product: managed-inference +--- + +Function calling allows a large language model (LLM) to interact with external tools or APIs. + +Parameters `tools` and `tool_choice` of our OpenAI-compatible chat API are now accepted for models with this capacity. + +Read [our dedicated documentation](https://www.scaleway.com/en/docs/ai-data/managed-inference/reference-content/function-calling-support/) and [tutorial to get started](https://www.scaleway.com/en/docs/tutorials/building-ai-application-function-calling)! + From 2b808c2c10086ac6055440c4bf72002b5c24df8d Mon Sep 17 00:00:00 2001 From: Christian VDZ Date: Mon, 28 Oct 2024 10:45:43 +0100 Subject: [PATCH 49/68] fix(docs): update ipfs-pinning quickstart (#3894) --- labs/ipfs-pinning/quickstart.mdx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/labs/ipfs-pinning/quickstart.mdx b/labs/ipfs-pinning/quickstart.mdx index 7b1a8847b7..aa2ce021f5 100644 --- a/labs/ipfs-pinning/quickstart.mdx +++ b/labs/ipfs-pinning/quickstart.mdx @@ -64,7 +64,7 @@ This operation allows you to add Scaleway as a remote service in your IPFS deskt 4. Click **Add a custom one** to add Scaleway as a remote pinning service. A configuration form displays. 5. Fill in the different fields by replacing the parameters in brackets with the relevant information: - Nickname: `Scaleway` - - API endpoint: `https:/.ipfs.labs.scw.cloud/` + - API endpoint: `https://.ipfs.labs.scw.cloud/` - Secret access token: `<$SCW_SECRET_KEY>` | Parameter | Description | @@ -85,7 +85,8 @@ Scaleway should now appear in the list of remote pinning services. ## How to retrieve your data -Now that you have pinned your data, you can retrieve it using [CloudFlare](https://www.cloudflare.com/), [Pinata](https://www.pinata.cloud/) or [Protocol Labs](https://protocol.ai/). These are IPFS gateways, which are services that allow you to interact with the IPFS network using regular, HTTP/HTTPS web protocols. This means you do not need a particular IPFS software to retrieve your data - you can instead use your regular web browser. +Now that you have pinned your data, you can retrieve it using [CloudFlare](https://www.cloudflare.com/), [Pinata](https://www.pinata.cloud/) or [Protocol Labs](https://protocol.ai/). +These services act as IPFS gateways, enabling you to interact with the IPFS network using standard HTTP/HTTPS web protocols. This means you don’t need specialized IPFS software to retrieve your data; you can simply use your regular web browser. 1. Click the icon next to the CID of the data you want to retrieve. The three IPFS gateways display. -2. Click the IPFS gateway you wish to retrieve your data from. Your data displays in a new tab. \ No newline at end of file +2. Click the IPFS gateway you wish to retrieve your data from. Your data displays in a new tab. From 5407ee4a0401ed2a7336c05b3ed4fa227114d8d0 Mon Sep 17 00:00:00 2001 From: SamyOubouaziz Date: Mon, 28 Oct 2024 10:50:32 +0100 Subject: [PATCH 50/68] docs(srv): add notes and troubleshooting on encoding secrets and env vars MTA-5183 (#3889) --- ...ainer-from-external-container-registry.mdx | 3 +++ ...ainer-from-scaleway-container-registry.mdx | 3 +++ .../troubleshooting/common-errors.mdx | 19 ++++++++++++++++++- .../functions/how-to/create-a-function.mdx | 3 +++ .../troubleshooting/common-errors.mdx | 17 +++++++++++++++++ .../create-job-from-external-registry.mdx | 3 +++ .../create-job-from-scaleway-registry.mdx | 3 +++ .../jobs/troubleshooting/common-errors.mdx | 19 ++++++++++++++++++- 8 files changed, 68 insertions(+), 2 deletions(-) diff --git a/serverless/containers/how-to/deploy-a-container-from-external-container-registry.mdx b/serverless/containers/how-to/deploy-a-container-from-external-container-registry.mdx index 49b2041071..7f23fee3e2 100644 --- a/serverless/containers/how-to/deploy-a-container-from-external-container-registry.mdx +++ b/serverless/containers/how-to/deploy-a-container-from-external-container-registry.mdx @@ -48,6 +48,9 @@ For now, Serverless Containers only supports public images. - Set your [scaling](/serverless/containers/concepts/#scaling) preferences, or leave them at default values. The Scaleway platform autoscales the number of available instances of your container to match the incoming load, depending on the settings you define here. - Click **Advanced options** to define any [environment variables](/serverless/containers/concepts/#environment-variables) you want to inject into your container. For each environment variable, click **+Add variable** and enter the key/value pair. - Add [secrets](/serverless/containers/concepts/#secrets) for your container. Secrets are environment variables which are injected into your container, but the values are not retained or displayed by Scaleway after initial validation. + + Encode your environment variables and secrets to `base64` if they are too large, and contain carriage returns. + - Set the desired [privacy policy](/serverless/containers/concepts/#privacy-policy) for your container. This defines whether container invocation may be done anonymously (**public**) or only via an authentication mechanism provided by the [Scaleway API](https://www.scaleway.com/en/developers/api/serverless-containers/#authentication) (**private**). - Set a custom [timeout](/serverless/containers/concepts/#timeout) for your container. - Verify the **estimated cost**. diff --git a/serverless/containers/how-to/deploy-a-container-from-scaleway-container-registry.mdx b/serverless/containers/how-to/deploy-a-container-from-scaleway-container-registry.mdx index d195f6f20d..0c5fb5afd6 100644 --- a/serverless/containers/how-to/deploy-a-container-from-scaleway-container-registry.mdx +++ b/serverless/containers/how-to/deploy-a-container-from-scaleway-container-registry.mdx @@ -42,6 +42,9 @@ You can deploy a container from the [Scaleway Container Registry](/containers/co - Set your [scaling](/serverless/containers/concepts/#scaling) preferences, or leave them at default values. The Scaleway platform autoscales the number of available instances of your container to match the incoming load, depending on the settings you define here. - Click **Advanced options** to define any [environment variables](/serverless/containers/concepts/#environment-variables) you want to inject into your container. For each environment variable, click **+Add variable** and enter the key/value pair. - Add [secrets](/serverless/containers/concepts/#secrets) for your container. Secrets are environment variables which are injected into your container, but the values are not retained or displayed by Scaleway after initial validation. + + Encode your environment variables and secrets to `base64` if they are too large, and contain carriage returns. + - Set the desired [privacy policy](/serverless/containers/concepts/#privacy-policy) for your container. This defines whether container invocation may be done anonymously (**public**) or only via an authentication mechanism provided by the [Scaleway API](https://www.scaleway.com/en/developers/api/serverless-containers/#authentication) (**private**). - Set a custom [timeout](/serverless/containers/concepts/#timeout) for your container. - Verify the **estimated cost**. diff --git a/serverless/containers/troubleshooting/common-errors.mdx b/serverless/containers/troubleshooting/common-errors.mdx index 4dc75d96f3..d2fe6930cc 100644 --- a/serverless/containers/troubleshooting/common-errors.mdx +++ b/serverless/containers/troubleshooting/common-errors.mdx @@ -65,4 +65,21 @@ Serverless products support external public registries (such as [Docker Hub](htt ### Solution -We recommend using [Scaleway's Container Registry](/containers/container-registry/) instead, as it allows for a seamless integration with Serverless Containers and Jobs at a [competitive price](/faq/containerregistry/#how-am-i-billed-for-scaleway-container-registry). \ No newline at end of file +We recommend using [Scaleway's Container Registry](/containers/container-registry/) instead, as it allows for a seamless integration with Serverless Containers and Jobs at a [competitive price](/faq/containerregistry/#how-am-i-billed-for-scaleway-container-registry). + +## My environment variable or secret is not properly injected in my container + +### Cause + +Environment variables or secrets that are too large, contain carriage returns and spread over several lines, as shown below, will not be injected properly. + +``` +"hello +world +. +" +``` + +### Solution + +To avoid issues while injecting environment variables and secrets, we recommend encoding them to `base64`. \ No newline at end of file diff --git a/serverless/functions/how-to/create-a-function.mdx b/serverless/functions/how-to/create-a-function.mdx index c4070b4153..a99e6cdccc 100644 --- a/serverless/functions/how-to/create-a-function.mdx +++ b/serverless/functions/how-to/create-a-function.mdx @@ -41,6 +41,9 @@ This page shows you how to deploy a [function](/serverless/functions/concepts/#f 5. Click **+ Advanced options** and complete the following steps: - Define any **environment variables** you want to inject into your function. For each environment variable, click **+ Add variable** and enter the key/value pair. - Optionally, set secret environment variables. **Secrets** are environment variables which are injected into your function and stored securely, but not displayed in the console after initial validation. Add a **key** and a **value**. + + Encode your environment variables and secrets to `base64` if they are too large, and contain carriage returns. + - Set the desired **privacy policy** for your function. This defines whether a function can be executed anonymously (**public**) or only via an authentication mechanism provided by the [Scaleway API](https://www.scaleway.com/en/developers/api/serverless-functions/#authentication) (**private**). - Set the desired timeout for your function. diff --git a/serverless/functions/troubleshooting/common-errors.mdx b/serverless/functions/troubleshooting/common-errors.mdx index e308928d89..f72bfef40a 100644 --- a/serverless/functions/troubleshooting/common-errors.mdx +++ b/serverless/functions/troubleshooting/common-errors.mdx @@ -108,3 +108,20 @@ The new deploy failed, and the [fallback mechanism has been triggered](/serverle ### Possible solution Identify the element that caused the deployment to fail, fix the error, and deploy the function again. + +## My environment variable or secret is not properly injected in my function + +### Cause + +Environment variables or secrets that are too large, contain carriage returns and spread over several lines, as shown below, will not be injected properly. + +``` +"hello +world +. +" +``` + +### Solution + +To avoid issues while injecting environment variables and secrets, we recommend encoding them to `base64`. diff --git a/serverless/jobs/how-to/create-job-from-external-registry.mdx b/serverless/jobs/how-to/create-job-from-external-registry.mdx index f3dd7d73ef..4cb5c8f9eb 100644 --- a/serverless/jobs/how-to/create-job-from-external-registry.mdx +++ b/serverless/jobs/how-to/create-job-from-external-registry.mdx @@ -39,6 +39,9 @@ Private external container registries are currently not supported. - Choose the **resources** to be allocated to your job at runtime. These define the performance characteristics of your job. - Optionally, add a **cron schedule** in the `* * * * *` format, and select your time zone to run your job periodically. Refer to the [cron schedules documentation](/serverless/jobs/reference-content/cron-schedules/) for more information. - Define any **environment variables** you want to inject into your job in the advanced options. For each environment variable, click **+Add new variable** and enter the key/value pair. + + Encode your environment variables to `base64` if they are too large, and contain carriage returns. + - Add a **startup command** to your job. It will be executed every time your job is run. - Set a **maximum duration** to your job to stop it automatically if it does not complete within this limit. - Verify the **estimated cost**. diff --git a/serverless/jobs/how-to/create-job-from-scaleway-registry.mdx b/serverless/jobs/how-to/create-job-from-scaleway-registry.mdx index 58c6d3b043..27e1ac2a98 100644 --- a/serverless/jobs/how-to/create-job-from-scaleway-registry.mdx +++ b/serverless/jobs/how-to/create-job-from-scaleway-registry.mdx @@ -34,6 +34,9 @@ Scaleway's Serverless Jobs allows you to create jobs from several container [reg - Choose the **resources** to be allocated to your job at runtime. These define the performance characteristics of your job. - Add a **cron schedule** in the `* * * * *` format, and select your time zone to run your job periodically. Refer to the [cron schedules documentation](/serverless/jobs/reference-content/cron-schedules/) for more information. - Define any **environment variables** you want to inject into your job in the advanced options. For each environment variable, click **+Add new variable** and enter the key/value pair. + + Encode your environment variables to `base64` if they are too large, and contain carriage returns. + - Add a **startup command** to your job. It will be executed every time your job is run. - Set a **maximum duration** to your job to stop it automatically if it does not complete within this limit. - Verify the **estimated cost**. diff --git a/serverless/jobs/troubleshooting/common-errors.mdx b/serverless/jobs/troubleshooting/common-errors.mdx index db3a79a95c..a6d923a3ce 100644 --- a/serverless/jobs/troubleshooting/common-errors.mdx +++ b/serverless/jobs/troubleshooting/common-errors.mdx @@ -29,4 +29,21 @@ Serverless products support external public registries (such as [Docker Hub](htt ### Solution -We recommend using [Scaleway's Container Registry](/containers/container-registry/) instead, as it allows for a seamless integration with Serverless Containers and Jobs at a [competitive price](/faq/containerregistry/#how-am-i-billed-for-scaleway-container-registry). \ No newline at end of file +We recommend using [Scaleway's Container Registry](/containers/container-registry/) instead, as it allows for a seamless integration with Serverless Containers and Jobs at a [competitive price](/faq/containerregistry/#how-am-i-billed-for-scaleway-container-registry). + +## My environment variable or secret is not properly injected in my job + +### Cause + +Environment variables or secrets that are too large, contain carriage returns and spread over several lines, as shown below, will not be injected properly. + +``` +"hello +world +. +" +``` + +### Solution + +To avoid issues while injecting environment variables and secrets, we recommend encoding them to `base64`. \ No newline at end of file From 7f449919a81f376194bc600fedb7b5ab82346bfa Mon Sep 17 00:00:00 2001 From: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Date: Mon, 28 Oct 2024 17:06:03 +0100 Subject: [PATCH 51/68] fix(pgw): remove duplicate H2 (#3897) --- network/public-gateways/how-to/create-a-public-gateway.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/network/public-gateways/how-to/create-a-public-gateway.mdx b/network/public-gateways/how-to/create-a-public-gateway.mdx index ef783408e4..4a5d4fd068 100644 --- a/network/public-gateways/how-to/create-a-public-gateway.mdx +++ b/network/public-gateways/how-to/create-a-public-gateway.mdx @@ -22,8 +22,6 @@ categories: ## How to create a Public Gateway -## How to create a Public Gateway - 1. Click **Public Gateways** in the **Network** section of the side menu. 2. Click **Create Public Gateway** to launch the Public Gateway creation wizard. 3. Complete the following steps in the wizard: From cccdb1c54fb48fe46ca4b56d42d5d200a5743aa0 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Mon, 28 Oct 2024 17:08:59 +0100 Subject: [PATCH 52/68] fix(ai): add missing link (#3899) --- menu/navigation.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/menu/navigation.json b/menu/navigation.json index 86d74e66f8..1e9fa3c32d 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -591,6 +591,10 @@ "label": "OpenAI API compatibility", "slug": "openai-compatibility" }, + { + "label": "Support for function calling in Scaleway Managed Inference", + "slug": "function-calling-support" + }, { "label": "Support for function calling", "slug": "function-calling-support" From ad62179cb6a453c6bb86875a427d9ad17a7c8ffd Mon Sep 17 00:00:00 2001 From: Thomas TACQUET Date: Tue, 29 Oct 2024 10:26:22 +0100 Subject: [PATCH 53/68] fix(serverless): faq title level (#3901) * fix(serverless): faq title level * one more --- faq/serverless-containers.mdx | 6 +++--- faq/serverless-functions.mdx | 2 +- faq/serverless-jobs.mdx | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/faq/serverless-containers.mdx b/faq/serverless-containers.mdx index 3d27192425..755f98b150 100644 --- a/faq/serverless-containers.mdx +++ b/faq/serverless-containers.mdx @@ -97,11 +97,11 @@ Ensure that your code avoids heavy computations or long-running initialization a Refer to our dedicated page about [Serverless Containers limitations and configuration restrictions](/serverless/containers/reference-content/containers-limitations/) for more information. -# Where should I host my container images for deployment ? +## Where should I host my container images for deployment ? -# How can I copy an image from an external registry to Scaleway Container Registry? +## How can I copy an image from an external registry to Scaleway Container Registry? You can copy an image from an external registry by [logging in to the Scaleway Container Registry](/containers/container-registry/how-to/connect-docker-cli/) using the Docker CLI, and by copying the image as shown below: @@ -153,7 +153,7 @@ Scaleway Serverless Containers do not currently support attaching block storage. stateless, meaning they do not retain data between invocations. For persistent storage, we recommend using external solutions like Scaleway Object Storage. -# Why does my container have an instance running after deployment, even with min-scale 0? +## Why does my container have an instance running after deployment, even with min-scale 0? Currently, a new container instance will always start after each deployment, even if there is no traffic and the minimum scale is set to 0. This behavior is not configurable at this time. diff --git a/faq/serverless-functions.mdx b/faq/serverless-functions.mdx index b4702d3727..708e500fe9 100644 --- a/faq/serverless-functions.mdx +++ b/faq/serverless-functions.mdx @@ -180,7 +180,7 @@ Scaleway Serverless Functions do not currently support attaching block storage. stateless, meaning they do not retain data between invocations. For persistent storage, we recommend using external solutions like Scaleway Object Storage. -# Why does my function have an instance running after deployment, even with min-scale 0? +## Why does my function have an instance running after deployment, even with min-scale 0? Currently, a new function instance will always start after each deployment, even if there is no traffic and the minimum scale is set to 0. This behavior is not configurable at this time. diff --git a/faq/serverless-jobs.mdx b/faq/serverless-jobs.mdx index fb7baf3451..7b9e8b216b 100644 --- a/faq/serverless-jobs.mdx +++ b/faq/serverless-jobs.mdx @@ -94,11 +94,11 @@ Scaleway Serverless Jobs is part of the Scaleway ecosystem, it can therefore be When starting a job, you can use contextual options to define the number of jobs to execute at the same time. Refer to the [dedicated documentation](/serverless/jobs/how-to/run-job/#how-to-run-a-job-with-contextual-options) for more information. -# Where should I host my jobs images for deployment ? +## Where should I host my jobs images for deployment ? -# How can I copy an image from an external registry to Scaleway Container Registry? +## How can I copy an image from an external registry to Scaleway Container Registry? You can copy an image from an external registry by [logging in to the Scaleway Container Registry](/containers/container-registry/how-to/connect-docker-cli/) using the Docker CLI, and by copying the image as shown below: @@ -119,4 +119,4 @@ skopeo copy --override-os linux docker://docker.io/alpine:latest docker://rg.fr- Scaleway Serverless Jobs does not currently support Scaleway VPC or Private Networks, though this feature is under development. -To add network restrictions on your resource, consult the [list of prefixes used at Scaleway](https://www.scaleway.com/en/peering/). Serverless resources do not have dedicated or predictable IP addresses. \ No newline at end of file +To add network restrictions on your resource, consult the [list of prefixes used at Scaleway](https://www.scaleway.com/en/peering/). Serverless resources do not have dedicated or predictable IP addresses. From 148b1bf723c9e2b616d475627b72f07f43231de6 Mon Sep 17 00:00:00 2001 From: SamyOubouaziz Date: Tue, 29 Oct 2024 10:40:59 +0100 Subject: [PATCH 54/68] docs(srv): add SEM x Jobs documentation MTA-5199 (#3898) * docs(srv): add SEM x Jobs documentation MTA-5199 * Update serverless/jobs/quickstart.mdx Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> * Update faq/serverless-jobs.mdx Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> * Update serverless/jobs/how-to/reference-secret-in-job.mdx Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> * Update serverless/jobs/how-to/reference-secret-in-job.mdx Co-authored-by: Thomas TACQUET * Update serverless/jobs/how-to/reference-secret-in-job.mdx Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> * Update serverless/jobs/how-to/reference-secret-in-job.mdx Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> * Update serverless/jobs/how-to/reference-secret-in-job.mdx Co-authored-by: Thomas TACQUET * Update serverless/jobs/how-to/reference-secret-in-job.mdx Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> * Update serverless/jobs/quickstart.mdx Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> * docs(srv): upadate * Update serverless/jobs/how-to/reference-secret-in-job.mdx Co-authored-by: Jessica <113192637+jcirinosclwy@users.noreply.github.com> * Update serverless/jobs/how-to/create-job-from-external-registry.mdx Co-authored-by: Jessica <113192637+jcirinosclwy@users.noreply.github.com> --------- Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Co-authored-by: Thomas TACQUET Co-authored-by: Jessica <113192637+jcirinosclwy@users.noreply.github.com> --- faq/serverless-jobs.mdx | 6 +- menu/navigation.json | 4 + serverless/jobs/concepts.mdx | 4 + .../create-job-from-external-registry.mdx | 1 + .../create-job-from-scaleway-registry.mdx | 1 + .../jobs/how-to/reference-secret-in-job.mdx | 80 +++++++++++++++++++ serverless/jobs/quickstart.mdx | 6 +- 7 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 serverless/jobs/how-to/reference-secret-in-job.mdx diff --git a/faq/serverless-jobs.mdx b/faq/serverless-jobs.mdx index 7b9e8b216b..ce721a99ef 100644 --- a/faq/serverless-jobs.mdx +++ b/faq/serverless-jobs.mdx @@ -66,7 +66,7 @@ Serverless Jobs are billed on a pay-as-you-go basis, strictly on resource consum * *Billed resources:* 864 000 - 400 000 = 464 000 GB-s * *Cost:* 464 000 * €0.0000010 = **€0.47** * **vCPU consumption** - * *Allocated vCPU conversion:* 1120mVCPU = 1.12 vCPU + * *Allocated vCPU conversion:* 1120 mVCPU = 1.12 vCPU * *Resource consumption:* 432 000 s * 1.12 vCPU = 483 840 vCPU-s * *Free tier:* 200 000 vCPU-s * *Billed resources:* 483 840 - 200 000 = 283 840 vCPU-s @@ -120,3 +120,7 @@ skopeo copy --override-os linux docker://docker.io/alpine:latest docker://rg.fr- Scaleway Serverless Jobs does not currently support Scaleway VPC or Private Networks, though this feature is under development. To add network restrictions on your resource, consult the [list of prefixes used at Scaleway](https://www.scaleway.com/en/peering/). Serverless resources do not have dedicated or predictable IP addresses. + +## Can I securely use sensitive information with Serverless Jobs? + +Yes, you can use sensitive data such as API secret keys, passwords, TLS/SSL certificates, or tokens. Serverless Jobs seamlessly integrates with [Secret Manager](/identity-and-access-management/secret-manager/), which allows you to securely reference sensitive information within your jobs. Refer to the [dedicated documentation](/serverless/jobs/how-to/reference-secret-in-job/) for more information. diff --git a/menu/navigation.json b/menu/navigation.json index 1e9fa3c32d..5f50e35e44 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -3933,6 +3933,10 @@ "label": "Manage the scheduling of a job", "slug": "manage-job-schedule" }, + { + "label": "Reference secrets in a job", + "slug": "reference-secret-in-job" + }, { "label": "Delete a job", "slug": "delete-job" diff --git a/serverless/jobs/concepts.mdx b/serverless/jobs/concepts.mdx index 39297a89a7..fcdcd4ec6b 100644 --- a/serverless/jobs/concepts.mdx +++ b/serverless/jobs/concepts.mdx @@ -53,6 +53,10 @@ The maximum duration option allows you to define the maximum execution time befo A schedule (cron) is a mechanism used to automatically start a Serverless Job at a specific time on a recurring schedule. It works similarly to a traditional Linux cron job, using the `* * * * *` format. Refer to our [cron schedules reference](/serverless/jobs/reference-content/cron-schedules/) for more information. +## Secrets reference + +A secret reference is a mechanism that allows you to use a secret stored in [Secret Manager](/identity-and-access-management/secret-manager/) within Serverless Jobs. It allows you to securely reference sensitive data, such as API secret keys, passwords, tokens, or certificates. + ## Startup command This optional field allows you to specify a custom command executed upon starting your job if your container image does not have one already, or if you use a public container image. diff --git a/serverless/jobs/how-to/create-job-from-external-registry.mdx b/serverless/jobs/how-to/create-job-from-external-registry.mdx index 4cb5c8f9eb..effd243a84 100644 --- a/serverless/jobs/how-to/create-job-from-external-registry.mdx +++ b/serverless/jobs/how-to/create-job-from-external-registry.mdx @@ -42,6 +42,7 @@ Private external container registries are currently not supported. Encode your environment variables to `base64` if they are too large, and contain carriage returns. + - Add the desired [secret references](/serverless/jobs/how-to/reference-secret-in-job/) to your job. - Add a **startup command** to your job. It will be executed every time your job is run. - Set a **maximum duration** to your job to stop it automatically if it does not complete within this limit. - Verify the **estimated cost**. diff --git a/serverless/jobs/how-to/create-job-from-scaleway-registry.mdx b/serverless/jobs/how-to/create-job-from-scaleway-registry.mdx index 27e1ac2a98..15738c37b2 100644 --- a/serverless/jobs/how-to/create-job-from-scaleway-registry.mdx +++ b/serverless/jobs/how-to/create-job-from-scaleway-registry.mdx @@ -37,6 +37,7 @@ Scaleway's Serverless Jobs allows you to create jobs from several container [reg Encode your environment variables to `base64` if they are too large, and contain carriage returns. + - Add the desired [secret references](/serverless/jobs/how-to/reference-secret-in-job/) to your job. - Add a **startup command** to your job. It will be executed every time your job is run. - Set a **maximum duration** to your job to stop it automatically if it does not complete within this limit. - Verify the **estimated cost**. diff --git a/serverless/jobs/how-to/reference-secret-in-job.mdx b/serverless/jobs/how-to/reference-secret-in-job.mdx new file mode 100644 index 0000000000..b1fa7bd272 --- /dev/null +++ b/serverless/jobs/how-to/reference-secret-in-job.mdx @@ -0,0 +1,80 @@ +--- +meta: + title: How to reference secrets in Serverless Jobs + description: Steps to reference secrets from Secret Manager in your Serverless Jobs. +content: + h1: How to reference secrets in Serverless Jobs + paragraph: Steps to reference secrets from Secret Manager in your Serverless Jobs. +tags: serverless jobs secrets secret-manager environment-variable +dates: + validation: 2024-10-27 + posted: 2024-10-27 +categories: + - serverless + - jobs +--- + +Serverless Jobs seamlessly integrates with [Secret Manager](/identity-and-access-management/secret-manager/), which allows you to store, manage, and access sensitive information, such as credentials, SSH keys, SSL/TLS certificates, or any key/value pairs you need to secure. + +You can reference any secret stored in Secret Manager in a job, without having to hardcode any sensitive data. + +A [job run](/serverless/jobs/concepts/#job-run) accesses each secret at startup, and each access generates a call to the Secret Manager API, which is billed accordingly. Refer to the [Secret Manager pricing](/identity-and-access-management/secret-manager) for more information. + + + +- A Scaleway account logged into the [console](https://console.scaleway.com) +- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization +- [Created a Serverless Job](/serverless/jobs/how-to/create-job-from-scaleway-registry/) +- [Created a secret](/identity-and-access-management/secret-manager/how-to/create-secret/) + +## Reference a secret in a job + +1. Click **Jobs** in the **Serverless** section of the side menu. The jobs page displays. + +2. Click the name of the job to which you want to add a secret, then open the **Settings** tab. + +3. In the **Secrets references** section, click **+ Add secret reference**. A pop-up displays. + +4. Select the secret you want to reference, and the desired version, then click **Select reference method**. + +5. Select the desired reference method: + + - **File**: copies the encrypted value of your secret to a file stored at the indicated location within your container. This method is recommended for large or complex data. For example, if your secret is a certificate, you can store it as a file in the `/my-certificates` folder in your container. + + - **Environment variable**: passes the encrypted value of your secret to your job as a variable. This method is recommended for small pieces of information, such as passwords, or API secret keys. For example, if you name this variable `MY_SECRET`, calling `$MY_SECRET` in your container will return the value of the selected secret in a secure way. + +6. Click **Add reference** to add the secret to your Serverless Job. Optionally, tick the **Add another reference** to add a new secret right away, then repeat steps 4 to 6. + +The secret is now referenced in your Serverless Job, and can be used within the container. + +## Update a secret reference from a job + +1. Click **Jobs** in the **Serverless** section of the side menu. The jobs page displays. + +2. Click the name of the job for which you want to update a secret, then open the **Settings** tab. + +3. In the **Secret references** section, click the icon next to the secret reference you want to update. A pop-up displays. + +4. Update the secret version if needed, then click **Update** to save your changes, or click **Select reference method** to continue. + +5. Either update the location of the file, or the name of the environment variable, then click **Update reference** to confirm your changes. + + +You cannot change the reference method of an existing secret. You have to delete the secret reference within the job first, then create it again with the desired reference method. + + +## Delete a secret reference from a job + +1. Click **Jobs** in the **Serverless** section of the side menu. The jobs page displays. + +2. Click the name of the job for which you want to delete a secret, then open the **Settings** tab. + +3. In the **Secret references** section, click the icon next to the secret reference you want to delete. A confirmation pop-up displays. + +4. Click **Delete reference** to confirm. + +The secret is no longer referenced in your Serverless Job. + + +Deleting a secret from the **Settings** tab of a job only deletes the secret reference, not the secret itself. To permanently delete a secret, follow [this procedure](/identity-and-access-management/secret-manager/how-to/delete-secret/). + \ No newline at end of file diff --git a/serverless/jobs/quickstart.mdx b/serverless/jobs/quickstart.mdx index 8ddc856c50..954a5ad39c 100644 --- a/serverless/jobs/quickstart.mdx +++ b/serverless/jobs/quickstart.mdx @@ -62,10 +62,12 @@ This page explains how to create a job definition with the latest Alpine Linux i 3. From the **Overview** tab, click **Run job**. -The execution appears in the **Job runs** section of the **Overview** tab. + The execution appears in the **Job runs** section of the **Overview** tab. + +4. Click the icon next to the last execution in the **Job runs** section, then click **Logs** to access your job's logs. - Refer to [How to monitor a job](/serverless/jobs/how-to/monitor-job/) to see the logs of the job you just executed. + Make sure that you [have retrieved your Grafana credentials](/observability/cockpit/how-to/retrieve-grafana-credentials/) before accessing your job's logs. ## How to delete a job From b9bd0697eb230f67cee8209bf7160b3bcfd3ab26 Mon Sep 17 00:00:00 2001 From: Thomas TACQUET Date: Tue, 29 Oct 2024 10:42:10 +0100 Subject: [PATCH 55/68] feat(serverless): fix somesyntax highlighting (#3895) * feat(serverless): fix somesyntax highlighting * missing syntax type * missing tags * json to hcl * more tf to hcl --- .../containers/how-to/secure-a-container.mdx | 2 +- .../create-serverless-scraping/index.mdx | 46 ++++++------- .../index.mdx | 66 +++++++++--------- .../index.mdx | 6 +- tutorials/large-messages/index.mdx | 26 +++---- .../index.mdx | 18 ++--- tutorials/snapshot-instances-jobs/index.mdx | 2 +- .../index.mdx | 68 +++++++++---------- 8 files changed, 117 insertions(+), 117 deletions(-) diff --git a/serverless/containers/how-to/secure-a-container.mdx b/serverless/containers/how-to/secure-a-container.mdx index 8164c90538..b29425faa3 100644 --- a/serverless/containers/how-to/secure-a-container.mdx +++ b/serverless/containers/how-to/secure-a-container.mdx @@ -57,7 +57,7 @@ secret: Add the following [resource description](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/container) in Terraform: -``` +```hcl secret_environment_variables = { "key" = "secret" } ``` diff --git a/tutorials/create-serverless-scraping/index.mdx b/tutorials/create-serverless-scraping/index.mdx index 30fb27d7b6..67c5e842da 100644 --- a/tutorials/create-serverless-scraping/index.mdx +++ b/tutorials/create-serverless-scraping/index.mdx @@ -47,7 +47,7 @@ We start by creating the scraper program, or the "data producer". SQS credentials and queue URL are read by the function from environment variables. Those variables are set by Terraform as explained in [one of the next sections](#create-a-terraform-file-to-provision-the-necessary-scaleway-resources). *If you choose another deployment method, such as the [console](https://console.scaleway.com/), do not forget to set them.* ```python - queue_url = os.getenv('QUEUE_URL') + queue_url = os.getenv('QUEUE_URL') sqs_access_key = os.getenv('SQS_ACCESS_KEY') sqs_secret_access_key = os.getenv('SQS_SECRET_ACCESS_KEY') ``` @@ -65,10 +65,10 @@ We start by creating the scraper program, or the "data producer". Using the AWS python sdk `boto3`, connect to the SQS queue and push the `title` and `url` of articles published less than 15 minutes ago. ```python sqs = boto3.client( - 'sqs', - endpoint_url=SCW_SQS_URL, - aws_access_key_id=sqs_access_key, - aws_secret_access_key=sqs_secret_access_key, + 'sqs', + endpoint_url=SCW_SQS_URL, + aws_access_key_id=sqs_access_key, + aws_secret_access_key=sqs_secret_access_key, region_name='fr-par') for age, titleline in zip(ages, titlelines): @@ -117,7 +117,7 @@ Next, let's create our consumer function. When receiving a message containing th Lastly, we write the information into the database. *To keep the whole process completely automatic the* `CREATE_TABLE_IF_NOT_EXISTS` *query is run each time. If you integrate the functions into an existing database, there is no need for it.* ```python conn = None - try: + try: conn = pg8000.native.Connection(host=db_host, database=db_name, port=db_port, user=db_user, password=db_password, timeout=15) conn.run(CREATE_TABLE_IF_NOT_EXISTS) @@ -136,7 +136,7 @@ As explained in the [Scaleway Functions documentation](/serverless/functions/how ## Create a Terraform file to provision the necessary Scaleway resources -For the purposes of this tutorial, we show how to provision all resources via Terraform. +For the purposes of this tutorial, we show how to provision all resources via Terraform. If you do not want to use Terraform, you can also create the required resources via the [console](https://console.scaleway.com/), the [Scaleway API](https://www.scaleway.com/en/developers/api/), or any other [developer tool](https://www.scaleway.com/en/developers/). Remember that if you do so, you will need to set up environment variables for functions as previously specified. The following documentation may help create the required resources: @@ -149,7 +149,7 @@ If you do not want to use Terraform, you can also create the required resources 1. Create a directory called `terraform` (at the same level as the `scraper` and `consumer` directories created in the previous steps). 2. Inside it, create a file called `main.tf`. 3. In the file you just created, add the code below to set up the [Scaleway Terraform provider](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs) and your Project: - ``` + ```hcl terraform { required_providers { scaleway = { @@ -167,7 +167,7 @@ If you do not want to use Terraform, you can also create the required resources } ``` 4. Still in the same file, add the code below to provision the SQS resources: SQS activation for the project, separate credentials with appropriate permissions for producer and consumer, and an SQS queue: - ``` + ```hcl resource "scaleway_mnq_sqs" "main" { project_id = scaleway_account_project.mnq_tutorial.id } @@ -202,7 +202,7 @@ If you do not want to use Terraform, you can also create the required resources } ``` 5. Add the code below to provision the Managed Database for PostgreSQL resources. Note that here we are creating a random password and using it for the default and worker user: - ``` + ```hcl resource "random_password" "dev_mnq_pg_exporter_password" { length = 16 special = true @@ -219,7 +219,7 @@ If you do not want to use Terraform, you can also create the required resources node_type = "db-dev-s" engine = "PostgreSQL-15" is_ha_cluster = false - disable_backup = true + disable_backup = true user_name = "mnq_initial_user" password = random_password.dev_mnq_pg_exporter_password.result } @@ -240,7 +240,7 @@ If you do not want to use Terraform, you can also create the required resources } resource "scaleway_rdb_database" "main" { - instance_id = scaleway_rdb_instance.main.id + instance_id = scaleway_rdb_instance.main.id name = "hn-database" } @@ -252,14 +252,14 @@ If you do not want to use Terraform, you can also create the required resources } resource "scaleway_rdb_privilege" "mnq_user_role" { - instance_id = scaleway_rdb_instance.main.id + instance_id = scaleway_rdb_instance.main.id user_name = scaleway_rdb_user.worker.name database_name = scaleway_rdb_database.main.name permission = "all" } ``` 6. Add the code below to provision the functions resources. First, activate the namespace, then locally zip the code and create the functions in the cloud. Note that we are referencing variables from other resources, to completely automate the deployment process: - ``` + ```hcl locals { scraper_folder_path = "../scraper" consumer_folder_path = "../consumer" @@ -354,17 +354,17 @@ If you do not want to use Terraform, you can also create the required resources } } ``` - Note that a folder `archives` needs to be created manually if you started from scratch. It is included in the git repository. -7. Add the code below to provision the triggers resources. The cron trigger activates at the minutes `[0, 15, 30, 45]` of every hour. No arguments are passed, but we could do so by specifying them in JSON format in the `args` parameter. - ``` + Note that a folder `archives` needs to be created manually if you started from scratch. It is included in the git repository. +7. Add the code below to provision the triggers resources. The cron trigger activates at the minutes `[0, 15, 30, 45]` of every hour. No arguments are passed, but we could do so by specifying them in JSON format in the `args` parameter. + ```hcl resource "scaleway_function_cron" "scraper_cron" { - function_id = scaleway_function.scraper.id + function_id = scaleway_function.scraper.id schedule = "0,15,30,45 * * * *" args = jsonencode({}) } resource "scaleway_function_trigger" "consumer_sqs_trigger" { - function_id = scaleway_function.consumer.id + function_id = scaleway_function.consumer.id name = "hn-sqs-trigger" sqs { project_id = scaleway_mnq_sqs.main.project_id @@ -378,7 +378,7 @@ Terraform makes this very straightforward. To provision all the resources and ge ``` cd terraform terraform init -terraform plan +terraform plan terraform apply ``` @@ -386,14 +386,14 @@ terraform apply Go to the [Scaleway console](https://console.scaleway.com/), and check the logs and metrics for Serverless Functions' execution and Messaging and Queuing SQS queue statistics. -To make sure the data is correctly stored in the database, you can [connect to it directly](/managed-databases/postgresql-and-mysql/how-to/connect-database-instance/) via a CLI tool such as `psql`. +To make sure the data is correctly stored in the database, you can [connect to it directly](/managed-databases/postgresql-and-mysql/how-to/connect-database-instance/) via a CLI tool such as `psql`. Retrieve the instance IP and port of your Managed Database from the console, under the [Managed Database section](https://console.scaleway.com/rdb/instances). Use the following command to connect to your database. When prompted for a password, you can find it by running `terraform output -json`. ``` psql -h --port -d hn-database -U worker ``` -When you are done testing, don't forget to clean up! To do so, run: +When you are done testing, don't forget to clean up! To do so, run: ``` cd terraform terraform destroy @@ -405,7 +405,7 @@ We have shown how to asynchronously decouple the producer and the consumer using While the volume of data processed in this example is quite small, thanks to the Messaging and Queuing SQS queue's robustness and the auto-scaling capabilities of the Serverless Functions, you can adapt this example to manage larger workloads. Here are some possible extensions to this basic example: - - Replace the simple proposed logic with your own. What about counting how many times some keywords (e.g: copilot, serverless, microservice) appear in Hacker News articles? + - Replace the simple proposed logic with your own. What about counting how many times some keywords (e.g: copilot, serverless, microservice) appear in Hacker News articles? - Define multiple cron triggers for different websites and pass the website as an argument to the function. Or, create multiple functions that feed the same queue. - Use a [Serverless Container](/serverless/containers/quickstart/) instead of the consumer function, and use a command line tool such as `htmldoc` or `pandoc` to convert the scraped articles to PDF and upload the result to a [Scaleway Object Storage](/storage/object/quickstart/) S3 bucket. - Replace the Managed Database for PostgreSQL with a [Scaleway Serverless Database](/serverless/sql-databases/quickstart/), so that all the infrastructure lives in the serverless ecosystem! *Note that at the moment there is no Terraform support for Serverless Database, hence the choice here to use Managed Database for PostgreSQL*. \ No newline at end of file diff --git a/tutorials/deploy-laravel-on-serverless-containers/index.mdx b/tutorials/deploy-laravel-on-serverless-containers/index.mdx index ff3827cec5..9f1374f2d9 100644 --- a/tutorials/deploy-laravel-on-serverless-containers/index.mdx +++ b/tutorials/deploy-laravel-on-serverless-containers/index.mdx @@ -7,7 +7,7 @@ content: paragraph: This tutorial provides a step-by-step guide for deploying a containerized Laravel application on the Scaleway cloud platform. tags: laravel php docker nginx fpm hero: assets/scaleway-umami.webp -categories: +categories: - containers - container-registry dates: @@ -42,7 +42,7 @@ Laravel applications make use of [queues](https://laravel.com/docs/10.x/queues) 2. Create a queue. In this example, we create a `Standard` queue (At-least-once delivery, the order of messages is not preserved) with the default parameters. This queue will be the default queue used by our application. - + 3. Generate credentials. In this example, we generate the credentials with `read` and `write` access. @@ -53,7 +53,7 @@ In this section, we will focus on building the containerized image. With Docker, 1. Create the Dockerfile: we create a `Dockerfile` which is a text file that contains instructions for Docker to build the image. In this example, we specify the base image as `php:fpm-alpine`, install and enable the necessary php dependencies with [`install-php-extensions`](https://github.com/mlocati/docker-php-extension-installer), and determine the commands to be executed at startup. - ``` + ```dockerfile # Dockerfile FROM --platform=linux/amd64 php:8.2.6-fpm-alpine3.18 @@ -84,9 +84,9 @@ In this section, we will focus on building the containerized image. With Docker, CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] ``` 2. Create the supervisor configuration file. [Supervisor](http://supervisord.org/) is a reliable and efficient process control system for managing and monitoring processes. This is used as multiple processes are running within the container. In this example, we create a `stubs/supervisor/supervisord.conf` file with the following configuration to start the web server Nginx, the php-fpm pool, and 5 workers: - ``` + ```conf # stubs/supervisor/supervisord.conf - [supervisord] + [supervisord] nodaemon=true logfile=/dev/null logfile_maxbytes=0 @@ -128,43 +128,43 @@ In this section, we will focus on building the containerized image. With Docker, 3. Create web server configuration files. Nginx will be used to serve the static assets and to forward the requests to the php-fpm pool for processing. In this example, we create the following configuration files `stubs/nginx/http.d/default.conf` and `stubs/nginx/nginx.conf`. - ``` + ```hcl # stubs/nginx/http.d/default.conf server { listen 80; listen [::]:80; server_name _; root /var/www/html/public; - + add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; - + index index.php; - + charset utf-8; - + location / { try_files $uri $uri/ /index.php?$query_string; } - + location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } - + error_page 404 /index.php; - + location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } - + location ~ /\.(?!well-known).* { deny all; } } ``` - ``` + ```hcl # stubs/nginx/nginx.conf error_log /var/log/nginx/error.log notice; events { @@ -183,11 +183,11 @@ In this section, we will focus on building the containerized image. With Docker, pid /var/run/nginx.pid; user nginx; worker_processes auto; - ``` + ``` 4. Create the php-fpm configuration file. The configuration `stubs/php/php-fpm.d/zz-docker.conf` file should be created, and the php-fpm pool configured to render the dynamic pages of the Laravel application. Depending on the needs of your application, you might have to fine-tune the configuration of the process manager. Further information is available in the [php manual](https://www.php.net/manual/en/install.fpm.configuration.php). - - ``` + + ```conf [global] daemonize = no @@ -197,27 +197,27 @@ In this section, we will focus on building the containerized image. With Docker, listen.group = www-data listen.mode = 0660 - pm = dynamic - pm.max_children = 75 - pm.start_servers = 10 - pm.min_spare_servers = 5 - pm.max_spare_servers = 20 + pm = dynamic + pm.max_children = 75 + pm.start_servers = 10 + pm.min_spare_servers = 5 + pm.max_spare_servers = 20 pm.process_idle_timeout = 10s ``` 5. Build the docker image. - ``` + ```sh docker build -t my-image . ``` -## Creating Container Registry +## Creating Container Registry 1. [Create a Scaleway Container Registry namespace](/containers/container-registry/how-to/create-namespace/) in the `PAR` region. Set the visibility to `Private` to avoid having your container retrieved without proper authentication and authorization. 2. Run the following command in your local terminal to log in to the newly created Container Registry. - ``` + ```sh docker login rg.fr-par.scw.cloud/namespace-zen-feistel -u nologin --password-stdin <<< "$SCW_SECRET_KEY" ``` @@ -226,8 +226,8 @@ In this section, we will focus on building the containerized image. With Docker, 3. Tag the image and push it to the Container Registry namespace. - - ``` + + ```sh docker tag my-image rg.fr-par.scw.cloud/namespace-zen-feistel/my-image:v1 docker push rg.fr-par.scw.cloud/namespace-zen-feistel/my-image:v1 ``` @@ -237,7 +237,7 @@ In this section, we will focus on building the containerized image. With Docker, The Scaleway documentation website provides a Quickstart on how to [create and manage a Serverless Container Namespace](/serverless/containers/quickstart/). 1. Create a Serverless Containers namespace. In this example, we create the `my-laravel-application` namespace and configure the environment variables and secrets necessary for our application. In particular, we must add all the variables needed to connect to the previously created SQS/SNS queue. - + By default, Laravel expects the following environment variables/secrets to be filled in for queues: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_DEFAULT_REGION`, `QUEUE_CONNECTION`, `SQS_PREFIX` and `SQS_QUEUE`. 2. Deploy the application. Click **+ Deploy a Container** once the namespace is created, and follow the instructions of the creation wizard. Select the registry namespace and the previously uploaded Docker image and configure the listening port (the Nginx web server is listening on port 80). For the CPU and memory, define at least 560mVPCU and 256 MB respectively. To reduce the limitations due to [cold start](/serverless/containers/concepts/#cold-start), we will run at least 1 instance. @@ -274,7 +274,7 @@ By default, some metrics will be available in the Scaleway console. However, to To test the load on the application, there is a basic test route that pushes a job into the queue and returns the welcome page. -``` php +```php # routes/web.php use App\Jobs\ProcessPodcast; @@ -287,7 +287,7 @@ Route::get('/test', function () { ``` The job does nothing but wait for a couple of seconds. -``` php +```php # app/Jobs/ProcessPodcast class ProcessPodcast implements ShouldQueue @@ -300,11 +300,11 @@ class ProcessPodcast implements ShouldQueue ``` Then, use `hey` to send 400 requests (20 concurrent requests) to this route. -``` +```sh hey -n 400 -q 20 https://example.com/test ``` -We can see that our deployment is not sufficiently sized to handle such workload and the response times are far from ideal. +We can see that our deployment is not sufficiently sized to handle such workload and the response times are far from ideal. ``` Response time histogram: diff --git a/tutorials/encode-videos-using-serverless-jobs/index.mdx b/tutorials/encode-videos-using-serverless-jobs/index.mdx index 3f68a4d1b4..01051cdcb3 100644 --- a/tutorials/encode-videos-using-serverless-jobs/index.mdx +++ b/tutorials/encode-videos-using-serverless-jobs/index.mdx @@ -21,7 +21,7 @@ This tutorial demonstrates the process of encoding videos retrieved from Object - A Scaleway account logged into the [console](https://console.scaleway.com) - [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization -- An [Object Storage bucket](/storage/object/how-to/create-a-bucket/) +- An [Object Storage bucket](/storage/object/how-to/create-a-bucket/) - A valid [API key](/identity-and-access-management/iam/how-to/create-api-keys/) - Installed [Docker engine](https://docs.docker.com/engine/install/) @@ -72,7 +72,7 @@ The initial step involves defining a Docker image for interacting with the S3 Ob This Dockerfile uses `linuxserver/ffmpeg` as a base image bundled with FFMPEG along with a variety of encoding codecs and installs [MinIO](https://min.io/) as a command-line S3 client to copy files over Object Storage. 3. Build and [push the image](/containers/container-registry/how-to/push-images/) to your Container Registry: - ``` + ```bash docker build . -t docker push ``` @@ -125,7 +125,7 @@ Once the run status is **Succeeded**, the encoded video can be found in your S3 Your job can also be triggered through the [Scaleway API](https://www.scaleway.com/en/developers/api/serverless-jobs/#path-job-definitions-run-an-existing-job-definition-by-its-unique-identifier-this-will-create-a-new-job-run) using the same environment variables: -``` +```bash curl -X POST \ -H "X-Auth-Token: " \ -H "Content-Type: application/json" \ diff --git a/tutorials/large-messages/index.mdx b/tutorials/large-messages/index.mdx index 4f851c6a4f..342ae7398b 100644 --- a/tutorials/large-messages/index.mdx +++ b/tutorials/large-messages/index.mdx @@ -4,7 +4,7 @@ meta: description: Learn how to build a serverless architecture for handling large messages with Scaleway's NATS, Serverless Functions, and Object Storage. Follow our step-by-step Terraform-based tutorial for asynchronous file conversion using messaging, functions, and triggers. content: h1: Create a serverless architecture for handling large messages using Scaleway's NATS, Serverless Functions, and Object Storage. - paragraph: Learn how to build a serverless architecture for handling large messages with Scaleway's NATS, Serverless Functions, and Object Storage. Follow our step-by-step Terraform-based tutorial for asynchronous file conversion using messaging, functions, and triggers. + paragraph: Learn how to build a serverless architecture for handling large messages with Scaleway's NATS, Serverless Functions, and Object Storage. Follow our step-by-step Terraform-based tutorial for asynchronous file conversion using messaging, functions, and triggers. categories: - messaging - functions @@ -52,7 +52,7 @@ Three essential services are required to ensure everything is working together: Remember that you can refer to the [code repository](https://github.com/rouche-q/serverless-examples/tree/main/projects/large-messages/README.md) to check all code files. - ```terraform + ```hcl terraform { required_providers { scaleway = { @@ -74,7 +74,7 @@ Three essential services are required to ensure everything is working together: The Scaleway provider is needed, but also three providers from HashiCorp that we will use later in the tutorial. 2. Include two variables to enable the secure passage of your Scaleway credentials. Then initialize the Scaleway provider in the `fr-par-1` region. - ```terraform + ```hcl variable "scw_access_key_id" { type = string sensitive = true @@ -97,7 +97,7 @@ Three essential services are required to ensure everything is working together: ``` 4. Continuing in the `main.tf` file, add the following Terraform code to create an Object Storage bucket that will be used for storing your images. - ```terraform + ```hcl resource "random_id" "bucket" { byte_length = 8 } @@ -119,7 +119,7 @@ Three essential services are required to ensure everything is working together: In this code, the resource `random_id.bucket` generates a random ID, which is then passed to the object bucket to ensure its uniqueness. Additionally, a `scaleway_object_bucket_acl` ACL is applied to the bucket, setting it to private and outputting the bucket name for use in your producer. 5. Add these resources to create a NATS account and your NATS credentials file: - ```terraform + ```hcl resource "scaleway_mnq_nats_account" "large_messages" { name = "nats-acc-large-messages" } @@ -162,7 +162,7 @@ As mentioned earlier, the producer will be implemented as a straightforward shel Our script takes the file path that we want to upload as the first parameter. To upload the file, we will use the AWS CLI configured with the Scaleway endpoint and credentials because Scaleway Object storage is fully compliant with S3. - + 3. Pass the path to the AWS CLI command as follows: ```bash aws s3 cp $1 s3://$SCW_BUCKET @@ -211,7 +211,7 @@ We continue using the Scaleway ecosystem and deploy the consumer using a Serverl ``` 5. Before proceeding with the function's logic, improve the Terraform code by adding the following code to your `main.tf` file: - ```terraform + ```hcl resource "null_resource" "install_dependencies" { provisioner "local-exec" { command = <<-EOT @@ -240,7 +240,7 @@ We continue using the Scaleway ecosystem and deploy the consumer using a Serverl The `null_resource` is used to download and package the correct versions of the libraries that we use with the function. Learn more about this in the [Scaleway documentation.](/serverless/functions/how-to/package-function-dependencies-in-zip/#specific-libraries-(with-needs-for-specific-c-compiled-code)) 6. Create the function namespace. - ```terraform + ```hcl resource "scaleway_function_namespace" "large_messages" { name = "large-messages-function" description = "Large messages namespace" @@ -248,7 +248,7 @@ We continue using the Scaleway ecosystem and deploy the consumer using a Serverl ``` 7. Add the resource to set up the function. - ```terraform + ```hcl resource "scaleway_function" "large_messages" { namespace_id = scaleway_function_namespace.large_messages.id runtime = "python311" @@ -275,15 +275,15 @@ We continue using the Scaleway ecosystem and deploy the consumer using a Serverl Essential environment variables and secrets to use in our function logic are also added. 8. Create the function trigger to "wake up" the function when a NATS message comes in. - ```terraform + ```hcl resource "scaleway_function_trigger" "large_messages" { function_id = scaleway_function.large_messages.id name = "large-messages-trigger" nats { account_id = scaleway_mnq_nats_account.large_messages.id subject = "large-messages" - } - } + } + } ``` It defines which account ID and subject to observe for getting messages. @@ -364,6 +364,6 @@ terraform apply ## Conclusion, going further In this introductory tutorial, we have demonstrated the usage of the NATS server for Messaging and Queuing, along with other services from the Scaleway ecosystem, to facilitate the transfer of large messages surpassing the typical size constraints. There are possibilities to expand upon this tutorial for various use cases, such as: - + - Extending the conversion capabilities to handle different document types like `docx`. - Sending URLs directly to NATS and converting HTML content to PDF. \ No newline at end of file diff --git a/tutorials/manage-instances-with-terraform-and-functions/index.mdx b/tutorials/manage-instances-with-terraform-and-functions/index.mdx index cb04ce6113..2b68b0a2e4 100644 --- a/tutorials/manage-instances-with-terraform-and-functions/index.mdx +++ b/tutorials/manage-instances-with-terraform-and-functions/index.mdx @@ -57,7 +57,7 @@ This tutorial will simulate a project with a production environment running all -- variables.tf ``` 4. Edit the `backend.tf` file to enable remote configuration backup: - ```json + ```hcl terraform { backend "s3" { bucket = "XXXXXXXXX" @@ -78,7 +78,7 @@ This tutorial will simulate a project with a production environment running all */ ``` 5. Edit the `provider.tf` file and add Scaleway as a provider: - ```json + ```hcl terraform { required_providers { scaleway = { @@ -91,7 +91,7 @@ This tutorial will simulate a project with a production environment running all ``` 6. Specify the following variables in the `variables.tf` file: - ```json + ```hcl variable "zone" { type = string } @@ -115,7 +115,7 @@ This tutorial will simulate a project with a production environment running all } ``` 7. Add the variable values to `terraform.tfvars`: - ```bash + ```hcl zone = "fr-par-1" region = "fr-par" env = "dev" @@ -170,7 +170,7 @@ def handle(event, context): ## Configuring your infrastructure 1. Edit the file `main.tf` to add a production Instance using a GP1-S named "Prod": - ```json + ```hcl ## Configuring Producion environment resource "scaleway_instance_ip" "public_ip-prod" { project_id = var.project_id @@ -193,7 +193,7 @@ def handle(event, context): } ``` 2. Add a development Instance using a DEV1-L named "Dev": - ```json + ```hcl ## Configuring Development environment that will be automatically turn off on week-ends and turn on monday mornings resource "scaleway_instance_ip" "public_ip-dev" { project_id = var.project_id @@ -215,7 +215,7 @@ def handle(event, context): } ``` 3. Write a function that will run the code you have just written: - ```json + ```hcl # Creating function code archive that will then be updated data "archive_file" "source_zip" { type = "zip" @@ -247,7 +247,7 @@ def handle(event, context): } ``` 4. Add a cronjob attached to the function to turn your function off every Friday evening: - ```json + ```hcl # Adding a first cron to turn off the Instance every friday evening (11:30 pm) resource "scaleway_function_cron" "turn-off" { function_id = scaleway_function.main.id @@ -261,7 +261,7 @@ def handle(event, context): } ``` 5. Create a cronjob attached to the function to turn your function on every Monday morning: - ```json + ```hcl # Adding a second cron to turn on the Instance every monday morning (7:00 am) resource "scaleway_function_cron" "turn-on" { function_id = scaleway_function.main.id diff --git a/tutorials/snapshot-instances-jobs/index.mdx b/tutorials/snapshot-instances-jobs/index.mdx index 99c358473f..7b04845764 100644 --- a/tutorials/snapshot-instances-jobs/index.mdx +++ b/tutorials/snapshot-instances-jobs/index.mdx @@ -169,7 +169,7 @@ Serverless Jobs rely on containers to run in the cloud, and therefore require a 1. Create a `Dockerfile`, and add the following code to it: - ```docker + ```dockerfile # Using apline/golang image FROM golang:1.22-alpine diff --git a/tutorials/strapi-app-serverless-containers-sqldb/index.mdx b/tutorials/strapi-app-serverless-containers-sqldb/index.mdx index c416876cb1..9d5c2e76e8 100644 --- a/tutorials/strapi-app-serverless-containers-sqldb/index.mdx +++ b/tutorials/strapi-app-serverless-containers-sqldb/index.mdx @@ -42,11 +42,11 @@ You can either deploy your application: 2. Run the command below to make sure the environment variables are properly set: ```sh - scw info + scw info ``` This command displays your access key and secret key in the last two lines of the output. The `ORIGIN` column should display `env (SCW_ACCESS_KEY)` and `env (SCW_SECRET_KEY)`, and not `default profile`. - + ```bash KEY VALUE ORIGIN (...) @@ -77,16 +77,16 @@ You can either deploy your application: && psql -h $DATABASE_HOST -p $DATABASE_PORT \ -d $DATABASE_NAME -U $DATABASE_USERNAME ``` - An input field with the name of your database should display: + An input field with the name of your database should display: ``` psql (15.3, server 16.1 (Debian 16.1-1.pgdg120+1)) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_128_GCM_SHA256, compression: off) - Type "help" for help. + Type "help" for help. tutorial-strapi-blog-db=> ``` - + ### Running Strapi locally 1. Create a Strapi blog template @@ -95,7 +95,7 @@ You can either deploy your application: --dbclient=postgres --dbhost=$DATABASE_HOST \ --dbport=$DATABASE_PORT --dbname=$DATABASE_NAME \ --dbusername=$DATABASE_USERNAME \ - --dbpassword=$DATABASE_PASSWORD --dbssl=true + --dbpassword=$DATABASE_PASSWORD --dbssl=true ``` 2. Access the folder you just created: @@ -120,7 +120,7 @@ You can either deploy your application: touch Dockerfile ``` 2. Add the code below to your file, save it, and exit. - ```bash + ```docker # Creating a multi-stage build for production FROM node:20-alpine as build RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev vips-dev git > /dev/null 2>&1 @@ -189,12 +189,12 @@ You can either deploy your application: ├── jsconfig.json ├── package.json ├── README.md - └── yarn.lock + └── yarn.lock ``` 5. Build your application container: ```bash - docker build -t my-strapi-blog . + docker build -t my-strapi-blog . ``` The docker build image process can take a few minutes, particularly during the `npm install` step, since Strapi requires around 1 GB of node modules to be built. @@ -281,7 +281,7 @@ You can either deploy your application: ``` When the status appears as `ready`, you can access the Strapi Administration Panel via your browser. - + 3. Copy the endpoint URL displayed next to the `DomainName` property, and paste it into your browser. The main Strapi page displays. Click "Open the administration" or add `/admin` to your browser URL to access the Strapi Administration Panel. 4. (Optional) You can check that Strapi APIs are working with the following command, or by accessing `https://{container_url}/api/articles` in your browser: @@ -319,7 +319,7 @@ However, your Strapi container currently connects to your database with your [us To secure your deployment, we will now add a dedicated [IAM application](/identity-and-access-management/iam/concepts/#application), give it the minimum required permissions, and provide its credentials to your Strapi container. -1. Run the following command to create an [IAM application](/identity-and-access-management/iam/concepts/#application) and export it as a variable: +1. Run the following command to create an [IAM application](/identity-and-access-management/iam/concepts/#application) and export it as a variable: ```bash export SCW_APPLICATION_ID=$(scw iam application create name=tutorial-strapi-blog -o json | jq -r '.id') ``` @@ -364,10 +364,10 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi secret-environment-variables.5.value=$JWT_SECRET redeploy=true ``` -6. Refresh your browser page displaying the Strapi Administration Panel. An updated version displays. +6. Refresh your browser page displaying the Strapi Administration Panel. An updated version displays. You have now deployed a full serverless Strapi blog example! - + ## Going further with containers - Inspect your newly created resources in the Scaleway console: @@ -399,11 +399,11 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi 2. Run the command below to make sure the environment variables are properly set: ```sh - scw info + scw info ``` This command displays your access_key and secret_key in the two last lines of the output. The `ORIGIN` column should display `env (SCW_ACCESS_KEY)` and `env (SCW_SECRET_KEY)`, and not `default profile`. - + ```bash KEY VALUE ORIGIN (...) @@ -512,12 +512,12 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi ├── jsconfig.json ├── package.json ├── README.md - └── yarn.lock + └── yarn.lock ``` 8. Build your application container: ```bash - docker build -t my-strapi-blog . + docker build -t my-strapi-blog . ``` The docker build image process can take a few minutes, particularly during the `npm install` step since Strapi requires around 1 GB of node modules to be built. @@ -545,7 +545,7 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi docker push $REGISTRY_ENDPOINT/my-strapi-blog:latest ``` - + ### Creating the Terraform configuration 1. Run the following command to create a new folder to store your Terraform files, and access it: @@ -553,7 +553,7 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi cd .. mkdir terraform-strapi-blog && cd terraform-strapi-blog - ``` + ``` 2. Create an empty `main.tf` Terraform file inside the folder. @@ -565,7 +565,7 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi ``` 3. Add the following code to your `main.tf` file: - ```json + ```hcl terraform { required_providers { scaleway = { @@ -577,12 +577,12 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi } required_version = ">= 0.13" } - + variable "REGISTRY_ENDPOINT" { type = string description = "Container Registry endpoint where your application container is stored" } - + variable "DEFAULT_PROJECT_ID" { type = string description = "Project ID where your resources will be created" @@ -606,12 +606,12 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi for_each = toset(local.secrets) length = 16 } - + resource scaleway_container_namespace main { name = "tutorial-strapi-blog-tf" description = "Namespace created for full serverless Strapi blog deployment" } - + resource scaleway_container main { name = "tutorial-strapi-blog-tf" @@ -628,7 +628,7 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi privacy = "public" protocol = "http1" deploy = true - + environment_variables = { "DATABASE_CLIENT"="postgres", "DATABASE_USERNAME" = scaleway_iam_application.app.id, @@ -648,11 +648,11 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi "JWT_SECRET" = random_bytes.generated_secrets["jwt_secret"].base64 } } - + resource scaleway_iam_application "app" { name = "tutorial-strapi-blog-tf" } - + resource scaleway_iam_policy "db_access" { name = "tutorial-strapi-policy-tf" description = "Gives tutorial Strapi blog access to Serverless SQL Database" @@ -662,17 +662,17 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi permission_set_names = ["ServerlessSQLDatabaseReadWrite"] } } - + resource scaleway_iam_api_key "api_key" { application_id = scaleway_iam_application.app.id } - + resource scaleway_sdb_sql_database "database" { name = "tutorial-strapi-tf" min_cpu = 0 max_cpu = 8 } - + output "database_connection_string" { // Output as an example, you can give this string to your application value = format("postgres://%s:%s@%s", @@ -682,7 +682,7 @@ To secure your deployment, we will now add a dedicated [IAM application](/identi ) sensitive = true } - + output "container_url" { // Output as an example, you can give this string to your application value = scaleway_container.main.domain_name @@ -718,7 +718,7 @@ The Terraform file creates several resources: ``` Edit the `ADMIN_EMAIL` and `ADMIN_PASSWORD` values with your own email and password. Optionally, you can also edit `ADMIN_FIRSTNAME` and `ADMIN_LASTNAME` values to change the default admin first and last name. - Strapi admin password requires at least 8 characters including one uppercase, one lowercase, one number, and one special character. + Strapi admin password requires at least 8 characters including one uppercase, one lowercase, one number, and one special character. If the admin password or email does not meet the requirements, the container will not start. @@ -813,7 +813,7 @@ Once you are done, run the following command to stop all your resources: - **Fine-tune deployment options** such as autoscaling, targeted regions, and more. You can find more information by typing `scw container deploy --help` in your terminal, or by referring to the [dedicated documentation](/serverless/containers/how-to/manage-a-container/) - Create a secondary production environment by duplicating your built container, building it in `NODE_ENV=production` environment, running `npm run start`, and plugging it onto another **Serverless SQL Database**. For instance, this will allow you to edit content-types which is not possible in production. - + ## Troubleshooting If you happen to encounter any issues, first check that you meet all the requirements. @@ -827,7 +827,7 @@ If you happen to encounter any issues, first check that you meet all the require UpdatedAt 1 year ago Description - ``` - + You can also find and compare your Project and Organization ID in the [Scaleway console settings](https://console.scaleway.com/project/settings). - You have **Docker Engine** installed. Running the `docker -v` command in a terminal should display your currently installed docker version: From 38468c289a14a975171bbd66794507cdca23e1f1 Mon Sep 17 00:00:00 2001 From: Thomas TACQUET Date: Tue, 29 Oct 2024 10:42:26 +0100 Subject: [PATCH 56/68] feat(serverless): advanced cold starts doc (#3891) * feat(serverless): advanced cold starts doc * Apply suggestions from code review Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> --------- Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> Co-authored-by: nerda-codes <87707325+nerda-codes@users.noreply.github.com> --- serverless/containers/concepts.mdx | 9 ++++++++- serverless/functions/concepts.mdx | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/serverless/containers/concepts.mdx b/serverless/containers/concepts.mdx index f59a9ed48a..b5628f1d39 100644 --- a/serverless/containers/concepts.mdx +++ b/serverless/containers/concepts.mdx @@ -14,7 +14,14 @@ categories: ## Cold Start -Cold start is the time a container Instance takes to handle a request when it is called for the first time. +Cold start is the time a Container takes to handle a request when it is called for the first time. + +Startup process steps are: +* Downloading the container image to our infrastructure +* Starting the container. Optimize your container startup speed to minimize this step (e.g., avoid waiting for slow connections or downloading large objects at startup) +* Waiting for the containeer to listen on the configured port. + +[How to reduce cold starts](/faq/serverless-containers/#how-can-i-reduce-the-cold-starts-of-serverless-containers) ## Concurrency diff --git a/serverless/functions/concepts.mdx b/serverless/functions/concepts.mdx index 94a026da99..f15d497b0d 100644 --- a/serverless/functions/concepts.mdx +++ b/serverless/functions/concepts.mdx @@ -14,7 +14,14 @@ categories: ## Cold Start -Cold start is the time a function Instance takes to handle a request when it is called for the first time. +Cold Start is the time a Fuction takes to handle a request when it is called for the first time. + +Startup process steps are: +* Downloading the container image (which contains the built Function) to our infrastructure +* Starting the container and the runtime +* Waiting for the container to be ready. + +[How to reduce cold starts](/faq/serverless-functions/#how-to-reduce-cold-start-of-serverless-functions) ## CRON trigger From 1e81d59a5b8c37d3b09c1c3e21888fb91e71cd14 Mon Sep 17 00:00:00 2001 From: SamyOubouaziz Date: Tue, 29 Oct 2024 10:42:46 +0100 Subject: [PATCH 57/68] docs(S3): update mentions of S3 in documentation MTA-5188 (#3874) * docs(S3): update mentions of S3 in documentation MTA-5188 * Update storage/object/api-cli/installing-rclone.mdx Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> * Update storage/object/index.mdx Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> * Update storage/object/api-cli/managing-lifecycle-cliv2.mdx Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> * feat(gen): remove mentions of S3 only * docs(S3): update --------- Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> --- .../2022-01-02-registry-changed-backend.mdx | 4 +-- components/docs-editor.mdx | 2 +- .../snapshot-import-export-feature.mdx | 4 +-- .../troubleshooting/bootscript-eol.mdx | 4 +-- .../kubernetes/how-to/edit-kosmos-cluster.mdx | 2 +- faq/objectstorage.mdx | 8 +++--- .../api-cli/using-api-key-object-storage.mdx | 8 +++--- .../iam/concepts.mdx | 2 +- .../iot-hub/api-cli/iot-hub-routes.mdx | 10 +++---- managed-services/iot-hub/concepts.mdx | 2 +- .../how-to/understand-event-messages.mdx | 4 +-- .../iot-hub/reference-content/routes.mdx | 2 +- menu/navigation.json | 2 +- network/load-balancer/concepts.mdx | 2 +- .../how-to/set-up-s3-failover.mdx | 2 +- .../configuring-backends.mdx | 2 +- serverless/functions/index.mdx | 2 +- storage/object/api-cli/bucket-operations.mdx | 2 +- storage/object/api-cli/bucket-policy.mdx | 4 +-- storage/object/api-cli/bucket-website-api.mdx | 2 +- .../combining-iam-and-object-storage.mdx | 2 +- .../api-cli/installing-minio-client.mdx | 2 +- storage/object/api-cli/installing-rclone.mdx | 10 +++---- .../object/api-cli/lifecycle-rules-api.mdx | 2 +- .../api-cli/manage-bucket-permissions-ip.mdx | 2 +- .../api-cli/managing-lifecycle-cliv2.mdx | 8 +++--- storage/object/api-cli/migrating-buckets.mdx | 2 +- storage/object/api-cli/object-operations.mdx | 2 +- .../object/api-cli/object-storage-aws-cli.mdx | 2 +- storage/object/api-cli/post-object.mdx | 4 +-- storage/object/api-cli/setting-cors-rules.mdx | 2 +- .../object/api-cli/using-api-call-list.mdx | 6 ++--- storage/object/concepts.mdx | 18 ++++++++----- .../object/how-to/create-bucket-policy.mdx | 2 +- .../how-to/restore-an-object-from-glacier.mdx | 2 +- .../how-to/upload-files-into-a-bucket.mdx | 2 +- storage/object/index.mdx | 6 ++--- storage/object/quickstart.mdx | 2 +- .../optimize-object-storage-performance.mdx | 4 +-- .../s3-iam-permissions-equivalence.mdx | 26 +++++++++---------- .../troubleshooting/api-key-does-not-work.mdx | 8 +++--- .../troubleshooting/cannot-access-data.mdx | 4 +-- .../troubleshooting/cannot-delete-bucket.mdx | 2 +- .../cannot-restore-glacier.mdx | 2 +- .../lost-bucket-access-bucket-policy.mdx | 2 +- .../troubleshooting/low-performance.mdx | 4 +-- styles/scw_styles/HeadingSentenceCase.yml | 2 +- .../abort-multipart-upload-minio/index.mdx | 12 ++++----- tutorials/ceph-cluster/index.mdx | 8 +++--- .../index.mdx | 2 +- .../index.mdx | 8 +++--- tutorials/configure-plex-s3/index.mdx | 4 +-- .../index.mdx | 2 +- .../create-serverless-scraping/index.mdx | 2 +- tutorials/deploy-nextcloud-s3/index.mdx | 2 +- tutorials/deploy-saas-application/index.mdx | 10 +++---- .../index.mdx | 2 +- .../index.mdx | 22 ++++++++-------- tutorials/encrypt-s3-data-rclone/index.mdx | 10 +++---- .../index.mdx | 6 ++--- .../index.mdx | 6 ++--- tutorials/how-to-implement-rag/index.mdx | 6 ++--- tutorials/k8s-velero-backup/index.mdx | 2 +- tutorials/large-messages/index.mdx | 6 ++--- tutorials/mastodon-community/index.mdx | 4 +-- tutorials/migrate-data-minio-client/index.mdx | 6 ++--- tutorials/migrate-data-rclone/index.mdx | 2 +- tutorials/nvidia-triton/index.mdx | 4 +-- tutorials/object-storage-s3fs/index.mdx | 6 ++--- tutorials/restic-s3-backup/index.mdx | 4 +-- tutorials/s3-customize-url-cname/index.mdx | 6 ++--- .../setup-nginx-reverse-proxy-s3/index.mdx | 12 ++++----- tutorials/terraform-quickstart/index.mdx | 2 +- .../index.mdx | 14 +++++----- .../index.mdx | 8 +++--- .../veeam-backup-replication-s3/index.mdx | 12 ++++----- 76 files changed, 197 insertions(+), 193 deletions(-) diff --git a/changelog/container-registry/january2022/2022-01-02-registry-changed-backend.mdx b/changelog/container-registry/january2022/2022-01-02-registry-changed-backend.mdx index 7c36054b22..5d9fefba94 100644 --- a/changelog/container-registry/january2022/2022-01-02-registry-changed-backend.mdx +++ b/changelog/container-registry/january2022/2022-01-02-registry-changed-backend.mdx @@ -1,5 +1,5 @@ --- -title: Migration to the new S3 backend (HIVE) for all regions +title: Migration to the new Object Storage backend (HIVE) for all regions status: changed author: fullname: 'Join the #container-registry channel on Slack.' @@ -9,4 +9,4 @@ category: containers product: container-registry --- -All regions were migrated to the new S3 backend (HIVE) and are now using its highly redundant #MultiAZ infrastructure in `FR-PAR`. As a result, almost all recent issues regarding the registry are resolved. \ No newline at end of file +All regions were migrated to the new Object Storage backend (HIVE) and are now using its highly redundant #MultiAZ infrastructure in `FR-PAR`. As a result, almost all recent issues regarding the registry are resolved. \ No newline at end of file diff --git a/components/docs-editor.mdx b/components/docs-editor.mdx index 26da9e23e1..626c7df263 100644 --- a/components/docs-editor.mdx +++ b/components/docs-editor.mdx @@ -259,7 +259,7 @@ At top of `.mdx` file, you MUST add data in frontmatter: ``` --- -title: Migration to the new S3 backend (HIVE) for all regions +title: Migration to the new Object Storage backend (HIVE) for all regions status: changed author: fullname: 'Join the #container-registry channel on Slack.' diff --git a/compute/instances/api-cli/snapshot-import-export-feature.mdx b/compute/instances/api-cli/snapshot-import-export-feature.mdx index 9dd5a91819..c7d0305e8c 100644 --- a/compute/instances/api-cli/snapshot-import-export-feature.mdx +++ b/compute/instances/api-cli/snapshot-import-export-feature.mdx @@ -35,7 +35,7 @@ More information on the QCOW2 file format, and how to use it can be found in the 1. Create a Scaleway Object Storage bucket. - You need an S3 bucket to export your QCOW2 file into. Any bucket that belongs to the same project as the snapshot can be used. However, if you do not have one already, you can [create it](/storage/object/how-to/create-a-bucket/) in the console. + You need an Object Storage bucket to export your QCOW2 file into. Any bucket that belongs to the same project as the snapshot can be used. However, if you do not have one already, you can [create it](/storage/object/how-to/create-a-bucket/) in the console. 2. Create a snapshot from a volume. To use this functionality, you must [create a snapshot](/compute/instances/how-to/create-a-snapshot/#how-to-create-a-snapshot) from the volume you want to export. @@ -53,7 +53,7 @@ More information on the QCOW2 file format, and how to use it can be found in the - The secret key of your API key pair (``) - The snapshot ID (``) - The name of the Object Storage bucket to store the snapshot (which has to exist in the same Scaleway region as the snapshot) - - A key (can be any acceptable key/object name for Scaleway S3 (suffixing qcow2 images with `.qcow2`)) + - A key (can be any acceptable key/object name for Scaleway Object Storage (suffixing qcow2 images with `.qcow2`)) The API returns an output as in the following example: ```json diff --git a/compute/instances/troubleshooting/bootscript-eol.mdx b/compute/instances/troubleshooting/bootscript-eol.mdx index 8bb1b5c1dc..2fb72ee52a 100644 --- a/compute/instances/troubleshooting/bootscript-eol.mdx +++ b/compute/instances/troubleshooting/bootscript-eol.mdx @@ -90,10 +90,10 @@ If your Instance is using the bootscript option to boot in normal mode you are i - #### Create a snapshot of the volume(s) and export it to S3 to retrieve the data + #### Create a snapshot of the volume(s) and export it to Object Storage to retrieve the data 1. [Create a snapshot](/compute/instances/how-to/create-a-snapshot/) of the volume using the **l_ssd** type of snapshot. - 2. [Export](/compute/instances/how-to/snapshot-import-export-feature/) the snapshot to an S3 bucket in the same region as the Instance. + 2. [Export](/compute/instances/how-to/snapshot-import-export-feature/) the snapshot to an Object Storage bucket in the same region as the Instance. 3. Retrieve your data from the Object Storage bucket and reuse it at your convenience. 4. Delete the old Instance that was using a bootscript once you have recovered your data. diff --git a/containers/kubernetes/how-to/edit-kosmos-cluster.mdx b/containers/kubernetes/how-to/edit-kosmos-cluster.mdx index 1128a4d8a9..80d3553236 100644 --- a/containers/kubernetes/how-to/edit-kosmos-cluster.mdx +++ b/containers/kubernetes/how-to/edit-kosmos-cluster.mdx @@ -111,7 +111,7 @@ In order to add external nodes to your multi-cloud cluster, you must first [crea The Kubernetes version of the existing nodes in your multi-cloud pool can be upgraded in place. Your workload will theoretically keep running during the upgrade, but it is best to drain the node before the upgrade. 1. In the Pools section of your Kosmos cluster, click **Upgrade** next to the node pool. This will not cause any of your existing nodes to upgrade, but will instead ensure that any new nodes added to the pool will start up with the newer version. -2. Run the installer program as you would do for a fresh node install, with the additional option `-self-update`. If the option is not available, redownload the program from S3 bucket. +2. Run the installer program as you would do for a fresh node install, with the additional option `-self-update`. If the option is not available, redownload the program from the Object Storage bucket. 3. Now the node will register itself with the Apiserver. Once it is ready, you will see the same node with two kubelet versions. The older node should end up `NotReady` after 5m, you can safely delete it with `kubectl`. 4. Detach the older node in Scaleway API. diff --git a/faq/objectstorage.mdx b/faq/objectstorage.mdx index 24ac111baa..cefbf7572a 100644 --- a/faq/objectstorage.mdx +++ b/faq/objectstorage.mdx @@ -1,7 +1,7 @@ --- meta: title: Object Storage FAQ - description: Discover S3 Object Storage. + description: Discover Scaleway Object Storage. content: h1: Object Storage hero: assets/objectstorage.webp @@ -13,14 +13,14 @@ category: storage ## What is Object Storage? -Object Storage is a service based on the S3 protocol. It allows you to store any kind of object (documents, images, videos, etc.). +Object Storage is a service based on the Amazon S3 protocol. It allows you to store any kind of object (documents, images, videos, etc.). Scaleway provides an integrated UI in the [console](https://console.scaleway.com) for convenience. As browsing infinite storage through the web requires some technical trade-offs, some actions are limited in the console for Object Storage: - batch deletion is limited to 1000 objects. - empty files are not reported as empty folders. -We provide an S3-compatible API for programmatic access or usage with any compatible software. Therefore, we recommend using dedicated tools such as `s3cmd` to manage large data sets. +We provide an Amazon Amazon S3-compatible API for programmatic access or usage with any compatible software. Therefore, we recommend using dedicated tools such as `s3cmd` to manage large data sets. ## How am I billed for Object Storage? @@ -283,4 +283,4 @@ Large objects can be uploaded using [multipart uploads](/storage/object/api-cli/ Yes, a best practice is to create a [lifecycle rule](/storage/object/how-to/manage-lifecycle-rules/) targeting all objects in the bucket, or using a filter with an empty prefix. In this case, all files contained within the selected bucket will have their storage class altered automatically on the dates stipulated by you. -However, due to S3 Protocol restrictions, a lifecycle rule cannot be created to modify the storage class from Glacier to Standard. \ No newline at end of file +However, due to some restrictions on Amazon's S3 protocol, a lifecycle rule cannot be created to modify the storage class from Glacier to Standard. \ No newline at end of file diff --git a/identity-and-access-management/iam/api-cli/using-api-key-object-storage.mdx b/identity-and-access-management/iam/api-cli/using-api-key-object-storage.mdx index 755832cf23..4fb19e53ca 100644 --- a/identity-and-access-management/iam/api-cli/using-api-key-object-storage.mdx +++ b/identity-and-access-management/iam/api-cli/using-api-key-object-storage.mdx @@ -5,7 +5,7 @@ meta: content: h1: Using IAM API keys with Object Storage paragraph: This page explains how to use IAM API keys with Object Storage -tags: API key Projects IAM API-key Preferred-project Object-Storage S3 +tags: API key Projects IAM API-key Preferred-project Object-Storage Amazon-S3 dates: validation: 2024-05-27 posted: 2022-11-02 @@ -15,7 +15,7 @@ categories: You can carry out actions on Scaleway Object Storage resources either via the [Scaleway console](https://console.scaleway.com/), or via a third-party API or CLI, such as [the AWS CLI](/storage/object/api-cli/object-storage-aws-cli/), [MinIOClient](/storage/object/api-cli/installing-minio-client/) or [Rclone](/storage/object/api-cli/installing-rclone/). -While the Scaleway console gives you the option to specify the [Scaleway Project](#what-is-a-project) to carry out your Object Storage actions in, this option is not available via third-party API/CLI tools. These tools are based on a [standard S3 programming interface](https://en.wikipedia.org/wiki/Amazon_S3#S3_API_and_competing_services), which does not accept Project ID as a parameter. Therefore, when you create a Scaleway API key with IAM, you are prompted to specify the API key's **preferred Project for Object Storage**. This API key will always use this Project when carrying out Object Storage actions via any API/CLI. +While the Scaleway console gives you the option to specify the [Scaleway Project](#what-is-a-project) to carry out your Object Storage actions in, this option is not available via third-party API/CLI tools. These tools are based on a [standard Amazon S3 programming interface](https://en.wikipedia.org/wiki/Amazon_S3#S3_API_and_competing_services), which does not accept Project ID as a parameter. Therefore, when you create a Scaleway API key with IAM, you are prompted to specify the API key's **preferred Project for Object Storage**. This API key will always use this Project when carrying out Object Storage actions via any API/CLI. In this document, we explain the concept of preferred Projects for Object Storage, explain how to configure your IAM API key for this, and give some code examples for overriding the preferred Project when making an API call. @@ -35,13 +35,13 @@ When you generate an API key with IAM, the key is associated with a specific [IA ## The impact of preferred Projects -When you perform an action on Scaleway Object Storage resources using a third-party API or CLI, such as [the AWS CLI](/storage/object/api-cli/object-storage-aws-cli/), [MinIOClient](/storage/object/api-cli/installing-minio-client/) or [Rclone](/storage/object/api-cli/installing-rclone/), you are using tools based on a [standard S3 programming interface](https://en.wikipedia.org/wiki/Amazon_S3#S3_API_and_competing_services). This standard interface does not accept Project ID as a parameter. Therefore, when you create a Scaleway API key with IAM, you are prompted to specify the API key's **preferred Project for Object Storage**. This API key will always use this Project when carrying out Object Storage actions via any API/CLI. The preferred Project is specified when creating the API key (or can be edited at a later date). +When you perform an action on Scaleway Object Storage resources using a third-party API or CLI, such as [the AWS CLI](/storage/object/api-cli/object-storage-aws-cli/), [MinIOClient](/storage/object/api-cli/installing-minio-client/) or [Rclone](/storage/object/api-cli/installing-rclone/), you are using tools based on a [standard Amazon S3 programming interface](https://en.wikipedia.org/wiki/Amazon_S3#S3_API_and_competing_services). This standard interface does not accept Project ID as a parameter. Therefore, when you create a Scaleway API key with IAM, you are prompted to specify the API key's **preferred Project for Object Storage**. This API key will always use this Project when carrying out Object Storage actions via any API/CLI. The preferred Project is specified when creating the API key (or can be edited at a later date). Setting the preferred Project does not automatically give the API key bearer permissions for Object Storage in this Project. Ensure that the user/application is either the Owner of the Organization, or has a [policy](/identity-and-access-management/iam/concepts/#policy) giving them appropriate permissions for Object Storage in this Project. Note that the application of Object Storage permissions can take up to 5 minutes after creating a new rule or policy. -When using the S3 CLI: +When using the AWS S3 CLI: - An action of listing the buckets (`aws s3 ls`) will list the buckets of the preferred Project - An action of creating a bucket (`aws s3 mb`) will create a new bucket inside the preferred Project - An action of moving an object from a bucket to another (`aws s3 mv source destination`) will only work if the source bucket and the destination buckets are in the preferred Project for an API key diff --git a/identity-and-access-management/iam/concepts.mdx b/identity-and-access-management/iam/concepts.mdx index 617e1e057b..54c9b71573 100644 --- a/identity-and-access-management/iam/concepts.mdx +++ b/identity-and-access-management/iam/concepts.mdx @@ -95,7 +95,7 @@ For each policy rule, you specify one or more permission sets (e.g. "list all In ## Preferred Project -You can carry out actions on Scaleway Object Storage resources either via the [Scaleway console](https://console.scaleway.com), or via a third-party API or CLI, such as [the AWS CLI](/storage/object/api-cli/object-storage-aws-cli/), [MinIOClient](/storage/object/api-cli/installing-minio-client/) or [Rclone](/storage/object/api-cli/installing-rclone/). While the Scaleway console gives you the option to specify the [Scaleway Project](#what-is-a-project) to carry out your Object Storage actions in, this option is not available via third-party API/CLI tools. These tools are based on a [standard S3 programming interface](https://en.wikipedia.org/wiki/Amazon_S3#S3_API_and_competing_services), which does not accept Project ID as a parameter. Therefore, when you create a Scaleway API key with IAM, you are prompted to specify the API key's **preferred Project for Object Storage**. This API key will always use this Project when carrying out Object Storage actions via any API/CLI. See our page on [using API keys with Object Storage](/identity-and-access-management/iam/api-cli/using-api-key-object-storage/) for more information. +You can carry out actions on Scaleway Object Storage resources either via the [Scaleway console](https://console.scaleway.com), or via a third-party API or CLI, such as [the AWS CLI](/storage/object/api-cli/object-storage-aws-cli/), [MinIOClient](/storage/object/api-cli/installing-minio-client/) or [Rclone](/storage/object/api-cli/installing-rclone/). While the Scaleway console gives you the option to specify the [Scaleway Project](#what-is-a-project) to carry out your Object Storage actions in, this option is not available via third-party API/CLI tools. These tools are based on a [standard Amazon S3 programming interface](https://en.wikipedia.org/wiki/Amazon_S3#S3_API_and_competing_services), which does not accept Project ID as a parameter. Therefore, when you create a Scaleway API key with IAM, you are prompted to specify the API key's **preferred Project for Object Storage**. This API key will always use this Project when carrying out Object Storage actions via any API/CLI. See our page on [using API keys with Object Storage](/identity-and-access-management/iam/api-cli/using-api-key-object-storage/) for more information. ## Principal diff --git a/managed-services/iot-hub/api-cli/iot-hub-routes.mdx b/managed-services/iot-hub/api-cli/iot-hub-routes.mdx index e195ce3c37..5e1fd555b8 100644 --- a/managed-services/iot-hub/api-cli/iot-hub-routes.mdx +++ b/managed-services/iot-hub/api-cli/iot-hub-routes.mdx @@ -9,7 +9,7 @@ categories: - managed-services dates: validation: 2024-04-22 -tags: iot iot-hub mqtt cli s3cmd s3 +tags: iot iot-hub mqtt cli s3cmd amazon-s3 --- Routes are integrations with the Scaleway ecosystem: they can forward MQTT messages to Scaleway services. @@ -26,9 +26,9 @@ Routes are integrations with the Scaleway ecosystem: they can forward MQTT messa - Installed the [Scaleway CLI](https://github.com/scaleway/scaleway-cli#scaleway-cli-v2) and [read the accompanying IoT document](/managed-services/iot-hub/api-cli/getting-started-with-iot-hub-cli/) - Installed and configured [`s3cmd`](/tutorials/s3cmd/) for Scaleway -## S3 Routes +## Amazon S3 Routes -The S3 route allows you to put the payload of MQTT messages directly into Scaleway's Object Storage. +The Amazon S3 route allows you to put the payload of MQTT messages directly into Scaleway's Object Storage. This section is a continuation of the [Iot Hub CLI quickstart](/managed-services/iot-hub/api-cli/getting-started-with-iot-hub-cli/). Make sure to follow the quickstart before beginning. @@ -41,9 +41,9 @@ The S3 route allows you to put the payload of MQTT messages directly into Scalew PREFIX="iot/messages" # Create the bucket s3cmd mb --region "$REGION" "s3://$BUCKET" - # Grant write access to IoT Hub S3 Route Service to your bucket + # Grant write access to IoT Hub Amazon S3 Route Service to your bucket s3cmd setacl --region "$REGION" "s3://$BUCKET" --acl-grant=write:555c69c3-87d0-4bf8-80f1-99a2f757d031:555c69c3-87d0-4bf8-80f1-99a2f757d031 - # Create the IoT Hub S3 Route + # Create the IoT Hub Amazon S3 Route scw iot route create \ hub-id=$(jq -r '.id' hub.json) \ name=route-s3-cli topic="hello/world" \ diff --git a/managed-services/iot-hub/concepts.mdx b/managed-services/iot-hub/concepts.mdx index ff81fc3302..f18f18d565 100644 --- a/managed-services/iot-hub/concepts.mdx +++ b/managed-services/iot-hub/concepts.mdx @@ -96,7 +96,7 @@ Increasing the QoS level decreases message throughput because of the additional ## Routes -IoT Routes forward messages to non publish/subscribe destinations such as databases, REST APIs, Serverless functions and S3 buckets. See [Understanding Routes](/managed-services/iot-hub/reference-content/routes/) for further information. +IoT Routes forward messages to non publish/subscribe destinations such as databases, REST APIs, Serverless functions and Object Storage buckets. See [Understanding Routes](/managed-services/iot-hub/reference-content/routes/) for further information. ## TLS diff --git a/managed-services/iot-hub/how-to/understand-event-messages.mdx b/managed-services/iot-hub/how-to/understand-event-messages.mdx index 46baac3f28..8aee54ccf3 100644 --- a/managed-services/iot-hub/how-to/understand-event-messages.mdx +++ b/managed-services/iot-hub/how-to/understand-event-messages.mdx @@ -60,9 +60,9 @@ This section shows you the types of message that can be received in IoT Hub Even ## Route messages -### S3 route errors +### Amazon S3 route errors - `"'BUCKET_NAME' s3 bucket write failed. Error HTTP_STATUS_CODE: ERROR_CODE (request-id: REQUEST_ID)"`: - The route failed to write to the specified s3 bucket. + The route failed to write to the specified Object Storage bucket. `BUCKET_NAME` is the name of the bucket route attempt to write to, `HTTP_STATUS_CODE` and `ERROR_CODE` are standard [S3 error codes](https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) ## Database errors diff --git a/managed-services/iot-hub/reference-content/routes.mdx b/managed-services/iot-hub/reference-content/routes.mdx index f454f94c51..d45c10046c 100644 --- a/managed-services/iot-hub/reference-content/routes.mdx +++ b/managed-services/iot-hub/reference-content/routes.mdx @@ -8,7 +8,7 @@ content: excerpt: | This page provides detailed information about Scaleway IoT Hub Routes. totalTime: PT5M -tags: iot iot-hub route s3 database postgres postgresql mysql rest api inference +tags: iot iot-hub route amazon-s3 database postgres postgresql mysql rest api inference dates: validation: 2024-05-06 posted: 2021-08-31 diff --git a/menu/navigation.json b/menu/navigation.json index 5f50e35e44..1d706b7314 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -4437,7 +4437,7 @@ "slug": "optimize-object-storage-performance" }, { - "label": "Equivalence between S3 actions and IAM permissions", + "label": "Equivalence between Object Storage actions and IAM permissions", "slug": "s3-iam-permissions-equivalence" } ], diff --git a/network/load-balancer/concepts.mdx b/network/load-balancer/concepts.mdx index 13fd072fa4..fa28cab6d8 100644 --- a/network/load-balancer/concepts.mdx +++ b/network/load-balancer/concepts.mdx @@ -159,7 +159,7 @@ See [balancing-methods](#balancing-methods). Routes allow you to specify, for a given frontend, which of its backends it should direct traffic to. For [HTTP](#protocol) frontends/backends, routes are based on HTTP Host headers. For [TCP](#protocol) frontends/backends, they are based on **S**erver **N**ame **I**dentification (SNI). You can configure multiple routes on a single Load Balancer. -## S3 failover +## Object Storage failover See [customized error page](#customized-error-page) diff --git a/network/load-balancer/how-to/set-up-s3-failover.mdx b/network/load-balancer/how-to/set-up-s3-failover.mdx index 9480263afd..7f1cdb3fcb 100644 --- a/network/load-balancer/how-to/set-up-s3-failover.mdx +++ b/network/load-balancer/how-to/set-up-s3-failover.mdx @@ -5,7 +5,7 @@ meta: content: h1: How to configure a customized error page paragraph: This page explains how to configure a customized error page for your Load Balancer, using the Scaleway Object Storage Bucket Website feature -tags: s3-failover s3 failover load-balancer object-storage bucket +tags: s3-failover amazon-s3 failover load-balancer object-storage bucket dates: validation: 2024-05-26 posted: 2022-02-21 diff --git a/network/load-balancer/reference-content/configuring-backends.mdx b/network/load-balancer/reference-content/configuring-backends.mdx index ea5bfd099a..39a86d75a1 100644 --- a/network/load-balancer/reference-content/configuring-backends.mdx +++ b/network/load-balancer/reference-content/configuring-backends.mdx @@ -159,7 +159,7 @@ Benefits of this feature include: - Providing information on service status or maintenance - Redirecting to a mirrored site or skeleton site -Note that when entering the S3 link to redirect to, the URL of the bucket endpoint is not sufficient. The bucket website URL is specifically required (e.g.`https://my-bucket.s3-website.nl-ams.scw.cloud`). See our [dedicated documentation](/network/load-balancer/how-to/set-up-s3-failover/) for further help. +Note that when entering the Object Storage link to redirect to, the URL of the bucket endpoint is not sufficient. The bucket website URL is specifically required (e.g.`https://my-bucket.s3-website.nl-ams.scw.cloud`). See our [dedicated documentation](/network/load-balancer/how-to/set-up-s3-failover/) for further help. ## Health checks diff --git a/serverless/functions/index.mdx b/serverless/functions/index.mdx index 31272f77d7..4a5baab212 100644 --- a/serverless/functions/index.mdx +++ b/serverless/functions/index.mdx @@ -64,7 +64,7 @@ meta: label="Read more" /> diff --git a/storage/object/api-cli/bucket-operations.mdx b/storage/object/api-cli/bucket-operations.mdx index 1c8aeacfa2..29e67fb235 100644 --- a/storage/object/api-cli/bucket-operations.mdx +++ b/storage/object/api-cli/bucket-operations.mdx @@ -668,7 +668,7 @@ aws s3api put-bucket-versioning --bucket BucketName ## PutBucketPolicy -This operation applies an S3 bucket policy to an S3 bucket. +This operation applies an Object Storage bucket policy to an Object Storage bucket. If the operation is successful, no output will be returned. diff --git a/storage/object/api-cli/bucket-policy.mdx b/storage/object/api-cli/bucket-policy.mdx index 8a29db9252..cfbb255055 100644 --- a/storage/object/api-cli/bucket-policy.mdx +++ b/storage/object/api-cli/bucket-policy.mdx @@ -362,7 +362,7 @@ Bucket policies use a JSON-based access policy language and are composed of stri ### Action **Description** -: Consists of an S3 namespace, a colon, and the name of an action. Action names can include wildcards represented by `*`. +: Consists of an Amazon S3 namespace, a colon, and the name of an action. Action names can include wildcards represented by `*`. **Required** : Yes @@ -451,7 +451,7 @@ Bucket policies use a JSON-based access policy language and are composed of stri ### Resource **Description** -: Consists in the S3 resource path. +: Consists in the Amazon S3 resource path. **Required** : Yes diff --git a/storage/object/api-cli/bucket-website-api.mdx b/storage/object/api-cli/bucket-website-api.mdx index 537142da84..51852b3e07 100644 --- a/storage/object/api-cli/bucket-website-api.mdx +++ b/storage/object/api-cli/bucket-website-api.mdx @@ -179,7 +179,7 @@ If you want your website to be accessible, you need to set up a bucket policy. ### Configuring your URL -You can access your website using the website endpoint of your bucket, generated by s3 under the default format: +You can access your website using the website endpoint of your bucket, generated by Amazon S3 under the default format: `https://.s3-website..scw.cloud` diff --git a/storage/object/api-cli/combining-iam-and-object-storage.mdx b/storage/object/api-cli/combining-iam-and-object-storage.mdx index 72d993fa08..d01825e3c9 100644 --- a/storage/object/api-cli/combining-iam-and-object-storage.mdx +++ b/storage/object/api-cli/combining-iam-and-object-storage.mdx @@ -5,7 +5,7 @@ meta: content: h1: Combining IAM and bucket policies to set up granular access to Object Storage paragraph: Integrate IAM with Scaleway Object Storage for enhanced access control. -tags: object storage command bucket s3 iam permissions acl policy +tags: object storage command bucket amazon-s3 iam permissions acl policy dates: validation: 2024-05-14 posted: 2023-01-17 diff --git a/storage/object/api-cli/installing-minio-client.mdx b/storage/object/api-cli/installing-minio-client.mdx index eb2d6991cb..832e0c645d 100644 --- a/storage/object/api-cli/installing-minio-client.mdx +++ b/storage/object/api-cli/installing-minio-client.mdx @@ -14,7 +14,7 @@ categories: - object-storage --- -The [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html) (`mc`) is a command-line tool that allows you to manage your s3 projects, providing a modern alternative to UNIX commands. +The [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html) (`mc`) is a command-line tool that allows you to manage your Object Storage projects, providing a modern alternative to UNIX commands. diff --git a/storage/object/api-cli/installing-rclone.mdx b/storage/object/api-cli/installing-rclone.mdx index 754693cc3e..3e85740fc3 100644 --- a/storage/object/api-cli/installing-rclone.mdx +++ b/storage/object/api-cli/installing-rclone.mdx @@ -14,7 +14,7 @@ categories: - object-storage --- -[Rclone](https://rclone.org) is a command-line tool that can be used to manage your cloud storage. It communicates with any S3-compatible cloud storage provider as well as other storage platforms. +[Rclone](https://rclone.org) is a command-line tool that can be used to manage your cloud storage. It communicates with any Amazon S3-compatible cloud storage provider as well as other storage platforms. Follow the instructions given in the [official Rclone documentation here](https://rclone.org/install/) to install Rclone. @@ -79,7 +79,7 @@ For example, on Linux: ``` 3. Type `s3` and hit enter to confirm this storage type. The following output displays: ``` - Choose your S3 provider. + Choose your Amazon S3 provider. Enter a string value. Press Enter for the default (""). Choose a number from below, or type in your own value 1 / Amazon Web Services (AWS) S3 @@ -106,10 +106,10 @@ For example, on Linux: \ "TencentCOS" 12 / Wasabi Object Storage \ "Wasabi" - 13 / Any other S3 compatible provider + 13 / Any other Amazon S3 compatible provider \ "Other" ``` -4. Type `Scaleway` and hit enter to confirm this S3 provider. The following output displays: +4. Type `Scaleway` and hit enter to confirm this Amazon S3 provider. The following output displays: ``` Get AWS credentials from runtime (environment variables or EC2/ECS meta data if no env vars). Only applies if access_key_id and secret_access_key is blank. @@ -252,6 +252,6 @@ For example, on Linux: If you want to be able to transfer data to or from a bucket in a different region to the one you just set up, repeat steps 1-14 again to set up a new remote in the required region. Simply enter the required region at steps 7 and 8. Similarly, you may wish to set up a new remote for a different Object Storage provider. -For further information, refer to the official [RClone S3 Object Storage Documentation](https://rclone.org/s3/). Official documentation also exists for [other storage backends](https://rclone.org/docs/). +For further information, refer to the official [RClone Object Storage Documentation](https://rclone.org/s3/). Official documentation also exists for [other storage backends](https://rclone.org/docs/). diff --git a/storage/object/api-cli/lifecycle-rules-api.mdx b/storage/object/api-cli/lifecycle-rules-api.mdx index 969274fa17..b841ab1112 100644 --- a/storage/object/api-cli/lifecycle-rules-api.mdx +++ b/storage/object/api-cli/lifecycle-rules-api.mdx @@ -37,7 +37,7 @@ Currently, the **expiration**, **transition**, and **incomplete multipart upload There might, for example, be a need to store log files for a week or a month, after which they become obsolete. It is possible to set a lifecycle rule to delete them automatically when they become obsolete. If you consider that a 3-month-old object is rarely used but still has a value, you might want to configure a rule to send it automatically to [Scaleway Glacier](https://www.scaleway.com/en/glacier-cold-storage/), for example. -Lifecycle management on Object Storage is available on every AWS S3 compliant tool (sdk, aws-cli, boto, etc), as well as from the Scaleway [console](https://console.scaleway.com/organization). +Lifecycle management on Object Storage is available on every Amazon S3 compliant tool (sdk, aws-cli, boto, etc), as well as from the Scaleway [console](https://console.scaleway.com/organization). ## Lifecycle specification diff --git a/storage/object/api-cli/manage-bucket-permissions-ip.mdx b/storage/object/api-cli/manage-bucket-permissions-ip.mdx index 2cb9c1de20..a42c76fa32 100644 --- a/storage/object/api-cli/manage-bucket-permissions-ip.mdx +++ b/storage/object/api-cli/manage-bucket-permissions-ip.mdx @@ -14,7 +14,7 @@ categories: - object-storage --- -You can stipulate which IP addresses or IP ranges have access or permission to perform S3 operations on your buckets by creating a [bucket policy](/storage/object/api-cli/bucket-policy/) with the `IpAddress` or `NotIpAddress` conditions. +You can stipulate which IP addresses or IP ranges have access or permission to perform operations on your buckets by creating a [bucket policy](/storage/object/api-cli/bucket-policy/) with the `IpAddress` or `NotIpAddress` conditions. It is possible to `Allow` actions for a specific IP address or range of IPs, using the `IpAddress` condition and the `aws:SourceIp` condition key. diff --git a/storage/object/api-cli/managing-lifecycle-cliv2.mdx b/storage/object/api-cli/managing-lifecycle-cliv2.mdx index 043c2a1b5f..df8185b9ff 100644 --- a/storage/object/api-cli/managing-lifecycle-cliv2.mdx +++ b/storage/object/api-cli/managing-lifecycle-cliv2.mdx @@ -14,7 +14,7 @@ categories: - object-storage --- -[Scaleway Object Storage](/storage/object/concepts/#object-storage) is a service based on the S3 protocol. It allows you to store different types of objects (documents, images, videos, etc.) and distribute them instantly, anywhere in the world. You can create and manage your Object Storage resources from the [console](https://console.scaleway.com/login), or via the [Scaleway Command Line Interface](/developer-tools/scaleway-cli/quickstart/) that uses external tools such as `rclone`, `s3cmd` and `mc`. +[Scaleway Object Storage](/storage/object/concepts/#object-storage) is a service based on the Amazon S3 protocol. It allows you to store different types of objects (documents, images, videos, etc.) and distribute them instantly, anywhere in the world. You can create and manage your Object Storage resources from the [console](https://console.scaleway.com/login), or via the [Scaleway Command Line Interface](/developer-tools/scaleway-cli/quickstart/) that uses external tools such as `rclone`, `s3cmd` and `mc`. ## Scaleway Command Line Interface Overview @@ -27,7 +27,7 @@ categories: - A valid [API key](/identity-and-access-management/iam/how-to/create-api-keys/) - An [Object Storage bucket](/storage/object/how-to/create-a-bucket/) - Installed and initialized the [Scaleway CLI](/developer-tools/scaleway-cli/quickstart/) -- Downloaded [S3cmd](https://github.com/s3tools/s3cmd), [rclone](https://rclone.org/downloads/) and [mc](https://github.com/minio/mc) s3 tools +- Downloaded [S3cmd](https://github.com/s3tools/s3cmd), [rclone](https://rclone.org/downloads/) and [mc](https://github.com/minio/mc) ## Creating a configuration file for the Scaleway CLI @@ -98,7 +98,7 @@ categories: ``` -## Installing a configuration file for S3 tools (s3cmd, rclone, and mc) +## Installing a configuration file for Amazon S3-compatible tools (s3cmd, rclone, and mc) 1. Run the following command in a terminal to install a configuration file for `s3cmd`: ``` @@ -210,7 +210,7 @@ Run the following command in a terminal to remove an object from your bucket: ``` - For more information about the s3 tools used in this documentation, refer to the official [rclone](https://rclone.org/docs/), [s3cmd](https://s3tools.org/s3cmd-howto), and [mc](https://github.com/minio/mc) documentation. + For more information about the Amazon S3-compatible tools used in this documentation, refer to the official [rclone](https://rclone.org/docs/), [s3cmd](https://s3tools.org/s3cmd-howto), and [mc](https://github.com/minio/mc) documentation. diff --git a/storage/object/api-cli/migrating-buckets.mdx b/storage/object/api-cli/migrating-buckets.mdx index de9e5eda2a..601aaa1d57 100644 --- a/storage/object/api-cli/migrating-buckets.mdx +++ b/storage/object/api-cli/migrating-buckets.mdx @@ -25,7 +25,7 @@ categories: ``` aws s3api create-bucket --bucket BUCKET-TARGET ``` -2. Copy the objects between the S3 buckets. +2. Copy the objects between the Object Storage buckets. If you have objects in the Scaleway `Glacier` storage class you must [restore](/storage/object/how-to/restore-an-object-from-glacier/) them before continuing. diff --git a/storage/object/api-cli/object-operations.mdx b/storage/object/api-cli/object-operations.mdx index 3014f58f22..3301b14371 100644 --- a/storage/object/api-cli/object-operations.mdx +++ b/storage/object/api-cli/object-operations.mdx @@ -388,7 +388,7 @@ aws s3api put-object --bucket BucketName --key dir-1/ObjectName --body ObjectNam ``` - To define the [storage class](/storage/object/concepts/#storage-class) of the object directly upon creation, use the `--storage-class ` option with `awscli` or add the `x-amz-storage-class: ` header when using the S3 API. You can specify one of the following classes: `STANDARD`, `ONEZONE_IA`, `GLACIER`. Example: `x-amz-storage-class: ONEZONE_IA`. +To define the [storage class](/storage/object/concepts/#storage-class) of the object directly upon creation, use the `--storage-class ` option with `awscli` or add the `x-amz-storage-class: ` header when using the Amazon S3 API. You can specify one of the following classes: `STANDARD`, `ONEZONE_IA`, `GLACIER`. Example: `x-amz-storage-class: ONEZONE_IA`. If no class is specified, the object is created as STANDARD by default. diff --git a/storage/object/api-cli/object-storage-aws-cli.mdx b/storage/object/api-cli/object-storage-aws-cli.mdx index d47b5abfb0..6131cfa15c 100644 --- a/storage/object/api-cli/object-storage-aws-cli.mdx +++ b/storage/object/api-cli/object-storage-aws-cli.mdx @@ -39,7 +39,7 @@ The AWS-CLI is an open-source tool built on top of the [AWS SDK for Python (Boto 3. When prompted, enter the following elements: - your API access key - your API secret key - - your preferred default S3 region (`fr-par`, `nl-ams`, or `pl-waw`) + - your preferred default Object Storage region (`fr-par`, `nl-ams`, or `pl-waw`) - `json` as the default output format 4. Open the `~/.aws/config` file in a code editor and edit it as follows: diff --git a/storage/object/api-cli/post-object.mdx b/storage/object/api-cli/post-object.mdx index 3c5bec78e3..cd7f883be8 100644 --- a/storage/object/api-cli/post-object.mdx +++ b/storage/object/api-cli/post-object.mdx @@ -87,7 +87,7 @@ import hashlib ACCESS_KEY_ID = "SCWXXXXXXXXXXXXXXXXX" SECRET_ACCESS_KEY = "110e8400-e29b-11d4-a716-446655440000" -# S3 Region +# Object Storage Region REGION = "fr-par" # Example for the demo @@ -213,7 +213,7 @@ import requests from botocore.exceptions import ClientError -# Generate a presigned URL for the S3 object +# Generate a presigned URL for the object session = boto3.session.Session() s3_client = session.client( diff --git a/storage/object/api-cli/setting-cors-rules.mdx b/storage/object/api-cli/setting-cors-rules.mdx index ffa736bc65..09ec7fb09c 100644 --- a/storage/object/api-cli/setting-cors-rules.mdx +++ b/storage/object/api-cli/setting-cors-rules.mdx @@ -5,7 +5,7 @@ meta: content: h1: Setting CORS rules on Object Storage buckets paragraph: Set CORS rules to manage cross-origin requests in Scaleway Object Storage. -tags: object storage object-storage s3 bucket cors cors-rule +tags: object storage object-storage aws-s3 bucket cors cors-rule dates: validation: 2024-06-17 posted: 2021-05-19 diff --git a/storage/object/api-cli/using-api-call-list.mdx b/storage/object/api-cli/using-api-call-list.mdx index 668dae9fd7..ab1f818db4 100644 --- a/storage/object/api-cli/using-api-call-list.mdx +++ b/storage/object/api-cli/using-api-call-list.mdx @@ -1,9 +1,9 @@ --- meta: - title: Scaleway Object Storage supported S3 API calls + title: Supported Object Storage API calls description: Learn how to use the API call list effectively with Scaleway Object Storage. content: - h1: Object Storage API + h1: Supported Object Storage API calls paragraph: Learn how to use the API call list effectively with Scaleway Object Storage. tags: object storage object-storage api bucket dates: @@ -67,7 +67,7 @@ Status: | PutBucketLifecycle | Creates a new lifecycle configuration or replaces an existing bucket lifecycle configuration | ❗ | | PutBucketLifecycleConfiguration| Creates a new lifecycle configuration or replaces an existing bucket lifecycle configuration | ✅ | | PutBucketNotification | Enables notifications of specified events for a bucket | ⌛ | -| [PutBucketPolicy](/storage/object/api-cli/bucket-operations/#putbucketpolicy) | Applies an S3 bucket policy to an S3 bucket. The key elements of bucket policy are [Version](/storage/object/api-cli/bucket-policy/#version), [ID](/storage/object/api-cli/bucket-policy/#id), [Statement](/storage/object/api-cli/bucket-policy/#statement), [Sid](/storage/object/api-cli/bucket-policy/#sid), [Principal](/storage/object/api-cli/bucket-policy/#principal), [Action](/storage/object/api-cli/bucket-policy/#action), [Effect](/storage/object/api-cli/bucket-policy/#effect), [Resource](/storage/object/api-cli/bucket-policy/#resource) and [Condition](/storage/object/api-cli/bucket-policy/#condition). You can find out more about each element by clicking the links, or consulting the full documentation | ✅ | +| [PutBucketPolicy](/storage/object/api-cli/bucket-operations/#putbucketpolicy) | Applies an Object Storage bucket policy to an Object Storage bucket. The key elements of bucket policy are [Version](/storage/object/api-cli/bucket-policy/#version), [ID](/storage/object/api-cli/bucket-policy/#id), [Statement](/storage/object/api-cli/bucket-policy/#statement), [Sid](/storage/object/api-cli/bucket-policy/#sid), [Principal](/storage/object/api-cli/bucket-policy/#principal), [Action](/storage/object/api-cli/bucket-policy/#action), [Effect](/storage/object/api-cli/bucket-policy/#effect), [Resource](/storage/object/api-cli/bucket-policy/#resource) and [Condition](/storage/object/api-cli/bucket-policy/#condition). You can find out more about each element by clicking the links, or consulting the full documentation | ✅ | | [PutBucketTagging](/storage/object/api-cli/bucket-operations/#putbuckettagging) | Sets the tag(s) of a bucket | ✅ | | [PutBucketVersioning](/storage/object/api-cli/bucket-operations/#putbucketversioning) | Sets the versioning state of an existing bucket | ✅ | | [PutBucketWebsite](/storage/object/api-cli/bucket-operations/#putbucketwebsite) | Enables bucket website and sets the basic configuration for the website | ✅ | diff --git a/storage/object/concepts.mdx b/storage/object/concepts.mdx index ccc398fa4f..afc5365c21 100644 --- a/storage/object/concepts.mdx +++ b/storage/object/concepts.mdx @@ -5,7 +5,7 @@ meta: content: h1: Object Storage - Concepts paragraph: Understand key concepts and features of Scaleway Object Storage. -tags: retention endpoint object-storage storage bucket acl multipart object s3 retention signature versioning archived +tags: retention endpoint object-storage storage bucket acl multipart object amazon-s3 retention signature versioning archived dates: validation: 2024-05-06 categories: @@ -15,7 +15,11 @@ categories: ## Access control list (ACL) -Access control lists (ACL) are subresources attached to buckets and objects. They define which Scaleway users have access to the attached object/bucket, and the type of access they have. Whenever a user makes a request against a resource, s3 checks its ACL and verifies that they have permission to carry out the request. +<<<<<<< HEAD +Access control lists (ACL) are subresources attached to buckets and objects. They define which Scaleway users have access to the attached object/bucket, and the type of access they have. Whenever a user makes a request against a resource, Amazon S3 checks its ACL and verifies that they have permission to carry out the request. +======= +Access control lists (ACL) are subresources attached to buckets and objects. They define which Scaleway users have access to the attached object/bucket, and the type of access they have. Whenever a user makes a request against a resource, Object Storage checks its ACL and verifies that they have permission to carry out the request. +>>>>>>> 8888c6b0f (feat(gen): remove mentions of S3 only) ## Bucket @@ -86,13 +90,13 @@ An object is a file and the metadata that describes it. Each object has a **key ## Object lock -An S3 API feature that allows users to lock objects to prevent them from being deleted or overwritten. Objects can be put on lock for a specific amount of time or indefinitely. The lock period is defined by the user. +An Amazon S3 API feature that allows users to lock objects to prevent them from being deleted or overwritten. Objects can be put on lock for a specific amount of time or indefinitely. The lock period is defined by the user. The feature uses a write-once-read-many (WORM) data protection model. This model is generally used in cases where data cannot be altered once it has been written. It provides regulatory compliance and protection against ransomware and malicious or accidental deletion of objects. ## Object Storage -A storage service based on the S3 protocol. It allows you to store different types of objects (documents, images, videos, etc.) and distribute them instantly, anywhere in the world. You can upload, download, and visualize stored objects. +A storage service based on the Amazon S3 protocol. It allows you to store different types of objects (documents, images, videos, etc.) and distribute them instantly, anywhere in the world. You can upload, download, and visualize stored objects. Contrary to other storage types such as block devices or file systems, Object Storage bundles the data itself along with metadata [tags](#tags) and a [prefix](#prefix), rather than a file name and a file path. @@ -141,13 +145,13 @@ Object Lock provides two modes to manage object retention, **Compliance** and ** A retention period specifies a fixed period for which an object remains locked. During this period, your object is WORM-protected and cannot be overwritten or deleted. -## S3 +## Amazon S3 -S3 is the de facto Object Storage protocol. Scaleway Object Storage officially supports a subset of S3. The list of supported features is described in the [Object Storage API documentation](/storage/object/api-cli/using-api-call-list/). +Amazon S3 is the de facto Object Storage protocol. Scaleway Object Storage officially supports a subset of Amazon S3. The list of supported features is described in the [Object Storage API documentation](/storage/object/api-cli/using-api-call-list/). ## Signature V2, Signature V4 -When you send HTTP requests to Object Storage, you sign the requests so that we can identify who sent them. You sign requests with your Scaleway access key, which consists of an access key and a secret key. The two main s3 protocols for authentication are Signature v2 and Signature v4. Signature v4 is more recent and it is the recommended version. +When you send HTTP requests to Object Storage, you sign the requests so that we can identify who sent them. You sign requests with your Scaleway access key, which consists of an access key and a secret key. The two main Amazon S3 protocols for authentication are Signature v2 and Signature v4. Signature v4 is more recent and it is the recommended version. ## Storage class diff --git a/storage/object/how-to/create-bucket-policy.mdx b/storage/object/how-to/create-bucket-policy.mdx index 1f7a5ee149..99658d2e37 100644 --- a/storage/object/how-to/create-bucket-policy.mdx +++ b/storage/object/how-to/create-bucket-policy.mdx @@ -5,7 +5,7 @@ meta: content: h1: How to create and manage bucket policies using the console paragraph: Create and apply bucket policies for Object Storage. -tags: bucket policy bucket console object storage s3 access +tags: bucket policy bucket console object storage aws-s3 access dates: validation: 2024-05-30 posted: 2024-05-30 diff --git a/storage/object/how-to/restore-an-object-from-glacier.mdx b/storage/object/how-to/restore-an-object-from-glacier.mdx index 2deb91fb5c..0a2931dfdc 100644 --- a/storage/object/how-to/restore-an-object-from-glacier.mdx +++ b/storage/object/how-to/restore-an-object-from-glacier.mdx @@ -41,7 +41,7 @@ categories: 4. Enter the number of days after which the object will be transferred back to `Glacier`, or click the toggle to permanently restore the object. -5. Click **Restore object from S3 Glacier**. +5. Click **Restore object from Glacier**. Your object remains available in `Standard` class for the duration you specified. It will be transferred automatically back to `Glacier` once the configured period is over. diff --git a/storage/object/how-to/upload-files-into-a-bucket.mdx b/storage/object/how-to/upload-files-into-a-bucket.mdx index 4e67015b71..7605aa6c75 100644 --- a/storage/object/how-to/upload-files-into-a-bucket.mdx +++ b/storage/object/how-to/upload-files-into-a-bucket.mdx @@ -14,7 +14,7 @@ categories: - object-storage --- -This page explains how to upload files into an Object Storage bucket using the [Scaleway console](https://consol.scaleway.com). To upload an object using the S3 API, refer to the [dedicated documentation](/storage/object/api-cli/object-operations/#putobject). +This page explains how to upload files into an Object Storage bucket using the [Scaleway console](https://consol.scaleway.com). To upload an object using the Amazon S3 API, refer to the [dedicated documentation](/storage/object/api-cli/object-operations/#putobject). diff --git a/storage/object/index.mdx b/storage/object/index.mdx index f85a357ae2..bc14b1306a 100644 --- a/storage/object/index.mdx +++ b/storage/object/index.mdx @@ -7,7 +7,7 @@ meta: @@ -65,7 +65,7 @@ meta: label="Read more" /> @@ -75,7 +75,7 @@ meta: diff --git a/storage/object/quickstart.mdx b/storage/object/quickstart.mdx index b96d0ece6a..37bbd9f037 100644 --- a/storage/object/quickstart.mdx +++ b/storage/object/quickstart.mdx @@ -14,7 +14,7 @@ categories: - object-storage --- -[Scaleway Object Storage](/storage/object/concepts/#object-storage) is an Object Storage service based on the S3 protocol. It allows you to store any objects (documents, images, videos, etc.) and access them anytime from anywhere in the world. You can manage your storage directly from the Scaleway console. On the control panel, you can easily upload, download, and visualize the objects in your buckets. In addition, you can integrate many existing libraries or CLI clients into your application or scripts. +[Scaleway Object Storage](/storage/object/concepts/#object-storage) is an Object Storage service based on the Amazon S3 protocol. It allows you to store any objects (documents, images, videos, etc.) and access them anytime from anywhere in the world. You can manage your storage directly from the Scaleway console. On the control panel, you can easily upload, download, and visualize the objects in your buckets. In addition, you can integrate many existing libraries or CLI clients into your application or scripts. diff --git a/storage/object/reference-content/optimize-object-storage-performance.mdx b/storage/object/reference-content/optimize-object-storage-performance.mdx index 844cc43d67..9be71f2878 100644 --- a/storage/object/reference-content/optimize-object-storage-performance.mdx +++ b/storage/object/reference-content/optimize-object-storage-performance.mdx @@ -14,7 +14,7 @@ categories: - object-storage --- -[Scaleway Object Storage](/storage/object/concepts/#object-storage) is a highly resilient and versatile service that guarantees the reliability and accessibility of your data, while being fully [S3-compatible](/storage/object/concepts/#s3) and user-friendly. +[Scaleway Object Storage](/storage/object/concepts/#object-storage) is a highly resilient and versatile service that guarantees the reliability and accessibility of your data, while being fully [Amazon S3-compatible](/storage/object/concepts/#s3) and user-friendly. Even though it is designed to provide best-in-class latency and throughput, user infrastructure plays a predominant role in achieving optimum efficiency, as many different factors can have an impact on performance, such as your hardware, your software stack, or the way you manage your objects. @@ -50,7 +50,7 @@ For example, if the most CPU-intensive operation uses 20% of your CPU, you can e ### Geographic location -The physical distance to the hardware hosting your Object Storage can also have an impact on performance, especially on latency. Make sure to benchmark the different [regions](/storage/object/concepts/##region-and-availability-zone) where Object Storage is available to compare latency on your mission-critical S3 operations. +The physical distance to the hardware hosting your Object Storage can also have an impact on performance, especially on latency. Make sure to benchmark the different [regions](/storage/object/concepts/##region-and-availability-zone) where Object Storage is available to compare latency on your mission-critical operations. For instance, media and content distribution are often heavily affected by the physical distance between the host and the client, as objects are usually large in this scenario. diff --git a/storage/object/reference-content/s3-iam-permissions-equivalence.mdx b/storage/object/reference-content/s3-iam-permissions-equivalence.mdx index 6a6fc1c990..896b1cb3ac 100644 --- a/storage/object/reference-content/s3-iam-permissions-equivalence.mdx +++ b/storage/object/reference-content/s3-iam-permissions-equivalence.mdx @@ -1,11 +1,11 @@ --- meta: - title: S3 and IAM permissions equivalence - description: Understand how IAM permissions in S3 relate to Scaleway Object Storage. + title: Amazon S3 and IAM permissions equivalence + description: Understand how IAM permissions in Amazon S3 relate to Scaleway Object Storage. content: - h1: S3 and IAM permissions equivalence - paragraph: Understand how IAM permissions in S3 relate to Scaleway Object Storage. -tags: object-storage s3 aws action equivalent iam permission set + h1: Amazon S3 and IAM permissions equivalence + paragraph: Understand how IAM permissions in Amazon S3 relate to Scaleway Object Storage. +tags: object-storage amazon-s3 aws action equivalent iam permission set categories: - storage - object @@ -13,7 +13,7 @@ categories: ## ObjectStorageFullAccess -| S3 Action | IAM Resource | IAM Action | Authorized | +| Amazon S3 Action | IAM Resource | IAM Action | Authorized | |---------------------------------| ------------ |------------|------------| | DeleteBucketPolicy | Policy | Write | ✅ | | GetBucketPolicy | Policy | Read | ✅ | @@ -72,7 +72,7 @@ categories: ## ObjectStorageReadOnly -| S3 Action | IAM Resource | IAM Action | Authorized | +| Amazon S3 Action | IAM Resource | IAM Action | Authorized | | ------------------------------- | ------------ | ---------- | -----------| | AbortMultipartUpload | Object | Delete | | | CompleteMultipartUpload | Object | Create | | @@ -131,7 +131,7 @@ categories: ## ObjectStorageBucketsRead -| S3 Action | IAM Resource | IAM Action | Authorized | +| Amazon S3 Action | IAM Resource | IAM Action | Authorized | |---------------------------------|--------------|------------|------------| | AbortMultipartUpload | Object | Delete | | | CompleteMultipartUpload | Object | Create | | @@ -190,7 +190,7 @@ categories: ## ObjectStorageBucketsWrite -| S3 Action | IAM Resource | IAM Action | Authorized | +| Amazon S3 Action | IAM Resource | IAM Action | Authorized | |---------------------------------|--------------|------------|------------| | AbortMultipartUpload | Object | Delete | | | CompleteMultipartUpload | Object | Create | | @@ -249,7 +249,7 @@ categories: ## ObjectStorageBucketsDelete -| S3 Action | IAM Resource | IAM Action | Authorized | +| Amazon S3 Action | IAM Resource | IAM Action | Authorized | |---------------------------------|--------------|------------|------------| | AbortMultipartUpload | Object | Delete | | | CompleteMultipartUpload | Object | Create | | @@ -308,7 +308,7 @@ categories: ## ObjectStorageObjectsRead -| S3 Action | IAM Resource | IAM Action | Authorized | +| Amazon S3 Action | IAM Resource | IAM Action | Authorized | |---------------------------------|--------------|------------|------------| | AbortMultipartUpload | Object | Delete | | | CompleteMultipartUpload | Object | Create | | @@ -367,7 +367,7 @@ categories: ## ObjectStorageObjectsWrite -| S3 Action | IAM Resource | IAM Action | Authorized | +| Amazon S3 Action | IAM Resource | IAM Action | Authorized | |---------------------------------|--------------|------------|------------| | AbortMultipartUpload | Object | Delete | | | CompleteMultipartUpload | Object | Create | ✅ | @@ -426,7 +426,7 @@ categories: ## ObjectStorageObjectsDelete -| S3 Action | IAM Resource | IAM Action | Authorized | +| Amazon S3 Action | IAM Resource | IAM Action | Authorized | |---------------------------------|--------------|------------|------------| | AbortMultipartUpload | Object | Delete | ✅ | | CompleteMultipartUpload | Object | Create | | diff --git a/storage/object/troubleshooting/api-key-does-not-work.mdx b/storage/object/troubleshooting/api-key-does-not-work.mdx index 2f6847ad2a..38bd43388d 100644 --- a/storage/object/troubleshooting/api-key-does-not-work.mdx +++ b/storage/object/troubleshooting/api-key-does-not-work.mdx @@ -28,9 +28,9 @@ When using third-party API or CLI tools, such as the [AWS CLI](/storage/object/a ## Cause -The API key you used to configure the S3 third-party tool has a [preferred Project](/identity-and-access-management/iam/concepts/#preferred-project) assigned. +The API key you used to configure the Amazon S3 third-party tool has a [preferred Project](/identity-and-access-management/iam/concepts/#preferred-project) assigned. -If you try to perform S3 operations in a Project that is **NOT** the [preferred Project](/identity-and-access-management/iam/concepts/#preferred-project) using a third-party tool, you will not be able to access your resources, resulting in an error message or an empty response. +If you try to perform Object Storage operations in a Project that is **NOT** the [preferred Project](/identity-and-access-management/iam/concepts/#preferred-project) using a third-party tool, you will not be able to access your resources, resulting in an error message or an empty response. ## Solution @@ -39,14 +39,14 @@ You can change the preferred project of your API key: - by editing it from the [Scaleway console](/identity-and-access-management/iam/how-to/manage-api-keys/#how-to-edit-an-api-key) - by [overriding it while making an API call](/identity-and-access-management/iam/api-cli/using-api-key-object-storage/#overriding-the-preferred-project-when-making-a-call) -You should now be able to list your buckets using a supported S3-compatible third-party tool. +You should now be able to list your buckets using a supported Amazon Amazon S3-compatible third-party tool. ## Going further - Refer to the documentation on [using IAM API keys with Object Storage](/identity-and-access-management/iam/api-cli/using-api-key-object-storage/) for more information. - If you did not manage to identify the error and solve it by yourself, [open a support ticket](/console/account/how-to/open-a-support-ticket/), and provide as many details as possible, along with the necessary information below: - - S3 Endpoint (e.g. `s3.fr-par.scw.cloud`) + - Object Storage Endpoint (e.g. `s3.fr-par.scw.cloud`) - Bucket name - Object name (if the request concerns an object) - Request type (PUT, GET, etc.) diff --git a/storage/object/troubleshooting/cannot-access-data.mdx b/storage/object/troubleshooting/cannot-access-data.mdx index d3e3b36adc..11d994b942 100644 --- a/storage/object/troubleshooting/cannot-access-data.mdx +++ b/storage/object/troubleshooting/cannot-access-data.mdx @@ -26,7 +26,7 @@ I am experiencing issues while trying to access my buckets and objects stored on - Go to the [Status page](https://status.scaleway.com/) to see if there is an ongoing incident on the Scaleway infrastructure. -- Retrieve the logs of your buckets using any S3-compatible tool to identify the cause of the problem: +- Retrieve the logs of your buckets using any Amazon S3-compatible tool to identify the cause of the problem: - [Rclone](https://rclone.org/docs/#logging) - [S3cmd](https://s3tools.org/usage) - [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc-admin/mc-admin-logs.html#mc-admin-logs) @@ -39,7 +39,7 @@ I am experiencing issues while trying to access my buckets and objects stored on ## Going further If you did not manage to identify the error and solve it by yourself, [open a support ticket](/console/account/how-to/open-a-support-ticket/), and provide as many details as possible, along with the necessary information below: - - S3 Endpoint (e.g. `s3.fr-par.scw.cloud`) + - Object Storage Endpoint (e.g. `s3.fr-par.scw.cloud`) - Bucket name - Object name (if the request concerns an object) - Request type (PUT, GET, etc.) diff --git a/storage/object/troubleshooting/cannot-delete-bucket.mdx b/storage/object/troubleshooting/cannot-delete-bucket.mdx index eb638de802..b45e84944c 100644 --- a/storage/object/troubleshooting/cannot-delete-bucket.mdx +++ b/storage/object/troubleshooting/cannot-delete-bucket.mdx @@ -40,7 +40,7 @@ I cannot delete my Scaleway Object Storage bucket. - Refer to the documentation on [how to delete a bucket](/storage/object/how-to/delete-a-bucket/) for more information. - If you did not manage to identify the error and solve it by yourself, [open a support ticket](/console/account/how-to/open-a-support-ticket/), and provide as many details as possible, along with the necessary information below: - - S3 Endpoint (e.g. `s3.fr-par.scw.cloud`) + - Object Storage Endpoint (e.g. `s3.fr-par.scw.cloud`) - Bucket name - Object name (if the request concerns an object) - Request type (PUT, GET, etc.) diff --git a/storage/object/troubleshooting/cannot-restore-glacier.mdx b/storage/object/troubleshooting/cannot-restore-glacier.mdx index f651beb259..c8cd4dd1eb 100644 --- a/storage/object/troubleshooting/cannot-restore-glacier.mdx +++ b/storage/object/troubleshooting/cannot-restore-glacier.mdx @@ -56,7 +56,7 @@ The `"Restore": "ongoing-request=\"true\"",` line indicates that the restore ope - Refer to the documentation on [how to restore objects from Glacier](/storage/object/how-to/restore-an-object-from-glacier/) for more information. - If you did not manage to identify the error and solve it by yourself, [open a support ticket](/console/account/how-to/open-a-support-ticket/), and provide as many details as possible, along with the necessary information below: - - S3 Endpoint (e.g. `s3.fr-par.scw.cloud`) + - Object Storage Endpoint (e.g. `s3.fr-par.scw.cloud`) - Bucket name - Object name (if the request concerns an object) - Request type (PUT, GET, etc.) diff --git a/storage/object/troubleshooting/lost-bucket-access-bucket-policy.mdx b/storage/object/troubleshooting/lost-bucket-access-bucket-policy.mdx index 6e449d0ebb..742c97fdf6 100644 --- a/storage/object/troubleshooting/lost-bucket-access-bucket-policy.mdx +++ b/storage/object/troubleshooting/lost-bucket-access-bucket-policy.mdx @@ -73,7 +73,7 @@ If you have the permission to apply a bucket policy, you can also delete it. To - Refer to the [bucket policies overview](/storage/object/api-cli/bucket-policy/) for more information on the different elements of a bucket policy. - If you did not manage to identify the error and solve it by yourself, [open a support ticket](/console/account/how-to/open-a-support-ticket/), and provide as many details as possible, along with the necessary information below: - - S3 Endpoint (e.g. `s3.fr-par.scw.cloud`) + - Object Storage Endpoint (e.g. `s3.fr-par.scw.cloud`) - Bucket name - Object name (if the request concerns an object) - Request type (PUT, GET, etc.) diff --git a/storage/object/troubleshooting/low-performance.mdx b/storage/object/troubleshooting/low-performance.mdx index ed54488bb7..f5e554baa7 100644 --- a/storage/object/troubleshooting/low-performance.mdx +++ b/storage/object/troubleshooting/low-performance.mdx @@ -26,7 +26,7 @@ I am noticing decreased throughputs, timeouts, high latency, and overall instabi - Go to the [Status page](https://status.scaleway.com/) to see if there is an ongoing incident on the Scaleway infrastructure. -- Retrieve the logs of your buckets using any S3-compatible tool to identify the cause of the problem: +- Retrieve the logs of your buckets using any Amazon S3-compatible tool to identify the cause of the problem: - [Rclone](https://rclone.org/docs/#logging) - [S3cmd](https://s3tools.org/usage) - [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc-admin/mc-admin-logs.html#mc-admin-logs) @@ -37,7 +37,7 @@ I am noticing decreased throughputs, timeouts, high latency, and overall instabi - Refer to the documentation on [how to optimize your Object Storage performance](/storage/object/reference-content/optimize-object-storage-performance/) for more information. - If you did not manage to identify the error and solve it by yourself, [open a support ticket](/console/account/how-to/open-a-support-ticket/), and provide as many details as possible, along with the necessary information below: - - S3 Endpoint (e.g. `s3.fr-par.scw.cloud`) + - Object Storage Endpoint (e.g. `s3.fr-par.scw.cloud`) - Bucket name - Object name (if the request concerns an object) - Request type (PUT, GET, etc.) diff --git a/styles/scw_styles/HeadingSentenceCase.yml b/styles/scw_styles/HeadingSentenceCase.yml index bc3fe0cc45..31cb9d6797 100644 --- a/styles/scw_styles/HeadingSentenceCase.yml +++ b/styles/scw_styles/HeadingSentenceCase.yml @@ -46,7 +46,7 @@ exceptions: - Object Storage - Glacier - Standard - - S3 + - Amazon S3 - Block Storage - Managed Database - Managed Databases diff --git a/tutorials/abort-multipart-upload-minio/index.mdx b/tutorials/abort-multipart-upload-minio/index.mdx index 0520f03bbf..b0b871f235 100644 --- a/tutorials/abort-multipart-upload-minio/index.mdx +++ b/tutorials/abort-multipart-upload-minio/index.mdx @@ -1,10 +1,10 @@ --- meta: - title: Aborting Incomplete S3 Multipart Uploads with MinIO Client - description: This page explains how to abort an incomplete S3 multipart upload with the MinIO client. + title: Aborting Incomplete Multipart Uploads with MinIO Client + description: This page explains how to abort an incomplete multipart upload with the MinIO client. content: - h1: Aborting Incomplete S3 Multipart Uploads with MinIO Client - paragraph: This page explains how to abort an incomplete S3 multipart upload with the MinIO client. + h1: Aborting Incomplete Multipart Uploads with MinIO Client + paragraph: This page explains how to abort an incomplete multipart upload with the MinIO client. tags: minio multipart-uploads categories: - object-storage @@ -13,13 +13,13 @@ dates: hero: assets/scaleway_minio.webp --- -## S3 Object Storage - Multipart Upload Overview +## Object Storage - Multipart Upload Overview [Multipart Uploads](/storage/object/api-cli/multipart-uploads/) allows you to upload large files (up to 5 TB) to the Object Storage platform in multiple parts. This allows faster, more flexible uploads. If you do not complete a multipart upload, all the uploaded parts will still be stored and counted as part of your storage usage. Multipart uploads can be aborted manually [via the API and CLI](/storage/object/api-cli/multipart-uploads/#aborting-a-multipart-upload) or automatically using a [Lifecycle rule](/storage/object/api-cli/lifecycle-rules-api/#setting-rules-for-incomplete-multipart-uploads). -If you use the API or the AWS CLI, you will have to abort each incomplete multipart upload independently. However, there is an easier and faster way to abort multipart uploads, using the open-source S3-compatible client [mc](https://github.com/minio/mc), from MinIO. In this tutorial, we show you how to use mc to abort and clean up all your incomplete multipart uploads at once. +If you use the API or the AWS CLI, you will have to abort each incomplete multipart upload independently. However, there is an easier and faster way to abort multipart uploads, using the open-source Amazon S3-compatible client [mc](https://github.com/minio/mc), from MinIO. In this tutorial, we show you how to use mc to abort and clean up all your incomplete multipart uploads at once. diff --git a/tutorials/ceph-cluster/index.mdx b/tutorials/ceph-cluster/index.mdx index 56244c9992..930fa7074d 100644 --- a/tutorials/ceph-cluster/index.mdx +++ b/tutorials/ceph-cluster/index.mdx @@ -193,7 +193,7 @@ Deploy the Ceph cluster on your machines by following these steps: ### Deploying a Ceph Object Gateway (RGW) -Deploy the Ceph Object Gateway (RGW) to access files using S3-compatible clients: +Deploy the Ceph Object Gateway (RGW) to access files using Amazon S3-compatible clients: 1. Run the following command on the admin machine: @@ -225,7 +225,7 @@ Deploy the Ceph Object Gateway (RGW) to access files using S3-compatible clients 3. Verify the installation by accessing `http://ceph-node-a:7480` in a web browser. -## Creating S3 credentials +## Creating Object Storage credentials On the gateway instance (`ceph-node-a`), run the following command to create a new user: @@ -233,7 +233,7 @@ On the gateway instance (`ceph-node-a`), run the following command to create a n sudo radosgw-admin user create --uid=johndoe --display-name="John Doe" --email=john@example.com ``` -- Note the `access_key` and `user_key`. Proceed to configure your S3 client, e.g., [aws-cli](/storage/object/api-cli/object-storage-aws-cli/). +- Note the `access_key` and `user_key`. Proceed to configure your Object Storage client, e.g., [aws-cli](/storage/object/api-cli/object-storage-aws-cli/). ## Configuring AWS-CLI @@ -286,4 +286,4 @@ Use AWS-CLI to manage objects in your Ceph storage cluster: ## Conclusion -You have successfully configured an S3-compatible storage cluster using Ceph and three [Dedibox dedicated servers](https://www.scaleway.com/en/dedibox/). You can now manage your data using any S3-compatible tool. For advanced configuration, refer to the official [Ceph documentation](https://docs.ceph.com/docs/master/). \ No newline at end of file +You have successfully configured an Amazon S3-compatible storage cluster using Ceph and three [Dedibox dedicated servers](https://www.scaleway.com/en/dedibox/). You can now manage your data using any Amazon S3-compatible tool. For advanced configuration, refer to the official [Ceph documentation](https://docs.ceph.com/docs/master/). \ No newline at end of file diff --git a/tutorials/cilicon-self-hosted-ci-on-apple-silicon/index.mdx b/tutorials/cilicon-self-hosted-ci-on-apple-silicon/index.mdx index ce462dabf6..3346b81f9a 100644 --- a/tutorials/cilicon-self-hosted-ci-on-apple-silicon/index.mdx +++ b/tutorials/cilicon-self-hosted-ci-on-apple-silicon/index.mdx @@ -95,7 +95,7 @@ provisioner: executor: # defaults to 'shell' maxNumberOfBuilds: # defaults to '1' downloadLatest: # defaults to 'true' - downloadURL: # defaults to GitLab official S3 bucket + downloadURL: # defaults to GitLab official Object Storage bucket configToml: > # Advanced config as custom config.toml file to be appended to the basic config and copied to the runner. ``` diff --git a/tutorials/configure-dvc-with-object-storage/index.mdx b/tutorials/configure-dvc-with-object-storage/index.mdx index 6bdcbf9901..2d928cac83 100644 --- a/tutorials/configure-dvc-with-object-storage/index.mdx +++ b/tutorials/configure-dvc-with-object-storage/index.mdx @@ -5,7 +5,7 @@ meta: content: h1: Configuring DVC with Object Storage paragraph: This page provides information on how to configure DVC with Scaleway Object Storage. -tags: s3 dvc machine-learning data-science +tags: amazon-s3 dvc machine-learning data-science categories: - object-storage dates: @@ -17,7 +17,7 @@ Git is unarguably the most popular and powerful version control system to store However, when it comes to large datasets, you might need to turn to third-party version control tools that are specifically designed to handle them. -Data Version Control (DVC) was specifically designed with this use case in mind. It works alongside Git and allows you to store your data in the remote storage of your choice (such as a Scaleway S3-enabled bucket) while storing only the metadata in a Git repository. +Data Version Control (DVC) was specifically designed with this use case in mind. It works alongside Git and allows you to store your data in the remote storage of your choice (such as a Scaleway Object Storage bucket) while storing only the metadata in a Git repository. In this tutorial, you learn how to use [Scaleway Object Storage](https://www.scaleway.com/en/object-storage/) as a remote storage for DVC. @@ -39,7 +39,7 @@ In this tutorial, you learn how to use [Scaleway Object Storage](https://www.sca pip3 install dvc ``` -2. Run the following command to install the S3 dependencies: +2. Run the following command to install the Amazon S3 dependencies: ```bash pip3 install "dvc[s3]" ``` @@ -93,7 +93,7 @@ In this tutorial, you learn how to use [Scaleway Object Storage](https://www.sca dvc remote add -d myremote s3://my-bucket/path ``` -2. Run the following command to set the S3 endpoint of your remote storage: +2. Run the following command to set the Object Storage endpoint of your remote storage: ```bash dvc remote modify myremote \ endpointurl https://s3.fr-par.scw.cloud diff --git a/tutorials/configure-plex-s3/index.mdx b/tutorials/configure-plex-s3/index.mdx index 1c51d5ef80..ab3409a18f 100644 --- a/tutorials/configure-plex-s3/index.mdx +++ b/tutorials/configure-plex-s3/index.mdx @@ -1,7 +1,7 @@ --- meta: title: Configuring Plex Media Server with Object Storage - description: This page shows how to set up an s3 media server with Plex and Object Storage + description: This page shows how to set up a media server with Plex and Object Storage content: h1: Configuring Plex Media Server with Object Storage paragraph: This page shows how to configure Plex media server with Object Storage @@ -167,7 +167,7 @@ Plex is a client/server media player system comprising two main components: - You can upload additional content to your server with any S3-compatible tool, like [Cyberduck](/tutorials/store-s3-cyberduck/). + You can upload additional content to your server with any Amazon S3-compatible tool, like [Cyberduck](/tutorials/store-s3-cyberduck/). 9. Click **Next** and then **Finish** to conclude the set-up. 10. Add media to your bucket and trigger a scan of your media folder in the Plex interface. Your media should display. If so, it is all set up. For more information about Plex, refer to their [official documentation](https://support.plex.tv/articles/). \ No newline at end of file diff --git a/tutorials/create-openwrt-image-for-scaleway/index.mdx b/tutorials/create-openwrt-image-for-scaleway/index.mdx index ba1c864690..7dfaf1b604 100644 --- a/tutorials/create-openwrt-image-for-scaleway/index.mdx +++ b/tutorials/create-openwrt-image-for-scaleway/index.mdx @@ -292,7 +292,7 @@ In this tutorial, we do not set up cloud-init, but use the same magic IP mechani ## Import the image -You can use the Scaleway console or your favorite S3 CLI to upload objects into a bucket. +You can use the Scaleway console or your favorite Amazon S3-compatible CLI tool to upload objects into a bucket. In this example, we use the [AWS CLI](/storage/object/api-cli/object-storage-aws-cli/). diff --git a/tutorials/create-serverless-scraping/index.mdx b/tutorials/create-serverless-scraping/index.mdx index 67c5e842da..b0eacb6a97 100644 --- a/tutorials/create-serverless-scraping/index.mdx +++ b/tutorials/create-serverless-scraping/index.mdx @@ -407,5 +407,5 @@ While the volume of data processed in this example is quite small, thanks to the Here are some possible extensions to this basic example: - Replace the simple proposed logic with your own. What about counting how many times some keywords (e.g: copilot, serverless, microservice) appear in Hacker News articles? - Define multiple cron triggers for different websites and pass the website as an argument to the function. Or, create multiple functions that feed the same queue. - - Use a [Serverless Container](/serverless/containers/quickstart/) instead of the consumer function, and use a command line tool such as `htmldoc` or `pandoc` to convert the scraped articles to PDF and upload the result to a [Scaleway Object Storage](/storage/object/quickstart/) S3 bucket. + - Use a [Serverless Container](/serverless/containers/quickstart/) instead of the consumer function, and use a command line tool such as `htmldoc` or `pandoc` to convert the scraped articles to PDF and upload the result to a [Scaleway Object Storage bucket](/storage/object/quickstart/). - Replace the Managed Database for PostgreSQL with a [Scaleway Serverless Database](/serverless/sql-databases/quickstart/), so that all the infrastructure lives in the serverless ecosystem! *Note that at the moment there is no Terraform support for Serverless Database, hence the choice here to use Managed Database for PostgreSQL*. \ No newline at end of file diff --git a/tutorials/deploy-nextcloud-s3/index.mdx b/tutorials/deploy-nextcloud-s3/index.mdx index 83c1be5d02..ed32715dc8 100644 --- a/tutorials/deploy-nextcloud-s3/index.mdx +++ b/tutorials/deploy-nextcloud-s3/index.mdx @@ -143,7 +143,7 @@ NextCloud can use Object Storage as primary storage. This gives you the possibil ``` nano /var/www/nextcloud/config/config.php ``` -3. Add a configuration block for S3-compatible storage, as follows: +3. Add a configuration block for Amazon S3-compatible storage, as follows: ``` 'objectstore' => array( 'class' => '\\OC\\Files\\ObjectStore\\S3', diff --git a/tutorials/deploy-saas-application/index.mdx b/tutorials/deploy-saas-application/index.mdx index a7e1cf1ae8..bdce57cccf 100644 --- a/tutorials/deploy-saas-application/index.mdx +++ b/tutorials/deploy-saas-application/index.mdx @@ -41,7 +41,7 @@ You will learn how to store environment variables with Kubernetes secrets and us In all applications, you have to define settings, usually based on environment variables, so that you can adapt the behavior of your application depending on their values. Having used Django to create your SaaS application, the settings you need can be found in a file called `settings.py`. In the following steps, we will modify `settings.py` to connect our private Object Storage bucket to our application. As noted in the requirements for this tutorial, you should have already [created a private Object Storage bucket](/storage/object/how-to/create-a-bucket/) before continuing. -1. Take a look at your Django application's `settings.py` file. Natively, Django does not manage the S3 protocol for storing static files, and it will provide you with a basic configuration at the end of this file: +1. Take a look at your Django application's `settings.py` file. Natively, Django does not manage the Amazon S3 protocol for storing static files, and it will provide you with a basic configuration at the end of this file: ``` STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') @@ -91,13 +91,13 @@ In all applications, you have to define settings, usually based on environment v - `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are the [access key and secret key for your Scaleway account](/identity-and-access-management/iam/how-to/create-api-keys/) - `AWS_STORAGE_BUCKET_NAME` is the name you gave your [Object Storage bucket](/storage/object/how-to/create-a-bucket/), e.g. `my_awesome_bucket` - `AWS_S3_REGION_NAME` is the region/zone of your Object Storage Bucket - - `AWS_S3_HOST` and `AWS_S3_ENDPOINT_URL` are the URLs needed to access your S3 bucket. They are composed of the previously defined variables. - - `AWS_LOCATION` is the folder that will be created in our S3 bucket for our static files + - `AWS_S3_HOST` and `AWS_S3_ENDPOINT_URL` are the URLs needed to access your Object Storage bucket. They are composed of the previously defined variables. + - `AWS_LOCATION` is the folder that will be created in our Object Storage bucket for our static files - `STATIC_URL` has changed - - `STATICFILES_STORAGE` defines the new storage class that we want to use, here standard S3 protocol storage. We now need to give values to our environment values, so that they can be correctly found by `settings.py` via `os.getenv('MY_VAR_NAME')`. + - `STATICFILES_STORAGE` defines the new storage class that we want to use, here standard Amazon S3 protocol storage. We now need to give values to our environment values, so that they can be correctly found by `settings.py` via `os.getenv('MY_VAR_NAME')`. - Remember that S3 is a standard protocol. Even though the `boto3` library asks us to prefix variables with `AWS`, it nonetheless works perfectly with Scaleway Object Storage. + Remember that Amazon S3 is a standard protocol. Even though the `boto3` library asks us to prefix variables with `AWS`, it nonetheless works perfectly with Scaleway Object Storage. Even though we added a lot of lines to `settings.py`, only four environment variables are ultimately needed to use our Object Storage bucket: `ACCESS_KEY_ID`, `SECRET_ACCESS_KEY`, `AWS_S3_REGION_NAME` (eg `nl-ams`) and `AWS_STORAGE_BUCKET_NAME`. These variables are called using `os.getenv('MY_VAR_NAME')` so we now need to set these values. diff --git a/tutorials/deploying-a-documentation-website-with-docusaurus-on-scaleway/index.mdx b/tutorials/deploying-a-documentation-website-with-docusaurus-on-scaleway/index.mdx index 264a034efc..3adcec84f0 100644 --- a/tutorials/deploying-a-documentation-website-with-docusaurus-on-scaleway/index.mdx +++ b/tutorials/deploying-a-documentation-website-with-docusaurus-on-scaleway/index.mdx @@ -107,7 +107,7 @@ Docusaurus is available for most operating systems. In this tutorial, we describ 9. Click **Skip this and set up a workflow yourself**. 10. Copy the following code in the text editor, keep the default file name `main.yml` and click **Start commit**: ``` - name: Deploy Docusaurus to S3 + name: Deploy Docusaurus to Object Storage on: push: branches: diff --git a/tutorials/encode-videos-using-serverless-jobs/index.mdx b/tutorials/encode-videos-using-serverless-jobs/index.mdx index 01051cdcb3..d2cb14f1be 100644 --- a/tutorials/encode-videos-using-serverless-jobs/index.mdx +++ b/tutorials/encode-videos-using-serverless-jobs/index.mdx @@ -15,7 +15,7 @@ dates: posted: 2024-05-15 --- -This tutorial demonstrates the process of encoding videos retrieved from Object Storage using Serverless Jobs: media encoding is a resource-intensive task over prolonged durations, making it suitable for Serverless Jobs. The job takes a video file as its input, encodes it using a Docker image based on [FFMPEG](https://ffmpeg.org/), then uploads the encoded video back to the S3 bucket. +This tutorial demonstrates the process of encoding videos retrieved from Object Storage using Serverless Jobs: media encoding is a resource-intensive task over prolonged durations, making it suitable for Serverless Jobs. The job takes a video file as its input, encodes it using a Docker image based on [FFMPEG](https://ffmpeg.org/), then uploads the encoded video back to the Object Storage bucket. @@ -28,14 +28,14 @@ This tutorial demonstrates the process of encoding videos retrieved from Object ## Creating the job image -The initial step involves defining a Docker image for interacting with the S3 Object Storage using [MinIO](https://min.io/) and performing a video encoding task using [FFMPEG](https://ffmpeg.org/). +The initial step involves defining a Docker image for interacting with the Object Storage using [MinIO](https://min.io/) and performing a video encoding task using [FFMPEG](https://ffmpeg.org/). 1. Create a bash script `encode.sh` with the following content: ```bash #!/bin/sh set -e - echo "Configuring S3 access for MinIO" + echo "Configuring Object Storage access for MinIO" mc config host add scw "https://$JOB_S3_ENDPOINT/" "$JOB_S3_ACCESS_KEY" "$JOB_S3_SECRET_KEY" echo "Downloading the file from S3" @@ -48,7 +48,7 @@ The initial step involves defining a Docker image for interacting with the S3 Ob mc cp "/tmp/$JOB_OUTPUT_FILENAME" "scw/$JOB_OUTPUT_PATH/$JOB_OUTPUT_FILENAME" ``` - That bash script downloads a video from an S3 bucket, encodes that video using FFMPEG, and then uploads the encoded video into the bucket, by leveraging a couple of environment variables which will be detailed in the following sections. + That bash script downloads a video from an Object Storage bucket, encodes that video using FFMPEG, and then uploads the encoded video into the bucket, by leveraging a couple of environment variables which will be detailed in the following sections. For illustration purposes, this script encodes a video using the x264 video codec and the AAC audio codec. Encoding settings can be modified using command-line parameters to FFMPEG. @@ -58,7 +58,7 @@ The initial step involves defining a Docker image for interacting with the S3 Ob ```dockerfile FROM linuxserver/ffmpeg:amd64-latest - # Install the MinIO S3 client + # Install the MinIO client RUN curl https://dl.min.io/client/mc/release/linux-amd64/mc -o /usr/local/bin/mc RUN chmod +x /usr/local/bin/mc @@ -69,7 +69,7 @@ The initial step involves defining a Docker image for interacting with the S3 Ob ENTRYPOINT /encode.sh ``` - This Dockerfile uses `linuxserver/ffmpeg` as a base image bundled with FFMPEG along with a variety of encoding codecs and installs [MinIO](https://min.io/) as a command-line S3 client to copy files over Object Storage. + This Dockerfile uses `linuxserver/ffmpeg` as a base image bundled with FFMPEG along with a variety of encoding codecs and installs [MinIO](https://min.io/) as a command-line client to copy files over Object Storage. 3. Build and [push the image](/containers/container-registry/how-to/push-images/) to your Container Registry: ```bash @@ -94,7 +94,7 @@ The initial step involves defining a Docker image for interacting with the S3 Ob 4. Toggle the **Advanced options** section and add 3 environment variables: - - `JOB_S3_ENDPOINT` is your S3 endpoint (e.g. `s3.nl-ams.scw.cloud`). + - `JOB_S3_ENDPOINT` is your Object Storage endpoint (e.g. `s3.nl-ams.scw.cloud`). - `JOB_S3_ACCESS_KEY` is your API access key. - `JOB_S3_SECRET_KEY` is your API secret key. @@ -104,14 +104,14 @@ The initial step involves defining a Docker image for interacting with the S3 Ob ## Triggering the serverless job -Ensure that your S3 bucket contains at least one video that can be encoded. +Ensure that your Object Storage bucket contains at least one video that can be encoded. 1. In the Scaleway Console, go to **Serverless Jobs** and click on the name of your job. The job **Overview** tab displays. 2. Click the **Actions** button, then click **Run job with options** in the drop-down menu. 3. Add 4 environment variables: - - `JOB_INPUT_PATH` is the folder containing the video to encode, including your S3 bucket name. + - `JOB_INPUT_PATH` is the folder containing the video to encode, including your Object Storage bucket name. - `JOB_INPUT_FILENAME` is the file name of the video to encode, including the file extension. - - `JOB_OUTPUT_PATH` is the folder containing the encoded video that will be uploaded, including your S3 bucket name. + - `JOB_OUTPUT_PATH` is the folder containing the encoded video that will be uploaded, including your Object Storage bucket name. - `JOB_OUTPUT_FILENAME` is the file name of the encoded video that will be uploaded. @@ -120,7 +120,7 @@ Ensure that your S3 bucket contains at least one video that can be encoded. The progress and details for your Job run can be viewed in the **Job runs** section of the job **Overview** tab in the [Scaleway console](https://console.scaleway.com). You can also access the detailed logs of your job in [Cockpit](/observability/cockpit/quickstart/). -Once the run status is **Succeeded**, the encoded video can be found in your S3 bucket under the folder and file name specified above in the environment variables. +Once the run status is **Succeeded**, the encoded video can be found in your Object Storage bucket under the folder and file name specified above in the environment variables. Your job can also be triggered through the [Scaleway API](https://www.scaleway.com/en/developers/api/serverless-jobs/#path-job-definitions-run-an-existing-job-definition-by-its-unique-identifier-this-will-create-a-new-job-run) using the same environment variables: diff --git a/tutorials/encrypt-s3-data-rclone/index.mdx b/tutorials/encrypt-s3-data-rclone/index.mdx index 21cca69e15..5b79243e56 100644 --- a/tutorials/encrypt-s3-data-rclone/index.mdx +++ b/tutorials/encrypt-s3-data-rclone/index.mdx @@ -7,7 +7,7 @@ content: paragraph: In this tutorial, you will learn how to encrypt your data using Rclone before uploading it to Scaleway Object Storage. categories: - object-storage -tags: encryption s3 rclone +tags: encryption amazon-s3 rclone dates: validation: 2024-09-16 posted: 2020-06-10 @@ -19,7 +19,7 @@ Offering virtual backends, Rclone facilitates encryption, caching, chunking, and Compatible with Windows, macOS X, and various Linux distributions, Rclone addresses a wide user base seeking efficient file management solutions. -In this tutorial, we will explore the capabilities of the **Rclone crypt** module, which empowers users to encrypt their data seamlessly before transmitting it to Scaleway Object Storage via the S3 protocol. +In this tutorial, we will explore the capabilities of the **Rclone crypt** module, which empowers users to encrypt their data seamlessly before transmitting it to Scaleway Object Storage via the Amazon S3 protocol. @@ -65,13 +65,13 @@ brew install rclone sudo mandb ``` -## Configuring an S3 remote endpoint +## Configuring an Object Storage remote endpoint You need to have your [API key](/identity-and-access-management/iam/how-to/create-api-keys/) ready for the `rclone` configuration. -Before encrypting your data, create a new remote S3 endpoint in Rclone using the `rclone config` command: +Before encrypting your data, create a new remote Object Storage endpoint in Rclone using the `rclone config` command: ``` No remotes found - make a new one @@ -187,7 +187,7 @@ e/n/d/r/c/s/q> q `rclone crypt` will use the previously configured endpoint to store the encrypted files. Configure it by running `rclone config` again. -In the config below we define the Object Storage bucket at the `remote` prompt. In our example, we use our S3 endpoint `scaleway` with the bucket `myobjectstoragebucket`. +In the config below we define the Object Storage bucket at the `remote` prompt. In our example, we use our Object Storage endpoint `scaleway` with the bucket `myobjectstoragebucket`. Edit these values towards your configuration. A long passphrase is recommended for security reasons, or you can use a random one. diff --git a/tutorials/getting-started-with-kops-on-scaleway/index.mdx b/tutorials/getting-started-with-kops-on-scaleway/index.mdx index 3554068e73..640c656eeb 100644 --- a/tutorials/getting-started-with-kops-on-scaleway/index.mdx +++ b/tutorials/getting-started-with-kops-on-scaleway/index.mdx @@ -41,11 +41,11 @@ export SCW_SECRET_KEY="my-secret-key" export SCW_DEFAULT_PROJECT_ID="my-project-id" # Configure the bucket name to store kops state export KOPS_STATE_STORE=scw:// # where is the name of the bucket you set earlier -# Scaleway Object Storage is S3 compatible so we just override some S3 configurations to talk to our bucket +# Scaleway Object Storage is Amazon S3-compatible so we just override some configurations to talk to our bucket export S3_REGION=fr-par # or another scaleway region providing Object Storage export S3_ENDPOINT=s3.$S3_REGION.scw.cloud # define provider endpoint -export S3_ACCESS_KEY_ID="my-access-key" # where is the S3 API access key for your bucket -export S3_SECRET_ACCESS_KEY="my-secret-key" # where is the S3 API secret key for your bucket +export S3_ACCESS_KEY_ID="my-access-key" # where is the API access key for your bucket +export S3_SECRET_ACCESS_KEY="my-secret-key" # where is the API secret key for your bucket # this is required since Scaleway support is currently in alpha so it is feature gated export KOPS_FEATURE_FLAGS="Scaleway" ``` diff --git a/tutorials/how-to-implement-rag-generativeapis/index.mdx b/tutorials/how-to-implement-rag-generativeapis/index.mdx index 570689a1fc..053bee87d2 100644 --- a/tutorials/how-to-implement-rag-generativeapis/index.mdx +++ b/tutorials/how-to-implement-rag-generativeapis/index.mdx @@ -59,11 +59,11 @@ Create a .env file and add the following variables. These will store your API ke SCW_DB_HOST=your_scaleway_managed_db_host # The IP address of your database instance SCW_DB_PORT=your_scaleway_managed_db_port # The port number for your database instance - # Scaleway S3 bucket configuration + # Scaleway Object Storage bucket configuration ## Will be used to store your proprietary data (PDF, CSV etc) SCW_BUCKET_NAME=your_scaleway_bucket_name SCW_REGION=fr-par - SCW_BUCKET_ENDPOINT="https://s3.{{SCW_REGION}}.scw.cloud" # S3 main endpoint, e.g., https://s3.fr-par.scw.cloud + SCW_BUCKET_ENDPOINT="https://s3.{{SCW_REGION}}.scw.cloud" # Object Storage main endpoint, e.g., https://s3.fr-par.scw.cloud # Scaleway Generative APIs endpoint ## LLM and Embedding model are served through this base URL @@ -196,7 +196,7 @@ page_iterator = paginator.paginate(Bucket=os.getenv("SCW_BUCKET_NAME", "")) In this code sample, we: - Set up a Boto3 session: we initialize a Boto3 session, which is the AWS SDK for Python, fully compatible with Scaleway Object Storage. This session manages configuration, including credentials and settings, that Boto3 uses for API requests. -- Create an S3 client: we establish an S3 client to interact with the Scaleway Object Storage service. +- Create an Amazon S3 client: we establish an Amazon client to interact with the Scaleway Object Storage service. - Set up pagination for listing objects: we prepare pagination to handle potentially large lists of objects efficiently. - Iterate through the bucket: this initiates the pagination process, allowing us to list all objects within the specified Scaleway Object bucket seamlessly. diff --git a/tutorials/how-to-implement-rag/index.mdx b/tutorials/how-to-implement-rag/index.mdx index d6197c4d74..2512c9b477 100644 --- a/tutorials/how-to-implement-rag/index.mdx +++ b/tutorials/how-to-implement-rag/index.mdx @@ -59,9 +59,9 @@ Create a .env file and add the following variables. These will store your API ke SCW_DB_HOST=your_scaleway_managed_db_host # The IP address of your database instance SCW_DB_PORT=your_scaleway_managed_db_port # The port number for your database instance - # Scaleway S3 bucket configuration + # Scaleway Object Storage bucket configuration SCW_BUCKET_NAME=your_scaleway_bucket_name - SCW_BUCKET_ENDPOINT="https://s3.{{SCW_REGION}}.scw.cloud" # S3 endpoint, e.g., https://s3.fr-par.scw.cloud + SCW_BUCKET_ENDPOINT="https://s3.{{SCW_REGION}}.scw.cloud" # Object Storage endpoint, e.g., https://s3.fr-par.scw.cloud # Scaleway Inference API configuration (Embeddings) SCW_INFERENCE_EMBEDDINGS_ENDPOINT="https://{{SCW_INFERENCE_EMBEDDINGS_DEPLOYMENT_ID}}.ifr.fr-par.scaleway.com/v1" # Endpoint for sentence-transformers/sentence-t5-xxl deployment @@ -207,7 +207,7 @@ page_iterator = paginator.paginate(Bucket=BUCKET_NAME) In this code sample we: - Set up a Boto3 session: We initialize a Boto3 session, which is the AWS SDK for Python, fully compatible with Scaleway Object Storage. This session manages configuration, including credentials and settings, that Boto3 uses for API requests. -- Create an S3 client: We establish an S3 client to interact with the Scaleway Object Storage service. +- Create an Amazon S3 client: We establish an Amazon S3 client to interact with the Scaleway Object Storage service. - Set up pagination for listing objects: We prepare pagination to handle potentially large lists of objects efficiently. - Iterate through the bucket: This initiates the pagination process, allowing us to list all objects within the specified Scaleway Object bucket seamlessly. diff --git a/tutorials/k8s-velero-backup/index.mdx b/tutorials/k8s-velero-backup/index.mdx index f88c4673ea..846850de0a 100644 --- a/tutorials/k8s-velero-backup/index.mdx +++ b/tutorials/k8s-velero-backup/index.mdx @@ -14,7 +14,7 @@ dates: posted: 2023-06-02 --- -Velero is an open-source utility designed to facilitate the backup, restoration, and migration of Kubernetes cluster resources and persistent volumes on S3-compatible Object Storage. Originally developed by Heptio, it became part of VMware following an acquisition. Velero offers a straightforward and effective approach to protecting your Kubernetes applications and data through regular backups and supporting disaster recovery measures. +Velero is an open-source utility designed to facilitate the backup, restoration, and migration of Kubernetes cluster resources and persistent volumes on Amazon S3-compatible Object Storage. Originally developed by Heptio, it became part of VMware following an acquisition. Velero offers a straightforward and effective approach to protecting your Kubernetes applications and data through regular backups and supporting disaster recovery measures. With Velero, users can generate either scheduled or on-demand backups encompassing the entire cluster or specific namespaces. These backups comprehensively capture the state of all resources within the cluster, including deployments, services, config maps, secrets, and persistent volumes. Velero ensures the preservation of associated metadata and labels, guaranteeing the completeness and accuracy of the backups for potential restoration. diff --git a/tutorials/large-messages/index.mdx b/tutorials/large-messages/index.mdx index 342ae7398b..6e7d17ffac 100644 --- a/tutorials/large-messages/index.mdx +++ b/tutorials/large-messages/index.mdx @@ -296,7 +296,7 @@ We continue using the Scaleway ecosystem and deploy the consumer using a Serverl secret_access_key = os.getenv("SECRET_ACCESS_KEY") ``` -10. Get the input file name from the body, define the PDF file name from this, and set up the s3 client to upload the file with Scaleway credentials. +10. Get the input file name from the body, define the PDF file name from this, and set up the Amazon S3 client to upload the file with Scaleway credentials. ```python input_file = event['body'] output_file = os.path.splitext(input_file)[0] + ".pdf" @@ -318,7 +318,7 @@ We continue using the Scaleway ecosystem and deploy the consumer using a Serverl print("Successfully made pdf file") ``` -12. Download the image from the bucket using the s3 client. +12. Download the image from the bucket using the Amazon S3 client. ```python s3.download_file(bucket_name, input_file, input_file) print("Object " + input_file + " downloaded") @@ -331,7 +331,7 @@ We continue using the Scaleway ecosystem and deploy the consumer using a Serverl print("Object " + input_file + " uploaded") ``` -14. Put a `try/except` around the code to gracefully handle any errors coming from the S3 client. +14. Put a `try/except` around the code to gracefully handle any errors coming from the Object Storage client. ```python try: s3.download_file(bucket_name, input_file, input_file) diff --git a/tutorials/mastodon-community/index.mdx b/tutorials/mastodon-community/index.mdx index 5fdbaa3d8d..cc50fd453b 100644 --- a/tutorials/mastodon-community/index.mdx +++ b/tutorials/mastodon-community/index.mdx @@ -18,7 +18,7 @@ Mastodon is an open-source, self-hosted, social media and social networking serv As there is no central server, you can choose whether to join or leave an instance according to its policy without actually leaving Mastodon Social Network. Mastodon is a part of [Fediverse](https://fediverse.party/), allowing users to interact with users on other platforms that support the same protocol for example: [PeerTube](https://joinpeertube.org/en/), [Friendica](https://friendi.ca/) and [GNU Social](https://gnu.io/social/). -Mastodon provides the possibility of using [S3 compatible Object Storage](/storage/object/how-to/create-a-bucket/) to store media content uploaded to Instances, making it flexible and scalable. +Mastodon provides the possibility of using [Amazon S3-compatible Object Storage](/storage/object/how-to/create-a-bucket/) to store media content uploaded to Instances, making it flexible and scalable. @@ -338,7 +338,7 @@ Mastodon requires access to a PostgreSQL database to store its configuration and ``` Provider Amazon S3 - S3 bucket name: [scaleway_bucket_name] + Object Storage bucket name: [scaleway_bucket_name] S3 region: fr-par S3 hostname: s3.fr-par.scw.cloud S3 access key: [scaleway_access_key] diff --git a/tutorials/migrate-data-minio-client/index.mdx b/tutorials/migrate-data-minio-client/index.mdx index fa37399a0e..273400d861 100644 --- a/tutorials/migrate-data-minio-client/index.mdx +++ b/tutorials/migrate-data-minio-client/index.mdx @@ -14,7 +14,7 @@ dates: posted: 2019-03-20 --- -The [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html) provides a modern alternative to UNIX commands like ls, cat, cp, mirror, diff, etc. It can communicate with any S3-compatible cloud storage provider and can be used to migrate data from one region to another. +The [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html) provides a modern alternative to UNIX commands like ls, cat, cp, mirror, diff, etc. It can communicate with any Amazon S3-compatible cloud storage provider and can be used to migrate data from one region to another. @@ -53,7 +53,7 @@ The [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html) prov 2. Optionally, add other providers: - For S3-compatible storage: + For Amazon S3-compatible storage: ``` mc config host add s3 --api S3v4 ``` @@ -74,7 +74,7 @@ The [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html) prov ``` The commands above: - 1. Migrates data from a S3 compatible Object Storage to Scaleway's **fr-par** Object Storage + 1. Migrates data from an Amazon S3-compatible Object Storage to Scaleway's **fr-par** Object Storage 2. Migrates data from GCS Object Storage to Scaleway's **nl-ams** Object Storage diff --git a/tutorials/migrate-data-rclone/index.mdx b/tutorials/migrate-data-rclone/index.mdx index 7d105cfba9..fd14d7138f 100644 --- a/tutorials/migrate-data-rclone/index.mdx +++ b/tutorials/migrate-data-rclone/index.mdx @@ -14,7 +14,7 @@ dates: posted: 2019-03-20 --- -Rclone provides a modern alternative to `rsync`. The tool communicates with any S3-compatible cloud storage provider as well as other storage platforms and can be used to migrate data from one bucket to another, even if those buckets are in different regions. +Rclone provides a modern alternative to `rsync`. The tool communicates with any Amazon S3-compatible cloud storage provider as well as other storage platforms and can be used to migrate data from one bucket to another, even if those buckets are in different regions. diff --git a/tutorials/nvidia-triton/index.mdx b/tutorials/nvidia-triton/index.mdx index c5a956604e..75967228b7 100644 --- a/tutorials/nvidia-triton/index.mdx +++ b/tutorials/nvidia-triton/index.mdx @@ -46,9 +46,9 @@ For this tutorial, we will use a pre-trained model available in the Triton Infer ./fetch_models.sh ``` 5. Navigate to the `server/docs/examples/model_repository` directory within the cloned repository. -6. Upload the example model folder to your bucket in Scaleway Object Storage. You can use the [Scaleway Object Storage API](/storage/object/api-cli/using-api-call-list/), any S3 compatible tool, or web interface to upload the model folder. +6. Upload the example model folder to your bucket in Scaleway Object Storage. You can use the [Scaleway Object Storage API](/storage/object/api-cli/using-api-call-list/), any Amazon S3-compatible tool, or web interface to upload the model folder. - You can use the `s3cmd` [command-line tool](/tutorials/s3cmd/) or any other S3-compatible tool to upload your data. + You can use the `s3cmd` [command-line tool](/tutorials/s3cmd/) or any other Amazon S3-compatible tool to upload your data. ## Configuring Triton Inference Server diff --git a/tutorials/object-storage-s3fs/index.mdx b/tutorials/object-storage-s3fs/index.mdx index f105cc58bd..9074b3f0e6 100644 --- a/tutorials/object-storage-s3fs/index.mdx +++ b/tutorials/object-storage-s3fs/index.mdx @@ -13,7 +13,7 @@ dates: posted: 2018-07-16 --- -In this tutorial you learn how to use [s3fs](https://github.com/s3fs-fuse/s3fs-fuse) as a client for [Scaleway Object Storage](/storage/object/concepts/#object-storage). `s3fs` is a FUSE-backed file interface for S3, allowing you to mount your S3 buckets on your local Linux or macOS operating system. `s3fs` preserves the native object format for files, so they can be used with other tools including AWS CLI. +In this tutorial you learn how to use [s3fs](https://github.com/s3fs-fuse/s3fs-fuse) as a client for [Scaleway Object Storage](/storage/object/concepts/#object-storage). `s3fs` is a FUSE-backed file interface for S3, allowing you to mount your Object Storage buckets on your local Linux or macOS operating system. `s3fs` preserves the native object format for files, so they can be used with other tools including AWS CLI. The version of `s3fs` available for installation using the systems package manager does not support files larger than 10 GB. It is therefore recommended to compile a version, including the required corrections, from the s3fs source code repository. This tutorial will guide you through that process. Note that even with the source code compiled version of s3fs, there is a [maximum file size of 128 GB](#configuring-s3fs) when using s3fs with Scaleway Object Storage. @@ -92,7 +92,7 @@ Next, download and install `s3fs-fuse` itself: ## Configuring s3fs -1. Execute the following commands to enter your S3 credentials (separated by a `:`) in a file `$HOME/.passwd-s3fs` and set owner-only permissions. This presumes that you have set your [API credentials](/identity-and-access-management/iam/how-to/create-api-keys/) as environment variables named `ACCESS_KEY` and `SECRET_KEY`: +1. Execute the following commands to enter your credentials (separated by a `:`) in a file `$HOME/.passwd-s3fs` and set owner-only permissions. This presumes that you have set your [API credentials](/identity-and-access-management/iam/how-to/create-api-keys/) as environment variables named `ACCESS_KEY` and `SECRET_KEY`: ``` echo $ACCESS_KEY:$SECRET_KEY > $HOME/.passwd-s3fs chmod 600 $HOME/.passwd-s3fs @@ -123,7 +123,7 @@ Next, download and install `s3fs-fuse` itself: The file system of the mounted bucket will appear in your OS like a local file system. This means you can access the files as if they were on your hard drive. -Note that there are some limitations when using S3 as a file system: +Note that there are some limitations when using Object Storage as a file system: - Random writes or appends to files require rewriting the entire file - Metadata operations such as listing directories have poor performance due to network latency diff --git a/tutorials/restic-s3-backup/index.mdx b/tutorials/restic-s3-backup/index.mdx index db93f9a8d0..9b6ae1227b 100644 --- a/tutorials/restic-s3-backup/index.mdx +++ b/tutorials/restic-s3-backup/index.mdx @@ -15,7 +15,7 @@ dates: posted: 2022-04-04 --- -Restic is a backup tool that allows you to back up your Linux, Windows, Mac, or BSD machines and send your backups to repositories via [different storage protocols](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html), including S3 (Object Storage). +Restic is a backup tool that allows you to back up your Linux, Windows, Mac, or BSD machines and send your backups to repositories via [different storage protocols](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html), including Object Storage. In this tutorial, you learn how to backup a Scaleway Instance running on Ubuntu 20.04 using Restic and Object Storage. @@ -48,7 +48,7 @@ In this tutorial, you learn how to backup a Scaleway Instance running on Ubuntu restic version ``` -## Setting up the S3 repository +## Setting up the Object Storage repository A repository is the storage space where your backups will be hosted. In this tutorial, we will use Scaleway Object Storage buckets to host our backups. diff --git a/tutorials/s3-customize-url-cname/index.mdx b/tutorials/s3-customize-url-cname/index.mdx index 8ed7e55216..3f22787a1c 100644 --- a/tutorials/s3-customize-url-cname/index.mdx +++ b/tutorials/s3-customize-url-cname/index.mdx @@ -1,15 +1,15 @@ --- meta: - title: S3 Object Storage - Customizing URLs with CNAME + title: Object Storage - Customizing URLs with CNAME description: This page shows how to use a customized domain name with Object Storage buckets content: - h1: S3 Object Storage - Customizing URLs with CNAME + h1: Object Storage - Customizing URLs with CNAME paragraph: This page shows how to use a customized domain name with Object Storage buckets categories: - storage - object-storage - domains-and-dns -tags: Object-Storage CNAME domain S3 +tags: Object-Storage CNAME domain amazon-S3 dates: validation: 2024-07-16 posted: 2019-05-21 diff --git a/tutorials/setup-nginx-reverse-proxy-s3/index.mdx b/tutorials/setup-nginx-reverse-proxy-s3/index.mdx index fa38b87eeb..091f7480fc 100644 --- a/tutorials/setup-nginx-reverse-proxy-s3/index.mdx +++ b/tutorials/setup-nginx-reverse-proxy-s3/index.mdx @@ -1,11 +1,11 @@ --- meta: - title: Setting up Nginx as a reverse proxy with S3 Object Storage - description: Learn how to configure an Nginx reverse proxy with Scaleway Object Storage (S3) for optimized access and caching. + title: Setting up Nginx as a reverse proxy with Object Storage + description: Learn how to configure an Nginx reverse proxy with Scaleway Object Storage for optimized access and caching. content: - h1: Setting up Nginx as a reverse proxy with S3 Object Storage - paragraph: This guide shows you how to configure an Nginx reverse proxy with Scaleway S3 Object Storage for optimized access and caching. -tags: Object-Storage, S3, reverse-proxy, nginx + h1: Setting up Nginx as a reverse proxy with Object Storage + paragraph: This guide shows you how to configure an Nginx reverse proxy with Scaleway Object Storage for optimized access and caching. +tags: Object-Storage amazon-S3 reverse-proxy nginx categories: - instances - object-storage @@ -156,7 +156,7 @@ You can now access the files of your bucket by going directly to `http://s3proxy ## Configuring Nginx as a reverse proxy for HTTPS -Connections to your S3 proxy are currently available in plain, unencrypted HTTP only. It is possible to encrypt the connection between the client and the Nginx proxy by configuring HTTPS. To do so, we will obtain a free SSL certificate issued by [Let's Encrypt](https://letsencrypt.org/) using [Certbot](https://certbot.eff.org/), a tool to obtain, manage and renew Let's Encrypt certificates automatically. +Connections to your proxy are currently available in plain, unencrypted HTTP only. It is possible to encrypt the connection between the client and the Nginx proxy by configuring HTTPS. To do so, we will obtain a free SSL certificate issued by [Let's Encrypt](https://letsencrypt.org/) using [Certbot](https://certbot.eff.org/), a tool to obtain, manage and renew Let's Encrypt certificates automatically. 1. Add the Certbot repository to apt to download the latest release of the software. Certbot is in active development and the packages included in Ubuntu may be already outdated. ``` diff --git a/tutorials/terraform-quickstart/index.mdx b/tutorials/terraform-quickstart/index.mdx index 004d9066df..8b5b215f3e 100644 --- a/tutorials/terraform-quickstart/index.mdx +++ b/tutorials/terraform-quickstart/index.mdx @@ -590,7 +590,7 @@ Apply the new configuration using `terraform apply`. Terraform will add an Elast ## Storing the Terraform state in the cloud -Optionally, you can use the S3 Backend to store your Terraform state in a [Scaleway Object Storage](https://www.scaleway.com/en/object-storage/). Configure your backend as follows: +Optionally, you can store your Terraform state with [Scaleway Object Storage](https://www.scaleway.com/en/object-storage/). Configure your backend as follows: ```json terraform { diff --git a/tutorials/transform-bucket-images-triggers-functions-deploy/index.mdx b/tutorials/transform-bucket-images-triggers-functions-deploy/index.mdx index 68b922460d..6fa010894c 100644 --- a/tutorials/transform-bucket-images-triggers-functions-deploy/index.mdx +++ b/tutorials/transform-bucket-images-triggers-functions-deploy/index.mdx @@ -1,10 +1,10 @@ --- meta: - title: Transforming images in an S3 bucket using Serverless Functions and Triggers - Deployment - description: This page shows you how to create and deploy functions to transform images in an S3 bucket using Serverless Functions and Triggers + title: Transforming images in an Object Storage bucket using Serverless Functions and Triggers - Deployment + description: This page shows you how to create and deploy functions to transform images in an Object Storage bucket using Serverless Functions and Triggers content: - h1: Transforming images in an S3 bucket using Serverless Functions and Triggers - Deployment - paragraph: This page shows you how to create and deploy functions to transform images in an S3 bucket using Serverless Functions and Triggers + h1: Transforming images in an Object Storage bucket using Serverless Functions and Triggers - Deployment + paragraph: This page shows you how to create and deploy functions to transform images in an Object Storage bucket using Serverless Functions and Triggers categories: - functions - messaging @@ -52,7 +52,7 @@ You will now learn how to deploy Serverless Functions and connect them using tri const SQS_ENDPOINT = process.env.SQS_ENDPOINT; const S3_ENDPOINT = `https://s3.${S3_REGION}.scw.cloud`; - // Create S3 service object + // Create Object Storage service object const s3Client = new S3Client({ credentials: { accessKeyId: S3_ACCESS_KEY_ID, @@ -174,7 +174,7 @@ You will now learn how to deploy Serverless Functions and connect them using tri width = 200; } - // Create S3 service object + // Create Object Storage service object const s3Client = new S3Client({ credentials: { accessKeyId: S3_ACCESS_KEY_ID, @@ -222,7 +222,7 @@ You will now learn how to deploy Serverless Functions and connect them using tri }; }; - // Download the image from the S3 source bucket. + // Download the image from the Object Storage source bucket. try { const input = { Bucket: SOURCE_BUCKET, diff --git a/tutorials/transform-bucket-images-triggers-functions-set-up/index.mdx b/tutorials/transform-bucket-images-triggers-functions-set-up/index.mdx index 0314dc3f5c..1960b96af4 100644 --- a/tutorials/transform-bucket-images-triggers-functions-set-up/index.mdx +++ b/tutorials/transform-bucket-images-triggers-functions-set-up/index.mdx @@ -1,10 +1,10 @@ --- meta: - title: Transforming images in an S3 bucket using Serverless Functions and Triggers - Set up - description: This page shows you how to set up your environment to transform images in an S3 bucket using Serverless Functions and Triggers + title: Transforming images in an Object Storage bucket using Serverless Functions and Triggers - Set up + description: This page shows you how to set up your environment to transform images in an Object Storage bucket using Serverless Functions and Triggers content: - h1: Transforming images in an S3 bucket using Serverless Functions and Triggers - Set up - paragraph: This page shows you how to set up your environment to transform images in an S3 bucket using Serverless Functions and Triggers + h1: Transforming images in an Object Storage bucket using Serverless Functions and Triggers - Set up + paragraph: This page shows you how to set up your environment to transform images in an Object Storage bucket using Serverless Functions and Triggers categories: - messaging - functions diff --git a/tutorials/veeam-backup-replication-s3/index.mdx b/tutorials/veeam-backup-replication-s3/index.mdx index e160419678..31ac4ddfea 100644 --- a/tutorials/veeam-backup-replication-s3/index.mdx +++ b/tutorials/veeam-backup-replication-s3/index.mdx @@ -18,7 +18,7 @@ dates: The solution provides backup, restore, and replication functionality for virtual machines, physical servers, and workstations as well as cloud-based workloads. -A native S3 interface for Veeam Backup & Replication is part of the Release 9.5 update 4, available in General Availability since January 22nd, 2019. It allows to push backups to an S3-compatible service to maximize backup capacity. +A native Object Storage interface for Veeam Backup & Replication is part of the Release 9.5 update 4, available in General Availability since January 22nd, 2019. It allows to push backups to an Amazon S3-compatible service to maximize backup capacity. The following schema represents the functionality of Veeam Backup and Restore which acts as an intermediate agent to manage primary data storage and secondary and archival storage: @@ -78,7 +78,7 @@ The following schema represents the functionality of Veeam Backup and Restore wh For a bucket located in the Amsterdam region, the service point is `s3.nl-ams.scw.cloud` and the region is `nl-ams`. -11. Veeam will connect to the S3 infrastructure and download the list of Object Storage Buckets. Choose the bucket to be used with Veeam from the drop-down list, click **Browse**, and create and select the folder for storing backups. Then click **Next**: +11. Veeam will connect to the Object Storage infrastructure and download the list of buckets. Choose the bucket to be used with Veeam from the drop-down list, click **Browse**, and create and select the folder for storing backups. Then click **Next**: @@ -87,7 +87,7 @@ The following schema represents the functionality of Veeam Backup and Restore wh ### Configuring a local backup repository -1. As Veeam cannot currently push backups directly to S3, a local backup repository is required which will be configured as **Storage Tier** with Object Storage in a later step. Click **Add Repository**: +1. As Veeam cannot currently push backups directly to an Amazon S3-compatible system, a local backup repository is required which will be configured as **Storage Tier** with Object Storage in a later step. Click **Add Repository**: 2. Choose **Direct Attached Storage** from the provided options: @@ -175,7 +175,7 @@ This section is designed to help you solve common issues encountered while perfo #### Cause -The application cannot access the S3 resource. +The application cannot access the Object Storage resource. #### Solution @@ -200,7 +200,7 @@ Scaleway Object Storage applies a rate limit on PUT operations for safety reason #### Solution -You can limit the number of concurrent tasks and update the timeout duration of S3 requests on the Veeam Backup & Replication server managing the backup copy operation by adding the elements below: +You can limit the number of concurrent tasks and update the timeout duration of Object Storage requests on the Veeam Backup & Replication server managing the backup copy operation by adding the elements below: ``` HKEY_LOCAL_MACHINE\SOFTWARE\Veeam\Veeam Backup and Replication @@ -228,7 +228,7 @@ You may experience reduced throughput due to the limitation. If you did not manage to identify the error and solve it by yourself, [open a support ticket](/console/account/how-to/open-a-support-ticket/), and provide as many details as possible, along with the necessary information below: -- S3 Endpoint (e.g. `s3.fr-par.scw.cloud`) +- Object Storage Endpoint (e.g. `s3.fr-par.scw.cloud`) - Bucket name - Object name (if the request concerns an object) - Request type (PUT, GET, etc.) From 8196ac62cb53d365779dc47bb9c603a75b3f5aab Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Tue, 29 Oct 2024 10:59:36 +0100 Subject: [PATCH 58/68] feat(instances): understanding qga (#3896) --- ...-instance-specific-ssh-keys-using-tags.mdx | 2 +- ...-automatic-network-hot-reconfiguration.mdx | 82 +++++++++++++ .../understanding-qemu-guest-agent.mdx | 112 ++++++++++++++++++ menu/navigation.json | 8 ++ 4 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 compute/instances/reference-content/understanding-automatic-network-hot-reconfiguration.mdx create mode 100644 compute/instances/reference-content/understanding-qemu-guest-agent.mdx diff --git a/compute/instances/reference-content/add-instance-specific-ssh-keys-using-tags.mdx b/compute/instances/reference-content/add-instance-specific-ssh-keys-using-tags.mdx index e91082f8a3..f0073fdafe 100644 --- a/compute/instances/reference-content/add-instance-specific-ssh-keys-using-tags.mdx +++ b/compute/instances/reference-content/add-instance-specific-ssh-keys-using-tags.mdx @@ -10,7 +10,7 @@ categories: dates: validation: 2024-10-08 posted: 2024-10-08 -tags: Instance ssh-key ssh tag +tags: instance ssh-key ssh tag --- In cloud environments, managing SSH keys across multiple Instances is key to keeping your infrastructure secure and easy to access. diff --git a/compute/instances/reference-content/understanding-automatic-network-hot-reconfiguration.mdx b/compute/instances/reference-content/understanding-automatic-network-hot-reconfiguration.mdx new file mode 100644 index 0000000000..ef266ad380 --- /dev/null +++ b/compute/instances/reference-content/understanding-automatic-network-hot-reconfiguration.mdx @@ -0,0 +1,82 @@ +--- +meta: + title: Understanding automatic network hot-reconfiguration for Scaleway Instances + description: Find out how to configure automatic network hot-reconfiguration for Scaleway Instances. +content: + h1: Understanding automatic network hot-reconfiguration for Scaleway Instances + paragraph: Find out how to configure automatic network hot-reconfiguration for Scaleway Instances. +categories: + - compute +dates: + validation: 2024-10-29 + posted: 2024-10-29 +tags: instance network hot-reconfiguration +--- + +The Scaleway Instances product includes a feature called **automatic network hot-reconfiguration**. + +This mechanism automatically configures or deconfigures a [flexible IP address](/compute/instances/concepts/#flexible-ip) in the guest operating system when it is attached to or detached from an Instance. + +This guide explains how to enable or disable the automatic network hot-reconfiguration mechanism on your Instance. + + + This documentation page does not apply to Instances running the Microsoft Windows operating system. + + +## Supported configurations + +Before proceeding, ensure that your operating system supports the target network configuration: refer to Scaleway’s compatibility guidelines on [OS images and flexible IP type combinations](/compute/instances/reference-content/comaptibility-scw-os-images-flexible-ip/). + +Starting from **October 10th, 2024**, all GNU/Linux-based operating systems and InstantApp images for Scaleway Instances have automatic network hot-reconfiguration enabled by default. + +To verify that the feature is active on your Instance, use the following command: + +```bash +# systemctl is-active scw-net-reconfig.path +``` + +If the output is `active`, the feature is enabled and ready to use. If the output is `inactive`, you have to enable it first. + + +### Enabling network hot-reconfiguration + +Follow these steps to enable automatic network hot-reconfiguration on a Scaleway Instance where the feature is currently inactive. + +1. Enable the QEMU Guest Agent. Refer to Scaleway’s documentation on [enabling the QEMU Guest Agent (GQA)](/compute/instances/reference-content/understanding-qemu-guest-agent/#opting-in) for further details. + +2. Install the latest Scaleway ecosystem package. + + - **Fedora / AlmaLinux / RockyLinux / CentOS** + ```bash + # yum -y --best install scaleway-ecosystem + ``` + + - **Debian / Ubuntu** + ```bash + # apt-get update + # apt-get -y install scaleway-ecosystem + ``` + + + Ensure you install version `0.0.7-1` or higher of the `scaleway-ecosystem` package. + + +3. Enable the automatic network reconfiguration mechanism. + + On Debian and Ubuntu systems, the mechanism typically activates automatically after installing or upgrading the `scaleway-ecosystem` package. However, RedHat-based distributions may require a manual start: + + ```bash + # systemctl enable --now scw-net-reconfig.path + ``` + + + Rebooting your Instance will also activate network hot-reconfiguration. + + +### Disabling network hot-reconfiguration + +If you prefer to prevent automatic network reconfiguration when a flexible IP is attached or detached, run the following command: + + ```bash + # systemctl disable --now scw-net-reconfig.path + ``` \ No newline at end of file diff --git a/compute/instances/reference-content/understanding-qemu-guest-agent.mdx b/compute/instances/reference-content/understanding-qemu-guest-agent.mdx new file mode 100644 index 0000000000..90775b5f8a --- /dev/null +++ b/compute/instances/reference-content/understanding-qemu-guest-agent.mdx @@ -0,0 +1,112 @@ +--- +meta: + title: Understanding the QEMU Guest Agent in Scaleway Instances + description: Discover how the QEMU Guest Agent works with Scaleway Instances. +content: + h1: Understanding the QEMU Guest Agent in Scaleway Instances + paragraph: Discover how the QEMU Guest Agent works with Scaleway Instances. +tags: instance qga guemu guest agent +dates: + validation: 2024-10-28 +categories: + - compute +--- + +Some features of the Instances product require Scaleway's infrastructure to query or exchange information with your Instance. To enable this communication, a software component must run on the guest operating system: the QEMU Guest Agent (QGA). + +This page provides essential insights into this mechanism. + + + This documentation page does not apply to Instances running the Microsoft Windows operating system. + + +## What are the features provided by QGA? + +Running the QEMU Guest Agent (QGA) on your Instance currently enables the following feature: + +- **Automatic network reconfiguration** upon flexible IP attachment or detachment [Learn how to enable/disable this feature](/compute/instances/reference-content/understanding-automatic-network-hot-reconfiguration/). + +Additional features may be added in the future. + +## Checking QGA's status + +Since March 1st, 2024, all Scaleway-provided GNU/Linux and InstantApp images for Instances come with QGA pre-installed and enabled by default. + +To verify that QGA is running on your Instance, use the following command: + +```bash +# systemctl is-active qemu-guest-agent.service +``` + +If the output is `active`, QGA is running, and you are ready to benefit from the associated features. If the output is `inactive`, you may need to install and/or activate QGA. + +## Opting in + +Follow these steps to enable QGA on an Instance where it is currently inactive. + +### Installation + +Instances created from images older than March 1st, 2024 may require manual installation of the `qemu-guest-agent` package: + +- **Fedora / AlmaLinux / RockyLinux / CentOS** + + ```bash + # yum -y --best install qemu-guest-agent + ``` + +- **Debian / Ubuntu** + + ```bash + # apt-get update + # apt-get -y install qemu-guest-agent + ``` + +### Activation + +After installing the package, start the `qemu-guest-agent.service` by either: + +- Rebooting your Instance, or +- Running the following command: + + ```bash + # systemctl start qemu-guest-agent.service + ``` + +## Opting Out + +Follow these steps to disable QGA and the associated Scaleway features. + +### Deactivation + + + Disabling QGA is not recommended, as doing so also disables all the [Scaleway features](#what-are-the-features-provided-by-qga) it provides. + + +To stop and disable QGA, run: + +```bash +# systemctl stop qemu-guest-agent.service +# systemctl mask qemu-guest-agent.service +``` + +This stops the service and prevents it from starting on subsequent reboots. + +### Deinstallation (Optional) + + + You do not necessarily need to deinstall QGA to opt out. [Deactivating the service](#deactivation) is sufficient. + + +If you prefer to completely remove QGA, ensure the service is stopped first, then run: + +- **Fedora / AlmaLinux / RockyLinux / CentOS** + + ```bash + # yum -y remove qemu-guest-agent + ``` + +- **Debian / Ubuntu** + + ```bash + # apt-get -y purge qemu-guest-agent + ``` \ No newline at end of file diff --git a/menu/navigation.json b/menu/navigation.json index 1d706b7314..8badfd3745 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -1357,6 +1357,14 @@ "label": "Understanding the differences between ARM and x86 Instances", "slug": "understanding-differences-x86-arm" }, + { + "label": "Understanding QEMU Guest Agent", + "slug": "understanding-qemu-guest-agent" + }, + { + "label": "Understanding automatic network hot-reconfiguration", + "slug": "understanding-automatic-network-hot-reconfiguration" + }, { "label": "Understanding Instance pricing", "slug": "understanding-instance-pricing" From 7c996be899ed3f3e8b3925e948c536d45975bd59 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Tue, 29 Oct 2024 11:02:29 +0100 Subject: [PATCH 59/68] chore(tutorials): review (#3902) * chore(tutorials): review * chore(tuto): content review * Update tutorials/terraform-quickstart/index.mdx Co-authored-by: Jessica <113192637+jcirinosclwy@users.noreply.github.com> --------- Co-authored-by: Jessica <113192637+jcirinosclwy@users.noreply.github.com> --- managed-services/webhosting/concepts.mdx | 2 +- .../configure-chef-ubuntu-xenial/index.mdx | 2 +- .../configure-failover-proxmox/index.mdx | 2 +- .../index.mdx | 2 +- .../index.mdx | 4 +- .../configure-nextcloud-ubuntu/index.mdx | 2 +- .../configure-nginx-lets-encrypt/index.mdx | 4 +- .../index.mdx | 4 +- .../index.mdx | 2 +- tutorials/sinatra/index.mdx | 2 +- tutorials/store-s3-cyberduck/index.mdx | 10 ++--- tutorials/store-wp-mediacloud-s3/index.mdx | 2 +- tutorials/systemd-essentials/index.mdx | 2 +- tutorials/terraform-quickstart/index.mdx | 39 +++++++++++++++---- tutorials/trigger-ifttt-actions/index.mdx | 4 +- .../wordpress-lemp-stack-focal/index.mdx | 2 +- 16 files changed, 53 insertions(+), 32 deletions(-) diff --git a/managed-services/webhosting/concepts.mdx b/managed-services/webhosting/concepts.mdx index 72720dcc67..d74f3805a6 100644 --- a/managed-services/webhosting/concepts.mdx +++ b/managed-services/webhosting/concepts.mdx @@ -7,7 +7,7 @@ content: paragraph: This page explains all the concepts related to Scaleway’s Web Hosting service tags: managed-services webhosting dates: - validation: 2024-04-22 + validation: 2024-10-28 categories: - managed-services --- diff --git a/tutorials/configure-chef-ubuntu-xenial/index.mdx b/tutorials/configure-chef-ubuntu-xenial/index.mdx index 9cc4c8aa9b..0fb3a6363d 100644 --- a/tutorials/configure-chef-ubuntu-xenial/index.mdx +++ b/tutorials/configure-chef-ubuntu-xenial/index.mdx @@ -9,7 +9,7 @@ tags: Chef Ubuntu Xenial Focal-Fossa categories: - instances dates: - validation: 2024-04-22 + validation: 2024-10-28 posted: 2018-07-05 --- diff --git a/tutorials/configure-failover-proxmox/index.mdx b/tutorials/configure-failover-proxmox/index.mdx index 96a23b20ee..015d3a4317 100644 --- a/tutorials/configure-failover-proxmox/index.mdx +++ b/tutorials/configure-failover-proxmox/index.mdx @@ -9,7 +9,7 @@ tags: dedicated-server Proxmox iso-file categories: - dedibox dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2020-01-23 --- diff --git a/tutorials/configure-ipv6-virtual-machine-esxi/index.mdx b/tutorials/configure-ipv6-virtual-machine-esxi/index.mdx index 2b2968ad4a..56f7ba11de 100644 --- a/tutorials/configure-ipv6-virtual-machine-esxi/index.mdx +++ b/tutorials/configure-ipv6-virtual-machine-esxi/index.mdx @@ -9,7 +9,7 @@ tags: esxi virtual-machine ubuntu categories: - dedibox dates: - validation: 2024-04-22 + validation: 2024-10-28 posted: 2022-02-24 --- diff --git a/tutorials/configure-netbox-managed-postgresql-database/index.mdx b/tutorials/configure-netbox-managed-postgresql-database/index.mdx index a4892c3409..2554e51bfb 100644 --- a/tutorials/configure-netbox-managed-postgresql-database/index.mdx +++ b/tutorials/configure-netbox-managed-postgresql-database/index.mdx @@ -10,13 +10,13 @@ categories: - postgresql-and-mysql hero: assets/scaleway_netbox.webp dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2019-11-14 --- NetBox is a web application designed and built to help manage and document large computer networks. It is designed for IP address management (IPAM) and data center infrastructure management (DCIM). The application runs as a web application based on the Django Python framework and uses a PostgreSQL database to store information. The open-source software was developed specifically with the needs of network and infrastructure engineers in mind. -In this tutorial, you will learn how to install and configure NetBox on an Instance running on Ubuntu 20.04 LTS and a Database for PostgreSQL. +In this tutorial, you learn how to install and configure NetBox on an Instance running on Ubuntu 20.04 LTS and a Database for PostgreSQL. diff --git a/tutorials/configure-nextcloud-ubuntu/index.mdx b/tutorials/configure-nextcloud-ubuntu/index.mdx index f74577d067..34c5b53bc4 100644 --- a/tutorials/configure-nextcloud-ubuntu/index.mdx +++ b/tutorials/configure-nextcloud-ubuntu/index.mdx @@ -9,7 +9,7 @@ categories: - instances tags: Nextcloud Ubuntu-Bionic-Beaver dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2018-10-26 --- diff --git a/tutorials/configure-nginx-lets-encrypt/index.mdx b/tutorials/configure-nginx-lets-encrypt/index.mdx index 37b52519d1..834dd882f9 100644 --- a/tutorials/configure-nginx-lets-encrypt/index.mdx +++ b/tutorials/configure-nginx-lets-encrypt/index.mdx @@ -9,11 +9,11 @@ categories: - instances tags: NGINX Let's-Encrypt dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2019-02-28 --- -Let's Encrypt, a renowned Certificate Authority (CA), offers a valuable service by providing free TLS/SSL certificates. +Let's Encrypt, a renowned Certificate Authority (CA), offers a valuable service by providing free TLS/SSL certificates. These certificates are a key element in enabling secure HTTPS connections on web servers. Let's Encrypt simplifies the process through its user-friendly software client, Certbot, which automates the majority of the steps involved in obtaining and configuring certificates, particularly within the Nginx web server environment. diff --git a/tutorials/configure-tem-smtp-with-wordpress-plugin/index.mdx b/tutorials/configure-tem-smtp-with-wordpress-plugin/index.mdx index eee4f3a561..a4cbe73b91 100644 --- a/tutorials/configure-tem-smtp-with-wordpress-plugin/index.mdx +++ b/tutorials/configure-tem-smtp-with-wordpress-plugin/index.mdx @@ -10,7 +10,7 @@ categories: - transactional-email - instances dates: - validation: 2024-04-24 + validation: 2024-10-29 posted: 2024-04-24 --- @@ -51,7 +51,7 @@ dates: 2. Click the **Launch Setup Wizard** button to configure the plug-in. You are redirected to the WP Mail SMTP welcome page. 3. Click **Let's Get Started**. 4. Choose **Other SMTP**, then click **Save and Continue**. -5. Enter `smtp.tem.scw.cloud` in the **SMTP Host** field. +5. Enter `smtp.tem.scaleway.com` in the **SMTP Host** field. 6. Select **TLS** in the **Encryption** field. 7. In the **SMTP Port** enter either of the Transactional Email TLS connection ports: `465` or `2465`. 8. Switch on the **Enable Authentication** toggle. diff --git a/tutorials/deploy-penpot-with-docker-instantapp/index.mdx b/tutorials/deploy-penpot-with-docker-instantapp/index.mdx index 805199637b..e9c6f3f81a 100644 --- a/tutorials/deploy-penpot-with-docker-instantapp/index.mdx +++ b/tutorials/deploy-penpot-with-docker-instantapp/index.mdx @@ -9,7 +9,7 @@ tags: penpot docker instantapp categories: - instances dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2022-09-28 hero: assets/scaleway-penpot.webp --- diff --git a/tutorials/sinatra/index.mdx b/tutorials/sinatra/index.mdx index eed21f195b..f7e760375b 100644 --- a/tutorials/sinatra/index.mdx +++ b/tutorials/sinatra/index.mdx @@ -9,7 +9,7 @@ tags: ansible Sinatra Ruby RubyGems categories: - instances dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2018-08-17 --- diff --git a/tutorials/store-s3-cyberduck/index.mdx b/tutorials/store-s3-cyberduck/index.mdx index af2c2f2daa..334b82bb05 100644 --- a/tutorials/store-s3-cyberduck/index.mdx +++ b/tutorials/store-s3-cyberduck/index.mdx @@ -1,16 +1,16 @@ --- meta: - title: Storing objects with Object Storage and Cyberduck - description: This page shows you how to store objects with Cyberduck. + title: Storing objects with Scaleway Object Storage and Cyberduck + description: This page shows you how to store objects with Cyberduck on Scaleway Object Storage. content: - h1: Storing objects with Object Storage and Cyberduck - paragraph: This page shows you how to store objects with Cyberduck. + h1: Storing objects with Scaleway Object Storage and Cyberduck + paragraph: This page shows you how to store objects with Cyberduck on Scaleway Object Storage. tags: Cyberduck Object-Storage categories: - storage - object-storage dates: - validation: 2024-04-22 + validation: 2024-10-28 posted: 2018-06-04 --- diff --git a/tutorials/store-wp-mediacloud-s3/index.mdx b/tutorials/store-wp-mediacloud-s3/index.mdx index 46a34ed460..4ef01400f2 100644 --- a/tutorials/store-wp-mediacloud-s3/index.mdx +++ b/tutorials/store-wp-mediacloud-s3/index.mdx @@ -10,7 +10,7 @@ categories: - object-storage - instances dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2019-02-13 --- diff --git a/tutorials/systemd-essentials/index.mdx b/tutorials/systemd-essentials/index.mdx index c3532e21df..b0e6b216c9 100644 --- a/tutorials/systemd-essentials/index.mdx +++ b/tutorials/systemd-essentials/index.mdx @@ -9,7 +9,7 @@ tags: systemd instances categories: - instances dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2018-07-10 --- diff --git a/tutorials/terraform-quickstart/index.mdx b/tutorials/terraform-quickstart/index.mdx index 8b5b215f3e..e3c89f6add 100644 --- a/tutorials/terraform-quickstart/index.mdx +++ b/tutorials/terraform-quickstart/index.mdx @@ -12,7 +12,7 @@ categories: tags: Terraform Elastic-Metal Instances HashiCorp hero: assets/scaleway_terraform.webp dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2018-04-06 --- @@ -51,22 +51,45 @@ The installation of Terraform on Windows can be done in a single command line us The installation of Terraform on Linux can be done in a few simple steps. -1. Download the HashiCorp GPG key on your machine. +1. Ensure your system is up to date and you have installed the `gnupg`, `software-properties-common`, and `curl` packages. ``` - wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg + apt update && apt install -y gnupg software-properties-common ``` -2. Add the Terraform repositories to the apt sources. +2. Download the HashiCorp GPG key on your machine. ``` - echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list + wget -O- https://apt.releases.hashicorp.com/gpg | \ + gpg --dearmor | \ + sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null ``` -3. Update the apt packet cache and install Terraform using `apt`. +3. Verify the key's fingerprint. + ``` + gpg --no-default-keyring \ + --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \ + --fingerprint + ``` + The `gpg` command reports the key's fingerprint: + ``` + /usr/share/keyrings/hashicorp-archive-keyring.gpg + ------------------------------------------------- + pub rsa4096 XXXX-XX-XX [SC] + AAAA AAAA AAAA AAAA + uid [ unknown] HashiCorp Security (HashiCorp Package Signing) + sub rsa4096 XXXX-XX-XX [E] + ``` +4. Add the Terraform repositories to the apt sources. + ``` + echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \ + https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \ + sudo tee /etc/apt/sources.list.d/hashicorp.list + ``` +5. Update the apt packet cache and install Terraform using `apt`. ``` apt update && apt install terraform ``` -4. Test the installation by running the `terraform version` command. +6. Test the installation by running the `terraform version` command. ``` terraform version - Terraform v1.8.1 + Terraform v1.9.8 on linux_amd64 ``` diff --git a/tutorials/trigger-ifttt-actions/index.mdx b/tutorials/trigger-ifttt-actions/index.mdx index cb8fc8b3b9..b31c49155a 100644 --- a/tutorials/trigger-ifttt-actions/index.mdx +++ b/tutorials/trigger-ifttt-actions/index.mdx @@ -10,12 +10,10 @@ hero: assets/scaleway_ifttt.webp categories: - iot-hub dates: - validation: 2024-04-22 + validation: 2024-10-29 posted: 2021-01-04 --- -## Quick & easy application creation with IoT Hub and IFTTT - IFTTT, an acronym for "If This, Then That," offers a user-friendly yet robust automation service, enabling users to trigger actions based on specific events. With an extensive array of customizable events and actions at your fingertips, the possibilities are virtually endless — an incredibly empowering feature. diff --git a/tutorials/wordpress-lemp-stack-focal/index.mdx b/tutorials/wordpress-lemp-stack-focal/index.mdx index 003a130a40..5ac58b0d38 100644 --- a/tutorials/wordpress-lemp-stack-focal/index.mdx +++ b/tutorials/wordpress-lemp-stack-focal/index.mdx @@ -9,7 +9,7 @@ tags: WordPress cms php LEMP nginx mysql mariadb categories: - instances dates: - validation: 2024-04-22 + validation: 2024-10-28 posted: 2021-12-03 --- From a59253a45d4d3018c2eef7567bd7016433fb3c85 Mon Sep 17 00:00:00 2001 From: nerda-codes <87707325+nerda-codes@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:06:25 +0100 Subject: [PATCH 60/68] chore(domains): weekly review (#3904) --- network/domains-and-dns/concepts.mdx | 32 +++++++++---------- .../how-to/manage-dns-records.mdx | 9 +++--- .../understanding-domains-and-dns.mdx | 6 ++-- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/network/domains-and-dns/concepts.mdx b/network/domains-and-dns/concepts.mdx index 5688589fd1..4e70790833 100644 --- a/network/domains-and-dns/concepts.mdx +++ b/network/domains-and-dns/concepts.mdx @@ -7,12 +7,16 @@ content: paragraph: Discover concepts related to Scaleway's Domains and DNS service. Learn about DNS namespaces, name servers, domain names, DNS resolution, records, zones, and more. tags: domains domain dns namespace dns-zone nameserver zone-file reverse-dns root-server dates: - validation: 2024-04-22 + validation: 2024-10-29 categories: - network --- -**DNS namespace** +## DNS + +**D**omain **N**ame **S**ystem is a name management system for computing devices connected to a network, be it public (internet) or private. It translates text-based [domain names](#domain-name) to numerical IP addresses or other services such as emails. + +## DNS namespace DNS domains are all organized in a hierarchy called the DNS namespace. The hierarchy consists of: @@ -22,24 +26,12 @@ DNS domains are all organized in a hierarchy called the DNS namespace. The hiera -**DNS name server** +## DNS name server A DNS name server stores the [DNS Records](#dns-record) for given domains. Scaleway has its own name servers for its managed domains. -## Domain name - -A **domain name** or **domain** is a unique alphanumeric name used to identify a computer (web or email server) on the internet. It translates the numeric address of the computer to a more legible human-readable and memorable name. A domain can consist of a single [DNS Zone](#dns-zone) or be divided into several zones. - -## Domain name resolution - -Domain name resolution refers to the process by which human-readable domain names, like `www.mydomain.com`, are translated into the numerical IP addresses that computers and servers use to communicate on the internet. - -## DNS - -The **D**omain **N**ame **S**ystem is a name management system for computing devices connected to a network, be it public (Internet) or private. It translates text-based [domain names](#domain-name) to numerical IP addresses or other services such as emails. - ## DNS record A [DNS](#dns) Record holds information translating a domain or subdomain to an IP address, mail server or other domain/subdomain. DNS records for each [DNS Zone](#dns-zone) are stored within files called [DNS zone files](#dns-zone-file). These are hosted on [DNS nameservers](#dns-name-server). DNS records act as instructions for the DNS servers, so they know which domain names and IP addresses are associated with each other. DNS records can be of multiple types, called [resource records](#resource-records). Check out our documentation on [how to manage DNS records](/network/domains-and-dns/how-to/manage-dns-records/). @@ -52,6 +44,14 @@ A DNS zone hosts the DNS records for a distinct part of the global domain namesp A DNS zone file describes a [DNS Zone](#dns-zone), containing DNS records which constitute mappings between domain names, IP addresses and other resources. +## Domain name + +A **domain name** or **domain** is a unique alphanumeric name used to identify a computer (web or email server) on the internet. It translates the numeric address of the computer to a more legible human-readable and memorable name. A domain can consist of a single [DNS Zone](#dns-zone) or be divided into several zones. + +## Domain name resolution + +Domain name resolution refers to the process by which human-readable domain names, like `www.mydomain.com`, are translated into the numerical IP addresses that computers and servers use to communicate on the internet. + ## External domain An external domain is any domain created via an external registrar (i.e. not Scaleway). You can manage DNS zones for external domains from the Scaleway console. @@ -65,7 +65,7 @@ An FQDN consists of a [hostname](#hostname), a [subdomain](#subdomain), a domain ## Hostname - + When looking at a [fully qualified domain name](#fully-qualified-domain-name-(fqdn)), the hostname usually comes before the domain name or the subdomain. A hostname is a label or name assigned to a computer, device, or server on a network. It helps identify and locate a specific computer or any device connected to a network among all the others. An example of a hostname can be `www` for the fully qualified domain name `www.mydomain.com.`. diff --git a/network/domains-and-dns/how-to/manage-dns-records.mdx b/network/domains-and-dns/how-to/manage-dns-records.mdx index 5b6facf21e..effba2658e 100644 --- a/network/domains-and-dns/how-to/manage-dns-records.mdx +++ b/network/domains-and-dns/how-to/manage-dns-records.mdx @@ -7,7 +7,7 @@ content: paragraph: Learn how to manage DNS records effectively with Scaleway Domains and DNS. Discover how to add, edit, and delete DNS records, along with advanced configurations like dynamic records for traffic management and Geo IP for optimizing user experience based on location. tags: txt-record mx-record dns-record dns domain records dates: - validation: 2024-04-25 + validation: 2024-10-29 posted: 2022-10-31 categories: - network @@ -24,9 +24,10 @@ categories: 1. Click **Domains and DNS** in the **Network** section of the [Scaleway console](https://console.scaleway.com) side menu. 2. Click the domain you want to manage. The domain's **Overview** page displays. 3. Click the **DNS zones** tab. A list of the DNS zones you have configured within the selected domain displays. -4. Click **+ Add records** to add new records to your DNS zone. A pop-up displays. -5. Fill in the required information for the record. -6. Click **Add Records** to confirm. +4. Click the DNS zone you want to add a record in. +5. Click **+ Add records**. A pop-up displays. +6. Fill in the required information for the record. +7. Click **Add records** to confirm. ## How to edit DNS records diff --git a/network/domains-and-dns/reference-content/understanding-domains-and-dns.mdx b/network/domains-and-dns/reference-content/understanding-domains-and-dns.mdx index bac04d6e54..58277e1418 100644 --- a/network/domains-and-dns/reference-content/understanding-domains-and-dns.mdx +++ b/network/domains-and-dns/reference-content/understanding-domains-and-dns.mdx @@ -7,7 +7,7 @@ content: paragraph: Learn about domain management, DNS zones, and the advantages of utilizing subdomains. tags: domains dns subdomain zone dates: - validation: 2024-04-25 + validation: 2024-10-29 posted: 2023-04-12 categories: - network @@ -21,7 +21,7 @@ A domain name is an identification string that defines a realm of administrative Domains are further divided into subdomains, that become DNS zones with their own set of administrators and DNS servers. -The term domain is used in the business functions of the entity assigned to it and the term zone is usually used for configuration of DNS services. +The term domain is used in the business functions of the entity assigned to it and the term zone is usually used for the configuration of DNS services. ## Example @@ -69,4 +69,4 @@ An internationalized domain name (IDN) is an internet domain name that contains Example: `allélua.com` converted in IDN is `xn--alllua-dva.com`. -To simplify its use, the Domains and DNS API uses `unicode` (`UTF-8`) for name and data fields. \ No newline at end of file +To simplify its use, the [Domains and DNS API](https://www.scaleway.com/en/developers/api/domains-and-dns/) uses `unicode` (`UTF-8`) for name and data fields. \ No newline at end of file From be588165e904ff61accfa15c8e5fc45b4926117c Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Tue, 29 Oct 2024 11:30:49 +0100 Subject: [PATCH 61/68] fix(ai): fix double link in navigation (#3906) --- menu/navigation.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/menu/navigation.json b/menu/navigation.json index 8badfd3745..6e7bf26e03 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -595,10 +595,6 @@ "label": "Support for function calling in Scaleway Managed Inference", "slug": "function-calling-support" }, - { - "label": "Support for function calling", - "slug": "function-calling-support" - }, { "label": "Llama-3-8b-instruct model", "slug": "llama-3-8b-instruct" From 8a150a51c74ed23b48cb607a481bc3ced8eb8439 Mon Sep 17 00:00:00 2001 From: SamyOubouaziz Date: Tue, 29 Oct 2024 11:37:11 +0100 Subject: [PATCH 62/68] fix(s3): fix rebase error (#3905) * fix(s3): fix rebase error * fix(s3): fix build error --- serverless/jobs/quickstart.mdx | 2 +- storage/object/concepts.mdx | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/serverless/jobs/quickstart.mdx b/serverless/jobs/quickstart.mdx index 954a5ad39c..d575d0d01c 100644 --- a/serverless/jobs/quickstart.mdx +++ b/serverless/jobs/quickstart.mdx @@ -64,7 +64,7 @@ This page explains how to create a job definition with the latest Alpine Linux i The execution appears in the **Job runs** section of the **Overview** tab. -4. Click the icon next to the last execution in the **Job runs** section, then click **Logs** to access your job's logs. +4. Click the icon next to the last execution in the **Job runs** section, then click **Logs** to access your job's logs. Make sure that you [have retrieved your Grafana credentials](/observability/cockpit/how-to/retrieve-grafana-credentials/) before accessing your job's logs. diff --git a/storage/object/concepts.mdx b/storage/object/concepts.mdx index afc5365c21..5efe1d4848 100644 --- a/storage/object/concepts.mdx +++ b/storage/object/concepts.mdx @@ -15,11 +15,7 @@ categories: ## Access control list (ACL) -<<<<<<< HEAD -Access control lists (ACL) are subresources attached to buckets and objects. They define which Scaleway users have access to the attached object/bucket, and the type of access they have. Whenever a user makes a request against a resource, Amazon S3 checks its ACL and verifies that they have permission to carry out the request. -======= -Access control lists (ACL) are subresources attached to buckets and objects. They define which Scaleway users have access to the attached object/bucket, and the type of access they have. Whenever a user makes a request against a resource, Object Storage checks its ACL and verifies that they have permission to carry out the request. ->>>>>>> 8888c6b0f (feat(gen): remove mentions of S3 only) +control lists (ACL) are subresources attached to buckets and objects. They define which Scaleway users have access to the attached object/bucket, and the type of access they have. Whenever a user makes a request against a resource, Amazon S3 checks its ACL and verifies that they have permission to carry out the request. ## Bucket From 6ef6cff73392badca0ccef78182dacbabb8539db Mon Sep 17 00:00:00 2001 From: fpagny Date: Tue, 29 Oct 2024 15:39:54 +0100 Subject: [PATCH 63/68] Update use-structured-outputs.mdx (#3908) Fixing a typo blocking tutorial snippet to work correctly. --- ai-data/generative-apis/how-to/use-structured-outputs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai-data/generative-apis/how-to/use-structured-outputs.mdx b/ai-data/generative-apis/how-to/use-structured-outputs.mdx index 35bb63f8a9..5d69bb81d3 100644 --- a/ai-data/generative-apis/how-to/use-structured-outputs.mdx +++ b/ai-data/generative-apis/how-to/use-structured-outputs.mdx @@ -215,7 +215,7 @@ extract = client.chat.completions.create( "items": {"type": "string"} } }, - "additionalProperties": false, + "additionalProperties": False, "required": ["title", "summary", "actionItems"] } } From a054c23c1fb56567c376b0f49d936f7fb13c1838 Mon Sep 17 00:00:00 2001 From: Thibault Genaitay Date: Tue, 29 Oct 2024 15:40:07 +0100 Subject: [PATCH 64/68] fix(ai): missing export (#3910) --- .../index.mdx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tutorials/building-ai-application-function-calling/index.mdx b/tutorials/building-ai-application-function-calling/index.mdx index e5fd792794..81c44c6940 100644 --- a/tutorials/building-ai-application-function-calling/index.mdx +++ b/tutorials/building-ai-application-function-calling/index.mdx @@ -232,14 +232,19 @@ if __name__ == "__main__": export SCALEWAY_API_KEY="your-api-key-here" ``` -2. Run the application: +2. Set your Base URL for OpenAI client: + ``` + export SCALEWAY_INFERENCE_ENDPOINT_URL="your-inference-endpoint-here" + ``` + +3. Run the application: ``` python main.py ``` -3. Try some example queries: - - "What flights are available from CDG to LHR tomorrow?" - - "Show me morning flights from Paris to London on November 1st" +4. Try some example queries: + - "What flights are available from CDG to LHR on November 1st?" + - "Show me morning flights from CDG to LHR on November 1st" - "Are there any afternoon flights from CDG to LHR on 2024-11-01?" ## How it works From 18d1af1adcf49b0e4de80e69e50c6352fa94b0c6 Mon Sep 17 00:00:00 2001 From: Justine Sudraud <124775951+jsudraud@users.noreply.github.com> Date: Tue, 29 Oct 2024 17:13:36 +0100 Subject: [PATCH 65/68] fix(datalab): wording overview page (#3911) --- managed-services/data-lab/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/managed-services/data-lab/index.mdx b/managed-services/data-lab/index.mdx index 3c04c2aa39..89684521c4 100644 --- a/managed-services/data-lab/index.mdx +++ b/managed-services/data-lab/index.mdx @@ -7,7 +7,7 @@ meta: From f8644a927a74bb2126b1a41ff656efd45b1e3992 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Tue, 29 Oct 2024 17:14:28 +0100 Subject: [PATCH 66/68] fix(k8s): remove doc temprary (#3912) --- .../kubernetes/api-cli/managing-storage.mdx | 102 ------------------ menu/navigation.json | 4 - 2 files changed, 106 deletions(-) delete mode 100644 containers/kubernetes/api-cli/managing-storage.mdx diff --git a/containers/kubernetes/api-cli/managing-storage.mdx b/containers/kubernetes/api-cli/managing-storage.mdx deleted file mode 100644 index 7a9e2aa5bc..0000000000 --- a/containers/kubernetes/api-cli/managing-storage.mdx +++ /dev/null @@ -1,102 +0,0 @@ ---- -meta: - title: Managing Block Storage volumes with Scaleway CSI - description: Learn how to manage Block Storage volumes using Scaleway's CSI driver on Kubernetes Kapsule and Kosmos clusters. -content: - h1: Managing Block Storage volumes with Scaleway CSI - paragraph: Learn how to manage Block Storage volumes using Scaleway's CSI driver on Kubernetes Kapsule and Kosmos clusters. -tags: block-storage scaleway-csi kubernetes pvc -dates: - validation: 2024-09-25 - posted: 2021-08-12 -categories: - - kubernetes ---- - -The [Scaleway Block Volume](https://www.scaleway.com/en/block-storage/) Container Storage Interface (CSI) driver is an implementation of the [CSI interface](https://github.com/container-storage-interface/spec/blob/master/spec.md) to provide a way to manage Scaleway Block Volumes through a container orchestration system, like Kubernetes. It is installed by default on every Kubernetes Kapsule and Kosmos cluster. - - - -- A Scaleway account logged into the [console](https://console.scaleway.com) -- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization -- A valid [API key](/identity-and-access-management/iam/how-to/create-api-keys/) -- Your Scaleway Project or Organization ID -- [Created](/containers/kubernetes/how-to/create-cluster/) a Kubernetes cluster running on Scaleway Instances (v1.21+) - - - Refer to our video tutorial [Getting Started with Kubernetes Part 4 - Storage](/containers/kubernetes/videos/) to view a visual presentation and step-by-step guidance of how to manage Block Storage volumes on Kubernetes with the Scaleway CSI. - - -## Verification of CSI driver status - -To verify if the driver is running, use the following command: - -```bash -kubectl get csidriver -``` - -The output of this command provides a quick status update on the CSI plugin within your Kubernetes cluster. For the latest features and enhancements, consider upgrading to [release 0.3](https://github.com/scaleway/scaleway-csi/tree/release-0.3#block-storage-low-latency), which supports **[Block Storage low latency](/storage/block/quickstart/)** volumes. - -To identify your current CSI release version, navigate to the [Cockpit interface](/observability/cockpit/how-to/access-grafana-and-managed-dashboards/), specifically the **Kubernetes Cluster - Overview** dashboard. - -## Upgrading to CSI version 0.3 - -### Using the API with curl - -You can trigger the migration to SBS-CSI using the following `curl` command: - -```bash -curl "https://api.scaleway.com/k8s/v1/regions/$REGION/clusters/$CLUSTER_ID/migrate-to-sbs-csi" \ --X POST \ --H "X-Auth-Token: $TOKEN" -``` - -Replace the placeholders with the following: - -- `$REGION`: Your cluster's region (e.g., `fr-par`, `nl-ams`). -- `$CLUSTER_ID`: Your cluster ID. -- `$TOKEN`: Your Scaleway API token. - -This command will initiate the migration process for your cluster to the new SBS-CSI. - -### Using the Scaleway CLI - -Alternatively, you can use the Scaleway CLI to perform the migration. Ensure the CLI is installed and configured with your API credentials. - -1. Install and configure the Scaleway CLI, if you have not already: - ```bash - scw init - ``` - -2. Run the migration command: - - ```bash - scw k8s cluster migrate-to-sbs-csi $CLUSTER_ID --region=$REGION - ``` - - Replace `$REGION` and `$CLUSTER_ID` with your cluster’s region and ID, respectively. - -### Post-migration verification - -After initiating the migration, the cluster status will change to _updating_. Once the migration completes, you can verify that the CSI driver has been updated and that the new driver properly handles Persistent Volume Claims (PVCs). - -```bash -kubectl get csidriver -``` - -This command will confirm that the migration was successful. - -## Going further - -* [Creating persistent volumes with Scaleway Block Storage](https://github.com/scaleway/scaleway-csi/tree/release-0.3/examples/kubernetes#pvc--deployment) -* [Creating raw block volumes](https://github.com/scaleway/scaleway-csi/tree/release-0.3/examples/kubernetes#raw-block-volumes) -* [Importing existing Scaleway volumes](https://github.com/scaleway/scaleway-csi/tree/release-0.3/examples/kubernetes#importing-existing-scaleway-volumes) -* [Creating volume snapshots](https://github.com/scaleway/scaleway-csi/tree/release-0.3/examples/kubernetes#volume-snapshots) -* [Importing volume snapshots](https://github.com/scaleway/scaleway-csi/tree/release-0.3/examples/kubernetes#importing-snapshots) -* [How to crate a storage class](https://github.com/scaleway/scaleway-csi/tree/release-0.3/examples/kubernetes#different-storageclass) -* [How to choose a zone for the volumes](https://github.com/scaleway/scaleway-csi/tree/release-0.3/examples/kubernetes#specify-in-which-zone-the-volumes-are-going-to-be-created) -* [How to choose the number of IOPS](https://github.com/scaleway/scaleway-csi/tree/release-0.3/examples/kubernetes#choose-the-number-of-iops) - - * `sbs-5k` and `sbs-15k` are pre-configured storage classes designed to meet your IOPS requirements. You can achieve the equivalent of setting `iops:5k` in your custom class. - -* [Encrypting volumes](https://github.com/scaleway/scaleway-csi/tree/release-0.3/examples/kubernetes#encrypting-volumes) diff --git a/menu/navigation.json b/menu/navigation.json index 6e7bf26e03..6236883e1f 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -1674,10 +1674,6 @@ "label": "Monitoring clusters", "slug": "cluster-monitoring" }, - { - "label": "Managing storage", - "slug": "managing-storage" - }, { "label": "Managing tags", "slug": "managing-tags" From 8b839ba3791ecbe6d44412c060392b463021d58b Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Wed, 30 Oct 2024 09:12:52 +0100 Subject: [PATCH 67/68] fix(ins): add posted date (#3909) --- .../reference-content/understanding-qemu-guest-agent.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/compute/instances/reference-content/understanding-qemu-guest-agent.mdx b/compute/instances/reference-content/understanding-qemu-guest-agent.mdx index 90775b5f8a..f43cf2cf77 100644 --- a/compute/instances/reference-content/understanding-qemu-guest-agent.mdx +++ b/compute/instances/reference-content/understanding-qemu-guest-agent.mdx @@ -8,6 +8,7 @@ content: tags: instance qga guemu guest agent dates: validation: 2024-10-28 + posted: 2024-10-28 categories: - compute --- From d7e9af3edfaf2539029a04565b324fb231cb0135 Mon Sep 17 00:00:00 2001 From: Thibault Genaitay Date: Wed, 30 Oct 2024 18:27:34 +0100 Subject: [PATCH 68/68] feat(genapi): introducing vision models --- ...t-models.mdx => query-language-models.mdx} | 23 +- .../how-to/query-vision-models.mdx | 238 ++++++++++++++++++ menu/navigation.json | 8 +- 3 files changed, 255 insertions(+), 14 deletions(-) rename ai-data/generative-apis/how-to/{query-text-models.mdx => query-language-models.mdx} (85%) create mode 100644 ai-data/generative-apis/how-to/query-vision-models.mdx diff --git a/ai-data/generative-apis/how-to/query-text-models.mdx b/ai-data/generative-apis/how-to/query-language-models.mdx similarity index 85% rename from ai-data/generative-apis/how-to/query-text-models.mdx rename to ai-data/generative-apis/how-to/query-language-models.mdx index e863101f35..5e97e6c8df 100644 --- a/ai-data/generative-apis/how-to/query-text-models.mdx +++ b/ai-data/generative-apis/how-to/query-language-models.mdx @@ -1,25 +1,24 @@ --- meta: - title: How to query text models - description: Learn how to interact with powerful text models using Scaleway's Generative APIs service. + title: How to query language models + description: Learn how to interact with powerful language models using Scaleway's Generative APIs service. content: - h1: How to query text models - paragraph: Learn how to interact with powerful text models using Scaleway's Generative APIs service. -tags: generative-apis ai-data text-models + h1: How to query language models + paragraph: Learn how to interact with powerful language models using Scaleway's Generative APIs service. +tags: generative-apis ai-data language-models dates: - validation: 2024-08-28 + validation: 2024-09-30 posted: 2024-08-28 --- -Scaleway's Generative APIs service allows users to interact with powerful text models hosted on the platform. +Scaleway's Generative APIs service allows users to interact with powerful language models hosted on the platform. -There are several ways to interact with text models: -- The Scaleway [console](https://console.scaleway.com) will soon provide a complete [playground](/ai-data/generative-apis/how-to/query-text-models/#accessing-the-playground), aiming to test models, adapt parameters, and observe how these changes affect the output in real-time. -- Via the [Chat API](/ai-data/generative-apis/how-to/query-text-models/#querying-text-models-via-api) +There are several ways to interact with language models: +- The Scaleway [console](https://console.scaleway.com) provides complete [playground](/ai-data/generative-apis/how-to/query-language-models/#accessing-the-playground), aiming to test models, adapt parameters, and observe how these changes affect the output in real-time. +- Via the [Chat API](/ai-data/generative-apis/how-to/query-language-models/#querying-language-models-via-api) -- Access to this service is restricted while in beta. You can request access to the product by filling out a form on Scaleway's [betas page](https://www.scaleway.com/en/betas/#generative-apis). - A Scaleway account logged into the [console](https://console.scaleway.com) - [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization - A valid [API key](/identity-and-access-management/iam/how-to/create-api-keys/) for API authentication @@ -40,7 +39,7 @@ The web playground displays. 3. Switch model at the top of the page, to observe the capabilities of chat models offered via Generative APIs. 4. Click **View code** to get code snippets configured according to your settings in the playground. -## Querying text models via API +## Querying language models via API The [Chat API](/ai-data/generative-apis/api-cli/using-chat-api/) is an OpenAI-compatible REST API for generating and manipulating conversations. diff --git a/ai-data/generative-apis/how-to/query-vision-models.mdx b/ai-data/generative-apis/how-to/query-vision-models.mdx new file mode 100644 index 0000000000..6760c1c5ca --- /dev/null +++ b/ai-data/generative-apis/how-to/query-vision-models.mdx @@ -0,0 +1,238 @@ +--- +meta: + title: How to query vision models + description: Learn how to interact with powerful vision models using Scaleway's Generative APIs service. +content: + h1: How to query vision models + paragraph: Learn how to interact with powerful vision models using Scaleway's Generative APIs service. +tags: generative-apis ai-data vision-models +dates: + validation: 2024-09-30 + posted: 2024-09-30 +--- + +Scaleway's Generative APIs service allows users to interact with powerful vision models hosted on the platform. + + + Vision models can understand and analyze images, not generate them. + + +There are several ways to interact with vision models: +- The Scaleway [console](https://console.scaleway.com) provides complete [playground](/ai-data/generative-apis/how-to/query-vision-models/#accessing-the-playground), aiming to test models, adapt parameters, and observe how these changes affect the output in real-time. +- Via the [Chat API](/ai-data/generative-apis/how-to/query-vision-models/#querying-vision-models-via-api) + + + +- A Scaleway account logged into the [console](https://console.scaleway.com) +- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization +- A valid [API key](/identity-and-access-management/iam/how-to/create-api-keys/) for API authentication +- Python 3.7+ installed on your system + +## Accessing the Playground + +Scaleway provides a web playground for vision models hosted on Generative APIs. + +1. Navigate to Generative APIs under the AI section of the [Scaleway console](https://console.scaleway.com/) side menu. The list of models you can query displays. +2. Click the name of the vision model you want to try. Alternatively, click next to the vision model, and click **Try model** in the menu. + +The web playground displays. + +## Using the Playground +1. Upload one or multiple images to the prompt area at the bottom of the page. Enter a prompt, for example, to describe the image(s) you attached. +2. Edit the hyperparameters listed on the right column, for example the default temperature for more or less randomness on the outputs. +3. Switch model at the top of the page, to observe the capabilities of chat and vision models offered via Generative APIs. +4. Click **View code** to get code snippets configured according to your settings in the playground. + +## Querying vision models via API + +The [Chat API](/ai-data/generative-apis/api-cli/using-chat-api/) is an OpenAI-compatible REST API for generating and manipulating conversations. + +You can query the vision models programmatically using your favorite tools or languages. +Vision models take both text and images as inputs. + + + Unlike traditional language models, vision models will take a content array for the user role, structuring text and images as inputs. + + +In the following example, we will use the OpenAI Python client. + +### Installing the OpenAI SDK + +Install the OpenAI SDK using pip: + +```bash +pip install openai +``` + +### Initializing the client + +Initialize the OpenAI client with your base URL and API key: + +```python +from openai import OpenAI + +# Initialize the client with your base URL and API key +client = OpenAI( + base_url="https://api.scaleway.ai/v1", # Scaleway's Generative APIs service URL + api_key="" # Your unique API secret key from Scaleway +) +``` + +### Generating a chat completion + +You can now create a chat completion, for example with the `pixtral-12b-2409` model: + +```python +# Create a chat completion using the 'pixtral-12b-2409' model +response = client.chat.completions.create( + model="pixtral-12b-2409", + messages=[ + { + "role": "user", + "content": [ + {"type": "text", "text": "What is this image?"}, + {"type": "image_url", "image_url": {"url": "https://picsum.photos/id/32/512/512"}}, + ] # Vision models will take a content array with text and image_url objects. + + } + ], + temperature=0.7, # Adjusts creativity + max_tokens=2048, # Limits the length of the output + top_p=0.9 # Controls diversity through nucleus sampling. You usually only need to use temperature. +) + +# Print the generated response +print(response.choices[0].message.content) +``` + +This code sends messages, prompt and image, to the vision model and returns an answer based on your input. The `temperature`, `max_tokens`, and `top_p` parameters control the response's creativity, length, and diversity, respectively. + +A conversation style may include a default system prompt. You may set this prompt by setting the first message with the role system. For example: + +```python +[ + { + "role": "system", + "content": "You are Xavier Niel." + } +] +``` + +### Passing images to Pixtral + +1. **Image URLs**: If the image is available online, you can just include the image URL in your request as demonstrated above. This approach is simple and does not require any encoding. +2. **Base64 encoded**: image Base64 encoding is a standard way to transform binary data, like images, into a text format, making it easier to transmit over the internet. + +The following Python code sample shows you how to encode an image in base64 format and pass it to your request payload. + +```python +import base64 +from io import BytesIO +from PIL import Image + +def encode_image(img): + buffered = BytesIO() + img.save(buffered, format="JPEG") + encoded_string = base64.b64encode(buffered.getvalue()).decode("utf-8") + return encoded_string + +img = Image.open("path_to_your_image.jpg") +base64_img = encode_image(img) + +payload = { + "messages": [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "What is this image?" + }, + { + "type": "image_url", + "image_url": { + "url": f"data:image/jpeg;base64,{base64_img}" + } + } + ] + } + ], + ... # other parameters +} + +``` + +### Model parameters and their effects + +The following parameters will influence the output of the model: + +- **`messages`**: A list of message objects that represent the conversation history. Each message should have a `role` (e.g., "system", "user", "assistant") and `content`. The content is an array that can contain text and/or image objects. +- **`temperature`**: Controls the output's randomness. Lower values (e.g., 0.2) make the output more deterministic, while higher values (e.g., 0.8) make it more creative. +- **`max_tokens`**: The maximum number of tokens (words or parts of words) in the generated output. +- **`top_p`**: Recommended for advanced use cases only. You usually only need to use temperature. `top_p` controls the diversity of the output, using nucleus sampling, where the model considers the tokens with top probabilities until the cumulative probability reaches `top_p`. +- **`stop`**: A string or list of strings where the model will stop generating further tokens. This is useful for controlling the end of the output. + + + If you encounter an error such as "Forbidden 403" refer to the [API documentation](/ai-data/generative-apis/api-cli/understanding-errors) for troubleshooting tips. + + +## Streaming + +By default, the outputs are returned to the client only after the generation process is complete. However, a common alternative is to stream the results back to the client as they are generated. This is particularly useful in chat applications, where it allows the client to view the results incrementally as each token is produced. +Following is an example using the chat completions API: + +```python +from openai import OpenAI + +client = OpenAI( + base_url="https://api.scaleway.ai/v1", # Scaleway's Generative APIs service URL + api_key="" # Your unique API key from Scaleway +) +response = client.chat.completions.create( + model="pixtral-12b-2409", + messages=[{ + "role": "user", + "content": [ + {"type": "text", "text": "What is this image?"}, + {"type": "image_url", "image_url": {"url": "https://picsum.photos/id/32/512/512"}}, + ] + }], + stream=True, +) + +for chunk in response: + if chunk.choices[0].delta.content: + print(chunk.choices[0].delta.content, end="") +``` + +## Async + +The service also supports asynchronous mode for any chat completion. + +```python + +import asyncio +from openai import AsyncOpenAI + +client = AsyncOpenAI( + base_url="https://api.scaleway.ai/v1", # Scaleway's Generative APIs service URL + api_key="" # Your unique API key from Scaleway +) + +async def main(): + stream = await client.chat.completions.create( + model="pixtral-12b-2409", + messages=[{ + "role": "user", + "content": [ + {"type": "text", "text": "What is this image?"}, + {"type": "image_url", "image_url": {"url": "https://picsum.photos/id/32/512/512"}}, + ] + }], + stream=True, + ) + async for chunk in stream: + print(chunk.choices[0].delta.content, end="") + +asyncio.run(main()) +``` diff --git a/menu/navigation.json b/menu/navigation.json index 6236883e1f..b2644d999f 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -660,13 +660,17 @@ { "items": [ { - "label": "Query text models", - "slug": "query-text-models" + "label": "Query language models", + "slug": "query-language-models" }, { "label": "Query embedding models", "slug": "query-embedding-models" }, + { + "label": "Query vision models", + "slug": "query-vision-models" + }, { "label": "Use structured outputs", "slug": "use-structured-outputs"