diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 84da8d0..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,11 +0,0 @@ -version: 2 -updates: - - package-ecosystem: github-actions - directory: / - schedule: - interval: weekly - - - package-ecosystem: docker - directory: / - schedule: - interval: weekly diff --git a/.github/workflows/gateway-publish.yml b/.github/workflows/gateway-publish.yml index f4f6cf6..6c65ef5 100644 --- a/.github/workflows/gateway-publish.yml +++ b/.github/workflows/gateway-publish.yml @@ -2,7 +2,7 @@ name: "Build & Publish Gateway Image" on: push: - branches: [main] + branches: [main, develop] tags: ["v*.*.*"] paths: - "nginx/**" @@ -95,6 +95,8 @@ jobs: TAGS="${IMAGE}:${VERSION},${IMAGE}:latest" elif [[ "${GH_REF}" == refs/heads/main ]]; then TAGS="${IMAGE}:latest,${IMAGE}:main-${SHA_SHORT}" + elif [[ "${GH_REF}" == refs/heads/develop ]]; then + TAGS="${IMAGE}:develop,${IMAGE}:develop-${SHA_SHORT}" fi echo "tags=${TAGS}" >> "$GITHUB_OUTPUT" diff --git a/docker-compose.swarm.yaml b/docker-compose.swarm.yaml index 76eb085..cf344d5 100644 --- a/docker-compose.swarm.yaml +++ b/docker-compose.swarm.yaml @@ -30,6 +30,18 @@ services: # --------------------------------------------------------------------------- evo_gateway: image: evoapicloud/evo-crm-gateway:latest + # The gateway routes to the 5 backend services by their docker service + # names. Defaults match the names used in this stack (evo_auth, evo_crm, + # evo_core, evo_processor, evo_bot_runtime). If you rename the services + # in your own stack (e.g. using a different prefix), uncomment and set + # the matching *_UPSTREAM env var — otherwise the gateway cannot resolve + # them and every request returns 502. See nginx/README.md for details. + # environment: + # AUTH_UPSTREAM: my_auth:3001 + # CRM_UPSTREAM: my_crm:3000 + # CORE_UPSTREAM: my_core:5555 + # PROCESSOR_UPSTREAM: my_processor:8000 + # BOT_RUNTIME_UPSTREAM: my_bot_runtime:8080 networks: - network_public deploy: diff --git a/docker-compose.yml b/docker-compose.yml index 7b0d11a..64e2748 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -245,6 +245,7 @@ services: LISTEN_ADDR: 0.0.0.0:8080 REDIS_URL: redis://:${REDIS_PASSWORD:-evoai_redis_pass}@redis:6379 AI_PROCESSOR_URL: http://evo-processor:8000 + BOT_RUNTIME_SECRET: ${BOT_RUNTIME_SECRET:-evo-bot-runtime-dev-secret} depends_on: redis: condition: service_healthy diff --git a/evo-ai-core-service-community b/evo-ai-core-service-community index 0dd157c..746adc2 160000 --- a/evo-ai-core-service-community +++ b/evo-ai-core-service-community @@ -1 +1 @@ -Subproject commit 0dd157cb4e5b4505efbf2d4c8785935fe27208fb +Subproject commit 746adc20b9df23cf5860f1233a90c7884d1ebc8f diff --git a/evo-ai-frontend-community b/evo-ai-frontend-community index 4485997..6c2cc86 160000 --- a/evo-ai-frontend-community +++ b/evo-ai-frontend-community @@ -1 +1 @@ -Subproject commit 4485997fedab18df01ca906b20663f6388ddfebc +Subproject commit 6c2cc86e164ffc93adf8a177fe87ab8be39a8ab3 diff --git a/nginx/Dockerfile b/nginx/Dockerfile index 47d11be..4d65ad9 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -1,3 +1,17 @@ FROM nginx:alpine -COPY nginx.conf /etc/nginx/conf.d/default.conf + +# Default upstream targets. Override any of these at deploy time when the +# backend service names in your stack differ from the defaults below. +ENV AUTH_UPSTREAM=evo_auth:3001 \ + CRM_UPSTREAM=evo_crm:3000 \ + CORE_UPSTREAM=evo_core:5555 \ + PROCESSOR_UPSTREAM=evo_processor:8000 \ + BOT_RUNTIME_UPSTREAM=evo_bot_runtime:8080 + +# Limit envsubst to the upstream vars so nginx's own $variables (e.g. $host, +# $request_uri) are not touched at render time. +ENV NGINX_ENVSUBST_FILTER="^(AUTH|CRM|CORE|PROCESSOR|BOT_RUNTIME)_UPSTREAM$" + +COPY default.conf.template /etc/nginx/templates/default.conf.template + EXPOSE 3030 diff --git a/nginx/README.md b/nginx/README.md new file mode 100644 index 0000000..2f47052 --- /dev/null +++ b/nginx/README.md @@ -0,0 +1,97 @@ +# Evo CRM — API Gateway + +Single-entrypoint nginx that dispatches incoming requests to the five +backend services by URL path. Packaged as +`evoapicloud/evo-crm-gateway` and meant to sit behind a TLS-terminating +reverse proxy (Traefik, Caddy, an ALB, etc.). + +## Routing + +Targets are declared as nginx variables at the top of the rendered config: + +| Variable | Receives requests for | +|---------------------------|------------------------------------------------------| +| `$auth_service` | `/oauth`, `/.well-known`, `/setup/*`, `/api/v1/auth`, `/api/v1/users`, `/api/v1/accounts`, `/platform/*`, `/api/v1/super_admin` (most) | +| `$crm_service` | `/cable`, `/webhooks/*`, `/rails/active_storage`, `/api/v1/accounts/:id/webhooks`, `/api/v1/super_admin/{whitelabel,app_configs,upload,agent_bots,installation_configs,account_users}`, catch-all for unmatched `/api/v1/*` and `/` | +| `$evoai_service` | `/api/v1/{agents,folders,mcp-servers,custom-mcp-servers,custom-tools}` | +| `$processor_service` | `/api/v1/{chat,a2a,sessions,tools,clients}`, `/api/v1/agents/:id/integrations`, `/api/v1/integrations/:provider/callback`, `/api/v1/custom-mcp-servers/discover-tools`, `/health`, `/ready` | +| `$bot_runtime_service` | `/api/v1/bot-runtime` | + +Full path matrix is in [`default.conf.template`](./default.conf.template). + +## Configurable upstreams + +Each of the five variables above is rendered at container start from an +environment variable. Defaults match the service names used by the +reference `docker-compose.yaml` and `docker-compose.swarm.yaml`. + +| Env var | Default | Points to | +|-------------------------|-------------------------|-----------| +| `AUTH_UPSTREAM` | `evo_auth:3001` | `evo-auth-service-community` | +| `CRM_UPSTREAM` | `evo_crm:3000` | `evo-ai-crm-community` | +| `CORE_UPSTREAM` | `evo_core:5555` | `evo-ai-core-service-community` | +| `PROCESSOR_UPSTREAM` | `evo_processor:8000` | `evo-ai-processor-community` | +| `BOT_RUNTIME_UPSTREAM` | `evo_bot_runtime:8080` | `evo-bot-runtime` | + +Format is always `host:port`, no scheme. The gateway concatenates `http://` +at the front when rendering. + +### When you need to override + +If your deployment renames any of the backend services (e.g. applying a +`evocrm_` prefix, or shortening to `auth`/`crm`/…) the gateway cannot +resolve the default hostnames and every proxied request returns **502 Bad +Gateway**. Set the matching `*_UPSTREAM` env vars on the gateway service +to the service names you actually used. + +### Example — prefixed service names + +Stack uses `evocrm_auth`, `evocrm_crm`, `evocrm_core`, `evocrm_processor`, +`evocrm_bot_runtime`: + +```yaml +services: + evocrm_gateway: + image: evoapicloud/evo-crm-gateway:latest + environment: + AUTH_UPSTREAM: evocrm_auth:3001 + CRM_UPSTREAM: evocrm_crm:3000 + CORE_UPSTREAM: evocrm_core:5555 + PROCESSOR_UPSTREAM: evocrm_processor:8000 + BOT_RUNTIME_UPSTREAM: evocrm_bot_runtime:8080 +``` + +### Example — non-standard ports + +If you expose the auth service on `4001` instead of `3001`: + +```yaml +environment: + AUTH_UPSTREAM: evo_auth:4001 +``` + +## Verifying the rendered config + +To confirm the variables were substituted correctly, inspect the rendered +file inside a running container: + +```bash +docker exec \ + grep -E "set \$(auth|crm|evoai|processor|bot_runtime)_service" \ + /etc/nginx/conf.d/default.conf +``` + +You should see the expected hostnames. If any line still contains +`${VARNAME}` literally, the env var was not set and envsubst skipped it. + +## Build + +```bash +docker build -t evo-crm-gateway:local nginx/ +``` + +The image uses the stock `nginx:alpine` base and the image's built-in +template rendering — templates in `/etc/nginx/templates/*.template` are +processed by envsubst at container start. `NGINX_ENVSUBST_FILTER` is +restricted to the five `*_UPSTREAM` vars so the substitution pass does +not touch nginx's own runtime variables (`$host`, `$request_uri`, etc.). diff --git a/nginx/nginx.conf b/nginx/default.conf.template similarity index 97% rename from nginx/nginx.conf rename to nginx/default.conf.template index fa240f5..86087fa 100644 --- a/nginx/nginx.conf +++ b/nginx/default.conf.template @@ -21,12 +21,16 @@ server { # ============================================================================= # Upstream targets as variables + # + # Hosts/ports are rendered at container start by envsubst from the + # *_UPSTREAM env vars (see Dockerfile for defaults). Override them + # when the backend service names in your stack differ from the defaults. # ============================================================================= - set $auth_service http://evo_auth:3001; - set $evoai_service http://evo_core:5555; - set $crm_service http://evo_crm:3000; - set $processor_service http://evo_processor:8000; - set $bot_runtime_service http://evo_bot_runtime:8080; + set $auth_service http://${AUTH_UPSTREAM}; + set $evoai_service http://${CORE_UPSTREAM}; + set $crm_service http://${CRM_UPSTREAM}; + set $processor_service http://${PROCESSOR_UPSTREAM}; + set $bot_runtime_service http://${BOT_RUNTIME_UPSTREAM}; underscores_in_headers on;