> For the complete documentation index, see [llms.txt](https://ajuda.zdg.com.br/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ajuda.zdg.com.br/avancado-recursos-tecnicos/infraestrutura/como-instalar-o-z-pro-em-modo-cluster.md).

# Como instalar o Z-PRO em Modo Cluster

Por padrão, o backend do Z-PRO roda em **modo fork** — um único processo Node.js atendendo todas as requisições. Em instalações com volume alto de atendimentos, isso pode limitar o aproveitamento dos núcleos de CPU disponíveis no servidor. O **Modo Cluster** resolve isso: o PM2 passa a rodar **múltiplos processos (workers)** do backend em paralelo, distribuindo a carga entre eles.

Este guia mostra como ativar o Modo Cluster numa instalação já funcionando do Z-PRO.

{% hint style="danger" %}
**Recurso em beta, fora do escopo do suporte técnico.** A configuração e o ajuste de infraestrutura do Modo Cluster (Redis, PM2, número de workers) ficam sob responsabilidade do licenciado, de acordo com os termos de uso do modelo self-hosted. Valide em ambiente de teste antes de aplicar em produção.
{% endhint %}

{% hint style="info" %}
**Pré-requisitos:**

* Z-PRO já instalado e funcionando em modo fork (padrão).
* Acesso root/sudo ao servidor.
* Docker (para rodar o Redis) ou um Redis já disponível na rede.
* PM2 instalado e em uso para gerenciar o processo do backend.
  {% endhint %}

***

### Como funciona

No Modo Cluster, o PM2 inicia **N processos** do backend. Um deles é eleito **Worker 0 (primary)** e os demais são **secundários**:

<table><thead><tr><th width="287">Recurso</th><th width="111.3333740234375" align="center">Worker 0 (primary)</th><th align="center">Workers 1..N (secundários)</th></tr></thead><tbody><tr><td>HTTP API (GET)</td><td align="center">✓</td><td align="center">✓</td></tr><tr><td>HTTP API (POST/PUT/DELETE em rotas de sessão)</td><td align="center">✓</td><td align="center">proxy automático → Worker 0</td></tr><tr><td>Socket.IO</td><td align="center">✓</td><td align="center">✓ (sincronizado via Redis)</td></tr><tr><td>Sessões WhatsApp (Baileys/WWJS)</td><td align="center">✓</td><td align="center">✗</td></tr><tr><td>Jobs (cron/setInterval)</td><td align="center">✓</td><td align="center">✗</td></tr><tr><td>WebSocket do Webchat</td><td align="center">✓</td><td align="center">✗</td></tr></tbody></table>

Como cada worker é um processo separado, eles **não compartilham memória**. Por isso o **Redis** é obrigatório: ele faz o papel de **Socket.IO Adapter**, repassando os eventos de WebSocket entre todos os workers para que qualquer usuário conectado em qualquer worker receba as atualizações em tempo real.

{% hint style="warning" %}
**Sessões, jobs e Webchat continuam centralizados no Worker 0.** O Modo Cluster escala o atendimento HTTP e o Socket.IO, mas as conexões WhatsApp (Baileys/WWJS) e os jobs periódicos do sistema sempre rodam num único processo — isso evita sessões duplicadas e disputas de lock.
{% endhint %}

***

### Etapa 1: Subir o Redis

Se você ainda não tem um Redis disponível, crie um com Docker:

```bash
docker run -d --name zpro-redis --restart unless-stopped -p 6379:6379 redis:7-alpine redis-server --requirepass SUA_SENHA_AQUI
```

Confirme que ele está respondendo:

```bash
docker ps | grep zpro-redis
docker exec -it zpro-redis redis-cli -a SUA_SENHA_AQUI ping
```

O comando `ping` deve retornar `PONG`.

***

### Etapa 2: Configurar o `.env` do backend

Adicione (ou edite) estas variáveis no `.env` do backend:

```env
# ===== REDIS (obrigatório para cluster) =====
IO_REDIS_SERVER=localhost
IO_REDIS_PASSWORD=SUA_SENHA_AQUI
IO_REDIS_PORT=6379
IO_REDIS_DB_SESSION=2

# ===== CLUSTER MODE =====
CLUSTER_MODE=true

# Número de workers (processos). Recomendado: número de CPUs do servidor ou metade
CLUSTER_INSTANCES=4

# Porta interna usada pelos workers secundários para fazer proxy ao Worker 0
# Não deve ser exposta externamente nem coincidir com a porta principal (PORT)
CLUSTER_PRIMARY_PORT=3002
```

{% hint style="danger" %}
**`CLUSTER_PRIMARY_PORT` é de uso interno.** Ela é usada apenas para a comunicação entre workers — não abra essa porta no firewall nem exponha ao público.
{% endhint %}

***

### Etapa 3: Build do projeto

Diferente do modo fork, o Modo Cluster **exige build** antes de iniciar:

```bash
npm run build
```

***

### Etapa 4: Iniciar com PM2

```bash
CLUSTER_MODE=true CLUSTER_INSTANCES=4 pm2 start ecosystem.config.js
```

{% hint style="info" %}
As variáveis também podem já estar definidas no `.env` — nesse caso, basta rodar `pm2 start ecosystem.config.js` sem repeti-las na linha de comando.
{% endhint %}

***

### Etapa 5: Verificar os workers

```bash
pm2 list                    # mostra quantos workers estão rodando
pm2 logs                    # logs de todos os workers
pm2 logs 0                  # logs só do Worker 0 (primary)
pm2 monit                   # monitor em tempo real (CPU/memória por worker)
```

Você deve ver `CLUSTER_INSTANCES` processos com o nome `zpro-backend` listados como `online`.

***

### Voltar ao modo fork

Para desativar o cluster e voltar ao comportamento original (um único processo):

```env
CLUSTER_MODE=false
```

Ou simplesmente remova a variável `CLUSTER_MODE` do `.env`. Depois, reinicie:

```bash
pm2 restart all
```

***

### Resumo dos Comandos

| Comando                           | Função                                              |
| --------------------------------- | --------------------------------------------------- |
| `pm2 start ecosystem.config.js`   | Inicia o backend (fork ou cluster, conforme `.env`) |
| `pm2 list`                        | Lista os workers em execução                        |
| `pm2 logs` / `pm2 logs 0`         | Logs de todos os workers / só do Worker 0           |
| `pm2 monit`                       | Monitor de CPU/memória em tempo real                |
| `pm2 restart all`                 | Reinicia todos os workers                           |
| `pm2 stop all` / `pm2 delete all` | Para / remove todos os workers                      |

***

### Encerramento

Com o Modo Cluster ativo, o Z-PRO passa a distribuir as requisições HTTP entre múltiplos processos, aproveitando melhor os núcleos de CPU do servidor — sem duplicar sessões do WhatsApp nem os jobs internos, que continuam centralizados no Worker 0. É a opção recomendada para instalações com alto volume de atendimentos simultâneos.

***

### Sobre o suporte a este recurso

O Z-PRO é **self-hosted**: a ZPRO fornece o software, não a infraestrutura — a gestão do servidor (VPS) é responsabilidade do Cliente (Termos de Uso, **cláusula 5.4**). Por isso, configuração, gestão, manutenção ou segurança do servidor ficam fora do escopo do suporte técnico padrão (**cláusula 7.4, item I**), o que inclui o ajuste de infraestrutura necessário para o Modo Cluster.

***

### Possíveis Erros e Soluções

#### Erro: workers secundários não conseguem se conectar ao Redis

**Causa:** `IO_REDIS_SERVER`/`IO_REDIS_PASSWORD`/`IO_REDIS_PORT` incorretos, ou o Redis não está acessível pela rede do servidor.

**Solução:** confirme o `docker exec -it zpro-redis redis-cli -a SUA_SENHA ping` retornando `PONG` e revise as variáveis `IO_REDIS_*` no `.env`.

#### Erro: build ausente ao iniciar em cluster

**Causa:** o Modo Cluster carrega o backend a partir de `dist/server.js` — sem rodar `npm run build` antes, o PM2 não encontra os arquivos.

**Solução:** rode `npm run build` antes de `pm2 start ecosystem.config.js` sempre que alternar para o Modo Cluster ou atualizar o código.

#### Sessões do WhatsApp não respondem em alguns workers

**Causa:** não é um erro — sessões WhatsApp (Baileys/WWJS), jobs e o WebSocket do Webchat só existem no **Worker 0**. Esse é o comportamento esperado do Modo Cluster.

**Solução:** nenhuma ação necessária. As requisições de sessão (POST/PUT/DELETE) feitas em workers secundários são automaticamente repassadas (proxy) para o Worker 0.

#### Conflito de porta com `CLUSTER_PRIMARY_PORT`

**Causa:** a porta interna definida em `CLUSTER_PRIMARY_PORT` já está em uso por outro serviço no servidor.

**Solução:** escolha outra porta livre e atualize a variável no `.env` antes de reiniciar.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ajuda.zdg.com.br/avancado-recursos-tecnicos/infraestrutura/como-instalar-o-z-pro-em-modo-cluster.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
