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.
| Component | Description | Type |
|---|---|---|
flomation-sentinel | Identity and access management (authentication, users, sessions) | Go service |
flomation-api | Core API server (organisations, workflows, executions) | Go service |
flomation-launch | Trigger/webhook ingress service (webhooks, QR codes, forms) | Go service |
flomation-editor | Web-based workflow editor UI | Node.js application |
flomation-executor | Workflow execution engine (invoked by the Runner) | Go CLI tool |
flomation-runner | Remote execution agent (polls API for pending work) | Go service |
Architecture
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
- Enterprise Linux 8 or 9 (RHEL, Rocky Linux, AlmaLinux, Oracle Linux)
- Root or sudo access
- A PostgreSQL server (see Section 4)
- Network connectivity between all component hosts
- SMTP server (required for user registration email verification)
Recommended Install Order
Components should be installed and configured in this order, as later services depend on earlier ones:
- PostgreSQL database
- Sentinel (identity — no dependencies on other Flomation services)
- API (depends on Sentinel)
- Launch (depends on API)
- Editor (depends on API, Launch, and Sentinel)
- 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:
bashsudo 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:
bashsudo 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:
bashsudo 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:
sqlCREATE 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";
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.
Install
bashsudo dnf install -y flomation-sentinel
Configure
Create the configuration file:
bashsudo 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:
bashsudo 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:trueonly when serving over HTTPS;falsefor 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
| Key | Env Variable | Description |
|---|---|---|
listener.address | LISTEN_ADDRESS | Bind 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.port | LISTEN_PORT | Listen port (default: 8999) |
listener.url | LISTEN_URL | External URL of this Sentinel instance |
database.hostname | DB_HOSTNAME | PostgreSQL hostname |
database.port | DB_PORT | PostgreSQL port |
database.username | DB_USERNAME | PostgreSQL username |
database.password | DB_PASSWORD | PostgreSQL password |
database.database | DB_NAME | PostgreSQL database name |
database.encryption_key | DB_ENCRYPTION_KEY | Encryption key for sensitive data |
database.ssl_mode | DB_SSL_MODE | PostgreSQL SSL mode (disable, require, etc.) |
security.secret | AUTH_SECRET | Secret key for JWT token signing |
security.realm | AUTH_REALM | Authentication realm |
security.login_redirect | AUTH_LOGIN_REDIRECT | Redirect URL after login |
security.logout_redirect | AUTH_LOGOUT_REDIRECT | Redirect URL after logout |
notification.enabled | NOTIFICATIONS_ENABLED | Enable email notifications |
notification.send_from | NOTIFICATIONS_SEND_FROM | Email sender address |
notification.smtp.host | SMTP_HOST | SMTP server hostname |
notification.smtp.port | SMTP_PORT | SMTP server port |
notification.smtp.username | SMTP_USERNAME | SMTP username |
notification.smtp.password | SMTP_PASSWORD | SMTP password |
Start
bashsudo systemctl enable --now flomation-sentinel
Verify the service is running:
bashsudo 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.
Install
bashsudo dnf install -y flomation-api
Configure
Create the configuration file:
bashsudo 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:
bashsudo chown flomation:flomation /opt/flomation/api/config.json sudo chmod 640 /opt/flomation/api/config.json
Configuration Reference
| Key | Env Variable | Description |
|---|---|---|
http.address | LISTEN_ADDRESS | Bind address |
http.port | LISTEN_PORT | Listen port |
database.hostname | DATABASE_HOSTNAME | PostgreSQL hostname |
database.port | DATABASE_PORT | PostgreSQL port |
database.username | DATABASE_USER | PostgreSQL username |
database.password | DATABASE_PASSWORD | PostgreSQL password |
database.database | DATABASE_NAME | PostgreSQL database name |
database.encryption_key | DATABASE_ENCRYPTION_KEY | Encryption key for sensitive data |
database.ssl_mode | DATABASE_SSL_MODE | PostgreSQL SSL mode |
security.identity_service | IDENTITY_SERVICE | URL of the Sentinel instance |
security.allowed_origins | — | Comma-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.url | LAUNCH_SERVICE_URL | URL of the Launch instance |
Start
bashsudo 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.
Install
bashsudo dnf install -y flomation-launch
Configure
Create the configuration file:
bashsudo 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:
bashsudo chown flomation:flomation /opt/flomation/launch/config.json sudo chmod 640 /opt/flomation/launch/config.json
Configuration Reference
| Key | Description |
|---|---|
http.address | Bind address |
http.port | Listen port |
database.hostname | PostgreSQL hostname |
database.port | PostgreSQL port |
database.username | PostgreSQL username |
database.password | PostgreSQL password |
database.database | PostgreSQL database name |
database.encryption_key | Encryption key for sensitive data |
automate.url | URL of the Flomation API instance |
automate.key | (Optional) API key for authenticating with the API |
security.identity_service | URL of the Sentinel instance, used for JWT verification on every request. Required. |
security.editor_url | URL of the Editor. (Optional.) |
public_url | Launch's own externally-reachable URL, used to build OAuth redirect URIs. Required if any inbound identity/OAuth integration is used. |
Start
bashsudo 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).
Install
bashsudo dnf install -y flomation-editor
Configure
The Editor is configured via an environment file. Copy the sample and edit it:
bashsudo 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:
bashsudo chown flomation:flomation /opt/flomation/editor/etc/environment sudo chmod 640 /opt/flomation/editor/etc/environment
Configuration Reference
| Variable | Description | Default |
|---|---|---|
AUTOMATE_API_URL | URL of the Flomation API instance | http://localhost:8080 |
BILLING_API_URL | URL 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_URL | URL of the Flomation Launch instance | http://localhost:8081 |
LOGIN_URL | URL of the Flomation Sentinel instance | http://localhost:8081 |
LAUNCH_URL | Public URL of the Flomation Launch instance, used for externally-reachable webhooks (Slack, Twilio, Teams) | http://localhost:8081 |
PORT | Port for the Editor to listen on | 8080 |
NODE_ENV | Node.js environment | production |
AUTOMATE_API_URL→ the API on port 8888 (the default:8080collides with the Editor's ownPORT).LOGIN_URL→ Sentinel on port 8999 (not:8081).TRIGGER_URLandLAUNCH_URL→ Launch on port 8081.BILLING_API_URL→ the Billing API. There is no client-side fallback toAUTOMATE_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
bashsudo systemctl enable --now flomation-editor
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.
Install
bashsudo 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.
Install
Install both the Runner and Executor on the same host:
bashsudo 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:
bashsudo 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:
bashsudo mkdir -p /opt/flomation/runner/workspace sudo chown flomation:flomation /opt/flomation/runner/workspace
Set appropriate permissions:
bashsudo chown flomation:flomation /opt/flomation/runner/config.json sudo chmod 640 /opt/flomation/runner/config.json
Configuration Reference
| Key | Env Variable | Description |
|---|---|---|
runner.url | FLOMATION_API | URL of the Flomation API instance |
runner.registration_code | FLOMATION_REGISTRATION_CODE | Registration code from the API |
runner.name | FLOMATION_RUNNER_NAME | Display name for this runner |
runner.checkin_timeout | FLOMATION_RUNNER_CHECKIN_TIMEOUT | Poll interval in seconds (default: 5) |
runner.certificate | FLOMATION_RUNNER_CERTIFICATE_PATH | RSA key filename (default: flomation-runner.pem) |
execution.max_concurrent_executors | FLOMATION_RUNNER_MAX_EXECUTORS | Max parallel executions (default: 5) |
execution.execution_directory | FLOMATION_RUNNER_EXECUTION_DIRECTORY | Working directory for executions |
execution.executable_name | FLOMATION_RUNNER_EXECUTABLE_NAME | Absolute path to the executor binary (/opt/flomation/executor/executor). A bare name is not found under systemd's minimal PATH. |
Start
bashsudo 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.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:
- Navigate to your Sentinel instance's
/authenticateendpoint in a browser (e.g.https://sentinel.example.com/authenticate). - Enter your email address. Since no accounts exist yet, Sentinel will present a registration prompt.
- Click Create account.
- Check your email for a verification message containing a link to set your password.
- Click the verification link and set your password.
sudo journalctl -u flomation-sentinel -f2. 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.
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:
- In the Editor, open the Queues section and click Create Queue.
- Each queue displays a registration code — copy it.
- Set it as
runner.registration_codein the Runner'sconfig.json(see Section 10). - Start (or restart) the Runner service — it will register into that queue.
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/.
| Service | Unit Name |
|---|---|
| Sentinel | flomation-sentinel.service |
| API | flomation-api.service |
| Launch | flomation-launch.service |
| Editor | flomation-editor.service |
| Runner | flomation-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:
- stdout/stderr logs:
/opt/flomation/<component>/logs/<component>.logand.err - Symlink:
/var/log/flomation/<component>points to the logs directory
File Locations
| Path | Description |
|---|---|
/opt/flomation/<component>/ | Application install directory |
/opt/flomation/<component>/config.json | Configuration file (Go services) |
/opt/flomation/<component>/etc/environment | Environment file (Editor) |
/opt/flomation/<component>/logs/ | Log directory |
/opt/flomation/snapshots/ | Upgrade snapshots |
/var/log/flomation/<component> | Log symlink |
/etc/systemd/system/flomation-<component>.service | Systemd unit file |
Upgrades
To upgrade a component:
bashsudo dnf update flomation-api
The RPM upgrade process automatically:
- Stops the running service.
- Creates a snapshot of the current installation in
/opt/flomation/snapshots/. - Installs the new version.
- 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:
bashsudo 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:
- Application directories (
usr_t) - Log directories (
var_log_t) - Snapshot directories (
usr_t)
If you encounter SELinux denials, check the audit log:
bashsudo ausearch -m avc -ts recent
To generate and apply a custom policy module if needed:
bashsudo ausearch -m avc -ts recent | audit2allow -M flomation-custom sudo semodule -i flomation-custom.pp
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:
/opt/flomation/sentinel/certificate.crtand/opt/flomation/sentinel/certificate.key/opt/flomation/api/certificate.crtand/opt/flomation/api/certificate.key/opt/flomation/launch/certificate.crtand/opt/flomation/launch/certificate.key
When these files are present, the service serves HTTPS automatically.
When serving over HTTPS, also ensure:
- Sentinel's
security.cookie.secureis set totrue. - The
listener.url(Sentinel),security.identity_service(API), and all URL references in the Editor environment file usehttps://URLs.
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
nginxserver { 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:
bashsudo 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
- Verify PostgreSQL is running and accessible from the service host.
- Check that the database credentials in
config.jsonare correct. - Ensure the
uuid-osspandpgcryptoextensions are installed on every database, and thatvector(pgvector) is installed on the API database and was created by a superuser — see Section 4. - If using SSL, verify the
ssl_modesetting matches your PostgreSQL configuration.
Editor shows blank page or API errors
- Verify the URLs in
/opt/flomation/editor/etc/environmentare correct and reachable from the user's browser (these are client-side URLs). - Delete
/opt/flomation/editor/build/client/run-config.jsand restart the Editor service to regenerate it from the environment file.
Runner cannot register
- Verify the
runner.urlin the Runner'sconfig.jsonpoints to the API server. - Ensure the registration code is valid and has not already been used.
- Check that the Runner can reach the API server over the network.
Verification email not received
- Check Sentinel logs for SMTP errors.
- Verify SMTP settings in Sentinel's
config.json. - Ensure
notification.enabledis set totrue.