Help us understand the problem. What is going on with this article?

Slackと連携するHubotをDocker in AWSで構築

More than 3 years have passed since last update.

やりたいこと

  • Slackと連携できるHubotを立てる
  • デプロイ方法は、Github -> CircleCI -> AWSとする
  • slackへのAccess Tokenなどは環境変数で渡す(誰でも利用しやすいように)
  • scriptsは誰でも追加しやすいように、localレポジトリのをDockerへ持っていくようにする

まずはHubotに必要なものを揃える

  • node.js
  • npm

Mac環境ならどちらもbrew installで簡単に用意できる

YeomanとYeomanのgenerator-hubotを用意する。
-gをつけずにbundle的なのりでローカルにインストールしたかったが、実行にあたってのパス設定が面倒そうなので諦めた。

% npm install -g yo generator-hubot
% yo hubot
% bin/hubot

これでhubotとの対話インターフェースが立ち上がる。

  • scriptsディレクトリ以下にスクリプトを置くと、機能追加ができる。
  • hubot-scriptsディレクトリ以下には、hubot-scripts.jsonに定義したscriptsがインストールされる。利用できるscriptsはこちら
  • package.jsonに利用したいthird-party npm packageを追記すると、external-scripts.jsonに値が追加される。
  • ERROR hubot-heroku-alive included, but missing HUBOT_HEROKU_KEEPALIVE_URLというメッセージが表示されてしまうので、external-scripts.jsonからheroku packageを削除。

Dockerの用意

  • Dockerfileを書く
  • hubotの実行にnode.jsが必要なので、Docker registryからnode:latestを持ってくる。-> https://registry.hub.docker.com/u/library/node/
  • あとは、ローカル側に用意したhubotの構成をDockerインスタンス上に移設して起動する設定をDockerfileに書く。

Dockerを起動してみる

まずはbuild

% docker build -t hubot .

そうすると、イメージが作成される。

% docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hubot               latest              663c24a4b22a        54 seconds ago      717.4 MB

作成されたイメージ上で、hubotを起動してみる

% docker run -it hubot bin/hubot
hubot> hubot ping
PONG

Slackの用意

Integration Settings

  • Hubotを有効に。
    • API Tokenを得られる
    • Iconのカスタマイズ、Nameのカスタマイズもできる

Dockerの起動

% docker run -e HUBOT_SLACK_TOKEN=${HUBOT_SLACK_TOKEN} -e HUBOT_SLACK_TEAM=${HUBOT_SLACK_TEAM} -e PORT=${PORT} -d -p 9999:9999 -v "$(pwd)":/hubot hubot

これでチームにhubotが参加してくる。

CircleCIの用意

circle.yml
machine:
  services:
    - docker
dependencies:
  cache_directories:
    - "~/docker"
  pre:
    - if [[ -e ~/docker/hubot.tar ]]; then docker load --input ~/docker/hubot.tar; fi
    - docker build -t hubot .
    - mkdir -p ~/docker
    - docker save hubot > ~/docker/hubot.tar
test:
  override:
    - docker run -p 9999:9999 -v "$(pwd)":/hubot hubot
  • circleCI上でDockerコンテナを起動するときは、services: dockerが必要
  • dependenciesのところは、dockerのイメージを毎回registryからダウンロードしなくてよいようにキャッシュしている

Hubotへスクリプトの追加

stamp.coffee
# Description:
#   A way to interact with the Stamp URI.
#
# Commands:
#   hubot stamp me <keyword> - The Original. Queries Stamp Images for <keyword> and returns a stamp image.
#   hubot stamp list         - Show a list of keywords.

stamps = JSON.parse(process.env.HUBOT_STAMPS)

module.exports = (robot) ->
  robot.respond /stamp me (.*)/i, (msg) ->
    keyword = msg.match[1]
    msg.send stamps[keyword] ? "No stamp for #{keyword}"

  robot.respond /stamp list/i, (msg) ->
    keys = for key, value of stamps
             key
    msg.send keys.join('\n')

scripts以下に配置するとhubotの起動時に読み込んでくれる。
決められたフォーマットでコメントを書いておくと、hubot helpしたときにコマンドの説明を表示してくれる。このscriptでは環境変数HUBOT_STAMPSにJSONを登録しておくと、keyに紐付いたimageのURLを返してくれる。

AWSへAnsibleを使ってデプロイする

hubot.yml
- hosts: aws
  user: ec2-user
  vars_files:
    - vars/env.yml
    - vars/private.yml
  tasks:
    - git: repo=https://github.com/osamunmun/hubot.git dest=/home/ec2-user/hubot accept_hostkey=yes
    - file: path=/home/ec2-user/cache state=directory
    - shell: cd /home/ec2-user/hubot; sudo ./docker-build.sh
    - shell: sudo docker stop $(sudo docker ps -a -q)
    - shell: cd /home/ec2-user/hubot; sudo docker run -e HUBOT_STAMPS={{ HUBOT_STAMPS }} -e HUBOT_SLACK_TOKEN={{ HUBOT_SLACK_TOKEN }} -e HUBOT_SLACK_TEAM={{ HUBOT_SLACK_TEAM }} -e PORT={{ PORT }} -p 9999:9999 -d -v $(pwd):/hubot hubot/slack

CircleCIからデプロイする

  • circleCIの環境変数に以下の値を登録しておく
    • ANSIBLE_VAULT
    • AWS_ACCESS_KEY_ID
    • AWS_DEFAULT_REGION
    • AWS_SECRET_ACCESS_KEY
    • AWS_SECURITY_GROUP_ID
    • HUBOT_SLACK_TEAM
    • HUBOT_SLACK_TOKEN
  • circleCIのSSH Permissionsにデプロイ先のEC2インスタンスへアクセスできる秘密鍵を登録しておく
circle.yml
machine:
  services:
    - docker
dependencies:
  cache_directories:
    - "~/cache"
  pre:
    - ./docker-build.sh
    - npm install
    - sudo pip install awscli
    - sudo pip install ansible
    - echo "${ANSIBLE_VAULT}" > ~/vault.txt
test:
  override:
    - ./node_modules/.bin/gulp mocha
    - docker run -e HUBOT_SLACK_TOKEN=${HUBOT_SLACK_TOKEN} -e HUBOT_SLACK_TEAM=${HUBOT_SLACK_TEAM} -e PORT=${PORT} -d -p 9999:9999 -v "$(pwd)":/hubot hubot/slack
deployment:
  production:
    branch: master
    commands:
      - sh ./deploy.sh
deploy.sh
#!/bin/sh
set -ex

IP=`curl -s ifconfig.me`

trap "aws ec2 revoke-security-group-ingress --group-id ${AWS_SECURITY_GROUP_ID} --protocol tcp --port 22 --cidr ${IP}/32" 0 1 2 3 15
aws ec2 authorize-security-group-ingress --group-id ${AWS_SECURITY_GROUP_ID} --protocol tcp --port 22 --cidr ${IP}/32
cd ansible; ansible-playbook -i hosts hubot.yml --vault-password-file ~/vault.txt
ansible/hubot.yml
- hosts: aws
  user: ec2-user
  vars_files:
    - vars/env.yml
    - vars/private.yml
  tasks:
    - git: repo=https://github.com/osamunmun/hubot.git dest=/home/ec2-user/hubot accept_hostkey=yes
    - file: path=/home/ec2-user/cache state=directory
    - shell: cd /home/ec2-user/hubot; sudo ./docker-build.sh
    - shell: sudo docker stop $(sudo docker ps -a -q)
    - shell: cd /home/ec2-user/hubot; sudo docker run -e HUBOT_STAMPS={{ HUBOT_STAMPS }} -e HUBOT_SLACK_TOKEN={{ HUBOT_SLACK_TOKEN }} -e HUBOT_SLACK_TEAM={{ HUBOT_SLACK_TEAM }} -d -v $(pwd):/hubot hubot/slack
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした