DevOps Guide
This guide is tailored to DevOps engineers that are responsible for Corteza instance deploys and it’s maintenance on a system level; such as configuring the environment and setting up email notifications.
Architecture overview
-
Frontend applications (WebApps),
-
Corteza server,
-
Corteza Corredor server.
-
Log storage,
-
error tracking,
-
email sending,
-
object storage,
-
database.
-
Corteza Auth handles all flows related to user authentication; such as sign-up, login, and password recovery,
-
Corteza Admin handles main administration aspects of your Corteza instance; such as configuring settings, defining roles, and managing general permissions,
-
Corteza Low Code is a low-code development platform and allows creation of record-absed business applications,
-
Corteza Messaging collaboration platform that allows teams to collaborate more efficiently and communicate safely with other organizations or customers,
-
Corteza One is a unified workspace to access and run third-party web and Corteza applications. Centralized access management from a single console enables administrative control over who can see or access applications.
System requirements
Supported clients
Corteza doesn’t support older browsers as we wish to develop a modern platform on modern technologies. If you wish to do so, you may build your own Docker containers with custom build procedures. |
Client | Version |
---|---|
Chrome |
v78+ |
Firefox |
v68+ |
Safari |
v12+ |
Edge |
v44+ |
iOS |
iPhone 5s devices and later with iOS 12+ |
Android |
Android 7+ |
Server Operating System
Any Docker-compatible operating system is supported.
We recommend a Linux-based operating system; preferably Ubuntu LTS. |
HTTP server
You should place the API and the web applications behind a firewall or an HTTP reverse proxy. The reverse proxy is responsible for traffic forwarding to Corteza services and SSL termination.
Most of the popular HTTP servers support this. |
The documentation provides configurations guides for Nginx Reverse Proxy and the LetsEncrypt nginx-proxy companion.
You don’t need to use Nginx; you can use the HTTP server you are most familiar with. Use provided examples for Nginx as a reference on how to configure it. |
Database
We recommend the Percona Server for MySQL 8.x, either native on the host or provided via Docker.
Hardware
Number of Users |
Processor |
Memory |
1 - 500 |
1 vCPU/cores |
2 GB RAM |
500 - 1000 |
2 vCPU/cores |
4 GB RAM |
1000 - 2000 |
4 vCPU/cores |
8 GB RAM |
2000 - 5000 |
8 vCPU/cores |
16 GB RAM |
5000+ |
16 vCPU/cores |
32 GB RAM |
Storage
Volume | Description | Recommended Storage |
---|---|---|
|
Messaging: sending text messages and links (without file upload); Low Code: creating plain-text records (without file upload). |
5 MB/user/month |
|
Messaging: sending text messages, links and occasionally sending documents and images; Low Code: attaching documents to records. |
25 MB/user/month |
|
Messaging: uploading large files daily; Low Code: attaching a high number of documents to records daily. |
100 MB/user/month |
-
Base storage (operating system and core components) of 10 GB,
-
recommended storage per user per month based on the matrix above (multiplied by 12 to get the yearly amount),
-
average number of users in a year,
-
apply a safety factor; we recommend at least 2.0.
total = (nr. of users * recommended storage * 12 * safety factor) + base storage
Recommended storage = (30 * 25 MB * 12 * 2) + 10 GB = 28 GB / year
Network
Depending on your configuration, Corteza may need some access to outside services.
If you intend to use any email communication; such as sending confirmation emails, password reset emails, or sending emails from automation scripts; you must configure your SMTP servers to be accessible.
If you enable OAuth2 or OIDC sign-up, or you are accessing external services via automation scripts, you should allow HTTP traffic.
Domain and hostname
-
Hostname for Web application,
-
hostname for API server.
If you already own a domain, you can add two or more hosts and use them to access your Corteza instance.
HTTPS/SSL Certificates
Corteza supports any SSL certificate from all certificate authorities (CA). You can use any existing or new SSL certificate from any commercial SSL certificate provider or self-signed.
We use Let’s Encrypt.
If you aren’t using any other HTTP server, we highly recommend you use Nginx Reverse Proxy and LetsEncrypt companion container for nginx-prox. Its an automated and the simplest way to secure Corteza or any other web application you host. |
Docker Compose
If you are not planning on using Docker you can skip this section entirely. |
Environment setup
If your system already has Docker (we recommend at least version 18.0) and Docker Compose installed, you can safely skip this. You can checkout your Docker version by entering |
If you don’t have Docker installed, or the version is below the recommended version, download and install a Docker community edition for desktop or server or cloud that fits your environment.
docker-compose file
The docker-compose.yaml
file describes the different services, networks and storage configurations, used to configure your Docker containers.
Refer to the Docker Compose documentation for a complete reference.
Some useful Docker Compose commands
Stop and remove containers along with their volumes without confirmation
docker-compose rm --force --stop -v
Server configuration
Core Corteza services are configured via the environment (.env
) file.
It allows a quick deploy to another platform, along with fine-tuning the system’s behaviour and enabled features.
The |
.env
file affects three levels:-
Implicit Docker Compose configuration,
-
variable substitution in Docker configuration,
-
service configuration.
When you are using Docker Compose, you must explicitly reference the environment file for each service in the |
You can use variables defined in the |
Base configuration
These variables control the base Corteza configurations, such as the port and the database DSN.
Type | Default value | Description |
---|---|---|
DB_DSN |
||
|
corteza:corteza@tcp(db:3306)/corteza?collation=utf8mb4_general_ci |
Database connection string <username>:<password>@(<host>:<port>)/<dbname>?collation=utf8mb4_general_ci |
DB_MAX_TRIES |
||
|
100 |
Maximum number of connection retries. |
DB_CONN_ERR_DELAY |
||
|
5 seconds |
Duration between database connection retries. |
DB_CONN_TIMEOUT |
||
|
1 minute |
After how long we should give up on connecting with the database. |
GRPC_SERVER_NETWORK |
||
|
tcp |
Network to use for gRPC. |
GRPC_SERVER_ADDR |
||
|
:50051 |
Where do we listen for gRPC connections. |
GRPC_CLIENT_BACKOFF_DELAY |
||
|
1 minute |
Maximum delay for backoff on connection. |
HTTP_ADDR |
||
|
:80 |
IP and port for the HTTP server. |
HTTP_METRICS |
||
|
false |
Enable (prometheus) metrics. |
HTTP_METRICS_NAME |
||
|
corteza |
Name for metrics endpoint. |
HTTP_METRICS_USERNAME |
||
|
metrics |
Username for the metrics endpoint. |
HTTP_METRICS_PASSWORD |
||
|
(random) |
Password for the metrics endpoint. |
HTTP_CLIENT_TIMEOUT |
||
|
30 seconds |
Default timeout for clients. |
MONITOR_INTERVAL |
||
|
5 minutes |
Output (log) interval for monitoring. |
STORAGE_PATH |
||
|
var/store |
Where do we store uploaded files |
Security
These variables control security aspects of Corteza, such as the JWT token secret and the token lifetime.
Type | Default value | Description | ||
---|---|---|---|---|
AUTH_JWT_SECRET |
||||
|
(random) |
Secret used for signing JWT tokens.
|
||
AUTH_JWT_EXPIRY |
||||
|
1 month |
Expiration time for the auth JWT tokens. |
||
HTTP_CLIENT_TSL_INSECURE |
||||
|
false |
Allow insecure (invalid, expired TSL/SSL certificates) connections.
|
Provisioning
Provisioning allows you to configure a Corteza instance when deployed. It occurs automatically after the Corteza server starts.
We recommend you to keep provisioning enabled as it simplifies version updates by updating the database and updating settings. If you’re doing local development or some debugging, you can disable this. |
Type | Default value | Description |
---|---|---|
PROVISION_ALWAYS |
||
|
true |
Controls if the provisioning should run when the server starts. |
UPGRADE_ALWAYS |
||
|
true |
Controls if the upgradable systems should be upgraded when the server starts. |
Provision authentication settings
Key | Type | Default value | Description |
---|---|---|---|
PROVISION_SETTINGS_AUTH_EXTERNAL_ENABLED |
|||
|
|
true |
Is OAuth2 enabled or disabled. |
PROVISION_SETTINGS_AUTH_EXTERNAL_REDIRECT_URL |
|||
|
|
searches env-variables ( |
|
PROVISION_SETTINGS_AUTH_EXTERNAL_SESSION_STORE_SECRET |
|||
|
|
random 64 char string |
generated 64 char long string if missing. Is session cookie "secure" flag used (if yes, cookie can only be access over HTTPS). |
PROVISION_SETTINGS_AUTH_EXTERNAL_SESSION_STORE_SECURE |
|||
|
|
false |
If HTTPS is used for external auth redirection url, value is set to true. |
PROVISION_SETTINGS_AUTH_FRONTEND_URL_BASE |
|||
|
|
Where the frontend SPA is located. Serves as base for generating other |
|
PROVISION_SETTINGS_AUTH_FRONTEND_URL_PASSWORD_RESET |
|||
|
|
Where the frontend SPA is located, the password reset form. |
|
PROVISION_SETTINGS_AUTH_FRONTEND_URL_EMAIL_CONFIRMATION |
|||
|
|
Where the frontend SPA is located, password email confirmation page.
|
|
PROVISION_SETTINGS_AUTH_FRONTEND_URL_REDIRECT |
|||
|
|
Where the frontend SPA is located.
User will be redirected here on successful external authentication.
Auto discovery uses |
|
PROVISION_SETTINGS_AUTH_EMAIL_FROM_ADDRESS |
|||
|
|
Email address used for sending auth emails (password reset, email confirmation). Name used for sending auth emails (password reset, email confirmation). |
|
PROVISION_SETTINGS_AUTH_EMAIL_FROM_NAME |
|||
|
|
Corteza Team (to-be-configured) |
The email from parameter. |
PROVISION_SETTINGS_AUTH_INTERNAL_ENABLED |
|||
|
|
true |
Controls if users are allowed to use internal authentication features, such as login, sign-up, and password reset. |
PROVISION_SETTINGS_AUTH_INTERNAL_SIGNUP_ENABLED |
|||
|
|
true |
Controls if users are allowed to ue internal authentication sign-up. |
PROVISION_SETTINGS_AUTH_INTERNAL_SIGNUP_EMAIL_CONFIRMATION_REQUIRED |
|||
|
|
false |
Controls if users are required to confirm the email?
Enabled on auto-discovery if server has email capabilities ( |
PROVISION_SETTINGS_AUTH_INTERNAL_PASSWORD_RESET_ENABLED |
|||
|
|
false |
Controls if suers are allowed to use password reset for accounts created via internal sign-up. |
Provision OIDC providers
Type | Default value | Description |
---|---|---|
PROVISION_OIDC_PROVIDER |
||
|
Registers available providers from a list of space delimited provided pairs ( The provider is auto-discovered only if it does not exist (match by name). Also, make sure that your redirect URL ( |
|
PROVISION_SETTINGS_AUTH_EXTERNAL_REDIRECT_URL |
||
|
Sets value for This should be set to |
Provision other external provider
Type | Default value | Description |
---|---|---|
PROVISION_SETTINGS_AUTH_EXTERNAL_GITHUB |
||
|
Github’s app credentials: |
|
PROVISION_SETTINGS_AUTH_EXTERNAL_FACEBOOK |
||
|
Facebook’s app credentials: |
|
PROVISION_SETTINGS_AUTH_EXTERNAL_GOOGLE |
||
|
Google’s app credentials: |
|
PROVISION_SETTINGS_AUTH_EXTERNAL_LINKEDIN |
||
|
LinkedIn’s app credentials: |
|
PROVISION_SETTINGS_AUTH_EXTERNAL_OIDC |
||
|
OIDC provider settings |
SMTP
Type | Default value | Description |
---|---|---|
SMTP_HOST |
||
|
localhost:25 |
The SMTP server hostname. |
SMTP_PORT |
||
|
The SMTP post. |
|
SMTP_USER |
||
|
The SMTP username. |
|
SMTP_PASS |
||
|
The SMTP password. |
|
SMTP_FROM |
||
|
The |
Corredor
Type | Default value | Description |
---|---|---|
CORREDOR_ENABLED |
||
|
true |
Enable/disable Corredor integration. |
CORREDOR_ADDR |
||
|
corredor:80 |
Hostname and port of the Corredor gRPC server. |
CORREDOR_MAX_BACKOFF_DELAY |
||
|
1 minute |
Max delay for backoff on connection. |
CORREDOR_MAX_RECEIVE_MESSAGE_SIZE |
||
int |
16MB |
|
CORREDOR_DEFAULT_EXEC_TIMEOUT |
||
time |
1 minute |
|
CORREDOR_LIST_TIMEOUT |
||
duration |
2 second |
|
CORREDOR_LIST_REFRESH |
||
duration |
2 second |
|
CORREDOR_RUN_AS_ENABLED |
||
bool |
false |
|
CORREDOR_CLIENT_CERTIFICATES_ENABLED |
||
bool |
false |
|
CORREDOR_CLIENT_CERTIFICATES_PATH |
||
string |
/certs/corredor/client |
|
CORREDOR_CLIENT_CERTIFICATES_CA |
||
string |
ca.crt |
|
CORREDOR_CLIENT_CERTIFICATES_PUBLIC |
||
string |
public.crt |
|
CORREDOR_CLIENT_CERTIFICATES_PRIVATE |
||
string |
private.key |
|
CORREDOR_CLIENT_CERTIFICATES_SERVER_NAME |
||
string |
"" |
MinIO
The MinIO integration allows you to replace local storage with cloud storage.
When configured, |
Type | Default value | Description |
---|---|---|
MINIO_ENDPOINT |
||
|
||
MINIO_SECURE |
||
|
true |
|
MINIO_ACCESS_KEY |
||
|
||
MINIO_SECRET_KEY |
||
|
||
MINIO_SSEC_KEY |
||
|
||
MINIO_BUCKET |
||
|
||
MINIO_STRICT |
||
|
false |
Debugging
These parameters help in the development and testing process. When you are deploying to production, these should be disabled to improve performance and reduce storage usage. You should configure external services such as Sentry or ELK to keep track of logs and error reports. |
Sentry
Type | Default value | Description |
---|---|---|
SENTRY_DSN |
||
|
Set to enable Sentry client. |
|
SENTRY_DEBUG |
||
|
false |
Print out debugging information. |
SENTRY_ATTACH_STACKTRACE |
||
|
false |
Attach stacktraces. |
SENTRY_SAMPLE_RATE |
||
|
Sample rate for event submission (0.0 - 1.0, defaults to 1.0). |
|
SENTRY_MAX_BREADCRUMBS |
||
|
Maximum number of breadcrumbs. |
|
SENTRY_SERVERNAME |
||
|
Set reported Server name. |
|
SENTRY_RELEASE |
||
|
(current version) |
Set reported Release. |
SENTRY_DIST |
||
|
Set reported distribution. |
|
SENTRY_ENVIRONMENT |
||
|
Set reported environment. |
Logging
Type | Default value | Description |
---|---|---|
DB_LOGGER |
||
|
false |
Log SQL queries. |
CORREDOR_LOG_ENABLED |
||
|
false |
Log communication with Corredor. |
HTTP_REPORT_PANIC |
||
|
true |
Report HTTP panic to Sentry. |
HTTP_LOG_REQUEST |
||
|
false |
Log HTTP requests. |
HTTP_LOG_RESPONSE |
||
|
false |
Log HTTP responses. |
HTTP_ENABLE_VERSION_ROUTE |
||
|
false |
Enable |
HTTP_ENABLE_DEBUG_ROUTE |
||
|
false |
Enable |
GRPC_CLIENT_LOG |
||
|
false |
Log gRPC communication. |
Delaying API execution
You can configure these options to defer API execution until another external (HTTP) service is up and running.
Delaying API execution can come in handy in complex setups where execution order is important. |
Type | Default value | Description |
---|---|---|
WAIT_FOR |
||
|
0 |
Delays API startup for the amount of time specified (10s, 2m…). This delay happens before service (WAIT_FOR_SERVICES) probing. |
WAIT_FOR_STATUS_PAGE |
||
|
true |
Show temporary status web page. |
WAIT_FOR_SERVICES |
||
|
Space delimited list of hosts and/or URLs to probe.
Host format: Services are probed in parallel. |
|
WAIT_FOR_SERVICES_TIMEOUT |
||
|
1m |
Max time for each service probe. |
WAIT_FOR_SERVICES_PROBE_TIMEOUT |
||
|
30s |
Timeout for each service probe. |
WAIT_FOR_SERVICES_PROBE_INTERVAL |
||
|
5s |
Interval between service probes. |
Corredor server configuration
You can place all configurations into a single |
Corteza Corredor server is configured via the environment (.env
) file.
It allows a quick deploy to another platform, along with fine-tuning the behaviour and enabled features.
The |
You can use variables defined in the |
Base configuration
These variables control the base Corredor server configurations, such as extension search paths, and certificate locations.
Type | Default value | Description |
---|---|---|
CORREDOR_ADDR |
||
|
corredor:80 |
This setting is used by both, Corredor and API Server. For Corredor server: where is server listening on For API server: where can Corredor server be accessed. Used by Corredor and API server. |
CORREDOR_ENABLED |
||
|
false |
This is a setting for API server, will Corredor be used for server automation? Used by Corredor and API server. |
CORREDOR_MAX_BACKOFF_DELAY |
||
|
1m |
Connection timeout (from API server to Corredor) Used by API server. |
CORREDOR_EXEC_CSERVERS_API_BASEURL_TEMPLATE |
||
string |
Location of the Corteza server API.
{host} is replaced with value from env variables (in this order: CORREDOR_EXEC_CSERVERS_API_HOST, DOMAIN, HOSTNAME, HOST), {service} is replaced dynamically inside Corredor with Used by Corredor server. |
|
CORREDOR_EXEC_CSERVERS_API_HOST |
||
string |
Hostname used for template Used by Corredor server. |
|
CORREDOR_LOG_ENABLED |
||
|
corredor |
This setting is used by both, Corredor and API Server. For Corredor service: where is service listening on (gRPC) For API server: where can Corredor service be accessed. Used by Corredor and API server. |
CORREDOR_LOG_LEVEL |
||
|
info |
Defaults to Used by Corredor and API server. |
CORREDOR_LOG_PRETTY |
||
|
false |
Are events logged in one-line JSON or formatted to ease development? Used by Corredor. |
CORREDOR_DEBUG |
||
|
false |
Corredor will log even more information. Used by Corredor. |
CORREDOR_EXT_DEPENDENCIES_AUTO_UPDATE |
||
boolean |
true |
Corredor will auto update script dependencies found in Used by Corredor. |
CORREDOR_EXT_SERVER_SCRIPTS_ENABLED |
||
boolean |
true |
Server scripts are enabled Used by Corredor. |
CORREDOR_EXT_SERVER_SCRIPTS_WATCH |
||
boolean |
true |
Corredor will reload server-scripts on change Used by Corredor. |
CORREDOR_EXT_CLIENT_SCRIPTS_ENABLED |
||
boolean |
true |
Client scripts are enabled Used by Corredor. |
CORREDOR_EXT_CLIENT_SCRIPTS_WATCH |
||
boolean |
true |
Corredor will reload client-scripts on change Used by Corredor. |
Corteza CLI
Corteza command-line interface tool allows you to quickly interact with different parts of the system — from changing the settings to assigning roles to users.
-
Microservice build produce
corteza-server-system
,corteza-server-messaging
andcorteza-server-compose
, -
monolith build produces
corteza-server
binary withsystem
,messaging
,compose
sub-commands.
Provision commands
Base command
Usage:
corteza-server provision [command]
Available Commands:
configuration Create permissions & resources
migrate-database Run database migration scripts
Flags:
-h, --help help for provision
Use "corteza-server provision [command] --help" for more information about a command.
System commands
External authentication
Usage:
corteza-server system auth [command]
Available Commands:
auto-discovery Auto discovers new OIDC client
jwt Generates new JWT for a user
test-notifications Sends samples of all authentication notification to the recipient
Flags:
-h, --help help for auth
Use "corteza-server system auth [command] --help" for more information about a command.
Auto discovers new OIDC client
Usage:
corteza-server system auth auto-discovery [name] [url] [flags]
Flags:
--enable Enable this provider and external auth
-h, --help help for auto-discovery
--skip-validation Skip validation
Sends samples of all authentication notification to the recipient
Usage:
corteza-server system auth test-notifications [recipient] [flags]
Flags:
-h, --help help for test-notifications
Generates new JWT for a user
Usage:
corteza-server system auth jwt [email-or-id] [flags]
Flags:
-h, --help help for jwt
Export system resources
Usage:
corteza-server system export [flags]
Flags:
-h, --help help for export
-p, --permissions Export system permissions
-s, --settings Export settings
Import system resources
Usage:
corteza-server system import [flags]
Flags:
-h, --help help for import
Manage roles
Usage:
corteza-server system roles [command]
Available Commands:
useradd Add user to role
Flags:
-h, --help help for roles
Use "corteza-server system roles [command] --help" for more information about a command.
Add user to role
Usage:
corteza-server system roles useradd [role-ID-or-name-or-handle] [user-ID-or-email] [flags]
Flags:
-h, --help help for useradd
Manage settings
Usage:
corteza-server system settings [command]
Available Commands:
delete Set value (raw JSON) for a specific key (or by prefix)
export Import settings as JSON to stdout or file
get Get value (raw JSON) for a specific key
import Import settings as JSON from stdin or file
list List all
set Set value (raw JSON) for a specific key
Flags:
-h, --help help for settings
Use "corteza-server system settings [command] --help" for more information about a command.
Remove settings for specific keys
Usage:
corteza-server system settings delete [keys, ...] [flags]
Flags:
-h, --help help for delete
--prefix string Filter settings by prefix
Export settings as JSON to stdout or a file
Usage:
corteza-server system settings export [file] [flags]
Flags:
-h, --help help for export
Get value for a specific key
The value is provided as a raw JSON. |
Usage:
corteza-server system settings get [key to get, ...] [flags]
Flags:
-h, --help help for get
Import settings as JSON from stdin or a file
Usage:
corteza-server system settings import [file] [flags]
Flags:
-h, --help help for import
List all settings
Usage:
corteza-server system settings list [flags]
Flags:
-h, --help help for list
--prefix string Filter settings by prefix
Set value for a specific key
The value is provided as a raw JSON. |
Usage:
corteza-server system settings set [key to set] [value] [flags]
Flags:
-h, --help help for set
Sink
Usage:
corteza-server system sink [command]
Available Commands:
signature Creates signature for sink HTTP endpoint
Flags:
-h, --help help for sink
Use "corteza-server system sink [command] --help" for more information about a command.
Create sink signature
Usage:
corteza-server system sink signature [flags]
Flags:
--content-type string Content type (optional)
--expires string Date of expiration (YYYY-MM-DD, optional)
-h, --help help for signature
--max-body-size int Max allowed body size
--method string HTTP method that will be used (optional)
--origin string Origin of the request (arbitrary string, optional)
--path string Full sink request path (do not include /sink prefix, add / for just root)
--signature-in-path Include signature in a path instead of query string
Manage system users
Usage:
corteza-server system users [command]
Available Commands:
add Add new user
list List users
password Change password for user
Flags:
-h, --help help for users
Use "corteza-server system users [command] --help" for more information about a command.
Low Code commands
Export Low Code resources
Usage:
corteza-server compose export [flags]
Flags:
-h, --help help for export
--namespace string Export namespace resources (by ID or string)
-p, --permissions Export system permissions
-s, --settings Export settings
Arguments:
modules Export modules
pages Export pages
charts Export charts
permissions Export permissions
Basic setup for a local demo
The section covers configuration files that are only suitable for a demo on a local environment. All services are on the same network, ports are bound to the host’s network, etc. This is not an optimal setup for a production environment. See Nginx proxy and production setup guides for a production deploy. |
Configurations
Some of the configuration lines in the provided docker-compose file are written in a single line for brevity and simpler enabling/disabling (commenting-out). |
Some operating systems do not like files that start with a dot, so make sure |
.env
########################################################################################################################
# docker-compose supports environment variable interpolation/substitution in compose configuraiton file
# (more info: https://docs.docker.com/compose/environment-variables)
########################################################################################################################
# General settings
VERSION=2020.9
########################################################################################################################
# Ports where these services will be accessible
# In case of an "address already in use" change these ports to a higher number
# Web applications
# http://localhost:18080
LOCAL_DEMO_SPA_PORT=18080
# API Server
# http://localhost:18081
LOCAL_DEMO_API_PORT=18081
# Corredor gRPC server, nothing to see here,
# just for internal traffic between API server and corredor
LOCAL_DEMO_CRD_PORT=18082
########################################################################################################################
# Database connection
DB_DSN=dbuser:dbpass@tcp(db:3306)/dbname?collation=utf8mb4_general_ci
########################################################################################################################
# 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
# Disable email confirmation for sign-up protocol to allow more seamless setup without the need
# for SMTP Server
PROVISION_SETTINGS_AUTH_INTERNAL_SIGNUP_EMAIL_CONFIRMATION_REQUIRED=false
# Point this to your local or external SMTP server
#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>'
docker-compose.yaml
version: '3.5'
services:
webapp:
image: cortezaproject/corteza-webapp:${VERSION}
restart: on-failure
depends_on: [ server ]
# Binds internal port 80 to port LOCAL_DEMO_SPA_PORT on localhost
ports: [ "127.0.0.1:${LOCAL_DEMO_SPA_PORT}:80" ]
environment:
# Monolith API settings informs webapp autoconfiguration script that we're running
# a monolith API server.
MONOLITH_API: "true"
# Configure web application with API location
API_BASEURL: "127.0.0.1:${LOCAL_DEMO_API_PORT}"
server:
image: cortezaproject/corteza-server-monolith:${VERSION}
restart: on-failure
depends_on: [ db, corredor ]
# Binds internal port 80 to port LOCAL_DEMO_API_PORT on localhost
ports: [ "127.0.0.1:${LOCAL_DEMO_API_PORT}:80" ]
env_file: [ .env ]
environment:
# Using name of the service, will connect to server API over internal docker network
CORREDOR_ADDR: "corredor:80"
corredor:
image: cortezaproject/corteza-server-corredor:${VERSION}
restart: on-failure
# Binds internal port 80 to port LOCAL_DEMO_CRD_PORT on localhost
ports: [ "127.0.0.1:${LOCAL_DEMO_CRD_PORT}:80" ]
env_file: [ .env ]
environment:
# We need to replace the default CORREDOR_EXEC_CSERVERS_API_BASEURL_TEMPLATE so that
# we can connect to it on a local network.
#
# Using name of the service, will connect to server API over internal docker network
CORREDOR_EXEC_CSERVERS_API_BASEURL_TEMPLATE: "http://server/{service}"
db:
# MySQL Database
# See https://hub.docker.com/r/percona/percona-server for details
image: percona:8.0
restart: on-failure
environment:
# To be picked up by percona image when creating the database
# Must match with DB_DSN settings inside .env
#
# 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
MYSQL_DATABASE: dbname
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbpass
MYSQL_RANDOM_ROOT_PASSWORD: "yes" # docker-compose logs db |grep "GENERATED ROOT PASSWORD"
healthcheck: { test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"], timeout: 20s, retries: 10 }
Create an empty directory with the .env
and docker-compose.yaml
files.
You can adjust the provided example configuration files as you see fit.
Make sure to change the |
Run the services
docker-compose up -d
Run this command in the same directory as your docker-compose.yaml
file.
It will start all of the services based on the configurations provided in the configuration files.
You can check if everything is running correctly, by executing the docker-compose ps
command.
The output should be similar to this one:
Name Command State Ports
-------------------------------------------------------------------------------------------------------
basic_corredor_1 /corredor/node_modules/.bi ... Up (healthy) 127.0.0.1:18082->80/tcp
basic_db_1 /docker-entrypoint.sh mysqld Up (healthy) 3306/tcp, 33060/tcp
basic_server_1 bin/server serve-api Up (healthy) 127.0.0.1:18081->80/tcp
basic_webapp_1 /entrypoint.sh Up (healthy) 127.0.0.1:18080->80/tcp
You can see 4 services up and running.
Two of them are accessible on localhost (ports 18080
and 18081
).
If you changed the ports in your |
Finishing the setup
-
Direct your browser to
http://localhost:18080
. If you used other ports in your configurations, use those. On your first visit, you should be redirected to the authentication page (/auth
), -
create your account through the sign-up form.
The first user gets automatically promoted to an administrator. You can add additional users by using the sign-up form or by adding them in the administration panel. |
Nginx proxy
This is not needed when working on local instances. Following the setup local demo section is enough to get a local instance up and running. |
We advise against merging/mixing Corteza and It can be done but requires some experience with Docker Compose. |
The following instructions assume that you don’t have anything similar setup on your current environment. If you are using other means of providing traffic forwarding or SSL certificate handling, proceed with caution. |
Containers must be on the same network as |
Nginx Proxy (docker image jwilder/nginx-proxy
) is an auto-configurable reverse-proxy that routes traffic from your public IP to Docker containers on the host.
LetsEncrypt Nginx Proxy Companion (docker image jrcs/letsencrypt-nginx-proxy-companion
) automates the process of creating, renewing and using Let’s Encrypt certificates for your Docker containers.
-
Both images listen for docker events to detect when containers start or stop,
-
Nginx Proxy generates and reloads the configuration, and starts forwarding HTTP traffic to that container based on the
VIRTUAL_HOST
, -
LetsEncrypt companion starts the certificate creation process, reconfigures Nginx Proxy and enables redirection from HTTP to HTTPS based on the
LETSENCRYPT_HOST
.
-
Containers (like Corteza server, and fronted application) that are exposed publicly no longer have to publish their ports on public IP,
-
complicated firewall configurations and network forwarding rules are no longer required.
Configurations
docker-compose.yaml
version: '3.5'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
restart: always
networks:
- proxy
ports:
- "80:80"
- "443:443"
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
volumes:
- ./certs:/etc/nginx/certs
- ./htpasswd:/etc/nginx/htpasswd
- ./vhost.d:/etc/nginx/vhost.d
- ./html:/usr/share/nginx/html
- ./custom.conf:/etc/nginx/conf.d/custom.conf:ro
- /var/run/docker.sock:/tmp/docker.sock:ro
nginx-letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: nginx-letsencrypt
restart: always
depends_on:
- nginx-proxy
volumes:
- ./certs:/etc/nginx/certs
- ./vhost.d:/etc/nginx/vhost.d
- ./html:/usr/share/nginx/html
- /var/run/docker.sock:/var/run/docker.sock:ro
# Create network if it does not exist
networks: { proxy: { name: proxy } }
custom.conf
# Make sure we can upload at least 200Mb files
client_max_body_size 200M;
# Add other custom configs.
#
|
Run the services
docker-compose up -d
You can check if everything is running correctly by executing the docker-compose ps
command.
The output should be similar to this one:
Name Command State Ports
-----------------------------------------------------------------------------------------------------
nginx-letsencrypt /bin/bash /app/entrypoint. ... Up
nginx-proxy /app/docker-entrypoint.sh ... Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
Production setup
You can use similar steps when deploying a staging or a demo environment. |
This setup depends on you running the Nginx proxy service. |
Make sure your nginx-proxy service is up and running before running Corteza. In other cases, you might get an error like:
|
If nginx-proxy refuses to start, inspect your configuration files and compare them with ones provided in the Nginx proxy section. |
DNS
This demo uses 2 example domains; your-demo.example.tld and api.your-demo.example.tld.
You need to configure your DNS by adding two hosts and point them to the IP address (A record) or the hostname (CNAME record) of the server you’re using for running Corteza.
Configurations
Some of the configuration options in the docker-compose are in-lined for brevity and easier enabling/disabling (commenting-out). |
Some operating systems do not like files that start with a dot, so make sure |
.env
########################################################################################################################
# docker-compose supports environment variable interpolation/substitution in compose configuraiton file
# (more info: https://docs.docker.com/compose/environment-variables)
########################################################################################################################
# General settings
DOMAIN=your-demo.example.tld
VERSION=2020.9
########################################################################################################################
# Database connection
DB_DSN=dbuser:dbpass@tcp(db:3306)/dbname?collation=utf8mb4_general_ci
########################################################################################################################
# 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
# Disable email confirmation for sign-up protocol to allow more seamless setup without the need
# for SMTP Server
#PROVISION_SETTINGS_AUTH_INTERNAL_SIGNUP_EMAIL_CONFIRMATION_REQUIRED=false
# Point this to your local or external SMTP server
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>'
########################################################################################################################
# Corredor service settings
# Corredor address is used in Corredor service for grpc server configuration
# and inside Server for configuring corredor gRPC client with location for corredor server
# If these two values are different in your environment for
CORREDOR_ADDR=corredor:80
docker-compose.yaml
version: '3.5'
services:
webapp:
image: cortezaproject/corteza-webapp:${VERSION}
restart: on-failure
depends_on: [ server ]
networks: [ proxy ]
environment:
# VIRTUAL_HOST helps NginX proxy route trafic for specific virtual host to
# this container
VIRTUAL_HOST: ${DOMAIN}
# This is needed only if you are using NginX Lets-Encrypt companion
# (see docs.cortezaproject.org for details)
LETSENCRYPT_HOST: ${DOMAIN}
# Monolith API settings informs webapp autoconfiguration script that we're running
# a monolith API server.
MONOLITH_API: "true"
server:
image: cortezaproject/corteza-server-monolith:${VERSION}
restart: on-failure
env_file: [ .env ]
depends_on: [ db, corredor ]
networks: [ proxy, internal ]
# Uncomment to use local fs for data persistence
# 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 auto-configuration procedure
# If this is changed, make sure you change settings accordingly
VIRTUAL_HOST: api.${DOMAIN}
# This is needed only if you are using NginX Lets-Encrypt companion
# (see docs.cortezaproject.org for details)
LETSENCRYPT_HOST: api.${DOMAIN}
corredor:
image: cortezaproject/corteza-server-corredor:${VERSION}
networks: [ internal ]
restart: on-failure
env_file: [ .env ]
# In case you do not follow the usual setup with $DOMAIN and api.$DOMAIN, please see the
# Documentation on how you can configure Corredor API endpoints with CORREDOR_EXEC_CSERVERS_API_BASEURL_TEMPLATE,
# CORREDOR_EXEC_CSERVERS_API_HOST and other CORREDOR_EXEC_CSERVERS_* variables.
db:
# MySQL Database
# See https://hub.docker.com/r/percona/percona-server for details
image: percona:8.0
restart: on-failure
# Uncomment to use local fs for data persistence
# volumes: [ "./data/db:/var/lib/mysql" ]
environment:
# To be picked up by percona image when creating the database
# Must match with DB_DSN settings inside .env
#
# 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
MYSQL_DATABASE: dbname
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbpass
MYSQL_RANDOM_ROOT_PASSWORD: random # docker-compose logs db |grep "GENERATED ROOT PASSWORD"
healthcheck: { test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"], timeout: 20s, retries: 10 }
networks: [ internal ]
networks:
internal: {}
proxy: { external: true }
Create an empty directory with the .env
and docker-compose.yaml
files.
You can adjust the provided example configuration files as you see fit.
Make sure to change the |
Run the services
docker-compose up -d
Run this command in the same directory as your docker-compose.yaml
file.
It will start all of the services based on the configurations provided in the configuration files.
You can check if everything is running correctly by executing the docker-compose ps
command.
The output should be similar to this one:
Name Command State Ports
-------------------------------------------------------------------------------------------
production_corredor_1 docker-entrypoint.sh node ... Up (healthy) 80/tcp
production_db_1 /docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
production_server_1 /bin/corteza-server serve-api Up (healthy) 80/tcp
production_webapp_1 /entrypoint.sh Up (healthy) 80/tcp
You can see four services up and running.
Your services should soon be available on the configured domains in a matter of minutes. |
Finishing the setup
-
Direct your browser to
http://your-demo.example.tld
. On your first visit, Corteza redirects you to the authentication page (/auth
), -
create your account through the sign-up form.
The first user gets automatically promoted to an administrator. You can add additional users by using the sign-up form or by adding them in the administration panel. |
Relaying inbound emails to Corteza with Postfix
Corteza allows you to detect and react to incoming emails via automation scripts. You can implement automatic responses, create records based on the email content, and forward the email to a Messaging channel.
All further sections assume that the system is configured by following these instructions. If you’ve used anything else, such as MailGun, the examples might not work correctly. |
This section doesn’t cover any script development related topics, such as detecting sink routes. Refer to the integrator guide for more information regarding script development. |
-
Postfix; or similar; forwards the email to the sink API endpoint,
-
Corteza sink service extracts header and body data from received email,
-
onReceive
triggers are filtered for a match (you can configure your triggers to only respond to specific conditions), -
automation scripts are executed.
Corteza setup
For a sink route to work, you must generate a sink signature.
Consider your sink signatures as passwords that allow access to some parts of the system. Make sure they are kept safe and sound. |
We recommend constraining sink signatures as much as possible to help with system security. For example, if we only care about POST requests, let the signature only allow POST requests. Run
|
For example:
docker-compose exec server system sink signature --content-type email
Should output something in the lines of:
/system/sink?__sign=187...3D
Sink request constraints:
- signature should be part of query-string
- body size is not limited
- expecting content type to be "email"
Make sure to specify a |
Take note of the above |
Postfix setup
/etc/postfix/main.cf
:virtual_alias_maps = pcre:/etc/postfix/virtual_alias
Make sure to change the domain in the below snippet. |
/etc/postfix/virtual_alias
:# Catch-all for corteza.domain.tld and redirect it to corteza_sink mailbox
# vv change this vv
/.+@corteza\.domain\.tld$/ corteza_sink
postmap /etc/postfix/virtual_alias
postfix reload
Make sure to change the domain and the sink signature to match your parameters. |
/etc/aliases
corteza_sink: "| curl --data-binary @- 'https://api.your-corteza-instance.tld/system/sink?content-type=email&expires=&method=POST&origin=postfix&__sign=187...3D'"
The above will forward any email for a specific mailbox to a curl command, which then pushes that raw email to the sink endpoint on the Corteza API. |
newaliases
Testing Postfix changes
We recommend using a different machine — one that is not running postfix. |
You can verify if everything works correctly by either sending an email to the configured address or with a simple CLI command:
# Make sure to change `test@corteza.domain.tld`.
echo "hello corteza"|mail -s 'hello' test@corteza.domain.tld
This should produce a new entry in your mail log (usually /var/log/mail.log
) for the test email, along with a log that looks something in the lines of:
postfix/smtpd[23155]: connect from some-host.tld[xxx.xxx.xxx.xxx]
postfix/smtpd[23155]: 277AF5C1B78: client=some-host.tld[xxx.xxx.xxx.xxx]
postfix/cleanup[23159]: 277AF5C1B78: message-id=<b808218e-ce41-6cbf-cb4f-be2b4cf8f776@crust.tech>
postfix/qmgr[14490]: 277AF5C1B78: from=<sender@some-host.tld>, size=1476, nrcpt=1 (queue active)
postfix/smtpd[23155]: disconnect from some-host.tld[xxx.xxx.xxx.xxx] ehlo=2 starttls=1 mail=1 rcpt=1 data=1 quit=1 commands=7
postfix/local[23160]: 277AF5C1B78: to=<corteza_sink@my-server>, orig_to=<demo@corteza.domain.tld>, relay=local, delay=0.67, delays=0.03/0.01/0/0.62, dsn=2.0.0, status=sent (delivered to command: curl --data-binary @- 'https://api.your-corteza-instance.tld/system/sink?content-type=email&expires=&method=POST&origin=postfix&__sign=187...3D')
postfix/qmgr[14490]: 277AF5C1B78: removed
If nothing happens when you send an email, there could be a firewall issue and blocked ports. |
Testing Corteza
To test if your sink signature and automaton script are setup correctly, you can use the following command:
echo "
From: <sender@cortezaproject.org>
To: <test@corteza.domain.tld>
Subject: hello
Message-ID: <1234@local.machine.example>
Ola Corteza!
" | curl -i --data-binary @- "https://api.your-corteza-instance.tld/system/sink?content-type=email&expires=&method=POST&origin=postfix&__sign=187...3D"
If this command does not return a 200 OK
response, it means that something is misconfigured.
Refer to system logs to see exactly where the issue lies.
Backup and restore
We recommend updating your database and uploaded files regularly. It is also highly recommended to do a database backup before you upgrade to a newer Corteza version.
You can define a cron job that backups your data to some external storage. |
Backup the database
We recommend the use of mysqldump
tool.
It’s builtin to the db
container (percona:8.0
image).
If you want to use a different tool to create your backup, you will need to connect to the container or publish MySQL ports. |
By default, |
Do not try to copy raw database files to perform a backup. It might lead to corrupted data. |
# This will dump the entire database and place it in the dump.sql file.
docker-compose exec -T \
--env MYSQL_PWD=your-password db \
mysqldump your-db-name --add-drop-database -u your-username > dump.sql
You can backup your data without shutting down Corteza server. |
Restore the database
# This will restore the database based on the dump.sql file
docker-compose exec -T \
--env MYSQL_PWD=your-password db \
mysql your-db-name -u your-username < dump.sql
We recommend that Corteza server is shut-down until the restore procedure finishes. |
Backup uploaded files
Without object storage service like Min.io, uploaded files are stored directly on the filesystem.
Corteza server is storing data to the /data
directory (if not configured differently with *_STORAGE_PATH
environmental variables).
You can use any one of the standard file management tools to make a backup copy of the files.
# This will compress all your uploaded files into the backup.tar.bz2 archive
tar -cjf backup.tar.bz2 data/server/