Online Deployment Examples

Multi-Image MySQL

DevNote: Describe this configuration; how many/what services it runs and things like that.

docker-compose.yaml
version: '3.5'

services:
  server:
    image: cortezaproject/corteza:${VERSION}
    restart: always
    env_file: [ .env ]
    depends_on: [ db ]
    networks: [ proxy, internal ]
    # Uncomment to use local fs for data persistence
    volumes: [ "./data/server:/data" ]
    environment:
      # These two are needed only if you are using NginX Lets-Encrypt companion
      # (see docs.cortezaproject.org for details)
      # VIRTUAL_HOST helps NginX proxy route traffic for specific virtual host to this container
      VIRTUAL_HOST:     ${DOMAIN}
      # LETSENCRYPT_HOST helps NginX LE companion pull and configure SSL certificates for your domain
      LETSENCRYPT_HOST: ${DOMAIN}

  db:
    # MySQL Database
    # See https://hub.docker.com/r/percona/percona-server for details
    image: percona:8.0
    restart: always
    volumes: [ "./data/db:/var/lib/mysql" ]
    environment:
      MYSQL_DATABASE: dbname
      MYSQL_USER:     dbuser
      MYSQL_PASSWORD: dbpass
      # get the random generated password by running: docker-compose logs db | grep "GENERATED ROOT PASSWORD"
      MYSQL_RANDOM_ROOT_PASSWORD: random
    healthcheck: { test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"], timeout: 20s, retries: 10 }
    networks: [ internal ]

networks:
  internal: {}
  proxy: { external: true }
.env
########################################################################################################################
# docker-compose supports environment variable interpolation/substitution in compose configuration file
# (more info: https://docs.docker.com/compose/environment-variables)

########################################################################################################################
# General settings
DOMAIN=your-demo.example.tld
VERSION=2023.3

########################################################################################################################
# Database connection

DB_DSN=dbuser:dbpass@tcp(db:3306)/dbname?collation=utf8mb4_general_ci

########################################################################################################################
# Server settings

# Serve Corteza webapps alongside API
HTTP_WEBAPP_ENABLED=true

# Send action log to container logs as well
# ACTIONLOG_DEBUG=true

# Uncomment for extra debug info if something goes wrong
# LOG_LEVEL=debug

# Use nicer and colorful log instead of JSON
# LOG_DEBUG=true

########################################################################################################################
# Authentication

# Secret to use for JWT token
# Make sure you change it (>30 random characters) if
# you expose your deployment to outside traffic
# AUTH_JWT_SECRET=this-is-only-for-demo-purpose--make-sure-you-change-it-for-production

########################################################################################################################
# SMTP (mail sending) settings

# Point this to your local or external SMTP server if you want to send emails.
# In most cases, Corteza can detect that SMTP is disabled and skips over sending emails without an error
#SMTP_HOST=smtp-server.example.tld:587
#SMTP_USER=postmaster@smtp-server.example.tld
#SMTP_PASS=this-is-your-smtp-password
#SMTP_FROM='"Demo" <info@your-demo.example.tld>'

Multi-Image PostgreSQL

DevNote: Describe this configuration; how many/what services it runs and things like that.

docker-compose.yaml
version: '3.5'

services:
  server:
    image: cortezaproject/corteza:${VERSION}
    networks: [ proxy, internal ]
    restart: always
    env_file: [ .env ]
    depends_on: [ db ]
    volumes: [ "./data/server:/data" ]
    environment:
      # VIRTUAL_HOST helps NginX proxy route traffic for specific virtual host to
      # this container
      # This value is also picked up by initial boot autoconfiguration procedure
      # If this is changed, make sure you change settings accordingly
      VIRTUAL_HOST: ${DOMAIN}
      # This is needed only if you are using NginX Lets-Encrypt companion
      # (see docs.cortezaproject.org for details)
      LETSENCRYPT_HOST: ${DOMAIN}

  db:
    # PostgreSQL Database
    # See https://hub.docker.com/_/postgres for details
    # Support for postgres 13, 14 and 15 is available in the latest version of Corteza
    image: postgres:15
    networks: [ internal ]
    restart: always
    healthcheck: { test: ["CMD-SHELL", "pg_isready -U corteza"], interval: 10s, timeout: 5s, retries: 5 }
    environment:
      # Warning: these are values that are only used on 1st start
      #          if you want to change it later, you need to do that
      #          manually inside db container
      POSTGRES_USER:     corteza
      POSTGRES_PASSWORD: corteza

networks:
  internal: {}
  proxy: { external: true }
.env
########################################################################################################################
# docker-compose supports environment variable interpolation/substitution in compose configuration file
# (more info: https://docs.docker.com/compose/environment-variables)

########################################################################################################################
# General settings
DOMAIN=your-demo.example.tld
VERSION=2023.3

########################################################################################################################
# Database connection

DB_DSN=postgres://corteza:corteza@db:5432/corteza?sslmode=disable

########################################################################################################################
# Server settings

# Serve Corteza webapps alongside API
HTTP_WEBAPP_ENABLED=true

# Send action log to container logs as well
# ACTIONLOG_DEBUG=true

# Uncomment for extra debug info if something goes wrong
# LOG_LEVEL=debug

# Use nicer and colorful log instead of JSON
# LOG_DEBUG=true

########################################################################################################################
# Authentication

# Secret to use for JWT token
# Make sure you change it (>30 random characters) if
# you expose your deployment to outside traffic
# AUTH_JWT_SECRET=this-is-only-for-demo-purpose--make-sure-you-change-it-for-production

########################################################################################################################
# SMTP (mail sending) settings

# Point this to your local or external SMTP server if you want to send emails.
# In most cases, Corteza can detect that SMTP is disabled and skips over sending emails without an error
#SMTP_HOST=smtp-server.example.tld:587
#SMTP_USER=postmaster@smtp-server.example.tld
#SMTP_PASS=this-is-your-smtp-password
#SMTP_FROM='"Demo" <info@your-demo.example.tld>'

Multi-image Discovery with PostgreSQL

Currently Corteza Discovery is tested on a running production servers in combination with PostgreSQL database, but should work with the latest MySQL versions. Beside the server and db containers, there should be also the indexer (opensearch-node) and the searcher (discovery) running.

If your Discovery is not working, try restarting the discovery service. There is a known issue with order of execution and health check reporting which may cause the service to fail for you.

Configuration Files

docker-compose.yaml
version: '3.5'

services:
  server:
    image: cortezaproject/corteza:${VERSION}
    env_file: [ .env ]
    networks: [ proxy, internal ]
    environment:
      VIRTUAL_HOST:     ${DOMAIN}
      LETSENCRYPT_HOST: ${DOMAIN}
    volumes:
      - data:/data
    restart: on-failure

  db:
    image: postgres:13
    networks: [ internal ]
    restart: on-failure
    healthcheck: { test: ["CMD-SHELL", "pg_isready -U corteza"], interval: 10s, timeout: 5s, retries: 5 }
    environment:
      POSTGRES_USER:     corteza
      POSTGRES_PASSWORD: corteza

  discovery:
    image: cortezaproject/corteza-server-discovery:${VERSION}
    env_file: [ .env ]
    restart: always
    depends_on:
      - opensearch-node
      - server
    networks:
      - proxy
      - internal
    environment:
      VIRTUAL_HOST:     ${DOMAIN_DISCOVERY}
      LETSENCRYPT_HOST: ${DOMAIN_DISCOVERY}
      ES_ADDRESS: "https://opensearch-node:9200"
      ES_USERNAME: "admin"
      ES_PASSWORD:  "supersecurepassword75@!1A"
      ES_SECURE: "false"
      ES_INDEX_INTERVAL: 60
      CORTEZA_SERVER_BASE_URL: "https://${DOMAIN}"
      CORTEZA_SERVER_AUTH_URL: "https://${DOMAIN}/auth"
    ports:
      - "8888:80"

  opensearch-node:
    image: opensearchproject/opensearch:latest
    networks:
      - internal
    ports:
      - "9200:9200"
      - "9600:9600"
    environment:
      - discovery.type=single-node
      - plugins.security.ssl.http.enabled=true
      - plugins.security.ssl.transport.enabled=true
      - plugins.security.allow_default_init_securityindex=true
      - plugins.security.disabled=false
      - OPENSEARCH_INITIAL_ADMIN_PASSWORD=supersecurepassword75@!1A

volumes:
  data:

networks:
  internal:
  proxy:
    external: true
.env
########################################################################################################################
# General settings

DOMAIN=corteza.mydomain.org
VERSION=2024.9.3

DB_DSN=postgres://corteza:corteza@db:5432/corteza?sslmode=disable

########################################################################################################################
# Server settings

HTTP_WEBAPP_ENABLED=true
HTTP_WEBAPP_LIST="compose,admin,workflow,reporter,discovery"
AUTH_JWT_SECRET=supersecurejwtsecret
LOG_LEVEL=debug

########################################################################################################################
# Discovery settings

DISCOVERY_ENABLED="true"
DISCOVERY_BASE_URL="https://corteza-discovery.mydomain.org"
DISCOVERY_INDEXER_ENABLED=true
DISCOVERY_SEARCHER_ENABLED=true
DISCOVERY_SEARCHER_JWT_SECRET=supersecurejwtsecret

DOMAIN_DISCOVERY=corteza-discovery.mydomain.org
DISCOVERY_CORTEZA_DOMAIN=https://corteza.mydomain.org

DISCOVERY_INDEXER_PRIVATE_INDEX_CLIENT_KEY="111111111111111111"
DISCOVERY_INDEXER_PRIVATE_INDEX_CLIENT_SECRET="supersecretsupersecretsupersecret"
DISCOVERY_INDEXER_PROTECTED_INDEX_CLIENT_KEY="111111111111111111"
DISCOVERY_INDEXER_PROTECTED_INDEX_CLIENT_SECRET="supersecretsupersecretsupersecret"
DISCOVERY_INDEXER_PUBLIC_INDEX_CLIENT_KEY="111111111111111111"
DISCOVERY_INDEXER_PUBLIC_INDEX_CLIENT_SECRET="supersecretsupersecretsupersecret"
DISCOVERY_SEARCHER_CLIENT_KEY="111111111111111111"
DISCOVERY_SEARCHER_CLIENT_SECRET="supersecretsupersecretsupersecret"

Preparing Corteza

Corteza Discovery is a stand alone application, independent from the rest of the Corteza system. In order to make Discovery functional, you must grant access by creating an auth client along with a user and a role.

Access control defines what data the Discovery indexer has access to.

Indexer Role

Firstly define a new role for the Discovery indexer to use. Open the Corteza Admin web application and navigate to System  Roles. Click on the New button, fill in the parameters and click on the Submit button.

Annotated image

Indexer User

Next, define a new user that the Discovery indexer should identify as. In the Corteza Admin web application navigate to System  Users. Click on the New button and fill in the parameters and click on the Submit button.

Annotated image

After you save the user, assign them the role you’ve created earlier.

Annotated image

Indexer Auth Client

Lastly, define an auth client that the Discovery indexer should use to authenticate with Corteza.

Since authentication between two systems is being performed, you should to use the client_credentials grant type.

In the Corteza Admin web application navigate to System  Auth Clients. Click on the New button and fill in the basic parameters; make sure you select the client_credentials grant type and check the allow client access to Corteza Discovery API on behalf of user. Select the previously created user in the impersonate user input and click on the Submit button.

It is recommended you define a new auth client for a new external application instead of reusing existing ones.

Annotated image