Installation Guide

Deploy the Flomation platform on Enterprise Linux 8 & 9 — RHEL, Rocky Linux, AlmaLinux, Oracle Linux.

01 Overview

The Flomation platform consists of six components.

ComponentDescriptionType
flomation-sentinelIdentity and access management (authentication, users, sessions)Go service
flomation-apiCore API server (organisations, workflows, executions)Go service
flomation-launchTrigger/webhook ingress service (webhooks, QR codes, forms)Go service
flomation-editorWeb-based workflow editor UINode.js application
flomation-executorWorkflow execution engine (invoked by the Runner)Go CLI tool
flomation-runnerRemote execution agent (polls API for pending work)Go service

Architecture

Editor Web UI Sentinel Auth / IdAM API Core Service Launch Triggers Runner Agent Executor CLI Tool PostgreSQL Users

Each backend service (Sentinel, API, Launch) requires its own PostgreSQL database. These can run on the same PostgreSQL server for cost savings. The Runner polls the API for pending executions and invokes the Executor to run workflows.

02 Prerequisites

Recommended Install Order

Components should be installed and configured in this order, as later services depend on earlier ones:

  1. PostgreSQL database
  2. Sentinel (identity — no dependencies on other Flomation services)
  3. API (depends on Sentinel)
  4. Launch (depends on API)
  5. Editor (depends on API, Launch, and Sentinel)
  6. Executor and Runner (depend on API)

03 Install the Flomation Repository

Install the Flomation yum repository configuration package on each host that will run a Flomation component.

For EL8:

bash
sudo dnf install -y https://flomation-packages-live.s3.eu-west-2.amazonaws.com/yum/flomation-repo-1.0.1-1.el8.noarch.rpm

For EL9:

bash
sudo dnf install -y https://flomation-packages-live.s3.eu-west-2.amazonaws.com/yum/flomation-repo-1.0.1-1.el9.noarch.rpm

Verify the repository is available:

bash
sudo dnf repolist | grep flomation

04 PostgreSQL Database

The Flomation platform requires a PostgreSQL database with the uuid-ossp and pgcrypto extensions, plus vector (pgvector) on the API database.

Setting up and administering PostgreSQL is outside the scope of this guide. Ensure you have a running PostgreSQL instance accessible from the hosts running Sentinel, API, and Launch.

Create the Database

Connect to your PostgreSQL server and create a database and user for Flomation:

sql
CREATE USER flomation WITH PASSWORD 'your-secure-password'; -- Create databases for each service CREATE DATABASE flomation_sentinel OWNER flomation; CREATE DATABASE flomation_api OWNER flomation; CREATE DATABASE flomation_launch OWNER flomation; -- Connect to each database and enable required extensions \c flomation_sentinel CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS "pgcrypto"; \c flomation_api CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS "pgcrypto"; CREATE EXTENSION IF NOT EXISTS "vector"; -- pgvector; must be run as a superuser \c flomation_launch CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS "pgcrypto";
i
Each service (Sentinel, API, Launch) requires its own database. They can share a single PostgreSQL server for cost savings. Each service manages its own tables and will run migrations automatically on first startup.
i
pgvector is not included in the default Enterprise Linux repositories. Install it on the PostgreSQL host before creating the extension — for example the pgvector_NN package from the PGDG yum repository (where NN matches your PostgreSQL major version), or build it from source against postgresql-server-devel. Because vector is not a trusted extension, CREATE EXTENSION "vector" must be run by a PostgreSQL superuser; the unprivileged flomation user cannot create it, and the API's startup migration will otherwise fail with permission denied to create extension "vector" (or a missing vector.control file if pgvector isn't installed) and leave the database in a dirty migration state.

05 Install Flomation Sentinel

Sentinel provides identity and access management — authentication, user accounts, sessions, and MFA.

flomation-sentinel

Install

bash
sudo dnf install -y flomation-sentinel

Configure

Create the configuration file:

bash
sudo vi /opt/flomation/sentinel/config.json
json
{ "listener": { "address": "0.0.0.0", "port": 8999, "url": "https://sentinel.example.com" }, "database": { "hostname": "db.example.com", "port": 5432, "username": "flomation", "password": "your-secure-password", "database": "flomation_sentinel", "encryption_key": "PLACEHOLDER-GENERATE-A-SECURE-KEY", "ssl_mode": "require" }, "security": { "cookie": { "domain": "example.com", "secure": true, "http_only": false, "expiration": 86400 }, "realm": "example.com", "secret": "PLACEHOLDER-GENERATE-A-SECURE-SECRET", "login_redirect": "https://editor.example.com/", "logout_redirect": "https://editor.example.com/logout" }, "notification": { "enabled": true, "send_from": "noreply@example.com", "smtp": { "host": "smtp.example.com", "port": 587, "username": "smtp-user", "password": "smtp-password" } } }

Set appropriate permissions on the configuration file:

bash
sudo chown flomation:flomation /opt/flomation/sentinel/config.json sudo chmod 640 /opt/flomation/sentinel/config.json
!
security.cookie.http_only must be false. The Editor reads the flomation-token cookie with client-side JavaScript, so an HttpOnly cookie is invisible to it — after login the Editor never receives the token and bounces the user back to the login screen in an infinite redirect loop. Set the other cookie fields to match your deployment:
  • secure: true only when serving over HTTPS; false for plain HTTP.
  • domain: leave empty ("") for a single-host or IP deployment; set it to a shared parent domain (e.g. example.com) only for cross-subdomain SSO.

Configuration Reference

KeyEnv VariableDescription
listener.addressLISTEN_ADDRESSBind address. The default 127.0.0.1 (loopback) makes Sentinel unreachable from the Editor and browsers — set 0.0.0.0 or a specific interface.
listener.portLISTEN_PORTListen port (default: 8999)
listener.urlLISTEN_URLExternal URL of this Sentinel instance
database.hostnameDB_HOSTNAMEPostgreSQL hostname
database.portDB_PORTPostgreSQL port
database.usernameDB_USERNAMEPostgreSQL username
database.passwordDB_PASSWORDPostgreSQL password
database.databaseDB_NAMEPostgreSQL database name
database.encryption_keyDB_ENCRYPTION_KEYEncryption key for sensitive data
database.ssl_modeDB_SSL_MODEPostgreSQL SSL mode (disable, require, etc.)
security.secretAUTH_SECRETSecret key for JWT token signing
security.realmAUTH_REALMAuthentication realm
security.login_redirectAUTH_LOGIN_REDIRECTRedirect URL after login
security.logout_redirectAUTH_LOGOUT_REDIRECTRedirect URL after logout
notification.enabledNOTIFICATIONS_ENABLEDEnable email notifications
notification.send_fromNOTIFICATIONS_SEND_FROMEmail sender address
notification.smtp.hostSMTP_HOSTSMTP server hostname
notification.smtp.portSMTP_PORTSMTP server port
notification.smtp.usernameSMTP_USERNAMESMTP username
notification.smtp.passwordSMTP_PASSWORDSMTP password

Start

bash
sudo systemctl enable --now flomation-sentinel

Verify the service is running:

bash
sudo systemctl status flomation-sentinel

06 Install Flomation API

The API server is the core of the platform — it manages organisations, workflows, executions, runners, and environments.

flomation-api

Install

bash
sudo dnf install -y flomation-api

Configure

Create the configuration file:

bash
sudo vi /opt/flomation/api/config.json
json
{ "http": { "address": "0.0.0.0", "port": 8888 }, "database": { "hostname": "db.example.com", "port": 5432, "username": "flomation", "password": "your-secure-password", "database": "flomation_api", "encryption_key": "PLACEHOLDER-GENERATE-A-SECURE-KEY", "ssl_mode": "require" }, "security": { "identity_service": "https://sentinel.example.com", "allowed_origins": "https://editor.example.com" }, "launch": { "url": "https://launch.example.com" } }

Set appropriate permissions:

bash
sudo chown flomation:flomation /opt/flomation/api/config.json sudo chmod 640 /opt/flomation/api/config.json

Configuration Reference

KeyEnv VariableDescription
http.addressLISTEN_ADDRESSBind address
http.portLISTEN_PORTListen port
database.hostnameDATABASE_HOSTNAMEPostgreSQL hostname
database.portDATABASE_PORTPostgreSQL port
database.usernameDATABASE_USERPostgreSQL username
database.passwordDATABASE_PASSWORDPostgreSQL password
database.databaseDATABASE_NAMEPostgreSQL database name
database.encryption_keyDATABASE_ENCRYPTION_KEYEncryption key for sensitive data
database.ssl_modeDATABASE_SSL_MODEPostgreSQL SSL mode
security.identity_serviceIDENTITY_SERVICEURL of the Sentinel instance
security.allowed_originsComma-separated string of allowed CORS origins (e.g. the Editor URL). Must be a string, not a JSON array (an array makes the API fail to start). If unset, the API allows all origins — set it explicitly.
launch.urlLAUNCH_SERVICE_URLURL of the Launch instance

Start

bash
sudo systemctl enable --now flomation-api

07 Install Flomation Launch

Launch is the trigger and webhook ingress service — it handles webhooks, QR codes, forms, tracking pixels, and scheduled triggers.

flomation-launch

Install

bash
sudo dnf install -y flomation-launch

Configure

Create the configuration file:

bash
sudo vi /opt/flomation/launch/config.json
json
{ "http": { "address": "0.0.0.0", "port": 8081 }, "database": { "hostname": "db.example.com", "port": 5432, "username": "flomation", "password": "your-secure-password", "database": "flomation_launch", "encryption_key": "PLACEHOLDER-GENERATE-A-SECURE-KEY", "ssl_mode": "require" }, "automate": { "url": "https://api.example.com" }, "security": { "identity_service": "https://sentinel.example.com", "editor_url": "https://editor.example.com" }, "public_url": "https://launch.example.com" }

Set appropriate permissions:

bash
sudo chown flomation:flomation /opt/flomation/launch/config.json sudo chmod 640 /opt/flomation/launch/config.json

Configuration Reference

KeyDescription
http.addressBind address
http.portListen port
database.hostnamePostgreSQL hostname
database.portPostgreSQL port
database.usernamePostgreSQL username
database.passwordPostgreSQL password
database.databasePostgreSQL database name
database.encryption_keyEncryption key for sensitive data
automate.urlURL of the Flomation API instance
automate.key(Optional) API key for authenticating with the API
security.identity_serviceURL of the Sentinel instance, used for JWT verification on every request. Required.
security.editor_urlURL of the Editor. (Optional.)
public_urlLaunch's own externally-reachable URL, used to build OAuth redirect URIs. Required if any inbound identity/OAuth integration is used.

Start

bash
sudo systemctl enable --now flomation-launch

08 Install Flomation Editor

The Editor is the web-based UI for designing and managing workflows. It is a Node.js application (React Router / SSR).

flomation-editor

Install

bash
sudo dnf install -y flomation-editor

Configure

The Editor is configured via an environment file. Copy the sample and edit it:

bash
sudo cp /opt/flomation/editor/etc/environment.sample /opt/flomation/editor/etc/environment sudo vi /opt/flomation/editor/etc/environment
bash
# Flomation Editor Configuration AUTOMATE_API_URL=https://api.example.com BILLING_API_URL=https://billing.example.com TRIGGER_URL=https://launch.example.com LOGIN_URL=https://sentinel.example.com LAUNCH_URL=https://launch.example.com PORT=8080 NODE_ENV=production

Set appropriate permissions:

bash
sudo chown flomation:flomation /opt/flomation/editor/etc/environment sudo chmod 640 /opt/flomation/editor/etc/environment

Configuration Reference

VariableDescriptionDefault
AUTOMATE_API_URLURL of the Flomation API instancehttp://localhost:8080
BILLING_API_URLURL of the Flomation Billing API instance. Does not fall back to AUTOMATE_API_URL on the client — if unset, the generated run-config.js uses the literal default below and billing UI features will not work.http://localhost:9085
TRIGGER_URLURL of the Flomation Launch instancehttp://localhost:8081
LOGIN_URLURL of the Flomation Sentinel instancehttp://localhost:8081
LAUNCH_URLPublic URL of the Flomation Launch instance, used for externally-reachable webhooks (Slack, Twilio, Teams)http://localhost:8081
PORTPort for the Editor to listen on8080
NODE_ENVNode.js environmentproduction
!
The defaults above are not usable on a real deployment — set every URL explicitly to match your environment:
  • AUTOMATE_API_URL → the API on port 8888 (the default :8080 collides with the Editor's own PORT).
  • LOGIN_URL → Sentinel on port 8999 (not :8081).
  • TRIGGER_URL and LAUNCH_URL → Launch on port 8081.
  • BILLING_API_URL → the Billing API. There is no client-side fallback to AUTOMATE_API_URL; for a deployment without billing, set it to your API URL (billing features will be inert) or omit it and expect a blank billing area.

Start

bash
sudo systemctl enable --now flomation-editor
i
On first start, the Editor generates a run-config.js file from the environment variables. If you change the environment file, you must delete /opt/flomation/editor/build/client/run-config.js and restart the service for the changes to take effect — a stale run-config.js is the most common cause of "my URL change did nothing".

09 Install Flomation Executor

The Executor is a command-line tool that runs workflow definitions. It is invoked by the Runner and does not run as a persistent service.

flomation-executor

Install

bash
sudo dnf install -y flomation-executor

The Executor binary is installed to /opt/flomation/executor/ and added to the system PATH via /etc/profile.d/flomation-executor.sh.

No additional configuration is needed — the Runner passes all required parameters when invoking the Executor.

10 Install Flomation Runner

The Runner is a background agent that polls the Flomation API for pending workflow executions and invokes the Executor to run them.

flomation-runner

Install

Install both the Runner and Executor on the same host:

bash
sudo dnf install -y flomation-runner flomation-executor

Obtain a Registration Code

Before configuring the Runner, you need a registration code from the API server. This is generated through the Flomation Editor UI after initial platform setup (see Section 11).

Configure

Create the configuration file:

bash
sudo vi /opt/flomation/runner/config.json
json
{ "runner": { "url": "https://api.example.com", "registration_code": "your-registration-code", "name": "runner-01", "checkin_timeout": 5, "certificate": "flomation-runner.pem" }, "execution": { "max_concurrent_executors": 5, "execution_directory": "/opt/flomation/runner/workspace/", "executable_name": "/opt/flomation/executor/executor" } }

Create the workspace directory:

bash
sudo mkdir -p /opt/flomation/runner/workspace sudo chown flomation:flomation /opt/flomation/runner/workspace

Set appropriate permissions:

bash
sudo chown flomation:flomation /opt/flomation/runner/config.json sudo chmod 640 /opt/flomation/runner/config.json

Configuration Reference

KeyEnv VariableDescription
runner.urlFLOMATION_APIURL of the Flomation API instance
runner.registration_codeFLOMATION_REGISTRATION_CODERegistration code from the API
runner.nameFLOMATION_RUNNER_NAMEDisplay name for this runner
runner.checkin_timeoutFLOMATION_RUNNER_CHECKIN_TIMEOUTPoll interval in seconds (default: 5)
runner.certificateFLOMATION_RUNNER_CERTIFICATE_PATHRSA key filename (default: flomation-runner.pem)
execution.max_concurrent_executorsFLOMATION_RUNNER_MAX_EXECUTORSMax parallel executions (default: 5)
execution.execution_directoryFLOMATION_RUNNER_EXECUTION_DIRECTORYWorking directory for executions
execution.executable_nameFLOMATION_RUNNER_EXECUTABLE_NAMEAbsolute path to the executor binary (/opt/flomation/executor/executor). A bare name is not found under systemd's minimal PATH.

Start

bash
sudo systemctl enable --now flomation-runner
!
execution.executable_name must be the absolute path to the executor binary (/opt/flomation/executor/executor). The binary is named executor, and /etc/profile.d/flomation-executor.sh only adds it to the PATH of interactive login shells — the systemd service runs with a minimal PATH, so a bare name fails with executable file not found in $PATH and the Runner can never register.
i
On first start, the Runner automatically generates an RSA key pair (flomation-runner.pem) and registers itself with the API server.

11 First-Time Setup

Once all services are running, follow these steps to bootstrap the platform.

1. Register the First User

Sentinel provides a self-registration flow:

  1. Navigate to your Sentinel instance's /authenticate endpoint in a browser (e.g. https://sentinel.example.com/authenticate).
  2. Enter your email address. Since no accounts exist yet, Sentinel will present a registration prompt.
  3. Click Create account.
  4. Check your email for a verification message containing a link to set your password.
  5. Click the verification link and set your password.
i
SMTP must be configured correctly in Sentinel for the verification email to be delivered. Check the Sentinel logs if the email does not arrive: sudo journalctl -u flomation-sentinel -f

2. Log In to the Editor

Navigate to your Editor instance (e.g. https://editor.example.com). You will be redirected to Sentinel to authenticate. Log in with the credentials you just created.

3. Create an Organisation

After logging in, the API automatically creates your user record. You can then create your first organisation through the Editor UI.

i
Creating an organisation is a prerequisite for registering runners. Queues — and the registration codes runners need — are organisation-scoped, so the Queues section only appears once you are working inside an organisation (it is hidden in personal mode).

4. Register a Runner

To execute workflows, you need at least one Runner registered. Registration codes are issued per queue, not from the Runners page:

  1. In the Editor, open the Queues section and click Create Queue.
  2. Each queue displays a registration code — copy it.
  3. Set it as runner.registration_code in the Runner's config.json (see Section 10).
  4. Start (or restart) the Runner service — it will register into that queue.
i
The Runners page only lists already-registered runners and copies their codes; it has no code-generation action. Registration codes come from creating a Queue. (Managing queues requires the runner.manage permission, which organisation admins have.)

12 Service Management

All Flomation services are managed via systemd. The RPM packages install service unit files to /etc/systemd/system/.

ServiceUnit Name
Sentinelflomation-sentinel.service
APIflomation-api.service
Launchflomation-launch.service
Editorflomation-editor.service
Runnerflomation-runner.service

Common operations:

bash
# Start a service sudo systemctl start flomation-api # Stop a service sudo systemctl stop flomation-api # Restart a service sudo systemctl restart flomation-api # View service status sudo systemctl status flomation-api # View logs sudo journalctl -u flomation-api -f

Log Files

Service logs are written to:

File Locations

PathDescription
/opt/flomation/<component>/Application install directory
/opt/flomation/<component>/config.jsonConfiguration file (Go services)
/opt/flomation/<component>/etc/environmentEnvironment file (Editor)
/opt/flomation/<component>/logs/Log directory
/opt/flomation/snapshots/Upgrade snapshots
/var/log/flomation/<component>Log symlink
/etc/systemd/system/flomation-<component>.serviceSystemd unit file

Upgrades

To upgrade a component:

bash
sudo dnf update flomation-api

The RPM upgrade process automatically:

  1. Stops the running service.
  2. Creates a snapshot of the current installation in /opt/flomation/snapshots/.
  3. Installs the new version.
  4. Restarts the service.

13 Firewall Configuration

If firewalld is enabled, you will need to open ports for each service running on the host. The specific ports depend on your configuration.

For example, to allow traffic to the API on port 8888:

bash
sudo firewall-cmd --permanent --add-port=8888/tcp sudo firewall-cmd --reload

Repeat for each service port as needed. Only open ports that need to be accessible from other hosts — services communicating on localhost do not require firewall rules.

14 SELinux

The Flomation RPM packages handle SELinux context configuration automatically during installation.

The packages set appropriate contexts for:

If you encounter SELinux denials, check the audit log:

bash
sudo ausearch -m avc -ts recent

To generate and apply a custom policy module if needed:

bash
sudo ausearch -m avc -ts recent | audit2allow -M flomation-custom sudo semodule -i flomation-custom.pp
i
The RPM packages require policycoreutils-python-utils for SELinux context management. This is pulled in as a dependency automatically.

15 TLS Configuration

The Sentinel, API, and Launch services support TLS termination directly. This is the recommended way to serve Flomation over HTTPS — a separate reverse proxy is not required.

Direct TLS termination (recommended)

Place the certificate and private key in each service's installation root:

When these files are present, the service serves HTTPS automatically.

When serving over HTTPS, also ensure:

Editor

The Editor service does not support TLS termination directly. To serve the Editor over HTTPS, place it behind a reverse proxy such as nginx, HAProxy, or Caddy that handles TLS termination.

Example: nginx

nginx
server { listen 80; server_name editor.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name editor.example.com; ssl_certificate /etc/nginx/ssl/editor.crt; ssl_certificate_key /etc/nginx/ssl/editor.key; location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }

Replace editor.example.com and the certificate paths with values appropriate for your environment.

Reverse proxy (optional for Sentinel, API, Launch)

A TLS-terminating reverse proxy such as HAProxy, nginx, or Caddy is also supported in front of Sentinel, API, and Launch. This can be useful for consolidating certificates, terminating TLS at the network edge, or fronting multiple services on a single hostname.

When using a reverse proxy, ensure the X-Forwarded-For and X-Forwarded-Proto headers are set correctly.

16 Troubleshooting

Service fails to start

Check the service logs:

bash
sudo journalctl -u flomation-<component> -e --no-pager sudo cat /opt/flomation/<component>/logs/<component>.err

First start logs "unable to load config"

Every Go service package (Sentinel, API, Launch, Runner) auto-starts immediately on install — before its config.json exists — and logs a single fatal: unable to load config. This is expected. Once you write the configuration file and start (or restart) the service, it recovers. Don't mistake this first-boot message for a failure.

Database connection errors

Editor shows blank page or API errors

Runner cannot register

Verification email not received