Okada Hiroshi の blog

typo が多いです

プログラムを実行して結果を返す mastodon bot のソースコードを公開しました。

プログラムを実行して結果を返す mastodon bot を作ってみました。 - Okada Hiroshi の blog

を改良して、ソース−コードを公開しました。

HiroshiOkada/hello-bot: A Mastodn bot that run short programs

botの使い方

画像を出力する部分で日本語が上手く表示できなくて修正に時間がかかってしまいましたが、なんとか公開できる状態になったと思います。

対応プログラミング言語も少し増やして 29言語ほどにしました。

拡張子 処理系&言語
.asm NASM
.bc bc
.bf beef(Brainfuck)
.cpp clang++(c++)
.cs mcs/mono(C#)
.c gcc(C)
.dot dot/Graphviz
.f .f90 .f95 gfortran
.go go
.hs ghc
.html phantomjs
java openjdk-9
.js nodejs
.lsp .lisp clisp
.lua lua5.3
.ml ocaml
.php php7
.plt .gnuplot .gpi gnuplot
.py2 python2
.py3 .py python3
.pl perl
.rb ruby
.scm guile(scheme)
.sh .bash bash
.sql sqlite3
.svg inkscape
.ts tsc(TypeScript)
.vim vim
.zsh zsh

プログラムを実行して結果を返す mastodon bot を作ってみました。

せっかく mastodon サーバーを立てたのだから bot を作ってみようと、プログラムを実行して結果を返す mastodon bot を作ってみました。

自分で立てたサーバーなので、負荷を気にせずに実験できるのはメリットの一つです。

今回作ったのは、プログラムを送ると docker コンテナ上で実行して出力を返すという bot です。

例えば、 @hello@mastodon.toycode.com 宛に

@hello@mastodon.toycode.com
hello.cpp
#include <iostream> 
int main()
{
    std::cout << "Hello, World!\n";
}

のようなメンションを toot すると、 Hello, World と帰ってきます。

@hello@mastodon.toycode.com の次の行にあるファイル名の拡張子で、どのプログラム言語かを判定しています。 又、ファイル名を書かずに shebang で始めることもできます。

#!/bin/bash

echo "今日は世界"

頑張って 20言語以上に対応したので、遊んでみて下さい。

なお、 svg, dot言語, gnuplot に対しては画像を返します。

さらにプログラムで out.svgsvg を出力するとその画像を返します。

Mastodn API を叩くための access token を取得するコマンドラインプログラムを node.jsで書きました。

Mastodn API を叩くための OAuth2 の access token を取得する。コマンドコマンドラインツールを node.js で書いてみました。

www.npmjs.com

(途中でブラウザが立ち上がります。)

npm を公開するにのは初めてだったので、数日かかってしましましたが、これで bot を作るのが楽になったと思います。

なお、 mastodon の場合

config/initializers/doorkeeper.rb

# Access token expiration time (default 2 hours).
# If you want to disable expiration, set this to nil.
 access_token_expires_in nil

となっているので、 access_token の更新はしなくても良いようです。

mastodonインスタンスを VPS から自作サーバーに引っ越しました

今まで mastodon インスタンス toycode -- Mastodon を の OVHとうい会社のVPS で運営してきましたが、結構ディスクをやメモリを食うので、自宅サーバーに引っ越すことにしました。

事前準備(VPS側)

  • 自宅サーバーに ubuntu16.04 と Docker, docker-compose 等の必要なソフトをインストールしました。
  • VPS から 自宅サーバに切り替えた時に DNS の変更が早く反映されるように TTL を 60 にしました、また VPS のホストを切替後も参照できるように old という名前を追加しました。DNSAmazon Route 53 を使っているので、比較的作業は簡単でした。

事前準備(自宅側)

  • NVR500でdns static a mastodon.toycode.com 192.168.100.200 ttl=120と入力し、自宅内からアクセスした時はLANのアドレスを返すようにしました。

停止

  • 僕以外、ほとんど使っている人はいないと思いますが、一応「止めますよ」と toot してから5分ほど待って docker-compose down でインスタンスを止めました。
  • インスタンスを停止したので、Amazon Route 53 で DNS のレコードを編集して、 mastodon.toycode.com が自宅を指すようにしました。

データの移行完了と起動

VPS 側で、パーミッション等の設定をした後、もう一度 rsync で残りのデータをコピーしました、事前に殆どのデータをコピーしていたので、*(1分以内** でコピーが終わりました。 docker-compose up -d で起動し、自宅内のパソコンと(LAN内)、WiFiを切った状態のスマートフォン(外からのアクセス)で動作しているのを確認しました。

Mastodon サーバーを v1.2.2 にしました

Mastodon サーバーを v1.2.2 にしました。

https://mastodon.toycode.com/mastodon.toycode.com

今回は、 docker-compose.yml を見なおして docker-compose pull だけで済むようにしました。 ( build しなくて良くしました )

version: '2'
services:

  nginx:
    image: nginx:alpine
    depends_on:
      - web
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/ssl

  db:
    restart: always
    image: postgres:alpine
    volumes:
      - ./postgres:/var/lib/postgresql/data

  redis:
    restart: always
    image: redis:alpine
    volumes:
      - ./redis:/data

  web:
    restart: always
    image: gargron/mastodon:v1.2.2
    env_file: .env.production
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    depends_on:
      - db
      - redis
    volumes:
      - ./public/assets:/mastodon/public/assets
      - ./public/system:/mastodon/public/system

  streaming:
    restart: always
    image: gargron/mastodon:v1.2.2
    env_file: .env.production
    command: npm run start
    depends_on:
      - db
      - redis

  sidekiq:
    restart: always
    image: gargron/mastodon:v1.2.2
    env_file: .env.production
    command: bundle exec sidekiq -q default -q mailers -q pull -q push
    depends_on:
      - db
      - redis
    volumes:
      - ./public/system:/mastodon/public/system

  cron:
    restart: always
    image: gargron/mastodon:v1.2.2
    env_file: .env.production
    command: |
      sh -c 'sh -s <<EOF
        trap "break;exit" SIGHUP SIGINT SIGTERM
        while /bin/true; do
          /bin/date -Ihours 
          /usr/bin/time rake mastodon:daily 
          /bin/sleep 1439m
        done >>/var/log/cron.log 2>&1
      EOF'
    depends_on:
      - db
      - redis
    volumes:
      - ./public/assets:/mastodon/public/assets
      - ./public/system:/mastodon/public/system
      - ./cron/log:/var/log

また、 メーリングリスト(mastodon-admin@lists.ffdn.org)で教えてもらったように、日々の定期処理 rake mastodon:daily を docker-compose.yml の中で完結するようにしました。

さらにバージョンアップ毎に書き換える必要があるので、 https://github.com/HiroshiOkada/mastodon.toycode.com で管理するようにしました。

Mastodon サーバーをアップデートしました

https://mastodon.toycode.com/mastodon.toycode.com

v1.2 が出ていたので、アップデートしました、途中手間取って1時間くらいかかってしまいました。

作業メモ

$ cd mastodon             # mastodn ディレクトリに移動
$ docker-compose down     # サービスをダウン
$ cd ..                   # バックアップを取るために一つ上のディレクトリに移動
$ sudo chown -R hiroshi:hiroshi mastodon       # 一部のファイルのオーナーが root になっていたのを修正
$ tar cvfz mastodon-before-update.tgz mastodon # バックアップ
$ cd mastodon                      # サイド mastodn ディレクトリに移動      
$ git checkout master              # master をチェックアウト
$ git pull                         # 変更を取り込み
$ git tag                          # タグを確認
$ git checkout toycode             # ローカルなブランチ toycode をチェックアウト
$ git merge v1.2 --no-commit       # v1.2 をマージ (commitは保留)
$ git status                       # 確認

# -- 変更箇所などをざっと確認、今回は問題なさそうなので commit することに --

$ git commit -m 'update to v1.2'   # 変更を commit する
$ docker-compose pull              # 最新版のイメージをプル
$ docker-compose build             # ビルド
$ docker-compose run --rm web rails db:migrate          # データベースのスキームが変わっているので必要
$ docker-compose run --rm web rails assets:precompile   # アセットをプリコンパイル
$ docker-compose up -d             # サービスを立ち上げ
$ docker-compose logs -f           # ログをみて正常に立ち上がっていることを確認
^C

前提条件として、 一つ前の記事 に書いたとおり、 本家を clone したあと toycode というローカルなブランチを切って、設定を書き換え、 フロントの nginx もまとめてdocker-compse で管理しています、

本家以外で参考にしたページ

Mastodon サーバーを立ててみました

ミーハーなので、流行りの Mastodon サーバーを立ててみました。

https://mastodon.toycode.com/mastodon.toycode.com

基本的には、以前から自分の勉強用に借りている VPS に docker と docker-compose を入れて設定しただけです。

sslは、自宅サーバー用に *.toycode.com の ワイルド−カード ssl 証明書を取得していたのでそれを使いました。

また、メールサーバーは、契約していたけどあまり使っていなかった、さくらのメールボックスを使うことにしました。

具体的には、git clone しローカルにブランチを切った後、 nginx というディレクトリを作って、サーバー証明書documentation/Production-guide.md at master · tootsuite/documentation を元に以下のように書き換え

--- default.conf.orig    2017-04-16 19:55:26.488591836 +0900
+++ default.conf  2017-04-16 13:19:25.319053418 +0900
@@ -6,14 +6,14 @@
 server {
   listen 80;
   listen [::]:80;
-  server_name example.com;
+  server_name mastodon.toycode.com;
   return 301 https://$host$request_uri;
 }
 
 server {
   listen 443 ssl;
   listen [::]:443 ssl;
-  server_name example.com;
+  server_name mastodon.toycode.com;
 
   ssl_protocols TLSv1.2;
   ssl_ciphers EECDH+AESGCM:EECDH+AES;
@@ -21,8 +21,8 @@
   ssl_prefer_server_ciphers on;
   ssl_session_cache shared:SSL:10m;
 
-  ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
-  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
+  ssl_certificate     /etc/nginx/server.crt;
+  ssl_certificate_key /etc/nginx/server.key;
 
   keepalive_timeout    70;
   sendfile             on;
@@ -53,7 +53,7 @@
     proxy_set_header Proxy "";
     proxy_pass_header Server;
 
-    proxy_pass http://127.0.0.1:3000;
+    proxy_pass http://web:3000;
     proxy_buffering off;
     proxy_redirect off;
     proxy_http_version 1.1;
@@ -70,7 +70,7 @@
     proxy_set_header X-Forwarded-Proto https;
     proxy_set_header Proxy "";
 
-    proxy_pass http://localhost:4000;
+    proxy_pass http://streaming:4000;
     proxy_buffering off;
     proxy_redirect off;
     proxy_http_version 1.1;
@@ -82,3 +82,4 @@
 
   error_page 500 501 502 503 504 /500.html;
 }
+

Dockerfile を作り

#
FROM nginx:alpine

MAINTAINER Hiroshi Okada <okadahiroshi@miobox.jp>

COPY server.crt server.key /etc/nginx/

COPY default.conf /etc/nginx/conf.d/

EXPOSE 443 80

元の docker-compose.yml を以下のように書き換えて

version: '2'
services:

  nginx:
    build: ./nginx
    image: okadahiroshi/nginx
    depends_on:
      - web
    ports:
      - "80:80"
      - "443:443"

  db:
    restart: always
    image: postgres:alpine
### Uncomment to enable DB persistance
    volumes:
      - ./postgres:/var/lib/postgresql/data

  redis:
    restart: always
    image: redis:alpine
### Uncomment to enable REDIS persistance
    volumes:
      - ./redis:/data

  web:
    restart: always
    build: .
    image: gargron/mastodon
    env_file: .env.production
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    depends_on:
      - db
      - redis
    volumes:
      - ./public/assets:/mastodon/public/assets
      - ./public/system:/mastodon/public/system

  streaming:
    restart: always
    build: .
    image: gargron/mastodon
    env_file: .env.production
    command: npm run start
    depends_on:
      - db
      - redis

  sidekiq:
    restart: always
    build: .
    image: gargron/mastodon
    env_file: .env.production
    command: bundle exec sidekiq -q default -q mailers -q pull -q push
    depends_on:
      - db
      - redis
    volumes:
      - ./public/system:/mastodon/public/system

残りの作業は、 https://github.com/tootsuite/mastodon#running-with-docker-and-docker-compose の通りに作業しました。

あまりむずかしい作業ではありませんでしたが、 VPS が海外サーバーで、さくらのメールに国外IPアドレスフィルタが設定してあったので、 最初メール認証がうまくいなかくて焦りました。

なお、立ち上げたサーバーはしばらく(最低一年程度)は運用するつもりです。今は自由にアカウントを作れる状態にしていますので自由にアカウントを作っていただいて OK ですが、 負荷が多いようだったら、新規のアカウントの作成はできないようにするつもりです。(spam 行為でないかぎり作成済みのアカウントを故意に消すことはないと思います。)