# チュートリアル：本番対応コンテナのデプロイ

> チュートリアル：本番対応コンテナのデプロイ -
> cURL、CLI、またはPulumiを使用して、ロックされたアーティファクト、importance、共有、監視を備えた本番環境のワークロードをデプロイします。

This Markdown file sits beside the HTML page at the same path (with a `.md` suffix). It summarizes the topic and lists links for tools and LLM context.

Companion generated at `2026-09-02T14:28:12.970421+00:00` (UTC).

## Primary page

- [チュートリアル：本番対応コンテナのデプロイ](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md): Full documentation for this topic (Markdown sidecar).

## Sections on this page

- [一目でわかるロックされたアーティファクトのワークロード](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#locked-artifact-workloads-at-a-glance): In-page section heading.
- [前提条件](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#prerequisites): In-page section heading.
- [ワークロードの作成](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#create-the-workload): In-page section heading.
- [アーティファクトのロック](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#lock-the-artifact): In-page section heading.
- [実行を待機する](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#wait-for-running): In-page section heading.
- [サービスの起動](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#invoke-the-service): In-page section heading.
- [ワークロードのガバナンス](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#govern-the-workload): In-page section heading.
- [観測](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#observe): In-page section heading.
- [サマリー](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#summary): In-page section heading.
- [次のステップ](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#next-steps): In-page section heading.

## Documentation content

> [!NOTE] プレミアム機能
> Workload APIはプレミアム機能です。 この機能を有効にする方法については、DataRobotの担当者または管理者にお問い合わせください。

完全なガバナンス（ロックされたアーティファクト、 `importance` 、共有、監視）を備えたコンテナ化されたAIサービスをデプロイします。ドラフトのワークロード（ [Hello, Workload](https://docs.datarobot.com/ja/docs/workload-api/get-started-workloads/tutorial-hello-world.html.md) を参照）とは異なり、これは長期にわたって実行される本番環境レベルのものです。

このチュートリアルでは、以下の機能を提供するFastAPIベースのエージェントサービス（ [otkachnlp/fastapi-server-example](https://hub.docker.com/r/otkachnlp/fastapi-server-example) 、DataRobotが公開したものではない一般に利用可能なサードパーティのイメージ）をデプロイします。

- OpenAI互換の /chat/completions 。DataRobot LLM Gatewayに接続されており、個別のLLMデプロイは必要ありません。
- LangGraphの /agent エンドポイント：ArXiv検索を行うReActエージェント。
- /healthz 、 /readyz 、および /health 。それぞれ生存（liveness）、準備完了（readiness）、詳細なステータスを提供します。

作業方法に一致するタブを選択してください。 cURL はREST APIを直接呼び出します。 CLI は同じ呼び出しを `dr workload` / `dr artifact` コマンドでラップします（サブコマンドが存在しない場合は `curl` にフォールバックします）。 Pulumi はロックされたアーティファクトとワークロードをコードとして宣言します。実行可能なノートブックを使用したい場合は、以下を選択してください。

[実行可能なノートブックとして表示](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/nb-tutorial-production-ready-container.html.md)

## 一目でわかるロックされたアーティファクトのワークロード

| プロパティ | 値 |
| --- | --- |
| Lifetime | 無期限。明示的に停止または削除されるまで持続します。 |
| Artifact mutability | ロックされると不変（Immutable）になります。 |
| importance | オプション。デフォルトは low です。本番環境用に明示的に設定します（critical、high、moderate、または low）。 |
| Workloads per artifact | 無制限。1つのロックされたアーティファクトが複数のワークロードをバックアップできます。 |
| 置換 | サポートされています。ロックされたものとロックされたもののみ置換します。 |

ドラフトとロックの完全な比較については、 [ワークロードの概念](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/workload-concepts.html.md#choose-draft-vs-locked) を参照してください。

## 前提条件

**cURL:**
curl
と
jq
が使用可能なターミナル。
DataRobot APIのエンドポイントとトークン：

```
export DATAROBOT_ENDPOINT="[https://app.datarobot.com/api/v2](https://app.datarobot.com/api/v2)"
export DATAROBOT_API_TOKEN="<your-api-token>" 
```

**CLI:**
認証済みの
DataRobot CLI
(
dr
)。ワークロードコマンドが有効になっていること（
export DATAROBOT_CLI_FEATURE_WORKLOAD=true
）。
CLIに対応するものがない呼び出し（共有とメタデータの更新）用の
curl
と
jq
。

**Pulumi:**
Pulumi CLI
および
DataRobot Pulumi プロバイダー
がインストールされ、スタックが設定されていること（
datarobot:endpoint
、
datarobot:apikey
）。
Pulumiがモデル化していない共有用の
curl
。
Pulumiを使用するタイミング
を参照してください。


次に、実行ごとに異なる値を設定します。

```
export MODEL="azure/gpt-5-nano-2025-08-07"
export RECIPIENT_USER_ID=""  # 共有するユーザー、グループ、または組織のID。スキップする場合は空白のままにします
```

## ワークロードの作成

アーティファクトは常に `draft` として作成されるため、cURLおよびCLIを使用する場合は、最初に `importance` を設定してワークロードを作成し、次のステップでアーティファクトをロックします。ロックにより、その背後にあるワークロードはロックされた（本番）ライフサイクルに切り替わります：無期限のライフタイム、不変のspec、ロックからロックへの置換の対象。

アーティファクトの `spec` はコンテナのトポロジ（イメージ、ポート、エントリポイント、環境変数、プローブ）など、デプロイ間でアーティファクトとともに移動するあらゆるものを定義します。レプリカ数、CPU/メモリー、およびオートスケーリングはデプロイ時の懸念事項であり、 `runtime.containerGroups[]` に存在します。エントリは、グループとコンテナの `name` によってアーティファクトと一致させられます。コンテナは、プラットフォームが解決し `{"source": "api-key"}` を介して自動的に注入するワークロードごとのAPIトークンを使用して、DataRobot LLM Gatewayに対して認証を行います。specには値が設定されていないため、トークンが `GET /artifacts/{id}` の応答に表示されることはありません。また、 `DATAROBOT_ENDPOINT` も [プラットフォームマネージド](https://docs.datarobot.com/ja/docs/workload-api/build-artifacts/artifacts-concepts.html.md#platform-managed-env-vars) であるため、設定する必要はありません。完全なリストについては、 [環境変数のタイプ](https://docs.datarobot.com/ja/docs/workload-api/build-artifacts/artifacts-concepts.html.md#environment-variable-types) を参照してください。

`readinessProbe.path` は `running` 状態への移行を制御します。プラットフォームはこのパスをポーリングし、2xxが返された場合にのみワークロードを `running` に移行させます。このチュートリアルでは、プローブのポイントを `/healthz` に設定します。これは、FastAPIプロセスが立ち上がるとすぐに2xxを返します。コンテナは、LLM接続を実行するより深い `/readyz` エンドポイントも公開しますが、readiness probeは `/healthz` を指したままにしてください：外部依存関係で `running` を制御すると、その依存関係に問題が発生するたびにワークロードのステータスがばたつきます。起動をブロックするのではなく、ディープチェックを監視およびランブックのための明示的なエンドポイントとして到達可能に保ちます。

**cURL:**
```
curl -s -X POST "${DATAROBOT_ENDPOINT}/workloads" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg model "$MODEL" \
    '{
      "name": "agent-service",
      "importance": "high",
      "artifact": {
        "name": "agent-service-artifact",
        "type": "service",
        "spec": {
          "containerGroups": [{
            "name": "default",
            "containers": [{
              "name": "agent",
              "imageUri": "otkachnlp/fastapi-server-example:latest",
              "port": 8080,
              "primary": true,
              "entrypoint": ["python", "server.py"],
              "environmentVars": [
                {"name": "MODEL", "value": $model},
                {"source": "api-key"}
              ],
              "readinessProbe": {"path": "/healthz", "port": 8080}
            }]
          }]
        }
      },
      "runtime": {
        "containerGroups": [{
          "name": "default",
          "replicaCount": 1,
          "containers": [{
            "name": "agent",
            "resourceAllocation": {"cpu": 1, "memory": "512MB"}
          }]
        }]
      }
    }'
  )" | tee /tmp/workload.json

export WORKLOAD_ID=$(jq -r '.id' /tmp/workload.json)
export ARTIFACT_ID=$(jq -r '.artifactId' /tmp/workload.json) 
```

**CLI:**
specをファイルに保存し、 `$MODEL` を代入します。

Save the spec to a file, substituting `$MODEL`:

```
cat > workload.yaml <<EOF
name: agent-service
importance: high
artifact:
  name: agent-service-artifact
  type: service
  spec:
    containerGroups:
      - name: default
        containers:
          - name: agent
            imageUri: otkachnlp/fastapi-server-example:latest
            port: 8080
            primary: true
            entrypoint: ["python", "server.py"]
            environmentVars:
              - name: MODEL
                value: $MODEL
              - source: api-key
            readinessProbe:
              path: "/healthz"
              port: 8080
runtime:
  containerGroups:
    - name: default
      replicaCount: 1
      containers:
        - name: agent
          resourceAllocation:
            cpu: 1
            memory: "512MB"
EOF

dr workload create --spec-file workload.yaml --output-format json | tee /tmp/workload.json
export WORKLOAD_ID=$(jq -r '.id' /tmp/workload.json)
export ARTIFACT_ID=$(jq -r '.artifactId' /tmp/workload.json) 
```

**Pulumi:**
`datarobot.Artifact` リソースは、 `pulumi up` の終了までに常に `locked` として解決されるため（ [Pulumiの使用時期](https://docs.datarobot.com/ja/docs/workload-api/workload-interfaces/workload-pulumi/index.html.md#when-to-use-pulumi) を参照）、このフローには個別のロック手順はありません。 `pulumi up` はアーティファクトをすでにロックされた状態で作成します。

```
import pulumi
import pulumi_datarobot as datarobot

artifact = datarobot.Artifact(
    "agent-service-artifact",
    name="agent-service-artifact",
    type="service",
    spec={
        "container_groups": [{
            "name": "default",
            "containers": [{
                "name": "agent",
                "image_uri": "otkachnlp/fastapi-server-example:latest",
                "port": 8080,
                "primary": True,
                "entrypoint": ["python", "server.py"],
                "environment_vars": [
                    {"name": "MODEL", "value": pulumi.Config().require("model")},
                    {"source": "api-key"},
                ],
                "readiness_probe": {"path": "/healthz", "port": 8080},
            }],
        }],
    },
)

workload = datarobot.Workload(
    "agent-service",
    name="agent-service",
    importance="high",
    artifact_id=artifact.artifact_id,
    runtime={
        "container_groups": [{
            "name": "default",
            "replica_count": 1,
            "containers": [{
                "name": "agent",
                "resource_allocation": {"cpu": 1, "memory": "512MB"},
            }],
        }],
    },
    opts=pulumi.ResourceOptions(replace_on_changes=["artifact_id"]),
)

pulumi.export("artifactId", artifact.artifact_id)
pulumi.export("workloadId", workload.id)
pulumi.export("endpoint", workload.endpoint) 
```

```
pulumi config set model "azure/gpt-5-nano-2025-08-07"
pulumi up 
```

`pulumi up` はワークロードが `running` になるまでブロックするため、戻ってきたら [サービスの呼び出し](https://docs.datarobot.com/ja/docs/workload-api/create-workloads/tutorial-production-ready-container.html.md#invoke-the-service) に進みます。


## アーティファクトのロック

アーティファクトを `draft` から `locked` に移行させます。このワークロードはドラフトアーティファクトをバックアップする唯一のワークロードであるため、ワークロードのライフサイクルはそれと一緒にロック済みに移行します。ロックは一方向です：ロックされたアーティファクトをドラフトに戻すことはできません。

**cURL:**
```
curl -X PATCH "${DATAROBOT_ENDPOINT}/artifacts/${ARTIFACT_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"status": "locked"}' 
```

`PATCH /artifacts/{artifact_id}` は、アーティファクトがまだ `draft` の状態である間のその他の更新の `name` 、 `description` 、および `spec` も受け入れます。

**CLI:**
```
dr artifact lock "$ARTIFACT_ID" 
```

**Pulumi:**
ここで実行することはありません。アーティファクトは前の手順で既にロックされた状態で作成されています。


## 実行を待機する

`running` に達するまで、ワークロードのステータスをポーリングします。想定される正常なパスの進行： `submitted` → `provisioning` → `launching` → `running` 。 `errored` は最終的な状態であり、ポーリングしてやり過ごす一時的な異常ではありません。これを確認した場合は、待機を続けるのではなく、停止して調査（ `dr workload get "$WORKLOAD_ID"` またはイベントエンドポイント）してください。

**cURL:**
```
curl -s "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" | jq -r '.status' 
```

**CLI:**
``` bash
dr workload status "$WORKLOAD_ID"

**Pulumi:**
ここで実行することはありません。 `pulumi up` はすでに `running` までブロックしています。


## サービスの起動

ワークロードから呼び出しURLを読み取り、それに対してアプリケーションルートを呼び出します。

**cURL:**
```
ENDPOINT=$(curl -s "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" | jq -r '.endpoint')

curl -X POST "${ENDPOINT}/chat/completions" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"model": "'"${MODEL}"'", "messages": [{"role": "user", "content": "Hello!"}]}' 
```

**CLI:**
```
ENDPOINT=$(dr workload endpoint "$WORKLOAD_ID")
curl -X POST "${ENDPOINT}/chat/completions" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"model": "'"${MODEL}"'", "messages": [{"role": "user", "content": "Hello!"}]}' 
```

**Pulumi:**
```
ENDPOINT=$(pulumi stack output endpoint)
curl -X POST "${ENDPOINT}/chat/completions" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"model": "'"${MODEL}"'", "messages": [{"role": "user", "content": "Hello!"}]}' 
```


サーバーには、ArXivをツールで呼び出すエージェントもあります。これをテストするには、 `{"query": "..."}` 本文を使用して `${ENDPOINT}/agent` に対して同じ方法で呼び出します。

## ワークロードのガバナンス

これが本番環境のワークロードになったので、重要度と共有を設定します。

**cURL:**
```
# Raise importance to critical
curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"importance": "critical"}'

# Share with another user, group, or organization (skip if RECIPIENT_USER_ID is blank)
if [ -n "$RECIPIENT_USER_ID" ]; then
  curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/sharedRoles" \
    -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
      "operation": "updateRoles",
      "roles": [{"id": "'"${RECIPIENT_USER_ID}"'", "role": "USER", "shareRecipientType": "user"}]
    }'
fi 
```

**CLI:**
重要度と共有の更新はREST APIを直接経由します。 `dr workload` は、作成、読み取り、ライフサイクル、およびログをカバーしており、メタデータや共有の更新はカバーしていません。

```
# Raise importance to critical
curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"importance": "critical"}'

# Share with another user, group, or organization (skip if RECIPIENT_USER_ID is blank)
if [ -n "$RECIPIENT_USER_ID" ]; then
  curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/sharedRoles" \
    -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
      "operation": "updateRoles",
      "roles": [{"id": "'"${RECIPIENT_USER_ID}"'", "role": "USER", "shareRecipientType": "user"}]
    }'
fi 
```

**Pulumi:**
`importance` は宣言的です。コード内で変更して再適用します。

```
workload = datarobot.Workload(
    "agent-service",
    name="agent-service",
    importance="critical",  # was "high"
    artifact_id=artifact.artifact_id,
    runtime={ ... },
    opts=pulumi.ResourceOptions(replace_on_changes=["artifact_id"]),
) 
```

```
pulumi up 
```

共有の設定はプロバイダー側では行われません。RESTまたはコンソールを使用して `/sharedRoles` を管理してください（ [Pulumiを使用するケース](https://docs.datarobot.com/ja/docs/workload-api/workload-interfaces/workload-pulumi/index.html.md#when-to-use-pulumi) を参照してください）。

```
if [ -n "$RECIPIENT_USER_ID" ]; then
  curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/sharedRoles" \
    -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
      "operation": "updateRoles",
      "roles": [{"id": "'"${RECIPIENT_USER_ID}"'", "role": "USER", "shareRecipientType": "user"}]
    }'
fi 
```


> [!NOTE] PATCHのスコープ
> `PATCH /workloads/{id}` は、 `name` 、 `description` 、および `importance` を受け入れます。ランタイムの変更（レプリカ、リソース）については、ローリング置換をトリガーする `PATCH /workloads/{id}/settings` を使用します。 [ランタイム設定](https://docs.datarobot.com/ja/docs/workload-api/operate-workloads/runtime-settings.html.md) を参照してください。

## 観測

ロックされたワークロードは、組織で設定されたテレメトリ保持期間とともに、完全な監視基盤を公開します。 [監視の概念：保持期間の概要](https://docs.datarobot.com/ja/docs/workload-api/monitor-workloads/monitoring-concepts.html.md#retention-summary) を参照してください。

| 機能 | エンドポイント |
| --- | --- |
| サービスの正常性、レイテンシー、エラー率 | GET /workloads/{id} （ワークロード上の計算フィールド） |
| ライフサイクルイベント（監査証跡） | GET /workloads/{id}/events |
| 集計リクエスト統計 | GET /workloads/{id}/stats |
| 指標ごとの時系列 | GET /workloads/{id}/stats/{metric_name} |
| レプリカごとのステータス | GET /workloads/{id}/protons/{proton_id}/statusDetails |

これらはすべて、ワークロードを作成するために使用したインターフェイスに関係なく、REST APIから直接読み取られます。 `dr workload logs` はコンテナのstdout/stderrをカバーしますが、これはこの表のシグナルとは別のシグナルです。

```
curl -s "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/events" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}"

curl -s "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/stats" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" 
```

## サマリー

このチュートリアルでは、以下を行いました：

- ドラフトアーティファクトにバックアップされ、 importance が設定されたワークロードを作成し、アーティファクトをロックして、本番環境（無期限）パスに移動させました。
- プラットフォームによって自動的に注入される、ワークロードごとのAPIトークンを使用して、DataRobot LLM Gatewayを呼び出すFastAPIエージェントサービスをデプロイしました。アーティファクトのspecに資格情報が表示されることはありませんでした。
- OpenAI互換の /chat/completions ルートとLangGraphの /agent ルートの両方を呼び出しました。
- importance を引き上げ、ワークロードを別のユーザー、グループ、または組織と共有しました。
- 監視サーフェスからイベントを読み取り、統計を集計しました。

## 次のステップ

| リソース | 説明 |
| --- | --- |
| Workload concepts | オブジェクトモデル、ライフサイクルの状態、およびドラフトとロック済みの決定についての詳細。 |
| Tutorial: Replace the artifact behind a running Workload | エンドポイントを削除せずに新しいコンテナバージョンをシップします。 |
| Deploy an open-weight model from Hugging Face | GPUコンピュートバンドルのサイズを設定し、Hugging Face Hubモデルを提供します。 |
| Instrument a Workload with OpenTelemetry (Python) | 各リクエストの内部にトレース、指標、およびログを追加します。 |
