← Blog

Hospede o Rocket.Chat para chat de equipe

Railyard

1 de julho de 2026 · 12 min de leitura

Siga isso no seu próprio servidor. Comece grátis, sem cartão

O preço por assento do Slack escala com o número de pessoas, não com quanto a sua equipe de fato conversa, e no momento em que você precisa que toda mensagem fique numa infraestrutura que você controla, uma caixa de entrada SaaS hospedada deixa de ser opção por completo. O Rocket.Chat é uma plataforma de chat de equipe open-source que faz o mesmo trabalho, canais, mensagens diretas, compartilhamento de arquivos, busca, e você mesmo roda ela. A única coisa que torna o self-host mais difícil do que a maioria das ferramentas de chat é que ela precisa do MongoDB configurado como um replica set, não um banco de dados standalone simples, porque o Rocket.Chat depende dos change streams do MongoDB para enviar mensagens aos clientes conectados em tempo real. No final deste guia, você vai ter uma instância Rocket.Chat funcionando no seu próprio servidor Hetzner, atrás de HTTPS, com esse replica set inicializado corretamente, backups e um jeito seguro de fazer upgrade depois.

O que você vai precisar

  • Uma conta Hetzner Cloud e um servidor. O Rocket.Chat mais um replica set do MongoDB precisa de mais folga do que as instâncias menores, então este guia usa o CX33 (4 vCPUs, 8 GB de memória, 80 GB NVMe), listado a €8,99/mês sem VAT. Confira os preços atuais no Hetzner Cloud Console antes de pedir, já que as opções e preços mudam.
  • Um domínio (ou um subdomínio de um que você já tenha), com acesso às configurações de DNS dele.
  • Um par de chaves SSH na sua máquina (ssh-keygen -t ed25519 se você ainda não tiver um).
  • Docker e o plugin Docker Compose instalados no servidor (coberto na Etapa 2).
  • Um terminal e cerca de vinte minutos, a maior parte esperando o DNS e a sincronização inicial.

Etapa 1: Crie o servidor e aponte um domínio para ele

No Hetzner Cloud Console, abra ou crie um projeto, depois escolha Add Server. Escolha uma localização: Nuremberg, Falkenstein ou Helsinki mantêm seus dados na UE, enquanto Ashburn, Hillsboro ou Singapore também estão disponíveis se a sua equipe estiver em outro lugar. Escolha Ubuntu 24.04 como imagem, depois em tipo de servidor escolha o Shared vCPU CX33 (4 vCPUs, 8 GB de memória, 80 GB NVMe). Em SSH keys, adicione a chave pública da sua máquina em vez de depender de uma senha gerada, depois crie o servidor.

Depois que ele subir, anote o endereço IPv4 público e conecte para confirmar o acesso:

ssh root@YOUR_SERVER_IP

Você deve cair num shell root com a mensagem de bem-vindo do Ubuntu, sem pedido de senha.

Nas configurações de DNS do seu domínio, adicione um registro A apontando um subdomínio, por exemplo chat.yourdomain.com, para esse IP:

Type: A
Name: chat
Value: <IP do seu servidor>
TTL: 300

A propagação do DNS pode levar de alguns minutos a algumas horas. Confirme da sua própria máquina antes de continuar, já que a requisição de certificado do Caddy na Etapa 5 depende disso:

dig chat.yourdomain.com +short

Você deve ver o IP do seu servidor impresso de volta.

Etapa 2: Instale o Docker

Conecte via SSH ao servidor e instale o Docker Engine mais o plugin Compose:

apt-get update
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
systemctl enable --now docker

A Hetzner não coloca um firewall na frente de um servidor novo por padrão, então trave a máquina com ufw:

ufw allow OpenSSH
ufw allow 80
ufw allow 443
ufw --force enable

Confira a instalação:

docker --version
docker compose version

Você deve ver uma versão do Docker e uma versão do Compose impressas, não um erro de “command not found”.

Etapa 3: Organize o projeto e seus segredos

Crie um diretório para a stack e um arquivo .env para guardar o domínio e qualquer outra coisa que não deveria viver no próprio arquivo compose:

mkdir -p /opt/rocketchat && cd /opt/rocketchat
cat > .env <<'EOF'
DOMAIN=chat.yourdomain.com
EOF
chmod 600 .env

O Rocket.Chat não recebe um usuário ou senha de admin como configuração de container do jeito que alguns apps fazem. A primeira conta de admin é criada mais tarde, pelo próprio assistente de configuração do app, então não há nenhuma credencial para gerar ou guardar nesta etapa além do domínio em si.

Etapa 4: Escreva o arquivo Docker Compose

É aqui que a exigência do replica set de fato aparece. O serviço mongo precisa iniciar o mongod com --replSet rs0, depois verificar se um replica set já está inicializado, e se não, iniciar um com ele mesmo como único membro. Isso é um comando composto de shell, não uma única chamada de binário, então precisa rodar por um shell em vez de como argumentos diretos do mongod.

Crie o docker-compose.yml:

services:
  rocket-chat:
    image: rocketchat/rocket.chat:8.5.4
    restart: unless-stopped
    environment:
      - PORT=3000
      - ROOT_URL=https://${DOMAIN}
      - DEPLOY_METHOD=docker
      - MONGO_URL=mongodb://mongo:27017/rocketchat?replicaSet=rs0
      - MONGO_OPLOG_URL=mongodb://mongo:27017/local?replicaSet=rs0
    volumes:
      - rocketchat_uploads:/app/uploads
    depends_on:
      - mongo
    networks:
      - rocketchat-net

  mongo:
    image: mongodb/mongodb-community-server:8.0-ubi8
    restart: unless-stopped
    command: ["bash", "-c", "mongod --replSet rs0 --bind_ip_all --fork --logpath /data/db/mongod.log && mongosh --quiet --eval \"try { rs.status().ok } catch (e) { rs.initiate({_id: 'rs0', members: [{_id: 0, host: 'mongo:27017'}]}) }\" && tail -f /data/db/mongod.log"]
    volumes:
      - mongo_data:/data/db
    networks:
      - rocketchat-net

  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      - DOMAIN=${DOMAIN}
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      - rocket-chat
    networks:
      - rocketchat-net

networks:
  rocketchat-net:

volumes:
  rocketchat_uploads:
  mongo_data:
  caddy_data:
  caddy_config:

Algumas coisas que valem explicar:

  • O command do mongo faz três coisas em sequência: inicia o mongod como um processo em segundo plano (--fork) vinculado a todas as interfaces com replicação ativada, depois roda o mongosh para verificar rs.status().ok, capturando o erro que essa chamada lança num banco de dados novo e chamando rs.initiate() com esse container como único membro de rs0 se isso acontecer, e por fim faz tail -f no arquivo de log para o container ter um processo em primeiro plano que o mantenha vivo. Em cada restart depois do primeiro, rs.status().ok já tem sucesso, então rs.initiate() é pulado e o container simplesmente começa a servir.
  • Nem rocket-chat nem mongo recebem uma entrada security_opt: ["no-new-privileges:true"], e isso é deliberado, não um descuido. O próprio entrypoint do MongoDB derruba privilégios de root reexecutando a si mesmo como subprocesso, e essa reexecução precisa da capacidade de ganhar novos privilégios. Adicionar a flag de hardening comum aqui quebra o mongod --fork com um “child process failed, exited with 1” genérico e nenhum erro mais claro no log.
  • As duas imagens estão fixadas em tags exatas, rocket.chat:8.5.4 e mongodb-community-server:8.0-ubi8, em vez de latest. Um servidor de chat que muda silenciosamente o comportamento do banco de dados num restart não é algo que você quer descobrir durante o horário de trabalho.
  • Só o Caddy publica portas no host. O Rocket.Chat e o MongoDB só são acessíveis pela rede interna do Docker.

Confira se o arquivo é interpretado sem erros:

docker compose config

Você deve ver a configuração totalmente resolvida impressa sem linhas de erro.

Etapa 5: Escreva o Caddyfile e inicie tudo

Crie o Caddyfile no mesmo diretório:

{$DOMAIN} {
	reverse_proxy rocket-chat:3000
}

O Caddy solicita um certificado TLS gratuito do Let’s Encrypt para o seu domínio automaticamente, desde que o DNS já resolva para este servidor e as portas 80 e 443 estejam acessíveis pela internet, o que a Etapa 1 e a Etapa 2 já configuraram.

Inicie a stack:

docker compose up -d

Observe os logs enquanto o Mongo sobe:

docker compose logs -f mongo

A primeira inicialização demora mais do que os restarts seguintes, já que precisa inicializar o replica set antes de o Rocket.Chat conseguir conectar. Depois que isso se resolver, confira se o Caddy obteve o certificado:

docker compose logs -f caddy

Você deve ver uma linha mencionando um certificado obtido para o seu domínio. Confirme que tudo está no ar:

docker compose ps

Os três serviços devem aparecer como Up.

Etapa 6: Crie a primeira conta de admin

Acesse https://chat.yourdomain.com num navegador. O próprio assistente de configuração do Rocket.Chat carrega, pedindo um nome de organização, depois uma conta de admin, e-mail e senha. Esse é o próprio fluxo de primeira execução do Rocket.Chat, não algo que o arquivo compose configura para você, então não há nada para automatizar aqui além de passar por ele uma vez. Depois disso, o assistente oferece algumas etapas opcionais, configurações de cadastro, um aviso de federação, que você pode pular ou configurar como quiser; nada disso bloqueia a instância de funcionar.

Etapa 7: Faça backup do banco de dados e do volume de uploads

Duas coisas precisam de backup: os dados do MongoDB (canais, mensagens, usuários, configurações) e o volume rocketchat_uploads (arquivos compartilhados no chat). Um mongodump contra o container rodando, canalizado direto para um arquivo compactado:

docker compose exec -T mongo mongodump --archive --gzip > rocketchat-backup-$(date +%F).gz

Coloque isso num cron job diário, e copie o resultado para algum lugar fora deste servidor, um bucket de object storage, outra máquina, qualquer lugar que não seja esta máquina. Um backup que vive só no servidor que ele está protegendo não sobrevive ao tipo de falha que de fato derruba um servidor.

Para o volume de uploads:

docker run --rm -v rocketchat_rocketchat_uploads:/data -v $(pwd):/backup alpine \
  tar czf /backup/rocketchat-uploads-backup.tar.gz -C /data .

Guarde os dois arquivos em algum lugar com acesso controlado; um backup de histórico de mensagens ainda é dado real de usuário.

Etapa 8: Faça upgrade com cuidado

As duas imagens estão fixadas, então um upgrade é uma escolha consciente, não algo que acontece num restart de rotina. Antes de mudar qualquer uma das tags, leia as próprias release notes do Rocket.Chat para cada versão entre a que você está rodando e a que você vai migrar. O Rocket.Chat, como muitos apps com um histórico longo, pode exigir passar por versões maiores intermediárias em sequência em vez de saltar direto de uma release antiga para a mais nova, então confira isso antes de assumir que um salto único é seguro.

Mude a tag no docker-compose.yml:

image: rocketchat/rocket.chat:8.6.0

Depois:

docker compose pull
docker compose up -d

Confira os logs para ver uma inicialização limpa sem erro de migração, e confirme que seus canais e histórico de mensagens estão intactos depois de fazer login de novo. Se uma migração de fato der errado, seu backup da Etapa 7 é o caminho de volta para a versão anterior; restaure contra a tag de imagem mais antiga antes de decidir o que fazer a seguir.

O caminho curto: faça com o Railyard

Tudo isso acima, um replica set dedicado do MongoDB inicializado corretamente, o volume de uploads, HTTPS já ligado, também está disponível como um deploy de um clique, mas por ser uma stack com múltiplos serviços em vez de um container único, o link não faz o deploy direto do jeito que um template de app de um único container faria:

https://app.railyard.run/deploy?stack=rocket-chat

Esse link abre o catálogo de templates em vez de fazer o deploy direto, já que uma stack precisa que você confirme os serviços dela antes de provisionar qualquer coisa. Escolha Rocket.Chat no catálogo de templates a partir daí. O Railyard liga a mesma exigência de replica set que este guia percorre à mão, o mesmo volume de uploads persistente, e HTTPS no seu domínio, sem você escrever o arquivo compose ou o comando de shell dentro do container Mongo você mesmo.

Deploy button explica como o link ?stack= e o fluxo do catálogo de templates funcionam, se você quiser entender ou incorporar um em outro lugar. Databases and backups cobre como os backups funcionam entre templates em geral, não só este. Se você está começando pelo Railyard antes de decidir pelo Rocket.Chat especificamente, o quickstart cobre o básico. O plano Free do Railyard cobre um servidor mais um servidor de banco de dados e três apps sem exigir cartão, o Pro é US$19/mês por equipe, e o Team, US$49/mês por equipe.

Solução de problemas

O replica set nunca inicializa, ou rs.status().ok continua falhando. Confira docker compose logs mongo em busca do erro real da chamada rs.initiate(). A causa mais comum é o hostname em members não corresponder ao que o serviço rocket-chat de fato resolve; neste arquivo compose esse host é o nome de serviço mongo, então se você renomeou o serviço, o valor host: dentro do comando precisa corresponder exatamente a ele.

O Mongo falha ao iniciar com mongod --fork: "child process failed, exited with 1". Isso quase sempre é security_opt: ["no-new-privileges:true"] adicionado ao serviço mongo, geralmente de aplicar uma rodada geral de hardening de containers em todos os serviços de um arquivo compose sem uma exceção para este. O entrypoint do MongoDB reexecuta a si mesmo como subprocesso para derrubar privilégios de root, e essa reexecução precisa da capacidade de ganhar novos privilégios; a flag de hardening bloqueia exatamente isso. Remova dela especificamente do serviço mongo.

O Rocket.Chat carrega, mas todo link, avatar ou redirecionamento aponta para o endereço errado. Isso é uma divergência de ROOT_URL. Ele precisa ser a URL HTTPS exata pela qual você de fato acessa a instância, incluindo o esquema; se estiver definido como http:// em vez de https://, ou com um hostname diferente daquele que o Caddy está servindo, você vai ver loops de redirecionamento no navegador ou URLs de recursos quebradas no código-fonte da página.

O Caddy nunca obtém um certificado, ou o navegador mostra um aviso de certificado. Isso quase sempre é DNS, não o Caddy. Rode dig chat.yourdomain.com +short e confirme que retorna o IP deste servidor, não um antigo ou nada. O Let’s Encrypt também precisa que a porta 80 esteja acessível pela internet para a etapa de validação inicial, então confira se o seu firewall permite entrada na 80, não só na 443.

O Mongo é morto ou o servidor fica sem resposta sob uso normal. Um replica set, mesmo um de um único nó, mantém mais coisa em memória do que uma instância Mongo standalone simples, e o próprio Rocket.Chat não é um processo leve. Se você estiver num servidor menor do que o CX33 que este guia usa, isso é a primeira coisa a conferir com docker stats antes de assumir que outra coisa está errada; subir de tamanho geralmente é a correção real, não uma flag de ajuste fino.

Perguntas frequentes

Posso pular o replica set e rodar o Mongo como uma instância standalone simples? Não. O Rocket.Chat usa os change streams do MongoDB, que só existem num replica set, para enviar novas mensagens e atualizações de presença para os clientes conectados sem fazer polling. Um Mongo standalone vai deixar o Rocket.Chat iniciar, mas as atualizações em tempo real não vão funcionar corretamente, então isso não é uma etapa de hardening opcional que você pode pular para um footprint menor.

Isso é o Rocket.Chat clássico ou a versão de microsserviços? É o monolito clássico, um único container rocket-chat conversando com um único banco de dados, que é o encaixe certo para a maioria dos tamanhos de equipe e a coisa mais simples de operar você mesmo. O Rocket.Chat também publica uma divisão em microsserviços para deploys muito grandes; a documentação deles cobre esse caminho se você algum dia precisar escalar além do que um container único aguenta.

Quanto isso custa para rodar? O servidor custa €8,99/mês sem VAT para o CX33 que este guia usa. O Rocket.Chat em si é software livre e gratuito sem cobrança por assento; o custo é a máquina em que ele roda, não uma licença.

O que acontece se uma migração falhar durante um upgrade? A inicialização do Rocket.Chat roda suas próprias migrações internas contra o banco de dados no boot. Se uma falhar, os logs do container vão mostrar isso claramente em vez de o app subir silenciosamente pela metade migrado. Suas opções nesse ponto são restaurar o backup da Etapa 7 contra a tag de imagem anterior, ou ler o erro de migração específico e as release notes correspondentes antes de tentar de novo; não tente de novo às cegas contra o mesmo estado de banco de dados.

Eu preciso de um serviço de e-mail separado para convidar usuários? Não para colocar a instância no ar; a conta de admin da Etapa 6 pode criar e convidar usuários diretamente pelo painel de admin sem e-mail de saída configurado. Você vai querer SMTP configurado eventualmente para redefinição de senha e e-mails de notificação, mas isso não é um bloqueio para um primeiro deploy funcionando.

Uma instância Rocket.Chat self-hosted é uma quantidade modesta de configuração para algo que você provavelmente vai deixar rodando por anos: o histórico de mensagens da sua equipe fica num servidor que você controla, com uma rotina de backup e um caminho de upgrade que não dependem da agenda de release de mais ninguém.

Por que escolhem o Railyard para isso

  • Sua própria conta de cloud. Faça deploy no DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, ou em qualquer servidor Linux via SSH, cobrado direto pelo seu provedor, sem markup.
  • Um preço fixo por equipe. O Free é grátis para sempre: um servidor mais um servidor de banco de dados, três apps, sem cartão. O Pro custa US$19 por mês para até cinco servidores e apps ilimitados. O Team custa US$49 por mês com servidores ilimitados. Sem cobrança por app, por deploy, por assento ou por gigabyte.
  • Templates de um clique. Faça deploy de apps open source, como bancos de dados, analytics e ferramentas de dev, no seu próprio servidor em um clique.
  • Bancos de dados gerenciados. Postgres, MySQL e Redis com backups programados, verificados por restauração, e recuperação point-in-time.
  • Push-to-deploy. Faça deploy a partir do GitHub, GitLab ou da CLI, com HTTPS automático e releases sem downtime.

Pule a configuração do servidor

Escolha Rocket.Chat no catálogo de templates do Railyard e já tenha o replica set, o volume de uploads e o HTTPS ligados.

Plano grátis, sem cartão, e 14 dias de Pro para cada equipe nova. Um preço fixo por equipe.