UI Services Separate Host Deployment

Overview

This deployment runs UI services (Backend + Portals) on a dedicated host. The deployment includes:

  • UI Backend - Spring Boot REST API service

  • UI Portals - Angular web applications on Nginx (Support Center & Management Console)

Architecture

ui-services-architecture

Prerequisites

For detailed information about Docker registry and image management, see Docker Image Management Guide.

For HTTPS configuration, see Ssl certificate configuration.

Required External Components

The following components must be installed and accessible:

Component Purpose Default Port

MySQL or Oracle

Main application database

3306 (MySQL) / 1521 (Oracle)

Hazelcast

Distributed cache

5701

FTACS Application

ACS web service

8080

Clickhouse

Analytics database

9000

System Requirements

  • Docker Engine 20.10+

  • Docker Compose 2.0+

  • Minimum 3GB RAM

  • 15GB free disk space

Preparation

1. Prepare Configuration Directory

Create the required directory structure:

mkdir -p /usr/local/ft-services/{ui-backend-conf,ft-data/ui-portals/{backend,nginx}/logs}

2. Configure UI Backend

The ui-backend-conf folder contains essential configuration files for the backend service.

Required Folder Structure

/usr/local/ft-services/ui-backend-conf/
├── hazelcast-client.xml              # Hazelcast client configuration
└── customization/                    # System customization files
    ├── def/                          # Default customizations
    ├── mc/                           # Management Console customizations
    └── sc/                           # Support Center customizations

Customization Folders

The customization folder contains JSON files for portal customizations:

  • def/ - Default system-wide customizations

  • mc/ - Management Console specific customizations

  • sc/ - Support Center specific customizations

These files control portal appearance and features.

3. Prepare Environment File

Choose the appropriate environment file:

MySQL
cp .env.mysql .env
Oracle
cp .env.oracle .env

4. Configure Host Variables

Edit .env and replace placeholder values:

# Required replacements:
~HOST~            → UI services hostname/IP (e.g., 192.168.1.100)
~HAZELCAST_HOST~  → Hazelcast server (e.g., 192.168.1.50)
~FTACS_HOST~      → FTACS server (e.g., 192.168.1.60)
~CLICKHOUSE_HOST~ → Clickhouse server (e.g., 192.168.1.70)
~MYSQL_HOST~      → MySQL server (for MySQL deployment)
~ORACLE_HOST~     → Oracle server (for Oracle deployment)

Example configuration:

HOST=192.168.1.100
HZ_MEMBERS=192.168.1.50:5701,192.168.1.51:5701
ACS_WEB_SERVICE_HOST=192.168.1.60
CLICKHOUSE_HOST=192.168.1.70
DB_HOST=192.168.1.80

Deployment

Deploy Services

docker compose up -d

Verify Deployment

Check service status:

docker compose ps

Expected output:

NAME                STATUS              PORTS
ui-backend          healthy             0.0.0.0:8881->8880/tcp, 0.0.0.0:5005->5005/tcp
portals             healthy             0.0.0.0:8880->80/tcp

Container Startup Process

UI Backend Startup

The backend container starts with the following initialization:

  1. Loads configuration from /app/conf (mounted from ui-backend-conf)

  2. Connects to Hazelcast cluster using hazelcast-client.xml

  3. Connects to MySQL/Oracle database

  4. Initializes REST API endpoints

  5. Health check becomes available at /iot-webservice/swagger-ui/index.html

UI Portals Startup (Entrypoint)

The portals container runs an entrypoint script that performs the following actions:

1. Configuration Patching

Patches Angular application configuration files with backend API endpoints:

# Support Center
/usr/share/nginx/html/support-center/assets/app-config.json
  → .server.api = "http://${HOST}:8881/iot-webservice/"

# Management Console
/usr/share/nginx/html/management-console/assets/app-config.json
  → .server.api = "http://${HOST}:8881/iot-webservice/"

This ensures the Angular apps know where to send API requests.

2. Permissions Upload

Uploads portal-specific permissions to the backend:

# Support Center permissions
curl -X PUT http://ui-backend:8880/iot-webservice/iotw/Setting/userGroup/permissions \
  -H "X-Internal-Keyword: ${FT_UI_BACKEND_KEYWORD}" \
  -H "X-Internal-Client-Type: sc" \
  -F "config=@/usr/share/nginx/html/support-center/assets/app-permissions-config.json"

# Management Console permissions
curl -X PUT http://ui-backend:8880/iot-webservice/iotw/Setting/userGroup/permissions \
  -H "X-Internal-Keyword: ${FT_UI_BACKEND_KEYWORD}" \
  -H "X-Internal-Client-Type: mc" \
  -F "config=@/usr/share/nginx/html/management-console/assets/app-permissions-config.json"

Purpose: Synchronizes user group permissions from Angular apps to the backend database.

Authentication: Uses FT_UI_BACKEND_KEYWORD header for internal service-to-service authentication.

3. Start Nginx

After patching and upload, Nginx starts serving the Angular applications.

Startup Dependencies

Services start in this order:

  1. UI Backend - Waits for database and Hazelcast connectivity

  2. UI Portals - Waits for backend health check, then runs entrypoint script

Environment Variables

Service Configuration

Variable Description Default Required

HOST

Public hostname for UI access (used in Angular configs)

HOST

Yes

FT_UI_HTTP_PORT

UI Portals HTTP port

8880

Yes

FT_UI_HTTPS_PORT

UI Portals HTTPS port

8843

Yes

FT_UI_BACKEND_HTTP_PORT

Backend API port

8881

Yes

FT_GRAFANA_API_URL

Grafana url for dashboards exporting (http://IP:PORT/)

No

FT_UI_BACKEND_JAVA_RAM

Backend JVM memory settings

-Xms512m -Xmx2g

No

FT_UI_BACKEND_LOG_LEVEL

Backend log level (info, debug, warn, error)

info

No

FT_UI_BACKEND_KEYWORD

Internal authentication keyword for cross-service communication (entrypoint uses this for permissions upload)

ft12Internal%^

Yes

Common Configuration

Variable Description Default Required

DATA_FOLDER

Base directory for persistent data and configurations

/usr/local/ft-services

Yes

TZ

Timezone for all services

Europe/Kiev

Yes

Database Configuration

MySQL
Variable Description Default Required

DB_HOST

MySQL server address

MYSQL_HOST

Yes

MYSQL_PORT

MySQL port

3306

Yes

MYSQL_USER

MySQL username

ftacs

Yes

DB_PASSWORD

MySQL password

ftacs

Yes

DB_VENDOR

Database type

mysql

Yes

Oracle
Variable Description Default Required

DB_HOST

Oracle server address

ORACLE_HOST

Yes

ORACLE_PORT

Oracle port

1521

Yes

ORACLE_SERVICE

Oracle service name

XEPDB1

Yes

ORACLE_USER_FTACS

Oracle username for FTACS schema

ftacs

Yes

ORACLE_USER_IOTW

Oracle username for IOTW schema

iotw

Yes

DB_PASSWORD

Oracle password

ftacs

Yes

DB_VENDOR

Database type

oracle

Yes

External Dependencies

Variable Description Default Required

HZ_MEMBERS

Hazelcast cluster members (comma-separated HOST:PORT)

HAZELCAST_HOST:5701

Yes

ACS_WEB_SERVICE_HOST

FTACS application host

FTACS_HOST

Yes

ACS_WEB_SERVICE_PORT

FTACS application port

8080

Yes

CLICKHOUSE_HOST

Clickhouse server address

CLICKHOUSE_HOST

Yes

CLICKHOUSE_PORT

Clickhouse port

9000

Yes

CLICKHOUSE_DATABASE

Clickhouse database name

ftacs_qoe_ui_data

Yes

CLICKHOUSE_USERNAME

Clickhouse username

ftacs

Yes

CLICKHOUSE_PASSWORD

Clickhouse password

ftacs

Yes

Service Access

After successful deployment:

Service URL Description

Support Center

http://<FT_UI_HOST>:8880/support-portal/

End-user support portal

Management Console

http://<FT_UI_HOST>:8880/management-console/

Administrator console

Backend API

http://<FT_UI_HOST>:8881/iot-webservice/swagger-ui/index.html

API documentation

Exposed Ports

Port Service Protocol Purpose Configurable Via

8880

UI Portals (Nginx)

HTTP

Web interface

FT_UI_HTTP_PORT

8843

UI Portals (Nginx)

HTTPS

Web interface

FT_UI_HTTPS_PORT

8881

UI Backend

HTTP

REST API

FT_UI_BACKEND_HTTP_PORT

Verify ports are listening:

netstat -tlnp | grep -E '8880|8881'

Data Persistence

Persistent data locations (assuming DATA_FOLDER=/usr/local/ft-services):

Path Content Backup Required

${DATA_FOLDER}/ui-backend-conf/

Configuration files (hazelcast-client.xml, customizations)

Yes

${DATA_FOLDER}/ft-data/ui-portals/backend/logs/

Backend application logs

No

${DATA_FOLDER}/ft-data/ui-portals/nginx/logs/

Nginx access and error logs

No

Folder structure:

/usr/local/ft-services/
├── ui-backend-conf/                    # Configuration (backup required)
│   ├── hazelcast-client.xml
│   └── customization/
│       ├── def/
│       ├── mc/
│       └── sc/
└── ft-data/ui-portals/                 # Runtime data
    ├── backend/logs/
    └── nginx/logs/

Troubleshooting

Check Service Logs

# All services
docker compose logs -f

# Backend only
docker compose logs -f ui-backend

# Portals only
docker compose logs -f portals

Common Issues

Portals Container Fails to Start

Symptom: Portals container exits or restarts repeatedly.

Check entrypoint logs:

docker compose logs portals | grep -E "Patched|Upload|WARN"

Common causes:

  1. Backend not healthy:

    • Portals depends on backend health check

    • Wait for backend to become healthy first

  2. Permissions upload failed:

    • Check FT_UI_BACKEND_KEYWORD matches between services

    • Verify backend API is accessible from portals container

  3. Missing permissions files:

    • Ensure portals image contains app-permissions-config.json files

    • Check entrypoint logs for "WARN: permissions file not found"

Backend Cannot Connect to Hazelcast

Symptom: Backend logs show Hazelcast connection errors.

Check:

# Verify Hazelcast is reachable
telnet <HAZELCAST_HOST> 5701

# Check hazelcast-client.xml
cat /usr/local/ft-services/ui-backend-conf/hazelcast-client.xml

# Check HZ_MEMBERS environment variable
docker compose exec ui-backend env | grep HZ_MEMBERS

Solution: - Update HZ_MEMBERS in .env with correct Hazelcast addresses - Verify hazelcast-client.xml references ${env.HZ_MEMBERS}

Angular Apps Cannot Reach Backend API

Symptom: UI shows connection errors or 404 responses.

Check:

# Verify backend API is accessible
curl http://<FT_UI_HOST>:8881/iot-webservice/swagger-ui/index.html

# Check patched configuration
docker compose exec portals cat /usr/share/nginx/html/support-center/assets/app-config.json | jq .server.api

Expected output:

"http://<FT_UI_HOST>:8881/iot-webservice/"

Solution: - Verify FT_UI_HOST is set correctly in .env - Ensure FT_UI_HOST is accessible from user browsers

Permissions Not Applied

Symptom: Users cannot access expected features.

Check entrypoint logs:

docker compose logs portals | grep -i "upload"

Verify permissions in database:

# Access backend API to check permissions
curl -X GET http://<FT_UI_HOST>:8881/iot-webservice/iotw/Setting/userGroup/permissions

Solution: - Restart portals to re-upload permissions: docker compose restart portals - Verify FT_UI_BACKEND_KEYWORD is correct

Database Connection Issues

Check connection:

# MySQL
telnet <DB_HOST> 3306

# Oracle
telnet <DB_HOST> 1521

# Check database vendor setting
docker compose exec ui-backend env | grep DB_VENDOR

Verify External Dependencies

Test connectivity to all external services:

# Database
telnet <DB_HOST> 3306    # MySQL
telnet <DB_HOST> 1521    # Oracle

# Hazelcast
telnet <HAZELCAST_HOST> 5701

# FTACS
curl http://<ACS_WEB_SERVICE_HOST>:8080

# Clickhouse
telnet <CLICKHOUSE_HOST> 9000

Restart Services

# Restart all
docker compose restart

# Restart specific service
docker compose restart ui-backend
docker compose restart portals

# Full restart (recreate containers)
docker compose down
docker compose up -d

Debugging

Enable Debug Logging

Edit .env:

FT_UI_BACKEND_LOG_LEVEL=debug

Restart backend:

docker compose restart ui-backend

View Backend Logs

# Real-time logs
tail -f /usr/local/ft-services/ft-data/ui-portals/backend/logs/application.log

# Or via Docker
docker compose logs -f ui-backend

View Nginx Logs

# Access logs
tail -f /usr/local/ft-services/ft-data/ui-portals/nginx/logs/access.log

# Error logs
tail -f /usr/local/ft-services/ft-data/ui-portals/nginx/logs/error.log

Maintenance

Update Services

# Pull latest images
docker compose pull

# Restart with new images
docker compose up -d

Force Repull Images

docker compose down
docker compose pull --ignore-pull-failures
docker compose up -d

Backup Configuration

# Backup ui-backend-conf folder
tar -czf ui-backend-conf-backup-$(date +%Y%m%d).tar.gz \
  /usr/local/ft-services/ui-backend-conf/

# Restore
tar -xzf ui-backend-conf-backup-YYYYMMDD.tar.gz -C /

Stop Services

# Stop (keeps data)
docker compose down

# Stop and remove all data
docker compose down -v