This guide deploys Hubot using Docker containers managed by Ansible. It combines container isolation with automated deployment.
- name: Deploy Hubot with Docker
hosts: hubot
become: true
vars:
hubot_name: hubot
hubot_image: local/hubot:14.1.0
hubot_project_dir: /opt/hubot
hubot_container_name: hubot
hubot_version: "14.1.0"
hubot_adapter: "shell"
hubot_bot_name: "opsbot"
hubot_bot_owner: "ops@example.com"
tasks:
- name: Install prerequisites on Debian family
ansible.builtin.apt:
update_cache: true
name:
- apt-transport-https
- ca-certificates
- curl
- gnupg
- lsb-release
state: present
when: ansible_os_family == "Debian"
- name: Install prerequisites on RHEL family
ansible.builtin.dnf:
name:
- dnf-utils
state: present
when: ansible_os_family == "RedHat"
- name: Add Docker GPG key (Debian/Ubuntu)
ansible.builtin.apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
when: ansible_os_family == "Debian"
- name: Add Docker repository (Debian/Ubuntu)
ansible.builtin.apt_repository:
repo: "deb [arch=amd64] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable"
state: present
filename: docker
when: ansible_os_family == "Debian"
- name: Add Docker repository (RHEL)
ansible.builtin.yum_repository:
name: docker-ce-stable
description: Docker CE Stable
baseurl: https://download.docker.com/linux/centos/$releasever/$basearch/stable
enabled: true
gpgcheck: true
gpgkey: https://download.docker.com/linux/centos/gpg
when: ansible_os_family == "RedHat"
- name: Install Docker Engine
ansible.builtin.apt:
update_cache: true
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
state: present
when: ansible_os_family == "Debian"
- name: Install Docker Engine (RHEL)
ansible.builtin.dnf:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
state: present
when: ansible_os_family == "RedHat"
- name: Ensure Docker service is running
ansible.builtin.systemd:
name: docker
enabled: true
state: started
- name: Ensure Hubot project directory exists
ansible.builtin.file:
path: "{{ hubot_project_dir }}"
state: directory
mode: "0755"
- name: Create Dockerfile for Hubot
ansible.builtin.copy:
dest: "{{ hubot_project_dir }}/Dockerfile"
content: |
FROM node:20-bookworm-slim
WORKDIR /opt/hubot
COPY package*.json ./
RUN npm install --omit=dev
COPY . .
CMD ["./bin/hubot"]
mode: "0644"
- name: Create package.json for Hubot
ansible.builtin.copy:
dest: "{{ hubot_project_dir }}/package.json"
content: |
{
"name": "hubot",
"version": "0.0.0",
"private": true,
"dependencies": {
"hubot": "{{ hubot_version }}",
"hubot-shell": "^1.1.0"
}
}
force: false
mode: "0644"
- name: Create bin directory
ansible.builtin.file:
path: "{{ hubot_project_dir }}/bin"
state: directory
mode: "0755"
- name: Create Hubot entry point script
ansible.builtin.copy:
dest: "{{ hubot_project_dir }}/bin/hubot"
content: |
#!/usr/bin/env node
const Hubot = require('hubot');
const { Shell } = require('hubot-shell');
const bot = Hubot.loadBot();
bot.adapter = new Shell(bot);
bot.run();
force: false
mode: "0755"
- name: Create scripts directory
ansible.builtin.file:
path: "{{ hubot_project_dir }}/scripts"
state: directory
mode: "0755"
- name: Create example script
ansible.builtin.copy:
dest: "{{ hubot_project_dir }}/scripts/example.js"
content: |
module.exports = function(robot) {
robot.hear(/hubot/i, function(msg) {
msg.send("I'm here!");
});
};
force: false
mode: "0644"
- name: Build Hubot Docker image
community.docker.docker_image:
name: "{{ hubot_image }}"
source: build
build:
path: "{{ hubot_project_dir }}"
pull: false
state: present
- name: Run Hubot container
community.docker.docker_container:
name: "{{ hubot_container_name }}"
image: "{{ hubot_image }}"
state: started
restart_policy: unless-stopped
env:
HUBOT_ADAPTER: "{{ hubot_adapter }}"
HUBOT_NAME: "{{ hubot_bot_name }}"
volumes:
- "{{ hubot_project_dir }}/scripts:/opt/hubot/scripts"
working_dir: /opt/hubot
- name: Verify container is running
community.docker.docker_container_info:
name: "{{ hubot_container_name }}"
register: hubot_container_info
- name: Show container status
ansible.builtin.debug:
var: hubot_container_info.container.State.Status
For environments without Docker Compose plugin, use this alternative:
- name: Deploy Hubot with Docker (Native)
hosts: hubot
become: true
vars:
hubot_image: local/hubot:14.1.0
hubot_project_dir: /opt/hubot
hubot_container_name: hubot
hubot_version: "14.1.0"
hubot_adapter: "shell"
hubot_bot_name: "opsbot"
tasks:
- name: Install Docker on Debian family
ansible.builtin.apt:
update_cache: true
name:
- docker.io
- docker-compose
state: present
when: ansible_os_family == "Debian"
- name: Ensure Docker service is running
ansible.builtin.systemd:
name: docker
enabled: true
state: started
- name: Ensure Hubot project directory exists
ansible.builtin.file:
path: "{{ hubot_project_dir }}"
state: directory
mode: "0755"
- name: Create Dockerfile for Hubot
ansible.builtin.copy:
dest: "{{ hubot_project_dir }}/Dockerfile"
content: |
FROM node:20-bookworm-slim
WORKDIR /opt/hubot
COPY package*.json ./
RUN npm install --omit=dev
COPY . .
CMD ["./bin/hubot"]
mode: "0644"
- name: Create package.json for Hubot
ansible.builtin.copy:
dest: "{{ hubot_project_dir }}/package.json"
content: |
{
"name": "hubot",
"version": "0.0.0",
"private": true,
"dependencies": {
"hubot": "{{ hubot_version }}",
"hubot-shell": "^1.1.0"
}
}
force: false
mode: "0644"
- name: Create bin directory
ansible.builtin.file:
path: "{{ hubot_project_dir }}/bin"
state: directory
mode: "0755"
- name: Create Hubot entry point script
ansible.builtin.copy:
dest: "{{ hubot_project_dir }}/bin/hubot"
content: |
#!/usr/bin/env node
const Hubot = require('hubot');
const { Shell } = require('hubot-shell');
const bot = Hubot.loadBot();
bot.adapter = new Shell(bot);
bot.run();
force: false
mode: "0755"
- name: Build Hubot Docker image
community.docker.docker_image:
name: "{{ hubot_image }}"
source: build
build:
path: "{{ hubot_project_dir }}"
pull: false
state: present
- name: Run Hubot container
community.docker.docker_container:
name: "{{ hubot_container_name }}"
image: "{{ hubot_image }}"
state: started
restart_policy: unless-stopped
env:
HUBOT_ADAPTER: "{{ hubot_adapter }}"
HUBOT_NAME: "{{ hubot_bot_name }}"
ansible-playbook -i inventory.ini hubot-docker-install.yml
# Check container status
docker ps | grep hubot
# View container logs
docker logs hubot
# Execute commands in running container
docker exec -it hubot npm list