sync: migrate aimaq-call-center deployment config to Gitea (2026-08-10)
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
|||||||
|
# deployment artifacts only — no secrets, no runtime data, no media
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
.data_pg/
|
||||||
|
.data_local/
|
||||||
|
.models/
|
||||||
|
*.wav
|
||||||
|
*.pdf
|
||||||
|
*.pcm
|
||||||
|
*.pid
|
||||||
|
*.opts
|
||||||
|
*.bak-*
|
||||||
|
*.bak
|
||||||
|
*.TAG
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
Executable
+72
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DEPLOY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SRC_DIR="/opt/konturai-migration/call-center-src"
|
||||||
|
IMAGE="call-center-app:active-aimaq"
|
||||||
|
|
||||||
|
SERVICES=(
|
||||||
|
auth-service
|
||||||
|
audit-service
|
||||||
|
customer-service
|
||||||
|
interaction-service
|
||||||
|
voice-adapter-service
|
||||||
|
recording-service
|
||||||
|
reporting-service
|
||||||
|
sales-service
|
||||||
|
asterisk-bridge-service
|
||||||
|
api-gateway
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== AIMAQ BACKEND DEPLOY ==="
|
||||||
|
echo "Источник : $SRC_DIR"
|
||||||
|
echo "Образ : $IMAGE"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 1. Сборка образа
|
||||||
|
echo "[1/4] Сборка Docker образа..."
|
||||||
|
docker build -t "$IMAGE" "$SRC_DIR"
|
||||||
|
echo " Готово."
|
||||||
|
|
||||||
|
# 2. Миграции БД
|
||||||
|
echo "[2/4] Запуск миграций БД..."
|
||||||
|
cd "$DEPLOY_DIR"
|
||||||
|
docker compose -f docker-compose.minimal.yml run --rm migrate
|
||||||
|
echo " Готово."
|
||||||
|
|
||||||
|
# 3. Перезапуск сервисов
|
||||||
|
echo "[3/4] Перезапуск сервисов..."
|
||||||
|
docker compose -f docker-compose.minimal.yml up -d --no-deps --force-recreate "${SERVICES[@]}"
|
||||||
|
echo " Готово."
|
||||||
|
|
||||||
|
# 4. Проверка
|
||||||
|
echo "[4/4] Проверка..."
|
||||||
|
sleep 5
|
||||||
|
FAILED=()
|
||||||
|
for SERVICE in "${SERVICES[@]}"; do
|
||||||
|
CONTAINER="aimaq-call-center-${SERVICE}-1"
|
||||||
|
# api-gateway имеет отдельное имя
|
||||||
|
if [ "$SERVICE" = "api-gateway" ]; then
|
||||||
|
CONTAINER="aimaq-call-center-app"
|
||||||
|
fi
|
||||||
|
STATUS=$(docker inspect --format '{{.State.Status}}' "$CONTAINER" 2>/dev/null || echo "not found")
|
||||||
|
if [ "$STATUS" != "running" ]; then
|
||||||
|
FAILED+=("$SERVICE ($STATUS)")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#FAILED[@]} -eq 0 ]; then
|
||||||
|
echo " Все сервисы запущены."
|
||||||
|
else
|
||||||
|
echo " ОШИБКА: следующие сервисы не запустились:"
|
||||||
|
for F in "${FAILED[@]}"; do
|
||||||
|
echo " - $F"
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== ДЕПЛОЙ ЗАВЕРШЁН ==="
|
||||||
|
echo "API: https://aimaq.konturai.kz/proxy/"
|
||||||
|
echo ""
|
||||||
Executable
+40
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DEPLOY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SRC_DIR="/tmp/cc-frontend-build"
|
||||||
|
IMAGE="omnichannel-contact-center:active-aimaq"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== AIMAQ FRONTEND DEPLOY ==="
|
||||||
|
echo "Источник : $SRC_DIR"
|
||||||
|
echo "Образ : $IMAGE"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 1. Сборка образа
|
||||||
|
echo "[1/3] Сборка Docker образа..."
|
||||||
|
docker build -t "$IMAGE" "$SRC_DIR"
|
||||||
|
echo " Готово."
|
||||||
|
|
||||||
|
# 2. Перезапуск контейнера
|
||||||
|
echo "[2/3] Перезапуск контейнера..."
|
||||||
|
cd "$DEPLOY_DIR"
|
||||||
|
docker compose -f docker-compose.minimal.yml up -d --no-deps --force-recreate frontend
|
||||||
|
echo " Готово."
|
||||||
|
|
||||||
|
# 3. Проверка
|
||||||
|
echo "[3/3] Проверка..."
|
||||||
|
sleep 3
|
||||||
|
STATUS=$(docker inspect --format '{{.State.Status}}' aimaq-call-center-frontend 2>/dev/null || echo "not found")
|
||||||
|
if [ "$STATUS" = "running" ]; then
|
||||||
|
echo " Контейнер запущен."
|
||||||
|
else
|
||||||
|
echo " ВНИМАНИЕ: контейнер в статусе '$STATUS'"
|
||||||
|
docker logs --tail 20 aimaq-call-center-frontend
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== ДЕПЛОЙ ЗАВЕРШЁН ==="
|
||||||
|
echo "Сайт: https://aimaq.konturai.kz"
|
||||||
|
echo ""
|
||||||
Executable
+41
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Deploy script: voice-ai backend + updated frontend (nginx + React)
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DEPLOY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
VOICE_AI_SRC="/root/voice-call-center-ai"
|
||||||
|
FRONTEND_SRC="/tmp/cc-frontend-build"
|
||||||
|
|
||||||
|
VOICE_AI_IMAGE="voice-call-center-ai:active-aimaq"
|
||||||
|
FRONTEND_IMAGE="omnichannel-contact-center:active-aimaq"
|
||||||
|
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo " Step 1/4 — Build voice-ai Docker image"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
docker build -t "$VOICE_AI_IMAGE" "$VOICE_AI_SRC"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo " Step 2/4 — Build frontend Docker image (React + nginx)"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
docker build -t "$FRONTEND_IMAGE" "$FRONTEND_SRC"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo " Step 3/4 — Start voice-ai + restart frontend"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
cd "$DEPLOY_DIR"
|
||||||
|
docker compose -f docker-compose.minimal.yml up -d --force-recreate voice-ai frontend
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo " Step 4/4 — Container status"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
docker compose -f docker-compose.minimal.yml ps voice-ai frontend
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✓ Done. Voice AI available via wss://aimaq.konturai.kz/voice-ai/ws"
|
||||||
|
echo ""
|
||||||
|
echo " ⚠ API keys must be set in: $DEPLOY_DIR/.env.voice-ai"
|
||||||
|
echo " OPENAI_API_KEY=..."
|
||||||
|
echo " ELEVENLABS_API_KEY=..."
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
services:
|
||||||
|
asterisk-bridge-service:
|
||||||
|
environment:
|
||||||
|
AI_VOICE_ENABLED: "1"
|
||||||
|
AI_VOICE_RUNTIME_SERVICE_URL: "http://92.38.48.166:8002"
|
||||||
|
SALES_VOICE_RUNTIME_ENABLED: "1"
|
||||||
|
ASTERISK_CALLCONTROL_ENABLED: "1"
|
||||||
|
ASTERISK_WEBRTC_ENABLED: "1"
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
name: aimaq-call-center
|
||||||
|
|
||||||
|
x-app-env: &app_env
|
||||||
|
CC_DATA_DIR: /app/.data_local
|
||||||
|
DATABASE_URL: postgresql+psycopg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
|
||||||
|
SCHEMA_MANAGEMENT_MODE: migrations
|
||||||
|
AUTH_SERVICE_URL: http://auth-service:8000
|
||||||
|
AUDIT_SERVICE_URL: http://audit-service:8000
|
||||||
|
CUSTOMER_SERVICE_URL: http://customer-service:8000
|
||||||
|
INTERACTION_SERVICE_URL: http://interaction-service:8000
|
||||||
|
VOICE_ADAPTER_SERVICE_URL: http://voice-adapter-service:8000
|
||||||
|
RECORDING_SERVICE_URL: http://recording-service:8000
|
||||||
|
ASTERISK_BRIDGE_SERVICE_URL: http://asterisk-bridge-service:8000
|
||||||
|
SALES_SERVICE_URL: http://sales-service:8000
|
||||||
|
REPORTING_SERVICE_URL: http://reporting-service:8000
|
||||||
|
LOCAL_STACK_PUBLIC_BASE_URL: https://aimaq.konturai.kz
|
||||||
|
ASTERISK_WEBRTC_WS_URL: wss://aimaq.konturai.kz/asterisk-ws
|
||||||
|
ASTERISK_CALLCONTROL_ENABLED: "0"
|
||||||
|
ASTERISK_IVR_FASTAGI_ENABLED: "0"
|
||||||
|
ASTERISK_WEBRTC_ENABLED: "0"
|
||||||
|
TELEGRAM_BOT_ENABLED: "0"
|
||||||
|
AI_TELEGRAM_ENABLED: "0"
|
||||||
|
WHATSAPP_OUTBOUND_ENABLED: "0"
|
||||||
|
AI_WHATSAPP_ENABLED: "0"
|
||||||
|
SALES_TELEGRAM_BRIDGE_ENABLED: "0"
|
||||||
|
EVENT_BUS_ENABLED: "0"
|
||||||
|
EVENT_BUS_CONSUMER_ENABLED: "0"
|
||||||
|
AI_VOICE_ENABLED: "0"
|
||||||
|
AI_VOICE_AUDIOSOCKET_ENABLED: "0"
|
||||||
|
SALES_VOICE_RUNTIME_ENABLED: "1"
|
||||||
|
ERROR_TELEGRAM_ALERTS: "0"
|
||||||
|
|
||||||
|
x-service-defaults: &service_defaults
|
||||||
|
image: ${CALL_CENTER_IMAGE:-call-center-app:active-aimaq}
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- ./.env.production
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
volumes:
|
||||||
|
- ./.data_local:/app/.data_local
|
||||||
|
extra_hosts:
|
||||||
|
- host.docker.internal:host-gateway
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: aimaq-call-center-postgres
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- ./.env
|
||||||
|
volumes:
|
||||||
|
- ./.data_pg:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD-SHELL
|
||||||
|
- pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB"
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 12
|
||||||
|
start_period: 15s
|
||||||
|
|
||||||
|
migrate:
|
||||||
|
<<: *service_defaults
|
||||||
|
restart: "no"
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
command: ["python", "scripts/migrate_core_db.py"]
|
||||||
|
|
||||||
|
auth-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.auth_service.app:app
|
||||||
|
|
||||||
|
audit-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.audit_service.app:app
|
||||||
|
|
||||||
|
customer-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.customer_service.app:app
|
||||||
|
|
||||||
|
interaction-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.interaction_service.app:app
|
||||||
|
|
||||||
|
voice-adapter-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.voice_adapter_service.app:app
|
||||||
|
|
||||||
|
recording-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.recording_service.app:app
|
||||||
|
CC_RECORDINGS_DIR: /app/.data_local/recordings
|
||||||
|
RECORDING_MAX_BYTES: 26214400
|
||||||
|
|
||||||
|
reporting-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.reporting_service.app:app
|
||||||
|
|
||||||
|
sales-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.sales_service.app:app
|
||||||
|
SALES_AUTOMATION_WORKER_ENABLED: "1"
|
||||||
|
SALES_AUTOMATION_WORKER_INTERVAL_SECONDS: "5"
|
||||||
|
SALES_POST_CALL_AI_ENABLED: "1"
|
||||||
|
SALES_VOICE_RUNTIME_ENABLED: "1"
|
||||||
|
SALES_TELEGRAM_BRIDGE_ENABLED: "0"
|
||||||
|
|
||||||
|
asterisk-bridge-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- interaction-service
|
||||||
|
- voice-adapter-service
|
||||||
|
- sales-service
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.asterisk_bridge_service.app:app
|
||||||
|
ASTERISK_BRIDGE_ENABLED: "1"
|
||||||
|
ASTERISK_BRIDGE_FAILED_RETRY_ENABLED: "0"
|
||||||
|
AI_VOICE_ENABLED: "0"
|
||||||
|
SALES_VOICE_RUNTIME_ENABLED: "1"
|
||||||
|
ports:
|
||||||
|
- "8036:8000"
|
||||||
|
|
||||||
|
api-gateway:
|
||||||
|
<<: *service_defaults
|
||||||
|
container_name: aimaq-call-center-app
|
||||||
|
depends_on:
|
||||||
|
- auth-service
|
||||||
|
- audit-service
|
||||||
|
- customer-service
|
||||||
|
- interaction-service
|
||||||
|
- voice-adapter-service
|
||||||
|
- recording-service
|
||||||
|
- reporting-service
|
||||||
|
- sales-service
|
||||||
|
- asterisk-bridge-service
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: gateway.app:app
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: ${CALL_CENTER_FRONTEND_IMAGE:-omnichannel-contact-center:active-aimaq}
|
||||||
|
container_name: aimaq-call-center-frontend
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- api-gateway
|
||||||
|
- voice-ai
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:3082:80"
|
||||||
|
volumes:
|
||||||
|
- ./frontend.nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- common_network
|
||||||
|
|
||||||
|
voice-ai:
|
||||||
|
image: ${VOICE_AI_IMAGE:-voice-call-center-ai:active-aimaq}
|
||||||
|
container_name: aimaq-voice-ai
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- ./.env.voice-ai
|
||||||
|
ports:
|
||||||
|
# AudioSocket-шлюз для входящих звонков из Asterisk (хост-процесс)
|
||||||
|
- "127.0.0.1:9094:9094"
|
||||||
|
volumes:
|
||||||
|
- /root/voice-call-center-ai/knowledge:/app/knowledge:ro
|
||||||
|
# CALLERID входящего звонка: диалплан пишет <uuid>.callerid, шлюз читает и удаляет
|
||||||
|
- /tmp/ainur-meta:/ainur-meta
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- common_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
name: aimaq-call-center_default
|
||||||
|
common_network:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
services:
|
||||||
|
ai-voice-runtime-service:
|
||||||
|
environment:
|
||||||
|
- AI_VOICE_V2_STREAMING_ASR_BACKEND=elevenlabs_realtime
|
||||||
|
- AI_VOICE_ASR_PROVIDER=elevenlabs
|
||||||
|
- AI_VOICE_START_DEFAULT_LANGUAGE_ON_UNCLEAR=ru
|
||||||
|
- AI_VOICE_V2_PARTIAL_ASR=1
|
||||||
|
- AI_VOICE_V2_DUPLEX_ENABLED=1
|
||||||
|
- AI_VOICE_V2_STREAMING_ASR_TIMEOUT_SECONDS=15
|
||||||
|
- AI_VOICE_V2_STREAMING_ASR_SUPPORTED_LANGUAGES=ru,kk
|
||||||
|
- AI_VOICE_VAD_RMS_THRESHOLD=800
|
||||||
|
- AI_VOICE_VAD_MIN_SPEECH_MS=300
|
||||||
|
- AI_VOICE_VAD_TRAILING_SILENCE_MS=500
|
||||||
|
ports:
|
||||||
|
- 127.0.0.1:9019:9019
|
||||||
|
volumes:
|
||||||
|
- /tmp/asr_modified.py:/app/services/ai_voice_runtime_service/providers/asr.py:ro
|
||||||
|
asterisk-bridge-service:
|
||||||
|
environment:
|
||||||
|
- ASTERISK_AMI_HOST=172.19.0.1
|
||||||
|
- ASTERISK_BRIDGE_ENABLED=1
|
||||||
|
- ASTERISK_SFTP_HOST=172.19.0.1
|
||||||
|
- MVPCC_AI_AUDIOSOCKET_SERVICE=127.0.0.1:9019
|
||||||
|
sales-service:
|
||||||
|
environment:
|
||||||
|
- WHATSAPP_OUTBOUND_ENABLED=1
|
||||||
|
- SALES_VOICE_RUNTIME_ENABLED=1
|
||||||
|
telegram-adapter-service:
|
||||||
|
environment:
|
||||||
|
- TELEGRAM_BOT_ENABLED=1
|
||||||
|
- AI_TELEGRAM_ENABLED=1
|
||||||
|
- SALES_TELEGRAM_BRIDGE_ENABLED=1
|
||||||
|
- SALES_VOICE_RUNTIME_ENABLED=1
|
||||||
|
whatsapp-adapter-service:
|
||||||
|
environment:
|
||||||
|
- WHATSAPP_OUTBOUND_ENABLED=1
|
||||||
|
- AI_WHATSAPP_ENABLED=1
|
||||||
|
- SALES_VOICE_RUNTIME_ENABLED=1
|
||||||
@@ -0,0 +1,400 @@
|
|||||||
|
name: aimaq-call-center
|
||||||
|
|
||||||
|
x-app-env: &app_env
|
||||||
|
CC_DATA_DIR: /app/.data_local
|
||||||
|
DATABASE_URL: postgresql+psycopg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
|
||||||
|
SCHEMA_MANAGEMENT_MODE: migrations
|
||||||
|
AUTH_SERVICE_URL: http://auth-service:8000
|
||||||
|
AUDIT_SERVICE_URL: http://audit-service:8000
|
||||||
|
CUSTOMER_SERVICE_URL: http://customer-service:8000
|
||||||
|
INTERACTION_SERVICE_URL: http://interaction-service:8000
|
||||||
|
ROUTING_SERVICE_URL: http://routing-service:8000
|
||||||
|
VOICE_ADAPTER_SERVICE_URL: http://voice-adapter-service:8000
|
||||||
|
RECORDING_SERVICE_URL: http://recording-service:8000
|
||||||
|
IVR_SERVICE_URL: http://ivr-service:8000
|
||||||
|
EVENT_BUS_SERVICE_URL: http://event-bus-service:8000
|
||||||
|
ASTERISK_BRIDGE_SERVICE_URL: http://asterisk-bridge-service:8000
|
||||||
|
TELEGRAM_ADAPTER_SERVICE_URL: http://telegram-adapter-service:8000
|
||||||
|
WHATSAPP_ADAPTER_SERVICE_URL: http://whatsapp-adapter-service:8000
|
||||||
|
AI_ORCHESTRATOR_SERVICE_URL: http://ai-orchestrator-service:8000
|
||||||
|
AI_VOICE_RUNTIME_SERVICE_URL: http://ai-voice-runtime-service:8000
|
||||||
|
WEBCHAT_ADAPTER_SERVICE_URL: http://webchat-adapter-service:8000
|
||||||
|
EMAIL_ADAPTER_SERVICE_URL: http://email-adapter-service:8000
|
||||||
|
KB_SERVICE_URL: http://kb-service:8000
|
||||||
|
REPORTING_SERVICE_URL: http://reporting-service:8000
|
||||||
|
SUPERVISOR_SERVICE_URL: http://supervisor-service:8000
|
||||||
|
SALES_SERVICE_URL: http://sales-service:8000
|
||||||
|
LOCAL_STACK_PUBLIC_BASE_URL: https://aimaq.konturai.kz
|
||||||
|
ASTERISK_WEBRTC_WS_URL: wss://aimaq.konturai.kz/asterisk-ws
|
||||||
|
ASTERISK_BRIDGE_ENABLED: "0"
|
||||||
|
ASTERISK_CALLCONTROL_ENABLED: "0"
|
||||||
|
ASTERISK_IVR_FASTAGI_ENABLED: "0"
|
||||||
|
ASTERISK_WEBRTC_ENABLED: "0"
|
||||||
|
TELEGRAM_BOT_ENABLED: "0"
|
||||||
|
AI_TELEGRAM_ENABLED: "0"
|
||||||
|
WHATSAPP_OUTBOUND_ENABLED: "0"
|
||||||
|
AI_WHATSAPP_ENABLED: "0"
|
||||||
|
SALES_TELEGRAM_BRIDGE_ENABLED: "0"
|
||||||
|
SALES_VOICE_RUNTIME_ENABLED: "0"
|
||||||
|
AI_VOICE_ENABLED: "0"
|
||||||
|
AI_VOICE_AUDIOSOCKET_ENABLED: "0"
|
||||||
|
ERROR_TELEGRAM_ALERTS: "0"
|
||||||
|
EVENT_BUS_ENABLED: "0"
|
||||||
|
EVENT_BUS_CONSUMER_ENABLED: "0"
|
||||||
|
AI_VOICE_ASR_PROVIDER: ${AI_VOICE_ASR_PROVIDER:-elevenlabs}
|
||||||
|
AI_VOICE_TTS_PROVIDER: ${AI_VOICE_TTS_PROVIDER:-elevenlabs}
|
||||||
|
AI_VOICE_V2_STREAMING_ASR_BACKEND: ${AI_VOICE_V2_STREAMING_ASR_BACKEND:-elevenlabs_realtime}
|
||||||
|
AI_VOICE_V2_STREAMING_ASR_BASE_URL: http://streaming-asr-sidecar:8021
|
||||||
|
AI_VOICE_V2_STREAMING_ASR_TIMEOUT_SECONDS: "4"
|
||||||
|
AI_VOICE_V2_STREAMING_ASR_PARTIAL_POLL_ENABLED: "1"
|
||||||
|
|
||||||
|
x-service-defaults: &service_defaults
|
||||||
|
image: ${CALL_CENTER_IMAGE:-call-center-app:active-main}
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- ./.env.production
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
volumes:
|
||||||
|
- ./.data_local:/app/.data_local
|
||||||
|
extra_hosts:
|
||||||
|
- host.docker.internal:host-gateway
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- python
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
from urllib.request import urlopen
|
||||||
|
import sys
|
||||||
|
sys.exit(0 if urlopen("http://127.0.0.1:8000/health", timeout=2).getcode() == 200 else 1)
|
||||||
|
interval: 15s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: aimaq-call-center-postgres
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- ./.env
|
||||||
|
volumes:
|
||||||
|
- ./.data_pg:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD-SHELL
|
||||||
|
- pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB"
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 12
|
||||||
|
start_period: 15s
|
||||||
|
|
||||||
|
migrate:
|
||||||
|
<<: *service_defaults
|
||||||
|
restart: "no"
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
command: ["python", "scripts/migrate_core_db.py"]
|
||||||
|
healthcheck:
|
||||||
|
disable: true
|
||||||
|
|
||||||
|
auth-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.auth_service.app:app
|
||||||
|
|
||||||
|
audit-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.audit_service.app:app
|
||||||
|
|
||||||
|
customer-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.customer_service.app:app
|
||||||
|
|
||||||
|
interaction-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.interaction_service.app:app
|
||||||
|
|
||||||
|
routing-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.routing_service.app:app
|
||||||
|
|
||||||
|
voice-adapter-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.voice_adapter_service.app:app
|
||||||
|
|
||||||
|
recording-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.recording_service.app:app
|
||||||
|
CC_RECORDINGS_DIR: /app/.data_local/recordings
|
||||||
|
RECORDING_MAX_BYTES: 26214400
|
||||||
|
|
||||||
|
ivr-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.ivr_service.app:app
|
||||||
|
|
||||||
|
telegram-adapter-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.telegram_adapter_service.app:app
|
||||||
|
|
||||||
|
whatsapp-adapter-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.whatsapp_adapter_service.app:app
|
||||||
|
|
||||||
|
ai-orchestrator-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.ai_orchestrator_service.app:app
|
||||||
|
|
||||||
|
streaming-asr-sidecar:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
command: ["sh", "-c", "uvicorn $${APP_MODULE} --host 0.0.0.0 --port 8021"]
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.streaming_asr_sidecar_service.app:app
|
||||||
|
AI_VOICE_V2_STREAMING_ASR_MODEL: base
|
||||||
|
AI_VOICE_V2_STREAMING_ASR_COMPUTE_TYPE: int8
|
||||||
|
AI_VOICE_V2_STREAMING_ASR_DEVICE: cpu
|
||||||
|
AI_VOICE_V2_STREAMING_ASR_CACHE_DIR: /models/faster_whisper
|
||||||
|
AI_VOICE_V2_STREAMING_ASR_SUPPORTED_LANGUAGES: ru
|
||||||
|
volumes:
|
||||||
|
- ./.data_local:/app/.data_local
|
||||||
|
- ./.models/faster_whisper:/models/faster_whisper
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- python
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
from urllib.request import urlopen
|
||||||
|
import sys
|
||||||
|
sys.exit(0 if urlopen("http://127.0.0.1:8021/health", timeout=2).getcode() == 200 else 1)
|
||||||
|
interval: 15s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
ai-voice-runtime-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
streaming-asr-sidecar:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.ai_voice_runtime_service.app:app
|
||||||
|
AI_VOICE_ENABLED: "1"
|
||||||
|
AI_VOICE_AUDIOSOCKET_ENABLED: "1"
|
||||||
|
SALES_VOICE_RUNTIME_ENABLED: "1"
|
||||||
|
ports:
|
||||||
|
- "9023:9019"
|
||||||
|
|
||||||
|
webchat-adapter-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.webchat_adapter_service.app:app
|
||||||
|
|
||||||
|
email-adapter-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.email_adapter_service.app:app
|
||||||
|
|
||||||
|
kb-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.kb_service.app:app
|
||||||
|
|
||||||
|
reporting-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.reporting_service.app:app
|
||||||
|
|
||||||
|
supervisor-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.supervisor_service.app:app
|
||||||
|
|
||||||
|
sales-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.sales_service.app:app
|
||||||
|
SALES_TELEGRAM_BRIDGE_ENABLED: "0"
|
||||||
|
SALES_VOICE_RUNTIME_ENABLED: "1"
|
||||||
|
|
||||||
|
event-bus-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.event_bus_service.app:app
|
||||||
|
|
||||||
|
asterisk-bridge-service:
|
||||||
|
<<: *service_defaults
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: services.asterisk_bridge_service.app:app
|
||||||
|
ASTERISK_IVR_FASTAGI_HOST: 0.0.0.0
|
||||||
|
ASTERISK_IVR_FASTAGI_PORT: 4573
|
||||||
|
ASTERISK_BRIDGE_ENABLED: "1"
|
||||||
|
AI_VOICE_ENABLED: "1"
|
||||||
|
ASTERISK_BRIDGE_FAILED_RETRY_ENABLED: "0"
|
||||||
|
ports:
|
||||||
|
- "8036:8000"
|
||||||
|
|
||||||
|
api-gateway:
|
||||||
|
<<: *service_defaults
|
||||||
|
container_name: aimaq-call-center-app
|
||||||
|
depends_on:
|
||||||
|
auth-service:
|
||||||
|
condition: service_healthy
|
||||||
|
audit-service:
|
||||||
|
condition: service_healthy
|
||||||
|
customer-service:
|
||||||
|
condition: service_healthy
|
||||||
|
interaction-service:
|
||||||
|
condition: service_healthy
|
||||||
|
routing-service:
|
||||||
|
condition: service_healthy
|
||||||
|
voice-adapter-service:
|
||||||
|
condition: service_healthy
|
||||||
|
recording-service:
|
||||||
|
condition: service_healthy
|
||||||
|
ivr-service:
|
||||||
|
condition: service_healthy
|
||||||
|
telegram-adapter-service:
|
||||||
|
condition: service_healthy
|
||||||
|
whatsapp-adapter-service:
|
||||||
|
condition: service_healthy
|
||||||
|
ai-orchestrator-service:
|
||||||
|
condition: service_healthy
|
||||||
|
ai-voice-runtime-service:
|
||||||
|
condition: service_healthy
|
||||||
|
webchat-adapter-service:
|
||||||
|
condition: service_healthy
|
||||||
|
email-adapter-service:
|
||||||
|
condition: service_healthy
|
||||||
|
kb-service:
|
||||||
|
condition: service_healthy
|
||||||
|
reporting-service:
|
||||||
|
condition: service_healthy
|
||||||
|
supervisor-service:
|
||||||
|
condition: service_healthy
|
||||||
|
sales-service:
|
||||||
|
condition: service_healthy
|
||||||
|
event-bus-service:
|
||||||
|
condition: service_healthy
|
||||||
|
asterisk-bridge-service:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
<<: *app_env
|
||||||
|
APP_MODULE: gateway.app:app
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: ${CALL_CENTER_FRONTEND_IMAGE:-omnichannel-contact-center:latest}
|
||||||
|
container_name: aimaq-call-center-frontend
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
api-gateway:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:3082:80"
|
||||||
|
volumes:
|
||||||
|
- ./frontend.nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- common_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
name: aimaq-call-center_default
|
||||||
|
common_network:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
resolver 127.0.0.11 valid=30s ipv6=off;
|
||||||
|
resolver_timeout 5s;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
client_max_body_size 50m;
|
||||||
|
|
||||||
|
location = /health {
|
||||||
|
set $api_gateway http://aimaq-call-center-app:8000;
|
||||||
|
proxy_pass $api_gateway/health;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /proxy/ {
|
||||||
|
set $api_gateway http://aimaq-call-center-app:8000;
|
||||||
|
proxy_pass $api_gateway;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
proxy_send_timeout 600s;
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header Origin $http_origin;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /voice-ai/operator-ws {
|
||||||
|
set $voice_ai_upstream_op http://aimaq-voice-ai:8099;
|
||||||
|
proxy_pass $voice_ai_upstream_op/operator-ws;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
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_read_timeout 3600s;
|
||||||
|
proxy_send_timeout 3600s;
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /voice-ai/ws {
|
||||||
|
set $voice_ai_upstream http://aimaq-voice-ai:8099;
|
||||||
|
proxy_pass $voice_ai_upstream/ws;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
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_read_timeout 3600s;
|
||||||
|
proxy_send_timeout 3600s;
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user