docs: introduce versioned docs and migrate to fuma (#11166)

## Todos for release

- [x] Configure Env in docs project on vercel
- [x] Configure Root Path in the docs project on vercel
- [ ] Remove old CSP https://github.com/zitadel/website/pull/1592

## What we did

This pull request migrates the project documentation from the old
`docs/` directory to the new `apps/docs/` directory, introduces a new
documentation system built with Next.js and Fumadocs, and updates all
relevant references, configuration files, and documentation to reflect
this change. It also adds new configuration and ignore files for the new
documentation app, updates CI and linting to exclude the new docs from
certain checks, and revises the contributing guidelines accordingly.

**Documentation System Migration and New Docs App**

* Migrated all documentation from `docs/` to `apps/docs/`, and updated
all references in `README.md`, `CONTRIBUTING.md`, and other files to
point to the new location.
[[1]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L585-L640)
[[2]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L660-R607)
[[3]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L740-R687)
[[4]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L2-R3)
[[5]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L30-R30)
* Added a new Next.js/Fumadocs-based documentation app under
`apps/docs/`, including core app files, layouts, routing, search API,
and a comprehensive `README.md` with development and contribution
instructions.
[[1]](diffhunk://#diff-5a1b07344a2c1b4d3f37b23ff1388b62cd9f57dea3c1cd23d8a0412b7602b132R1-R74)
[[2]](diffhunk://#diff-462b9ad1eabbb7d1c29bb9c36e4931eb180fd7190900e6d2babf8f4d66ad1c28R1-R39)
[[3]](diffhunk://#diff-e16ae25660ded787b10ac35dea96d5ecaacf895dae0afc8a9bd4382dc79a8c87R1-R7)
[apps/docs/app/[[...slug]]/layout.tsxR1-R81](diffhunk://#diff-59e08acde4e805b7aeccef1dcf98f1d71dfc550777e6b9402085cee0e9fa4e0aR1-R81),
[apps/docs/app/[[...slug]]/page.tsxR1-R79](diffhunk://#diff-e5df3f80d0fa01e12d63d81f29c57a9d14e846c78fd3beabb2ef768e38fd9580R1-R79),
[[4]](diffhunk://#diff-389b34918e040cacaa87cd7201ffa462cc2b0b716736f537e3d3c660ac69353bR1-R7)
[[5]](diffhunk://#diff-d3b03416d1c457b19f1c27b26f2db741412df841b875c26ccadc36e4522247f4R1-R29)
[[6]](diffhunk://#diff-c8fb8339570a5305809be7c618e14705fd86390dc278e6ce8ba224a7bc8b0c3cR1-R25)

**Configuration and Tooling Updates**

* Updated `.github/workflows/codeql.yml`, `.golangci.yaml`, and
`.github/dependabot.yml` to properly handle the new docs app: excluded
`apps/docs` from certain checks, added npm dependency updates for the
docs app, and excluded generated content.
[[1]](diffhunk://#diff-12783128521e452af0cfac94b99b8d250413c516ec71fe6d97dbea666ff7ba27L8-R14)
[[2]](diffhunk://#diff-9917ddc9f1c3304218f7269265b746d997c5c0615478177b5fceecd33ef47cb5R5-R6)
[[3]](diffhunk://#diff-9917ddc9f1c3304218f7269265b746d997c5c0615478177b5fceecd33ef47cb5R126-R129)
[[4]](diffhunk://#diff-dd4fbda47e51f1e35defb9275a9cd9c212ecde0b870cba89ddaaae65c5f3cd28R89-R106)
* Updated `.devcontainer/devcontainer.json` to use the latest Go 1.25.3
version for consistency.

**Licensing and Miscellaneous**

* Added `apps/docs/` to the list of licensed directories in
`LICENSING.md`.

These changes ensure the documentation is now maintained in a modern,
scalable system and all project tooling is updated to support the new
structure.

---------

Co-authored-by: Federico Coppede <[email protected]>
This commit is contained in:
Florian Forster
2026-01-29 08:38:36 -08:00
committed by GitHub
co-authored by Federico Coppede
parent 7b6395c348
commit d8ea041c56
2826 changed files with 78739 additions and 23571 deletions
@@ -0,0 +1 @@
*.pat
@@ -0,0 +1 @@
Visit http://localhost:8080/ui/[email protected] and enter `Password1!` to log in.
@@ -0,0 +1,8 @@
## Disclaimer
This guide is for development / demonstration purpose only and does NOT reflect a production setup.
Things such as TLS termination and email verification will not be available unless you
- Use an API gateway with valid certificates in front of the service
- Configure an appropriate email server
@@ -0,0 +1,8 @@
## What's next
For running a production grade ZITADEL instance in your environment, go on with the [configure ZITADEL](/self-hosting/manage/configure) section.
<Callout type="warn">
The ZITADEL management console [requires end-to-end HTTP/2 support](/self-hosting/manage/http2)
</Callout>
@@ -0,0 +1,89 @@
---
title: Set up Zitadel with Docker Compose
sidebar_label: Docker Compose
---
import CodeBlock from '@/components/docusaurus/code-block';
import NoteInstanceNotFound from './troubleshooting/_note_instance_not_found.mdx';
import DockerComposeSource from "./docker-compose.yaml"
import Disclaimer from './_disclaimer.mdx'
import DefaultUser from './_defaultuser.mdx'
import Next from './_next.mdx'
This guide is the entrypoint for running the Zitadel platform locally for the first time.
It is for demonstration and development purposes only and does not set up a production-ready and security hardened instance of Zitadel.
Once Zitadel up is and running, learn more about a production setup in the [What's Next section](#next-steps).
## Prerequisites
The setup is likely to work with other software versions too, but it is tested against the following environment:
- Ubuntu 24.04.1
- Docker 28.3.2
- Docker Compose v2.38.2
- curl 8.5.0
## Docker compose
The following commands set up services for a PostgreSQL database, a Zitadel API and a Zitadel login:
1. Download the `docker-compose.yaml` file from the Zitadel repository:
```shell
curl -L https://raw.githubusercontent.com/zitadel/zitadel/main/docs/self-hosting/deploy/docker-compose.yaml -o docker-compose.yaml
```
2. Make sure the containers use the latest image versions.
```shell
docker compose pull
```
3. Run the PostgreSQL database, the Zitadel API, and the Zitadel login.
```shell
docker compose up --detach --wait
```
4. Verify the containers are running and healthy.
```shell
docker compose ps
```
<DefaultUser components={props.components} />
## What's next
Before proceeding, review the downloaded `docker-compose.yaml` file:
The comments give context to the used variables and show examples for commonly used configuration variants.
<details>
<summary>docker-compose.yaml</summary>
<CodeBlock language="yaml">{DockerComposeSource}</CodeBlock>
</details>
Here are some natural steps forward to go from the current setup to production:
- **Use a different master key**: Set up an instance from scratch and use a different master key. For example, generate one by running `tr -dc A-Za-z0-9 </dev/urandom | head -c 32`
- **Use files for secrets instead of environment variables, and don't commit them to Git**: Learn how to [configure the platform](/self-hosting/manage/configure)
- **Run the containers as non-root users**: Remove the `user: "0"` lines from the `docker-compose.yaml` file.
- **Configure a different external domain or IP**: Beware that the login only works with HTTPS on non-localhost domains. [Run and configure a reverse proxy](/self-hosting/manage/reverseproxy/reverse_proxy)
- **Serve the API and the UI together on the same port**: [Run and configure a reverse proxy](/self-hosting/manage/reverseproxy/reverse_proxy)
- **Encrypt Traffic**: [Run and configure a reverse proxy](/self-hosting/manage/reverseproxy/reverse_proxy)
For more detailed recommendations, read the [Zitadel Production Setup Guide](/self-hosting/manage/production).
<details>
<summary>Read this if the environment uses the login v1</summary>
<p>
The login v2 is the next generation of the Zitadel login.
Its code and deployment are easily customizable.
Unlike the login v1, it runs in its own process.
The login v2 is enabled by default in new installations.
But if an existing `docker-compose.yaml` file is updated by following this guide,
an additional `zitadel-login` service is now running which is actually not doing anything, yet.
The following steps give guidance on how to enable the login v2 in an environment.
</p>
<ol>
<li>Read the login v2 related comments in the docker-compose.yaml.</li>
<li><a href="../../self-hosting/manage/login-client#create-login-client">Manually create a login client personal access token (PAT) for the now running v2 login</a>.</li>
<li>Move the PAT to `./login-client.pat`</li>
<li>Restart the login process: `docker compose restart login`</li>
<li><a href="../../self-hosting/manage/login-client#require-login-v2">Enable the Login UI for all users</a></li>
</ol>
</details>
@@ -0,0 +1,32 @@
---
title: Developing ZITADEL with Dev Containers
sidebar_label: Dev Containers
---
Dev containers provide a convenient way to set up a development environment for ZITADEL with all the necessary dependencies pre-configured. This allows you to start contributing or working on ZITADEL locally with minimal setup.
## Prerequisites
- Docker installed on your machine. You can find installation instructions for Docker on their official website: https://docs.docker.com/engine/install/
- A code editor or IDE with remote container development capabilities (optional, but recommended). [Visual Studio Code](https://code.visualstudio.com) with the [Remote Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) is a popular option.
## Setting Up Dev Container
ZITADEL provides a `.devcontainer` folder that configures the development environment within a container. Here's how to get started:
1. Clone the ZITADEL repository from GitHub:
```bash
git clone https://github.com/zitadel/zitadel.git
```
2. Navigate to the project directory:
```bash
cd zitadel
```
3. Open the project in your code editor or IDE (if using one with remote container support).
4. Follow the instructions provided by your code editor/IDE to initiate the development container. This typically involves opening the "Command Palette" or similar functionality and searching for commands related to "Dev Containers" or "Remote Containers". The quick start guide for VS Code can found [here](https://code.visualstudio.com/docs/devcontainers/containers#_quick-start-open-an-existing-folder-in-a-container)
**Note**: The first time you run this command, it might take some time to download the container image.
## Using Dev Container
Once the container is running, you will have a development environment set up with all the necessary dependencies pre-installed. You can then follow the instructions in the ZITADEL [contribution guide](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#developing-zitadel-with-dev-containers) to build and run ZITADEL, or develop the ZITADEL Management Console application.
@@ -0,0 +1,136 @@
services:
zitadel:
restart: unless-stopped
image: ghcr.io/zitadel/zitadel:latest
command: start-from-init --masterkey "MasterkeyNeedsToHave32Characters"
environment:
# See "What's next" to learn about how to serve Zitadel on a different domain or IP.
ZITADEL_EXTERNALDOMAIN: localhost
# See "What's next" to learn about how to enable TLS.
ZITADEL_EXTERNALSECURE: false
ZITADEL_TLS_ENABLED: false
# Database connection settings.
ZITADEL_DATABASE_POSTGRES_HOST: db
ZITADEL_DATABASE_POSTGRES_PORT: 5432
# The database is created by the init job if it does not exist.
ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
# The admin user must already exist in the database.
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: postgres
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: postgres
ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable
# The zitadel user is created by the init job if it does not exist.
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
# By configuring a login client, the setup job creates a user of type machine with the role IAM_LOGIN_CLIENT.
# It writes a PAT to the path specified in ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH.
# The PAT is passed to the login container via the environment variable ZITADEL_SERVICE_USER_TOKEN_FILE.
ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH: /current-dir/login-client.pat
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED: false
ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_USERNAME: login-client
ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_NAME: Automatically Initialized IAM_LOGIN_CLIENT
ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_PAT_EXPIRATIONDATE: '2029-01-01T00:00:00Z'
# Activate the login v2 on an installation from scratch.
# To activate the login v2 on an existing installation, read the "What's next" section.
ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED: true # To use the login v1, set this to false.
ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_BASEURI: http://localhost:3000/ui/v2/login
# Configure the redirection paths to the login v2.
ZITADEL_OIDC_DEFAULTLOGINURLV2: http://localhost:3000/ui/v2/login/login?authRequest=
ZITADEL_OIDC_DEFAULTLOGOUTURLV2: http://localhost:3000/ui/v2/login/logout?post_logout_redirect=
ZITADEL_SAML_DEFAULTLOGINURLV2: http://localhost:3000/ui/v2/login/login?samlRequest=
# By configuring a machine, the setup job creates a user of type machine with the role IAM_OWNER.
# It writes a personal access token (PAT) to the path specified in ZITADEL_FIRSTINSTANCE_PATPATH.
# The PAT can be used to provision resources with [Terraform](/guides/manage/terraform-provider), for example.
# ZITADEL_FIRSTINSTANCE_PATPATH: /current-dir/admin.pat
# ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME: admin
# ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME: Automatically Initialized IAM_OWNER
# ZITADEL_FIRSTINSTANCE_ORG_MACHINE_PAT_EXPIRATIONDATE: '2029-01-01T00:00:00Z'
# To change the initial human admin users username and password, uncomment the following lines.
# The first login name is formatted like this: <username>@<org_name>.<external_domain>
# With the following incommented configuration, this would be [email protected]
# Visit http://localhost:8080/ui/console to check if the login name works.
# If you can't log in, check the available login names:
# echo "select * from projections.login_names3;" | psql -h localhost -U postgres -d zitadel
# The postgres users password is postgres.
# ZITADEL_FIRSTINSTANCE_ORG_NAME: My Organization
# ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME: root
# ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD: RootPassword1!
# Enable debug logs
# ZITADEL_LOG_LEVEL: debug
# Write Access Logs to stdout.
# ZITADEL_LOGSTORE_ACCESS_STDOUT_ENABLED: true
healthcheck:
test:
- CMD
- /app/zitadel
- ready
interval: 10s
timeout: 60s
retries: 5
start_period: 10s
user: "0"
volumes:
- .:/current-dir:delegated
ports:
- 8080:8080
- 3000:3000
networks:
- zitadel
depends_on:
db:
condition: service_healthy
login:
restart: unless-stopped
image: ghcr.io/zitadel/zitadel-login:latest
# If you can't use the network_mode service:zitadel, you can pass the environment variables ZITADEL_API_URL=http://zitadel:8080 and CUSTOM_REQUEST_HEADERS=Host:localhost instead.
environment:
- ZITADEL_API_URL=http://localhost:8080
- NEXT_PUBLIC_BASE_PATH=/ui/v2/login
- ZITADEL_SERVICE_USER_TOKEN_FILE=/current-dir/login-client.pat
network_mode: service:zitadel
user: "0"
volumes:
- .:/current-dir:ro
depends_on:
zitadel:
condition: service_healthy
restart: false
db:
restart: unless-stopped
image: postgres:17
environment:
PGUSER: postgres
POSTGRES_PASSWORD: postgres
healthcheck:
test:
- CMD-SHELL
- pg_isready
- -d
- zitadel
- -U
- postgres
interval: 10s
timeout: 30s
retries: 5
start_period: 20s
networks:
- zitadel
ports:
- 5432:5432
volumes:
- 'data:/var/lib/postgresql/data:rw'
networks:
zitadel:
volumes:
data:
@@ -0,0 +1,8 @@
---
title: Set up ZITADEL on Kubernetes
sidebar_label: Kubernetes
---
For getting started with an easily testable insecure setup with Postgres, follow the [Insecure Postgres Example](https://github.com/zitadel/zitadel-charts/tree/main/examples/1-postgres-insecure).
For more information and configuration examples, go to the [ZITADEL charts repo](https://github.com/zitadel/zitadel-charts).
@@ -0,0 +1,73 @@
---
title: Install Zitadel on Linux
sidebar_label: Linux
---
import Disclaimer from "./_disclaimer.mdx";
import DefaultUser from "./_defaultuser.mdx";
import Next from "./_next.mdx";
import NoteInstanceNotFound from "./troubleshooting/_note_instance_not_found.mdx";
<Callout type="warn">
Be aware! This guide does not work for the newly updated version of Zitadel 4! [Learn more](https://github.com/zitadel/zitadel/issues/10526)
Please use Docker version if you want to use Zitadel 4.
</Callout>
## Install PostgreSQL
Download a `postgresql` binary as described [in the PostgreSQL docs](https://www.postgresql.org/download/linux/).
Zitadel is tested against PostgreSQL latest stable tag and latest Ubuntu LTS.
## Run PostgreSQL
```bash
sudo systemctl start postgresql
sudo systemctl enable postgresql
```
## Install Zitadel
Download the Zitadel release according to your architecture from [Github](https://github.com/zitadel/zitadel/releases/latest), unpack the archive and copy zitadel binary to /usr/local/bin
```bash
LATEST=$(curl -i https://github.com/zitadel/zitadel/releases/latest | grep location: | cut -d '/' -f 8 | tr -d '\r'); ARCH=$(uname -m); case $ARCH in armv5*) ARCH="armv5";; armv6*) ARCH="armv6";; armv7*) ARCH="arm";; aarch64) ARCH="arm64";; x86) ARCH="386";; x86_64) ARCH="amd64";; i686) ARCH="386";; i386) ARCH="386";; esac; wget -c https://github.com/zitadel/zitadel/releases/download/$LATEST/zitadel-linux-$ARCH.tar.gz -O - | tar -xz && sudo mv zitadel-linux-$ARCH/zitadel /usr/local/bin
```
## Run Zitadel
```bash
ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=root ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=postgres ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
```
<DefaultUser components={props.components} />
<NoteInstanceNotFound components={props.components} />
## VideoGuide
<iframe
width="100%"
height="315"
src="https://www.youtube.com/embed/YVLua-q7dbs"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
### Setup Zitadel with a service account
```bash
ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=root ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false ZITADEL_FIRSTINSTANCE_MACHINEKEYPATH=/tmp/zitadel-admin-sa.json ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME=zitadel-admin-sa ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME=Admin ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_TYPE=1 zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
# then you can move your machine key
mv /tmp/zitadel-admin-sa.json $HOME/zitadel-admin-sa.json
```
This key can be used to provision resources with for example [Terraform](/guides/manage/terraform-provider).
<Next components={props.components} />
<Disclaimer components={props.components} />
@@ -0,0 +1,68 @@
---
title: Install ZITADEL on MacOS
sidebar_label: MacOS
---
import NoteInstanceNotFound from './troubleshooting/_note_instance_not_found.mdx';
import Disclaimer from './_disclaimer.mdx'
import DefaultUser from './_defaultuser.mdx'
import Next from './_next.mdx'
## Install PostgreSQL
Download a `postgresql` binary as described [in the PostgreSQL docs](https://www.postgresql.org/download/macosx/).
ZITADEL is tested against PostgreSQL latest stable tag and latest Ubuntu LTS.
## Run PostgreSQL
```bash
sudo pg_ctl init -D /tmp/postgresql
sudo pg_ctl start -D /tmp/postgresql
```
## Install ZITADEL
### Homebrew
```bash
brew install zitadel/tap/zitadel
```
### Download from GitHub
Download the ZITADEL release according to your architecture from [Github](https://github.com/zitadel/zitadel/releases/latest)
## Unpack the archive
move to your download location and unpack the archive
```bash
#unpack and copy to /usr/local/bin
LATEST=$(curl -i https://github.com/zitadel/zitadel/releases/latest | grep location: | cut -d '/' -f 8 | tr -d '\r'); wget -qO- https://github.com/zitadel/zitadel/releases/download/$LATEST/zitadel_Darwin_$(uname -m).tar.gz | tar -xJ zitadel && sudo mv zitadel /usr/local/bin
```
## Run ZITADEL
```bash
ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=$(whoami) ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=postgres ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
```
<DefaultUser components={props.components} />
<NoteInstanceNotFound components={props.components} />
## VideoGuide
<iframe width="100%" height="315" src="https://www.youtube.com/embed/Ob-kBzmezeg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
### Setup ZITADEL with a service account
```bash
ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=$(whoami) ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false ZITADEL_FIRSTINSTANCE_MACHINEKEYPATH=/tmp/zitadel-admin-sa.json ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME=zitadel-admin-sa ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME=Admin ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_TYPE=1 zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
# then you can move your machine key
mv /tmp/zitadel-admin-sa.json $HOME/zitadel-admin-sa.json
```
This key can be used to provision resources with for example [Terraform](/guides/manage/terraform-provider).
<Next components={props.components} />
<Disclaimer components={props.components} />
@@ -0,0 +1,33 @@
---
title: Deploy ZITADEL
sidebar_label: Overview
---
Choose your platform and run ZITADEL with the most minimal configuration possible.
- [Linux](./linux)
- [MacOS](./macos)
- [Docker Compose](./compose)
- [Kubernetes](./kubernetes)
## Prerequisites
- 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 PostgreSQL as only needed storage. Make sure to read our [Production Guide](/self-hosting/manage/production#prefer-postgre-sql) before you decide to use Postgresql.
## Releases
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 in a high frequency.
# Production Setup
After you have 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](/self-hosting/manage/production).
To achieve high availability, we recommend using 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.
@@ -0,0 +1,5 @@
`ID=QUERY-n0wng Message=Instance not found`
If you're self hosting with a Custom Domain, you need to instruct ZITADEL to use the `ExternalDomain`.
You can find further instructions in our guide about [Custom Domains](/self-hosting/manage/custom-domain).
We also provide a guide on how to [configure](/self-hosting/manage/configure) ZITADEL with variables from files or environment variables.
@@ -0,0 +1,5 @@
<Callout>
This guide is based on a local setup.
If you encounter an error "Instance Not Found" please read the following section:
[Instance not found](/self-hosting/deploy/troubleshooting#instance-not-found)
</Callout>
@@ -0,0 +1,37 @@
If you operate Zitadel behind a Reverse Proxy or Ingress inside a Kubernetes cluster,
you may encounter an Error like `upstream sent too big header while reading response header from upstream`
in your NGINX Logs and receive a 403 Error when accessing NGINX.
you can solve it by increasing the grpc buffer size in your nginx config:
### Ingress NGINX
```yaml
ingress:
enabled: true
annotations:
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleRemoveById 949110
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
nginx.ingress.kubernetes.io/configuration-snippet: |
grpc_set_header Host $host;
more_clear_input_headers "Host" "X-Forwarded-Host";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_x_forwarded_host;
# highlight-next-line
nginx.ingress.kubernetes.io/server-snippet: "grpc_buffer_size 8k;"
```
### NGINX Config
```nginx
http {
server {
listen 80;
http2 on;
location / {
grpc_pass grpc://zitadel-disabled-tls:8080;
grpc_set_header Host $host:$server_port;
# highlight-next-line
grpc_buffer_size 8k;
}
}
}
```
@@ -0,0 +1,15 @@
---
title: Troubleshoot ZITADEL
---
import InstanceNotFound from "../../../self-hosting/deploy/troubleshooting/_instance_not_found.mdx";
import UpstreamHeader from "../../../self-hosting/deploy/troubleshooting/_upstream_header.mdx"
## Instance not found
<InstanceNotFound components={props.components} />
## upstream sent too big header while reading response header from upstream
<UpstreamHeader components={props.components} />