From a731525f5e1abfb97000ba4cd31a62b82f918e6e Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Fri, 20 Feb 2026 11:57:47 +0700 Subject: [PATCH] infra: split deploy into frontend delivery and langfuse projects --- deploy-map.toml | 5 +- deploy/README.md | 17 ++++ deploy/delivery/docker-compose.yml | 17 ++++ deploy/frontend/docker-compose.yml | 43 +++++++++ deploy/langfuse/docker-compose.yml | 144 +++++++++++++++++++++++++++++ 5 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 deploy/README.md create mode 100644 deploy/delivery/docker-compose.yml create mode 100644 deploy/frontend/docker-compose.yml create mode 100644 deploy/langfuse/docker-compose.yml diff --git a/deploy-map.toml b/deploy-map.toml index e45bd84..918ce2a 100644 --- a/deploy-map.toml +++ b/deploy-map.toml @@ -1,5 +1,6 @@ version = 1 [services] -frontend = { deploy_mode = "dokploy_webhook", env_storage = "dokploy_ui" } -delivery_worker = { deploy_mode = "dokploy_webhook", env_storage = "dokploy_ui" } +frontend = { deploy_mode = "dokploy_webhook", env_storage = "dokploy_ui", compose_path = "deploy/frontend/docker-compose.yml" } +delivery_worker = { deploy_mode = "dokploy_webhook", env_storage = "dokploy_ui", compose_path = "deploy/delivery/docker-compose.yml" } +langfuse = { deploy_mode = "dokploy_webhook", env_storage = "dokploy_ui", compose_path = "deploy/langfuse/docker-compose.yml" } diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..4e3c6b6 --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,17 @@ +# Deployment Split + +This repository now includes independent compose files per project: + +- `deploy/frontend/docker-compose.yml` - Nuxt app (UI + Nitro API/GraphQL + Prisma access) +- `deploy/delivery/docker-compose.yml` - delivery worker only +- `deploy/langfuse/docker-compose.yml` - Langfuse + ClickHouse/Redis/Postgres/MinIO + +Use separate Dokploy projects so each stack can be redeployed independently. + +## Recommended Dokploy mapping + +1. Frontend project -> `deploy/frontend/docker-compose.yml` +2. Delivery project -> `deploy/delivery/docker-compose.yml` +3. Langfuse project -> `deploy/langfuse/docker-compose.yml` + +`deploy-map.toml` contains the same paths in `[services]`. diff --git a/deploy/delivery/docker-compose.yml b/deploy/delivery/docker-compose.yml new file mode 100644 index 0000000..ffd2d0e --- /dev/null +++ b/deploy/delivery/docker-compose.yml @@ -0,0 +1,17 @@ +services: + delivery: + build: + context: ../../Frontend + dockerfile: Dockerfile.worker + environment: + DATABASE_URL: "${DATABASE_URL:-postgresql://postgres:dpb6gmj1umjhohso@crm-sql-q57r8m:5432/postgres?schema=public}" + REDIS_URL: "${REDIS_URL:-redis://default:nw0mv1pemhnbh7gw@crm-redis-vkpxku:6379}" + TELEGRAM_API_BASE: "${TELEGRAM_API_BASE:-https://api.telegram.org}" + TELEGRAM_BOT_TOKEN: "${TELEGRAM_BOT_TOKEN:-}" + networks: + - default + - dokploy-network + +networks: + dokploy-network: + external: true diff --git a/deploy/frontend/docker-compose.yml b/deploy/frontend/docker-compose.yml new file mode 100644 index 0000000..4f2d832 --- /dev/null +++ b/deploy/frontend/docker-compose.yml @@ -0,0 +1,43 @@ +services: + frontend: + build: + context: ../../Frontend + dockerfile: Dockerfile + expose: + - "3000" + environment: + DATABASE_URL: "${DATABASE_URL:-postgresql://postgres:dpb6gmj1umjhohso@crm-sql-q57r8m:5432/postgres?schema=public}" + REDIS_URL: "${REDIS_URL:-redis://default:nw0mv1pemhnbh7gw@crm-redis-vkpxku:6379}" + CF_AGENT_MODE: "langgraph" + OPENROUTER_API_KEY: "${OPENROUTER_API_KEY:-}" + OPENROUTER_BASE_URL: "https://openrouter.ai/api/v1" + OPENROUTER_MODEL: "arcee-ai/trinity-large-preview:free" + OPENROUTER_HTTP_REFERER: "${OPENROUTER_HTTP_REFERER:-}" + OPENROUTER_X_TITLE: "clientsflow" + OPENROUTER_REASONING_ENABLED: "${OPENROUTER_REASONING_ENABLED:-1}" + CF_WHISPER_MODEL: "${CF_WHISPER_MODEL:-Xenova/whisper-small}" + CF_WHISPER_LANGUAGE: "${CF_WHISPER_LANGUAGE:-ru}" + LANGFUSE_ENABLED: "${LANGFUSE_ENABLED:-true}" + LANGFUSE_BASE_URL: "${LANGFUSE_BASE_URL:-http://langfuse-web:3000}" + LANGFUSE_PUBLIC_KEY: "${LANGFUSE_PUBLIC_KEY:-pk-lf-local}" + LANGFUSE_SECRET_KEY: "${LANGFUSE_SECRET_KEY:-sk-lf-local}" + labels: + - traefik.enable=true + - traefik.docker.network=dokploy-network + - traefik.http.routers.clientsflow-web.entrypoints=web + - traefik.http.routers.clientsflow-web.middlewares=redirect-to-https@file + - traefik.http.routers.clientsflow-web.rule=Host(`clientsflow.dsrptlab.com`) + - traefik.http.routers.clientsflow-web.service=clientsflow-web + - traefik.http.routers.clientsflow-websecure.entrypoints=websecure + - traefik.http.routers.clientsflow-websecure.rule=Host(`clientsflow.dsrptlab.com`) + - traefik.http.routers.clientsflow-websecure.service=clientsflow-websecure + - traefik.http.routers.clientsflow-websecure.tls.certresolver=letsencrypt + - traefik.http.services.clientsflow-web.loadbalancer.server.port=3000 + - traefik.http.services.clientsflow-websecure.loadbalancer.server.port=3000 + networks: + - default + - dokploy-network + +networks: + dokploy-network: + external: true diff --git a/deploy/langfuse/docker-compose.yml b/deploy/langfuse/docker-compose.yml new file mode 100644 index 0000000..9ac9a86 --- /dev/null +++ b/deploy/langfuse/docker-compose.yml @@ -0,0 +1,144 @@ +services: + langfuse-worker: + image: docker.io/langfuse/langfuse-worker:3 + restart: always + depends_on: + langfuse-postgres: + condition: service_healthy + langfuse-minio: + condition: service_healthy + langfuse-redis: + condition: service_healthy + langfuse-clickhouse: + condition: service_healthy + environment: &langfuse_env + NEXTAUTH_URL: "http://localhost:3001" + DATABASE_URL: "postgresql://langfuse:langfuse@langfuse-postgres:5432/langfuse" + SALT: "clientsflow-local-salt" + ENCRYPTION_KEY: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + TELEMETRY_ENABLED: "false" + CLICKHOUSE_MIGRATION_URL: "clickhouse://langfuse-clickhouse:9000" + CLICKHOUSE_URL: "http://langfuse-clickhouse:8123" + CLICKHOUSE_USER: "clickhouse" + CLICKHOUSE_PASSWORD: "clickhouse" + CLICKHOUSE_CLUSTER_ENABLED: "false" + LANGFUSE_S3_EVENT_UPLOAD_BUCKET: "langfuse" + LANGFUSE_S3_EVENT_UPLOAD_REGION: "auto" + LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID: "minio" + LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY: "miniosecret" + LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT: "http://langfuse-minio:9000" + LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE: "true" + LANGFUSE_S3_EVENT_UPLOAD_PREFIX: "events/" + LANGFUSE_S3_MEDIA_UPLOAD_BUCKET: "langfuse" + LANGFUSE_S3_MEDIA_UPLOAD_REGION: "auto" + LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID: "minio" + LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY: "miniosecret" + LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT: "http://langfuse-minio:9000" + LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE: "true" + LANGFUSE_S3_MEDIA_UPLOAD_PREFIX: "media/" + REDIS_HOST: "langfuse-redis" + REDIS_PORT: "6379" + REDIS_AUTH: "langfuse-redis" + REDIS_TLS_ENABLED: "false" + + langfuse-web: + image: docker.io/langfuse/langfuse:3 + restart: always + depends_on: + langfuse-postgres: + condition: service_healthy + langfuse-minio: + condition: service_healthy + langfuse-redis: + condition: service_healthy + langfuse-clickhouse: + condition: service_healthy + expose: + - "3000" + environment: + <<: *langfuse_env + NEXTAUTH_SECRET: "clientsflow-local-nextauth-secret" + LANGFUSE_INIT_ORG_ID: "org-clientsflow" + LANGFUSE_INIT_ORG_NAME: "Clientsflow Local" + LANGFUSE_INIT_PROJECT_ID: "proj-clientsflow" + LANGFUSE_INIT_PROJECT_NAME: "clientsflow" + LANGFUSE_INIT_PROJECT_PUBLIC_KEY: "pk-lf-local" + LANGFUSE_INIT_PROJECT_SECRET_KEY: "sk-lf-local" + LANGFUSE_INIT_USER_EMAIL: "admin@clientsflow.local" + LANGFUSE_INIT_USER_NAME: "Local Admin" + LANGFUSE_INIT_USER_PASSWORD: "clientsflow-local-admin" + networks: + - default + - dokploy-network + + langfuse-clickhouse: + image: docker.io/clickhouse/clickhouse-server:latest + restart: always + user: "101:101" + environment: + CLICKHOUSE_DB: "default" + CLICKHOUSE_USER: "clickhouse" + CLICKHOUSE_PASSWORD: "clickhouse" + volumes: + - langfuse_clickhouse_data:/var/lib/clickhouse + - langfuse_clickhouse_logs:/var/log/clickhouse-server + healthcheck: + test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1"] + interval: 5s + timeout: 5s + retries: 20 + start_period: 5s + + langfuse-minio: + image: cgr.dev/chainguard/minio:latest + restart: always + entrypoint: sh + command: -c 'mkdir -p /data/langfuse && minio server --address ":9000" --console-address ":9001" /data' + environment: + MINIO_ROOT_USER: "minio" + MINIO_ROOT_PASSWORD: "miniosecret" + volumes: + - langfuse_minio_data:/data + healthcheck: + test: ["CMD", "mc", "ready", "local"] + interval: 2s + timeout: 5s + retries: 15 + start_period: 5s + + langfuse-redis: + image: docker.io/redis:7-alpine + restart: always + command: ["redis-server", "--requirepass", "langfuse-redis", "--maxmemory-policy", "noeviction"] + healthcheck: + test: ["CMD-SHELL", "redis-cli -a langfuse-redis ping | grep PONG"] + interval: 3s + timeout: 5s + retries: 20 + start_period: 5s + + langfuse-postgres: + image: postgres:16-alpine + restart: always + environment: + POSTGRES_DB: "langfuse" + POSTGRES_USER: "langfuse" + POSTGRES_PASSWORD: "langfuse" + volumes: + - langfuse_postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U langfuse -d langfuse"] + interval: 3s + timeout: 3s + retries: 20 + start_period: 5s + +volumes: + langfuse_postgres_data: + langfuse_clickhouse_data: + langfuse_clickhouse_logs: + langfuse_minio_data: + +networks: + dokploy-network: + external: true