diff --git a/cmd/defaults.yaml b/cmd/defaults.yaml index 6539457b2a..06a728ef24 100644 --- a/cmd/defaults.yaml +++ b/cmd/defaults.yaml @@ -8,6 +8,12 @@ Metrics: # Select type otel (OpenTelemetry) or none (disables collection and endpoint) Type: otel +Tracing: + # Choose one in "otel", "google", "log" and "none" + Type: none + Fraction: 1 + MetricPrefix: zitadel + # Port ZITADEL will listen on Port: 8080 # Port ZITADEL is exposed on, it can differ from port e.g. if you proxy the traffic diff --git a/docs/docs/guides/deploy/overview.mdx b/docs/docs/guides/deploy/overview.mdx index 40c7a9ed94..50356a463f 100644 --- a/docs/docs/guides/deploy/overview.mdx +++ b/docs/docs/guides/deploy/overview.mdx @@ -3,8 +3,6 @@ title: Overview --- Choose your platform and run ZITADEL with the most minimal configuration possible. -For an easy self-hosted production setup, we recommend running ZITADEL on [Kubernetes](https://kubernetes.io/docs/home/), using our official [Helm](https://helm.sh/docs/) chart. -By default, it runs a highly available ZITADEL instance along with a secure and highly available [CockroachDB](https://www.cockroachlabs.com/docs/stable/) instance. - [Linux](./linux) - [MacOS](./macos) @@ -12,12 +10,10 @@ By default, it runs a highly available ZITADEL instance along with a secure and - [Knative](./knative) - [Kubernetes](./kubernetes) -## Prerequisits +## Prerequisites -- ZITADEL does not need many resources, 1 CPU and 512MB memory are more than enough. (With more CPU, the password hashing might be faster) +- For test environments, ZITADEL does not need many resources, 1 CPU and 512MB memory are more than enough. (With more CPU, the password hashing might be faster) - A cockroachDB or Postgresql (currently in beta) as only needed storage -- If you want to front ZITADEL with a reverse proxy, web application firewall or content delivery network, make sure to support [HTTP/2](../manage/self-hosted/http2) - ## Releases @@ -25,4 +21,13 @@ The easiest way to use ZITADEL is to run one of our container releases - ZITADEL does provide latest and stable [container images](https://github.com/zitadel/zitadel/pkgs/container/zitadel) - **stable** is the current **production** release of ZITADEL. -- **latest** is the **last created** release from our pipelines that gets updated on a high frequency. \ No newline at end of file +- **latest** is the **last created** release from our pipelines that gets updated in a high frequency. + +# Production Setup + +As soon as you successfully created your first test environment using one of the deployment guides in this section, +you might want to configure ZITADEL for production and embed it into your system landscape. +To do so, jump straight to the [production setup guide](../manage/self-hosted/production). + +To achieving high availability, we recommend to use a [Kubernetes](https://kubernetes.io/docs/home/) Cluster. +We have an official [Helm chart](https://artifacthub.io/packages/helm/zitadel/zitadel) for easy deployment and maintenance. diff --git a/docs/docs/guides/manage/self-hosted/configure/docker-compose.yaml b/docs/docs/guides/manage/self-hosted/configure/docker-compose.yaml index 6f931e7dff..4b99cdc137 100644 --- a/docs/docs/guides/manage/self-hosted/configure/docker-compose.yaml +++ b/docs/docs/guides/manage/self-hosted/configure/docker-compose.yaml @@ -1,53 +1,55 @@ -version: '3.8' +version: "3.8" services: - zitadel: - restart: 'always' + restart: "always" networks: - - 'zitadel' - image: 'ghcr.io/zitadel/zitadel:stable' + - "zitadel" + image: "ghcr.io/zitadel/zitadel:stable" command: 'start-from-init --config /example-zitadel-config.yaml --config /example-zitadel-secrets.yaml --steps /example-zitadel-init-steps.yaml --masterkey "${ZITADEL_MASTERKEY}" --tlsMode disabled' depends_on: - chown: - condition: 'service_completed_successfully' + certs: + condition: "service_completed_successfully" ports: - - '8080:8080' + - "8080:8080" volumes: - - './example-zitadel-config.yaml:/example-zitadel-config.yaml:ro' - - './example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro' - - './example-zitadel-init-steps.yaml:/example-zitadel-init-steps.yaml:ro' - - 'zitadel-certs:/crdb-certs:ro' + - "./example-zitadel-config.yaml:/example-zitadel-config.yaml:ro" + - "./example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro" + - "./example-zitadel-init-steps.yaml:/example-zitadel-init-steps.yaml:ro" + - "zitadel-certs:/crdb-certs:ro" - chown: - image: 'cockroachdb/cockroach:v22.1.0' - entrypoint: [ '/bin/bash', '-c' ] - command: [ 'cp /certs/ca.crt /zitadel-certs/ && cp /certs/client.root.crt /zitadel-certs/ && cp /certs/client.root.key /zitadel-certs/ && chown 1000:1000 /zitadel-certs/* && chmod 0400 /zitadel-certs/*' ] + certs: + image: "cockroachdb/cockroach:v22.1.0" + entrypoint: ["/bin/bash", "-c"] + command: + [ + "cp /certs/* /zitadel-certs/ && cockroach cert create-client --overwrite --certs-dir /zitadel-certs/ --ca-key /zitadel-certs/ca.key zitadel_user && chown 1000:1000 /zitadel-certs/*", + ] volumes: - - 'certs:/certs:ro' - - 'zitadel-certs:/zitadel-certs:rw' + - "certs:/certs:ro" + - "zitadel-certs:/zitadel-certs:rw" depends_on: my-cockroach-db: - condition: 'service_healthy' + condition: "service_healthy" my-cockroach-db: - restart: 'always' + restart: "always" networks: - - 'zitadel' - image: 'cockroachdb/cockroach:v22.1.0' - command: 'start-single-node --advertise-addr my-cockroach-db' + - "zitadel" + image: "cockroachdb/cockroach:v22.1.0" + command: "start-single-node --advertise-addr my-cockroach-db" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"] - interval: '10s' - timeout: '30s' + interval: "10s" + timeout: "30s" retries: 5 - start_period: '20s' + start_period: "20s" ports: - - '9090:8080' - - '26257:26257' + - "9090:8080" + - "26257:26257" volumes: - - 'certs:/cockroach/certs:rw' - - 'data:/cockroach/cockroach-data:rw' + - "certs:/cockroach/certs:rw" + - "data:/cockroach/cockroach-data:rw" networks: zitadel: diff --git a/docs/docs/guides/manage/self-hosted/configure/example-zitadel-secrets.yaml b/docs/docs/guides/manage/self-hosted/configure/example-zitadel-secrets.yaml index de60e62cfb..6485eef207 100644 --- a/docs/docs/guides/manage/self-hosted/configure/example-zitadel-secrets.yaml +++ b/docs/docs/guides/manage/self-hosted/configure/example-zitadel-secrets.yaml @@ -6,7 +6,5 @@ Database: User: # If the user doesn't exist already, it is created Username: 'zitadel_user' - Password: 'Secret_DB_User_Password' Admin: Username: 'root' - Password: '' diff --git a/docs/docs/guides/manage/self-hosted/database/_cockroachdb.mdx b/docs/docs/guides/manage/self-hosted/database/_cockroachdb.mdx index 0a1925e89b..ad58f376c7 100644 --- a/docs/docs/guides/manage/self-hosted/database/_cockroachdb.mdx +++ b/docs/docs/guides/manage/self-hosted/database/_cockroachdb.mdx @@ -1,8 +1,9 @@ ## Cockroach -The default database of ZITADEL is [CockroachDB](https://www.cockroachlabs.com). The SQL database provides a bunch of features like horizontal scalability, data reginality and many more. +The default database of ZITADEL is [CockroachDB](https://www.cockroachlabs.com). The SQL database provides a bunch of features like horizontal scalability, data regionality and many more. The default configuration of the database looks like this: + ```yaml Database: cockroach: @@ -29,4 +30,4 @@ Database: RootCert: "" Cert: "" Key: "" -``` \ No newline at end of file +``` diff --git a/docs/docs/guides/manage/self-hosted/http2.mdx b/docs/docs/guides/manage/self-hosted/http2.mdx index d3c6b5d4f0..8ab671c273 100644 --- a/docs/docs/guides/manage/self-hosted/http2.mdx +++ b/docs/docs/guides/manage/self-hosted/http2.mdx @@ -2,14 +2,14 @@ title: HTTP/2 Support --- -ZITADEL follows a strict API first approach and makes heavy use of the modern API framework called [gRPC](https://grpc.io/). +ZITADEL follows a strict API first approach and makes heavy use of the modern API framework called [gRPC](https://grpc.io/). Besides gRPC all APIs are also available in an openapi Rest fashion as well as in gRPC-web for compatibilty towards browser integrations. To make us of gRPC it is vital to allow your clients to communicate with ZITADEL with [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2). -Sometimes you need to configure explicitly that you want to use HTTP/2 if you run ZITADEL behind a proxy and below you should find examples for different vendors and projects. +Sometimes you need to configure explicitly that you want to use HTTP/2 if you run ZITADEL behind a reverse proxy and below you should find examples for different vendors and projects. -Furthermore it is important to notice that by default HTTP/2 is always encrypted, but if you want to run ZITADEL without TLS from your proxy or service mesh this is possible through [h2c](https://httpd.apache.org/docs/2.4/howto/http2.html). +Furthermore it is important to notice that by default HTTP/2 is always encrypted, but if you want to run ZITADEL without TLS from your reverse proxy or service mesh this is possible through [h2c](https://httpd.apache.org/docs/2.4/howto/http2.html). Oftentimes when you run ZITADEL inside a service mesh, or a servelerss offering (e.g. Google Cloud Run, Knative, ...) you will need h2c. You can read more about ZITADEL's [TLSs modes here](/docs/guides/manage/self-hosted/tls_modes). diff --git a/docs/docs/guides/manage/self-hosted/production.md b/docs/docs/guides/manage/self-hosted/production.md new file mode 100644 index 0000000000..ae8d457e7e --- /dev/null +++ b/docs/docs/guides/manage/self-hosted/production.md @@ -0,0 +1,101 @@ +--- +title: Production Checklist +--- + +As soon as you successfully deployed ZITADEL as a proof of concept using one of our [deployment guides](/docs/guides/deploy/overview), +you are ready to configure ZITADEL for production usage. + +## High Availability + +We recommend running ZITADEL highly available using an orchestrator that schedules ZITADEL on multiple servers, like [Kubernetes](/docs/guides/deploy/kubernetes). + +## Configuration + +Read [on the configure page](/docs/guides/manage/self-hosted/configure) about the available options you have to configure the ZITADEL. + +## Networking + +- To make ZITADEL available at the domain of your choice, [you need to configure the ExternalDomain property](/docs/guides/manage/self-hosted/custom-domain). +- To enable and restrict access to **HTTPS**, head over to [the description of your TLS options](/docs/guides/manage/self-hosted/tls_modes). +- If you want to front ZITADEL with a reverse proxy, web application firewall or content delivery network, make sure to support **[HTTP/2](/docs/guides/manage/self-hosted/http2)**. +- You can also refer to some **[example reverse proxy configurations](/docs/guides/manage/self-hosted/reverseproxy/reverse_proxy)**. + +## Monitoring + +By default, [**metrics**](docs/apis/observability/metrics) are exposed at /debug/metrics in OpenTelemetry (otel) format. + +Also, you can enable **tracing** in the ZITADEL configuration. + +```yaml +Tracing: + # Choose one in "otel", "google", "log" and "none" + Type: google + Fraction: 1 + MetricPrefix: zitadel +``` + +## Database + +Depending on your environment, you maybe would want to tweak some settings about how ZITADEL interacts with the database in the database section of your ZITADEL configuration. Read more about your [database configuration options](/docs/guides/manage/self-hosted/database). + +```yaml +Database: + cockroach: + Host: localhost + Port: 26257 + Database: zitadel + //highlight-start + MaxOpenConns: 20 + MaxConnLifetime: 30m + MaxConnIdleTime: 30m + //highlight-end + Options: "" +``` + +You also might want to configure how [projections](/docs/concepts/eventstore/implementation#projections) are computed. These are the default values: + +```yaml +Projections: + RequeueEvery: 60s + RetryFailedAfter: 1s + MaxFailureCount: 5 + ConcurrentInstances: 1 + BulkLimit: 200 + MaxIterators: 1 + Customizations: + projects: + BulkLimit: 2000 +``` + +## Data Initialization + +- You can configure instance defaults in the DefaultInstance section. + If you plan to eventually create [multiple virtual instances](/docs/concepts/structure/instance#multiple-virtual-instances), these defaults take effect, too. + Also, these configurations apply to the first instance, that ZITADEL automatically creates for you. + Especially the following properties are of special interest for your production setup. + +```yaml +DefaultInstance: + OIDCSettings: + AccessTokenLifetime: 12h + IdTokenLifetime: 12h + RefreshTokenIdleExpiration: 720h #30d + RefreshTokenExpiration: 2160h #90d + # this configuration sets the default email configuration + SMTPConfiguration: + # configuration of the host + SMTP: + #for example smtp.mailtrap.io:2525 + Host: + User: + Password: + TLS: + # if the host of the sender is different from ExternalDomain set DefaultInstance.DomainPolicy.SMTPSenderAddressMatchesInstanceDomain to false + From: + FromName: +``` + +- If you don't want to use the DefaultInstance configuration for the first instance that ZITADEL automatically creates for you during the [startup phase](/docs/guides/manage/self-hosted/configure#database-initialization), you can provide a FirstInstance YAML section using the --steps argument. +- Learn how to configure ZITADEL via the [Console user interface](/docs/guides/manage/console/overview). +- Probably, you also want [apply your custom branding](/docs/guides/manage/customize/branding), [hook into certain events](/docs/guides/manage/customize/behavior), [customize texts](/docs/guides/manage/customize/texts) or [add metadata to your users](/docs/guides/manage/customize/user-metadata) +- If you want to automatically setup ZITADEL resources, you can use the [ZITADEL Terraform Provider](/docs/guides/manage/terraform/basics) diff --git a/docs/docs/guides/manage/self-hosted/proxy/_more.mdx b/docs/docs/guides/manage/self-hosted/proxy/_more.mdx deleted file mode 100644 index b004111152..0000000000 --- a/docs/docs/guides/manage/self-hosted/proxy/_more.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## More information - -- [You can read here about the TLS Modes](./tls_modes) -- [And here about how ZITADEL makes use of HTTP/2](./http2) \ No newline at end of file diff --git a/docs/docs/guides/manage/self-hosted/proxy/proxy.mdx b/docs/docs/guides/manage/self-hosted/proxy/proxy.mdx deleted file mode 100644 index 3364f8846b..0000000000 --- a/docs/docs/guides/manage/self-hosted/proxy/proxy.mdx +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Proxy Configuration ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; -import Zcloud from './_zitadel_cloud.mdx' -import Nginx from './_nginx.mdx' -import Traefik from './_traefik.mdx' -import Caddy from './_caddy.mdx' -import Cftunnel from './_cloudflare_tunnel.mdx' -import Cloudflare from './_cloudflare.mdx' -import More from './_more.mdx' - -# Proxy Configuration - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/docs/guides/manage/self-hosted/proxy/_caddy.mdx b/docs/docs/guides/manage/self-hosted/reverseproxy/_caddy.mdx similarity index 100% rename from docs/docs/guides/manage/self-hosted/proxy/_caddy.mdx rename to docs/docs/guides/manage/self-hosted/reverseproxy/_caddy.mdx diff --git a/docs/docs/guides/manage/self-hosted/proxy/_cloudflare.mdx b/docs/docs/guides/manage/self-hosted/reverseproxy/_cloudflare.mdx similarity index 88% rename from docs/docs/guides/manage/self-hosted/proxy/_cloudflare.mdx rename to docs/docs/guides/manage/self-hosted/reverseproxy/_cloudflare.mdx index 921b7750bb..d74dec2f88 100644 --- a/docs/docs/guides/manage/self-hosted/proxy/_cloudflare.mdx +++ b/docs/docs/guides/manage/self-hosted/reverseproxy/_cloudflare.mdx @@ -3,7 +3,7 @@ - [Make sure HTTP/2 is enabled](https://support.cloudflare.com/hc/en-us/articles/200168076-Understanding-Cloudflare-HTTP-2-and-HTTP-3-Support) - [Verify that gRPC is enabled](https://support.cloudflare.com/hc/en-us/articles/360050483011-Understanding-Cloudflare-gRPC-support) - [Verify that traffic is proxied through cloudflare](https://developers.cloudflare.com/dns/manage-dns-records/reference/proxied-dns-records/) -- [Configure ZITADEL to use the TLS Mode enabled](./tls_modes#enabled) +- [Configure ZITADEL to use the TLS Mode enabled](/docs/guides/manage/self-hosted/tls_modes#enabled) :::info [Cloudflare does only support gRPC with TLS!](https://support.cloudflare.com/hc/en-us/articles/360050483011-Understanding-Cloudflare-gRPC-support) @@ -14,5 +14,5 @@ If something is not working please check the cloudflare WAF rules for potential violations. These two rules are known to be triggered: -- 100001 Anomaly:Header:User-Agent - Missing Cloudflare Specials -- 100004 Anomaly:Header:User-Agent, Anomaly:Header:Referer - Missing or empty \ No newline at end of file +- 100001 Anomaly:Header:User-Agent - Missing Cloudflare Specials +- 100004 Anomaly:Header:User-Agent, Anomaly:Header:Referer - Missing or empty diff --git a/docs/docs/guides/manage/self-hosted/proxy/_cloudflare_tunnel.mdx b/docs/docs/guides/manage/self-hosted/reverseproxy/_cloudflare_tunnel.mdx similarity index 100% rename from docs/docs/guides/manage/self-hosted/proxy/_cloudflare_tunnel.mdx rename to docs/docs/guides/manage/self-hosted/reverseproxy/_cloudflare_tunnel.mdx diff --git a/docs/docs/guides/manage/self-hosted/reverseproxy/_more.mdx b/docs/docs/guides/manage/self-hosted/reverseproxy/_more.mdx new file mode 100644 index 0000000000..2afac6de96 --- /dev/null +++ b/docs/docs/guides/manage/self-hosted/reverseproxy/_more.mdx @@ -0,0 +1,4 @@ +## More information + +- [You can read here about the TLS Modes](/docs/guides/manage/self-hosted/tls_modes) +- [And here about how ZITADEL makes use of HTTP/2](/docs/guides/manage/self-hosted/http2) diff --git a/docs/docs/guides/manage/self-hosted/proxy/_nginx.mdx b/docs/docs/guides/manage/self-hosted/reverseproxy/_nginx.mdx similarity index 100% rename from docs/docs/guides/manage/self-hosted/proxy/_nginx.mdx rename to docs/docs/guides/manage/self-hosted/reverseproxy/_nginx.mdx diff --git a/docs/docs/guides/manage/self-hosted/proxy/_traefik.mdx b/docs/docs/guides/manage/self-hosted/reverseproxy/_traefik.mdx similarity index 100% rename from docs/docs/guides/manage/self-hosted/proxy/_traefik.mdx rename to docs/docs/guides/manage/self-hosted/reverseproxy/_traefik.mdx diff --git a/docs/docs/guides/manage/self-hosted/proxy/_zitadel_cloud.mdx b/docs/docs/guides/manage/self-hosted/reverseproxy/_zitadel_cloud.mdx similarity index 100% rename from docs/docs/guides/manage/self-hosted/proxy/_zitadel_cloud.mdx rename to docs/docs/guides/manage/self-hosted/reverseproxy/_zitadel_cloud.mdx diff --git a/docs/docs/guides/manage/self-hosted/reverseproxy/reverse_proxy.mdx b/docs/docs/guides/manage/self-hosted/reverseproxy/reverse_proxy.mdx new file mode 100644 index 0000000000..6ddaf1edf2 --- /dev/null +++ b/docs/docs/guides/manage/self-hosted/reverseproxy/reverse_proxy.mdx @@ -0,0 +1,53 @@ +--- +title: Reverse Proxy Configuration +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; +import Zcloud from "./_zitadel_cloud.mdx"; +import Nginx from "./_nginx.mdx"; +import Traefik from "./_traefik.mdx"; +import Caddy from "./_caddy.mdx"; +import Cftunnel from "./_cloudflare_tunnel.mdx"; +import Cloudflare from "./_cloudflare.mdx"; +import More from "./_more.mdx"; + +# Proxy Configuration + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/sidebars.js b/docs/sidebars.js index f51ba760ba..1d01f24c9a 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -77,8 +77,9 @@ module.exports = { type: "category", label: "Self-Hosted", items: [ + "guides/manage/self-hosted/production", "guides/manage/self-hosted/configure/configure", - "guides/manage/self-hosted/proxy/proxy", + "guides/manage/self-hosted/reverseproxy/reverse_proxy", "guides/manage/self-hosted/custom-domain", "guides/manage/self-hosted/http2", "guides/manage/self-hosted/tls_modes",