Deploy
MCP — Deployment Guide
Message Control Platform — Contact Policy Enforcement Engine
Prerequisites
Before deploying MCP, ensure the following requirements are met:
| Requirement | Details |
|---|---|
| Docker | Version 20.10 or later |
| Docker Compose | Version 2.x or later |
| Docker Network | An external Docker network named contact-policy-node must be created prior to deployment |
| S3-Compatible Storage | An S3 or MinIO instance for hosting blacklist files |
Create the Docker Network
docker network create contact-policy-node
Quick Start
1. Create a Project Directory
mkdir mcp && cd mcp
mkdir -p config/node_red_data
2. Create compose.yml
Use the following template as your base configuration:
services:
contact-policy-0:
image: ernestmr/message-control-platform:latest
container_name: contact-policy-0
ports:
- "1880:1880"
volumes:
- ./config/node_red_data:/data
networks:
- contact-policy-node
restart: unless-stopped
tty: true
stdin_open: true
depends_on:
redis:
condition: service_healthy
command: ["/usr/src/node-red/wait-for-redis.sh"]
redis:
image: redis:latest
container_name: cp-redis
command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
ports:
- "6379:6379"
volumes:
- mcp_redis_data:/data
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 2s
retries: 5
networks:
- contact-policy-node
networks:
contact-policy-node:
external: true
volumes:
mcp_redis_data:
3. Start the Services
docker compose up -d
4. Verify the Deployment
curl http://localhost:1880/api/v1/health
Expected response: OK
Configuration
Node-RED Web UI
Once running, the Node-RED flow editor is available at:
http://<host>:1880/
All policy workflows are pre-configured in the platform image. Use the web UI to review, customize, or extend the policy flows.
Flow Data Persistence
The volume mount ./config/node_red_data:/data ensures all flow configurations, credentials, and runtime state persist across container restarts.
[!IMPORTANT] On first launch, Node-RED will initialize the
/datadirectory with default flow configurations. All subsequent customizations are stored in this directory.
S3 / MinIO Setup for Blacklists
MCP loads blacklist entries from CSV files stored in an S3-compatible object storage.
Bucket Structure
contact-policy/ ← Bucket name
└── black-list/ ← Prefix (folder)
├── blacklist.csv
├── corporate.csv
└── ... ← Additional CSV files
CSV Format
Each line contains a single phone number (destination address):
000000000001
998901234567
998970123654
Configure S3 Connection in Node-RED
- Open the Node-RED web UI at
http://<host>:1880/ - Navigate to the BlackList tab
- Double-click the LoadList node
- Configure the S3 connection:
- Bucket name —
contact-policy - Region — your S3 region
- Endpoint — your S3/MinIO endpoint URL
- Access Key — your S3 access key
- Secret Key — your S3 secret key
- Bucket name —
- Repeat the same S3 configuration for the ReadAll node
- Click Deploy to save changes
Blacklist Management
Auto-Renewal
MCP supports automatic blacklist refresh from S3 on a configurable schedule. The auto-renewal is configured in the BlackList tab using a cron scheduler node.
When triggered, MCP will:
- Fetch the latest CSV files from S3
- Parse all entries
- Atomically write them into Redis
- Clean up stale entries from the previous load
Manual Refresh
To manually reload the blacklist, use the manual inject button in the BlackList tab of the Node-RED UI.
Counter Reset Scheduler
Contact policy strategies CP1 use daily and weekly counters that need periodic reset.
Automated Reset via Cron Container
Deploy the counter reset scheduler alongside MCP:
services:
cp-redis-cron:
image: ernestmr/cp-redis-cron:latest
container_name: cp-redis-cron
environment:
REDIS_HOST: cp-redis
REDIS_PORT: "6379"
networks:
- contact-policy-node
restart: unless-stopped
This container runs two cron jobs:
| Schedule | Action |
|---|---|
| Every day at 00:00 | Resets daily counters (d → 0) for all tracked recipients |
| Every Monday at 00:00 | Resets weekly counters (w → 0) for all tracked recipients |
Manual Reset
Counter resets can also be triggered manually via the MCP API:
# Reset daily counters
curl http://localhost:1880/api/v1/dcp
# Reset weekly counters
curl http://localhost:1880/api/v1/wcp
Scaling
MCP supports horizontal scaling. Add additional instances by defining more services in your compose.yml:
contact-policy-1:
image: ernestmr/message-control-platform:latest
container_name: contact-policy-1
ports:
- "1881:1880"
volumes:
- ./config/node_red_data:/data
networks:
- contact-policy-node
restart: unless-stopped
tty: true
stdin_open: true
depends_on:
redis:
condition: service_healthy
command: ["/usr/src/node-red/wait-for-redis.sh"]
[!TIP] All instances share the same flow definitions and Redis backend. Use an external load balancer (e.g., Nginx, HAProxy, Traefik) to distribute traffic across instances.
Full Compose Example (Multi-Instance + Cron + MinIO)
services:
contact-policy-0:
image: ernestmr/message-control-platform:latest
container_name: contact-policy-0
ports:
- "1880:1880"
volumes:
- ./config/node_red_data:/data
networks:
- contact-policy-node
restart: unless-stopped
tty: true
stdin_open: true
depends_on:
redis:
condition: service_healthy
command: ["/usr/src/node-red/wait-for-redis.sh"]
contact-policy-1:
image: ernestmr/message-control-platform:latest
container_name: contact-policy-1
ports:
- "1881:1880"
volumes:
- ./config/node_red_data:/data
networks:
- contact-policy-node
restart: unless-stopped
tty: true
stdin_open: true
depends_on:
redis:
condition: service_healthy
command: ["/usr/src/node-red/wait-for-redis.sh"]
redis:
image: redis:latest
container_name: cp-redis
command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
ports:
- "6379:6379"
volumes:
- mcp_redis_data:/data
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 2s
retries: 5
networks:
- contact-policy-node
cp-redis-cron:
image: ernestmr/cp-redis-cron:latest
container_name: cp-redis-cron
environment:
REDIS_HOST: cp-redis
REDIS_PORT: "6379"
networks:
- contact-policy-node
restart: unless-stopped
minio:
image: minio/minio:latest
container_name: mcp-minio
ports:
- "9000:9000"
- "9001:9001"
volumes:
- mcp_minio_data:/data
networks:
- contact-policy-node
command: server /data --console-address ":9001"
networks:
contact-policy-node:
external: true
volumes:
mcp_redis_data:
mcp_minio_data:
API Verification
After deployment, verify that the system is operational:
Health Check
curl http://localhost:1880/api/v1/health
# Expected: OK
Policy Check (Example)
curl -X POST http://localhost:1880/api/v1/check \
-H "Content-Type: application/json" \
-H "x-api-auth: <your_api_key>" \
-d '{
"task_id": "1",
"transaction_id": "test-001",
"app_id": 1,
"esme": 100,
"saddr": "COMPANY",
"daddr": "998901234567",
"message": "Hello",
"strategy": "cp1"
}'
Expected response (allowed):
{
"state": "ok",
"pass": true
}
Ports Reference
| Service | Default Port | Description |
|---|---|---|
| Node-RED (instance 0) | 1880 | Flow editor + Policy API |
| Node-RED (instance N) | 1880 + N | Additional instances |
| Redis | 6379 | State storage |
| MinIO API | 9000 | S3-compatible API |
| MinIO Console | 9001 | MinIO web management UI |