Skip to main content

バックエンド サービスのセットアップ

サーバー側アプリケーション (API、Web バックエンド、マイクロサービス、バックグラウンド ワーカー) で Copilot SDK を実行します。 CLI は、バックエンド コードがネットワーク経由で接続するヘッドレス サーバーとして実行されます。

次の場合に最適です。 Web アプリ バックエンド、API サービス、内部ツール、CI/CD 統合、任意のサーバー側ワークロード。

どのように機能するのか

SDK が CLI 子プロセスを生成する代わりに、 ヘッドレス サーバー モードで CLI を個別に実行します。 バックエンドは、 Connection オプション (UriConnection) を使用して TCP 経由で接続します。

図: 説明されたプロセスを示すフローチャート。

主な特性:

  • CLI は永続的なサーバー プロセスとして実行されます (要求ごとに生成されません)
  • SDK は TCP 経由で接続します。CLI とアプリは異なるコンテナーで実行できます
  • 複数の SDK クライアントが 1 つの CLI サーバーを共有できる
  • 任意の認証方法 (GitHub トークン、env vars、BYOK) で動作します

アーキテクチャ: 自動管理と外部 CLI

図: 説明されたプロセスを示すフローチャート。

手順 1: ヘッドレス モードで CLI を開始する

CLI をバックグラウンド サーバーとして実行します。

# Start with a specific port
copilot --headless --port 4321

# Or let it pick a random port (prints the URL)
copilot --headless
# Output: Listening on http://localhost:52431

既定では、ヘッドレス サーバーはループバック (127.0.0.1) からの接続のみを受け入れます。 ネットワーク上の別のマシンなど、他のホストからの接続を受け入れるには、 --hostを使用して非ループバック アドレスにバインドします。

copilot --headless --host 0.0.0.0 --port 4321

運用環境の場合は、システム サービスまたはコンテナーで実行します。

メモ

Copilot CLI 用の公式の事前構築済み Docker イメージはありません。 GitHub releases から独自にビルドできます。

FROM debian:bookworm-slim
ARG COPILOT_VERSION=1.0.7
RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates wget \
    && ARCH=$(dpkg --print-architecture) \
    && case "${ARCH}" in amd64) COPILOT_ARCH="x64" ;; arm64) COPILOT_ARCH="arm64" ;; *) echo "Unsupported: ${ARCH}" && exit 1 ;; esac \
    && wget -q "https://github.com/github/copilot-cli/releases/download/v${COPILOT_VERSION}/copilot-linux-${COPILOT_ARCH}.tar.gz" \
    && tar -xzf "copilot-linux-${COPILOT_ARCH}.tar.gz" \
    && mv copilot /usr/local/bin/ \
    && rm "copilot-linux-${COPILOT_ARCH}.tar.gz" \
    && apt-get purge -y wget && apt-get autoremove -y && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["copilot"]
# Build the image
docker build --build-arg COPILOT_VERSION=1.0.7 -t copilot-cli:latest .

# For remote deployments (Kubernetes, ACI, etc.), push to your registry
docker tag copilot-cli:latest your-registry/copilot-cli:latest
docker push your-registry/copilot-cli:latest
# Docker — must bind to 0.0.0.0 so the container's published port is reachable
docker run -d --name copilot-cli \
    -p 4321:4321 \
    -e COPILOT_GITHUB_TOKEN="$TOKEN" \
    copilot-cli:latest \
    --headless --host 0.0.0.0 --port 4321

# systemd
[Service]
ExecStart=/usr/local/bin/copilot --headless --port 4321
Environment=COPILOT_GITHUB_TOKEN=your-token
Restart=always

手順 2: SDK を接続する

TypeScript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient({
    cliUrl: "localhost:4321",
});

const session = await client.createSession({
    sessionId: `user-${userId}-${Date.now()}`,
    model: "gpt-4.1",
});

const response = await session.sendAndWait({ prompt: req.body.message });
res.json({ content: response?.data.content });
Python
from copilot import CopilotClient, RuntimeConnection
from copilot.session import PermissionHandler

client = CopilotClient(
    connection=RuntimeConnection.for_uri("localhost:4321"),
)
await client.start()

session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-4.1", session_id=f"user-{user_id}-{int(time.time())}")

response = await session.send_and_wait(message)
Go
package main

import (
    "context"
    "fmt"
    "time"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    ctx := context.Background()
    userID := "user1"
    message := "Hello"

    client := copilot.NewClient(&copilot.ClientOptions{
        Connection: copilot.UriConnection{URL: "localhost:4321"},
    })
    client.Start(ctx)
    defer client.Stop()

    session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
        SessionID: fmt.Sprintf("user-%s-%d", userID, time.Now().Unix()),
        Model:     "gpt-4.1",
    })

    response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: message})
    _ = response
}
client := copilot.NewClient(&copilot.ClientOptions{
    Connection: copilot.UriConnection{URL: "localhost:4321"},
})
client.Start(ctx)
defer client.Stop()

session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
    SessionID: fmt.Sprintf("user-%s-%d", userID, time.Now().Unix()),
    Model:     "gpt-4.1",
})

response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: message})
.NET
using GitHub.Copilot;

var userId = "user1";
var message = "Hello";

var client = new CopilotClient(new CopilotClientOptions
{
    Connection = RuntimeConnection.ForUri("localhost:4321"),
});

await using var session = await client.CreateSessionAsync(new SessionConfig
{
    SessionId = $"user-{userId}-{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}",
    Model = "gpt-4.1",
});

var response = await session.SendAndWaitAsync(
    new MessageOptions { Prompt = message });
var client = new CopilotClient(new CopilotClientOptions
{
    Connection = RuntimeConnection.ForUri("localhost:4321"),
});

await using var session = await client.CreateSessionAsync(new SessionConfig
{
    SessionId = $"user-{userId}-{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}",
    Model = "gpt-4.1",
});

var response = await session.SendAndWaitAsync(
    new MessageOptions { Prompt = message });
Java
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;

var userId = "user1";
var message = "Hello!";

var client = new CopilotClient(new CopilotClientOptions()
    .setCliUrl("localhost:4321")
);

try {
    client.start().get();

    var session = client.createSession(new SessionConfig()
        .setSessionId(String.format("user-%s-%d", userId, System.currentTimeMillis() / 1000))
        .setModel("gpt-4.1")
        .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
    ).get();

    var response = session.sendAndWait(new MessageOptions()
        .setPrompt(message)).get();
} finally {
    client.stop().get();
}

バックエンド サービスの認証

環境変数トークン

最も簡単な方法は、CLI サーバーでトークンを設定することです。

図: 説明されたプロセスを示すフローチャート。

# All requests use this token
export COPILOT_GITHUB_TOKEN="gho_service_account_token"
copilot --headless --port 4321

ユーザーごとのトークン (OAuth)

セッションの作成時に個々のユーザー トークンを渡します。 完全なフローについては 、AUTOTITLE を参照してください。

// Your API receives user tokens from your auth layer
app.post("/chat", authMiddleware, async (req, res) => {
    const client = new CopilotClient({
        cliUrl: "localhost:4321",
        gitHubToken: req.user.githubToken,
        useLoggedInUser: false,
    });

    const session = await client.createSession({
        sessionId: `user-${req.user.id}-chat`,
        model: "gpt-4.1",
    });

    const response = await session.sendAndWait({
        prompt: req.body.message,
    });

    res.json({ content: response?.data.content });
});

BYOK (GitHub認証なし)

モデル プロバイダーには独自の API キーを使用します。 詳しくは、「BYOK (bring your own key)」をご覧ください。

const client = new CopilotClient({
    cliUrl: "localhost:4321",
});

const session = await client.createSession({
    model: "gpt-4.1",
    provider: {
        type: "openai",
        baseUrl: "https://api.openai.com/v1",
        apiKey: process.env.OPENAI_API_KEY,
    },
});

一般的なバックエンド パターン

Express を使用した Web API

図: 説明されたプロセスを示すフローチャート。

import express from "express";
import { CopilotClient } from "@github/copilot-sdk";

const app = express();
app.use(express.json());

// Single shared CLI connection
const client = new CopilotClient({
    cliUrl: process.env.CLI_URL || "localhost:4321",
});

app.post("/api/chat", async (req, res) => {
    const { sessionId, message } = req.body;

    // Create or resume session
    let session;
    try {
        session = await client.resumeSession(sessionId);
    } catch {
        session = await client.createSession({
            sessionId,
            model: "gpt-4.1",
        });
    }

    const response = await session.sendAndWait({ prompt: message });
    res.json({
        sessionId,
        content: response?.data.content,
    });
});

app.listen(3000);

バックグラウンド ワーカー

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient({
    cliUrl: process.env.CLI_URL || "localhost:4321",
});

// Process jobs from a queue
async function processJob(job: Job) {
    const session = await client.createSession({
        sessionId: `job-${job.id}`,
        model: "gpt-4.1",
    });

    const response = await session.sendAndWait({
        prompt: job.prompt,
    });

    await saveResult(job.id, response?.data.content);
    await session.disconnect();  // Clean up after job completes
}

Docker compose のデプロイ

version: "3.8"

services:
  copilot-cli:
    image: copilot-cli:latest  # See "Step 1" above for how to build this image
    command: ["--headless", "--host", "0.0.0.0", "--port", "4321"]
    environment:
      - COPILOT_GITHUB_TOKEN=${COPILOT_GITHUB_TOKEN}
    ports:
      - "4321:4321"
    restart: always
    volumes:
      - session-data:/root/.copilot/session-state

  api:
    build: .
    environment:
      - CLI_URL=copilot-cli:4321
    depends_on:
      - copilot-cli
    ports:
      - "3000:3000"

volumes:
  session-data:

図: 説明されたプロセスを示すフローチャート。

健康診断

CLI サーバーの正常性を監視します。

// Periodic health check
async function checkCLIHealth(): Promise<boolean> {
    try {
        const status = await client.getStatus();
        return status !== undefined;
    } catch {
        return false;
    }
}

セッションのクリーンアップ

バックエンド サービスは、リソース リークを回避するために、セッションを積極的にクリーンアップする必要があります。

// Clean up expired sessions periodically
async function cleanupSessions(maxAgeMs: number) {
    const sessions = await client.listSessions();
    const now = Date.now();

    for (const session of sessions) {
        const age = now - new Date(session.createdAt).getTime();
        if (age > maxAgeMs) {
            await client.deleteSession(session.sessionId);
        }
    }
}

// Run every hour
setInterval(() => cleanupSessions(24 * 60 * 60 * 1000), 60 * 60 * 1000);

制限事項

制限事項詳細情報
単一 CLI サーバー = 単一障害点HA パターンについては スケーリングとマルチテナント を参照してください
SDK と CLI の間に組み込みの認証がないネットワーク パス (同じホスト、VPC など) をセキュリティで保護する
ローカル ディスク上のセッション状態コンテナーの再起動用に永続ストレージをマウントする
30 分間の無操作タイムアウトアクティビティのないセッションは自動クリーンアップされます

次に進むタイミング

必要次のガイドへ
複数の CLI サーバー/高可用性
スケーリングとマルチテナント
ユーザー向け GitHub アカウント認証
GitHub OAuth のセットアップ
独自のモデル キー
BYOK (bring your own key)

次のステップ