LoginSignup
1
2

More than 5 years have passed since last update.

Errbot on Docker のデバッグ環境構築手順

Posted at

Errbotとは

chatbotの1つでslackなどのチャットサービスにbotとして簡単に導入できます。
python実装のため、プラグイン開発もpythonで行えます。

実現したいこと

ローカルフォルダで開発中のプラグインをDocker内のerrbotで実行し、VSCodeでデバッグ実行できる。
開発後は、slackに接続してchatbot運用する。

動作確認したDockerバージョン

$ docker version
Client: Docker Engine - Community
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        6247962
 Built:             Sun Feb 10 04:12:39 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       6247962
  Built:            Sun Feb 10 04:13:06 2019
  OS/Arch:          linux/amd64
  Experimental:     true

Errbot on Dockerの構築

errbot をビルドするために Dockerfile,requirements.txt,entrypoint.sh,errbot設定ファイルsrv/config.pyを用意します。

ファイル一覧
docker-errbot/
|--Dockerfile
|--entrypoint.sh
|--requirements.txt
|--srv
|  |--config.py
Dockerfile
FROM python:alpine
WORKDIR /app
COPY . /app
# Install Requirments Packages.
RUN apk add --no-cache --virtual .build-deps \
    gcc \
    libffi-dev \
    musl-dev \
    openssl-dev \
    && : Install pip packages \
    && python -m pip install -r requirements.txt \
    && : Delete build-deps packages \
    && apk del --purge .build-deps \
    && : Delete pip cache files \
    && rm -rf /root/.cache
# Install minimal Packages, and Setup Errbot.
RUN apk add --no-cache \
    bash \
    shadow \
    tzdata \
    && : Setup timezone \
    && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && echo "Asia/Tokyo" > /etc/timezone \
    && : Setup user \
    && groupadd -r errbot && useradd -m -r -g errbot errbot \
    && : Setup errbot \
    && errbot --init \
    && : Change owner and group \
    && chown -R errbot:errbot /app \
    && : Change permission  \
    && chmod +x entrypoint.sh

# Run
USER errbot
ENTRYPOINT [ "./entrypoint.sh" ]
CMD [ "run" ]
  • できるだけイメージサイズを小さくしたいのでpython:alpineをベースイメージとして選択します
  • pip install 時だけに必要なパッケージは、apk add --no-cache --virtual .build-depsでインストールし、pip install 後にapk del --purge .build-depsで削除します
  • pip install 時のキャッシュファイル/root/.cacheも削除します
  • timezoneはAsia/Tokyoに設定します
  • ユーザerrbotでerrbotを起動します
requirements.txt
errbot
slackclient
websocket-client
ptvsd
  • ptvsd(Python Tools for Visual Studio debug server)を導入することでVSCodeからリモートデバッグできるようになります
entrypoint.sh
#!/bin/bash -eu

[[ -v DEBUG ]] && ${DEBUG} && set -x

case ${1} in
    run)
        errbot -c srv/config.py
        ;;
    debug)
        python -m ptvsd --host 0.0.0.0 --port 5678 /usr/local/bin/errbot -c srv/config.py
        ;;
    *)
        exec "$@"
        ;;
esac
  • entrypoint.shスクリプトをデバッグしたい時はDEBUG=trueとすることでset -xが実行されます
  • entrypoint.sh runで通常実行
  • entrypoint.sh debugでデバッグ実行
  • デバッグ実行時は ptvsd が 0.0.0.0:5678 でデバッグ接続を待ち受けて errbot を起動します
config-tempalateとの差分
$ diff -u config-tempalate.py srv/config.py
--- config-template.py  2019-05-04 18:02:05.000000000 +0900
+++ srv/config.py   2019-05-04 18:13:20.000000000 +0900
@@ -17,6 +17,7 @@
 ##########################################################################

 import logging
+import os

 ##########################################################################
 # Core Errbot configuration                                              #
@@ -44,7 +45,7 @@
 # 'Telegram' - cloud-based mobile and desktop messaging app with a focus
 #              on security and speed. (https://telegram.org/)

-# BACKEND = 'XMPP'  # defaults to XMPP
+BACKEND = os.environ.get('BACKEND', 'Text')

 # STORAGE selection.
 # This configures the type of persistence you wish to use Errbot with.
@@ -63,7 +64,7 @@

 # The location where all of Err's data should be stored. Make sure to set
 # this to a directory that is writable by the user running the bot.
-BOT_DATA_DIR = '/var/lib/err'
+BOT_DATA_DIR = '/app/data'

 ### Repos and plugins config.

@@ -82,7 +83,7 @@
 # locally before publishing it. Note that you can specify only a single
 # directory, however you are free to create subdirectories with multiple
 # plugins inside this directory.
-BOT_EXTRA_PLUGIN_DIR = None
+BOT_EXTRA_PLUGIN_DIR = '/app/plugins'

 # If you use an external backend as a plugin,
 # this is where you tell Errbot where to find it.
@@ -126,7 +127,7 @@
 # If you encounter any issues with Err, please set your log level to
 # logging.DEBUG and attach a log with your bug report to aid the developers
 # in debugging the issue.
-BOT_LOG_LEVEL = logging.INFO
+BOT_LOG_LEVEL = logging.getLevelName(os.environ.get('BOT_LOG_LEVEL', 'INFO'))

 # Enable logging to sentry (find out more about sentry at www.getsentry.com).
 # This is optional and disabled by default.
@@ -153,9 +154,9 @@
 # The identity, or credentials, used to connect to a server
 BOT_IDENTITY = {
     # XMPP (Jabber) mode
-    'username':
-    'err@localhost',  # The JID of the user you have created for the bot
-    'password': 'changeme',  # The corresponding password for this user
+    # 'username':
+    # 'err@localhost',  # The JID of the user you have created for the bot
+    # 'password': 'changeme',  # The corresponding password for this user
     # 'server': ('host.domain.tld',5222), # server override

     ## HipChat mode (Comment the above if using this mode)
@@ -170,7 +171,7 @@
     # 'endpoint': 'https://api.hipchat.com'

     ## Slack mode (comment the others above if using this mode)
-    # 'token': 'xoxb-4426949411-aEM7...',
+    'token': os.environ.get('BOT_SLACK_TOKEN'),
     ## you can also include the proxy for the SlackClient connection
     # 'proxies': {'http': 'some-http-proxy', 'https': 'some-https-proxy'}

@@ -198,7 +199,7 @@
 #
 # Unix-style glob patterns are supported, so 'gbin@localhost'
 # would be considered an admin if setting '*@localhost'.
-BOT_ADMINS = ('gbin@localhost', )
+BOT_ADMINS = tuple(os.environ.get('BOT_ADMINS', '@admin').split(','), )

 # Set of admins that wish to receive administrative bot notifications.
 #BOT_ADMINS_NOTIFICATIONS = ()
@@ -238,7 +239,8 @@
 # names, rather than the BOT_PREFIX above. This option allows you to
 # specify alternative prefixes the bot will respond to in addition to
 # the prefix above.
-#BOT_ALT_PREFIXES = ('Err',)
+BOT_ALT_PREFIXES = tuple(
+    os.environ.get('BOT_ALT_PREFIXES', 'Err').split(','), )

 # If you use alternative prefixes, you might want to allow users to insert
 # separators like , and ; between the prefix and the command itself. This
  • errbotのconfig-templateを取得し、上記のように書き換えてsrv/config.pyにします
  • デフォルトはTextモードで起動されます
  • BACKEND=Slackとすることでslackモードで起動し、slackに接続されます
  • slackのAPIトークンはBOT_SLACK_TOKEN=xoxb-...で設定します

dockerイメージのビルド

$ docker build ./ -t errbot
Sending build context to Docker daemon  50.18kB
Step 1/8 : FROM python:alpine
 ---> 715a1f28828d
Step 2/8 : WORKDIR /app
 ---> Running in 1a057f81fc87
Removing intermediate container 1a057f81fc87
 ---> 9cca706eba25
Step 3/8 : COPY . /app
 ---> 780a7a9beb56
Step 4/8 : RUN apk add --no-cache --virtual .build-deps     gcc     libffi-dev     musl-dev     openssl-dev     && : Install pip packages     && python -m pip install -r requirements.txt     && : Delete build-deps packages     && apk del --purge .build-deps     && : Delete pip cache files     && rm -rf /root/.cache
 ---> Running in c19b0fedc8f4
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
(1/16) Installing binutils (2.31.1-r2)
(2/16) Installing gmp (6.1.2-r1)
(3/16) Installing isl (0.18-r0)
※省略

Errbotを通常(Text)モードで起動確認

下記のコマンドでerrbotを起動します。
[@admin ➡ @errbot] >>>
でerrbotの起動が成功し、コマンド待ち状態となります。

$ docker run --rm -it --name errbot errbot
20:29:58 INFO     errbot.bootstrap          Found Storage plugin: Shelf.
20:29:58 INFO     errbot.bootstrap          Found Backend plugin: Text
20:29:59 INFO     errbot                    webhooks:  Flag to bind /echo to echo
────────────────────────────────────────────────────────────────────────────────
 You start as a bot admin in a one-on-one conversation with the bot.

    Context of the chat

• Use !inroom to switch to a room conversation.
• Use !inperson to switch back to a one-on-one conversation.
• Use !asuser to talk as a normal user.
• Use !asadmin to switch back as a bot admin.

    Preferences

• Use !ml to flip on/off the multiline mode (Enter twice at the end to send).
────────────────────────────────────────────────────────────────────────────────

[@admin ➡ @errbot] >>> 

VSCode側のデバッグ構成

VSCodeでデバッグ構成ファイル(launch,json)を下記のように設定します

launch.json
"configurations": [
    {
        "name": "Python: Attach",
        "type": "python",
        "request": "attach",
        "port": 5678,
        "host": "localhost",
        "pathMappings": [
            {
                "localRoot": "${workspaceFolder}/plugins",
                "remoteRoot": "/app/plugins"
            }
        ]
    },
※省略
  • Python: Attach実行時にlocalhost:5678に接続します
  • Python: Attach実行時にローカルのpluginsフォルダとリモートの/app/pluginsフォルダをマッピングします

Errbotをデバッグ(Text)モードで起動

下記コマンドでerrbotを起動してVSCodeでデバッグPython:attachを実行するとブレークポイントの指定や変数の状態なども確認でき、デバッグが簡単にできるようになります。

$ docker run --rm -it --name errbot -v $(pwd)/plugins:/app/plugins:ro -p 5678:5678 -e DEBUG=true errbot debug
+ case ${1} in
+ python -m ptvsd --host 0.0.0.0 --port 5678 /usr/local/bin/errbot -c srv/config.py
20:42:37 INFO     errbot.bootstrap          Found Storage plugin: Shelf.
20:42:37 INFO     errbot.bootstrap          Found Backend plugin: Text
20:42:39 INFO     errbot                    webhooks:  Flag to bind /echo to echo
────────────────────────────────────────────────────────────────────────────────
 You start as a bot admin in a one-on-one conversation with the bot.

    Context of the chat

• Use !inroom to switch to a room conversation.
• Use !inperson to switch back to a one-on-one conversation.
• Use !asuser to talk as a normal user.
• Use !asadmin to switch back as a bot admin.

    Preferences

• Use !ml to flip on/off the multiline mode (Enter twice at the end to send).
────────────────────────────────────────────────────────────────────────────────

[@admin ➡ @errbot] >>> 
  • pluginsフォルダ配下に開発中のプラグインソースを置きます
  • docker起動時の -vオプションでpluginsフォルダをdocker内/app/pluginsにマウントします
  • docker起動時の -pオプションでport 5678をdocker内のptvsdが待ち受けているport 5678に接続できます
  • docker起動時の -eオプションでDEBUG=trueentrypoin.shスクリプトの実行も確認できます

slackのchatbotとしての運用方法

slackモードで運用するときには、docker runで渡すパラメータが増えて大変なのでdocker-composeで起動できるように下記のdocker-compose.ymlを用意します

docker-compose.yml
version: '2.1'

services:
  errbot:
    image: errbot
    build: 
      context: .
    environment:
      - BACKEND=Slack
      - BOT_SLACK_TOKEN
      - BOT_ADMINS=@admin
    stdin_open: true
    tty: true

BOT_SLACK_TOKENにslackのAPIトークンを直接記載してもよいのですが、docker-compose.ymlもgit管理にしたいのでBOT_SLACK_TOKEN.envファイルに記載します。
.envファイルを.gitignoreでgit管理外に設定することでAPIトークンを誤ってgithubにpushしないようにするためです。

.env
BOT_SLACK_TOKEN=xoxb-...
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2