← Blog

Autoalojar Rocket.Chat para el chat de equipo

Railyard

1 de julio de 2026 · 12 min de lectura

Sigue esto en tu propio servidor. Empieza gratis, sin tarjeta

El precio por asiento de Slack crece con la cantidad de personas, no con cuánto chatea realmente tu equipo, y en el momento en que cada mensaje necesita quedarse en infraestructura que tú controlas, un SaaS alojado deja de ser una opción por completo. Rocket.Chat es una plataforma de chat de equipo de código abierto que hace el mismo trabajo, canales, mensajes directos, archivos compartidos, búsqueda, y que tú mismo alojas. Lo único que hace más difícil autoalojarla que la mayoría de las herramientas de chat es que necesita MongoDB configurado como replica set, no una base de datos independiente normal, porque Rocket.Chat depende de los change streams de MongoDB para enviar mensajes a los clientes conectados en tiempo real. Al final de esta guía tendrás una instancia de Rocket.Chat funcionando en tu propio servidor Hetzner, detrás de HTTPS, con ese replica set correctamente inicializado, respaldos y una forma segura de actualizarla más adelante.

Lo que necesitas

  • Una cuenta de Hetzner Cloud y un servidor. Rocket.Chat junto con un replica set de MongoDB necesita más margen que las instancias más pequeñas, así que esta guía usa el CX33 (4 vCPU, 8 GB de memoria, 80 GB NVMe), listado en 8.99 €/mes sin IVA. Revisa el precio actual en la consola de Hetzner Cloud antes de pedirlo, ya que las líneas y precios sí cambian.
  • Un nombre de dominio (o un subdominio de uno que ya tengas), con acceso a su configuración DNS.
  • Un par de llaves SSH en tu máquina (ssh-keygen -t ed25519 si todavía no tienes una).
  • Docker y el plugin de Docker Compose instalados en el servidor (cubierto en el paso 2).
  • Una terminal y unos veinte minutos, sobre todo esperando el DNS y la sincronización inicial.

Paso 1: crear el servidor y apuntar un dominio hacia él

En la consola de Hetzner Cloud, abre o crea un proyecto, luego elige Add Server. Elige una ubicación: Nuremberg, Falkenstein o Helsinki mantienen tus datos en la UE, mientras que Ashburn, Hillsboro o Singapur también están disponibles si tu equipo está en otro lugar. Elige Ubuntu 24.04 como imagen, luego en el tipo de servidor elige el vCPU compartido CX33 (4 vCPU, 8 GB de memoria, 80 GB NVMe). En llaves SSH, agrega la llave pública de tu máquina en lugar de confiar en una contraseña generada, y luego crea el servidor.

Una vez que arranca, anota su dirección IPv4 pública y conéctate para confirmar el acceso:

ssh root@YOUR_SERVER_IP

Deberías llegar a una shell de root con el mensaje de bienvenida de Ubuntu, sin que te pida contraseña.

En la configuración DNS de tu dominio, agrega un registro A que apunte un subdominio, por ejemplo chat.tudominio.com, hacia esa IP:

Type: A
Name: chat
Value: <la IP de tu servidor>
TTL: 300

La propagación DNS puede tardar de unos minutos a unas horas. Confírmalo desde tu propia máquina antes de continuar, ya que la solicitud de certificado de Caddy en el paso 5 depende de esto:

dig chat.tudominio.com +short

Deberías ver la IP de tu servidor como resultado.

Paso 2: instalar Docker

Conéctate por SSH al servidor e instala Docker Engine junto con el plugin de Compose:

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

Hetzner no pone un firewall frente a un servidor nuevo por defecto, así que asegura el host con ufw:

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

Verifica la instalación:

docker --version
docker compose version

Deberías ver una versión de Docker y una versión de Compose impresas, no un error de “command not found”.

Paso 3: organizar el proyecto y sus secretos

Crea un directorio para la pila y un archivo .env para guardar el dominio y cualquier otra cosa que no deba vivir en el propio archivo compose:

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

Rocket.Chat no recibe un nombre de usuario o contraseña de administrador como configuración de contenedor, a diferencia de otras aplicaciones. La primera cuenta de administrador se crea más adelante, mediante el propio asistente de configuración de la aplicación, así que no hay ninguna credencial que generar o guardar en esta etapa más allá del dominio mismo.

Paso 4: escribir el archivo Docker Compose

Aquí es donde el requisito del replica set realmente entra en juego. El servicio mongo necesita arrancar mongod con --replSet rs0, luego revisar si ya hay un replica set inicializado, y si no lo hay, iniciar uno con él mismo como único miembro. Eso es un comando de shell compuesto, no una simple invocación de binario, así que tiene que ejecutarse a través de una shell en lugar de como argumentos directos de mongod.

Crea 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:

Vale la pena explicar algunas cosas:

  • El command de mongo hace tres cosas en secuencia: arrancar mongod en segundo plano (--fork) enlazado a todas las interfaces con la replicación activada, luego ejecutar mongosh para revisar rs.status().ok, capturando el error que esa llamada lanza en una base de datos nueva y llamando a rs.initiate() con este contenedor como único miembro de rs0 si eso ocurre, y finalmente hacer tail -f del archivo de registro para que el contenedor tenga un proceso en primer plano que lo mantenga vivo. En cada reinicio después del primero, rs.status().ok ya tiene éxito, así que rs.initiate() se salta y el contenedor simplemente arranca.
  • Ni rocket-chat ni mongo tienen una entrada security_opt: ["no-new-privileges:true"], y eso es deliberado, no un descuido. El propio entrypoint de MongoDB abandona los privilegios de root reejecutándose a sí mismo como subproceso, y esa reejecución necesita la capacidad de ganar nuevos privilegios. Agregar el flag de endurecimiento habitual aquí rompe mongod --fork con un genérico “child process failed, exited with 1” y nada más claro en el registro.
  • Ambas imágenes están fijadas a etiquetas exactas, rocket.chat:8.5.4 y mongodb-community-server:8.0-ubi8, en lugar de latest. Un servidor de chat que cambia de comportamiento de base de datos silenciosamente en un reinicio no es algo que quieras descubrir en medio de una jornada de trabajo.
  • Solo Caddy publica puertos hacia el host. Rocket.Chat y MongoDB solo son alcanzables dentro de la red interna de Docker.

Verifica que el archivo se analiza correctamente:

docker compose config

Deberías ver la configuración completamente resuelta impresa sin líneas de error.

Paso 5: escribir el Caddyfile y arrancar todo

Crea Caddyfile en el mismo directorio:

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

Caddy solicita automáticamente un certificado TLS gratuito de Let’s Encrypt para tu dominio, siempre que el DNS ya resuelva hacia este servidor y los puertos 80 y 443 sean alcanzables desde internet, lo que los pasos 1 y 2 ya dejaron configurado.

Arranca la pila:

docker compose up -d

Observa los registros mientras Mongo arranca:

docker compose logs -f mongo

El primer arranque toma más tiempo que los reinicios posteriores, ya que tiene que inicializar el replica set antes de que Rocket.Chat pueda conectarse. Una vez que eso se estabiliza, revisa que Caddy obtuvo su certificado:

docker compose logs -f caddy

Deberías ver una línea mencionando un certificado obtenido para tu dominio. Confirma que todo está arriba:

docker compose ps

Los tres servicios deberían mostrarse como Up.

Paso 6: crear la primera cuenta de administrador

Visita https://chat.tudominio.com en un navegador. El propio asistente de configuración de Rocket.Chat se carga, pidiendo un nombre de organización, luego una cuenta de administrador, correo electrónico y contraseña. Este es el flujo de primer arranque de Rocket.Chat, no algo que el archivo compose configure por ti, así que no hay nada que automatizar aquí más allá de completarlo una vez. Después de eso, el asistente ofrece algunos pasos opcionales, ajustes de registro, una invitación a configurar federación, que puedes saltar o configurar como prefieras; nada de eso bloquea el funcionamiento de la instancia.

Paso 7: respaldar la base de datos y el volumen de subidas

Hay dos cosas que respaldar: los datos de MongoDB (canales, mensajes, usuarios, configuración) y el volumen rocketchat_uploads (archivos compartidos en el chat). Un mongodump contra el contenedor en ejecución, enviado directamente a un archivo comprimido:

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

Pon eso en una tarea cron diaria, y copia el resultado a algún lugar que no sea este servidor, un bucket de almacenamiento de objetos, otra máquina, cualquier lugar que no sea esta caja. Un respaldo que vive únicamente en el servidor que protege no sobrevive al modo de falla que realmente tumba un servidor.

Para el volumen de subidas:

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

Guarda ambos archivos en algún lugar con acceso controlado; un respaldo del historial de mensajes sigue siendo datos reales de usuarios.

Paso 8: actualizar de forma deliberada

Ambas imágenes están fijadas, así que una actualización es una decisión consciente, no algo que ocurre en un reinicio de rutina. Antes de cambiar cualquiera de las etiquetas, lee las notas de versión propias de Rocket.Chat para cada versión entre la que tienes corriendo y a la que vas. Rocket.Chat, como muchas aplicaciones con una larga historia, puede requerir pasar por versiones mayores intermedias en secuencia en lugar de saltar directamente de una versión vieja a la más nueva, así que revisa eso antes de asumir que un solo salto es seguro.

Cambia la etiqueta en docker-compose.yml:

image: rocketchat/rocket.chat:8.6.0

Luego:

docker compose pull
docker compose up -d

Revisa los registros en busca de un arranque limpio sin error de migración, y confirma que tus canales e historial de mensajes están intactos después de volver a iniciar sesión. Si una migración realmente sale mal, tu respaldo del paso 7 es el camino de vuelta a la versión anterior; restáuralo contra la etiqueta de imagen anterior antes de decidir qué hacer a continuación.

El atajo: hacerlo con Railyard

Todo lo anterior, un replica set de MongoDB dedicado correctamente inicializado, el volumen de subidas, HTTPS ya configurado, también está disponible como despliegue de un clic, pero como es una pila de varios servicios en lugar de un solo contenedor, el enlace no la despliega directamente como lo haría una plantilla de aplicación de un solo contenedor:

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

Ese enlace abre el catálogo de plantillas en lugar de desplegar de inmediato, ya que una pila necesita que confirmes sus servicios antes de aprovisionar nada. Elige Rocket.Chat en el catálogo de plantillas desde ahí. Railyard configura el mismo requisito de replica set que esta guía recorre a mano, el mismo volumen de subidas persistente, y HTTPS en tu dominio, sin que tengas que escribir el archivo compose ni el comando de shell dentro del contenedor de Mongo tú mismo.

Botón de despliegue explica cómo funcionan el enlace ?stack= y el flujo del catálogo de plantillas si quieres entenderlo o incrustar uno en otro lugar. Bases de datos y respaldos cubre cómo funcionan los respaldos a través de las plantillas en general, no solo esta. Si estás partiendo desde Railyard antes de decidirte por Rocket.Chat específicamente, la guía de inicio rápido cubre lo básico. El plan gratuito de Railyard cubre un servidor más un servidor de base de datos y tres aplicaciones sin tarjeta requerida, Pro es 19 $/mes por equipo, y Team es 49 $/mes por equipo.

Solución de problemas

El replica set nunca se inicializa, o rs.status().ok sigue fallando. Revisa docker compose logs mongo para ver el error real de la llamada a rs.initiate(). La causa más común es que el nombre de host en members no coincide con lo que el servicio rocket-chat realmente resuelve; en este archivo compose ese host es el nombre de servicio mongo, así que si renombraste el servicio, el valor host: dentro del comando debe coincidir exactamente.

Mongo falla al arrancar con mongod --fork: "child process failed, exited with 1". Esto casi siempre es security_opt: ["no-new-privileges:true"] agregado al servicio mongo, generalmente por aplicar un endurecimiento general de contenedores a todos los servicios de un archivo compose sin una excepción para este. El entrypoint de MongoDB se reejecuta a sí mismo como subproceso para abandonar los privilegios de root, y esa reejecución necesita la capacidad de ganar nuevos privilegios; el flag de endurecimiento bloquea exactamente eso. Quítalo específicamente del servicio mongo.

Rocket.Chat carga pero cada enlace, avatar o redirección apunta a la dirección equivocada. Esto es un desajuste de ROOT_URL. Necesita ser exactamente la URL HTTPS con la que realmente visitas la instancia, incluyendo el esquema; si está configurado como http:// en lugar de https://, o hacia un nombre de host distinto al que Caddy está sirviendo, verás bucles de redirección en el navegador o URLs de recursos rotas en el código fuente de la página.

Caddy nunca obtiene un certificado, o el navegador muestra una advertencia de certificado. Esto casi siempre es el DNS, no Caddy. Ejecuta dig chat.tudominio.com +short y confirma que devuelve la IP de este servidor, no una antigua ni nada en absoluto. Let’s Encrypt también necesita que el puerto 80 sea alcanzable desde internet para el paso de validación inicial, así que revisa que tu firewall permita tráfico entrante en el 80, no solo en el 443.

Mongo se cae o el servidor deja de responder bajo uso normal. Un replica set, incluso uno de un solo nodo, mantiene más en memoria que una instancia Mongo independiente normal, y Rocket.Chat en sí mismo no es un proceso liviano. Si estás en un servidor más pequeño que el CX33 que usa esta guía, eso es lo primero que hay que revisar con docker stats antes de asumir que algo más está mal; subir de tamaño suele ser la solución real, no un ajuste de configuración.

Preguntas frecuentes

¿Puedo saltarme el replica set y correr Mongo como una instancia independiente normal? No. Rocket.Chat usa los change streams de MongoDB, que solo existen en un replica set, para enviar nuevos mensajes y actualizaciones de presencia a los clientes conectados sin sondeo. Un Mongo independiente dejará que Rocket.Chat arranque, pero las actualizaciones en tiempo real no funcionarán correctamente, así que esto no es un paso de endurecimiento opcional que puedas saltarte para una huella más pequeña.

¿Esta es la versión clásica de Rocket.Chat o la de microservicios? Esta es el monolito clásico, un solo contenedor rocket-chat hablando con una sola base de datos, lo cual es lo adecuado para la mayoría de los tamaños de equipo y lo más simple de operar tú mismo. Rocket.Chat también publica una versión dividida en microservicios para despliegues muy grandes; su propia documentación cubre esa ruta si alguna vez necesitas escalar más allá de lo que un solo contenedor maneja.

¿Cuánto cuesta operar esto? El servidor cuesta 8.99 €/mes sin IVA por el CX33 que usa esta guía. Rocket.Chat en sí mismo es software libre y de código abierto sin cargo por asiento; el costo es la máquina en la que corre, no una licencia.

¿Qué pasa si una migración falla durante una actualización? El arranque de Rocket.Chat ejecuta sus propias migraciones internas contra la base de datos al iniciar. Si una falla, los registros del contenedor lo mostrarán claramente en lugar de que la aplicación arranque silenciosamente a medio migrar. Tus opciones en ese momento son restaurar el respaldo del paso 7 contra la etiqueta de imagen anterior, o leer el error de migración específico y las notas de versión correspondientes antes de intentarlo de nuevo; no reintentes a ciegas contra el mismo estado de base de datos.

¿Necesito un servicio de correo separado para invitar usuarios? No para que la instancia funcione; la cuenta de administrador del paso 6 puede crear e invitar usuarios directamente desde el panel de administración sin correo saliente configurado. Eventualmente querrás configurar SMTP para los restablecimientos de contraseña y los correos de notificación, pero no es un obstáculo para un primer despliegue funcional.

Una instancia de Rocket.Chat autoalojada es una cantidad modesta de configuración para algo que probablemente dejarás corriendo durante años: el historial de mensajes de tu equipo se queda en un servidor que tú controlas, con una rutina de respaldo y una ruta de actualización que no dependen del calendario de lanzamientos de nadie más.

Por qué eligen Railyard para esto

  • Tu propia cuenta en la nube. Despliega en DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, o cualquier servidor Linux por SSH, facturado directamente por tu proveedor, sin márgenes adicionales.
  • Un precio fijo por equipo. El plan Free es gratis para siempre: un servidor más un servidor de base de datos, tres apps, sin tarjeta. Pro cuesta $19 al mes por hasta cinco servidores y apps ilimitadas. Team cuesta $49 al mes con servidores ilimitados. Sin cargos por app, por despliegue, por asiento ni por gigabyte.
  • Plantillas de un clic. Despliega apps de código abierto, como bases de datos, analítica y herramientas de desarrollo, en tu propio servidor con un clic.
  • Bases de datos administradas. Postgres, MySQL y Redis, con copias de seguridad programadas y verificadas por restauración, y recuperación a un punto en el tiempo.
  • Despliegue con git push. Despliega desde GitHub, GitLab o la CLI, con HTTPS automático y lanzamientos sin tiempo de inactividad.

Salta la configuración del servidor

Elige Rocket.Chat en el catálogo de plantillas de Railyard y obtén el replica set, el volumen de subidas y HTTPS ya configurados.

Plan gratis, sin tarjeta, y 14 días de Pro para cada equipo nuevo. Un precio fijo por equipo.