Skip to content

CH 27 · 展開形態の選定

全文字数約 4,210 字所要時間約 25 分前提CH 03、CH 05難易度再現可能

本章のゴール

これまで dsh web をローカルで動かして dsh を使ってきましたが、これが最も一般的ですが唯一の方法ではありません。dsh には主に 4 つの実行方法があり、それぞれ異なるシーンに向いています:

  • ローカル Web UI:これまでのチュートリアルで実演してきたもの
  • Headless CLI:インターフェース不要、1 コマンドでタスクを実行して終了、スクリプトや CI に組み込みやすい
  • Python SDK:dsh を自分の Python プログラムに組み込み、Agent をコード内の関数呼び出しにする
  • Docker コンテナ化:dsh をコンテナに入れてサーバーで動かす、チーム共有に向く——本章で完全な展開チュートリアルを解説

読み終えると、自分のニーズにどの方法を使うべきか(dsh web しか知らない、ではなく)が分かります。

まず確認:なぜ dsh に複数の形態があるのか

CH 08 の「すべてはプラグイン」を思い出してください。dsh のコアは @deepseek-ai/dsh-base(モデルアダプタ、ツール、永続化、サンドボックス、承認などの低層機能)で、その上に異なる bundle を重ねると異なる形態になります:

重ねる bundle形態起動方法
@deepseek-ai/dsh-web-appブラウザ UI 付き Web UIdsh web
@deepseek-ai/dsh-headlessUI なし、実行後終了する CLIdsh --profile headless "task"
Python SDK ラッパPython プログラムに組み込んで呼び出すpip install deepseek-harness-sdk
上記いずれかをコンテナ化サーバーで長期稼働docker compose up -d

同じ土台に 4 つの着せ方。これも「すべてはプラグイン」の現れであり、形態そのものが bundle の組み合わせです。

形態 1:ローカル Web UI

CH 03 から CH 04 で実演してきたのがこれです。dsh web で起動し、ブラウザで http://127.0.0.1:3080 を開くと、セッション・プラグイン・キーがすべてローカルに保存されます。

日常利用、プラグインのデバッグ、初心者に適しています。制約は PC の電源が入っているときしか使えないこと——電源を切れば Agent も止まるため、24 時間オンラインが必要、または他者に常時アクセスさせる必要があるシーンには向きません。

形態 2:Headless CLI

CH 05 で既にハンズオンしました。UI なしでタスクを渡せば実行して結果を返し終了します。

powershell
dsh --profile headless "Summarize the current directory's README into three sentences"

スクリプト、CI/CD、定時タスク(CH 15 で毎日 AI ホットトピックを集めるものがこれを使っています)、バッチ処理に向きます。マルチターンの対話が必要なシーンには向きません。

注意点:headless の呼び出し 1 回ごとに独立したセッションとなり、完了時に終了します。コンテキストを再利用するには Python SDK を使うか、ファイル経由の受け渡しを書く必要があります。

形態 3:Python SDK

dsh を Python コードのライブラリとして扱い、Agent を関数呼び出しにします。pip install deepseek-harness-sdk でインストールでき、SDK には Node ランタイムが同梱されるため、対象マシンに Node を別途インストールする必要はありません。

python
from deepseek_harness_sdk import DeepSeekHarness

dsh = DeepSeekHarness()
result = dsh.run("List the current directory's files, skip node_modules")
print(result.last_message)

Agent を自分のプロダクトに組み込みたい、セッションを細かく制御したい(再利用、イベント監視、ストリーミング出力)、コンテキストを共有するバッチタスク、に向きます。単にタスクをさっと走らせたいだけ(headless で 1 コマンドで十分)には向きません。

詳細:SDK と Web UI はそれぞれ独立したインスタンスであり、起動中の Web UI を共有することはできず、それぞれが独自の DSH_HOME を持ちます。

形態 4:Docker コンテナ(展開チュートリアル完全版)

dsh を Docker コンテナにインストールしてサーバーで動かす、長期稼働とチーム共有に向きます。

サーバーに進む前にひとこと:サーバーをまだ持っていない場合、Tencent Cloud の新規ユーザー向けキャンペーン では低コストな軽量アプリケーションサーバーが用意されていることが多く、年間わずか 100 元強で dsh には十分です。また Tencent Cloud ではインスタンス作成時に DeepSeek Harness イメージを直接選択することもできるため、いじるのが好きな方はそちらも調べてみてください。以下は成熟したコミュニティのオープンソースプロジェクトを使った完全な展開手順を実演します。

deepseek-harness-web-docker は dsh + Caddy(リバースプロキシ + Basic 認証)を 1 つのコンテナにまとめ、すぐに使える状態で配布しており、データは永続化、自動ヘルスチェックも備えています。

このプロジェクトが解決する問題

サーバーで公式の dsh web を直接使うと 3 つの痛みがあります:

  1. 認証がない——dsh の Web UI にはログイン機構がなく、パブリックに展開すると裸で動かしているのと同じ
  2. ループバックでしかリッスンしない——既定は 127.0.0.1 で、外部アクセスを許可するには設定変更が必要
  3. 環境管理が面倒——Node バージョン、依存関係、データディレクトリをすべて自前で管理する必要がある

このプロジェクトは Caddy をリバースプロキシとして使い、Basic 認証(ユーザー名/パスワードログイン)を追加します。dsh はコンテナ内のループバックだけでリッスンし、外部からのリクエストは Caddy の認証を通過しなければ入れません。データはすべてホストの ./data ディレクトリにマウントされるため、コンテナを削除してもデータは失われません。

ステップ 1:準備

Linux サーバー(2 コア 2G から)と、宝塔(BT)パネルをインストールします。宝塔 AI は使う前にまずモデルを設定する必要があります——左メニュー AI → 上部 SettingsAdd Custom Model をクリックし、モデルの API Key を入力します。

宝塔パネルでカスタムモデルを追加

モデルを設定すると、宝塔 AI がコマンド実行を助けてくれるようになります。

ステップ 2:宝塔 AI でワンクリック展開

宝塔パネルの左メニューで AI をクリックし、以下のプロンプトを送信します:

text
Help me deploy DeepSeek Harness Web Docker, do this in order:
1. Confirm Docker and Docker Compose are installed, install if not
2. Project address is https://github.com/Xidong-AI/deepseek-harness-web-docker
3. Enter the project directory, cp .env.example .env
4. Edit .env: DSH_AUTH_USER=admin, DSH_AUTH_PASSWORD set a strong password, DEEPSEEK_API_KEY etc. tell me the file path before starting I'll fill it in myself
5. docker compose up -d to start
6. Give me a summary after verification

宝塔 AI が手順を踏んでくれます。ステップ 4 に差し掛かると、.env ファイルの API Key 以外を設定し、ファイルパスを教えてくれるので、自分で DEEPSEEK_API_KEY を入力します:

宝塔 AI が .env の API Key 入力を促す

入力後「Done」と返信すれば、AI は docker compose up -d を続行して起動し、ヘルスチェックで検証し、最後に完全なサマリーを返してくれます:

宝塔 AI が展開成功を検証

コンテナの状態が healthy で、Basic 認証が有効になっている(認証なしで 401 を返す)なら、展開成功です。

ステップ 3:アクセス

ブラウザで http://server-IP:3080 を開くと、Basic 認証のダイアログがポップアップするので、.env に設定したユーザー名とパスワードを入力すれば dsh の Web UI に入れます。

ブラウザの左上に「保護されていません」と表示されますが、これは現在のプロトコルが HTTP で SSL 証明書がないためであり、dsh 自身の問題ではありません。本番展開ではドメイン + HTTPS を紐付ける必要があります(次のステップ)。

ブラウザが「保護されていません」と表示

ログイン後はローカルで dsh を使うのと変わらず、ワークスペースを選んでメッセージを送信します。

ステップ 4:ドメイン + HTTPS を紐付ける

本番環境ではドメイン + HTTPS を紐付けなければ正常に動作しません。http://server-IP で直接アクセスすると、ワークスペースを選ぶ際に以下のエラーが出ます:

ワークスペース選択時の crypto.randomUUID エラー

原因は crypto.randomUUID() がブラウザの Web API で、仕様上セキュアコンテキスト——すなわち https:// のページ、または localhost/127.0.0.1——でのみ利用可能と定められているためです。http://IP でのアクセスは非セキュアコンテキストとなり、この関数は undefined のため、セッション作成やワークスペース選択の瞬間にフロントエンドが crypto.randomUUID is not a function を投げます。

したがって、ドメイン + HTTPS の紐付けは任意の最適化ではなく必須です。

前提条件:まずドメイン管理コンソール(Tencent Cloud DNSPod、Alibaba Cloud Wanwang など)でドメインの A レコードを追加し、サーバーのパブリック IP に向けてください。数分待って反映されるのを待ちます。

先ほど続けた会話のまま(新しい会話を始める必要はありません)、宝塔 AI に以下を送信します:

text
Help me bind a domain to the dsh I just deployed and apply for an SSL certificate and configure it for me
1. The domain is your-domain, already resolved to this server
2. Verify that https://your-domain is accessible, tell me the result

宝塔 AI が自動的に Caddy の設定を変更し、ポートを開き、コンテナを再起動し、証明書を申請します。完了後 https://your-domain にアクセスすると、ブラウザの左上に鍵アイコンが表示され、「保護されていません」は消えます。

証明書は Let's Encrypt が発行し、Caddy が自動更新するため、手動管理は不要です。

継続的な運用

展開後の日常的な質問は宝塔 AI に直接聞けばよいです。例えば:

  • 「How to upgrade the dsh container to the latest version?」
  • 「How to view the dsh container's running logs?」
  • 「How to restart the dsh container?」
  • 「How to back up dsh's data?」
  • 「The dsh container is taking too much disk space, how to clean it up?」

AI が実際の環境に応じたコマンドを提示し実行してくれます。データはすべてプロジェクトディレクトリの ./data/ に保存されているため、コンテナ削除やイメージのアップグレードでデータは失われません。バックアップはこの ./data ディレクトリを丸ごとコピーするだけです。

コンテナ内にインストールできるツール

コンテナには node 22、pnpm、python3、git、curl、jq、ripgrep、make/gcc(ネイティブモジュールのコンパイル用)、Rust などの汎用ツールがプリインストールされています。Agent は x-cmd を使って自分でさらにツールをインストールすることもでき(root 不要)、インストールされたデータも ./data に入るため再起動後も残ります。

注意事項

  1. 現在バージョンの dsh にはマルチユーザー分離がない——全員が同じ Basic 認証でログインし、同じセッションと設定を共有します。チームで共有する際は機密情報を保存しないか、各人が独立したインスタンスを展開してください。
  2. compose に API Key をハードコードしない——.env ファイルを使い、プロジェクトで既に git ignore されています。
  3. Agent はコンテナ内で動く——見えるのはコンテナ内のファイルシステムであり、サーバーのものではありません。サーバー上のディレクトリを操作させたい場合は、docker-compose でボリュームマウントを追加し、ホストディレクトリをコンテナにマップする必要があります。
  4. パスワード変更.envDSH_AUTH_PASSWORD を編集し、docker compose up -d を実行すると、コンテナ起動時にハッシュが自動再生成されます。

どう選ぶか:早見表

ニーズ選ぶ形態理由
ブラウザを毎日開いて Agent と作業ローカル Web UI直感的な UI、軌跡が見え承認できる
スクリプト / CI / 定時タスクに組み込むHeadless CLI1 コマンド、実行して終了
Agent を自分のプログラムに組み込むPython SDK関数レベル呼び出し、セッションとイベントを制御できる
サーバーで長期稼働 / チーム共有Dockerコンテナ化展開、自動再起動、データマウント
バッチタスクでコンテキスト共有が必要Python SDKheadless は呼び出しごとに独立セッション、SDK は再利用可能

実用的なアドバイス:ほとんどの人はまずローカル Web UI から始めれば十分です。自動化が必要になったら headless を、プロダクトに組み込みたくなったら SDK を、サーバーで動かしたくなったら Docker を追加で。最初から 4 つとも整える必要はありません——dsh のうまみは必要なときにすぐ切り替えられることで、土台は同じ 1 セットです。

この章で学んだこと

以下の項目を自分で達成できれば合格です:

  • [ ] dsh には 4 つの展開形態(ローカル Web UI、Headless CLI、Python SDK、Docker)があることを知っている
  • [ ] 4 つの形態の起動方法と適用シーンを説明できる
  • [ ] ニーズに応じて適切な形態を選べる(dsh web しか知らない、ではなく)
  • [ ] Headless の呼び出しはそれぞれ独立したセッションであり、コンテキストを再利用するには SDK を使う必要があることを知っている
  • [ ] Python SDK には Node ランタイムが同梱されており、Web UI とは独立したインスタンスであることを知っている
  • [ ] deepseek-harness-web-docker プロジェクトを使って、Basic 認証付きでサーバーに dsh を展開できる
  • [ ] 展開した dsh にドメイン + HTTPS を紐付けられる(Caddy 自動証明書)
  • [ ] Docker 展開の注意事項を言える:マルチユーザー分離なし、.env にキー、コンテナ内のパス差異

Open Source · MIT · Community Driven