From ca393cc1aa47f0886524046710f2763d1cd38737 Mon Sep 17 00:00:00 2001 From: spbolton Date: Thu, 25 Jan 2024 12:00:18 -0500 Subject: [PATCH] restore cleaned up files --- docker/dev-env/Dockerfile | 65 + docker/dev-env/README.md | 114 + docker/dev-env/entrypoint.sh | 177 ++ docker/docker-compose-examples/README.md | 22 + .../analytics/docker-compose.yml | 157 ++ .../dev/clickhouse/clickhouse-issue-15638.xml | 8 + .../analytics/setup/config/dev/cube/cube.js | 30 + .../setup/config/dev/cube/schema/Events.js | 151 ++ .../dev/jitsu/server/config/eventnative.yaml | 102 + .../config/dev/keycloak/keycloak-keystore.jks | Bin 0 -> 2228 bytes .../setup/config/dev/keycloak/test-realm.json | 2300 +++++++++++++++++ .../analytics/setup/db/mssql/entrypoint.sh | 17 + .../setup/db/mssql/init-scripts/init.sql | 7 + .../db/postgres/init-scripts/init-config.sh | 11 + .../setup/db/postgres/init-scripts/init.sql | 1 + .../cluster-mode/README.md | 54 + .../cluster-mode/docker-compose-node-1.yml | 74 + .../cluster-mode/docker-compose-node-2.yml | 35 + .../push-publish/README.md | 48 + .../push-publish/docker-compose-receiver.yml | 74 + .../push-publish/docker-compose-sender.yml | 74 + .../push-publish/receiver/docker-compose.yml | 74 + .../dotcms-get-demo-site-starter-urls.sh | 32 + .../scripts/dotcms_properties_to_env_vars.py | 199 ++ .../Intellij Debug Mode.png | Bin 0 -> 233460 bytes .../single-node-debug-mode/README.md | 50 + .../single-node-debug-mode/docker-compose.yml | 75 + .../single-node-demo-site/README.md | 33 + .../single-node-demo-site/docker-compose.yml | 75 + .../single-node/README.md | 40 + .../single-node/docker-compose.yml | 74 + .../with-kibana/docker-compose.yml | 72 + .../with-opensearch-dashboard/README.md | 42 + .../docker-compose.yml | 83 + .../with-redis-session/README.md | 111 + .../docker-compose-node-1.yml | 90 + .../docker-compose-node-2.yml | 42 + .../with-redis/README.md | 56 + .../with-redis/docker-compose-node-1.yml | 88 + .../with-redis/docker-compose-node-2.yml | 42 + 40 files changed, 4799 insertions(+) create mode 100644 docker/dev-env/Dockerfile create mode 100644 docker/dev-env/README.md create mode 100644 docker/dev-env/entrypoint.sh create mode 100644 docker/docker-compose-examples/README.md create mode 100644 docker/docker-compose-examples/analytics/docker-compose.yml create mode 100644 docker/docker-compose-examples/analytics/setup/config/dev/clickhouse/clickhouse-issue-15638.xml create mode 100644 docker/docker-compose-examples/analytics/setup/config/dev/cube/cube.js create mode 100644 docker/docker-compose-examples/analytics/setup/config/dev/cube/schema/Events.js create mode 100644 docker/docker-compose-examples/analytics/setup/config/dev/jitsu/server/config/eventnative.yaml create mode 100644 docker/docker-compose-examples/analytics/setup/config/dev/keycloak/keycloak-keystore.jks create mode 100644 docker/docker-compose-examples/analytics/setup/config/dev/keycloak/test-realm.json create mode 100644 docker/docker-compose-examples/analytics/setup/db/mssql/entrypoint.sh create mode 100644 docker/docker-compose-examples/analytics/setup/db/mssql/init-scripts/init.sql create mode 100644 docker/docker-compose-examples/analytics/setup/db/postgres/init-scripts/init-config.sh create mode 100644 docker/docker-compose-examples/analytics/setup/db/postgres/init-scripts/init.sql create mode 100644 docker/docker-compose-examples/cluster-mode/README.md create mode 100644 docker/docker-compose-examples/cluster-mode/docker-compose-node-1.yml create mode 100644 docker/docker-compose-examples/cluster-mode/docker-compose-node-2.yml create mode 100644 docker/docker-compose-examples/push-publish/README.md create mode 100644 docker/docker-compose-examples/push-publish/docker-compose-receiver.yml create mode 100644 docker/docker-compose-examples/push-publish/docker-compose-sender.yml create mode 100644 docker/docker-compose-examples/push-publish/receiver/docker-compose.yml create mode 100644 docker/docker-compose-examples/scripts/dotcms-get-demo-site-starter-urls.sh create mode 100644 docker/docker-compose-examples/scripts/dotcms_properties_to_env_vars.py create mode 100644 docker/docker-compose-examples/single-node-debug-mode/Intellij Debug Mode.png create mode 100644 docker/docker-compose-examples/single-node-debug-mode/README.md create mode 100644 docker/docker-compose-examples/single-node-debug-mode/docker-compose.yml create mode 100644 docker/docker-compose-examples/single-node-demo-site/README.md create mode 100644 docker/docker-compose-examples/single-node-demo-site/docker-compose.yml create mode 100644 docker/docker-compose-examples/single-node/README.md create mode 100644 docker/docker-compose-examples/single-node/docker-compose.yml create mode 100644 docker/docker-compose-examples/with-kibana/docker-compose.yml create mode 100644 docker/docker-compose-examples/with-opensearch-dashboard/README.md create mode 100644 docker/docker-compose-examples/with-opensearch-dashboard/docker-compose.yml create mode 100644 docker/docker-compose-examples/with-redis-session/README.md create mode 100644 docker/docker-compose-examples/with-redis-session/docker-compose-node-1.yml create mode 100644 docker/docker-compose-examples/with-redis-session/docker-compose-node-2.yml create mode 100644 docker/docker-compose-examples/with-redis/README.md create mode 100644 docker/docker-compose-examples/with-redis/docker-compose-node-1.yml create mode 100644 docker/docker-compose-examples/with-redis/docker-compose-node-2.yml diff --git a/docker/dev-env/Dockerfile b/docker/dev-env/Dockerfile new file mode 100644 index 000000000000..a482ffd9a237 --- /dev/null +++ b/docker/dev-env/Dockerfile @@ -0,0 +1,65 @@ +# ---------------------------------------------- +# Stage 1: Build dotCMS from our builder image +# ---------------------------------------------- +ARG DOTCMS_DOCKER_TAG="latest" + +FROM dotcms/dotcms:${DOTCMS_DOCKER_TAG} AS dotcms + +FROM ubuntu:22.04 + +# Defining default non-root user UID, GID, and name +ARG USER_UID="65001" +ARG USER_GID="65001" +ARG USER_GROUP="dotcms" +ARG USER_NAME="dotcms" + +RUN groupadd -f -g $USER_GID $USER_GROUP +# Creating default non-user +# the useradd +RUN useradd -l -d /srv -g $USER_GID -u $USER_UID $USER_NAME + +COPY --from=dotcms --chown=$USER_NAME:$USER_GROUP /srv/ /srv/ + +ARG DEBIAN_FRONTEND=noninteractive +ARG UBUNTU_RELEASE=jammy +ARG PG_VERSION=15 +ARG PGDATA=/data/postgres +ARG DEBIAN_FRONTEND=noninteractive +ARG DEBCONF_NONINTERACTIVE_SEEN=true +RUN mkdir /data +RUN chmod 777 /data + +# Installing basic packages +RUN apt-get update && \ + apt-get upgrade -y && \ + apt-get install -y --no-install-recommends bash zip unzip wget libtcnative-1\ + tzdata tini ca-certificates openssl libapr1 libpq-dev curl gnupg\ + vim libarchive-tools + + +RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $UBUNTU_RELEASE-pgdg main" > /etc/apt/sources.list.d/pgdg.list' + +RUN wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | tee /etc/apt/trusted.gpg.d/pgdg.asc &>/dev/null \ + && apt-get update -y \ + && apt-get upgrade -y \ + && apt-get install -y postgresql-$PG_VERSION + + +# Cleanup +RUN apt-get autoremove -y && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + + +COPY --from=opensearchproject/opensearch:1.3.11 --chown=$USER_NAME:$USER_GROUP /usr/share/opensearch /usr/share/opensearch + +RUN echo "discovery.type: single-node\nbootstrap.memory_lock: true\ncluster.routing.allocation.disk.threshold_enabled: true\ncluster.routing.allocation.disk.watermark.low: 1g\ncluster.routing.allocation.disk.watermark.high: 500m\ncluster.routing.allocation.disk.watermark.flood_stage: 400m\ncluster.info.update.interval: 5m" >> /usr/share/opensearch/config/opensearch.yml + + +ENV PATH=$PATH:/usr/share/opensearch/bin +RUN /usr/share/opensearch/opensearch-onetime-setup.sh +RUN chown -R dotcms.dotcms /usr/share/opensearch/config +COPY entrypoint.sh / +RUN chmod 755 /entrypoint.sh + +ENTRYPOINT ["/usr/bin/tini", "--", "/entrypoint.sh"] diff --git a/docker/dev-env/README.md b/docker/dev-env/README.md new file mode 100644 index 000000000000..691fda76db12 --- /dev/null +++ b/docker/dev-env/README.md @@ -0,0 +1,114 @@ +# dotCMS Development Docker Image +### All in one docker image including Postgres and Opensearch +This image, intended for development, runs Ubuntu 22.04 and contains dotCMS, Postgres 15 and Opensearch 1.x. All dotCMS, db and es index data is stored in the `/data` directory, which should be mapped in if you want your environment to persist. The beauty of this image that it can be used to CLONE an existing dotCMS instance. + + +## Running the image +This image takes all the normal dotCMS docker config switches - keep in mind that the DB and ES come pre-wired, so no need to change those. This image also takes the following env variables: + +- `DOTCMS_SOURCE_ENVIRONMENT` : the url for the environment you wish to clone, e.g. https://demo.dotcms.com . +- `DOTCMS_API_TOKEN` : A valid dotCMS API Token from an admin user in the source environment. +- `DOTCMS_USERNAME_PASSWORD` : The username:password for an admin user in the source environment. +- `DOTCMS_DEBUG` : Run dotCMS in debug mode and listen for a remote debugger on port 8000, defaults to `false`. +- `ALL_ASSETS` : Controls whether old versions of assets are included in the download, defaults to false, which means only the current live and working versions of assets will be downloaded. + + + +## Cloning a dotCMS Environment +When running this image, if you specify a source environment and a valid means to authenticate, the image will attempt to pull the **assets** and **db** from the source environment. To do this, you start the image up and pass it a `DOTCMS_SOURCE_ENVIRONMENT` and either an `DOTCMS_API_TOKEN` or `DOTCMS_USERNAME_PASSWORD` (e.g. `admin@dotcms.com:admin`). On startup, the image will try to reach out and download the database and assets from the specified dotCMS instance, load the db and assets and start dotCMS in debug mode. Once the server starts, you need to run a full reindex. + + + +#### Clone demo with a dotCMS API Token +``` +export TOK=XXXXXXX_YOUR_DOTCMS_TOKEN.eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +docker run --rm \ +-p 8000:8000 \ +-p 8443:8443 \ +-v $PWD/data:/data \ +-e DOTCMS_SOURCE_ENVIRONMENT=https://demo.dotcms.com \ +-e DOTCMS_API_TOKEN=$TOK \ + dotcms/dotcms-dev:latest +``` + +#### Clone demo with UserID/Password +``` +docker run --rm \ +-p 8443:8443 \ +-v $PWD/data:/data \ +-e DOTCMS_SOURCE_ENVIRONMENT=https://demo.dotcms.com \ +-e DOTCMS_USERNAME_PASSWORD="admin@dotcms.com:admin" \ + dotcms/dotcms-dev:latest +``` + +#### Run normal startup with Postgres port exposed, running debug +``` +docker run --rm \ +-p 8443:8443 \ +-p 5432:5432 \ +-p 8000:8000 \ +-v $PWD/data:/data \ +-e DOTCMS_DEBUG=true \ + dotcms/dotcms-dev:latest +``` + + +#### Troubleshooting the Download +Due to a bug in docker, downloading large environments can time out. To get around this, you can download the assets and db yourself (outside of docker) to seed your installation and add them to the data volume you map into the image. dotCMS will look for `/data/assets.zip` and/or `/data/dotcms_db.sql.gz` to import before running the normal starter import routine. + +#### Downloading your assets and db outside of Docker +dotCMS offers two admin only endpoints to download your data and assets +- `/api/v1/maintenance/_downloadAssets` +- `/api/v1/maintenance/_downloadDb` + +When downloading assets, you can specify `?oldAssets=false`, and dotCMS will only include the assets for live and working versions of your content, thus hopefully generating a MUCH smaller download + +#### Example wget to download assets +``` +wget --header="$AUTH_HEADER" -t 1 -O assets.zip $DOTCMS_SOURCE_ENVIRONMENT/api/v1/maintenance/_downloadAssets?oldAssets=false +``` + +#### Example wget to download your DB +``` +wget --header="$AUTH_HEADER" -t 1 -O dotcms_db.sql.gz $DOTCMS_SOURCE_ENVIRONMENT/api/v1/maintenance/_downloadDb + +``` + +#### Starting from a clean slate +Your development instance can be deleted and reset by deleting the ./data directory that is mapped in. + + + + +## Building this Image +By default, this image is built from the `dotcms/dotcms:latest` tagged version of dotCMS. You can specify another dotCMS version you want use for your dev instance by passing the build-arg `DOTCMS_DOCKER_TAG` to indicate which dotCMS image tag to use to build, e.g. +`--build-arg DOTCMS_DOCKER_TAG=latest` or `--build-arg DOTCMS_DOCKER_TAG=23.07` + +``` +docker build --pull --build-arg DOTCMS_DOCKER_TAG=latest . -t dotcms/dotcms-dev +``` +or +``` +docker buildx build --build-arg DOTCMS_DOCKER_TAG=master_latest_SNAPSHOT --platform linux/amd64,linux/arm64 --pull --push -t dotcms/dotcms-dev:master_latest_SNAPSHOT . +``` + +### Included Database and Elasticsearch + +This image runs the following servers internally. + +#### Opensearch 1.3.11 +Running https on +- https on port 9200 +- basic auth (admin/admin) +- data stored in /data/opensearch + + +#### Postgres 15 +Running on port 5432 and using the dotCMS defaults: +- db: dotcms +- user: dotcmsdbuser +- pass: password +- data stored in /data/postgres + +If you wish to connect to these instances remotely, you will need to expose their ports in docker when you run the image, e.g. diff --git a/docker/dev-env/entrypoint.sh b/docker/dev-env/entrypoint.sh new file mode 100644 index 000000000000..0181eceb2760 --- /dev/null +++ b/docker/dev-env/entrypoint.sh @@ -0,0 +1,177 @@ +#!/bin/bash -e + +ASSETS_BACKUP_FILE=/data/assets.zip +DB_BACKUP_FILE=/data/dotcms_db.sql.gz + +export JAVA_HOME=/usr/share/opensearch/jdk +export PATH=$PATH:$JAVA_HOME/bin:/usr/local/pgsql/bin +export ES_JAVA_OPTS=${ES_JAVA_OPTS:-"-Xmx512m"} + + +setup_postgres () { + echo "Starting Postgres Database" + if [ ! -d "/data/postgres" ]; then + mv /var/lib/postgresql/$PG_VERSION/main /data/postgres + fi + rm -rf /var/lib/postgresql/$PG_VERSION/main + ln -sf /data/postgres /var/lib/postgresql/$PG_VERSION/main + + + /etc/init.d/postgresql start + + if su -c "psql -lqt" postgres | cut -d \| -f 1 | grep -qw dotcms; then + # database exists + echo "- dotCMS db exists, skipping import" + echo "- Delete the /data/postgres folder to force a re-import" + return 0 + fi + + # creating database + su -c "psql -c \"CREATE database dotcms;\" 1> /dev/null" postgres + su -c "psql -c \"CREATE USER dotcmsdbuser WITH PASSWORD 'password';\" 1> /dev/null" postgres + su -c "psql -c \"ALTER DATABASE dotcms OWNER TO dotcmsdbuser;\" 1> /dev/null" postgres + + if [ -f "$DB_BACKUP_FILE" ]; then + echo "- Importing dotCMS db from backup" + # import database + cat $DB_BACKUP_FILE | gzip -d | PGPASSWORD=password psql -h 127.0.0.1 -Udotcmsdbuser dotcms + fi + + return 0 +} + + +setup_opensearch () { + + + if [ ! -d "/data/opensearch" ]; then + mv /usr/share/opensearch/data /data/opensearch + chown dotcms.dotcms /data/opensearch + fi + + rm -rf /usr/share/opensearch/data + ln -sf /data/opensearch /usr/share/opensearch/data + chown dotcms.dotcms /data/opensearch + + echo "Starting OPENSEARCH" + # Start up Elasticsearch + su -c "/usr/share/opensearch/bin/opensearch 1> /dev/null" dotcms & +} + + +pull_dotcms_backups () { + + # If these are 0 length files, delete them + if [ ! -s $ASSETS_BACKUP_FILE ] ; then + rm -rf $ASSETS_BACKUP_FILE + fi + + if [ ! -s $DB_BACKUP_FILE ] ; then + rm -rf $DB_BACKUP_FILE + fi + + if [ -f "$ASSETS_BACKUP_FILE" ] && [ -f $DB_BACKUP_FILE ]; then + + echo "- DB and Assets backups exist, skipping" + echo "- Delete $ASSETS_BACKUP_FILE and $DB_BACKUP_FILE to force a re-download" + return 0 + fi + + if [ -z "$DOTCMS_SOURCE_ENVIRONMENT" ]; then + echo "- No dotCMS env to clone, starting normally" + return 0 + fi + if [ -z "$DOTCMS_API_TOKEN" -a -z "$DOTCMS_USERNAME_PASSWORD" ]; then + echo "- Source environment specified, but no dotCMS auth available" + return 1 + fi + + echo "Pulling Environment from $DOTCMS_SOURCE_ENVIRONMENT" + + if [ -n "$DOTCMS_API_TOKEN" ]; then + echo "- Using Authorization: Bearer" + AUTH_HEADER="Authorization: Bearer $DOTCMS_API_TOKEN" + else + echo "- Using Authorization: Basic" + AUTH_HEADER="Authorization: Basic $(echo -n $DOTCMS_USERNAME_PASSWORD | base64)" + fi + + mkdir -p /data/shared/assets + chown -R dotcms.dotcms /data/shared + + if [ ! -f "$ASSETS_BACKUP_FILE" ]; then + su -c "rm -rf $ASSETS_BACKUP_FILE.tmp" + echo "- Downloading ASSETS" + su -c "wget --no-check-certificate --header=\"$AUTH_HEADER\" -t 1 -O $ASSETS_BACKUP_FILE.tmp $DOTCMS_SOURCE_ENVIRONMENT/api/v1/maintenance/_downloadAssets\?oldAssets=${ALL_ASSETS:-"false"} " dotcms + if [ -s $ASSETS_BACKUP_FILE.tmp ]; then + su -c "mv $ASSETS_BACKUP_FILE.tmp $ASSETS_BACKUP_FILE" + else + su -c "rm -rf $ASSETS_BACKUP_FILE.tmp" + echo "asset download failed, please check your credentials and try again" + exit 1 + fi + fi + + if [ ! -f "$DB_BACKUP_FILE" ]; then + echo "- Downloading database" + su -c "rm -rf $DB_BACKUP_FILE.tmp" + su -c "wget --no-check-certificate --header=\"$AUTH_HEADER\" -t 1 -O $DB_BACKUP_FILE.tmp $DOTCMS_SOURCE_ENVIRONMENT/api/v1/maintenance/_downloadDb" dotcms + if [ -s $DB_BACKUP_FILE.tmp ]; then + su -c "mv $DB_BACKUP_FILE.tmp $DB_BACKUP_FILE" + else + su -c "rm -rf $DB_BACKUP_FILE.tmp" + echo "database download failed, please check your credentials and try again" + exit 1 + fi + fi + +} + +unpack_assets(){ + if [ -d "/data/shared/assets/1" ]; then + echo "Assets Already Unpacked, skipping. If you would like to unpack them again, please delete the /data/shared/assets folder" + return 0 + fi + if [ ! -s "$ASSETS_BACKUP_FILE" ]; then + return 0 + fi + + + echo "Unzipping assets.zip" + su -c "unzip -u $ASSETS_BACKUP_FILE -d /data/shared" || true +} + + + +start_dotcms () { + + + if [ "$DOTCMS_DEBUG" == "true" ];then + echo "Setting java debug port to 8000. If you want to change the debug options," + echo "pass in your options using the CMS_JAVA_OPTS variable instead" + export CMS_JAVA_OPTS="$CMS_JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=*:8000" + fi + + export DB_BASE_URL=${DB_BASE_URL:-"jdbc:postgresql://127.0.0.1/dotcms"} + export DOT_ES_ENDPOINTS=${DOT_ES_ENDPOINTS:-"https://127.0.0.1:9200"} + export DOT_DOTCMS_CLUSTER_ID=${DOT_DOTCMS_CLUSTER_ID:-"dotcms_dev"} + + echo "Starting dotCMS using" + echo " - CMS_JAVA_OPTS: $CMS_JAVA_OPTS" + echo " - ES_JAVA_OPTS: $ES_JAVA_OPTS" + echo " - DB_BASE_URL: $DB_BASE_URL" + echo " - DOT_ES_ENDPOINTS: $DOT_ES_ENDPOINTS" + echo " - DOT_DOTCMS_CLUSTER_ID: $DOT_DOTCMS_CLUSTER_ID" + + . /srv/entrypoint.sh +} + + + + + +pull_dotcms_backups && echo "" +setup_postgres && echo "" +unpack_assets && echo "" +setup_opensearch && echo "" +start_dotcms diff --git a/docker/docker-compose-examples/README.md b/docker/docker-compose-examples/README.md new file mode 100644 index 000000000000..ce303eb9110a --- /dev/null +++ b/docker/docker-compose-examples/README.md @@ -0,0 +1,22 @@ +# Docker Compose Examples + +This directory contains docker-compose examples ready to use + +The following examples are provided: + +- **cluster-mode:** dotcms instance with 2 nodes in a cluster +- **elasticsearch-with-kibana:** elasticsearch server with kibana +- **oracle-database:** oracle database running on port 1521 +- **push-publish:** dotcms environment with a sender and a receiver +- **single-node:** basic dotcms instance running with postgres database +- **single-node-debug-mode:** basic dotcms instance running with postgres database and debug mode enabled +- **single-node-demo-site:** basic dotcms instance running demo site +- **with-kibana:** basic dotcms instance running with postgres database and kibana +- **with-mssql:** basic dotcms instance running with MSSQL database +- **with-oracle:** basic dotcms instance running with oracle database +- **with-redis:** dotcms cluster with redis cache and pub/sub provider + +The following scripts are provided: + +- **dotcms-get-demo-site-starter-urls.sh:** prints demo site starter URL for each dotCMS version +- **dotcms_properties_to_env_vars.py:** prints ENV variables based on dotCMS properties in a "binary" install - helpful for upgrades diff --git a/docker/docker-compose-examples/analytics/docker-compose.yml b/docker/docker-compose-examples/analytics/docker-compose.yml new file mode 100644 index 000000000000..a43f631c49df --- /dev/null +++ b/docker/docker-compose-examples/analytics/docker-compose.yml @@ -0,0 +1,157 @@ +version: '2.2' + +services: + + postgres: + container_name: postgres + image: postgres:13.2 + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRESQL_DB:-postgres} + POSTGRES_USER: ${POSTGRESQL_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRESQL_PASS:-postgres} + ports: + - ${POSTGRESQL_HOST_PORT:-54321}:5432 + + keycloak: + container_name: keycloak + depends_on: + - postgres + environment: + DB_VENDOR: postgres + DB_ADDR: postgres + KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN:-admin} + KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-keycloak} + DB_DATABASE: ${POSTGRESQL_DB:-postgres} + DB_USER: ${POSTGRESQL_USER:-postgres} + DB_PASSWORD: ${POSTGRESQL_PASS:-postgres} + image: quay.io/keycloak/keycloak:${KEYCLOAK_VERSION:-18.0.2} + volumes: + - ./setup/config/dev/keycloak/test-realm.json:/opt/keycloak/data/import/example-realm.json + entrypoint: ["/opt/keycloak/bin/kc.sh", "start-dev", "--import-realm"] + ports: + - "${KEYCLOAK_HOST_PORT:-61111}:8080" + restart: always + + dotcms-analytics: + container_name: dotcms-analytics + image: dotcms/configurator:latest + environment: + - JITSU_USE_CONFIGURATOR='true' + - JITSU_JITSU_CONFIGURATOR=http://host.docker.internal:7007/ + - JITSU_CLUSTER_TOKEN=myadmin + - JITSU_JITSU_SERVER=http://jitsu:8001/ + - QUARKUS_OIDC_AUTH_SERVER_URL=${AUTH_SERVER_URL:-http://host.docker.internal:61111/realms/dotcms} + - QUARKUS_DATASOURCE_DB_KIND=postgresql + - QUARKUS_DATASOURCE_REACTIVE_URL=postgresql://postgres:54321/${POSTGRESQL_DB:-keycloak} + - QUARKUS_DATASOURCE_USERNAME=${POSTGRESQL_USER:-postgres} + - QUARKUS_DATASOURCE_PASSWORD=${POSTGRESQL_PASS:-postgres} + - QUARKUS_HIBERNATE_ORM_DATABASE_GENERATION=drop-and-create + - QUARKUS_HIBERNATE_ORM_DATABASE_GENERATION_CREATE_SCHEMAS=true + - QUARKUS_SWAGGER_UI_ALWAYS_INCLUDE=true + - EXCLUDED_QUERY_PARAMS=${ANALYTICS_EXCLUDED_QUERY_PARAMS:-variantName,redirect} + ports: + - "${DOTCMS_ANALYTICS_HOST_PORT:-8088}:8080" + depends_on: + - keycloak + - postgres + - jitsu + - jitsu-configurator + + jitsu: + container_name: jitsu + image: jitsucom/server:latest + environment: + - CLUSTER_ADMIN_TOKEN=myadmin + - REDIS_URL=redis://jitsu_redis:6379 + - JITSU_CONFIGURATOR_URL=${JITSU_CONFIGURATOR_URL:-http://host.docker.internal:7007} +# - JITSU_CONFIGURATOR_URL=${JITSU_CONFIGURATOR_URL:-http://dotcms-analytics:8090} + - SERVER_PORT=8001 + - TERM=xterm-256color + - TLS_SKIP_VERIFY=true + depends_on: + - redis + - ch_server + volumes: + - ./setup/config/dev/jitsu/server/config:/home/eventnative/data/config + restart: always + ports: + - "${JITSU_HOST_PORT:-8081}:8001" + + jitsu-configurator: + container_name: jitsu-configurator + image: jitsucom/configurator:latest + environment: + - CLUSTER_ADMIN_TOKEN=myadmin + - REDIS_URL=redis://jitsu_redis:6379 + - JITSU_SERVER_URL=http://jitsu:8001 + - BACKEND_API_BASE=redis + - JITSU_EXTENDED_TELEMETRY_DISABLED=true + - JITSU_HTTP_CONTEXT_ENRICHMENT=true + - TERM=xterm-256color + - TLS_SKIP_VERIFY=true + depends_on: + redis: + condition: service_healthy + ch_server: + condition: service_healthy + restart: always + ports: + - "${JITSU_CONFIGURATOR_PORT:-7007}:7000" + + redis: + container_name: jitsu_redis + image: redis:6.2.6-bullseye + volumes: + - redis-data:/data + restart: always + healthcheck: + test: ["CMD-SHELL", "redis-cli -h localhost -p 6379 PING"] + interval: 1s + timeout: 30s + + cube: + container_name: cube + image: cubejs/cube:latest + ports: + - ${CUBE_HOST_PORT:-4001}:4000 + environment: + - CUBEJS_DEV_MODE=true + - CUBEJS_DB_TYPE=clickhouse + - CUBEJS_DB_HOST=${CH_SERVER:-ch_server} + - CUBEJS_DB_NAME=${CH_DB:-clickhouse_test_db} + - CUBEJS_DB_USER=${CH_USER:-clickhouse_test_user} + - CUBEJS_DB_PASS=${CH_PWD:-clickhouse_password} + - CUBEJS_JWK_URL=${JWKS_URL:-http://keycloak:61111/realms/dotcms/protocol/openid-connect/certs} + - CUBEJS_JWT_AUDIENCE=api-dotcms-analytics-audience + - CUBEJS_JWT_ISSUER=${AUTH_SERVER_URL:-http://keycloak:61111/realms/dotcms} + - CUBEJS_JWT_ALGS=RS256 + - CUBEJS_JWT_CLAIMS_NAMESPACE=https://dotcms.com/analytics + volumes: + - cube_metastore:/cube/conf/.cubestore + - ./setup/config/dev/cube/schema:/cube/conf/schema + + ch_server: + container_name: ch_server + image: dotcms/clickhouse-server:latest + ports: + - "${CH_HOST_PORT:-8124}:8123" + ulimits: + nofile: + soft: 262144 + hard: 262144 + healthcheck: + test: wget --no-verbose --tries=1 --spider http://localhost:8123 || exit 1 + environment: + - CLICKHOUSE_DB=${CH_DB:-clickhouse_test_db} + - CLICKHOUSE_USER=${CH_USER:-clickhouse_test_user} + - CLICKHOUSE_PASSWORD=${CH_PWD:-clickhouse_password} + volumes: + - ch_data:/var/lib/clickhouse + +volumes: + workspace: + ch_data: + redis-data: + redis_ur_data: + cube_metastore: diff --git a/docker/docker-compose-examples/analytics/setup/config/dev/clickhouse/clickhouse-issue-15638.xml b/docker/docker-compose-examples/analytics/setup/config/dev/clickhouse/clickhouse-issue-15638.xml new file mode 100644 index 000000000000..a77fac2669f0 --- /dev/null +++ b/docker/docker-compose-examples/analytics/setup/config/dev/clickhouse/clickhouse-issue-15638.xml @@ -0,0 +1,8 @@ + + + + 0 + 0 + + + diff --git a/docker/docker-compose-examples/analytics/setup/config/dev/cube/cube.js b/docker/docker-compose-examples/analytics/setup/config/dev/cube/cube.js new file mode 100644 index 000000000000..3bd1b3ca920c --- /dev/null +++ b/docker/docker-compose-examples/analytics/setup/config/dev/cube/cube.js @@ -0,0 +1,30 @@ +// cube.js configuration file +module.exports = { + /* + contextToAppId: ({ securityContext }) => + `CUBEJS_APP_${securityContext.customerId}`, + preAggregationsSchema: ({ securityContext }) => + `pre_aggregations_${securityContext.customerId}`, +*/ + + queryRewrite: (query, { securityContext }) => { + + + if (!securityContext) { + throw new Error('No valid token'); + } + + const tokenData = securityContext["https://dotcms.com/analytics"]; + + query.filters.push({ + member: 'Events.clusterId', + operator: 'equals', + values: [tokenData.clusterId], + }); + + + return query; + }, + + +}; \ No newline at end of file diff --git a/docker/docker-compose-examples/analytics/setup/config/dev/cube/schema/Events.js b/docker/docker-compose-examples/analytics/setup/config/dev/cube/schema/Events.js new file mode 100644 index 000000000000..9e0ecd25eb9b --- /dev/null +++ b/docker/docker-compose-examples/analytics/setup/config/dev/cube/schema/Events.js @@ -0,0 +1,151 @@ +cube(`Events`, { + sql: ` + WITH CountsAndLastURL AS (SELECT lookbackwindow, MAX(utc_time) AS maxDate + FROM events + GROUP BY lookbackwindow + ) + SELECT + E.experiment, + E.lookbackwindow, + E.variant, + E.runningid, + toDateTime(toStartOfDay(toTimeZone(toDateTime(utc_time), 'UTC'), 'UTC'), 'UTC') as day, + min(CASE WHEN (isexperimentpage = true AND event_type = 'pageview') THEN utc_time END) as firstExperimentPageVisit, + max(CASE WHEN (istargetpage = true AND event_type = 'pageview') THEN utc_time END) as lastTargetPageVisit, + firstExperimentPageVisit is not null as isSession, + COUNT(CASE WHEN event_type = 'pageview' THEN 1 ELSE 0 END) AS pageviews, + SUM(CASE WHEN (E.isexperimentpage = true AND C.maxDate = E.utc_time AND event_type = 'pageview') THEN 1 ELSE 0 END) as experimentPageLastVisited + FROM events E JOIN CountsAndLastURL C ON C.lookbackwindow = E.lookbackwindow + WHERE event_type = 'pageview' + GROUP BY experiment, runningid, lookbackwindow, variant, day + having isSession = 1 + order by day + `, + preAggregations: { + /*targetVisitedAfterAggregation: { + measures: [Events.totalSessions, Events.targetVisitedAfterSuccesses], + dimensions: [Events.experiment, Events.runningId, Events.variant], + timeDimension: Events.day, + granularity: `day`, + indexes: { + totalSessions_targetVisitedAfter_index: { + columns: [experiment, variant] + } + } + }, + bounceRateAggregation: { + measures: [Events.totalSessions, Events.bounceRateSuccesses], + dimensions: [Events.experiment, Events.variant], + timeDimension: Events.day, + granularity: `day`, + indexes: { + totalSessions_bounceRateSuccesses_index: { + columns: [totalSessions, bounceRateSuccesses] + } + } + }, + exitRateAggregation: { + measures: [Events.totalSessions, Events.exitRateSuccesses], + dimensions: [Events.experiment, Events.variant], + timeDimension: Events.day, + granularity: `day`, + indexes: { + totalSessions_exitRateSuccesses_index: { + columns: [totalSessions, exitRateSuccesses] + } + } + }*/ + }, + joins: {}, + measures: { + count: { + type: `count` + }, + totalSessions: { + type: `count_distinct`, + sql: `lookbackwindow` + }, + targetVisitedAfterSuccesses: { + type: `count_distinct`, + sql: `lookbackwindow`, + filters: [{ + sql: `firstExperimentPageVisit < lastTargetPageVisit` + }] + }, + bounceRateSuccesses: { + type: `count`, + sql: `lookbackwindow`, + filters: [{ + sql: `pageviews > 1` + }] + }, + exitRateSuccesses: { + type: `count`, + sql: `lookbackwindow`, + filters: [{ + sql: `experimentPageLastVisited == 0` + }] + }, + targetVisitedAfterConvertionRate: { + description: 'Convertion Rate', + format: `percent`, + type: 'number', + sql: `ROUND(${targetVisitedAfterSuccesses} * 100 / ${totalSessions}, 2)` + }, + bounceRateConvertionRate: { + description: 'Convertion Rate', + format: `percent`, + type: 'number', + sql: `ROUND(${bounceRateSuccesses} * 100 / ${totalSessions}, 2)` + }, + exitRateConvertionRate: { + description: 'Convertion Rate', + format: `percent`, + type: 'number', + sql: `ROUND(${exitRateSuccesses} * 100 / ${totalSessions}, 2)` + } + }, + dimensions: { + experiment: { + sql: `experiment`, + type: `string` + }, + runningId: { + sql: `runningid`, + type: `string` + }, + lookBackWindow: { + sql: `lookbackwindow`, + type: `string` + }, + variant: { + sql: `variant`, + type: `string` + }, + isExperimentSession: { + type: 'boolean', + sql: 'isSession' + }, + pageViewsTotal: { + type: 'number', + sql: 'pageviews' + }, + lastUrlVisited: { + type: 'string', + sql: 'lastUrlVisited' + }, + firstExperimentPageVisit: { + sql: `firstExperimentPageVisit`, + type: `time` + }, + lastTargetPageVisit: { + sql: `lastTargetPageVisit`, + type: `time` + }, + day: { + sql: `day`, + type: `time` + } + }, + dataSource: `default` +}); \ No newline at end of file diff --git a/docker/docker-compose-examples/analytics/setup/config/dev/jitsu/server/config/eventnative.yaml b/docker/docker-compose-examples/analytics/setup/config/dev/jitsu/server/config/eventnative.yaml new file mode 100644 index 000000000000..4407ca68bf0a --- /dev/null +++ b/docker/docker-compose-examples/analytics/setup/config/dev/jitsu/server/config/eventnative.yaml @@ -0,0 +1,102 @@ +server: + name: jitsu + port: '${env.SERVER_PORT|8001}' + disable_welcome_page: true + strict_auth_tokens: true + admin_token: '${env.CLUSTER_ADMIN_TOKEN|env.SERVER_ADMIN_TOKEN|demo___please_provide_value_in_production___}' + telemetry: + disabled: + usage: true + #telemetry: '${env.TELEMETRY_URL|}' + cache: + enabled: '${env.EVENTS_CACHE_ENABLED|true}' + events: + #default value. Amount of events which are saved per token or destination. + #If there are more events, old ones will be replaced with new ones. + size: 100 + #by default Jitsu applies rate limiting for not saving all events into the cache. + #Jitsu saves in cache ${size} events per ${time_window_sec}. Other events are skipped. + time_window_sec: 60 + #Every ${trim_interval_ms} value Jitsu will delete events from cache + #if size of the cache collection by token or destination is greater than ${size} + trim_interval_ms: 500 + #When Jitsu receives malformed event JSON, event will be cut to ${max_malformed_event_size_bytes} bytes (10KB) and saved to cache + max_malformed_event_size_bytes: 10000 + pool: + #number of goroutines which are process events cache + size: 10 + metrics: + relay: + disabled: '${env.JITSU_EXTENDED_TELEMETRY_DISABLED|false}' + deployment_id: '${env.JITSU_EXTENDED_TELEMETRY_DEPLOYMENT_ID|}' + +geo: + maxmind_path: '${env.MAX_MIND_PATH|}' + +configurator: + base_url: '${env.JITSU_CONFIGURATOR_URL|}' + admin_token: '${env.CLUSTER_ADMIN_TOKEN|env.CONFIGURATOR_ADMIN_TOKEN|demo___please_provide_value_in_production___}' + +geo_resolvers: '${env.GEO_RESOLVERS_URL|}' + + +sources: '${env.SOURCES_URL|}' + +system: '${env.SYSTEM_URL|}' + +notifications: + slack: + url: '${env.SLACK_NOTIFICATIONS_WEBHOOK|}' + +ui: + base_url: '${env.JITSU_UI_BASE_URL|}' + +users_recognition: + enabled: '${env.USER_RECOGNITION_ENABLED|false}' + anonymous_id_node: /user/anonymous_id + identification_nodes: + - /user/id + - /user/email + redis: + host: '${env.USER_RECOGNITION_REDIS_URL|}' + tls_skip_verify: '${env.TLS_SKIP_VERIFY|false}' + ttl_minutes: + anonymous_events: '${env.USER_RECOGNITION_TTL_MINUTES|10080}' + +meta: + storage: + redis: + host: '${env.REDIS_URL|}' + tls_skip_verify: '${env.TLS_SKIP_VERIFY|false}' + ttl_minutes: + anonymous_events: '${env.USER_RECOGNITION_TTL_MINUTES|10080}' + +events: + queue: + redis: + host: '${env.EVENTS_QUEUE_REDIS_URL|}' + tls_skip_verify: '${env.TLS_SKIP_VERIFY|false}' + +coordination: + type: redis + +sql_debug_log: + ddl: + enabled: '${env.SQL_DDL_LOG_ENABLED|true}' + queries: + enabled: '${env.SQL_QUERIES_LOG_ENABLED|false}' + +singer-bridge: + log: + enabled: '${env.SINGER_LOG_ENABLED|false}' + batch_size: '${env.SOURCES_SYNC_BATCH_SIZE|10000}' + +airbyte-bridge: + batch_size: '${env.SOURCES_SYNC_BATCH_SIZE|10000}' + +google-ads: + developer-token: '${env.GOOGLE_ADS_DEVELOPER_TOKEN|}' + +api_keys: '${env.API_KEYS_URL|}' + +destinations: '${env.DESTINATIONS_URL|}' diff --git a/docker/docker-compose-examples/analytics/setup/config/dev/keycloak/keycloak-keystore.jks b/docker/docker-compose-examples/analytics/setup/config/dev/keycloak/keycloak-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..6961a6b1d02030386c861968cf3ac3ae87699190 GIT binary patch literal 2228 zcmchY`9IW+7RTp1n~)L0WUQg5;+gqcCNzyvWGPD`CZxu`Z!^SWZDb-_wkLa1L`Zfa zyCIRSnAybP4&1rHVYAX`962M( z0GL)pF18%_IA;?w$vnEnNI)(B7D?doCrQ^n$;(iZPzHIe;r5nRY!FBCP?F2!%<7A@ zsw`P{V|hOZLI3`S^gEgp71g|3$9f`CWT%2VD#LRLs6Wv{tQS27#8n;QiYgx-aOe(J zu!6Hq-Y?}|;3~=#t!V7q1U4Jwh3fh`f#{O%K$l$~F;qB7VR0zLLZsjh!E;a4JfH8Y z#pb;KRyjK=rg?^cMR7#+bYat`PRjMrj%=E4M^7#l36%z|tqG^n_LWQ2W>EdwlV6stY1^(n&D; zJ}39A9^wG~k4VGA9TXcnLEWjSEr8{c*sIsmgiEW$S%OR2 z3QfZM{WI_`0H(o9Qzpiy<{OcTH_ z!LyH_OZUXQ>Z@yb=zHcQwJ)^^d;k6NXfR0JKejNxj=l+vaQ&FNc=Jkq^`r)~y=Lb` z!CjZoJxu6~*;1>9*4;j?^zLHum=C)uI$2D?j$(;CE{h%wT{{`S-LhNvCv$q!DK;rv9*f>4bDIJw1)u&$?Xy^x(Y zUBUd~%+9IzMZ2Sffp3GMYy81g@t5kbb{K_v(T<_OYZ zwjdpyZO=NvpFZbEOZO*Kl?_m zHOZN(_3CD?|7owO?08TqL$8P^?DVYb(moE!dED9p?0$mt>fD>2TN#bWqlunWxSz4b zjq4%vDAb!xKh11Dr+U-lQTULRh%O^OQF z>)w`VG*!Q+nE!6{cFfilRD>AZjkhwHq8+f}2AV3bnynaB4c7&U!J^ko*12ce*97|0 zCwSZ6i+h)K$I6%*e|OH@O2m8mh7-iq%xi*Km&ojMx*JZf|2%Vm>7QGkJJmQ2)$UWs z-o!RXiIUgV4Zy5j(>eLQ^A;&o7*Re}k*0W_TGu{0ZGs&;EhF!hiP3FI*orNo*vpA? z&g9k4L%4wG!e?4k5+;(5wccLO#tgxscS)xL!LmEOA95tQ+Hq)$ literal 0 HcmV?d00001 diff --git a/docker/docker-compose-examples/analytics/setup/config/dev/keycloak/test-realm.json b/docker/docker-compose-examples/analytics/setup/config/dev/keycloak/test-realm.json new file mode 100644 index 000000000000..e0ead2e837ce --- /dev/null +++ b/docker/docker-compose-examples/analytics/setup/config/dev/keycloak/test-realm.json @@ -0,0 +1,2300 @@ +{ + "id": "c2d84f46-24fd-4e64-b0a9-f0933b0efa9d", + "realm": "dotcms", + "notBefore": 0, + "defaultSignatureAlgorithm": "RS256", + "revokeRefreshToken": false, + "refreshTokenMaxReuse": 0, + "accessTokenLifespan": 300, + "accessTokenLifespanForImplicitFlow": 900, + "ssoSessionIdleTimeout": 1800, + "ssoSessionMaxLifespan": 36000, + "ssoSessionIdleTimeoutRememberMe": 0, + "ssoSessionMaxLifespanRememberMe": 0, + "offlineSessionIdleTimeout": 2592000, + "offlineSessionMaxLifespanEnabled": false, + "offlineSessionMaxLifespan": 5184000, + "clientSessionIdleTimeout": 0, + "clientSessionMaxLifespan": 0, + "clientOfflineSessionIdleTimeout": 0, + "clientOfflineSessionMaxLifespan": 0, + "accessCodeLifespan": 60, + "accessCodeLifespanUserAction": 300, + "accessCodeLifespanLogin": 1800, + "actionTokenGeneratedByAdminLifespan": 43200, + "actionTokenGeneratedByUserLifespan": 300, + "oauth2DeviceCodeLifespan": 600, + "oauth2DevicePollingInterval": 5, + "enabled": true, + "sslRequired": "external", + "registrationAllowed": false, + "registrationEmailAsUsername": false, + "rememberMe": false, + "verifyEmail": false, + "loginWithEmailAllowed": true, + "duplicateEmailsAllowed": false, + "resetPasswordAllowed": false, + "editUsernameAllowed": false, + "bruteForceProtected": false, + "permanentLockout": false, + "maxFailureWaitSeconds": 900, + "minimumQuickLoginWaitSeconds": 60, + "waitIncrementSeconds": 60, + "quickLoginCheckMilliSeconds": 1000, + "maxDeltaTimeSeconds": 43200, + "failureFactor": 30, + "roles": { + "realm": [ + { + "id": "5a71d573-601c-4770-8bd4-a19ce4a13ca9", + "name": "admin", + "composite": false, + "clientRole": false, + "containerId": "c2d84f46-24fd-4e64-b0a9-f0933b0efa9d", + "attributes": {} + }, + { + "id": "0d702c89-baa5-4a60-b818-5f73933cb9db", + "name": "default-roles-dotcms", + "description": "${role_default-roles}", + "composite": true, + "composites": { + "realm": [ + "offline_access", + "uma_authorization" + ], + "client": { + "account": [ + "view-profile", + "manage-account" + ] + } + }, + "clientRole": false, + "containerId": "c2d84f46-24fd-4e64-b0a9-f0933b0efa9d", + "attributes": {} + }, + { + "id": "9c89755d-7189-4aed-aeb3-6bc2471e7d9d", + "name": "uma_authorization", + "description": "${role_uma_authorization}", + "composite": false, + "clientRole": false, + "containerId": "c2d84f46-24fd-4e64-b0a9-f0933b0efa9d", + "attributes": {} + }, + { + "id": "3bf85699-f4bd-44a0-91b2-42f90cd7ebd6", + "name": "offline_access", + "description": "${role_offline-access}", + "composite": false, + "clientRole": false, + "containerId": "c2d84f46-24fd-4e64-b0a9-f0933b0efa9d", + "attributes": {} + }, + { + "id": "80009ebc-2cbb-4cdf-906a-6b3b58236273", + "name": "user", + "composite": false, + "clientRole": false, + "containerId": "c2d84f46-24fd-4e64-b0a9-f0933b0efa9d", + "attributes": {} + } + ], + "client": { + "realm-management": [ + { + "id": "34d74121-cdc1-4531-b952-a679e31d0cf5", + "name": "view-identity-providers", + "description": "${role_view-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "564847a9-1541-49bf-bc0f-720bc434fe16", + "name": "view-clients", + "description": "${role_view-clients}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-clients" + ] + } + }, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "77ae64e3-41af-48b4-abf4-6f90ad30ad5d", + "name": "impersonation", + "description": "${role_impersonation}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "95bb3765-32ef-4678-a99a-6914ee8e69e4", + "name": "manage-identity-providers", + "description": "${role_manage-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "d4753cbd-ec99-40a2-847a-c080f811445a", + "name": "query-groups", + "description": "${role_query-groups}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "ca627879-0c0f-4884-8f08-1616117bc0e1", + "name": "view-events", + "description": "${role_view-events}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "01c33522-cece-4d57-b633-869ce88b456e", + "name": "manage-clients", + "description": "${role_manage-clients}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "75d27407-ecae-4723-8964-4d1ad3a7f650", + "name": "manage-authorization", + "description": "${role_manage-authorization}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "218995b5-0bc5-4256-9a98-0f69c37e7100", + "name": "view-authorization", + "description": "${role_view-authorization}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "c6eb238e-8fb8-4932-84ed-a67559ac80ce", + "name": "query-users", + "description": "${role_query-users}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "186948f6-b9a2-47fc-9838-8602868186a8", + "name": "view-realm", + "description": "${role_view-realm}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "4212b14b-6bb0-4416-a496-f5eb2e136d78", + "name": "query-clients", + "description": "${role_query-clients}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "9fa7e573-3e8c-4943-8b12-0fa0e7ba4e28", + "name": "manage-events", + "description": "${role_manage-events}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "ad4d5230-b2d1-4e69-b96a-e151338191a0", + "name": "manage-users", + "description": "${role_manage-users}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "7c49dc68-11d1-4ae9-9603-49ac5037656b", + "name": "view-users", + "description": "${role_view-users}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-groups", + "query-users" + ] + } + }, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "eb319200-7657-48e1-8adc-86d2131783eb", + "name": "realm-admin", + "description": "${role_realm-admin}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "view-identity-providers", + "view-clients", + "impersonation", + "manage-identity-providers", + "view-events", + "query-groups", + "manage-clients", + "view-authorization", + "manage-authorization", + "query-users", + "view-realm", + "query-clients", + "manage-events", + "view-users", + "manage-users", + "manage-realm", + "create-client", + "query-realms" + ] + } + }, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "7a8ca77b-2971-4981-b882-6a5eccf298ed", + "name": "create-client", + "description": "${role_create-client}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "712c071c-f458-42de-bf6c-558cafc73404", + "name": "manage-realm", + "description": "${role_manage-realm}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + }, + { + "id": "dda4ed0f-2b4d-4a11-94c5-2770b9550281", + "name": "query-realms", + "description": "${role_query-realms}", + "composite": false, + "clientRole": true, + "containerId": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "attributes": {} + } + ], + "analytics-customer-customer1": [], + "security-admin-console": [], + "admin-cli": [], + "account-console": [], + "broker": [ + { + "id": "f08e8acd-9f32-4cbb-8bb4-b8f64b11a422", + "name": "read-token", + "description": "${role_read-token}", + "composite": false, + "clientRole": true, + "containerId": "f50f5154-7bfa-44d7-a125-4717dc69fc77", + "attributes": {} + } + ], + "account": [ + { + "id": "33c70297-8cae-4ea1-bbc5-05f3bb7fddcf", + "name": "delete-account", + "description": "${role_delete-account}", + "composite": false, + "clientRole": true, + "containerId": "c87b98ca-7461-48b1-aad7-35e41d5b579b", + "attributes": {} + }, + { + "id": "14c098fc-3788-4a90-9dd2-f208717ac000", + "name": "view-applications", + "description": "${role_view-applications}", + "composite": false, + "clientRole": true, + "containerId": "c87b98ca-7461-48b1-aad7-35e41d5b579b", + "attributes": {} + }, + { + "id": "5b7f8a85-41c9-4815-9ca0-011e15f44e66", + "name": "manage-account-links", + "description": "${role_manage-account-links}", + "composite": false, + "clientRole": true, + "containerId": "c87b98ca-7461-48b1-aad7-35e41d5b579b", + "attributes": {} + }, + { + "id": "94c21df9-44b5-4565-a694-0432eb03b8c1", + "name": "view-profile", + "description": "${role_view-profile}", + "composite": false, + "clientRole": true, + "containerId": "c87b98ca-7461-48b1-aad7-35e41d5b579b", + "attributes": {} + }, + { + "id": "6d169d3c-ecfc-412f-a013-c6d45fd04abc", + "name": "view-consent", + "description": "${role_view-consent}", + "composite": false, + "clientRole": true, + "containerId": "c87b98ca-7461-48b1-aad7-35e41d5b579b", + "attributes": {} + }, + { + "id": "5fcca1e6-03bb-4bb0-bf30-d2ba0e8fb2d5", + "name": "manage-account", + "description": "${role_manage-account}", + "composite": true, + "composites": { + "client": { + "account": [ + "manage-account-links" + ] + } + }, + "clientRole": true, + "containerId": "c87b98ca-7461-48b1-aad7-35e41d5b579b", + "attributes": {} + }, + { + "id": "835ebb45-9c3a-4d60-bb76-6faedac10291", + "name": "manage-consent", + "description": "${role_manage-consent}", + "composite": true, + "composites": { + "client": { + "account": [ + "view-consent" + ] + } + }, + "clientRole": true, + "containerId": "c87b98ca-7461-48b1-aad7-35e41d5b579b", + "attributes": {} + } + ] + } + }, + "groups": [], + "defaultRole": { + "id": "0d702c89-baa5-4a60-b818-5f73933cb9db", + "name": "default-roles-dotcms", + "description": "${role_default-roles}", + "composite": true, + "clientRole": false, + "containerId": "c2d84f46-24fd-4e64-b0a9-f0933b0efa9d" + }, + "requiredCredentials": [ + "password" + ], + "otpPolicyType": "totp", + "otpPolicyAlgorithm": "HmacSHA1", + "otpPolicyInitialCounter": 0, + "otpPolicyDigits": 6, + "otpPolicyLookAheadWindow": 1, + "otpPolicyPeriod": 30, + "otpSupportedApplications": [ + "FreeOTP", + "Google Authenticator" + ], + "webAuthnPolicyRpEntityName": "keycloak", + "webAuthnPolicySignatureAlgorithms": [ + "ES256" + ], + "webAuthnPolicyRpId": "", + "webAuthnPolicyAttestationConveyancePreference": "not specified", + "webAuthnPolicyAuthenticatorAttachment": "not specified", + "webAuthnPolicyRequireResidentKey": "not specified", + "webAuthnPolicyUserVerificationRequirement": "not specified", + "webAuthnPolicyCreateTimeout": 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyAcceptableAaguids": [], + "webAuthnPolicyPasswordlessRpEntityName": "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms": [ + "ES256" + ], + "webAuthnPolicyPasswordlessRpId": "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", + "webAuthnPolicyPasswordlessCreateTimeout": 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyPasswordlessAcceptableAaguids": [], + "users": [ + { + "id": "6440a66e-b9da-4818-a8e5-7c443b6ce86a", + "createdTimestamp": 1663193849309, + "username": "service-account-analytics-customer-customer1", + "enabled": true, + "totp": false, + "emailVerified": false, + "serviceAccountClientId": "analytics-customer-customer1", + "disableableCredentialTypes": [], + "requiredActions": [], + "realmRoles": [ + "default-roles-dotcms" + ], + "notBefore": 0, + "groups": [] + } + ], + "scopeMappings": [ + { + "clientScope": "offline_access", + "roles": [ + "offline_access" + ] + } + ], + "clientScopeMappings": { + "account": [ + { + "client": "account-console", + "roles": [ + "manage-account" + ] + } + ] + }, + "clients": [ + { + "id": "c87b98ca-7461-48b1-aad7-35e41d5b579b", + "clientId": "account", + "name": "${client_account}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/dotcms/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/realms/dotcms/account/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "acr", + "profile", + "roles", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "98fc4fcf-ffc5-43c5-b940-781ddaef1c5e", + "clientId": "account-console", + "name": "${client_account-console}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/dotcms/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/realms/dotcms/account/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "d3ab518c-e2c8-47a2-a31b-258c895d1ed8", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + } + ], + "defaultClientScopes": [ + "web-origins", + "acr", + "profile", + "roles", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "5a5faecf-8284-4f05-8dfb-446f792bed60", + "clientId": "admin-cli", + "name": "${client_admin-cli}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "acr", + "profile", + "roles", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "a123e641-7747-4feb-a842-4abb90e7377d", + "clientId": "analytics-customer-customer1", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "testsecret", + "redirectUris": [ + "*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": true, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ + { + "id": "f5279aef-8eca-405e-a0c8-c697a5f64847", + "name": "Client ID", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientId", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientId", + "jsonType.label": "String" + } + }, + { + "id": "8212d3b3-f99d-49a8-8d7c-36b00898d4dd", + "name": "dotcms-customer1-claim", + "protocol": "openid-connect", + "protocolMapper": "oidc-hardcoded-claim-mapper", + "consentRequired": false, + "config": { + "claim.value": "{\"customerId\":\"customer1\",\"clusterId\":\"cluster1\"}", + "userinfo.token.claim": "false", + "id.token.claim": "false", + "access.token.claim": "true", + "claim.name": "https://dotcms\\.com/analytics", + "jsonType.label": "JSON", + "access.tokenResponse.claim": "false" + } + }, + { + "id": "2c8d16d9-5083-4b56-b056-04415ab5273d", + "name": "Client Host", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientHost", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientHost", + "jsonType.label": "String" + } + }, + { + "id": "d3ba5236-0a6d-4776-925a-b144684c86b8", + "name": "dotcms-customer1-roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-hardcoded-claim-mapper", + "consentRequired": false, + "config": { + "claim.value": "[\"customer\"]", + "userinfo.token.claim": "false", + "id.token.claim": "false", + "access.token.claim": "true", + "claim.name": "https://dotcms\\.com/analytics/roles", + "jsonType.label": "JSON", + "access.tokenResponse.claim": "false" + } + }, + { + "id": "c36c0942-ec8d-475b-8864-8e29a09b0500", + "name": "Client IP Address", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientAddress", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientAddress", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": [ + "dotcms-analytics" + ], + "optionalClientScopes": [] + }, + { + "id": "f50f5154-7bfa-44d7-a125-4717dc69fc77", + "clientId": "broker", + "name": "${client_broker}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "acr", + "profile", + "roles", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "4a5e7947-43b8-4215-82e0-d8b46e838822", + "clientId": "realm-management", + "name": "${client_realm-management}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "acr", + "profile", + "roles", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "5e055154-21ac-4397-b333-8a5cc1f081b6", + "clientId": "security-admin-console", + "name": "${client_security-admin-console}", + "rootUrl": "${authAdminUrl}", + "baseUrl": "/admin/dotcms/console/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/admin/dotcms/console/*" + ], + "webOrigins": [ + "+" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "a52f02e8-5b7f-4222-bfba-0e76bb824776", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": [ + "web-origins", + "acr", + "profile", + "roles", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + } + ], + "clientScopes": [ + { + "id": "1d37b12c-15c7-4a55-ba24-4cd9901e0da3", + "name": "microprofile-jwt", + "description": "Microprofile - JWT built-in scope", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "bbab86e4-c9ee-48c3-b815-513aa3d1991e", + "name": "groups", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "multivalued": "true", + "userinfo.token.claim": "true", + "user.attribute": "foo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "groups", + "jsonType.label": "String" + } + }, + { + "id": "c2eb6e27-0bfc-4bfc-bcff-35654a09c259", + "name": "upn", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "upn", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "2aeb4fa0-e533-4092-a83a-71f00e44efe2", + "name": "profile", + "description": "OpenID Connect built-in scope: profile", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${profileScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "b0279360-a7a6-4b08-b051-9e7c16db8887", + "name": "updated at", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "updatedAt", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "updated_at", + "jsonType.label": "long" + } + }, + { + "id": "4eb5a55b-47d8-4808-aa82-bfa764b54b35", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "95e405cc-b9c7-42c3-a693-75cb61ac667e", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + }, + { + "id": "5c0411c9-fbeb-46b5-8c2f-d08aeabf28cd", + "name": "middle name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "middleName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "middle_name", + "jsonType.label": "String" + } + }, + { + "id": "34d651bf-f031-4a72-b3f6-d5b35f90b335", + "name": "nickname", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "nickname", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "nickname", + "jsonType.label": "String" + } + }, + { + "id": "c0462a4d-90e6-4c6a-b399-0d1298f0528d", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + }, + { + "id": "c5a706b4-5eea-4899-a213-40c5ef0061bc", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "0acde712-90a2-47dd-8138-67e626ec43f6", + "name": "zoneinfo", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "zoneinfo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "zoneinfo", + "jsonType.label": "String" + } + }, + { + "id": "7eecaccf-d246-4ed4-b8e0-b480e33f9d8a", + "name": "birthdate", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "birthdate", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "birthdate", + "jsonType.label": "String" + } + }, + { + "id": "1f54e46c-799f-435f-bb21-d2b54400726a", + "name": "website", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "website", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "website", + "jsonType.label": "String" + } + }, + { + "id": "c551b600-6a07-44c4-9ce5-c753e9aca6f6", + "name": "profile", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "profile", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "profile", + "jsonType.label": "String" + } + }, + { + "id": "f28bbf39-5e5f-4288-acdd-7e6eace37c94", + "name": "picture", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "picture", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "picture", + "jsonType.label": "String" + } + }, + { + "id": "f1ee2aaa-a3c5-4354-a939-669115d67693", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": false, + "config": { + "id.token.claim": "true", + "access.token.claim": "true", + "userinfo.token.claim": "true" + } + }, + { + "id": "3cd9d868-b85b-4501-8b05-ca890bcb926d", + "name": "gender", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "gender", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "gender", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "7ad24138-39d9-4934-8957-2b00774654d8", + "name": "phone", + "description": "OpenID Connect built-in scope: phone", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${phoneScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "66fd4328-1e1c-47ef-a7f8-e091d893b791", + "name": "phone number verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "phoneNumberVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number_verified", + "jsonType.label": "boolean" + } + }, + { + "id": "e3ed0390-af13-4dfb-a471-a9d0edce8fa2", + "name": "phone number", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "phoneNumber", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "b121e238-3531-4279-aa1f-d7f6d95b298f", + "name": "acr", + "description": "OpenID Connect scope for add acr (authentication context class reference) to the token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "b79638f0-136f-4857-97f2-71ea87f4eaa3", + "name": "acr loa level", + "protocol": "openid-connect", + "protocolMapper": "oidc-acr-mapper", + "consentRequired": false, + "config": { + "id.token.claim": "true", + "access.token.claim": "true", + "userinfo.token.claim": "true" + } + } + ] + }, + { + "id": "2c830d64-f4ca-49f4-94a9-0bd672f6d4cb", + "name": "roles", + "description": "OpenID Connect scope for add user roles to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "true", + "consent.screen.text": "${rolesScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "c6a49ed9-72a2-4324-af1b-600249ff85d7", + "name": "realm roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "realm_access.roles", + "jsonType.label": "String", + "multivalued": "true" + } + }, + { + "id": "707deecd-86db-4672-be56-19060de01964", + "name": "client roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "consentRequired": false, + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "resource_access.${client_id}.roles", + "jsonType.label": "String", + "multivalued": "true" + } + }, + { + "id": "5f81a25c-d313-40e0-9766-4238738964a4", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + } + ] + }, + { + "id": "f28cd780-61fc-41ba-969d-7901936ef24b", + "name": "email", + "description": "OpenID Connect built-in scope: email", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${emailScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "bc158984-318a-4759-b394-46972c7159da", + "name": "email verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "emailVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email_verified", + "jsonType.label": "boolean" + } + }, + { + "id": "2060a90f-f79e-4466-8003-b4af9d462123", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "a7b0a492-c971-4b18-8cf5-9ee423bc1809", + "name": "address", + "description": "OpenID Connect built-in scope: address", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${addressScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "d3d277e7-d797-4aa7-81ea-fb20eb0b7452", + "name": "address", + "protocol": "openid-connect", + "protocolMapper": "oidc-address-mapper", + "consentRequired": false, + "config": { + "user.attribute.formatted": "formatted", + "user.attribute.country": "country", + "user.attribute.postal_code": "postal_code", + "userinfo.token.claim": "true", + "user.attribute.street": "street", + "id.token.claim": "true", + "user.attribute.region": "region", + "access.token.claim": "true", + "user.attribute.locality": "locality" + } + } + ] + }, + { + "id": "e4151403-d94f-4393-a843-eaffd643ec49", + "name": "dotcms-analytics", + "description": "dotcms-analytics", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "5f37d200-476c-453d-9b9c-a899b943a719", + "name": "api-dotcms-analytics-audience", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-mapper", + "consentRequired": false, + "config": { + "id.token.claim": "false", + "access.token.claim": "true", + "included.custom.audience": "api-dotcms-analytics-audience", + "userinfo.token.claim": "false" + } + } + ] + }, + { + "id": "d83e05ab-746e-4bfb-bebe-dcd0b3b1f357", + "name": "web-origins", + "description": "OpenID Connect scope for add allowed web origins to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false", + "consent.screen.text": "" + }, + "protocolMappers": [ + { + "id": "f9aff61f-8671-4342-8bcc-ebc652f31e55", + "name": "allowed web origins", + "protocol": "openid-connect", + "protocolMapper": "oidc-allowed-origins-mapper", + "consentRequired": false, + "config": {} + } + ] + }, + { + "id": "757af9b7-5e38-43a2-bd01-106c67ce2dd8", + "name": "offline_access", + "description": "OpenID Connect built-in scope: offline_access", + "protocol": "openid-connect", + "attributes": { + "consent.screen.text": "${offlineAccessScopeConsentText}", + "display.on.consent.screen": "true" + } + }, + { + "id": "f432ddea-d3f4-4f9c-a773-376204dfcc99", + "name": "role_list", + "description": "SAML role list", + "protocol": "saml", + "attributes": { + "consent.screen.text": "${samlRoleListScopeConsentText}", + "display.on.consent.screen": "true" + }, + "protocolMappers": [ + { + "id": "fc9312d3-ef60-4c1c-bcbd-712cc68da78b", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + } + ] + } + ], + "defaultDefaultClientScopes": [ + "profile", + "roles", + "acr", + "web-origins", + "email", + "role_list" + ], + "defaultOptionalClientScopes": [ + "microprofile-jwt", + "offline_access", + "phone", + "address" + ], + "browserSecurityHeaders": { + "contentSecurityPolicyReportOnly": "", + "xContentTypeOptions": "nosniff", + "xRobotsTag": "none", + "xFrameOptions": "SAMEORIGIN", + "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "xXSSProtection": "1; mode=block", + "strictTransportSecurity": "max-age=31536000; includeSubDomains" + }, + "smtpServer": {}, + "eventsEnabled": false, + "eventsListeners": [ + "jboss-logging" + ], + "enabledEventTypes": [], + "adminEventsEnabled": false, + "adminEventsDetailsEnabled": false, + "identityProviders": [], + "identityProviderMappers": [], + "components": { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ + { + "id": "24c97025-f0c0-442d-bb57-7278a139fdd3", + "name": "Trusted Hosts", + "providerId": "trusted-hosts", + "subType": "anonymous", + "subComponents": {}, + "config": { + "host-sending-registration-request-must-match": [ + "true" + ], + "client-uris-must-match": [ + "true" + ] + } + }, + { + "id": "ffee4d74-a29d-49de-ae1a-59f3bd618b82", + "name": "Max Clients Limit", + "providerId": "max-clients", + "subType": "anonymous", + "subComponents": {}, + "config": { + "max-clients": [ + "200" + ] + } + }, + { + "id": "86a7d9dc-cbe6-46d0-9467-537d74367c41", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "4ef53676-e3a0-4ac9-8996-480871f2e1dc", + "name": "Consent Required", + "providerId": "consent-required", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "c7a16421-2a37-4a82-af86-bf4862f58284", + "name": "Full Scope Disabled", + "providerId": "scope", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "dfc740b3-bc84-49b4-be55-c120debabc2d", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "saml-role-list-mapper", + "oidc-full-name-mapper", + "oidc-address-mapper", + "oidc-sha256-pairwise-sub-mapper", + "oidc-usermodel-attribute-mapper", + "saml-user-property-mapper", + "oidc-usermodel-property-mapper", + "saml-user-attribute-mapper" + ] + } + }, + { + "id": "844ebf9f-2fcb-46c2-bd26-6a9d7ccd46fb", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "728d6f54-e5af-46ae-9e66-f1c48b678ad6", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "oidc-usermodel-property-mapper", + "saml-user-attribute-mapper", + "oidc-full-name-mapper", + "saml-user-property-mapper", + "oidc-usermodel-attribute-mapper", + "saml-role-list-mapper", + "oidc-sha256-pairwise-sub-mapper", + "oidc-address-mapper" + ] + } + } + ], + "org.keycloak.keys.KeyProvider": [ + { + "id": "4b965f2f-81f0-45b7-b41b-38442966280e", + "name": "rsa-enc-generated", + "providerId": "rsa-enc-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "RSA-OAEP" + ] + } + }, + { + "id": "3f0f46d2-60db-4ee2-afe2-e948ce4eb32f", + "name": "hmac-generated", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "HS256" + ] + } + }, + { + "id": "f30e4465-72cc-45c5-bbf5-9339c9f0acd0", + "name": "rsa-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "d3250f0f-f995-498e-ab86-73aa64832fef", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + } + ] + }, + "internationalizationEnabled": false, + "supportedLocales": [], + "authenticationFlows": [ + { + "id": "e7f2e461-f9ad-45d8-bb11-85b8ca4dc98e", + "alias": "Account verification options", + "description": "Method with which to verity the existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-email-verification", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "Verify Existing Account by Re-authentication", + "userSetupAllowed": false + } + ] + }, + { + "id": "4eb6626c-4cdb-47f8-9bf4-119b5798c42c", + "alias": "Authentication Options", + "description": "Authentication options.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "basic-auth", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "basic-auth-otp", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "auth-spnego", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 30, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "2d8c1e79-5b37-48ad-9430-61b121df7a54", + "alias": "Browser - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "43b5ae13-2859-4e29-90b2-a12fa14f5880", + "alias": "Direct Grant - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "direct-grant-validate-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "999fb0c5-8a20-4e4a-9d76-690255ccba4b", + "alias": "First broker login - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "1ee2a128-c3ec-4706-bf55-553475bb7b2e", + "alias": "Handle Existing Account", + "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-confirm-link", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "Account verification options", + "userSetupAllowed": false + } + ] + }, + { + "id": "ff5716a9-6728-4c1e-8f2a-ded918a47ee2", + "alias": "Reset - Conditional OTP", + "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "reset-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "3b16b201-b663-41b4-997c-a4b1e1bb06fe", + "alias": "User creation or linking", + "description": "Flow for the existing/non-existing user alternatives", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "create unique user config", + "authenticator": "idp-create-user-if-unique", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "Handle Existing Account", + "userSetupAllowed": false + } + ] + }, + { + "id": "944849f1-b670-47e9-bdf5-6345759795f5", + "alias": "Verify Existing Account by Re-authentication", + "description": "Reauthentication of existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-username-password-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "First broker login - Conditional OTP", + "userSetupAllowed": false + } + ] + }, + { + "id": "744664da-4702-4f0b-ba4f-fd4419a540ac", + "alias": "browser", + "description": "browser based authentication", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-cookie", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "auth-spnego", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "identity-provider-redirector", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 25, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 30, + "autheticatorFlow": true, + "flowAlias": "forms", + "userSetupAllowed": false + } + ] + }, + { + "id": "56bfba5f-995b-420e-96cf-b0b841cc9d51", + "alias": "clients", + "description": "Base authentication for clients", + "providerId": "client-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "client-secret", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "client-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "client-secret-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 30, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "client-x509", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 40, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "64d644f6-5c37-435e-a5b6-34f4b30729e3", + "alias": "direct grant", + "description": "OpenID Connect Resource Owner Grant", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "direct-grant-validate-username", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "direct-grant-validate-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 30, + "autheticatorFlow": true, + "flowAlias": "Direct Grant - Conditional OTP", + "userSetupAllowed": false + } + ] + }, + { + "id": "28fb8933-c1b3-496b-9c5b-2deb5d627e4a", + "alias": "docker auth", + "description": "Used by Docker clients to authenticate against the IDP", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "docker-http-basic-authenticator", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "8eb12082-1cdc-47b0-8d8e-150832f5091b", + "alias": "first broker login", + "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "review profile config", + "authenticator": "idp-review-profile", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "User creation or linking", + "userSetupAllowed": false + } + ] + }, + { + "id": "2a0fa96c-4c05-4973-8f2e-44e2c5939ce5", + "alias": "forms", + "description": "Username, password, otp and other auth forms.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-username-password-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "Browser - Conditional OTP", + "userSetupAllowed": false + } + ] + }, + { + "id": "b25e2a42-6b99-43eb-8630-eaa22d86393b", + "alias": "http challenge", + "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "no-cookie-redirect", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "Authentication Options", + "userSetupAllowed": false + } + ] + }, + { + "id": "9758f4a2-c995-4113-9e0c-ac07b4aae4b4", + "alias": "registration", + "description": "registration flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-page-form", + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": true, + "flowAlias": "registration form", + "userSetupAllowed": false + } + ] + }, + { + "id": "683e6b13-fd26-48ea-a427-0cb22a33f29d", + "alias": "registration form", + "description": "registration form", + "providerId": "form-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-user-creation", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "registration-profile-action", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 40, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "registration-password-action", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 50, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "registration-recaptcha-action", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 60, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "4ad9683f-7e97-4ea6-902a-c3bb0af53f81", + "alias": "reset credentials", + "description": "Reset credentials for a user if they forgot their password or something", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "reset-credentials-choose-user", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "reset-credential-email", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "reset-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 30, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 40, + "autheticatorFlow": true, + "flowAlias": "Reset - Conditional OTP", + "userSetupAllowed": false + } + ] + }, + { + "id": "6cb879f1-c45e-42c0-b0c3-9a1bec24ed72", + "alias": "saml ecp", + "description": "SAML ECP Profile Authentication Flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "http-basic-authenticator", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + } + ], + "authenticatorConfig": [ + { + "id": "502a8dff-26a3-4564-ad27-f3cec1d72932", + "alias": "create unique user config", + "config": { + "require.password.update.after.registration": "false" + } + }, + { + "id": "92447eb8-7e2f-4e83-aec0-a1c461cf1ee8", + "alias": "review profile config", + "config": { + "update.profile.on.first.login": "missing" + } + } + ], + "requiredActions": [ + { + "alias": "CONFIGURE_TOTP", + "name": "Configure OTP", + "providerId": "CONFIGURE_TOTP", + "enabled": true, + "defaultAction": false, + "priority": 10, + "config": {} + }, + { + "alias": "terms_and_conditions", + "name": "Terms and Conditions", + "providerId": "terms_and_conditions", + "enabled": false, + "defaultAction": false, + "priority": 20, + "config": {} + }, + { + "alias": "UPDATE_PASSWORD", + "name": "Update Password", + "providerId": "UPDATE_PASSWORD", + "enabled": true, + "defaultAction": false, + "priority": 30, + "config": {} + }, + { + "alias": "UPDATE_PROFILE", + "name": "Update Profile", + "providerId": "UPDATE_PROFILE", + "enabled": true, + "defaultAction": false, + "priority": 40, + "config": {} + }, + { + "alias": "VERIFY_EMAIL", + "name": "Verify Email", + "providerId": "VERIFY_EMAIL", + "enabled": true, + "defaultAction": false, + "priority": 50, + "config": {} + }, + { + "alias": "delete_account", + "name": "Delete Account", + "providerId": "delete_account", + "enabled": false, + "defaultAction": false, + "priority": 60, + "config": {} + }, + { + "alias": "update_user_locale", + "name": "Update User Locale", + "providerId": "update_user_locale", + "enabled": true, + "defaultAction": false, + "priority": 1000, + "config": {} + } + ], + "browserFlow": "browser", + "registrationFlow": "registration", + "directGrantFlow": "direct grant", + "resetCredentialsFlow": "reset credentials", + "clientAuthenticationFlow": "clients", + "dockerAuthenticationFlow": "docker auth", + "attributes": { + "cibaBackchannelTokenDeliveryMode": "poll", + "cibaExpiresIn": "120", + "cibaAuthRequestedUserHint": "login_hint", + "oauth2DeviceCodeLifespan": "600", + "clientOfflineSessionMaxLifespan": "0", + "oauth2DevicePollingInterval": "5", + "clientSessionIdleTimeout": "0", + "parRequestUriLifespan": "60", + "clientSessionMaxLifespan": "0", + "clientOfflineSessionIdleTimeout": "0", + "cibaInterval": "5" + }, + "keycloakVersion": "18.0.2", + "userManagedAccessAllowed": false, + "clientProfiles": { + "profiles": [] + }, + "clientPolicies": { + "policies": [] + } +} \ No newline at end of file diff --git a/docker/docker-compose-examples/analytics/setup/db/mssql/entrypoint.sh b/docker/docker-compose-examples/analytics/setup/db/mssql/entrypoint.sh new file mode 100644 index 000000000000..fb33f75de424 --- /dev/null +++ b/docker/docker-compose-examples/analytics/setup/db/mssql/entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/bash +wait_time=15s + +# wait for SQL Server to come up +echo "" +echo "---" +echo importing data will start in $wait_time... +sleep $wait_time + +echo "" +echo "---" +echo importing data... + +# run the init script to create the DB and the tables in /table +/opt/mssql-tools/bin/sqlcmd -S 0.0.0.0 -U sa -P ${MSSQL_SA_PASSWORD} -i ./init-scripts/init.sql + +echo data imported... \ No newline at end of file diff --git a/docker/docker-compose-examples/analytics/setup/db/mssql/init-scripts/init.sql b/docker/docker-compose-examples/analytics/setup/db/mssql/init-scripts/init.sql new file mode 100644 index 000000000000..a0607d491f4f --- /dev/null +++ b/docker/docker-compose-examples/analytics/setup/db/mssql/init-scripts/init.sql @@ -0,0 +1,7 @@ +CREATE DATABASE dotcms; + +ALTER DATABASE dotcms SET READ_COMMITTED_SNAPSHOT ON; +GO + +ALTER DATABASE dotcms SET ALLOW_SNAPSHOT_ISOLATION ON; +GO \ No newline at end of file diff --git a/docker/docker-compose-examples/analytics/setup/db/postgres/init-scripts/init-config.sh b/docker/docker-compose-examples/analytics/setup/db/postgres/init-scripts/init-config.sh new file mode 100644 index 000000000000..97e0cd6f80aa --- /dev/null +++ b/docker/docker-compose-examples/analytics/setup/db/postgres/init-scripts/init-config.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +echo "Detected MAX_LOCKS_PER_TRANSACTION: '${MAX_LOCKS_PER_TRANSACTION}'" +max_locks=$(echo -e "${MAX_LOCKS_PER_TRANSACTION}" | tr -d '[:space:]') + +if [[ "${max_locks}" != '' ]]; then + sed -i "s,^#max_locks_per_transaction =.*$,max_locks_per_transaction = ${max_locks},g" /var/lib/postgresql/data/postgresql.conf \ + cat /var/lib/postgresql/data/postgresql.conf | grep 'max_locks_per_transaction' +fi diff --git a/docker/docker-compose-examples/analytics/setup/db/postgres/init-scripts/init.sql b/docker/docker-compose-examples/analytics/setup/db/postgres/init-scripts/init.sql new file mode 100644 index 000000000000..3c939294d620 --- /dev/null +++ b/docker/docker-compose-examples/analytics/setup/db/postgres/init-scripts/init.sql @@ -0,0 +1 @@ +-- CREATE LANGUAGE plpgsql; diff --git a/docker/docker-compose-examples/cluster-mode/README.md b/docker/docker-compose-examples/cluster-mode/README.md new file mode 100644 index 000000000000..5f608a3bec41 --- /dev/null +++ b/docker/docker-compose-examples/cluster-mode/README.md @@ -0,0 +1,54 @@ +# Dotcms Cluster Mode + +Cluster with 2 dotCMS instances running on ports 8080 and 8081 respectively. Database: postgres + +## Usage + +#### Environment setup + + +1) A local path to license pack must be set here: + +``` +- {license_local_path}/license.zip:/data/shared/assets/license.zip +``` + +The license pack must contain at least two licenses (one for each node in the cluster) + + +2) A local path to access data in the instance can be set uncommenting this line: + +``` +#- {local_data_path}:/data/shared +``` + +3) A custom starter can be set through this line (uncomment and change the starter url accordingly): + +``` +#"CUSTOM_STARTER_URL": 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20210920/starter-20210920.zip' +``` + +#### Deploying nodes: + +```bash +docker-compose -f docker-compose-node-1.yml up + +``` + +Once the node 1 is running, deploy node 2: +```bash +docker-compose -f docker-compose-node-2.yml up + +``` + + +#### Undeploying nodes: + +```bash +docker-compose -f docker-compose-node-2.yml down +docker-compose -f docker-compose-node-1.yml down +``` + +**Important note:** `ctrl+c` does not destroy instances + + diff --git a/docker/docker-compose-examples/cluster-mode/docker-compose-node-1.yml b/docker/docker-compose-examples/cluster-mode/docker-compose-node-1.yml new file mode 100644 index 000000000000..4148567bb0cd --- /dev/null +++ b/docker/docker-compose-examples/cluster-mode/docker-compose-node-1.yml @@ -0,0 +1,74 @@ +version: '3.5' + +networks: + db_net: + opensearch-net: + +volumes: + cms-shared: + dbdata: + opensearch-data: + +services: + opensearch: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9200:9200 + - 9600:9600 + volumes: + - opensearch-data:/usr/share/opensearch/data + networks: + - opensearch-net + + dotcms-node-1: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-production' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + depends_on: + - opensearch + - db + volumes: + #- {local_data_path}:/data/shared + - {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net + - opensearch-net + ports: + - "8082:8082" + - "8443:8443" + + db: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata:/var/lib/postgresql/data + networks: + - db_net + diff --git a/docker/docker-compose-examples/cluster-mode/docker-compose-node-2.yml b/docker/docker-compose-examples/cluster-mode/docker-compose-node-2.yml new file mode 100644 index 000000000000..5271c3ecc0a7 --- /dev/null +++ b/docker/docker-compose-examples/cluster-mode/docker-compose-node-2.yml @@ -0,0 +1,35 @@ +version: '3.5' + +networks: + cluster-mode_db_net: + external: true + cluster-mode_opensearch-net: + external: true + +volumes: + cms-shared: + +services: + dotcms-node-2: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-production' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + volumes: + #- {local_data_path}:/data/shared + - {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - cluster-mode_db_net + - cluster-mode_opensearch-net + ports: + - "8081:8082" + - "8444:8443" diff --git a/docker/docker-compose-examples/push-publish/README.md b/docker/docker-compose-examples/push-publish/README.md new file mode 100644 index 000000000000..1ae8639d878c --- /dev/null +++ b/docker/docker-compose-examples/push-publish/README.md @@ -0,0 +1,48 @@ +# Dotcms Push Publish + +Push publish environment where the sender runs on port 8080 and the receiver on 8081. Database: postgres. + +**Important note:** For the endpoint configuration, the local IP address must be used instead of `localhost` or `127.0.0.1` + +## Usage + +#### Environment setup + + +1) A local path to license pack must be set here: + +``` +- {license_local_path}/license.zip:/data/shared/assets/license.zip +``` + +The license pack must contain at least two licenses (one for each node in the cluster) + + +2) A local path to access data in the instance can be set uncommenting this line: + +``` +#- {local_data_path}:/data/shared +``` + +3) A custom starter can be set through this line (uncomment and change the starter url accordingly): + +``` +#"CUSTOM_STARTER_URL": 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20210920/starter-20210920.zip' +``` + +#### Deploying nodes: + +```bash +docker-compose -f docker-compose-sender.yml up +docker-compose -f docker-compose-receiver.yml up + +``` + +#### Undeploying nodes: + +```bash +docker-compose -f docker-compose-sender.yml down +docker-compose -f docker-compose-receiver.yml down +``` + +**Important note:** `ctrl+c` does not destroy instances diff --git a/docker/docker-compose-examples/push-publish/docker-compose-receiver.yml b/docker/docker-compose-examples/push-publish/docker-compose-receiver.yml new file mode 100644 index 000000000000..c97370952002 --- /dev/null +++ b/docker/docker-compose-examples/push-publish/docker-compose-receiver.yml @@ -0,0 +1,74 @@ +version: '3.5' + +networks: + db_net_receiver: + opensearch-net_receiver: + +volumes: + dbdata_receiver: + opensearch-data_receiver: + +services: + opensearch-receiver: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9201:9200 + - 9601:9600 + volumes: + - opensearch-data_receiver:/usr/share/opensearch/data + networks: + - opensearch-net_receiver + + dotcms-receiver: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db-receiver/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch-receiver:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-receiver' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + depends_on: + - opensearch-receiver + - db-receiver + volumes: + #- {local_data_path}:/data/shared + - {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net_receiver + - opensearch-net_receiver + ports: + - "8081:8082" + - "8444:8443" + + db-receiver: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata_receiver:/var/lib/postgresql/data + networks: + - db_net_receiver + + diff --git a/docker/docker-compose-examples/push-publish/docker-compose-sender.yml b/docker/docker-compose-examples/push-publish/docker-compose-sender.yml new file mode 100644 index 000000000000..433ba9c91390 --- /dev/null +++ b/docker/docker-compose-examples/push-publish/docker-compose-sender.yml @@ -0,0 +1,74 @@ +version: '3.5' + +networks: + db_net_sender: + opensearch-net_sender: + +volumes: + dbdata_sender: + opensearch-data_sender: + +services: + opensearch-sender: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9200:9200 + - 9600:9600 + volumes: + - opensearch-data_sender:/usr/share/opensearch/data + networks: + - opensearch-net_sender + + dotcms-sender: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db-sender/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch-sender:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-sender' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + depends_on: + - opensearch-sender + - db-sender + volumes: + #- {local_data_path}:/data/shared + - {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net_sender + - opensearch-net_sender + ports: + - "8082:8082" + - "8443:8443" + + db-sender: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata_sender:/var/lib/postgresql/data + networks: + - db_net_sender + + diff --git a/docker/docker-compose-examples/push-publish/receiver/docker-compose.yml b/docker/docker-compose-examples/push-publish/receiver/docker-compose.yml new file mode 100644 index 000000000000..124260dbe491 --- /dev/null +++ b/docker/docker-compose-examples/push-publish/receiver/docker-compose.yml @@ -0,0 +1,74 @@ +version: '3.5' + +networks: + db_net_sender: + opensearch-net_sender: + +volumes: + dbdata_sender: + opensearch-data_sender: + +services: + opensearch-sender: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9200:9200 + - 9600:9600 + volumes: + - opensearch-data_sender:/usr/share/opensearch/data + networks: + - opensearch-net_sender + + dotcms-sender: + image: dotcms/dotcms:22.12_f479a493_SNAPSHOT + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db-sender/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch-sender:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-sender' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + depends_on: + - opensearch-sender + - db-sender + # volumes: + # #- {local_data_path}:/data/shared + # - {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net_sender + - opensearch-net_sender + ports: + - "8082:8082" + - "8443:8443" + + db-sender: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata_sender:/var/lib/postgresql/data + networks: + - db_net_sender + + diff --git a/docker/docker-compose-examples/scripts/dotcms-get-demo-site-starter-urls.sh b/docker/docker-compose-examples/scripts/dotcms-get-demo-site-starter-urls.sh new file mode 100644 index 000000000000..d3f1ab883bee --- /dev/null +++ b/docker/docker-compose-examples/scripts/dotcms-get-demo-site-starter-urls.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Prints docker-compose.yml snippets to fetch the proper +# Demo Site content for each dotCMS version + +# This clones the dotCMS core repo on its first run which will take some time + +gitdir=/var/tmp/dotcms-get-starter-urls-repo +if [ ! -d $gitdir ] +then + echo "Cloning dotcms core repo to $gitdir" + git clone https://github.com/dotCMS/core.git $gitdir +fi + +pushd $gitdir >/dev/null +git checkout -q master +git pull -q +for version in $(git tag -l v* | sed 's/^v//' | sort -n | uniq | grep -v MM.YY) +do + echo + git checkout -q v${version} + starter_date=$(grep 'starter group' dotCMS/build.gradle | grep -v empty_ | awk -F \' '{print $6}') + cat </dev/null diff --git a/docker/docker-compose-examples/scripts/dotcms_properties_to_env_vars.py b/docker/docker-compose-examples/scripts/dotcms_properties_to_env_vars.py new file mode 100644 index 000000000000..f14ba19a729f --- /dev/null +++ b/docker/docker-compose-examples/scripts/dotcms_properties_to_env_vars.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 + +import argparse +from pathlib import Path + +epilog = """ +Retrieve settings from .properties files from "binary install" of dotCMS, +and print them out in docker or k8s yaml environment variable format + +see https://www.dotcms.com/docs/latest/configuration-properties#EnvironmentVariables +""" + + +def list_properties_files( + search_path="/home/dotcms/wwwroot/current/plugins/com.dotcms.config/conf", +): + """ + returns a list of possible dotcms properties files + """ + properties_files = [] + conf_path = Path(search_path) + if conf_path.is_file(): + properties_files = [conf_path] + elif conf_path.is_dir(): + for base in [ + "dotmarketing-config", + "dotcms-config-cluster", + "portal", + "system", + ]: + for ext in ["", "-ext"]: + for ini in ["", ".ini"]: + properties_files += list(Path(conf_path).glob(f"**/{base}{ext}.properties{ini}")) + else: + print(f"specified path '{conf_path}' is not a file or directory") + if not properties_files: + print(f"No properties files found on path: {conf_path}") + return properties_files + + +def get_property_value(line): + """ + parse a single line from a config file + return a dict e.g. + {"property" : "CMS_HEAP_SIZE", "value": "10g"} + """ + ignored_properties = [ + "DOT_ASSET_REAL_PATH", + "DOT_DOTCMS_LOGGING_HOME", + "DOT_DYNAMIC_CONTENT_PATH", + "DOT_TAIL_LOG_LOG_FOLDER", + "DOT_FELIX_BASE_DIR", + "DOT_FELIX_FELIX_FILEINSTALL_DIR", + "DOT_FELIX_FELIX_UNDEPLOYED_DIR", + "DOT_ES_PATH_DATA", + "DOT_ES_PATH_WORK", + "DOT_ES_HTTP_ENABLED", + "DOT_ES_HTTP_CORS_ENABLED", + "DOT_ES_HTTP_PORT", + "DOT_ES_HTTP_HOST", + ] + line = line.strip() + (prop, value) = line.split("=", 1) + prop = "DOT_" + prop.strip().upper().replace(".", "_") + value = value.strip() + if not value: + value = "" + # quote yaml literals and int's + value = yaml_safe_value(value) + env_var = {} + if prop not in ignored_properties: + env_var = {"property": prop, "value": value} + return env_var + + +def parse_properties_file(properties_files): + output_lines = [] + for file in properties_files: + try: + with open(file, "r") as f: + properties_contents = f.readlines() + except FileNotFoundError: + continue + for line in properties_contents: + line = line.strip() + if not line: + pass + elif "=" in line and not line.startswith("#"): + parsed_line = get_property_value(line) + if parsed_line: + output_lines.append(parsed_line) + return output_lines + + +def print_properties_docker_yml(properties): + """ + each element in "properties" should either be a dict with a "comment" key, or with both "property" and "value" keys set + """ + prepend = 6 * " " + for line in properties: + print(f'{prepend}{line["property"]}: {line["value"]}') + + +def print_properties_k8s(properties): + """ + each element in "properties" should either be a dict with a "comment" key, or with both "property" and "value" keys set + """ + prepend = 8 * " " + print(f"{prepend}env:") + for line in properties: + print(f'{prepend} - name: {line["property"]}') + print(f"{prepend} value: {line['value']}") + + +def yaml_safe_value(value): + """ + env var values which are ints or literals must be quoted in docker/k8s yaml config files else yaml processor + does not pass them to docker/k8s as strings + + we also convert yaml null to empty string, though we should not encounter nulls in this script + """ + yaml_nulls = ( + "null", + "Null", + "NULL", + ) + + yaml_bools = ( + "y", + "Y", + "yes", + "Yes", + "YES", + "n", + "N", + "no", + "No", + "NO", + "true", + "True", + "TRUE", + "false", + "False", + "FALSE", + "on", + "On", + "ON", + "off", + "Off", + "OFF", + ) + try: + value = int(value) + except (TypeError, ValueError): + pass + if isinstance(value, int) or value in yaml_bools: + value = f'"{value}"' + elif value in yaml_nulls: + value = "" + return value + + +if __name__ == "__main__": + output_choices = ["docker", "k8s"] + parser = argparse.ArgumentParser( + description="Convert dotCMS config plugin properties to ENV vars", + epilog=epilog, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument( + "--format", + choices=output_choices, + default="docker", + help="output formats: " + ",".join(output_choices), + ) + parser.add_argument( + "propfile", + help="Filesystem path to a properties file, or a conf directory containing dotcms properties files. These files will reside in plugins/com.dotcms.config/conf if a ROOT config plugin was used" + ) + args = parser.parse_args() + + properties_files = list_properties_files(args.propfile) + properties = parse_properties_file(properties_files) + + print() + if args.format == "docker": + print_properties_docker_yml(properties) + elif args.format == "k8s": + print_properties_k8s(properties) + print() + print(""" +## Be sure to verify these values before running in production! +## Remember integers and booleans should be quoted in yaml for docker compose and k8s config. +## Source properties files: +""") + for file in properties_files: + print(f"## {file}") + print() + diff --git a/docker/docker-compose-examples/single-node-debug-mode/Intellij Debug Mode.png b/docker/docker-compose-examples/single-node-debug-mode/Intellij Debug Mode.png new file mode 100644 index 0000000000000000000000000000000000000000..a215dfbcea4fa9cf7aa0fbea2b79b5330631ada6 GIT binary patch literal 233460 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®Z$C1zH7Xm!)GCwbPPz{2aX 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 D0CQfM literal 0 HcmV?d00001 diff --git a/docker/docker-compose-examples/single-node-debug-mode/README.md b/docker/docker-compose-examples/single-node-debug-mode/README.md new file mode 100644 index 000000000000..5f495f530136 --- /dev/null +++ b/docker/docker-compose-examples/single-node-debug-mode/README.md @@ -0,0 +1,50 @@ +# Dotcms Single Node (Debug Mode) + +A single instance of dotcms running on port 8080. Database: postgres. Debug mode enabled on port 8000 + +## Usage + +#### Environment setup + + +1) A local path to license pack must be set here: + +``` +- {license_local_path}/license.zip:/data/shared/assets/license.zip +``` + +2) A local path to access data in the instance can be set uncommenting this line: + +``` +#- {local_data_path}:/data/shared +``` + +3) A custom starter can be set through this line (uncomment and change the starter url accordingly): + +``` +#"CUSTOM_STARTER_URL": 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20210920/starter-20210920.zip' +``` + +#### Run an example: + +```bash +docker-compose up +``` + +#### Shut down instances: + +```bash +docker-compose down +``` + +**Important note:** `ctrl+c` does not destroy instances + + +4) Configure your IDE enabling remote debugging: + +![Remote Debugging](https://github.com/dotCMS/core/blob/new-docker-compose-examples/docker/docker-compose-examples/single-node-debug-mode/Intellij%20Debug%20Mode.png?raw=true) + + + + + diff --git a/docker/docker-compose-examples/single-node-debug-mode/docker-compose.yml b/docker/docker-compose-examples/single-node-debug-mode/docker-compose.yml new file mode 100644 index 000000000000..71f28daf57d3 --- /dev/null +++ b/docker/docker-compose-examples/single-node-debug-mode/docker-compose.yml @@ -0,0 +1,75 @@ +version: '3.5' + +networks: + db_net: + opensearch-net: + +volumes: + cms-shared: + dbdata: + opensearch-data: + +services: + opensearch: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9200:9200 + - 9600:9600 + volumes: + - opensearch-data:/usr/share/opensearch/data + networks: + - opensearch-net + + dotcms: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:8000 ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-production' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + depends_on: + - opensearch + - db + volumes: + - cms-shared:/data/shared + #- {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net + - opensearch-net + ports: + - "8082:8082" + - "8000:8000" + - "8443:8443" + + db: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata:/var/lib/postgresql/data + networks: + - db_net + diff --git a/docker/docker-compose-examples/single-node-demo-site/README.md b/docker/docker-compose-examples/single-node-demo-site/README.md new file mode 100644 index 000000000000..db535820592a --- /dev/null +++ b/docker/docker-compose-examples/single-node-demo-site/README.md @@ -0,0 +1,33 @@ +# Dotcms Single Node With Demo Content + +A single instance of dotcms running on port 8080 that will download and install the demo site on initialization. Database: postgres + +## Usage +`scripts/dotcms-get-demo-site-starter-urls.sh` prints the correct demo site starter URL for each dotCMS version + +#### Environment setup +Specifiy a custom starter that will be included: +``` +"CUSTOM_STARTER_URL": "https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/xxxxxxxxxx.zip" +``` +A local path to license pack can be set here: + +``` +- {license_local_path}/license.zip:/data/shared/assets/license.zip +``` + +#### Run an example: + +```bash +docker-compose up +``` + +#### Shut down instances: + +```bash +docker-compose down +``` + +**Important note:** `ctrl+c` does not destroy instances + + diff --git a/docker/docker-compose-examples/single-node-demo-site/docker-compose.yml b/docker/docker-compose-examples/single-node-demo-site/docker-compose.yml new file mode 100644 index 000000000000..3e3121594059 --- /dev/null +++ b/docker/docker-compose-examples/single-node-demo-site/docker-compose.yml @@ -0,0 +1,75 @@ +version: '3.5' + +networks: + db_net: + opensearch-net: + +volumes: + cms-shared: + dbdata: + opensearch-data: + +services: + opensearch: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9200:9200 + - 9600:9600 + volumes: + - opensearch-data:/usr/share/opensearch/data + networks: + - opensearch-net + + dotcms: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-production' + CUSTOM_STARTER_URL: https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20220713/starter-20220713.zip + depends_on: + - opensearch + - db + volumes: + - cms-shared:/data/shared + #- {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net + - opensearch-net + ports: + - "8082:8082" + - "8443:8443" + + db: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata:/var/lib/postgresql/data + networks: + - db_net + + diff --git a/docker/docker-compose-examples/single-node/README.md b/docker/docker-compose-examples/single-node/README.md new file mode 100644 index 000000000000..ce652efc1ba7 --- /dev/null +++ b/docker/docker-compose-examples/single-node/README.md @@ -0,0 +1,40 @@ +# Dotcms Single Node + +A single instance of dotcms running on port 8080. Database: postgres + +## Usage + +#### Environment setup + + +1) A local path to license pack must be set here: + +``` +- {license_local_path}/license.zip:/data/shared/assets/license.zip +``` + +2) A local path to access data in the instance can be set uncommenting this line: + +``` +#- {local_data_path}:/data/shared +``` + +3) A custom starter can be set through this line (uncomment and change the starter url accordingly): + +``` +#"CUSTOM_STARTER_URL": 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20210920/starter-20210920.zip' +``` + +#### Run an example: + +```bash +docker-compose up +``` + +#### Shut down instances: + +```bash +docker-compose down +``` + +**Important note:** `ctrl+c` does not destroy instances diff --git a/docker/docker-compose-examples/single-node/docker-compose.yml b/docker/docker-compose-examples/single-node/docker-compose.yml new file mode 100644 index 000000000000..aee6ebeb354b --- /dev/null +++ b/docker/docker-compose-examples/single-node/docker-compose.yml @@ -0,0 +1,74 @@ +version: '3.5' + +networks: + db_net: + opensearch-net: + +volumes: + cms-shared: + dbdata: + opensearch-data: + +services: + opensearch: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9200:9200 + - 9600:9600 + volumes: + - opensearch-data:/usr/share/opensearch/data + networks: + - opensearch-net + + dotcms: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-production' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + depends_on: + - opensearch + - db + volumes: + - cms-shared:/data/shared + #- {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net + - opensearch-net + ports: + - "8082:8082" + - "8443:8443" + + db: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata:/var/lib/postgresql/data + networks: + - db_net + diff --git a/docker/docker-compose-examples/with-kibana/docker-compose.yml b/docker/docker-compose-examples/with-kibana/docker-compose.yml new file mode 100644 index 000000000000..5e8122e74b5a --- /dev/null +++ b/docker/docker-compose-examples/with-kibana/docker-compose.yml @@ -0,0 +1,72 @@ +version: '3.5' + +networks: + db_net: + es_net: + +volumes: + cms-shared: + dbdata: + esdata: + +services: + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:7.9.1 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "ES_JAVA_OPTS=-Xmx1G " + ports: + - 9200:9200 + - 9600:9600 + volumes: + - esdata:/usr/share/elasticsearch/data + networks: + - es_net + + kibana: + image: docker.elastic.co/kibana/kibana:7.9.1 + environment: + ELASTICSEARCH_HOSTS: '["http://elasticsearch:9200"]' + ports: + - "5601:5601" + networks: + - es_net + + dotcms: + image: dotcms/dotcms:latest + environment: + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'http://elasticsearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-production' + #"CUSTOM_STARTER_URL": 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20220713/starter-20220713.zip' + depends_on: + - elasticsearch + - db + volumes: + #- {local_data_path}:/data/shared + - {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net + - es_net + ports: + - "8080:8080" + - "8443:8443" + + db: + image: postgres:11 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata:/var/lib/postgresql/data + networks: + - db_net diff --git a/docker/docker-compose-examples/with-opensearch-dashboard/README.md b/docker/docker-compose-examples/with-opensearch-dashboard/README.md new file mode 100644 index 000000000000..f03818c242b3 --- /dev/null +++ b/docker/docker-compose-examples/with-opensearch-dashboard/README.md @@ -0,0 +1,42 @@ +# Dotcms with Kibana + +A single instance of dotcms running on port 8080. Kibana was included for torubleshooting and runs on port 5601. Database: postgres. + +## Usage + +#### Environment setup + + +1) A local path to license pack must be set here: + +``` +- {license_local_path}/license.zip:/data/shared/assets/license.zip +``` + +2) A local path to access data in the instance can be set uncommenting this line: + +``` +#- {local_data_path}:/data/shared +``` + +3) A custom starter can be set through this line (uncomment and change the starter url accordingly): + +``` +#"CUSTOM_STARTER_URL": 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20210920/starter-20210920.zip' +``` + +#### Run an example: + +```bash +docker-compose up +``` + +#### Shut down instances: + +```bash +docker-compose down +``` + +**Important note:** `ctrl+c` does not destroy instances + + diff --git a/docker/docker-compose-examples/with-opensearch-dashboard/docker-compose.yml b/docker/docker-compose-examples/with-opensearch-dashboard/docker-compose.yml new file mode 100644 index 000000000000..abb42fb5d1ee --- /dev/null +++ b/docker/docker-compose-examples/with-opensearch-dashboard/docker-compose.yml @@ -0,0 +1,83 @@ +version: '3.5' + +networks: + db_net: + opensearch-net: + +volumes: + cms-shared: + dbdata: + opensearch-data: + +services: + opensearch: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9200:9200 + - 9600:9600 + volumes: + - opensearch-data:/usr/share/opensearch/data + networks: + - opensearch-net + + dashboard: + image: opensearchproject/opensearch-dashboards:1.3.6 + environment: + OPENSEARCH_HOSTS: '["https://opensearch:9200"]' + ports: + - "5601:5601" + networks: + - opensearch-net + + dotcms: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-production' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + depends_on: + - opensearch + - db + volumes: + - cms-shared:/data/shared + # - {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net + - opensearch-net + ports: + - "8082:8082" + - "8443:8443" + + db: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata:/var/lib/postgresql/data + networks: + - db_net + diff --git a/docker/docker-compose-examples/with-redis-session/README.md b/docker/docker-compose-examples/with-redis-session/README.md new file mode 100644 index 000000000000..1fd4a421d8ac --- /dev/null +++ b/docker/docker-compose-examples/with-redis-session/README.md @@ -0,0 +1,111 @@ +# dotCMS Cluster Mode with Redis Session Manager + +This is an example of a 2-node dotCMS Cluster running on ports 8081 and 8082 respectively, using the Redis Session Manager feature. For more information, please refer to the plugin's repository: https://github.com/dotCMS/tomcat-redis-session-manager + +The Redis server runs on port 6379 with password `MY_SECRET_P4SS`. + +## Usage + +#### Environment setup + +1) A local path to license pack must be set here: +``` +- {license_local_path}/license.zip:/data/shared/assets/license.zip +``` +The license pack must contain at least two licenses (one for each node in the cluster). + +2) A local path to access data in the instance can be set uncommenting this line: +``` +#- {local_data_path}:/data/shared +``` + +3) A custom starter can be set through this line (uncomment and change the starter URL accordingly): +``` +#"CUSTOM_STARTER_URL": 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20230712/starter-20230712.zip' +``` + +4) The most important configuration parameters have already been set in both `docker-compose.yml` files. Please refer to the plugin's official repository above for additional ones. + + +#### Deploying nodes: + +```bash +docker-compose -f docker-compose-node-1.yml up +``` + +Once the node 1 is running, deploy node 2: +```bash +docker-compose -f docker-compose-node-2.yml up +``` + +#### Checking Session persistence in Redis: + +You can easily check that the dotCMS Sessions are being persisted in Redis by following these simple steps: + +1. SSH into the Redis container: +```bash +docker exec -it with-redis-session-redis-1 /bin/bash +``` +2. Run the following command to access the Redis CLI: +```bash +redis-cli -a MY_SECRET_P4SS +``` +3. Log into the dotCMS back-end in both nodes. +4. Run this command to print all the keys stored in Redis: +```bash +KEYS * +``` +4. You should see a list of keys similar to this one: +``` +1) "dotcms-redis-cluster4E5ACD893B6250FACEB24CAE6F02581E" +2) "dotcms-redis-cluster31AE4BC07CF37EDA49323954DFDC5B25" +``` + +The key is composed of (1) the current Cluster ID -- which is optional -- and the actual JSESSION ID. + +Additionally, at the beggining of the dotCMS log, you will see the folowing information related to the Redis Session Manager, and the most important configuration values that are being used to instantiate the service: +``` +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.276 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.startInternal ==================================== +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.277 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.startInternal Redis-managed Tomcat Session plugin +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.277 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.startInternal ==================================== +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.277 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.startInternal - Attaching 'com.dotcms.tomcat.redissessions.RedisSessionManager' to 'com.dotcms.tomcat.redissessions.RedisSessionHandlerValve' +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.279 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeSerializer Attempting to use serializer: com.dotcms.tomcat.redissessions.JavaSerializer +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.280 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.startInternal - Initializing configuration parameters: +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.282 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_SESSION_HOST: redis +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.283 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_SESSION_PORT: 6379 +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.283 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_SESSION_PASSWORD: - Set - +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.284 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_SESSION_SSL_ENABLED: false +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.284 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_SESSION_SENTINEL_MASTER: null +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.285 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_SESSION_SENTINELS: null +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.285 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_SESSION_DATABASE: 0 +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.286 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_SESSION_TIMEOUT: 2000 +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.286 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_SESSION_PERSISTENT_POLICIES: DEFAULT +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.287 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_MAX_CONNECTIONS: 128 +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.288 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_MAX_IDLE_CONNECTIONS: 100 +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.288 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_MAX_IDLE_CONNECTIONS: 32 +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.289 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- DOT_DOTCMS_CLUSTER_ID (Redis Key Prefix): dotcms-redis-cluster +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.289 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.initializeConfigParams -- TOMCAT_REDIS_ENABLED_FOR_ANON_TRAFFIC: false +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.289 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.startInternal - Initializing Redis connection +with-redis-session-dotcms-node-1-1 | SLF4J: No SLF4J providers were found. +with-redis-session-dotcms-node-1-1 | +with-redis-session-dotcms-node-1-1 | +with-redis-session-dotcms-node-1-1 | SLF4J: Defaulting to no-operation (NOP) logger implementation +with-redis-session-dotcms-node-1-1 | +with-redis-session-dotcms-node-1-1 | +with-redis-session-dotcms-node-1-1 | SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details. +with-redis-session-dotcms-node-1-1 | +with-redis-session-dotcms-node-1-1 | +with-redis-session-dotcms-node-1-1 | 18-Jul-2023 18:30:02.378 INFO [main] com.dotcms.tomcat.redissessions.RedisSessionManager.startInternal - Successful! Redis-managed Tomcat Sessions will expire after 1800 seconds. +``` + + +#### Un-deploying nodes: + +```bash +docker-compose -f docker-compose-node-2.yml down +docker-compose -f docker-compose-node-1.yml down +``` + +**Important note:** `ctrl+c` does not destroy instances + + diff --git a/docker/docker-compose-examples/with-redis-session/docker-compose-node-1.yml b/docker/docker-compose-examples/with-redis-session/docker-compose-node-1.yml new file mode 100644 index 000000000000..664130ac91b4 --- /dev/null +++ b/docker/docker-compose-examples/with-redis-session/docker-compose-node-1.yml @@ -0,0 +1,90 @@ +version: '3.5' + +networks: + db_net: + opensearch-net: + redis_net: + +volumes: + cms-shared: + dbdata: + opensearch-data: + +services: + opensearch: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9200:9200 + - 9600:9600 + volumes: + - opensearch-data:/usr/share/opensearch/data + networks: + - opensearch-net + + dotcms-node-1: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + TOMCAT_REDIS_SESSION_ENABLED: 'true' + TOMCAT_REDIS_SESSION_HOST: 'redis' + TOMCAT_REDIS_SESSION_PORT: '6379' + TOMCAT_REDIS_SESSION_PASSWORD: 'MY_SECRET_P4SS' + TOMCAT_REDIS_SESSION_SSL_ENABLED: 'false' + TOMCAT_REDIS_SESSION_PERSISTENT_POLICIES: 'DEFAULT' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-redis-cluster' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20230712/starter-20230712.zip' + depends_on: + - opensearch + - db + - redis + volumes: + - {local_data_path}:/data/shared + - {license_local_path}:/data/shared/assets/license.zip + networks: + - db_net + - opensearch-net + - redis_net + ports: + - "8082:8082" + - "8443:8443" + + redis: + image: "redis:latest" + command: redis-server --requirepass MY_SECRET_P4SS + ports: + - "6379:6379" + networks: + - redis_net + + db: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata:/var/lib/postgresql/data + networks: + - db_net \ No newline at end of file diff --git a/docker/docker-compose-examples/with-redis-session/docker-compose-node-2.yml b/docker/docker-compose-examples/with-redis-session/docker-compose-node-2.yml new file mode 100644 index 000000000000..bc8987d8c122 --- /dev/null +++ b/docker/docker-compose-examples/with-redis-session/docker-compose-node-2.yml @@ -0,0 +1,42 @@ +version: '3.5' + +networks: + with-redis-session_db_net: + external: true + with-redis-session_opensearch-net: + external: true + with-redis-session_redis_net: + external: true + +volumes: + cms-shared: + +services: + dotcms-node-2: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + TOMCAT_REDIS_SESSION_ENABLED: 'true' + TOMCAT_REDIS_SESSION_HOST: 'redis' + TOMCAT_REDIS_SESSION_PORT: '6379' + TOMCAT_REDIS_SESSION_PASSWORD: 'MY_SECRET_P4SS' + TOMCAT_REDIS_SESSION_SSL_ENABLED: 'false' + TOMCAT_REDIS_SESSION_PERSISTENT_POLICIES: 'DEFAULT' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-redis-cluster' + volumes: + - { local_data_path }:/data/shared + - {license_local_path}:/data/shared/assets/license.zip + networks: + - with-redis-session_db_net + - with-redis-session_opensearch-net + - with-redis-session_redis_net + ports: + - "8081:8082" + - "8444:8443" \ No newline at end of file diff --git a/docker/docker-compose-examples/with-redis/README.md b/docker/docker-compose-examples/with-redis/README.md new file mode 100644 index 000000000000..bca540373b42 --- /dev/null +++ b/docker/docker-compose-examples/with-redis/README.md @@ -0,0 +1,56 @@ +# Dotcms Cluster Mode with Redis + +Cluster with 2 dotCMS instances running on ports 8080 and 8081 respectively. Database: postgres. + +This environment uses Redis Pub/Sub and Cache. Redis runs on port 6379 with password `MY_SECRET_P4SS` + +## Usage + +#### Environment setup + + +1) A local path to license pack must be set here: + +``` +- {license_local_path}/license.zip:/data/shared/assets/license.zip +``` + +The license pack must contain at least two licenses (one for each node in the cluster) + + +2) A local path to access data in the instance can be set uncommenting this line: + +``` +#- {local_data_path}:/data/shared +``` + +3) A custom starter can be set through this line (uncomment and change the starter url accordingly): + +``` +#"CUSTOM_STARTER_URL": 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20210920/starter-20210920.zip' +``` + +#### Deploying nodes: + +```bash +docker-compose -f docker-compose-node-1.yml up + +``` + +Once the node 1 is running, deploy node 2: +```bash +docker-compose -f docker-compose-node-2.yml up + +``` + + +#### Undeploying nodes: + +```bash +docker-compose -f docker-compose-node-2.yml down +docker-compose -f docker-compose-node-1.yml down +``` + +**Important note:** `ctrl+c` does not destroy instances + + diff --git a/docker/docker-compose-examples/with-redis/docker-compose-node-1.yml b/docker/docker-compose-examples/with-redis/docker-compose-node-1.yml new file mode 100644 index 000000000000..80e93452575b --- /dev/null +++ b/docker/docker-compose-examples/with-redis/docker-compose-node-1.yml @@ -0,0 +1,88 @@ +version: '3.5' + +networks: + db_net: + opensearch-net: + redis_net: + +volumes: + cms-shared: + dbdata: + opensearch-data: + +services: + opensearch: + image: opensearchproject/opensearch:1.3.6 + environment: + - cluster.name=elastic-cluster + - discovery.type=single-node + - data + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xmx1G " + ulimits: + memlock: + soft: -1 # Set memlock to unlimited (no soft or hard limit) + hard: -1 + nofile: + soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536 + hard: 65536 + ports: + - 9200:9200 + - 9600:9600 + volumes: + - opensearch-data:/usr/share/opensearch/data + networks: + - opensearch-net + + dotcms-node-1: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-redis-cluster' + DOT_DOT_PUBSUB_PROVIDER_OVERRIDE: 'com.dotcms.dotpubsub.RedisPubSubImpl' + DOT_REDIS_LETTUCECLIENT_URLS: 'redis://MY_SECRET_P4SS@redis' + DOT_CACHE_DEFAULT_CHAIN: 'com.dotmarketing.business.cache.provider.caffine.CaffineCache,com.dotcms.cache.lettuce.RedisCache' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + depends_on: + - opensearch + - db + - redis + volumes: + #- {local_data_path}:/data/shared + - {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - db_net + - opensearch-net + - redis_net + ports: + - "8082:8082" + - "8443:8443" + + redis: + image: "redis:latest" + command: redis-server --requirepass MY_SECRET_P4SS + ports: + - "6379:6379" + networks: + - redis_net + + db: + image: postgres:15 + command: postgres -c 'max_connections=400' -c 'shared_buffers=128MB' + environment: + "POSTGRES_USER": 'dotcmsdbuser' + "POSTGRES_PASSWORD": 'password' + "POSTGRES_DB": 'dotcms' + volumes: + - dbdata:/var/lib/postgresql/data + networks: + - db_net + diff --git a/docker/docker-compose-examples/with-redis/docker-compose-node-2.yml b/docker/docker-compose-examples/with-redis/docker-compose-node-2.yml new file mode 100644 index 000000000000..eb8e2e53dd6e --- /dev/null +++ b/docker/docker-compose-examples/with-redis/docker-compose-node-2.yml @@ -0,0 +1,42 @@ +version: '3.5' + +networks: + with-redis_db_net: + external: true + with-redis_opensearch-net: + external: true + with-redis_redis_net: + external: true + +volumes: + cms-shared: + +services: + dotcms-node-2: + image: dotcms/dotcms:latest + environment: + CMS_JAVA_OPTS: '-Xmx1g ' + LANG: 'C.UTF-8' + TZ: 'UTC' + DB_BASE_URL: "jdbc:postgresql://db/dotcms" + DB_USERNAME: 'dotcmsdbuser' + DB_PASSWORD: 'password' + DOT_ES_AUTH_BASIC_PASSWORD: 'admin' + DOT_ES_ENDPOINTS: 'https://opensearch:9200' + DOT_INITIAL_ADMIN_PASSWORD: 'admin' + DOT_DOTCMS_CLUSTER_ID: 'dotcms-redis-cluster' + DOT_DOT_PUBSUB_PROVIDER_OVERRIDE: 'com.dotcms.dotpubsub.RedisPubSubImpl' + DOT_REDIS_LETTUCECLIENT_URLS: 'redis://MY_SECRET_P4SS@redis' + DOT_CACHE_DEFAULT_CHAIN: 'com.dotmarketing.business.cache.provider.caffine.CaffineCache,com.dotcms.cache.lettuce.RedisCache' + #CUSTOM_STARTER_URL: 'https://repo.dotcms.com/artifactory/libs-release-local/com/dotcms/starter/20211201/starter-20211201.zip' + volumes: + #- {local_data_path}:/data/shared + - {license_local_path}/license.zip:/data/shared/assets/license.zip + networks: + - with-redis_db_net + - with-redis_opensearch-net + - with-redis_redis_net + ports: + - "8081:8082" + - "8444:8443" +