Instalar tu propio servidor de Rocket Chat con Docker parte 1

Hola a todos, hoy volvemos con Docker pero esta vez nos enfocaremos en el montaje de servicios, específicamente Rocket Chat, para los que aun no saben que es aquí les dejo una pequeña reseña:

Rocket Chat es una solución estupenda para Comunidades y Compañías que requieren de un servicio avanzado de Chat, hospedado en su propio Data Center, o en Servidores que controlan y administran.

Conocido esto proseguimos, lo primero es instalar Docker, si no sabe aun como hacerlo pase por aquí, si ya tenemos nuestro nodo listo, pasaremos a crear nuestro archivo docker-compose.yaml (no es necesario que este fichero tenga el nombre de docker-compose pero es más cómodo). Basado en la documentación oficial para montar Rocket Chat en Docker, en el originalmente nginx va independiente en el host.

Si tiene duda cuanto necesita para correr Rocket Chat estos son los requerimientos https://docs.rocket.chat/installation/minimum-requirements.

Para que exista mayor organización pondremos el proyecto de nuestro despliegue en una carpeta que la llamaremos rocket y dentro sub-carpetas donde se montaran los volúmenes de cada container, deberá quedar así:

[avalon rocket]$ tree
.
├── data
│   ├── db
│   └── dump
├── docker-compose.yml
├── nginx
│   ├── certificate.crt
│   ├── certificate.key
│   ├── dhparams.pem
│   └── nginx.conf
└── uploads

Nota: los ficheros antes vistos, serán explicados en el articulo.

Antes de pasar al tema de las configuraciones crearemos el certificado, para este tutorial se usaron auto-firmados. Dentro de la carpeta nginx generamos el certificado, para esto debe tener instalado previamente openssl:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout certificate.key -out certificate.crt

Sigue las indicaciones.

Consejo: es IMPORTANTE que el Common Name se establezca correctamente. Ingrese su nombre de dominio completo (FQDN) aquí o, si no tiene un FQDN, use su dirección IP pública. Por ejemplo, mi FQDN para el servidor de chat es chat.aldrock.net.

Cambiamos los permisos de certificate.key

sudo chmod 400 certificate.key

Por ultimo generamos la clave ciptografica Diffie-Hellman (DH) de 2048-bits perteneciente al grupo DH 14.

sudo openssl dhparam -out /etc/nginx/dhparams.pem 2048

Si desea usar Let’s Encrypt puede ver como hacerlo aquí.

Tenemos todo listo pasamos a crear el fichero docker-compose.yaml:

[avalon rocket]$ nano docker-compose.yaml

Nota: dentro de este fichero van todas las opciones de nuestro despliegue voy por partes y luego lo pongo entero al final.

El primer servicio(a partir de este momento los containers serán llamados servicios) a agregar sera web usando nginx:

version: '3' 

services: 

  web: 
    image: nginx:1.19-alpine 
    restart: unless-stopped 
    # Montamos nuestro fichero de configuración propio de nginx y el certificado.
    volumes: 
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro 
      - ./nginx/certificate.key:/etc/nginx/certificate.key:ro
      - ./nginx/certificate.crt:/etc/nginx/certificate.crt:ro
      - ./nginx/dhparams.pem:/etc/nginx/dhparams.pem:ro
    # Enlazamos nginx con el servicio de RocketChat para no exponer el puerto 3000.
    links: 
      - rocketchat 
    ports: 
      - "80:80"
      - "443:443"

antes de seguir con los servicios creamos el fichero nginx.conf:

[avalon nginx]$ nano nginx.conf

este es el contenido de nginx.conf, es muy básico pero pueden mejorarlo:

user nginx;

events {
  worker_connections 768;
}

http {
  upstream backend {
    server rocketchat:3000;
  }

  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  gzip on;
  gzip_disable "msie6";
  server_tokens off;

  server {
    listen 80;
        server_name chat.aldrock.net;
        return 301 https://chat.aldrock.net;
    }      
  server {
    listen 443 http2 ssl;
    server_name chat.aldrock.net;

    error_log /var/log/nginx/rocketchat_error.log;

    ssl_certificate /etc/nginx/certificate.crt;
    ssl_certificate_key /etc/nginx/certificate.key;
    ssl_dhparam /etc/nginx/dhparams.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM;';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 180m;
            
   location / {
           proxy_pass http://rocketchat:3000;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
           proxy_set_header Host $http_host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forward-Proto http;
           proxy_set_header X-Nginx-Proxy true;
           proxy_redirect off;
       }  
   }
}

Listo, entonces seguimos con el próximo servicio que sera rocketchat:

  rocketchat: 
    image: rocket.chat:latest 
    command: bash -c 'for i in `seq 1 30`; do node main.js && s=$$? && break || s=$$?; echo "Tried $$i times. Waiting 5 secs..."; sleep 5; done; (exit $$s)' 
    restart: unless-stopped 
    # Definimos el volumen donde se guardaran los datos de Rocket Chat.
    volumes: 
      - ./uploads:/app/uploads 
    environment: 
      - PORT=3000 
      - ROOT_URL=http://chat.aldrock.net # Cambiar por su dominio.
      - MONGO_URL=mongodb://mongo:27017/rocketchat 
      - MONGO_OPLOG_URL=mongodb://mongo:27017/local 
      #- Accounts_UseDNSDomainCheck=True
      # - VIRTUAL_HOST=chat.aldrock.net
      # Si se fijan las 2 opciones de arriba estan comentadas y debajo se utiliza la primera con el valor False, debido a que estamos detrás de un proxy(nginx).
      - Accounts_UseDNSDomainCheck=False
    # Definimos que dependemos del servicio de MongoDB.
    depends_on: 
      - mongo 
    # Si se fijan exponemos el puerto pero solo para la red interna de Docker, así obligamos que el cliente siempre acceda a través del nginx.
    expose: 
      - "3000"

Ahora proseguimos con el servicio de mongodb:

  mongo:
    image: mongo:4.0
    restart: unless-stopped
    # Al igual que en los servicios anteriores definimos el volumen donde quedaran guardados los archivos de la base de datos.
    volumes:
     - ./data/db:/data/db
     - ./data/dump:/dump
    command: mongod --smallfiles --oplogSize 128 --replSet rs0 --storageEngine=mmapv1

  # El trabajo de este contenedor es simplemente ejecutar el comando para inicializar el conjunto de réplicas.
  # Ejecutará el comando y se eliminará a sí mismo (no permanecerá ejecutándose)
  mongo-init-replica:
    image: mongo
    command: 'bash -c "for i in `seq 1 30`; do mongo mongo/rocketchat --eval \"rs.initiate({ _id: ''rs0'', members: [ { _id: 0, host: ''localhost:27017'' } ]})\" && s=$$? && break || s=$$?; echo \"Tried $$i times. Waiting 5 secs...\"; sleep 5; done; (exit $$s)"'
    depends_on:
      - mongo

Por ultimo el servicio de hubot:

  hubot:
    image: rocketchat/hubot-rocketchat:latest
    restart: unless-stopped
    environment:
      - ROCKETCHAT_URL=:0.0.0.0:3000
      - ROCKETCHAT_ROOM=GENERAL
      - ROCKETCHAT_USER=bot 
      - ROCKETCHAT_PASSWORD=botpassword # Se recomienda cambiar la contraseña antes de desplegar el proyecto.
      - BOT_NAME=bot
    # Puede agregar más scripts como desee aquí, deben instalarse antes de npm
      - EXTERNAL_SCRIPTS=hubot-help,hubot-seen,hubot-links,hubot-diagnostics
    # Definimos que depende de rocketchat
    depends_on:
      - rocketchat
    volumes:
      - ./scripts:/home/hubot/scripts
  # Esto se usa para exponer el puerto hubot para notificaciones en el host en el puerto 3001, p. para hubot-jenkins-notifier
    ports:
      - 3001:8080

Ya tenemos todo, ahora antes de darles el fichero en una sola parte les daré unos tips:

  • Para hacer mas fácil el trabajo de las imágenes y no tener que estar fajado con el tema VPN y mirrors Chinos, podemos usar DockerImageSave trae versiones para GNU/Linux, Windows y MacOS. Las imagenes son:
    • nginx:1.19-alpine
    • rocket.chat:latest
    • mongo:4.0
    • mongo:latest
    • rocketchat/hubot-rocketchat:latest
  • La imagen de MongoDB es la misma tanto para el servicio mongo como para mongo-init-replica, si ya se que dirán «pero no se llaman igual», lo único diferente es el tag con bajar cualquiera de las 2 y luego hacer docker image tag mongo:4.0 mongo:latest es suficiente, y no tienen que estar bajando +400MB 2 veces.

Dicho esto vemos que nos queda el docker-compose.yaml así:

version: '3'

services:

  web:  
    image: nginx:1.19-alpine
    restart: unless-stopped
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/certificate.key:/etc/nginx/certificate.key:ro
      - ./nginx/certificate.crt:/etc/nginx/certificate.crt:ro
      - ./nginx/dhparams.pem:/etc/nginx/dhparams.pem:ro

    links:
      - rocketchat
    ports:
      - "80:80"
      - "443:443"

  rocketchat:
    image: rocket.chat:latest
    command: bash -c 'for i in `seq 1 30`; do node main.js && s=$$? && break || s=$$?; echo "Tried $$i times. Waiting 5 secs..."; sleep 5; done; (exit $$s)'
    restart: unless-stopped
    volumes:
      - ./uploads:/app/uploads
    environment:
      - PORT=3000
      - ROOT_URL=http://chat.aldrock.net
      - MONGO_URL=mongodb://mongo:27017/rocketchat
      - MONGO_OPLOG_URL=mongodb://mongo:27017/local
      #- Accounts_UseDNSDomainCheck=True
      # - VIRTUAL_HOST=chat.aldrock.net
      - Accounts_UseDNSDomainCheck=False
    depends_on:
      - mongo
    expose:
      - "3000"

  mongo:
    image: mongo:4.0
    restart: unless-stopped
    volumes:
     - ./data/db:/data/db
     - ./data/dump:/dump
    command: mongod --smallfiles --oplogSize 128 --replSet rs0 --storageEngine=mmapv1

  mongo-init-replica:
    image: mongo
    command: 'bash -c "for i in `seq 1 30`; do mongo mongo/rocketchat --eval \"rs.initiate({ _id: ''rs0'', members: [ { _id: 0, host: ''localhost:27017'' } ]})\" && s=$$? && break || s=$$?; echo \"Tried $$i times. Waiting 5 secs...\"; sleep 5; done; (exit $$s)"'
    depends_on:
      - mongo

  hubot:
    image: rocketchat/hubot-rocketchat:latest
    restart: unless-stopped
    environment:
      - ROCKETCHAT_URL=:0.0.0.0:3000
      - ROCKETCHAT_ROOM=GENERAL
      - ROCKETCHAT_USER=bot
      - ROCKETCHAT_PASSWORD=botpassword
      - BOT_NAME=bot
      - EXTERNAL_SCRIPTS=hubot-help,hubot-seen,hubot-links,hubot-diagnostics
    depends_on:
      - rocketchat
    volumes:
      - ./scripts:/home/hubot/scripts
    ports:
      - 3001:8080

Pasamos a desplegar el proyecto para luego hacer la instalación y configuración en la administración de Rocket Chat, para eso corremos:

[avalon rocket]$ docker-compose up -d

Si no nos dio error, solo resta pasar al navegador y escribir la URL(en mi caso chat.aldrock.net), y pasar al procedimiento de instalación.

Lo primero sera dar tu información como administrador:

Seguidamente la información de tu organización, empresa:

Idioma, nombre del sitio y tipo de servidor, privado o público:

En este ultimo paso puedes escoger la primera opción, yo escogí la segunda para pruebas con certificados propios, recomiendo la primera:

Si llegaste hasta aquí todo esta bien y ya tienes Rocket Chat funcionado:

Así se ve la interfaz de usuario:

Como vieron no es tan difícil instalar Rocket Chat usando Docker, la verdad el paso mas complicado es preparar el docker-compose.yaml para que todo funcione sin problemas, ya levantar los servicios no pasa de 2 minutos. En la próxima parte tocare un poco mas el tema de configuración propia de la plataforma de chat y probaremos el cliente Desktop y el Móvil.

¿De cuánta utilidad te ha parecido este contenido?

¡Haz clic en una estrella para puntuar!

Promedio de puntuación 4.4 / 5. Recuento de votos: 7

Hasta ahora, ¡no hay votos!. Sé el primero en puntuar este contenido.

Sobre Arian López Delgado 4 artículos
Sysadmin freelance, usuario de GNU/Linux desde 2009

4 comentarios

  1. Google Chrome 83.0.4103.116 Google Chrome 83.0.4103.116 Windows 10 x64 Edition Windows 10 x64 Edition
    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

    Excelente Arian. Le propongo que en la próxima parte se toque la integración con LDAP.
    Gracias por el tuto.

  2. Google Chrome 83.0.4103.116 Google Chrome 83.0.4103.116 Windows 10 x64 Edition Windows 10 x64 Edition
    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

    Se que no fue el propósito de este articulo muy bueno por cierto gracias a es aprendí otra variante de descargar imágenes docker pero pudieras hacer una comparación de este servicio con el openfire u otro similar.

    • Google Chrome 84.0.4147.89 Google Chrome 84.0.4147.89 Windows 10 x64 Edition Windows 10 x64 Edition
      Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36

      Hola Pedro, sin duda alguna Rocket es una de las mejores soluciones de mensajería empresarial existentes actualmente, para no decir la mejor, tengo dos instancias ejecutandose hace más de dos años y he seguido de cerca el desarrollo este producto. Invito a todos que revisen el site oficial. El post está genial, pero ciertamente no está orientado a explicar sus funciones y puede que algunos no se animen a profundizar más en este sistema.
      Les comparto los principales enlaces y desde ya les digo que no se limiten a la integración.
      Sitio Oficial: https://rocket.chat/es/
      Docs: https://docs.rocket.chat/
      Github: https://github.com/RocketChat/

Responder a pedro Cancelar la respuesta

Tu dirección de correo electrónico no será publicada.


*