mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-01 12:42:26 +00:00
docs: improve compose example (#10518)
# Which Problems Are Solved The [compose deployment example](https://zitadel.com/docs/self-hosting/deploy/compose) has improved guidance and a more robust compose configuration. It provides clear paths to a variety of target environments. # How the Problems Are Solved - The introduction sentences make clear that the setup is not intended to be used as is in production. - Info blocks are removed as they rather increased the mental overhead instead of drawing attention to important hints. - The What's next section adds links and hints that help evolving the setup towards production. - The docker-compose.yaml explains variables better, gives hints and provides configuration examples. - The root user is used to write and read the `login-client.pat` file to avoid file permission errors and failing setup steps. - The postgres data is persisted in a named volume, so it survives the PostgreSQL container lifecycle. - `curl` is used instead of `wget`, because `curl` is more likely to already be installed on hosts. # Additional Context - Closes #10432 - Closes #8910 - Implements changes proposed [here](https://github.com/zitadel/zitadel/issues/10432#issuecomment-3188569674) and [here](https://github.com/zitadel/zitadel/issues/10432#issuecomment-3191360487). To test the changes, you can't download the compose file as suggested [by the preview doc](https://docs-nuzruxtoh-zitadel.vercel.app/docs/self-hosting/deploy/compose). As the updated compose file is not merged to main yet, you have to use a different download link: ```shell curl -L https://raw.githubusercontent.com/zitadel/zitadel/improve-compose-example/docs/docs/self-hosting/deploy/docker-compose.yaml -o docker-compose.yaml ``` --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
This commit is contained in:
@@ -1,6 +1 @@
|
||||
Open your favorite internet browser and navigate to http://localhost:8080/ui/console?login_hint=zitadel-admin@zitadel.localhost.
|
||||
Enther the password *Password1!* to log in.
|
||||
|
||||
:::info
|
||||
In the above login hint in the URL, replace localhost with your configured external domain, if any. e.g. with *zitadel-admin@<span></span>zitadel.sso.my.domain.tld*
|
||||
:::
|
||||
Visit http://localhost:8080/ui/console?login_hint=zitadel-admin@zitadel.localhost and enter `Password1!` to log in.
|
||||
|
||||
@@ -10,40 +10,80 @@ import DefaultUser from './_defaultuser.mdx'
|
||||
import Next from './_next.mdx'
|
||||
import NoteInstanceNotFound from './troubleshooting/_note_instance_not_found.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).
|
||||
|
||||
The setup is tested against Docker version 28.3.2 and Docker Compose version v2.38.2
|
||||
## 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
|
||||
|
||||
By executing the commands below, you will download the following file:
|
||||
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/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/>
|
||||
|
||||
## What's next{#next-steps}
|
||||
|
||||
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>
|
||||
|
||||
```bash
|
||||
# Download the docker compose example configuration.
|
||||
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/docker-compose.yaml
|
||||
Here are some natural steps forward to go from the current setup to production:
|
||||
|
||||
# Make sure you have the latest image versions
|
||||
docker compose pull
|
||||
- **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](/docs/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](/docs/self-hosting/manage/reverseproxy/reverse_proxy)
|
||||
- **Serve the API and the UI together on the same port**: [Run and configure a reverse proxy](/docs/self-hosting/manage/reverseproxy/reverse_proxy)
|
||||
- **Encrypt Traffic**: [Run and configure a reverse proxy](/docs/self-hosting/manage/reverseproxy/reverse_proxy)
|
||||
|
||||
# Run the PostgreSQL database, the Zitadel API and the Zitadel login.
|
||||
docker compose up
|
||||
```
|
||||
For more detailed recommendations, read the [Zitadel Production Setup Guide](/docs/self-hosting/manage/production).
|
||||
|
||||
<DefaultUser components={props.components} />
|
||||
<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="/docs/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="/docs/self-hosting/manage/login-client#require-login-v2">Enable the Login UI for all users</a></li>
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
:::info
|
||||
If you ran these commands for an existing instance that still uses the login v1, [create a login client for it to the now running v2 login](/self-hosting/manage/login-client#create-login-client).
|
||||
Move the login client PAT to `./login-client.pat` and restart the login container.
|
||||
```bash
|
||||
docker compose restart login
|
||||
```
|
||||
Now, [enable the Login UI for all users](/self-hosting/manage/login-client#require-login-v2)
|
||||
:::
|
||||
|
||||
<NoteInstanceNotFound/>
|
||||
<Next components={props.components} />
|
||||
<Disclaimer components={props.components} />
|
||||
|
||||
@@ -2,19 +2,29 @@ services:
|
||||
zitadel:
|
||||
restart: unless-stopped
|
||||
image: ghcr.io/zitadel/zitadel:latest
|
||||
command: start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
|
||||
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
|
||||
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel
|
||||
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel
|
||||
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
|
||||
# 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.
|
||||
@@ -23,28 +33,49 @@ services:
|
||||
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'
|
||||
ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED: true
|
||||
# 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](/docs/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_MACHINEKEY_TYPE: 1
|
||||
# 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 root@my-organization.localhost
|
||||
# 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
|
||||
- CMD
|
||||
- /app/zitadel
|
||||
- ready
|
||||
interval: 10s
|
||||
timeout: 60s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
user: "0"
|
||||
volumes:
|
||||
- .:/current-dir:delegated
|
||||
ports:
|
||||
@@ -59,13 +90,13 @@ services:
|
||||
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 variable CUSTOM_REQUEST_HEADERS=Host:localhost instead.
|
||||
# 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
|
||||
user: "${UID:-1000}"
|
||||
network_mode: service:zitadel
|
||||
user: "0"
|
||||
volumes:
|
||||
- .:/current-dir:ro
|
||||
depends_on:
|
||||
@@ -93,6 +124,13 @@ services:
|
||||
start_period: 20s
|
||||
networks:
|
||||
- zitadel
|
||||
ports:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
- 'data:/var/lib/postgresql/data:rw'
|
||||
|
||||
networks:
|
||||
zitadel:
|
||||
|
||||
volumes:
|
||||
data:
|
||||
|
||||
Reference in New Issue
Block a user