Installation & Deployment
This guide covers deploying FT Configs Service — the centralized configuration management backend for ACS, Angular Console, Provision Portal, Northbound API, and Service API — as a single Docker container.
FT Configs Service does not ship a database or Hazelcast; both are external dependencies you provision separately (see Required External Dependencies). Its companion frontend, FT Configs UI, is a separate container with its own installation guide and is out of scope here. To deploy the two together as one stack, see FT Configs Stack deployment.
1. Overview
FT Configs Service is deployed as a single container (ft-configs-service) — a Spring Boot 4 / Java 25 application — exposing its REST API, Actuator, and Swagger UI under the context path /configs-service.
Docker Compose is the only deployment method described here: the repository builds a Spring Boot fat jar and a container image, not a distribution archive.
Configurations are persisted in MySQL or Oracle and published to a Hazelcast cache for runtime consumers, chiefly FTACS.
The database, the Hazelcast cluster, and FTACS itself are assumed to be deployed already — see All in one server deployment or Separate server deployment.
Angular Console / Provision Portal / Northbound API -> FT Configs Service -> MySQL / Oracle + Hazelcast -> FTACS
|
FT Configs Service publishes ACS runtime configuration into the shared Hazelcast cluster that FTACS consumes. FTACS treats it as a hard dependency since version 6.5.2: without a published snapshot, FTACS starts with no ACS configuration, no web service users, and no parameter-name cache rules — silently, with no connection error in either log. FT Configs Service and FTACS must be clients of the same Hazelcast cluster. FTACS is not deployed or documented here; see Required External Dependencies. |
2. Prerequisites
2.1. Host Requirements
| Component | Minimum | Recommended | Notes |
|---|---|---|---|
Docker Engine |
20.10 |
Latest stable |
Runs the |
Docker Compose |
2.0 |
Latest stable |
The compose file in Docker Compose uses Compose v2 syntax |
RAM |
2 GB |
4 GB |
The JVM is container-aware ( |
Free disk space |
1 GB |
1 GB or more |
Image plus the mounted |
|
JDK 25 is only required for local Gradle builds ( |
2.2. Required External Dependencies
These services must be installed, running, and reachable from this host before FT Configs Service starts. None of them are deployed by this guide.
| Component | Minimum Version | Why It Is Needed | Port | Required |
|---|---|---|---|---|
MySQL or Oracle |
MySQL 8.4; Oracle — verify with FT DevOps |
Stores every configuration the service serves. Liquibase creates the tables on first startup inside an already existing |
3306 (TCP) for MySQL, 1521 (TCP) for Oracle |
Yes |
Hazelcast |
5.7 |
Receives the published configuration snapshots. It must be the same cluster FTACS connects to; without it FTACS starts with no ACS configuration, no web service users, and no parameter-name cache rules. Not needed when the service runs without FTACS integration. |
5701 (TCP) |
No (optional) |
|
The Hazelcast minimum version reflects the client library the service ships with ( |
2.3. Supported Operating Systems
| Deployment | Operating system |
|---|---|
Docker |
Linux (recommended), macOS, or Windows with WSL2 |
2.4. Registry Access
Network access to the hub.friendly-tech.com Docker registry (or offline image archives — see Offline Servers).
Access to the FT_DISK — ft-configs/backend folder for the deployment files (compose.yml, the shared .env, and the per-service ft-configs-service/.env) and the configuration templates.
2.5. Create the Database Schema and User
FT Configs Service does not create the database, schema, or user itself. Liquibase migrations run on startup and create the tables inside an already-existing schema, using a user that already has the required privileges. Provision the schema and user before the first startup; the credentials must match the values you set in ft-configs-service/.env in Environment Configuration.
|
The passwords in the snippets below ( |
- MySQL
-
Connect as a privileged user (e.g.
root) and create theconfigsschema and theftacs_configsuser:CREATE DATABASE IF NOT EXISTS configs; CREATE USER IF NOT EXISTS 'ftacs_configs'@'%' IDENTIFIED BY 'ftacs_configs'; GRANT ALL PRIVILEGES ON configs.* TO 'ftacs_configs'@'%'; FLUSH PRIVILEGES;The shared QA provisioning script creates several service databases ( flowable,ftacs_quartz,ftacs_qoe_ui,configs) in one file. Only theconfigsschema and theftacs_configsuser shown above are required by FT Configs Service. - Oracle
-
Connect as a privileged user (e.g.
SYS/SYSTEM) and create the tablespace and theconfigsuser:CREATE TABLESPACE configs_data DATAFILE '&1/configs_data01.dbf' SIZE 100M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED; CREATE USER configs IDENTIFIED BY configs DEFAULT TABLESPACE configs_data TEMPORARY TABLESPACE temp QUOTA UNLIMITED ON configs_data; GRANT CONNECT, RESOURCE TO configs; GRANT CREATE TABLE TO configs; GRANT CREATE SEQUENCE TO configs; GRANT CREATE VIEW TO configs;This user (
configs) and its password must matchORACLE_USER/ORACLE_PASSWORDinft-configs-service/.env. The connection uses theXEPDB1pluggable-database service, selected throughDB_SERVICE=XEPDB1in the shared.env— see Switching to Oracle.
3. Network Requirements
Outbound connections FT Configs Service opens to its infrastructure. Each row is a connection that must be open through firewalls when the peer is on another host; traffic to peers on the same Docker bridge needs no rule. Inbound connections — API clients (Angular Console, Provision Portal, Northbound API) and Prometheus scraping — arrive on the published HTTP/HTTPS ports listed in Port Reference.
| Destination | Port | Protocol | Purpose |
|---|---|---|---|
Database |
3306 (MySQL), 1521 (Oracle) |
TCP |
JDBC connection to the |
Hazelcast |
5701 |
TCP |
Publishes configuration snapshots to the cluster FTACS reads from |
|
For a quick connectivity check from any host:
|
3.1. Docker Networking
The compose file in Docker Compose attaches the container to a user-defined bridge network (ft-network) and adds extra_hosts: "host.docker.internal:host-gateway".
-
Peers on the same bridge are reached by container name and container port (for example
mysql:3306). -
When the database or Hazelcast cluster runs on the host machine rather than in Docker, use
host.docker.internal(works on Docker Desktop, and on Linux through theextra_hostsentry above) or the host’s real IP address inMYSQL_HOST/ORACLE_HOSTandHZ_MEMBERS.localhostwill not work — inside the container it points at the container itself. -
Peers on another host are reached by that host’s IP and the published port.
4. Registry Authentication
FT Configs Service images are pulled from hub.friendly-tech.com. Authenticate once per host before the first docker compose up.
docker login hub.friendly-tech.com
Enter the read-only pull credentials when prompted:
| Field | Value |
|---|---|
Username |
|
Password |
|
|
The |
Alternatively, log in non-interactively:
echo "fokxuw-fymte1-taSxyc" | docker login hub.friendly-tech.com -u readonly --password-stdin
Verify authentication:
docker info | grep -A 5 Registry
4.1. Offline Servers
When the target host cannot reach hub.friendly-tech.com, pull the image on a machine that does have registry access, export it to an archive, transfer it, and load it on the offline host.
The connected machine can run Linux, macOS, or Windows — commands are given for both shells below. It does not need to be the same platform as the offline host.
|
An explicit |
-
On the offline host, find out which architecture it runs — this is the value you will pass as
PLATFORMbelow. Ask Docker itself, since it reports what the daemon will actually accept:docker version --format '{{.Server.Arch}}'If Docker is not installed there yet, use the operating system instead —
uname -mon Linux/macOS, orecho $env:PROCESSOR_ARCHITECTUREin PowerShell on Windows. Map the result:docker versionreportsuname -m/ Windows reportsUse as PLATFORMamd64x86_64/AMD64linux/amd64arm64aarch64/ARM64linux/arm64On Windows with Docker Desktop,
{{.Server.Arch}}reports the architecture of the Linux VM that actually runs the containers — which is the value you want, not the Windows host’s own architecture. -
On a machine with registry access, log in. Run this on its own — it prompts for a password, so anything pasted after it would be swallowed as input:
docker login hub.friendly-tech.com -
Pull and export the image. Paste the whole block as-is; the only lines to change are
PLATFORMandTAGon top.Linux / macOS (bash):
PLATFORM=linux/amd64 TAG=latest docker pull --platform "$PLATFORM" "hub.friendly-tech.com/configs/ft-configs-service:$TAG" docker save "hub.friendly-tech.com/configs/ft-configs-service:$TAG" | gzip > "ft-configs-service-$TAG.tar.gz"Windows (PowerShell):
$PLATFORM = "linux/amd64" $TAG = "latest" docker pull --platform $PLATFORM "hub.friendly-tech.com/configs/ft-configs-service:$TAG" docker save -o "ft-configs-service-$TAG.tar" "hub.friendly-tech.com/configs/ft-configs-service:$TAG"On Windows, always write the archive with
docker save -o <file>. Piping or redirectingdocker savefrom PowerShell corrupts the archive — the pipeline re-encodes the stream as text instead of raw bytes, anddocker loadthen fails withunexpected EOForinvalid tar header. To compress for transfer, use the bundledtar.exe(Windows 10 1803+ / Server 2019+):tar.exe -czf ft-configs-service.tar.gz ft-configs-service-$TAG.tar. -
Transfer the archive to the offline host, together with
compose.yml, the shared.env, andft-configs-service/.env. -
On the offline host, load the archive and start the service. Set
TAGto the same value used above:Linux (bash):
TAG=latest gzip -dc "ft-configs-service-$TAG.tar.gz" | docker load docker compose up -d ft-configs-serviceWindows (PowerShell):
$TAG = "latest" docker load -i "ft-configs-service-$TAG.tar" docker compose up -d ft-configs-service
Confirm the image is present before starting, so a missing or mis-architected image fails here rather than mid-startup:
docker images hub.friendly-tech.com/configs/ft-configs-service
Upgrades use the same flow: pull the new tag on the connected machine, transfer and load the archive, then docker compose up -d ft-configs-service.
|
This covers the FT Configs Service image only.
The database and Hazelcast are separate images on their own hosts — for the offline procedure covering a whole stack, see All in one server deployment — Offline Servers, which derives the image list from |
5. Preparation
5.1. Directory Structure
mkdir -p /usr/local/ft-system/ft-configs-service/{config,logs}
cd /usr/local/ft-system
# The container runs as a non-root user (UID 1001) and writes file logs to the
# mounted logs/ directory. Grant write access so the application can write logs:
sudo chown -R 1001:1001 /usr/local/ft-system/ft-configs-service/logs
|
The container runs as the non-root user |
Download the deployment files from the FT_DISK — ft-configs/backend folder, or copy the templates from the source repository’s docker/ directory.
5.1.1. Directory Layout
FT Configs Service occupies one subdirectory of the platform working directory, alongside compose.yml and the shared .env:
/usr/local/ft-system/
├── compose.yml # from FT_DISK
├── .env # shared stack environment
└── ft-configs-service/
├── .env # per-service environment
├── config/ # -> /etc/app
│ └── keystore.p12 # TLS keystore (only when HTTPS is enabled)
└── logs/ # -> /app/logs (written by the container as UID 1001)
| Path | Content | Backup |
|---|---|---|
|
Stack definition; the FT Configs Service block is shown in Docker Compose. |
Yes |
|
Shared stack environment: database connection ( |
Yes |
|
Per-service environment: host ports, schema credentials, HikariCP pool, JVM settings, JWT, bootstrap admin, CORS, mail. |
Yes |
|
Mounted to |
Yes |
|
Mounted to |
No |
5.2. Environment Configuration
FT Configs Service reads its configuration from environment variables loaded via --env-file / env_file. The platform uses a two-layer environment file architecture — there is no file per database vendor:
| File | Purpose |
|---|---|
|
Shared by every service: database connection ( |
|
Per-service only: host ports, the |
MySQL is the default. Switching to Oracle is not a file swap — change DB_PROFILE, SPRING_PROFILES_ACTIVE, DB_HOST, DB_PORT and DB_SERVICE inside the single root .env, as listed in Switching to Oracle. compose.yml maps the generic DB_* names onto the vendor-specific ones this service expects through the service’s environment: block — MYSQL_HOST/MYSQL_PORT in a MySQL stack, ORACLE_HOST/ORACLE_PORT/ORACLE_SERVICE in an Oracle one — so the application keeps reading MYSQL_* / ORACLE_* unchanged. The block is shown in Docker Compose; when you write your own compose.yml, it must be present, otherwise these variables stay unset in the container and the service falls back to its built-in defaults and cannot reach the database.
The most important values to set, and the layer each belongs to:
| Variable | Description | Default | Required |
|---|---|---|---|
|
Selects the database profile: |
|
Yes |
|
Base64-encoded HMAC-SHA256 key that decodes to at least 32 bytes; startup fails otherwise. Generate per environment: |
empty |
Yes |
|
Password of the bootstrap admin account (username |
empty |
Yes, on first startup |
|
MySQL connection — must match the schema and user created in Create the Database Schema and User. Host and port come from |
|
Yes, with |
|
Oracle connection — must match the user created in Create the Database Schema and User. Host, port and service come from |
|
Yes, with |
|
The UI host/port the user types in the browser, for both HTTP and HTTPS. Never the internal Docker service name. In a Docker deployment replace |
No |
|
|
Hazelcast member(s), e.g. |
unset |
No |
|
Container timezone. Set in the shared |
|
No |
|
Download both env files from FT_DISK, or create them from the FT Configs Service Environment Variables reference:
SharePoint may strip the leading dot when downloading dotfiles; rename |
| When the database or Hazelcast cluster runs on the host machine rather than in Docker, set the host-side addresses as described in Docker Networking. |
The full variable reference:
|
Do not commit secrets ( |
|
|
5.3. A) Quick start (most common knobs)
| Variable | Required | Default | Description |
|---|---|---|---|
|
Yes |
|
Active Spring profile: |
|
No |
|
Primary server port. When |
|
No |
|
Plain HTTP port. In dual-mode (HTTP + HTTPS), set this to a different value than |
|
No |
from Hazelcast client config |
Comma-separated Hazelcast members ( |
|
No |
Comma-separated list of allowed CORS origins. Must match the URL the user sees in the browser address bar (where the frontend is loaded from), never the internal Docker service name. Scheme-sensitive: |
|
|
No |
|
Log level for the application package. Values: |
5.4. B) Database (MySQL profile: SPRING_PROFILES_ACTIVE=mysql)
Provide either MYSQL_JDBC_URL or the decomposed MYSQL_HOST/MYSQL_PORT/MYSQL_SCHEMA inputs.
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
derived if unset |
Full MySQL JDBC URL. Recommended for Docker/Kubernetes to avoid host, port, and schema drift. |
|
No |
|
Shared DB host fallback used by MySQL and Oracle when profile-specific host is not set. |
|
No |
|
MySQL host used if |
|
No |
|
MySQL port used if |
|
No |
|
MySQL schema used if |
|
No |
|
MySQL username for the service. The env templates in |
|
No |
|
MySQL password for the service. The env templates in |
|
No |
|
Override JDBC driver class if needed. |
|
No |
|
HikariCP max pool size. |
|
No |
|
HikariCP minimum idle connections. |
|
No |
|
HikariCP connection timeout in milliseconds. |
When both *_JDBC_URL and decomposed variables are set, the explicit JDBC URL always takes precedence.
|
5.5. C) Database (Oracle profile: SPRING_PROFILES_ACTIVE=oracle)
Provide either ORACLE_JDBC_URL or the decomposed ORACLE_HOST/ORACLE_PORT/ORACLE_SERVICE (plus optional ORACLE_SCHEMA) inputs.
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
derived if unset |
Full Oracle JDBC URL. Recommended for Docker/Kubernetes to avoid host, port, and service drift. |
|
No |
|
Oracle host used if |
|
No |
|
Oracle port used if |
|
No |
|
Oracle service name used if |
|
No |
empty |
Optional schema mapped to |
|
No |
|
Oracle username for the service. |
|
No |
|
Oracle password for the service. Treat as a secret. |
|
No |
|
Override Oracle JDBC driver class if needed. |
5.6. D) Hazelcast / cache
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
|
Base path for Hazelcast config files. |
|
No |
|
When true, starts an embedded Hazelcast member from |
|
No |
|
Name of the Hazelcast cache from which ACS publishes product-class groups, consumed by the |
5.7. E) Auth / JWT & cookies
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
defined in profile |
Base64-encoded HMAC-SHA256 signing key. Must decode to at least 32 bytes (256-bit) or startup fails. Generate with |
|
No |
|
Access token expiration in milliseconds. |
|
No |
|
Refresh token expiration in milliseconds. |
|
No |
|
Set |
|
No |
empty |
Optional domain for cross-subdomain cookie sharing. |
5.7.1. Mail
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
|
Email delivery mode (case-insensitive; blank or unknown falls back to |
|
No |
|
SMTP host used for registration and deletion flows. Under |
|
No |
|
SMTP port. |
|
No |
SMTP username. Under |
|
|
No |
SMTP password. Treat as a secret. Under |
|
|
No |
|
Usually |
|
No |
|
SMTP authentication toggle. |
|
No |
|
STARTTLS toggle. |
|
No |
|
From address used in sent emails. |
|
No |
empty |
URL for the "Sign In" call-to-action button in emails. Must start with |
The MAIL_FROM_NAME variable has been removed.
The sender display name is now localized via the mail.brand message key (mail_messages*.properties), returning "Configuration Center" (EN) or the localized equivalent for other locales.
|
5.7.2. Audit
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
|
Number of days to retain audit events. Minimum 3, maximum 90. Set to |
|
No |
empty |
Comma-separated list of additional sensitive field names to redact in audit snapshots and change records. Added on top of the 18 built-in defaults (password, token, secret, apiKey, etc.). |
5.7.3. Bootstrap admin (first install)
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
|
Username for first startup when no admin exists. |
|
Yes (first startup) |
empty |
Password for bootstrap admin. Must be set on first startup or the admin account will not be created. Rotate immediately after bootstrap via |
|
No |
empty |
Optional email assigned to bootstrap admin. |
|
No |
empty |
Optional locale for bootstrap admin. |
5.7.4. JVM / container runtime
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
set in Docker image |
JVM options passed by |
|
No |
|
Container timezone. |
For comprehensive details on every configuration option, see the Configuration Guide.
5.8. TLS Keystore (optional)
To enable HTTPS, provide a PKCS12 keystore file. Place keystore.p12 in the config/ directory on the host (mounted to /etc/app/ inside the container).
For local development, generate a self-signed keystore:
cd /usr/local/ft-system/ft-configs-service
keytool -genkeypair \
-alias server \
-keyalg RSA \
-keysize 2048 \
-storetype PKCS12 \
-keystore config/keystore.p12 \
-validity 3650 \
-storepass <keystore-password> \
-keypass <key-password> \
-dname "CN=*.friendly-tech.com, OU=Dev, O=Friendly, L=Local, ST=Local, C=US" \
-ext "SAN=dns:*.friendly-tech.com,dns:friendly-tech.com,dns:localhost,ip:127.0.0.1"
Then set in ft-configs-service/.env:
-
SERVER_SSL_ENABLED=true -
SERVER_PORT=8443(HTTPS primary),SERVER_HTTP_PORT=8080(HTTP secondary — must differ) -
SERVER_SSL_KEY_STORE=file:/etc/app/keystore.p12 -
SERVER_SSL_KEY_STORE_PASSWORD=<keystore-password> -
SERVER_SSL_KEY_PASSWORD=<key-password>
| For production, use a certificate issued by your CA/security team and export it to PKCS12 format. |
6. Deployment
6.1. Startup Dependencies
FT Configs Service has no depends_on on its infrastructure — the database and Hazelcast cluster live outside this stack, so Compose cannot gate on their health. Both must be up before it launches: Liquibase applies the schema migrations on first start, and the Hazelcast client connects during context initialisation.
Wait for each of them explicitly before starting the service:
# Wait for the database
until nc -z <db-host-ip> 3306; do sleep 2; done
# Wait for Hazelcast
until nc -z <hazelcast-host-ip> 5701; do sleep 2; done
# Then start FT Configs Service
docker compose up -d ft-configs-service
FT Configs Service itself restarts cleanly at any time once the infrastructure is up — restart: unless-stopped reconnects it after a host reboot.
6.2. Docker Compose
Click to expand compose.yml (FT Configs Service)
services:
ft-configs-service:
image: hub.friendly-tech.com/configs/ft-configs-service:latest
container_name: ft-configs-service
# The database and Hazelcast are external to this stack, so there is no
# depends_on. They must be reachable before the service starts -- see
# <<startup-dependencies>>.
env_file:
- .env
- ./ft-configs-service/.env
environment:
# Maps the generic DB_* names from the shared .env onto the vendor-specific
# names this service reads. With DB_PROFILE=oracle, replace the MYSQL_* lines
# with: ORACLE_HOST: ${DB_HOST} / ORACLE_PORT: ${DB_PORT} / ORACLE_SERVICE: ${DB_SERVICE}
SPRING_PROFILES_ACTIVE: ${DB_PROFILE}
MYSQL_HOST: ${DB_HOST}
MYSQL_PORT: ${DB_PORT}
HZ_MEMBERS: ${HZ_MEMBERS}
JAVA_OPTS: "${FT_CONFIGS_SERVICE_JAVA_RAM:--Xms512m -Xmx1g} -Duser.timezone=${TZ:-UTC}"
ports:
- "${FT_CONFIGS_SERVICE_HTTP_PORT:-8087}:8080"
- "${FT_CONFIGS_SERVICE_HTTPS_PORT:-8447}:8443"
volumes:
- ./ft-configs-service/config:/etc/app
- ./ft-configs-service/logs:/app/logs
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1:8080/configs-service/actuator/health"]
interval: 10s
timeout: 5s
retries: 50
networks:
- ft-network
networks:
ft-network:
driver: bridge
The default published ports are 8087 (HTTP) and 8447 (HTTPS) rather than 8080/8443, to avoid clashing with FT QoE Web (8086) when FT Configs Service runs alongside the rest of the platform on a shared host — see FT Configs Service Environment Variables. To change them, set FT_CONFIGS_SERVICE_HTTP_PORT / FT_CONFIGS_SERVICE_HTTPS_PORT in ft-configs-service/.env, or edit only the left side of each ports: mapping.
cd /usr/local/ft-system
docker login hub.friendly-tech.com
docker compose up -d ft-configs-service
docker compose ps
docker compose logs -f ft-configs-service
To run it as a single container without Compose (docker run has no equivalent of the compose environment: block, so the vendor-specific names must be passed explicitly with -e; use the ORACLE_* names with SPRING_PROFILES_ACTIVE=oracle):
cd /usr/local/ft-system/ft-configs-service
docker run -d \
--name ft-configs-service \
--env-file ../.env \
--env-file .env \
-e SPRING_PROFILES_ACTIVE=mysql \
-e MYSQL_HOST=<db-host> \
-e MYSQL_PORT=3306 \
-e HZ_MEMBERS=<hazelcast-host>:5701 \
-v $(pwd)/config:/etc/app \
-v $(pwd)/logs:/app/logs \
-p 8087:8080 \
-p 8447:8443 \
--add-host=host.docker.internal:host-gateway \
--restart unless-stopped \
hub.friendly-tech.com/configs/ft-configs-service:latest
Both layers are passed in order — the shared .env first, the per-service .env second, so per-service values win. For Oracle, change the database variables in the shared .env as described in Switching to Oracle; the command itself does not change. For HTTP-only deployment, omit -p 8447:8443.
7. Verification
After starting the container, run the checks below. The examples use the default published ports 8087 (HTTP) and 8447 (HTTPS).
7.1. Startup Log
# Container status
docker ps -f name=ft-configs-service
# Expected: container with status "Up" and port 0.0.0.0:8087->8080/tcp
# Application logs
docker logs ft-configs-service --tail 50
A successful startup ends with the StartupInfoLogger summary banner (timestamp, PID, version, build, and Java runtime vary; the active profile reflects your deployment, and the connector shows the in-container port 8080):
INFO --- [] c.f.f.utils.config.StartupInfoLogger :
============================================================
FT Configs Service startup summary
------------------------------------------------------------
Active profiles : <active-profile>
Connectors : http (:8080)
Context path : /configs-service
Swagger UI : /configs-service/swagger-ui/index.html
Version : <version>
Build : <build>
Java runtime : <java-version>
PID : <pid>
============================================================
7.2. Endpoint Checks
# 1. Health check
curl -s http://localhost:8087/configs-service/actuator/health
# Expected: {"status":"UP"}
# 2. HTTPS health check (when SERVER_SSL_ENABLED=true)
curl -ks https://localhost:8447/configs-service/actuator/health
# Expected: {"status":"UP"}
# 3. Swagger UI (open in browser)
# http://localhost:8087/configs-service/swagger-ui/index.html
/actuator/health and /actuator/info are the only Actuator endpoints reachable without authentication. /actuator/metrics and /actuator/prometheus are exposed but require a JWT — see HTTP Endpoints.
7.3. Database Connectivity
Liquibase applies the schema migrations during startup, so a container that reaches the state above has already connected to the database. To check it explicitly:
# Reachability from inside the container (MySQL; use 1521 for Oracle)
docker exec ft-configs-service nc -zv <db-host> 3306
# Liquibase applied the changelog
docker logs ft-configs-service | grep -i liquibase
The Liquibase tracking tables (DATABASECHANGELOG, DATABASECHANGELOGLOCK) and the application tables must exist in the configs schema created in Create the Database Schema and User.
8. Port Reference
Ports are written as published → container. Across hosts you connect to the published port; inside the Docker bridge you connect to the container port. Both published ports are configurable through the FT_CONFIGS_SERVICE_HTTP_PORT / FT_CONFIGS_SERVICE_HTTPS_PORT variables shown in Docker Compose.
8.1. HTTP / HTTPS
| Port | Protocol | Purpose | Exposure |
|---|---|---|---|
8087 → 8080 |
HTTP |
REST API, Actuator, Swagger UI under the context path |
Published (API clients, monitoring) |
8447 → 8443 |
HTTPS |
TLS connector, active when |
Published (API clients) |
When HTTPS is enabled and keystore settings are provided, the application can run with two connectors: HTTPS on SERVER_PORT (typically 8443) and HTTP on SERVER_HTTP_PORT (typically 8080). Publishing both Docker mappings is safe.
|
8.2. Outbound Connections
Ports FT Configs Service dials on the existing infrastructure. These are the published ports of those services — confirm them against whoever operates them, and set the matching variables in the shared .env (DB_HOST, DB_PORT) and in ft-configs-service/.env.
| Destination | Port | Protocol | Purpose |
|---|---|---|---|
Relational database |
3306 (MySQL), 1521 (Oracle) |
TCP |
JDBC connection; addressed through |
Hazelcast cluster |
5701 |
TCP |
Publishes configuration snapshots; addressed through |
8.3. HTTP Endpoints
Paths include the /configs-service context path. Auth follows the access rules declared in application.yml (ft-configs.security.endpoints): every path not listed as public requires a JWT.
| Method | Path | Purpose | Auth |
|---|---|---|---|
GET |
|
Health status; used by the container healthcheck |
None |
GET |
|
Build and version information |
None |
GET |
|
Micrometer metrics |
JWT |
GET |
|
Prometheus scrape endpoint |
JWT |
GET |
|
Swagger UI |
None |
GET |
|
OpenAPI document |
None |
POST |
|
Obtains a JWT |
None |
POST |
|
Rotates the bootstrap admin password on first login |
None |
9. Stack Management
9.1. Logs
| Command | Description |
|---|---|
|
Follow application logs |
|
Show the last 200 log lines |
|
File logs written to the mounted |
9.2. Start, Stop, Restart
| Command | Description |
|---|---|
|
Start the service in the background |
|
Stop and remove the container |
|
Restart the application |
|
Show container status |
9.3. Shell Access
| Command | Description |
|---|---|
|
Enter the application container |
|
Check mounted configuration files |
|
Check environment variables |
9.4. Updating FT Configs Service
docker compose pull downloads the latest image, then docker compose up -d recreates the container with the new version. Configuration files and logs are preserved.
# 1. Backup configuration (run from the stack root, where compose.yml lives)
cd /usr/local/ft-system
tar -czf ft-configs-backup-$(date +%Y%m%d).tar.gz \
compose.yml .env ft-configs-service/.env ft-configs-service/config/
# 2. Pull the latest image and recreate the container
docker compose pull ft-configs-service
docker compose up -d ft-configs-service
# 3. Verify
curl -s http://localhost:8087/configs-service/actuator/health
10. Production Checklist
-
Database credentials: default values in the
.envfile replaced (MYSQL_PASSWORD/ORACLE_PASSWORD). -
JWT secret: empty
JWT_SECRETreplaced with a secure value (openssl rand -base64 32). -
Bootstrap admin password rotated after the first login (
/auth/first-login) and removed from.env. -
CORS origins:
CORS_ALLOWED_ORIGINSset to the host users type in the browser, listing both the HTTP and HTTPS origins —http://<ui-host>:3001,https://<ui-host>:3443with<ui-host>replaced by the real host. -
Hazelcast cluster:
HZ_MEMBERSpoints at the same cluster FTACS uses — a mismatch is silent (no connection error) and leaves FTACS with no configuration. -
File permissions:
chmod 600 .env ft-configs-service/.env(run from/usr/local/ft-system). -
Log management:
/app/logsmounted, external log rotation configured (for examplelogrotate). -
Resource limits:
deploy.resources.limitsadded incompose.yml. -
Restart policy:
restart: unless-stoppedpresent incompose.yml.
11. Troubleshooting
11.1. Env File Not Found
Symptom: Docker fails to start with open .env: no such file or directory.
Fix:
-
Confirm both layers exist:
ls -la /usr/local/ft-system/.env /usr/local/ft-system/ft-configs-service/.env. -
Run
docker runfrom the directory containing the env file, or use an absolute path in--env-file. -
In
compose.yml, verify bothenv_fileentries (.envand./ft-configs-service/.env) are correct relative to the compose file location —docker composemust be run from/usr/local/ft-system.
11.2. Database Connection Failure (MySQL)
Symptom: Communications link failure or Access denied in logs.
Fix:
-
Test connectivity from inside the container:
docker exec ft-configs-service nc -zv <db-host> 3306. -
Check
MYSQL_HOST,MYSQL_PORT,MYSQL_USER, andMYSQL_PASSWORDagainst the schema and user created in Create the Database Schema and User. -
If the database runs on the host machine, use
host.docker.internalinstead oflocalhost.
11.3. Database Connection Failure (Oracle)
Symptom: ORA-12514: Cannot connect to Oracle or ORA-01017: invalid username/password in logs.
Fix:
-
Test connectivity from inside the container:
docker exec ft-configs-service nc -zv <db-host> 1521. -
Verify
DB_HOST,DB_PORTandDB_SERVICEin the shared.envandORACLE_USER/ORACLE_PASSWORDinft-configs-service/.env. ConfirmDB_SERVICE=XEPDB1matches exactly (case-sensitive). -
If the database runs on the host machine, use
host.docker.internalinstead oflocalhost.
11.4. Hazelcast Connection Failure
Symptom: Unable to connect to any address in logs.
Fix:
-
Verify
HZ_MEMBERSis set and points to reachable Hazelcast members (e.g.,HZ_MEMBERS=hazelcast-host:5701). -
Confirm Hazelcast members are running and on the same Docker network, or reachable across hosts.
-
Check that
CACHE_CONFIG_PATHis correct — the defaultclasspath:loads the JAR-bundledhazelcast-client.yaml; only set afile:path when externalizing the config to a mounted volume.
11.5. FTACS Does Not Receive Published Configuration
Symptom: FT Configs Service is healthy and its UI shows the configuration as saved, but FTACS starts with configuration falling back to defaults and no error appears in either log.
Cause: FT Configs Service and FTACS are Hazelcast clients of different clusters — this failure is silent by design, since Hazelcast never reports "no such publisher."
Fix:
-
Compare
HZ_MEMBERSon both services — both must resolve to the same cluster. -
Compare the Hazelcast cluster name FT Configs Service uses with the one in FTACS’s
hazelcast-client.xml(default:dev). -
Confirm the configuration was actually saved through FT Configs UI, not left in draft.
11.6. Port Already in Use
Symptom: address already in use error.
Fix:
-
Find the process holding the port:
lsof -i :8087ordocker ps. -
Stop the conflicting service, or expose a different host port via
FT_CONFIGS_SERVICE_HTTP_PORTinft-configs-service/.env.
11.7. Container Restarting or Healthcheck Failing
Symptom: docker ps shows the container in a restart loop or health status is unhealthy.
Fix:
-
Review the logs for startup errors:
docker logs ft-configs-service --tail 200. -
The healthcheck allows 50 retries at a 10s interval before Compose reports it unhealthy — a slow database connection can still be the cause even after that window.
-
Verify the health endpoint responds directly:
http://localhost:8087/configs-service/actuator/health.
11.8. Wrong Profile Selected
Symptom: The application tries to connect to the wrong database type (e.g., MySQL errors when using Oracle).
Fix:
-
Check the active profile:
docker exec ft-configs-service env | grep SPRING_PROFILES_ACTIVE. -
Verify
DB_PROFILE(andSPRING_PROFILES_ACTIVE) ismysqlororaclein the shared.env—compose.ymlinjects it into the container. See Switching to Oracle.
11.9. Liquibase Migration Failure
Symptom: LiquibaseException or Migration failed in application logs during startup.
Fix:
-
Check database connectivity and credentials — see Database Connectivity.
-
Ensure the database user has sufficient privileges to create/alter tables — see Create the Database Schema and User.
-
If upgrading from a previous version, check the schema is not corrupted; restore from backup if necessary.
11.10. Bootstrap Admin Not Created
Symptom: Cannot log in after first startup. No admin account exists.
Cause: AdminBootstrap runs on every startup, but only creates the account when the configs schema contains no user with the ADMIN role and both FT_CONFIGS_BOOTSTRAP_ADMIN_USERNAME and FT_CONFIGS_BOOTSTRAP_ADMIN_PASSWORD are non-empty. With either value missing it logs Admin bootstrap skipped and continues.
Fix:
-
Check
docker exec ft-configs-service env | grep FT_CONFIGS_BOOTSTRAP— both the username and the password must be non-empty (password: minimum 8 characters). -
Confirm the skip in the log:
docker logs ft-configs-service | grep -i "admin bootstrap". -
Set the missing values in
ft-configs-service/.envand recreate the container. No database wipe is needed — the bootstrap retries on the next startup, and the database is external to this stack, sodocker compose down -vwould delete nothing:cd /usr/local/ft-system docker compose up -d --force-recreate ft-configs-service docker compose logs -f ft-configs-service | grep -i "bootstrap administrator"If an
ADMINuser does already exist in theconfigsschema, the bootstrap stays skipped by design — recover that account instead of expecting a new one.
11.11. Getting Support
When an issue is not covered above, collect the following before contacting the FT Configs Service maintainers:
-
docker logs ft-configs-service --tail 500and the file logs from the mountedlogs/directory. -
docker inspect ft-configs-service --format '{{json .Config.Env}}', with secrets removed. -
The active profile, the image tag, and the output of
curl -s http://localhost:8087/configs-service/actuator/health.
For issues outside deployment, see the Troubleshooting Guide.