diff --git a/30e307eb.7dea8cfa.js b/30e307eb.7dea8cfa.js
new file mode 100644
index 0000000000..ed8f8eb2c9
--- /dev/null
+++ b/30e307eb.7dea8cfa.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[56],{208:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return b})),n.d(t,"metadata",(function(){return u})),n.d(t,"rightToc",(function(){return d})),n.d(t,"default",(function(){return p}));var a=n(1),r=n(9),l=(n(0),n(424)),o=n(436),s=n(442),c=n(433),i=n(423),b=(n(428),{last_modified_on:"2023-12-27",title:"Kubernetes",description:"Learn how to install and configure Qovery on your own Kubernetes cluster (BYOK) / Self-managed Kubernetes cluster"}),u={id:"using-qovery/configuration/provider/kubernetes",title:"Kubernetes",description:"Learn how to install and configure Qovery on your own Kubernetes cluster (BYOK) / Self-managed Kubernetes cluster",source:"@site/docs/using-qovery/configuration/provider/kubernetes.md",permalink:"/docs/using-qovery/configuration/provider/kubernetes",sidebar:"docs",previous:{title:"Provider",permalink:"/docs/using-qovery/configuration/provider"},next:{title:"Cluster Advanced Settings",permalink:"/docs/using-qovery/configuration/cluster-advanced-settings"}},d=[{value:"Components",id:"components",children:[]},{value:"What's the requirements?",id:"whats-the-requirements",children:[]},{value:"Private registry",id:"private-registry",children:[]},{value:"Install Qovery",id:"install-qovery",children:[]},{value:"Configuration",id:"configuration",children:[{value:"Qovery",id:"qovery",children:[]},{value:"Ingress",id:"ingress",children:[]},{value:"DNS",id:"dns",children:[]},{value:"Logging",id:"logging",children:[]},{value:"Certificates",id:"certificates",children:[]}]},{value:"Observability",id:"observability",children:[{value:"Metrics Server",id:"metrics-server",children:[]}]},{value:"FAQ",id:"faq",children:[{value:"I have a non-covered use case. What should I do?",id:"i-have-a-non-covered-use-case-what-should-i-do",children:[]},{value:"Can I host the Qovery control plane on my own?",id:"can-i-host-the-qovery-control-plane-on-my-own",children:[]}]}],m={rightToc:d};function p(e){var t=e.components,n=Object(r.a)(e,["components"]);return Object(l.b)("wrapper",Object(a.a)({},m,n,{components:t,mdxType:"MDXLayout"}),Object(l.b)(i.a,{type:"warning",mdxType:"Alert"},Object(l.b)("p",null,"Installing Qovery on your Kubernetes cluster is currently in beta. ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://www.qovery.com/solutions/bring-your-own-kubernetes"}),"You need to request your access here"),".")),Object(l.b)(i.a,{type:"info",mdxType:"Alert"},Object(l.b)("p",null,"This section is for Kubernetes power-users. If you are not familiar with Kubernetes, we recommend you to use Qovery on a Managed Kubernetes cluster on ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/cloud-service-provider/amazon-web-services/"}),"AWS"),", ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/cloud-service-provider/google-cloud-platform/"}),"GCP"),", ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/cloud-service-provider/microsoft-azure/"}),"Scaleway"),", or contact us.")),Object(l.b)("p",null,"Qovery Self-Managed (or BYOK: Bring Your Own Kubernetes) is a self-hosted version of Qovery. It allows you to install Qovery on your own Kubernetes cluster.\nRead ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://www.qovery.com/blog/kubernetes-managed-by-qovery-vs-self-managed-byok"}),"this article")," to better understand the difference with the Managed Kubernetes by Qovery. In a nutshell, Qovery Managed/BYOK is for Kubernetes experts who want to manage their own Kubernetes cluster.\nIn this version, Qovery does not manage the Kubernetes cluster for you."),Object(l.b)("p",null,"This page explains how to install and configure Qovery on your Kubernetes cluster. If you are looking for a quick step-by-step guide, please follow the ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"/guides/provider/guide-kubernetes/"}),"Kubernetes guide"),"."),Object(l.b)("h2",{id:"components"},"Components"),Object(l.b)("p",{align:"center"},Object(l.b)("img",{src:"/img/qovery_byok_how_it_works.jpg",alt:"How Qovery works with Self Managed Kubernetes cluster"})),Object(l.b)("p",null,"They are two types of components:"),Object(l.b)("p",null,"Qovery components:"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"Qovery Control Plane: the Qovery Control Plane is the brain of Qovery. It is responsible for managing your applications and providing the API to interact with Qovery."),Object(l.b)("li",{parentName:"ul"},"Qovery Cluster Agent (mandatory): the Qovery Cluster Agent is responsible for securely forwarding logs and metrics from your Kubernetes cluster to Qovery control plane."),Object(l.b)("li",{parentName:"ul"},"Qovery Shell Agent (mandatory): the Qovery Shell Agent is responsible for giving you a secure remote shell access to your Kubernetes pods if you need it. E.g. when using ",Object(l.b)("inlineCode",{parentName:"li"},"qovery shell")," command."),Object(l.b)("li",{parentName:"ul"},"Qovery Engine (optional): the Qovery Engine is responsible for managing your applications deployment on your Kubernetes cluster. It can be used Qovery side or is installed on your Kubernetes cluster.")),Object(l.b)("p",null,"Third-party components:"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"NGINX Ingress Controller (optional)"),Object(l.b)("li",{parentName:"ul"},"External DNS (optional)"),Object(l.b)("li",{parentName:"ul"},"Loki (optional)"),Object(l.b)("li",{parentName:"ul"},"Promtail (optional)"),Object(l.b)("li",{parentName:"ul"},"Cert Manager (optional)"),Object(l.b)("li",{parentName:"ul"},"...")),Object(l.b)("p",null,"You can chose what you want to install and manage, and you will have a description of what services are used, and responsible for. You can disable them if you don't want to use them. And you can even install other components if you want to."),Object(l.b)("h2",{id:"whats-the-requirements"},"What's the requirements?"),Object(l.b)("p",null,"Qovery requires a Kubernetes cluster with the following requirements:"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"Kubernetes version 1.26 or higher"),Object(l.b)("li",{parentName:"ul"},"Helm version 3.0 or higher"),Object(l.b)("li",{parentName:"ul"},"2 CPU"),Object(l.b)("li",{parentName:"ul"},"4 GB RAM"),Object(l.b)("li",{parentName:"ul"},"20 GB disk space"),Object(l.b)("li",{parentName:"ul"},"Being able to access to the Internet"),Object(l.b)("li",{parentName:"ul"},"A private registry")),Object(l.b)("p",null,"Here are some examples of Kubernetes distributions that can be used with Qovery. ",Object(l.b)("strong",{parentName:"p"},"This is a non exhaustive list"),"."),Object(l.b)(i.a,{type:"danger",mdxType:"Alert"},Object(l.b)("p",null,"Theses examples are not recommendations! Simply examples of what can be installed in the fastest way.")),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"eks",placeholder:"Select a cloud provider",select:!1,size:null,values:[{group:"k8s",label:"AWS - EKS",value:"eks"},{group:"k8s",label:"GCP - GKE",value:"gke"},{group:"k8s",label:"Scaleway - Kapsule",value:"kapsule"},{group:"k8s",label:"Demo (K3D)",value:"demo"}],mdxType:"Tabs"},Object(l.b)(s.a,{value:"eks",mdxType:"TabItem"},Object(l.b)("p",null,"To create a Kubernetes cluster on AWS, the simplest way is to use ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://eksctl.io/installation/"}),"eksctl binary"),". For example:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-bash"}),"eksctl create cluster --region=us-east-2 --zones=us-east-2a,us-east-2b,us-east-2d\n"))),Object(l.b)(s.a,{value:"gke",mdxType:"TabItem"},Object(l.b)("p",null,"To create a Kubernetes cluster on GCP, the simplest way is to use ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://cloud.google.com/sdk/docs/install"}),"gcloud binary"),". For example:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-bash"}),'gcloud beta container --project "qovery-gcp-tests" \\\n clusters create-auto "qovery-test" \\\n --region "us-east5" \\\n --release-channel "stable" \\\n --network "projects/qovery-gcp-tests/global/networks/default" \\\n --subnetwork "projects/qovery-gcp-tests/regions/us-east5/subnetworks/default"\n --cluster-ipv4-cidr "/16"\n --services-ipv4-cidr "10.0.0.0/16"\n'))),Object(l.b)(s.a,{value:"kapsule",mdxType:"TabItem"},Object(l.b)("p",null,"To create a Kubernetes cluster on Scaleway, the simplest way is to use ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/scaleway/scaleway-cli"}),"scw binary"),". For example:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-bash"}),"scw k8s cluster create name=qovery-test\nscw k8s pool create cluster-id= name=pool node-type=GP1_XL size=3\n")),Object(l.b)("p",null,"You can find the ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://www.scaleway.com/en/docs/containers/kubernetes/api-cli/creating-managing-kubernetes-lifecycle-cliv2/"}),"complete documentation here"),".")),Object(l.b)(s.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"Here is an example with K3d to deploy a local Kubernetes cluster (you can use k3s or any other Kubernetes distribution):"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-bash"}),'k3d cluster create --image rancher/k3s:v1.26.11-k3s2 --k3s-arg "--disable=traefik,metrics-server@server:0" \\\n-v $(pwd)/registry_bin:/var/lib/rancher/credentialprovider/bin@server:0 \\\n-v $(pwd)/config.yaml:/var/lib/rancher/credentialprovider/config.yaml@server:0\n')),Object(l.b)("p",null,"Note: please take a look at the registry information below to understand why we need to mount the registry folder."))),Object(l.b)("h2",{id:"private-registry"},"Private registry"),Object(l.b)("p",null,"Qovery requires a private registry to store built images and mirror containers in order to reduce potential images deletion by 3rd party, while you still need them (",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/image-mirroring/"}),"more info here"),")."),Object(l.b)("p",{align:"center"},Object(l.b)("img",{src:"/img/configuration/provider/kubelet-credential-providers-plugin.png",alt:"Kubelet Credential Providers"})),Object(l.b)("p",null,"To do so, Qovery advise to use ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://kubernetes.io/blog/2022/12/22/kubelet-credential-providers/"}),"Kubelet Credential Provider")," as it's transparent for developers."),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"cpor",placeholder:"Select a platform",select:!1,size:null,values:[{group:"Registry",label:"Cloud Provider Own Registry",value:"cpor"},{group:"Registry",label:"ECR",value:"ecr"}],mdxType:"Tabs"},Object(l.b)(s.a,{value:"cpor",mdxType:"TabItem"},Object(l.b)("p",null,"If you're running Qovery Self-Managed version, and you are going to use the registry from the cloud provider itself, you don't have anything to do. The cloud providers already manage this part for you.")),Object(l.b)(s.a,{value:"ecr",mdxType:"TabItem"},Object(l.b)("p",null,"If you want to use ECR on a non-EKS cluster, you will need to install the ECR Credential Provider on your Kubernetes cluster."),Object(l.b)("p",null,"You have to create an IAM user with the following policy, and generate an access key:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-json"}),'{\n "Statement": [\n {\n "Action": [\n "ecr:*",\n ],\n "Effect": "Allow",\n "Resource": "*"\n }\n ],\n "Version": "2012-10-17"\n}\n')),Object(l.b)("p",null,"Then we create a ",Object(l.b)("inlineCode",{parentName:"p"},"config.yaml")," file to configure the ECR credential provider, where you should set the AWS credentials previously generated:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),'apiVersion: kubelet.config.k8s.io/v1\nkind: CredentialProviderConfig\nproviders:\n - name: ecr-credential-provider\n matchImages:\n - "*.dkr.ecr.*.amazonaws.com"\n - "*.dkr.ecr.*.amazonaws.com.cn"\n - "*.dkr.ecr-fips.*.amazonaws.com"\n - "*.dkr.ecr.us-iso-east-1.c2s.ic.gov"\n - "*.dkr.ecr.us-isob-east-1.sc2s.sgov.gov"\n defaultCacheDuration: "12h"\n apiVersion: credentialprovider.kubelet.k8s.io/v1\n env:\n - name: AWS_ACCESS_KEY_ID\n value: xxx\n - name: AWS_DEFAULT_REGION\n value: xxx\n - name: AWS_SECRET_ACCESS_KEY\n value: xxx\n')),Object(l.b)(i.a,{type:"info",mdxType:"Alert"},Object(l.b)("p",null,"Depending on your Kubernetes installation (cloud provider, on premise...) please refer to the official documentation to deploy the credential provider.")),Object(l.b)("details",null,Object(l.b)("summary",null,"Example with K3d"),Object(l.b)("p",null,"Here is an example with K3d to deploy a local Kubernetes cluster with the ECR credential provider."),Object(l.b)("p",null,"We first create the prerequired folders and file for the binary:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{}),"mkdir -p registry_bin\ntouch registry_bin/ecr-credential-provider\nchmod 755 registry_bin/ecr-credential-provider\n")),Object(l.b)("p",null,"Note: the ecr-credential-provider binary should be present for k3s to start. We will build it later."),Object(l.b)("p",null,"Now we can run a local Kubernetes cluster (update the path to ",Object(l.b)("inlineCode",{parentName:"p"},"config.yaml")," file, and the Kubernetes ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://hub.docker.com/r/rancher/k3s/tags"}),"image tag version"),"):"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-bash"}),'k3d cluster create --image rancher/k3s:v1.26.11-k3s2 --k3s-arg "--disable=traefik,metrics-server@server:0" \\\n-v $(pwd)/registry_bin:/var/lib/rancher/credentialprovider/bin@server:0 \\\n-v $(pwd)/config.yaml:/var/lib/rancher/credentialprovider/config.yaml@server:0\n'))),Object(l.b)("br",null),Object(l.b)("p",null,"Once the Credential provider configuration has been deployed, we'll build the binary and deploy it on the cluster (note: it has to be present on all worker nodes).\nSimply deploy this job which will do the work:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),'apiVersion: batch/v1\nkind: Job\nmetadata:\n name: cloud-provider-repository-binary-builder\nspec:\n backoffLimit: 0\n template:\n spec:\n restartPolicy: Never\n containers:\n - name: ecr-credential-builder\n image: alpine:3.18\n command:\n - /bin/sh\n - -c\n - |\n apk add -U ca-certificates tar zstd tzdata go git\n git clone https://github.com/kubernetes/cloud-provider-aws.git\n cd cloud-provider-aws/cmd/ecr-credential-provider\n CGO_ENABLED=0 go build -mod=readonly .\n chmod 755 ecr-credential-provider\n mkdir -p /mnt/host/var/lib/rancher/credentialprovider/bin/\n cp ecr-credential-provider /mnt/host/var/lib/rancher/credentialprovider/bin/\n volumeMounts:\n - mountPath: /mnt/host\n name: host\n volumes:\n - hostPath:\n path: /\n type: ""\n name: host\n')),Object(l.b)("p",null,"You can now move on the Qovery Helm deployment."))),Object(l.b)("h2",{id:"install-qovery"},"Install Qovery"),Object(l.b)(c.a,{headingDepth:3,mdxType:"Steps"},Object(l.b)("ol",null,Object(l.b)("li",null,Object(l.b)("p",null,"Install ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://helm.sh"}),"Helm")," command line tool.")),Object(l.b)("li",null,Object(l.b)("p",null,"Add Qovery Helm repository."),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-bash"}),"helm repo add qovery https://helm.qovery.com\nhelm repo update\n"))),Object(l.b)("li",null,Object(l.b)("p",null,"Login to the Qovery console, create a cluster until it's asked to save informations in the ",Object(l.b)("inlineCode",{parentName:"p"},"values.yaml")," file.")),Object(l.b)("li",null,Object(l.b)("p",null,"You will find several ",Object(l.b)("inlineCode",{parentName:"p"},"values.yaml")," files. Depending on you need, select the one you want and update the configuration accordingly:"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"values-demo.yaml"),": this version is to locally test with k3s or minikube"),Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"values-.yaml"),": find versions made for some providers")),Object(l.b)(i.a,{type:"info",mdxType:"Alert"},Object(l.b)("p",null,"Note: The provided values files are examples. There is no restriction where Qovery can be deployed. Feel free to copy or use an existing example and adapt it to your needs.")),Object(l.b)("p",null,"Here is an example of how the chart works:"),Object(l.b)("details",null,Object(l.b)("summary",null,"values-demo.yaml"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),'## Services you can enable or disable\nservices:\n qovery:\n qovery-cluster-agent:\n enabled: true\n qovery-shell-agent:\n enabled: true\n ingress:\n ingress-nginx:\n enabled: true\n dns:\n external-dns:\n enabled: true\n logging:\n loki:\n enabled: true\n promtail:\n enabled: true\n certificates:\n cert-manager:\n enabled: true\n qovery-cert-manager-webhook:\n enabled: true\n cert-manager-configs:\n enabled: true\n observability:\n metrics-server:\n enabled: true\n\n## Qovery Common config\n# Past information from Qovery cluster console creation\n\nqovery:\n clusterId: &clusterId "set-by-customer"\n clusterShortId: &shortClusterId "set-by-customer"\n organizationId: &organizationId "set-by-customer"\n jwtToken: &jwtToken "set-by-customer"\n domain: &domain "set-by-customer"\n grpcServer: &grpcServer "set-by-customer"\n engineGrpcServer: &engineGrpcServer "set-by-customer"\n qoveryDnsUrl: &qoveryDnsUrl "set-by-customer"\n lokiUrl: &lokiUrl "set-by-customer"\n promtailLokiUrl: &promtailLokiUrl "set-by-customer"\n acmeEmailAddr: &acmeEmailAddr "set-by-customer"\n externalDnsPrefix: &externalDnsPrefix "set-by-customer"\n architectures: &architectures "set-by-customer"\n\n## Chart overrides\n...\n')))),Object(l.b)("li",null,Object(l.b)("p",null,"Install Qovery on your Kubernetes cluster."),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-bash"}),"helm upgrade --install -n qovery -f values-demo.yaml qovery\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"-n qovery"),": the namespace where Qovery and its dependencies will be installed"),Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"-f values-demo.yaml"),": specify the values overrides file you want to use"),Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"qovery"),": name of the chart to deploy"))))),Object(l.b)("h2",{id:"configuration"},"Configuration"),Object(l.b)("h3",{id:"qovery"},"Qovery"),Object(l.b)("p",null,"This is the configuration of Qovery itself. It is used by all Qovery components."),Object(l.b)(i.a,{type:"danger",mdxType:"Alert"},Object(l.b)("p",null,Object(l.b)("strong",{parentName:"p"},"Do not share the jwtToken! Keep it in a safe place.")," It is used to authenticate the cluster.")),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Key"),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Required"),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Description"),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Default"))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.clusterId")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"The cluster ID. It is used to identify your cluster."),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.shortClusterId")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"The short cluster ID. It is used to identify your cluster."),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.organizationId")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"The organization ID. It is used to identify your organization."),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.jwtToken")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"The JWT token. It is used to authenticate your cluster."),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.domain")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"The domain name used by Qovery."),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.qoveryDnsUrl")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Qovery DNS url in case you want to use Qovery provided DNS"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.lokiUrl")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Local Loki URL (required if Loki is set)"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.promtailLokiUrl")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Promtail Loki URL (required if Promtail and Loki are set)"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.acmeEmailAddr")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Email address used for ",Object(l.b)("inlineCode",{parentName:"td"},"Let's Encrypt")," TLS requests"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.externalDnsPrefix")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"ExernalDNS TXT record prefix (required if ExternalDNS is set)"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.architectures")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Set cluster architectures (comma separated)"),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"AMD64"))))),Object(l.b)("h4",{id:"qovery-cluster-agent"},"Qovery Cluster Agent"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Yes")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"The cluster agent is responsible for securely forwarding logs and metrics from your Kubernetes cluster to Qovery control plane")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"The cluster will not report to Qovery control plane Kubernetes information, so the Qovery console will report unknown satus values")))),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"qovery-cluster-agent:\n fullnameOverride: qovery-cluster-agent\n")),Object(l.b)("h4",{id:"qovery-shell-agent"},"Qovery Shell Agent"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Yes")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Used to give a remote shell access to you Kubernetes pods (if user is allowed from Qovery RBAC) with the Qovery CLI")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No remote connection will be possible, and Qovery support will not be able to help you to diagnose issues")))),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"qovery-shell-agent:\n fullnameOverride: qovery-shell-agent\n")),Object(l.b)("h3",{id:"ingress"},"Ingress"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Web services can be privately or publicly exposed")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No web services will be exposed")))),Object(l.b)("p",null,"Qovery us will be exposed ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://docs.nginx.com/nginx-ingress-controller/"}),"NGINX Ingress Controller")," by default to route traffic to your applications."),Object(l.b)("h4",{id:"nginx-ingress-controller"},"Nginx Ingress Controller"),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"NginxIngress",label:"Demo",value:"demo"},{group:"NginxIngress",label:"AWS",value:"aws"},{group:"NginxIngress",label:"GCP",value:"gcp"},{group:"NginxIngress",label:"Scaleway",value:"scaleway"}],mdxType:"Tabs"},Object(l.b)(s.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"Here is the minimum override configuration to be used:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),'ingress-nginx:\n fullnameOverride: ingress-nginx\n controller:\n useComponentLabel: true\n admissionWebhooks:\n enabled: false\n # Ingress class used when an application/container with public access is set\n ingressClass: nginx-qovery\n extraArgs:\n # Default TLS certificate name and path\n default-ssl-certificate: "qovery/letsencrypt-acme-qovery-cert"\n # Allows customization of the source of the IP address or FQDN to report in the ingress status field\n publishService:\n enabled: true\n'))),Object(l.b)(s.a,{value:"aws",mdxType:"TabItem"},Object(l.b)("p",null,"Here is an example with Nginx Ingress Controller on AWS with NLB:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),'ingress-nginx:\n controller:\n useComponentLabel: true\n admissionWebhooks:\n enabled: set-by-customer\n # enable if you want metrics scrapped by prometheus\n metrics:\n enabled: set-by-customer\n serviceMonitor:\n enabled: set-by-customer\n config:\n # set global default file size limit to 100m\n proxy-body-size: 100m\n # hide Nginx version\n server-tokens: "false"\n # the Ingress Class name to be used by Ingresses (use "nginx-qovery" for Qovery application/container deployments)\n ingressClass: nginx-qovery\n extraArgs:\n # Kubernetes path of the default Cert-manager TLS certificate (if used)\n default-ssl-certificate: "cert-manager/letsencrypt-acme-qovery-cert"\n updateStrategy:\n rollingUpdate:\n # set the minimum acceptable number of unavailable pods during a rolling update\n maxUnavailable: 1\n # enable auoscaling if you want to scale the number of replicas based on CPU usage\n autoscaling:\n enabled: true\n minReplicas: set-by-customer\n maxReplicas: set-by-customer\n targetCPUUtilizationPercentage: set-by-customer\n # required if you rely on a load balancer\n # the controller mirrors the address of this service\'s endpoints to the load-balancer status of all Ingress objects it satisfies.\n publishService:\n enabled: true\n # set a load balancer if you want your Nginx to be publicly accessible\n service:\n enabled: true\n annotations:\n service.beta.kubernetes.io/aws-load-balancer-type: nlb\n # Qovery managed DNS requieres *.$domain (something like: *..)\n external-dns.alpha.kubernetes.io/hostname: "set-by-customer"\n externalTrafficPolicy: "Local"\n sessionAffinity: ""\n healthCheckNodePort: 0\n'))),Object(l.b)(s.a,{value:"gcp",mdxType:"TabItem"},Object(l.b)("p",null,"Here is an example with Nginx Ingress Controller on AWS with NLB:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),'ingress-nginx:\n controller:\n useComponentLabel: true\n admissionWebhooks:\n enabled: set-by-customer\n # enable if you want metrics scrapped by prometheus\n metrics:\n enabled: set-by-customer\n serviceMonitor:\n enabled: set-by-customer\n config:\n # set global default file size limit to 100m\n proxy-body-size: 100m\n # hide Nginx version\n server-tokens: "false"\n # the Ingress Class name to be used by Ingresses (use "nginx-qovery" for Qovery application/container deployments)\n ingressClass: nginx-qovery\n extraArgs:\n # Kubernetes path of the default Cert-manager TLS certificate (if used)\n default-ssl-certificate: "qovery/letsencrypt-acme-qovery-cert"\n updateStrategy:\n rollingUpdate:\n # set the minimum acceptable number of unavailable pods during a rolling update\n maxUnavailable: 1\n # enable auoscaling if you want to scale the number of replicas based on CPU usage\n autoscaling:\n enabled: true\n minReplicas: set-by-customer\n maxReplicas: set-by-customer\n targetCPUUtilizationPercentage: set-by-customer\n # required if you rely on a load balancer\n # the controller mirrors the address of this service\'s endpoints to the load-balancer status of all Ingress objects it satisfies.\n publishService:\n enabled: true\n # set a load balancer if you want your Nginx to be publicly accessible\n service:\n enabled: true\n annotations:\n # Qovery managed DNS requieres *.$domain (something like: *..)\n external-dns.alpha.kubernetes.io/hostname: "set-by-customer"\n externalTrafficPolicy: "Local"\n sessionAffinity: ""\n healthCheckNodePort: 0\n'))),Object(l.b)(s.a,{value:"scaleway",mdxType:"TabItem"},Object(l.b)("p",null,"Here is an example with Nginx Ingress Controller on Scaleway:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),'ingress-nginx:\n controller:\n useComponentLabel: true\n admissionWebhooks:\n enabled: set-by-customer\n # enable if you want metrics scrapped by prometheus\n metrics:\n enabled: set-by-customer\n serviceMonitor:\n enabled: set-by-customer\n config:\n # set global default file size limit to 100m\n proxy-body-size: 100m\n # hide Nginx version\n server-tokens: "false"\n # required for X-Forwarded-for to work\n use-proxy-protocol: "true"\n # the Ingress Class name to be used by Ingresses (use "nginx-qovery" for Qovery application/container deployments)\n ingressClass: nginx-qovery\n extraArgs:\n # Kubernetes path of the default Cert-manager TLS certificate (if used)\n default-ssl-certificate: "cert-manager/letsencrypt-acme-qovery-cert"\n updateStrategy:\n rollingUpdate:\n # set the minimum acceptable number of unavailable pods during a rolling update\n maxUnavailable: 1\n # enable auoscaling if you want to scale the number of replicas based on CPU usage\n autoscaling:\n enabled: true\n minReplicas: set-by-customer\n maxReplicas: set-by-customer\n targetCPUUtilizationPercentage: set-by-customer\n # required if you rely on a load balancer\n # the controller mirrors the address of this service\'s endpoints to the load-balancer status of all Ingress objects it satisfies.\n publishService:\n enabled: true\n # set a load balancer if you want your Nginx to be publicly accessible\n service:\n enabled: true\n # https://github.com/scaleway/scaleway-cloud-controller-manager/blob/master/docs/loadbalancer-annotations.md\n annotations:\n service.beta.kubernetes.io/scw-loadbalancer-forward-port-algorithm: "leastconn"\n service.beta.kubernetes.io/scw-loadbalancer-protocol-http: "false"\n service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v1: "false"\n service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v2: "true"\n service.beta.kubernetes.io/scw-loadbalancer-health-check-type: tcp\n service.beta.kubernetes.io/scw-loadbalancer-use-hostname: "true"\n # set Scaleway load balancer type https://www.scaleway.com/en/load-balancer/ (ex: LB-GP-S, LB-GP-M, LB-GP-L, LB-GP-XL)\n service.beta.kubernetes.io/scw-loadbalancer-type: "set-by-customer"\n # Qovery managed DNS requieres *.$domain (something like: *..)\n external-dns.alpha.kubernetes.io/hostname: "set-by-customer"\n externalTrafficPolicy: "Local"\n')))),Object(l.b)("h4",{id:"other-ingress-controllers"},"Other Ingress Controllers"),Object(l.b)("p",null,"Qovery supports other Ingress Controllers. Please contact us if you want to use another one. We will be happy to help you."),Object(l.b)("h3",{id:"dns"},"DNS"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Used to easily reach your applications with DNS records, even on private network")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"You will have easy access with dns names to your services, you'll have to use IPs")))),Object(l.b)("p",null,"Qovery uses ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/kubernetes-sigs/external-dns"}),"External DNS")," to automatically configure DNS records for your applications."),Object(l.b)("p",null,"If you don't want or can't add your own DNS provider, Qovery proposes it's own managed sub-domain DNS provider for free.\nYou'll then be able to later add your custom DNS record (no matter the provider) to point to your Qovery DNS sub-domain."),Object(l.b)("h4",{id:"external-dns"},"External DNS"),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"ExternalDns",label:"Demo & QoveryDNS",value:"demo"},{group:"ExternalDns",label:"Cloudflare",value:"cloudflare"}],mdxType:"Tabs"},Object(l.b)(s.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"Here is one example with Qovery DNS provider:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"external-dns:\n fullnameOverride: external-dns\n # set pdns for Qovery DNS managed (or you can use any supported provider by external-dns)\n provider: pdns\n # will use the domain name given by Qovery during the cluster setup phease\n domainFilters: [*domain]\n # an owner ID is set to avoid conflicts in case of multiple Qovery clusters\n txtOwnerId: *shortClusterId\n # a prefix to help Qovery to debug in case of issues\n txtPrefix: *externalDnsPrefix\n # set the Qovery DNS provider configuration\n pdns:\n apiUrl: *qoveryDnsUrl\n apiKey: *jwtToken\n apiPort: 443\n"))),Object(l.b)(s.a,{value:"cloudflare",mdxType:"TabItem"},Object(l.b)("p",null,"Here is one example with Cloudflare:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),'external-dns:\n # set the provider to use\n provider: set-by-customer\n # keep the config you want to use and remove the others. Configure the provider you want to use.\n cloudflare:\n apiToken: set-by-customer\n email: set-by-customer\n proxied: set-by-customer\n pdns:\n # Qovery DNS: apiUrl: *qoveryDnsUrl\n apiUrl: set-by-customer\n # Qovery DNS: apiPort: "443"\n apiPort: set-by-customer\n # Qovery DNS: apiKey: "443"\n apiKey: set-by-customer\n # Make external DNS ignore this ingress https://github.com/kubernetes-sigs/external-dns/issues/1910#issuecomment-976371247\n annotationFilter: external-dns.alpha.kubernetes.io/exclude notin (true)\n # set domainFilters to the domain you want to manage: [*domain]\n domainFilters: set-by-customer\n triggerLoopOnEvent: true\n policy: sync\n # avoid dns collision with other external-dns instances\n txtOwnerId: set-by-customer\n txtPrefix: set-by-customer\n # set the number of replicas you want to use\n replicas: 1\n # set the rolling update strategy you want to apply\n updateStrategy:\n type: set-by-customer\n # remove if you don\'t want to use a custom image\n image:\n registry: set-by-customer\n repository: set-by-customer\n tag: 0.13.2-debian-11-r17\n # set resources\n resources:\n limits:\n cpu: 50m\n memory: 100Mi\n requests:\n cpu: 50m\n memory: 100Mi\n')))),Object(l.b)("h3",{id:"logging"},"Logging"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Retrieve and store application's log history")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"You'll have live logs, but you will miss log history for debugging purpose")))),Object(l.b)("p",null,"Qovery uses ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://grafana.com/oss/loki/"}),"Loki")," to store your logs in a S3 compatible bucket and ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://grafana.com/docs/loki/latest/clients/promtail/"}),"Promtail")," to collect your logs."),Object(l.b)("h4",{id:"loki"},"Loki"),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"Loki",label:"Demo",value:"demo"},{group:"Loki",label:"AWS S3",value:"s3"}],mdxType:"Tabs"},Object(l.b)(s.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"Here is a configuration ",Object(l.b)("strong",{parentName:"p"},"in Memory (no persistence)")," for Loki:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"loki:\n fullnameOverride: loki\n loki:\n # no auth is set for internal cluster usage\n auth_enabled: false\n ingester:\n lifecycler:\n ring:\n kvstore:\n # we store it in memory for the demo, you'll lose history once Loki restarts\n store: inmemory\n replication_factor: 1\n schema_config:\n configs:\n - from: 2020-05-15\n store: boltdb-shipper\n object_store: filesystem\n schema: v11\n index:\n prefix: index_\n period: 24h\n monitoring:\n # all the monitoring part is disabled to reduce resource footprint for the demo usage\n dashboards:\n enabled: false\n rules:\n enabled: false\n serviceMonitor:\n enabled: false\n metricsInstance:\n enabled: false\n selfMonitoring:\n enabled: false\n grafanaAgent:\n installOperator: false\n grafanaAgent:\n enabled: false\n lokiCanary:\n enabled: false\n test:\n enabled: false\n gateway:\n enabled: false\n # we use a single binary to reduce resource footprint for the demo usage\n singleBinary:\n replicas: 1\n persistence:\n enabled: false\n extraVolumes:\n - name: data\n emptyDir: {}\n - name: storage\n emptyDir: {}\n extraVolumeMounts:\n - name: data\n mountPath: /data\n - name: storage\n mountPath: /var/loki\n"))),Object(l.b)(s.a,{value:"s3",mdxType:"TabItem"},Object(l.b)("p",null,"Here is a configuration example with AWS S3 as storage backend:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"loki:\n # remove if you don't want to use a custom image\n kubectlImage:\n registry: set-by-customer\n repository: set-by-customer\n loki:\n # remove if you don't want to use a custom image\n image:\n registry: set-by-customer\n repository: set-by-customer\n # set if you want to use authentication\n auth_enabled: false\n commonConfig:\n # for simple usage, without high throughput, you can use the 1 replica only\n # note: replication is assured by the storage backend\n replication_factor: 1\n ingester:\n chunk_idle_period: 3m\n chunk_block_size: 262144\n chunk_retain_period: 1m\n max_transfer_retries: 0\n lifecycler:\n ring:\n kvstore:\n store: memberlist\n replication_factor: 1\n memberlist:\n abort_if_cluster_join_fails: false\n bind_port: 7946\n join_members:\n # set loki headless service\n - loki-headless.logging.svc:7946\n max_join_backoff: 1m\n max_join_retries: 10\n min_join_backoff: 1s\n limits_config:\n ingestion_rate_mb: 20\n ingestion_burst_size_mb: 30\n enforce_metric_name: false\n reject_old_samples: true\n reject_old_samples_max_age: 168h\n max_concurrent_tail_requests: 100\n split_queries_by_interval: 15m\n max_query_lookback: 12w\n compactor:\n working_directory: /data/retention\n # configure storage provider for the compactor\n shared_store: aws\n compaction_interval: 10m\n retention_enabled: set-by-customer\n retention_delete_delay: 2h\n retention_delete_worker_count: 150\n table_manager:\n retention_deletes_enabled: set-by-customer\n retention_period: set-by-customer\n schema_config:\n configs:\n # set the schema for the index (2020 version can be deleted on a fresh install)\n - from: 2020-05-15\n store: boltdb-shipper\n object_store: s3\n schema: v11\n index:\n prefix: index_\n period: 24h\n - from: 2023-06-01\n store: boltdb-shipper\n object_store: s3\n schema: v12\n index:\n prefix: index_\n period: 24h\n storage:\n # configure the object storage backend\n bucketNames:\n chunks:\n ruler:\n admin:\n type: s3\n s3:\n s3:\n region:\n s3ForcePathStyle:\n insecure:\n storage_config:\n boltdb_shipper:\n active_index_directory: /data/loki/index\n shared_store: s3\n resync_interval: 5s\n cache_location: /data/loki/boltdb-cache\n monitoring:\n dashboards:\n enabled: false\n rules:\n enabled: false\n serviceMonitor:\n enabled: false\n metricsInstance:\n enabled: false\n selfMonitoring:\n enabled: false\n grafanaAgent:\n installOperator: false\n grafanaAgent:\n enabled: false\n lokiCanary:\n enabled: false\n test:\n enabled: false\n gateway:\n enabled: false\n # set the single binary version for basic usage\n singleBinary:\n replicas: 1\n # set resources\n resources:\n limits:\n cpu: 1\n memory: 2Gi\n requests:\n cpu: 300m\n memory: 1Gi\n persistence:\n enabled: false\n extraVolumes:\n - name: data\n emptyDir: {}\n - name: storage\n emptyDir: {}\n extraVolumeMounts:\n - name: data\n mountPath: /data\n - name: storage\n mountPath: /var/loki\n # set disk persistence to reduce data loss in case of pod crash\n # persistence:\n # storageClass: set-by-customer\n serviceAccount:\n annotations: {}\n")))),Object(l.b)("h4",{id:"promtail"},"Promtail"),Object(l.b)("p",null,"A configuration example compatible with all providers:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"promtail:\n fullnameOverride: promtail\n # promtail requires to be spawned in kube-system namespace\n namespace: kube-system\n priorityClassName: system-node-critical\n config:\n clients:\n # forward logs to Loki\n - url: *promtailLokiUrl\n snippets:\n extraRelabelConfigs:\n - action: labelmap\n # required to be able to watch logs from Qovery console interface\n regex: __meta_kubernetes_pod_label_(qovery_com_service_id|qovery_com_service_type|qovery_com_environment_id)\n")),Object(l.b)("h3",{id:"certificates"},"Certificates"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Cert-manager helps you to get TLS certificates through Let's Encrypt")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Without it, you will not be able to automatically get TLS certificates")))),Object(l.b)("p",null,"Qovery uses ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://cert-manager.io/"}),"Cert Manager")," to automatically get TLS certificates for your applications."),Object(l.b)("h4",{id:"cert-manager"},"Cert Manager"),Object(l.b)("p",null,"Here is the minimal setup for all cloud providers:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"cert-manager:\n fullnameOverride: cert-manager\n # CRD are required\n installCRDs: true\n replicaCount: 1\n startupapicheck:\n jobAnnotations:\n helm.sh/hook: post-install,post-upgrade\n rbac:\n annotations:\n helm.sh/hook: post-install,post-upgrade\n serviceAccount:\n annotations:\n helm.sh/hook: post-install,post-upgrade\n")),Object(l.b)("h4",{id:"qovery-cert-manager-webhook"},"Qovery Cert Manager Webhook"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No (but if you're using Qovery DNS Provider)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Required to get Let's Encrypt TLS if Qovery DNS Provider is used")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Without it, you will not be able to automatically get TLS certificates with Qovery DNS Provider")))),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"qovery",placeholder:"Select a platform",select:!1,size:null,values:[{group:"QoveryCertManagerWebhook",label:"Qovery DNS",value:"qovery"},{group:"QoveryCertManagerWebhook",label:"",value:""}],mdxType:"Tabs"},Object(l.b)(s.a,{value:"qovery",mdxType:"TabItem"},Object(l.b)("p",null,"A configuration example compatible with all providers:"),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"qovery-cert-manager-webhook:\n fullnameOverride: qovery-cert-manager-webhook\n certManager:\n # set the same namespace than cert-manager\n namespace: qovery\n serviceAccountName: cert-manager\n secret:\n apiUrl: *qoveryDnsUrl\n apiKey: *jwtToken\n")))),Object(l.b)("h4",{id:"cert-manager-configs"},"Cert Manager Configs"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"This is an helper to deploy cert-manager config. But you can manually set it")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Installing Cert-manager is not enough, you have to configure it to get TLS working")))),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"ExternalDns",label:"Demo",value:"demo"},{group:"ExternalDns",label:"Qovery DNS",value:"qovery"},{group:"ExternalDns",label:"Cloudflare",value:"cloudflare"}],mdxType:"Tabs"},Object(l.b)(s.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"This is the configuration of Cert Manager itself. It is used by all Cert Manager components."),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"cert-manager-configs:\n fullnameOverride: cert-manager-configs\n # set pdns to use Qovery DNS provider\n externalDnsProvider: pdns\n managedDns: [*domain]\n acme:\n letsEncrypt:\n emailReport: *acmeEmailAddr\n # As it's a demo cluster, we use the staging environment to avoid rate limit issues\n acmeUrl: https://acme-staging-v02.api.letsencrypt.org/directory\n provider:\n # set the provider of your choice or use the Qovery DNS provider\n pdns:\n apiPort: 443\n apiUrl: *qoveryDnsUrl\n apiKey: *jwtToken\n"))),Object(l.b)(s.a,{value:"qovery",mdxType:"TabItem"},Object(l.b)("p",null,"This is the configuration of Cert Manager itself. It is used by all Cert Manager components."),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"cert-manager-configs:\n fullnameOverride: cert-manager-configs\n # set pdns to use Qovery DNS provider\n externalDnsProvider: pdns\n managedDns: [*domain]\n acme:\n letsEncrypt:\n emailReport: *acmeEmailAddr\n # set the Let's Encrypt URL\n # Test: https://acme-staging-v02.api.letsencrypt.org/directory\n # Prod: https://acme-v02.api.letsencrypt.org/directory\n acmeUrl: https://acme-v02.api.letsencrypt.org/directory\n provider:\n # set the provider of your choice or use the Qovery DNS provider\n pdns:\n apiPort: 443\n apiUrl: *qoveryDnsUrl\n apiKey: *jwtToken\n"))),Object(l.b)(s.a,{value:"cloudflare",mdxType:"TabItem"},Object(l.b)("p",null,"This is the configuration of Cert Manager itself. It is used by all Cert Manager components."),Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),'cert-manager-configs:\n fullnameOverride: cert-manager-configs\n # set pdns to use Qovery DNS provider\n externalDnsProvider: cloudflare\n managedDns: [*domain]\n acme:\n letsEncrypt:\n emailReport: *acmeEmailAddr\n acmeUrl: https://acme-v02.api.letsencrypt.org/directory\n provider:\n cloudflare:\n apiToken: "set your Cloudflare API token here"\n email: "set your Cloudflare email here"\n')))),Object(l.b)("p",null,"Qovery uses ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/kubernetes-sigs/metrics-server"}),"Metrics Server")," to collect metrics from your Kubernetes cluster and scale your applications automatically based on custom metrics."),Object(l.b)("h2",{id:"observability"},"Observability"),Object(l.b)("h3",{id:"metrics-server"},"Metrics Server"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(a.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Mandatory if you want to retrive pod metrics for the Qovery agent and if you want to be able to use the horizontal pod scaling")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"No HPA and no application metrics in the QOveyr console")))),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"MetricsServer",label:"Demo",value:"demo"},{group:"MetricsServer",label:"AWS",value:"aws"},{group:"MetricsServer",label:"GCP",value:"gcp"},{group:"MetricsServer",label:"Scaleway",value:"scaleway"}],mdxType:"Tabs"},Object(l.b)(s.a,{value:"aws",mdxType:"TabItem"},Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"metrics-server:\n # create api service to be able to use hpa/vpa\n apiService:\n create: true\n # set rolling restart strategy\n updateStrategy:\n type: set-by-customer\n # set resources\n resources:\n limits:\n cpu: set-by-customer\n memory: set-by-customer\n requests:\n cpu: set-by-customer\n memory: set-by-customer\n"))),Object(l.b)(s.a,{value:"gcp",mdxType:"TabItem"},Object(l.b)("p",null,"Nothing needs to be deployed, as GCP already provides a managed metrics server.")),Object(l.b)(s.a,{value:"scaleway",mdxType:"TabItem"},Object(l.b)("p",null,"Nothing needs to be deployed, as Scaleway already provides a managed metrics server.")),Object(l.b)(s.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("pre",null,Object(l.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"metrics-server:\n fullnameOverride: metrics-server\n defaultArgs:\n - --cert-dir=/tmp\n - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\n - --kubelet-use-node-status-port\n - --metric-resolution=15s\n - --kubelet-insecure-tls\n apiService:\n create: false\n")))),Object(l.b)("h2",{id:"faq"},"FAQ"),Object(l.b)("h3",{id:"i-have-a-non-covered-use-case-what-should-i-do"},"I have a non-covered use case. What should I do?"),Object(l.b)("p",null,"Please ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://www.qovery.com/contact"}),"contact us"),". We will be happy to help you."),Object(l.b)("h3",{id:"can-i-host-the-qovery-control-plane-on-my-own"},"Can I host the Qovery control plane on my own?"),Object(l.b)("p",null,"At the momement, you can't. But please ",Object(l.b)("a",Object(a.a)({parentName:"p"},{href:"https://www.qovery.com/contact"}),"contact us")," to discuss about it. We will be happy to help you."))}p.isMDXComponent=!0},423:function(e,t,n){"use strict";n(425);var a=n(0),r=n.n(a),l=n(422),o=n.n(l);n(132);t.a=function(e){var t=e.children,n=e.classNames,a=e.fill,l=e.icon,s=e.type,c=null;switch(s){case"danger":c="alert-triangle";break;case"success":c="check-circle";break;case"warning":c="alert-triangle";break;default:c="info"}return r.a.createElement("div",{className:o()(n,"alert","alert--"+s,{"alert--fill":a,"alert--icon":!1!==l}),role:"alert"},!1!==l&&r.a.createElement("i",{className:o()("feather","icon-"+(l||c))}),t)}},427:function(e,t,n){var a=n(28).f,r=Function.prototype,l=/^\s*function ([^ (]*)/;"name"in r||n(10)&&a(r,"name",{configurable:!0,get:function(){try{return(""+this).match(l)[1]}catch(e){return""}}})},428:function(e,t,n){"use strict";n(427);var a=n(0),r=n.n(a),l=n(423);t.a=function(e){var t=e.children,n=e.name;return r.a.createElement(l.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},r.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",n||"page"," assumes the following:"),t)}},433:function(e,t,n){"use strict";var a=n(0),r=n.n(a),l=(n(422),n(432)),o=n.n(l);n(134);t.a=function(e){var t=e.children,n=e.headingDepth,l=e.hideFeedbackQuestion,s="undefined"!=typeof window?window.location:null,c={title:"Tutorial on "+s+" failed",body:"The tutorial on:\n\n"+s+"\n\nHere's what went wrong:\n\n\x3c!-- Insert command output and details. Thank you for reporting! :) --\x3e"},i="https://github.com/qovery/documentation/issues/new?"+o.a.stringify(c),b=Object(a.useState)(null),u=b[0],d=b[1];return r.a.createElement("div",{className:"steps steps--h"+n},t,!l&&!u&&r.a.createElement("div",{className:"steps--feedback"},"How was it? Did this tutorial work?\xa0\xa0",r.a.createElement("span",{className:"button button--sm button--primary",onClick:function(){return d("yes")}},"Yes"),"\xa0\xa0",r.a.createElement("a",{href:i,target:"_blank",className:"button button--sm button--primary"},"No")),"yes"==u&&r.a.createElement("div",{className:"steps--feedback steps--feedback--success"},"Thanks! If you're enjoying Qovery please consider ",r.a.createElement("a",{href:"https://github.com/qovery/documentation/",target:"_blank"},"starring our Github repo"),"."))}},436:function(e,t,n){"use strict";var a=n(1),r=(n(441),n(438),n(52),n(29),n(22),n(21),n(0)),l=n.n(r),o=n(446),s=n(422),c=n.n(s),i=n(432),b=n.n(i),u=n(445),d=37,m=39;function p(e){var t=e.block,n=e.centered,a=e.changeSelectedValue,r=e.className,o=e.handleKeydown,s=e.style,i=e.values,b=e.selectedValue,u=e.tabRefs;return l.a.createElement("div",{className:n?"tabs--centered":null},l.a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:c()("tabs",r,{"tabs--block":t}),style:s},i.map((function(e){var t=e.value,n=e.label;return l.a.createElement("li",{role:"tab",tabIndex:"0","aria-selected":b===t,className:c()("tab-item",{"tab-item--active":b===t}),key:t,ref:function(e){return u.push(e)},onKeyDown:function(e){return o(u,e.target,e)},onFocus:function(){return a(t)},onClick:function(){return a(t)}},n)}))))}function g(e){var t=e.placeholder,n=e.selectedValue,a=e.changeSelectedValue,r=e.size,s=e.values,c=s;if(c[0].group){var i=_.groupBy(c,"group");c=Object.keys(i).map((function(e){return{label:e,options:i[e]}}))}return l.a.createElement(o.a,{className:"react-select-container react-select--"+r,classNamePrefix:"react-select",options:c,isClearable:n,placeholder:t,value:s.find((function(e){return e.value==n})),onChange:function(e){return a(e?e.value:null)}})}t.a=function(e){e.block,e.centered;var t=e.children,n=e.defaultValue,o=e.groupId,s=e.label,c=e.placeholder,i=e.select,y=e.size,O=(e.style,e.values),j=e.urlKey,h=Object(u.a)(),v=h.tabGroupChoices,f=h.setTabGroupChoices,N=Object(r.useState)(n),w=N[0],k=N[1];if(null!=o){var x=v[o];null!=x&&x!==w&&k(x)}var C=function(e){k(e),null!=o&&f(o,e)},q=[],I=function(e,t,n){switch(n.keyCode){case m:!function(e,t){var n=e.indexOf(t)+1;e[n]?e[n].focus():e[0].focus()}(e,t);break;case d:!function(e,t){var n=e.indexOf(t)-1;e[n]?e[n].focus():e[e.length-1].focus()}(e,t)}};return Object(r.useEffect)((function(){if("undefined"!=typeof window&&window.location&&j){var e=b.a.parse(window.location.search);e[j]&&k(e[j])}}),[]),l.a.createElement(l.a.Fragment,null,l.a.createElement("div",{className:"margin-bottom--"+(y||"md")},s&&l.a.createElement("div",{className:"margin-vert--sm"},s),O.length>1&&(i?l.a.createElement(g,Object(a.a)({changeSelectedValue:C,handleKeydown:I,placeholder:c,selectedValue:w,size:y,tabRefs:q},e)):l.a.createElement(p,Object(a.a)({changeSelectedValue:C,handleKeydown:I,selectedValue:w,tabRefs:q},e)))),r.Children.toArray(t).filter((function(e){return e.props.value===w}))[0])}},442:function(e,t,n){"use strict";var a=n(0),r=n.n(a);t.a=function(e){return r.a.createElement(r.a.Fragment,null,e.children)}}}]);
\ No newline at end of file
diff --git a/30e307eb.a184537e.js b/30e307eb.a184537e.js
deleted file mode 100644
index db03829d46..0000000000
--- a/30e307eb.a184537e.js
+++ /dev/null
@@ -1 +0,0 @@
-(window.webpackJsonp=window.webpackJsonp||[]).push([[56],{208:function(e,t,a){"use strict";a.r(t),a.d(t,"frontMatter",(function(){return i})),a.d(t,"metadata",(function(){return u})),a.d(t,"rightToc",(function(){return d})),a.d(t,"default",(function(){return m}));var n=a(1),r=a(9),l=(a(0),a(424)),o=a(436),c=a(442),b=a(433),s=a(423),i=(a(428),{last_modified_on:"2023-12-22",title:"Kubernetes",description:"Learn how to install and configure Qovery on your own Kubernetes cluster (BYOK) / Self-managed Kubernetes cluster"}),u={id:"using-qovery/configuration/provider/kubernetes",title:"Kubernetes",description:"Learn how to install and configure Qovery on your own Kubernetes cluster (BYOK) / Self-managed Kubernetes cluster",source:"@site/docs/using-qovery/configuration/provider/kubernetes.md",permalink:"/docs/using-qovery/configuration/provider/kubernetes",sidebar:"docs",previous:{title:"Provider",permalink:"/docs/using-qovery/configuration/provider"},next:{title:"Cluster Advanced Settings",permalink:"/docs/using-qovery/configuration/cluster-advanced-settings"}},d=[{value:"Components",id:"components",children:[]},{value:"What's the requirements?",id:"whats-the-requirements",children:[]},{value:"Private registry",id:"private-registry",children:[]},{value:"Install Qovery",id:"install-qovery",children:[]},{value:"Configuration",id:"configuration",children:[{value:"Qovery",id:"qovery",children:[]},{value:"Ingress",id:"ingress",children:[]},{value:"DNS",id:"dns",children:[]},{value:"Logging",id:"logging",children:[]},{value:"Certificates",id:"certificates",children:[]}]},{value:"Observability",id:"observability",children:[{value:"Metrics Server",id:"metrics-server",children:[]}]},{value:"FAQ",id:"faq",children:[{value:"I have a non-covered use case. What should I do?",id:"i-have-a-non-covered-use-case-what-should-i-do",children:[]},{value:"Can I host the Qovery control plane on my own?",id:"can-i-host-the-qovery-control-plane-on-my-own",children:[]}]}],p={rightToc:d};function m(e){var t=e.components,a=Object(r.a)(e,["components"]);return Object(l.b)("wrapper",Object(n.a)({},p,a,{components:t,mdxType:"MDXLayout"}),Object(l.b)(s.a,{type:"warning",mdxType:"Alert"},Object(l.b)("p",null,"Installing Qovery on your Kubernetes cluster is currently in beta. ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://www.qovery.com/solutions/bring-your-own-kubernetes"}),"You need to request your access here"),".")),Object(l.b)(s.a,{type:"info",mdxType:"Alert"},Object(l.b)("p",null,"This section is for Kubernetes power-users. If you are not familiar with Kubernetes, we recommend you to use Qovery on a Managed Kubernetes cluster on ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/cloud-service-provider/amazon-web-services/"}),"AWS"),", ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/cloud-service-provider/google-cloud-platform/"}),"GCP"),", ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/cloud-service-provider/microsoft-azure/"}),"Scaleway"),", or contact us.")),Object(l.b)("p",null,"Qovery Self-Managed (or BYOK: Bring Your Own Kubernetes) is a self-hosted version of Qovery. It allows you to install Qovery on your own Kubernetes cluster.\nRead ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://www.qovery.com/blog/kubernetes-managed-by-qovery-vs-self-managed-byok"}),"this article")," to better understand the difference with the Managed Kubernetes by Qovery. In a nutshell, Qovery Managed/BYOK is for Kubernetes experts who want to manage their own Kubernetes cluster.\nIn this version, Qovery does not manage the Kubernetes cluster for you."),Object(l.b)("p",null,"This page explains how to install and configure Qovery on your Kubernetes cluster. If you are looking for a quick step-by-step guide, please follow the ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"/guides/provider/guide-kubernetes/"}),"Kubernetes guide"),"."),Object(l.b)("h2",{id:"components"},"Components"),Object(l.b)("p",{align:"center"},Object(l.b)("img",{src:"/img/qovery_byok_how_it_works.jpg",alt:"How Qovery works with Self Managed Kubernetes cluster"})),Object(l.b)("p",null,"They are two types of components:"),Object(l.b)("p",null,"Qovery components:"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"Qovery Control Plane: the Qovery Control Plane is the brain of Qovery. It is responsible for managing your applications and providing the API to interact with Qovery."),Object(l.b)("li",{parentName:"ul"},"Qovery Cluster Agent (mandatory): the Qovery Cluster Agent is responsible for securely forwarding logs and metrics from your Kubernetes cluster to Qovery control plane."),Object(l.b)("li",{parentName:"ul"},"Qovery Shell Agent (mandatory): the Qovery Shell Agent is responsible for giving you a secure remote shell access to your Kubernetes pods if you need it. E.g. when using ",Object(l.b)("inlineCode",{parentName:"li"},"qovery shell")," command."),Object(l.b)("li",{parentName:"ul"},"Qovery Engine (optional): the Qovery Engine is responsible for managing your applications deployment on your Kubernetes cluster. It can be used Qovery side or is installed on your Kubernetes cluster.")),Object(l.b)("p",null,"Third-party components:"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"NGINX Ingress Controller (optional)"),Object(l.b)("li",{parentName:"ul"},"External DNS (optional)"),Object(l.b)("li",{parentName:"ul"},"Loki (optional)"),Object(l.b)("li",{parentName:"ul"},"Promtail (optional)"),Object(l.b)("li",{parentName:"ul"},"Cert Manager (optional)"),Object(l.b)("li",{parentName:"ul"},"...")),Object(l.b)("p",null,"You can chose what you want to install and manage, and you will have a description of what services are used, and responsible for. You can disable them if you don't want to use them. And you can even install other components if you want to."),Object(l.b)("h2",{id:"whats-the-requirements"},"What's the requirements?"),Object(l.b)("p",null,"Qovery requires a Kubernetes cluster with the following requirements:"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"Kubernetes version 1.26 or higher"),Object(l.b)("li",{parentName:"ul"},"Helm version 3.0 or higher"),Object(l.b)("li",{parentName:"ul"},"2 CPU"),Object(l.b)("li",{parentName:"ul"},"4 GB RAM"),Object(l.b)("li",{parentName:"ul"},"20 GB disk space"),Object(l.b)("li",{parentName:"ul"},"Being able to access to the Internet"),Object(l.b)("li",{parentName:"ul"},"A private registry")),Object(l.b)("p",null,"Here are some examples of Kubernetes distributions that can be used with Qovery. ",Object(l.b)("strong",{parentName:"p"},"This is a non exhaustive list"),"."),Object(l.b)(s.a,{type:"danger",mdxType:"Alert"},Object(l.b)("p",null,"Theses examples are not recommendations! Simply examples of what can be installed in the fastest way.")),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"eks",placeholder:"Select a cloud provider",select:!1,size:null,values:[{group:"k8s",label:"AWS - EKS",value:"eks"},{group:"k8s",label:"GCP - GKE",value:"gke"},{group:"k8s",label:"Scaleway - Kapsule",value:"kapsule"},{group:"k8s",label:"Demo (K3D)",value:"demo"}],mdxType:"Tabs"},Object(l.b)(c.a,{value:"eks",mdxType:"TabItem"},Object(l.b)("p",null,"To create a Kubernetes cluster on AWS, the simplest way is to use ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://eksctl.io/installation/"}),"eksctl binary"),". For example:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-bash"}),"eksctl create cluster --region=us-east-2 --zones=us-east-2a,us-east-2b,us-east-2d\n"))),Object(l.b)(c.a,{value:"gke",mdxType:"TabItem"},Object(l.b)("p",null,"To create a Kubernetes cluster on GCP, the simplest way is to use ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://cloud.google.com/sdk/docs/install"}),"gcloud binary"),". For example:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-bash"}),'gcloud beta container --project "qovery-gcp-tests" \\\n clusters create-auto "qovery-test" \\\n --region "us-east5" \\\n --release-channel "stable" \\\n --network "projects/qovery-gcp-tests/global/networks/default" \\\n --subnetwork "projects/qovery-gcp-tests/regions/us-east5/subnetworks/default"\n --cluster-ipv4-cidr "/16"\n --services-ipv4-cidr "10.0.0.0/16"\n'))),Object(l.b)(c.a,{value:"kapsule",mdxType:"TabItem"},Object(l.b)("p",null,"To create a Kubernetes cluster on Scaleway, the simplest way is to use ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://github.com/scaleway/scaleway-cli"}),"scw binary"),". For example:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-bash"}),"scw k8s cluster create name=qovery-test\nscw k8s pool create cluster-id= name=pool node-type=GP1_XL size=3\n")),Object(l.b)("p",null,"You can find the ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://www.scaleway.com/en/docs/containers/kubernetes/api-cli/creating-managing-kubernetes-lifecycle-cliv2/"}),"complete documentation here"),".")),Object(l.b)(c.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"Here is an example with K3d to deploy a local Kubernetes cluster (you can use k3s or any other Kubernetes distribution):"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-bash"}),'k3d cluster create --image rancher/k3s:v1.26.11-k3s2 --k3s-arg "--disable=traefik,metrics-server@server:0" \\\n-v $(pwd)/registry_bin:/var/lib/rancher/credentialprovider/bin@server:0 \\\n-v $(pwd)/config.yaml:/var/lib/rancher/credentialprovider/config.yaml@server:0\n')),Object(l.b)("p",null,"Note: please take a look at the registry information below to understand why we need to mount the registry folder."))),Object(l.b)("h2",{id:"private-registry"},"Private registry"),Object(l.b)("p",null,"Qovery requires a private registry to store built images and mirror containers in order to reduce potential images deletion by 3rd party, while you still need them (",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/image-mirroring/"}),"more info here"),")."),Object(l.b)("p",{align:"center"},Object(l.b)("img",{src:"/img/configuration/provider/kubelet-credential-providers-plugin.png",alt:"Kubelet Credential Providers"})),Object(l.b)("p",null,"To do so, Qovery advise to use ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://kubernetes.io/blog/2022/12/22/kubelet-credential-providers/"}),"Kubelet Credential Provider")," as it's transparent for developers."),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"cpor",placeholder:"Select a platform",select:!1,size:null,values:[{group:"Registry",label:"Cloud Provider Own Registry",value:"cpor"},{group:"Registry",label:"ECR",value:"ecr"}],mdxType:"Tabs"},Object(l.b)(c.a,{value:"cpor",mdxType:"TabItem"},Object(l.b)("p",null,"If you're running Qovery Self-Managed version, and you are going to use the registry from the cloud provider itself, you don't have anything to do. The cloud providers already manage this part for you.")),Object(l.b)(c.a,{value:"ecr",mdxType:"TabItem"},Object(l.b)("p",null,"If you want to use ECR on a non-EKS cluster, you will need to install the ECR Credential Provider on your Kubernetes cluster."),Object(l.b)("p",null,"You have to create an IAM user with the following policy, and generate an access key:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-json"}),'{\n "Statement": [\n {\n "Action": [\n "ecr:*",\n ],\n "Effect": "Allow",\n "Resource": "*"\n }\n ],\n "Version": "2012-10-17"\n}\n')),Object(l.b)("p",null,"Then we create a ",Object(l.b)("inlineCode",{parentName:"p"},"config.yaml")," file to configure the ECR credential provider, where you should set the AWS credentials previously generated:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),'apiVersion: kubelet.config.k8s.io/v1\nkind: CredentialProviderConfig\nproviders:\n - name: ecr-credential-provider\n matchImages:\n - "*.dkr.ecr.*.amazonaws.com"\n - "*.dkr.ecr.*.amazonaws.com.cn"\n - "*.dkr.ecr-fips.*.amazonaws.com"\n - "*.dkr.ecr.us-iso-east-1.c2s.ic.gov"\n - "*.dkr.ecr.us-isob-east-1.sc2s.sgov.gov"\n defaultCacheDuration: "12h"\n apiVersion: credentialprovider.kubelet.k8s.io/v1\n env:\n - name: AWS_ACCESS_KEY_ID\n value: xxx\n - name: AWS_DEFAULT_REGION\n value: xxx\n - name: AWS_SECRET_ACCESS_KEY\n value: xxx\n')),Object(l.b)(s.a,{type:"info",mdxType:"Alert"},Object(l.b)("p",null,"Depending on your Kubernetes installation (cloud provider, on premise...) please refer to the official documentation to deploy the credential provider.")),Object(l.b)("details",null,Object(l.b)("summary",null,"Example with K3d"),Object(l.b)("p",null,"Here is an example with K3d to deploy a local Kubernetes cluster with the ECR credential provider."),Object(l.b)("p",null,"We first create the prerequired folders and file for the binary:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{}),"mkdir -p registry_bin\ntouch registry_bin/ecr-credential-provider\nchmod 755 registry_bin/ecr-credential-provider\n")),Object(l.b)("p",null,"Note: the ecr-credential-provider binary should be present for k3s to start. We will build it later."),Object(l.b)("p",null,"Now we can run a local Kubernetes cluster (update the path to ",Object(l.b)("inlineCode",{parentName:"p"},"config.yaml")," file, and the Kubernetes ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://hub.docker.com/r/rancher/k3s/tags"}),"image tag version"),"):"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-bash"}),'k3d cluster create --image rancher/k3s:v1.26.11-k3s2 --k3s-arg "--disable=traefik,metrics-server@server:0" \\\n-v $(pwd)/registry_bin:/var/lib/rancher/credentialprovider/bin@server:0 \\\n-v $(pwd)/config.yaml:/var/lib/rancher/credentialprovider/config.yaml@server:0\n'))),Object(l.b)("br",null),Object(l.b)("p",null,"Once the Credential provider configuration has been deployed, we'll build the binary and deploy it on the cluster (note: it has to be present on all worker nodes).\nSimply deploy this job which will do the work:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),'apiVersion: batch/v1\nkind: Job\nmetadata:\n name: cloud-provider-repository-binary-builder\nspec:\n backoffLimit: 0\n template:\n spec:\n restartPolicy: Never\n containers:\n - name: ecr-credential-builder\n image: alpine:3.18\n command:\n - /bin/sh\n - -c\n - |\n apk add -U ca-certificates tar zstd tzdata go git\n git clone https://github.com/kubernetes/cloud-provider-aws.git\n cd cloud-provider-aws/cmd/ecr-credential-provider\n CGO_ENABLED=0 go build -mod=readonly .\n chmod 755 ecr-credential-provider\n mkdir -p /mnt/host/var/lib/rancher/credentialprovider/bin/\n cp ecr-credential-provider /mnt/host/var/lib/rancher/credentialprovider/bin/\n volumeMounts:\n - mountPath: /mnt/host\n name: host\n volumes:\n - hostPath:\n path: /\n type: ""\n name: host\n')),Object(l.b)("p",null,"You can now move on the Qovery Helm deployment."))),Object(l.b)("h2",{id:"install-qovery"},"Install Qovery"),Object(l.b)(b.a,{headingDepth:3,mdxType:"Steps"},Object(l.b)("ol",null,Object(l.b)("li",null,Object(l.b)("p",null,"Install ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://helm.sh"}),"Helm")," command line tool.")),Object(l.b)("li",null,Object(l.b)("p",null,"Add Qovery Helm repository."),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-bash"}),"helm repo add qovery https://helm.qovery.com\nhelm repo update\n"))),Object(l.b)("li",null,Object(l.b)("p",null,"Login to the Qovery console, create a cluster until it's asked to save informations in the ",Object(l.b)("inlineCode",{parentName:"p"},"values.yaml")," file.")),Object(l.b)("li",null,Object(l.b)("p",null,"You will find several ",Object(l.b)("inlineCode",{parentName:"p"},"values.yaml")," files. Depending on you need, select the one you want and update the configuration accordingly:"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"values-demo.yaml"),": this version is to locally test with k3s or minikube"),Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"values-.yaml"),": find versions made for some providers")),Object(l.b)(s.a,{type:"info",mdxType:"Alert"},Object(l.b)("p",null,"Note: The provided values files are examples. There is no restriction where Qovery can be deployed. Feel free to copy or use an existing example and adapt it to your needs.")),Object(l.b)("p",null,"Here is an example of how the chart works:"),Object(l.b)("details",null,Object(l.b)("summary",null,"values-demo.yaml"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),'## Services you can enable or disable\nservices:\n qovery:\n qovery-cluster-agent:\n enabled: true\n qovery-shell-agent:\n enabled: true\n ingress:\n ingress-nginx:\n enabled: true\n dns:\n external-dns:\n enabled: true\n logging:\n loki:\n enabled: true\n promtail:\n enabled: true\n certificates:\n cert-manager:\n enabled: true\n qovery-cert-manager-webhook:\n enabled: true\n cert-manager-configs:\n enabled: true\n observability:\n metrics-server:\n enabled: true\n\n## Qovery Common config\n# Past information from Qovery cluster console creation\n\nqovery:\n clusterId: &clusterId "set-by-customer"\n clusterShortId: &shortClusterId "set-by-customer"\n organizationId: &organizationId "set-by-customer"\n jwtToken: &jwtToken "set-by-customer"\n domain: &domain "set-by-customer"\n grpcServer: &grpcServer "set-by-customer"\n engineGrpcServer: &engineGrpcServer "set-by-customer"\n qoveryDnsUrl: &qoveryDnsUrl "set-by-customer"\n lokiUrl: &lokiUrl "set-by-customer"\n promtailLokiUrl: &promtailLokiUrl "set-by-customer"\n acmeEmailAddr: &acmeEmailAddr "set-by-customer"\n externalDnsPrefix: &externalDnsPrefix "set-by-customer"\n architectures: &architectures "set-by-customer"\n\n## Chart overrides\n...\n')))),Object(l.b)("li",null,Object(l.b)("p",null,"Install Qovery on your Kubernetes cluster."),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-bash"}),"helm upgrade --install -n qovery -f values-demo.yaml qovery\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"-n qovery"),": the namespace where Qovery and its dependencies will be installed"),Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"-f values-demo.yaml"),": specify the values overrides file you want to use"),Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"qovery"),": name of the chart to deploy"))))),Object(l.b)("h2",{id:"configuration"},"Configuration"),Object(l.b)("h3",{id:"qovery"},"Qovery"),Object(l.b)("p",null,"This is the configuration of Qovery itself. It is used by all Qovery components."),Object(l.b)(s.a,{type:"danger",mdxType:"Alert"},Object(l.b)("p",null,Object(l.b)("strong",{parentName:"p"},"Do not share the jwtToken! Keep it in a safe place.")," It is used to authenticate the cluster.")),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null}),"Key"),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null}),"Required"),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null}),"Description"),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null}),"Default"))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.clusterId")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"The cluster ID. It is used to identify your cluster."),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.shortClusterId")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"The short cluster ID. It is used to identify your cluster."),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.organizationId")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"The organization ID. It is used to identify your organization."),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.jwtToken")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"The JWT token. It is used to authenticate your cluster."),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.domain")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"The domain name used by Qovery."),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.qoveryDnsUrl")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Yes"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Qovery DNS url in case you want to use Qovery provided DNS"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.lokiUrl")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Local Loki URL (required if Loki is set)"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.promtailLokiUrl")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Promtail Loki URL (required if Promtail and Loki are set)"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.acmeEmailAddr")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Email address used for ",Object(l.b)("inlineCode",{parentName:"td"},"Let's Encrypt")," TLS requests"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.externalDnsPrefix")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"ExernalDNS TXT record prefix (required if ExternalDNS is set)"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"set-by-customer"))),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"qovery.architectures")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Set cluster architectures (comma separated)"),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("inlineCode",{parentName:"td"},"AMD64"))))),Object(l.b)("h4",{id:"qovery-cluster-agent"},"Qovery Cluster Agent"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Yes")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"The cluster agent is responsible for securely forwarding logs and metrics from your Kubernetes cluster to Qovery control plane")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"The cluster will not report to Qovery control plane Kubernetes information, so the Qovery console will report unknown satus values")))),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"qovery-cluster-agent:\n fullnameOverride: qovery-cluster-agent\n")),Object(l.b)("h4",{id:"qovery-shell-agent"},"Qovery Shell Agent"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Yes")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Used to give a remote shell access to you Kubernetes pods (if user is allowed from Qovery RBAC) with the Qovery CLI")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No remote connection will be possible, and Qovery support will not be able to help you to diagnose issues")))),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"qovery-shell-agent:\n fullnameOverride: qovery-shell-agent\n")),Object(l.b)("h3",{id:"ingress"},"Ingress"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Web services can be privately or publicly exposed")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No web services will be exposed")))),Object(l.b)("p",null,"Qovery us will be exposed ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://docs.nginx.com/nginx-ingress-controller/"}),"NGINX Ingress Controller")," by default to route traffic to your applications."),Object(l.b)("h4",{id:"nginx-ingress-controller"},"Nginx Ingress Controller"),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"NginxIngress",label:"Demo",value:"demo"},{group:"NginxIngress",label:"AWS",value:"aws"},{group:"NginxIngress",label:"GCP",value:"gcp"},{group:"NginxIngress",label:"Scaleway",value:"scaleway"}],mdxType:"Tabs"},Object(l.b)(c.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"Here is the minimum override configuration to be used:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),'ingress-nginx:\n fullnameOverride: ingress-nginx\n controller:\n useComponentLabel: true\n admissionWebhooks:\n enabled: false\n # Ingress class used when an application/container with public access is set\n ingressClass: nginx-qovery\n extraArgs:\n # Default TLS certificate name and path\n default-ssl-certificate: "qovery/letsencrypt-acme-qovery-cert"\n # Allows customization of the source of the IP address or FQDN to report in the ingress status field\n publishService:\n enabled: true\n'))),Object(l.b)(c.a,{value:"aws",mdxType:"TabItem"},Object(l.b)("p",null,"Here is an example with Nginx Ingress Controller on AWS with NLB:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),'ingress-nginx:\n controller:\n useComponentLabel: true\n admissionWebhooks:\n enabled: set-by-customer\n metrics:\n enabled: set-by-customer\n serviceMonitor:\n enabled: set-by-customer\n config:\n proxy-body-size: 100m\n server-tokens: "false"\n ingressClass: nginx-qovery\n extraArgs:\n default-ssl-certificate: "cert-manager/letsencrypt-acme-qovery-cert"\n updateStrategy:\n rollingUpdate:\n maxUnavailable: 1\n \n autoscaling:\n enabled: true\n minReplicas: set-by-customer\n maxReplicas: set-by-customer\n targetCPUUtilizationPercentage: set-by-customer\n \n publishService:\n enabled: true\n \n service:\n enabled: true\n annotations:\n service.beta.kubernetes.io/aws-load-balancer-type: nlb\n external-dns.alpha.kubernetes.io/hostname: "set-by-customer"\n externalTrafficPolicy: "Local"\n sessionAffinity: ""\n healthCheckNodePort: 0\n'))),Object(l.b)(c.a,{value:"scaleway",mdxType:"TabItem"},Object(l.b)("p",null,"Here is an example with Nginx Ingress Controller on Scaleway:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),'ingress-nginx:\n controller:\n useComponentLabel: true\n admissionWebhooks:\n enabled: set-by-customer\n metrics:\n enabled: set-by-customer\n serviceMonitor:\n enabled: set-by-customer\n config:\n proxy-body-size: 100m\n server-tokens: "false"\n use-proxy-protocol: "true"\n ingressClass: nginx-qovery\n extraArgs:\n default-ssl-certificate: "cert-manager/letsencrypt-acme-qovery-cert"\n updateStrategy:\n rollingUpdate:\n maxUnavailable: 1\n autoscaling:\n enabled: true\n minReplicas: set-by-customer\n maxReplicas: set-by-customer\n targetCPUUtilizationPercentage: set-by-customer\n publishService:\n enabled: true\n service:\n enabled: true\n # https://github.com/scaleway/scaleway-cloud-controller-manager/blob/master/docs/loadbalancer-annotations.md\n annotations:\n service.beta.kubernetes.io/scw-loadbalancer-forward-port-algorithm: "leastconn"\n service.beta.kubernetes.io/scw-loadbalancer-protocol-http: "false"\n service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v1: "false"\n service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v2: "true"\n service.beta.kubernetes.io/scw-loadbalancer-health-check-type: tcp\n service.beta.kubernetes.io/scw-loadbalancer-use-hostname: "true"\n service.beta.kubernetes.io/scw-loadbalancer-type: "set-by-customer"\n external-dns.alpha.kubernetes.io/hostname: "set-by-customer"\n externalTrafficPolicy: "Local"\n')))),Object(l.b)("h4",{id:"other-ingress-controllers"},"Other Ingress Controllers"),Object(l.b)("p",null,"Qovery supports other Ingress Controllers. Please contact us if you want to use another one. We will be happy to help you."),Object(l.b)("h3",{id:"dns"},"DNS"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Used to easily reach your applications with DNS records, even on private network")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"You will have easy access with dns names to your services, you'll have to use IPs")))),Object(l.b)("p",null,"Qovery uses ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://github.com/kubernetes-sigs/external-dns"}),"External DNS")," to automatically configure DNS records for your applications."),Object(l.b)("p",null,"If you don't want or can't add your own DNS provider, Qovery proposes it's own managed sub-domain DNS provider for free.\nYou'll then be able to later add your custom DNS record (no matter the provider) to point to your Qovery DNS sub-domain."),Object(l.b)("h4",{id:"external-dns"},"External DNS"),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"ExternalDns",label:"Demo & QoveryDNS",value:"demo"},{group:"ExternalDns",label:"Cloudflare",value:"cloudflare"}],mdxType:"Tabs"},Object(l.b)(c.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"Here is one example with Qovery DNS provider:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"external-dns:\n fullnameOverride: external-dns\n # set pdns for Qovery DNS managed (or you can use any supported provider by external-dns)\n provider: pdns\n # will use the domain name given by Qovery during the cluster setup phease\n domainFilters: [*domain]\n # an owner ID is set to avoid conflicts in case of multiple Qovery clusters\n txtOwnerId: *shortClusterId\n # a prefix to help Qovery to debug in case of issues\n txtPrefix: *externalDnsPrefix\n # set the Qovery DNS provider configuration\n pdns:\n apiUrl: *qoveryDnsUrl\n apiKey: *jwtToken\n apiPort: 443\n"))),Object(l.b)(c.a,{value:"cloudflare",mdxType:"TabItem"},Object(l.b)("p",null,"Here is one example with Cloudflare:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),'external-dns:\n fullnameOverride: external-dns\n provider: cloudflare\n domainFilters: [""]\n # an owner ID is set to avoid conflicts in case of multiple Qovery clusters\n txtOwnerId: *shortClusterId\n # a prefix to help Qovery to debug in case of issues\n txtPrefix: *externalDnsPrefix\n # set the Cloudflare DNS provider configuration\n cloudflare:\n ## @param cloudflare.apiToken When using the Cloudflare provider, `CF_API_TOKEN` to set (optional)\n apiToken: ""\n ## @param cloudflare.apiKey When using the Cloudflare provider, `CF_API_KEY` to set (optional)\n apiKey: ""\n ## @param cloudflare.secretName When using the Cloudflare provider, it\'s the name of the secret containing cloudflare_api_token or cloudflare_api_key.\n ## This ignores cloudflare.apiToken, and cloudflare.apiKey\n secretName: ""\n ## @param cloudflare.email When using the Cloudflare provider, `CF_API_EMAIL` to set (optional). Needed when using CF_API_KEY\n email: ""\n ## @param cloudflare.proxied When using the Cloudflare provider, enable the proxy feature (DDOS protection, CDN...) (optional)\n proxied: true\n')))),Object(l.b)("h3",{id:"logging"},"Logging"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Retrieve and store application's log history")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"You'll have live logs, but you will miss log history for debugging purpose")))),Object(l.b)("p",null,"Qovery uses ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://grafana.com/oss/loki/"}),"Loki")," to store your logs in a S3 compatible bucket and ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://grafana.com/docs/loki/latest/clients/promtail/"}),"Promtail")," to collect your logs."),Object(l.b)("h4",{id:"loki"},"Loki"),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"Loki",label:"Demo",value:"demo"},{group:"Loki",label:"AWS S3",value:"s3"}],mdxType:"Tabs"},Object(l.b)(c.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"Here is a configuration ",Object(l.b)("strong",{parentName:"p"},"in Memory (no persistence)")," for Loki:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"loki:\n fullnameOverride: loki\n loki:\n # no auth is set for internal cluster usage\n auth_enabled: false\n ingester:\n lifecycler:\n ring:\n kvstore:\n # we store it in memory for the demo, you'll lose history once Loki restarts\n store: inmemory\n replication_factor: 1\n schema_config:\n configs:\n - from: 2020-05-15\n store: boltdb-shipper\n object_store: filesystem\n schema: v11\n index:\n prefix: index_\n period: 24h\n monitoring:\n # all the monitoring part is disabled to reduce resource footprint for the demo usage\n dashboards:\n enabled: false\n rules:\n enabled: false\n serviceMonitor:\n enabled: false\n metricsInstance:\n enabled: false\n selfMonitoring:\n enabled: false\n grafanaAgent:\n installOperator: false\n grafanaAgent:\n enabled: false\n lokiCanary:\n enabled: false\n test:\n enabled: false\n gateway:\n enabled: false\n # we use a single binary to reduce resource footprint for the demo usage\n singleBinary:\n replicas: 1\n persistence:\n enabled: false\n extraVolumes:\n - name: data\n emptyDir: {}\n - name: storage\n emptyDir: {}\n extraVolumeMounts:\n - name: data\n mountPath: /data\n - name: storage\n mountPath: /var/loki\n"))),Object(l.b)(c.a,{value:"s3",mdxType:"TabItem"},Object(l.b)("p",null,"Here is a configuration example with AWS S3 as storage backend:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"loki:\n fullnameOverride: loki\n kubectlImage:\n registry: set-by-customer\n repository: set-by-customer\n \n loki:\n image:\n registry: set-by-customer\n repository: set-by-customer\n auth_enabled: false\n commonConfig:\n replication_factor: 1 # single binary version\n ingester:\n chunk_idle_period: 3m \n chunk_block_size: 262144 \n chunk_retain_period: 1m \n max_transfer_retries: 0 \n lifecycler:\n ring:\n kvstore:\n store: memberlist \n replication_factor: 1 \n memberlist:\n abort_if_cluster_join_fails: false \n bind_port: 7946 \n join_members:\n - loki-headless.logging.svc:7946 \n max_join_backoff: 1m \n max_join_retries: 10 \n min_join_backoff: 1s \n limits_config:\n ingestion_rate_mb: 20 \n ingestion_burst_size_mb: 30 \n enforce_metric_name: false \n reject_old_samples: true \n reject_old_samples_max_age: 168h \n max_concurrent_tail_requests: 100 (default 10)\n split_queries_by_interval: 15m (default 15m)\n max_query_lookback: 12w (default 0)\n compactor:\n working_directory: /data/retention\n shared_store: aws\n compaction_interval: 10m\n retention_enabled: set-by-customer \n retention_delete_delay: 2h\n retention_delete_worker_count: 150\n table_manager:\n retention_deletes_enabled: set-by-customer \n retention_period: set-by-customer \n schema_config:\n configs:\n - from: 2020-05-15\n store: boltdb-shipper\n object_store: s3\n schema: v11\n index:\n prefix: index_\n period: 24h\n - from: 2023-06-01\n store: boltdb-shipper\n object_store: s3\n schema: v12\n index:\n prefix: index_\n period: 24h\n storage:\n bucketNames:\n chunks: \n ruler: \n admin: \n type: s3\n s3:\n s3: \n region: \n s3ForcePathStyle: \n insecure: \n storage_config:\n boltdb_shipper:\n active_index_directory: /data/loki/index\n shared_store: s3\n resync_interval: 5s\n cache_location: /data/loki/boltdb-cache\n")))),Object(l.b)("h4",{id:"promtail"},"Promtail"),Object(l.b)("p",null,"A configuration example compatible with all providers:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"promtail:\n fullnameOverride: promtail\n # promtail requires to be spawned in kube-system namespace\n namespace: kube-system\n priorityClassName: system-node-critical\n config:\n clients:\n # forward logs to Loki\n - url: *promtailLokiUrl\n snippets:\n extraRelabelConfigs:\n - action: labelmap\n # required to be able to watch logs from Qovery console interface\n regex: __meta_kubernetes_pod_label_(qovery_com_service_id|qovery_com_service_type|qovery_com_environment_id)\n")),Object(l.b)("h3",{id:"certificates"},"Certificates"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Cert-manager helps you to get TLS certificates through Let's Encrypt")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Without it, you will not be able to automatically get TLS certificates")))),Object(l.b)("p",null,"Qovery uses ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://cert-manager.io/"}),"Cert Manager")," to automatically get TLS certificates for your applications."),Object(l.b)("h4",{id:"cert-manager"},"Cert Manager"),Object(l.b)("p",null,"Here is the minimal setup for all cloud providers:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"cert-manager:\n fullnameOverride: cert-manager\n # CRD are required\n installCRDs: true\n replicaCount: 1\n startupapicheck:\n jobAnnotations:\n helm.sh/hook: post-install,post-upgrade\n rbac:\n annotations:\n helm.sh/hook: post-install,post-upgrade\n serviceAccount:\n annotations:\n helm.sh/hook: post-install,post-upgrade\n")),Object(l.b)("h4",{id:"qovery-cert-manager-webhook"},"Qovery Cert Manager Webhook"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No (but if you're using Qovery DNS Provider)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Required to get Let's Encrypt TLS if Qovery DNS Provider is used")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Without it, you will not be able to automatically get TLS certificates with Qovery DNS Provider")))),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"qovery",placeholder:"Select a platform",select:!1,size:null,values:[{group:"QoveryCertManagerWebhook",label:"Qovery DNS",value:"qovery"},{group:"QoveryCertManagerWebhook",label:"",value:""}],mdxType:"Tabs"},Object(l.b)(c.a,{value:"qovery",mdxType:"TabItem"},Object(l.b)("p",null,"A configuration example compatible with all providers:"),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"qovery-cert-manager-webhook:\n fullnameOverride: qovery-cert-manager-webhook\n certManager:\n namespace: qovery\n serviceAccountName: cert-manager\n secret:\n apiUrl: *qoveryDnsUrl\n apiKey: *jwtToken\n")))),Object(l.b)("h4",{id:"cert-manager-configs"},"Cert Manager Configs"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"This is an helper to deploy cert-manager config. But you can manually set it")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Installing Cert-manager is not enough, you have to configure it to get TLS working")))),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"ExternalDns",label:"Demo",value:"demo"},{group:"ExternalDns",label:"Qovery DNS",value:"qovery"},{group:"ExternalDns",label:"Cloudflare",value:"cloudflare"}],mdxType:"Tabs"},Object(l.b)(c.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("p",null,"This is the configuration of Cert Manager itself. It is used by all Cert Manager components."),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"cert-manager-configs:\n fullnameOverride: cert-manager-configs\n # set pdns to use Qovery DNS provider\n externalDnsProvider: pdns\n managedDns: [*domain]\n acme:\n letsEncrypt:\n emailReport: *acmeEmailAddr\n # As it's a demo cluster, we use the staging environment to avoid rate limit issues\n acmeUrl: https://acme-staging-v02.api.letsencrypt.org/directory\n provider:\n # set the provider of your choice or use the Qovery DNS provider\n pdns:\n apiPort: 443\n apiUrl: *qoveryDnsUrl\n apiKey: *jwtToken\n"))),Object(l.b)(c.a,{value:"qovery",mdxType:"TabItem"},Object(l.b)("p",null,"This is the configuration of Cert Manager itself. It is used by all Cert Manager components."),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"cert-manager-configs:\n fullnameOverride: cert-manager-configs\n # set pdns to use Qovery DNS provider\n externalDnsProvider: pdns\n managedDns: [*domain]\n acme:\n letsEncrypt:\n emailReport: *acmeEmailAddr\n acmeUrl: https://acme-v02.api.letsencrypt.org/directory\n provider:\n # set the provider of your choice or use the Qovery DNS provider\n pdns:\n apiPort: 443\n apiUrl: *qoveryDnsUrl\n apiKey: *jwtToken\n"))),Object(l.b)(c.a,{value:"cloudflare",mdxType:"TabItem"},Object(l.b)("p",null,"This is the configuration of Cert Manager itself. It is used by all Cert Manager components."),Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),'cert-manager-configs:\n fullnameOverride: cert-manager-configs\n # set pdns to use Qovery DNS provider\n externalDnsProvider: pdns\n managedDns: [*domain]\n acme:\n letsEncrypt:\n emailReport: *acmeEmailAddr\n acmeUrl: https://acme-v02.api.letsencrypt.org/directory\n provider:\n cloudflare:\n apiToken: "set your Cloudflare API token here"\n email: "set your Cloudflare email here"\n')))),Object(l.b)("p",null,"Qovery uses ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://github.com/kubernetes-sigs/metrics-server"}),"Metrics Server")," to collect metrics from your Kubernetes cluster and scale your applications automatically based on custom metrics."),Object(l.b)("h2",{id:"observability"},"Observability"),Object(l.b)("h3",{id:"metrics-server"},"Metrics Server"),Object(l.b)("table",null,Object(l.b)("thead",{parentName:"table"},Object(l.b)("tr",{parentName:"thead"},Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})),Object(l.b)("th",Object(n.a)({parentName:"tr"},{align:null})))),Object(l.b)("tbody",{parentName:"table"},Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"Required")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No (but strongly recommended)")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If deployed")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"Mandatory if you want to retrive pod metrics for the Qovery agent and if you want to be able to use the horizontal pod scaling")),Object(l.b)("tr",{parentName:"tbody"},Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),Object(l.b)("strong",{parentName:"td"},"If missing")),Object(l.b)("td",Object(n.a)({parentName:"tr"},{align:null}),"No HPA and no application metrics in the QOveyr console")))),Object(l.b)(o.a,{centered:!0,className:"rounded",defaultValue:"demo",placeholder:"Select a platform",select:!1,size:null,values:[{group:"MetricsServer",label:"Demo",value:"demo"},{group:"MetricsServer",label:"AWS",value:"aws"},{group:"MetricsServer",label:"GCP",value:"gcp"},{group:"MetricsServer",label:"Scaleway",value:"scaleway"}],mdxType:"Tabs"},Object(l.b)(c.a,{value:"aws",mdxType:"TabItem"},Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"metrics-server:\n fullnameOverride: metrics-server\n apiService:\n create: true\n\n updateStrategy:\n type: set-by-customer\n\n resources:\n limits:\n cpu: set-by-customer\n memory: set-by-customer\n requests:\n cpu: set-by-customer\n memory: set-by-customer\n"))),Object(l.b)(c.a,{value:"gcp",mdxType:"TabItem"},Object(l.b)("p",null,"Nothing needs to be deployed, as GCP already provides a managed metrics server.")),Object(l.b)(c.a,{value:"scaleway",mdxType:"TabItem"},Object(l.b)("p",null,"Nothing needs to be deployed, as Scaleway already provides a managed metrics server.")),Object(l.b)(c.a,{value:"demo",mdxType:"TabItem"},Object(l.b)("pre",null,Object(l.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"metrics-server:\n fullnameOverride: metrics-server\n defaultArgs:\n - --cert-dir=/tmp\n - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\n - --kubelet-use-node-status-port\n - --metric-resolution=15s\n - --kubelet-insecure-tls\n apiService:\n create: false\n")))),Object(l.b)("h2",{id:"faq"},"FAQ"),Object(l.b)("h3",{id:"i-have-a-non-covered-use-case-what-should-i-do"},"I have a non-covered use case. What should I do?"),Object(l.b)("p",null,"Please ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://www.qovery.com/contact"}),"contact us"),". We will be happy to help you."),Object(l.b)("h3",{id:"can-i-host-the-qovery-control-plane-on-my-own"},"Can I host the Qovery control plane on my own?"),Object(l.b)("p",null,"At the momement, you can't. But please ",Object(l.b)("a",Object(n.a)({parentName:"p"},{href:"https://www.qovery.com/contact"}),"contact us")," to discuss about it. We will be happy to help you."))}m.isMDXComponent=!0},423:function(e,t,a){"use strict";a(425);var n=a(0),r=a.n(n),l=a(422),o=a.n(l);a(132);t.a=function(e){var t=e.children,a=e.classNames,n=e.fill,l=e.icon,c=e.type,b=null;switch(c){case"danger":b="alert-triangle";break;case"success":b="check-circle";break;case"warning":b="alert-triangle";break;default:b="info"}return r.a.createElement("div",{className:o()(a,"alert","alert--"+c,{"alert--fill":n,"alert--icon":!1!==l}),role:"alert"},!1!==l&&r.a.createElement("i",{className:o()("feather","icon-"+(l||b))}),t)}},427:function(e,t,a){var n=a(28).f,r=Function.prototype,l=/^\s*function ([^ (]*)/;"name"in r||a(10)&&n(r,"name",{configurable:!0,get:function(){try{return(""+this).match(l)[1]}catch(e){return""}}})},428:function(e,t,a){"use strict";a(427);var n=a(0),r=a.n(n),l=a(423);t.a=function(e){var t=e.children,a=e.name;return r.a.createElement(l.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},r.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",a||"page"," assumes the following:"),t)}},433:function(e,t,a){"use strict";var n=a(0),r=a.n(n),l=(a(422),a(432)),o=a.n(l);a(134);t.a=function(e){var t=e.children,a=e.headingDepth,l=e.hideFeedbackQuestion,c="undefined"!=typeof window?window.location:null,b={title:"Tutorial on "+c+" failed",body:"The tutorial on:\n\n"+c+"\n\nHere's what went wrong:\n\n\x3c!-- Insert command output and details. Thank you for reporting! :) --\x3e"},s="https://github.com/qovery/documentation/issues/new?"+o.a.stringify(b),i=Object(n.useState)(null),u=i[0],d=i[1];return r.a.createElement("div",{className:"steps steps--h"+a},t,!l&&!u&&r.a.createElement("div",{className:"steps--feedback"},"How was it? Did this tutorial work?\xa0\xa0",r.a.createElement("span",{className:"button button--sm button--primary",onClick:function(){return d("yes")}},"Yes"),"\xa0\xa0",r.a.createElement("a",{href:s,target:"_blank",className:"button button--sm button--primary"},"No")),"yes"==u&&r.a.createElement("div",{className:"steps--feedback steps--feedback--success"},"Thanks! If you're enjoying Qovery please consider ",r.a.createElement("a",{href:"https://github.com/qovery/documentation/",target:"_blank"},"starring our Github repo"),"."))}},436:function(e,t,a){"use strict";var n=a(1),r=(a(441),a(438),a(52),a(29),a(22),a(21),a(0)),l=a.n(r),o=a(446),c=a(422),b=a.n(c),s=a(432),i=a.n(s),u=a(445),d=37,p=39;function m(e){var t=e.block,a=e.centered,n=e.changeSelectedValue,r=e.className,o=e.handleKeydown,c=e.style,s=e.values,i=e.selectedValue,u=e.tabRefs;return l.a.createElement("div",{className:a?"tabs--centered":null},l.a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:b()("tabs",r,{"tabs--block":t}),style:c},s.map((function(e){var t=e.value,a=e.label;return l.a.createElement("li",{role:"tab",tabIndex:"0","aria-selected":i===t,className:b()("tab-item",{"tab-item--active":i===t}),key:t,ref:function(e){return u.push(e)},onKeyDown:function(e){return o(u,e.target,e)},onFocus:function(){return n(t)},onClick:function(){return n(t)}},a)}))))}function g(e){var t=e.placeholder,a=e.selectedValue,n=e.changeSelectedValue,r=e.size,c=e.values,b=c;if(b[0].group){var s=_.groupBy(b,"group");b=Object.keys(s).map((function(e){return{label:e,options:s[e]}}))}return l.a.createElement(o.a,{className:"react-select-container react-select--"+r,classNamePrefix:"react-select",options:b,isClearable:a,placeholder:t,value:c.find((function(e){return e.value==a})),onChange:function(e){return n(e?e.value:null)}})}t.a=function(e){e.block,e.centered;var t=e.children,a=e.defaultValue,o=e.groupId,c=e.label,b=e.placeholder,s=e.select,O=e.size,j=(e.style,e.values),y=e.urlKey,h=Object(u.a)(),v=h.tabGroupChoices,f=h.setTabGroupChoices,N=Object(r.useState)(a),w=N[0],k=N[1];if(null!=o){var x=v[o];null!=x&&x!==w&&k(x)}var C=function(e){k(e),null!=o&&f(o,e)},T=[],I=function(e,t,a){switch(a.keyCode){case p:!function(e,t){var a=e.indexOf(t)+1;e[a]?e[a].focus():e[0].focus()}(e,t);break;case d:!function(e,t){var a=e.indexOf(t)-1;e[a]?e[a].focus():e[e.length-1].focus()}(e,t)}};return Object(r.useEffect)((function(){if("undefined"!=typeof window&&window.location&&y){var e=i.a.parse(window.location.search);e[y]&&k(e[y])}}),[]),l.a.createElement(l.a.Fragment,null,l.a.createElement("div",{className:"margin-bottom--"+(O||"md")},c&&l.a.createElement("div",{className:"margin-vert--sm"},c),j.length>1&&(s?l.a.createElement(g,Object(n.a)({changeSelectedValue:C,handleKeydown:I,placeholder:b,selectedValue:w,size:O,tabRefs:T},e)):l.a.createElement(m,Object(n.a)({changeSelectedValue:C,handleKeydown:I,selectedValue:w,tabRefs:T},e)))),r.Children.toArray(t).filter((function(e){return e.props.value===w}))[0])}},442:function(e,t,a){"use strict";var n=a(0),r=a.n(n);t.a=function(e){return r.a.createElement(r.a.Fragment,null,e.children)}}}]);
\ No newline at end of file
diff --git a/404.html b/404.html
index 7be943f5f4..4d0d0405e6 100644
--- a/404.html
+++ b/404.html
@@ -26,7 +26,7 @@
-
+
@@ -39,7 +39,7 @@
-
+
diff --git a/community/index.html b/community/index.html
index 90822bac6c..02c81826df 100644
--- a/community/index.html
+++ b/community/index.html
@@ -26,7 +26,7 @@
-
+
@@ -47,7 +47,7 @@
-
+
diff --git a/components/index.html b/components/index.html
index c221eb7806..c85922aa22 100644
--- a/components/index.html
+++ b/components/index.html
@@ -26,7 +26,7 @@
-
+
@@ -47,7 +47,7 @@
-
+
diff --git a/contact/index.html b/contact/index.html
index 6a087e6026..eea517cf5f 100644
--- a/contact/index.html
+++ b/contact/index.html
@@ -26,7 +26,7 @@
-
+
@@ -47,7 +47,7 @@
-
+
diff --git a/docs/getting-started/basic-concepts/index.html b/docs/getting-started/basic-concepts/index.html
index 7c0a0207f0..827e773cf8 100644
--- a/docs/getting-started/basic-concepts/index.html
+++ b/docs/getting-started/basic-concepts/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/getting-started/deploy-my-app/index.html b/docs/getting-started/deploy-my-app/index.html
index 7b8336a83f..b89d57486e 100644
--- a/docs/getting-started/deploy-my-app/index.html
+++ b/docs/getting-started/deploy-my-app/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/getting-started/how-qovery-works/index.html b/docs/getting-started/how-qovery-works/index.html
index 6222afd69c..b8f2c06666 100644
--- a/docs/getting-started/how-qovery-works/index.html
+++ b/docs/getting-started/how-qovery-works/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/getting-started/index.html b/docs/getting-started/index.html
index 9d016db09e..a18a3dfb39 100644
--- a/docs/getting-started/index.html
+++ b/docs/getting-started/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/getting-started/install-qovery/index.html b/docs/getting-started/install-qovery/index.html
index c1342c28f8..0ea1d4d92a 100644
--- a/docs/getting-started/install-qovery/index.html
+++ b/docs/getting-started/install-qovery/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/getting-started/what-is-qovery/index.html b/docs/getting-started/what-is-qovery/index.html
index a611d70c4c..c048df91d9 100644
--- a/docs/getting-started/what-is-qovery/index.html
+++ b/docs/getting-started/what-is-qovery/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/getting-started/whats-next/index.html b/docs/getting-started/whats-next/index.html
index 50bb31d3e2..4f458feb0a 100644
--- a/docs/getting-started/whats-next/index.html
+++ b/docs/getting-started/whats-next/index.html
@@ -26,7 +26,7 @@
-
+
@@ -56,7 +56,7 @@
-
+
diff --git a/docs/index.html b/docs/index.html
index 7b8efa21e0..51413a9156 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -22,7 +22,7 @@
-
+
@@ -37,7 +37,7 @@
-
+
diff --git a/docs/security-and-compliance/backup-and-restore/index.html b/docs/security-and-compliance/backup-and-restore/index.html
index 21448235a1..5179382f83 100644
--- a/docs/security-and-compliance/backup-and-restore/index.html
+++ b/docs/security-and-compliance/backup-and-restore/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/security-and-compliance/encryption/index.html b/docs/security-and-compliance/encryption/index.html
index 5ad8e62b3b..18cb728f7a 100644
--- a/docs/security-and-compliance/encryption/index.html
+++ b/docs/security-and-compliance/encryption/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/security-and-compliance/gdpr/index.html b/docs/security-and-compliance/gdpr/index.html
index ca94e2a8a8..c34b75426f 100644
--- a/docs/security-and-compliance/gdpr/index.html
+++ b/docs/security-and-compliance/gdpr/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/security-and-compliance/index.html b/docs/security-and-compliance/index.html
index cce30b4755..d6f65c3fb5 100644
--- a/docs/security-and-compliance/index.html
+++ b/docs/security-and-compliance/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/security-and-compliance/soc2/index.html b/docs/security-and-compliance/soc2/index.html
index 67c36ce501..cdbf00c207 100644
--- a/docs/security-and-compliance/soc2/index.html
+++ b/docs/security-and-compliance/soc2/index.html
@@ -26,7 +26,7 @@
-
+
@@ -56,7 +56,7 @@
-
+
diff --git a/docs/useful-resources/faq/index.html b/docs/useful-resources/faq/index.html
index 16820ebc61..714b4a4763 100644
--- a/docs/useful-resources/faq/index.html
+++ b/docs/useful-resources/faq/index.html
@@ -26,7 +26,7 @@
-
+
@@ -57,7 +57,7 @@
-
+
diff --git a/docs/useful-resources/help-and-support/index.html b/docs/useful-resources/help-and-support/index.html
index 450ee8b4f7..a1da310796 100644
--- a/docs/useful-resources/help-and-support/index.html
+++ b/docs/useful-resources/help-and-support/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/audit-logs/index.html b/docs/using-qovery/audit-logs/index.html
index 4f34f458d5..849c2809af 100644
--- a/docs/using-qovery/audit-logs/index.html
+++ b/docs/using-qovery/audit-logs/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/advanced-settings/index.html b/docs/using-qovery/configuration/advanced-settings/index.html
index 660137759e..623a322090 100644
--- a/docs/using-qovery/configuration/advanced-settings/index.html
+++ b/docs/using-qovery/configuration/advanced-settings/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/application-health-checks/index.html b/docs/using-qovery/configuration/application-health-checks/index.html
index badf76abec..f0f261fe3b 100644
--- a/docs/using-qovery/configuration/application-health-checks/index.html
+++ b/docs/using-qovery/configuration/application-health-checks/index.html
@@ -26,7 +26,7 @@
-
+
@@ -59,7 +59,7 @@
-
+
diff --git a/docs/using-qovery/configuration/application/index.html b/docs/using-qovery/configuration/application/index.html
index 0b9a219043..48c67afb81 100644
--- a/docs/using-qovery/configuration/application/index.html
+++ b/docs/using-qovery/configuration/application/index.html
@@ -26,7 +26,7 @@
-
+
@@ -62,7 +62,7 @@
-
+
diff --git a/docs/using-qovery/configuration/cloud-service-provider/amazon-web-services/index.html b/docs/using-qovery/configuration/cloud-service-provider/amazon-web-services/index.html
index e63f68f083..5b83a962ef 100644
--- a/docs/using-qovery/configuration/cloud-service-provider/amazon-web-services/index.html
+++ b/docs/using-qovery/configuration/cloud-service-provider/amazon-web-services/index.html
@@ -26,7 +26,7 @@
-
+
@@ -57,7 +57,7 @@
-
+
diff --git a/docs/using-qovery/configuration/cloud-service-provider/digital-ocean/index.html b/docs/using-qovery/configuration/cloud-service-provider/digital-ocean/index.html
index 01edaa756a..79b09d7b39 100644
--- a/docs/using-qovery/configuration/cloud-service-provider/digital-ocean/index.html
+++ b/docs/using-qovery/configuration/cloud-service-provider/digital-ocean/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/cloud-service-provider/google-cloud-platform/index.html b/docs/using-qovery/configuration/cloud-service-provider/google-cloud-platform/index.html
index eb29555e20..cd6e606b2e 100644
--- a/docs/using-qovery/configuration/cloud-service-provider/google-cloud-platform/index.html
+++ b/docs/using-qovery/configuration/cloud-service-provider/google-cloud-platform/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/cloud-service-provider/index.html b/docs/using-qovery/configuration/cloud-service-provider/index.html
index 0213d5f0fd..8739546512 100644
--- a/docs/using-qovery/configuration/cloud-service-provider/index.html
+++ b/docs/using-qovery/configuration/cloud-service-provider/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/cloud-service-provider/microsoft-azure/index.html b/docs/using-qovery/configuration/cloud-service-provider/microsoft-azure/index.html
index b1c9a2dac5..1bb57ec5ea 100644
--- a/docs/using-qovery/configuration/cloud-service-provider/microsoft-azure/index.html
+++ b/docs/using-qovery/configuration/cloud-service-provider/microsoft-azure/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/cloud-service-provider/other-csps/index.html b/docs/using-qovery/configuration/cloud-service-provider/other-csps/index.html
index fc08079566..8f44c5441a 100644
--- a/docs/using-qovery/configuration/cloud-service-provider/other-csps/index.html
+++ b/docs/using-qovery/configuration/cloud-service-provider/other-csps/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/cloud-service-provider/scaleway/index.html b/docs/using-qovery/configuration/cloud-service-provider/scaleway/index.html
index 6e05662430..e8163667b7 100644
--- a/docs/using-qovery/configuration/cloud-service-provider/scaleway/index.html
+++ b/docs/using-qovery/configuration/cloud-service-provider/scaleway/index.html
@@ -26,7 +26,7 @@
-
+
@@ -59,7 +59,7 @@
-
+
diff --git a/docs/using-qovery/configuration/cluster-advanced-settings/index.html b/docs/using-qovery/configuration/cluster-advanced-settings/index.html
index 2a1f279322..fb60e22c8b 100644
--- a/docs/using-qovery/configuration/cluster-advanced-settings/index.html
+++ b/docs/using-qovery/configuration/cluster-advanced-settings/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/clusters/index.html b/docs/using-qovery/configuration/clusters/index.html
index d8f0db98a7..6ff6bd2e7f 100644
--- a/docs/using-qovery/configuration/clusters/index.html
+++ b/docs/using-qovery/configuration/clusters/index.html
@@ -26,7 +26,7 @@
-
+
@@ -61,7 +61,7 @@
-
+
diff --git a/docs/using-qovery/configuration/cronjob/index.html b/docs/using-qovery/configuration/cronjob/index.html
index 8b40618e3d..c26ec01049 100644
--- a/docs/using-qovery/configuration/cronjob/index.html
+++ b/docs/using-qovery/configuration/cronjob/index.html
@@ -26,7 +26,7 @@
-
+
@@ -59,7 +59,7 @@
-
+
diff --git a/docs/using-qovery/configuration/database/index.html b/docs/using-qovery/configuration/database/index.html
index ed83862255..16443c243c 100644
--- a/docs/using-qovery/configuration/database/index.html
+++ b/docs/using-qovery/configuration/database/index.html
@@ -26,7 +26,7 @@
-
+
@@ -56,7 +56,7 @@
-
+
diff --git a/docs/using-qovery/configuration/database/mongodb/index.html b/docs/using-qovery/configuration/database/mongodb/index.html
index 21b4a48994..6b77ed2994 100644
--- a/docs/using-qovery/configuration/database/mongodb/index.html
+++ b/docs/using-qovery/configuration/database/mongodb/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/database/mysql/index.html b/docs/using-qovery/configuration/database/mysql/index.html
index 504c245b5c..7a9da2ce4d 100644
--- a/docs/using-qovery/configuration/database/mysql/index.html
+++ b/docs/using-qovery/configuration/database/mysql/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/database/postgresql/index.html b/docs/using-qovery/configuration/database/postgresql/index.html
index 2c43e2abc1..91b9344f33 100644
--- a/docs/using-qovery/configuration/database/postgresql/index.html
+++ b/docs/using-qovery/configuration/database/postgresql/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/database/redis/index.html b/docs/using-qovery/configuration/database/redis/index.html
index 85f2b8b4a5..dbd5f9c942 100644
--- a/docs/using-qovery/configuration/database/redis/index.html
+++ b/docs/using-qovery/configuration/database/redis/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/deployment-rule/index.html b/docs/using-qovery/configuration/deployment-rule/index.html
index 7424aeee1b..6e941131dd 100644
--- a/docs/using-qovery/configuration/deployment-rule/index.html
+++ b/docs/using-qovery/configuration/deployment-rule/index.html
@@ -26,7 +26,7 @@
-
+
@@ -63,7 +63,7 @@
-
+
diff --git a/docs/using-qovery/configuration/environment-variable/index.html b/docs/using-qovery/configuration/environment-variable/index.html
index db4b9e6e22..7ebe85f7d7 100644
--- a/docs/using-qovery/configuration/environment-variable/index.html
+++ b/docs/using-qovery/configuration/environment-variable/index.html
@@ -26,7 +26,7 @@
-
+
@@ -67,7 +67,7 @@
-
+
diff --git a/docs/using-qovery/configuration/environment/index.html b/docs/using-qovery/configuration/environment/index.html
index 0ef7a273db..27a614765b 100644
--- a/docs/using-qovery/configuration/environment/index.html
+++ b/docs/using-qovery/configuration/environment/index.html
@@ -26,7 +26,7 @@
-
+
@@ -57,7 +57,7 @@
-
+
diff --git a/docs/using-qovery/configuration/helm/index.html b/docs/using-qovery/configuration/helm/index.html
index e6852bb7e0..c9afcdf2cf 100644
--- a/docs/using-qovery/configuration/helm/index.html
+++ b/docs/using-qovery/configuration/helm/index.html
@@ -26,7 +26,7 @@
-
+
@@ -61,7 +61,7 @@
-
+
diff --git a/docs/using-qovery/configuration/index.html b/docs/using-qovery/configuration/index.html
index e9cab0c5e1..ee9d052deb 100644
--- a/docs/using-qovery/configuration/index.html
+++ b/docs/using-qovery/configuration/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/lifecycle-job/index.html b/docs/using-qovery/configuration/lifecycle-job/index.html
index 2287e72196..e44ad982fc 100644
--- a/docs/using-qovery/configuration/lifecycle-job/index.html
+++ b/docs/using-qovery/configuration/lifecycle-job/index.html
@@ -26,7 +26,7 @@
-
+
@@ -61,7 +61,7 @@
-
+
diff --git a/docs/using-qovery/configuration/object-storage/index.html b/docs/using-qovery/configuration/object-storage/index.html
index ab28343b98..fbbe854b86 100644
--- a/docs/using-qovery/configuration/object-storage/index.html
+++ b/docs/using-qovery/configuration/object-storage/index.html
@@ -26,7 +26,7 @@
-
+
@@ -66,7 +66,7 @@
-
+
diff --git a/docs/using-qovery/configuration/organization/api-token/index.html b/docs/using-qovery/configuration/organization/api-token/index.html
index 71625d1ca7..5456d53da0 100644
--- a/docs/using-qovery/configuration/organization/api-token/index.html
+++ b/docs/using-qovery/configuration/organization/api-token/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/organization/container-registry/index.html b/docs/using-qovery/configuration/organization/container-registry/index.html
index 8453fcd9e8..1fbe716fc8 100644
--- a/docs/using-qovery/configuration/organization/container-registry/index.html
+++ b/docs/using-qovery/configuration/organization/container-registry/index.html
@@ -26,7 +26,7 @@
-
+
@@ -56,7 +56,7 @@
-
+
diff --git a/docs/using-qovery/configuration/organization/git-repository-access/index.html b/docs/using-qovery/configuration/organization/git-repository-access/index.html
index 34ea38a943..d12c432053 100644
--- a/docs/using-qovery/configuration/organization/git-repository-access/index.html
+++ b/docs/using-qovery/configuration/organization/git-repository-access/index.html
@@ -26,7 +26,7 @@
-
+
@@ -60,7 +60,7 @@
-
+
diff --git a/docs/using-qovery/configuration/organization/helm-repository/index.html b/docs/using-qovery/configuration/organization/helm-repository/index.html
index 53c2273412..d417bc21a1 100644
--- a/docs/using-qovery/configuration/organization/helm-repository/index.html
+++ b/docs/using-qovery/configuration/organization/helm-repository/index.html
@@ -26,7 +26,7 @@
-
+
@@ -56,7 +56,7 @@
-
+
diff --git a/docs/using-qovery/configuration/organization/index.html b/docs/using-qovery/configuration/organization/index.html
index 8ed201beb5..135749d070 100644
--- a/docs/using-qovery/configuration/organization/index.html
+++ b/docs/using-qovery/configuration/organization/index.html
@@ -26,7 +26,7 @@
-
+
@@ -57,7 +57,7 @@
-
+
diff --git a/docs/using-qovery/configuration/organization/members-rbac/index.html b/docs/using-qovery/configuration/organization/members-rbac/index.html
index d7d3b4e5da..ab4cdbbb9a 100644
--- a/docs/using-qovery/configuration/organization/members-rbac/index.html
+++ b/docs/using-qovery/configuration/organization/members-rbac/index.html
@@ -26,7 +26,7 @@
-
+
@@ -58,7 +58,7 @@
-
+
diff --git a/docs/using-qovery/configuration/project/index.html b/docs/using-qovery/configuration/project/index.html
index 39b4e2d95b..0d0d8ac01b 100644
--- a/docs/using-qovery/configuration/project/index.html
+++ b/docs/using-qovery/configuration/project/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/provider/index.html b/docs/using-qovery/configuration/provider/index.html
index 19fc98f53f..c1a25a14a2 100644
--- a/docs/using-qovery/configuration/provider/index.html
+++ b/docs/using-qovery/configuration/provider/index.html
@@ -26,7 +26,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/docs/using-qovery/configuration/provider/kubernetes/index.html b/docs/using-qovery/configuration/provider/kubernetes/index.html
index c561b8021f..57b74b2199 100644
--- a/docs/using-qovery/configuration/provider/kubernetes/index.html
+++ b/docs/using-qovery/configuration/provider/kubernetes/index.html
@@ -26,7 +26,7 @@
-
+
@@ -46,7 +46,7 @@
-
+
@@ -58,12 +58,12 @@
## Qovery Common config
# Past information from Qovery cluster console creation
Used to easily reach your applications with DNS records, even on private network
If missing
You will have easy access with dns names to your services, you'll have to use IPs
Qovery uses External DNS to automatically configure DNS records for your applications.
If you don't want or can't add your own DNS provider, Qovery proposes it's own managed sub-domain DNS provider for free.
-You'll then be able to later add your custom DNS record (no matter the provider) to point to your Qovery DNS sub-domain.