Skip to content
/ websh Public
forked from jiro4989/websh

シェル芸botをWebで使えるようにしたNim製Webアプリ

License

Notifications You must be signed in to change notification settings

yklmbbs/websh

 
 

Repository files navigation

websh - Web shellgei execution environment

Latest version Build Status

websh はWebブラウザ上でシェル芸botの実行環境を提供するWebアプリです。
シェル芸の実行はDockerコンテナ上で行っており、イメージに シェル芸botのDockerイメージ を使用しています。

image-top

  • 画面を表示する
  • 画面左のtextareaにシェルを入力する
  • 画面左のRunボタンを押す
  • 結果が画面右のtextareaにセットされる
  • やりたかったらTweetボタンでつぶやく

実体はフロントエンドのHTMLからAPIリクエストして実行結果を受け取ってるだけです。 なので普通にcurlでPOSTリクエスト送れば画面がなくても動きます。

以下のようなリクエストを送ればコマンドラインからwebshを使用できます。

curl -X POST -d '{"code":"echo hello", "images":[]}' 'https://websh.jiro4989.com/api/shellgei'

images にbase64エンコードした画像ファイルを含めるとwebsh上の /media 配下にア ップロードしたファイルがbase64デコードされて配置されます。

シェル芸Bot のWeb移植の SGWeb というWebアプリがある。

最新のシェル芸botに追従してなかったので、試しに自分が最新のシェル芸botに追従する Webアプリ作って公開してみるか、と思ったから。 あとWebアプリを作る勉強もかねて。

アプリはすべてDockerコンテナ上で動作する。

ブラウザの画面からシェルを実行するとコンテナ上のNginxへリクエストが流れる。 Nginxはリバースプロキシし、コンテナ上のAPIサーバがリクエストを受ける。

APIサーバはホストネットワーク上のDockerAPIを使用して、 シェル芸Botコンテナを操作する。

画像ファイルなどを配置する一時ディレクトリの後始末は APIサーバからは行わず、removerコンテナが非同期に削除する。

ローカル環境の構成図

Infrastructure as Code (Ansible) している。 ソースコードは infra リポジトリ(非公開)で管理。

監視系はローカルPCのDockerコンテナ上で動作するGrafanaとPrometheusで実施。 nimbot はSlack用のBotで、 websh用のサーバに後乗せで一緒に稼働している。

ログは一旦ローカルに書き出したファイルをFluentdが拾ってJSON形式に変換して保存。 GrafanaLokiがログを拾って、Grafanaからログを取得してログ監視をしている。

システム構成図

ブラウザからPOSTリクエストを受け、POSTの内容を取得し、Dockerコンテナ内でシェルを実行する。

コンテナは状態を保持しないようにする。 一度リクエストをしたあと、再度コンテナにリクエストをしても、前回実行した結果はコンテナ内に残らないようにする。 リクエストの都度、コンテナを破棄して生成するようにする。

ただしコンテナの破棄と生成はAPIサーバプロセス自体は実施しない。 コンテナの破棄と起動には時間がかかり、合計で約2秒ほどかかってしまう。 レスポンスタイム向上のため、コンテナの破棄と生成は別プロセスが引き受けるようにする。 APIサーバはコンテナの破棄のトリガーを生成するのみに留める。

コンテナの起動はインフラ側のsupervisorが引受ける。 コンテナや画像ファイルの破棄は別APIサーバとは別プロセスが引き受ける。

以上を踏まえて、Webからのリクエストを受けてレスポンスを返すまでの一連の処理フローは以下の通り。

データ処理フロー

以下のツールがインストールされている必要があります。

  • Nim
  • Docker
  • Docker-compose
Path Description
docs READMEの画像ファイルなど
nginx ローカル開発用のnginxの設定
websh_front フロントエンドのプログラム
websh_server バックエンドのAPIサーバのプログラム
websh_remover バックエンドの後始末を行うプログラム
Dockerfile アプリのDockerイメージ
docker-compose.yml ローカル開発でのみ使用する開発環境設定

DockerをAPIで操作できるようにする必要がある。 Linux環境ではSystemdでDockerを起動しているはず。 docker.serviceを以下のように修正する。

/lib/systemd/system/docker.service

# ここを
ExecStart=/usr/bin/dockerd -H fd:https:// --containerd=/run/containerd/containerd.sock

# こう修正
ExecStart=/usr/bin/dockerd -H tcp:https://0.0.0.0:2376 -H fd:https:// --containerd=/run/containerd/containerd.sock

以下のコマンドをリポジトリディレクトリ配下で実行する。

# シェル芸botのイメージを取得 (巨大なので注意)
docker pull theoldmoon0602/shellgeibot
docker-compose build
docker-compose up

サーバを起動して待機状態になったら、ブラウザで以下のページにアクセスする。

http:https://localhost

以下の5種類のブランチを使う。

Branch name Description
master 本番用
feature/#xx-desc 新機能、UI改善
hotfix/#xx-desc バグ修正
chore/#xx-desc CIやローカル開発環境の整備など、アプリに影響しない雑多なもの

feature, hotfix, choreのブランチ名のプレフィックスは、PR作成時のラベル自動付与にも使用している。 よって、必ずブランチ命名規則を守ること。

1つずつリリースしたいので各ブランチからmasterにPRを出す。 複数の改修をまとめてリリースしたい時だけdevelopブランチを使う。

ドキュメントの更新だけの場合はmasterブランチから直接pushする。 この時は必ずコミットログに [skip ci] を含めなければならない。 masterブランチのCIが走るとリリースドラフトが生成されてしまうため。 詳細は CI のセクションを参照。

websh_frontディレクトリ配下のREADME を参照。

websh_serverディレクトリ配下のREADME を参照。

.github ディレクトリ配下にワークフローを定義している。 ビルド、テスト、デプロイのフローは .github/workflows/main.yml に定義している。

CIのジョブフローは以下。

CIフロー

masterブランチでのpush、margeの場合は create-tag-draft が実行される。

create-tag-draft ではタグのドラフトを作成する。 タグのドラフトは、PRの説明から自動でセットされる。 Feature/BugFixなどの分類は、 PR時のラベルでカテゴライズされる。

PR時のラベルはブランチのプレフィックスから自動でセットされる。 ブランチ命名規則については <<開発,ブランチ運用>> を参照。

タグドラフトをpublishすると deploy が実行され、サーバ上にmasterのビルド成果物をデプロイする。

前述のCIの通り、リリースを作成すると自動でデプロイされる。

リリースの下書きはGitHub Actionsが下書きを作成する。 下書きをpublishすると、GitHub Actionが起動して、デプロイされる。 以下はデプロイのフロー。

リリースフロー

デザインとか超手抜きですので、プルリクエストお待ちしてます。

Apache License

About

シェル芸botをWebで使えるようにしたNim製Webアプリ

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Nim 93.3%
  • CSS 5.0%
  • HTML 1.1%
  • Other 0.6%