mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-14 04:59:28 +08:00
* feat(sandbox): default to official Alpine sandbox image default_sandbox_image() now returns docker.io/library/alpine:3.22, a generic version-qualified official image, so a fresh install no longer depends on the community sandbox image catalog. All compute drivers (docker, podman, kubernetes, vm) inherit this fallback. Part of #3116. Signed-off-by: Akram Signed-off-by: Akram <akram.benaissi@gmail.com> * feat(deploy): default deployment configs to the official Alpine sandbox image Update the shared gateway default_image, Helm chart values, the standalone Kubernetes manifest, and the dev gateway task scripts to use docker.io/library/alpine:3.22 instead of the community base image, consistent with default_sandbox_image(). GPU e2e image-build base is left unchanged (CUDA needs a glibc base). Part of #3116. Signed-off-by: Akram Signed-off-by: Akram <akram.benaissi@gmail.com> * feat(driver): default to numeric non-root identity for USER-less images With the default sandbox image now Alpine, images that declare no OCI USER must start instead of being rejected. When the image declares no USER and the policy requests none, the Podman and Docker drivers now supply a numeric non-root identity (DEFAULT_SANDBOX_UID/GID = 1000) instead of rejecting, matching the numeric-identity behavior of the Kubernetes and VM drivers. The supervisor's resolved-identity path runs the sandbox as a synthesized non-root account without the account existing in the image. Images that declare a USER keep the OCI resolution path unchanged. Part of #3116. Signed-off-by: Akram <akram.benaissi@gmail.com> Signed-off-by: Evan Lezar <elezar@nvidia.com> * test(conformance): use Alpine workload image Signed-off-by: Evan Lezar <elezar@nvidia.com> * refactor(policy): drop community image /app path from default policy The restrictive default policy granted read-only access to /app, a directory that only existed in the community base image. A generic Alpine default has no /app, so remove it. Landlock best-effort already ignores absent paths; this just stops advertising a community-specific layout in the default. Part of #3116. Signed-off-by: Akram Signed-off-by: Akram <akram.benaissi@gmail.com> * docs(config): document Alpine default images Signed-off-by: Evan Lezar <elezar@nvidia.com> * fix(podman): report early sandbox termination Signed-off-by: Evan Lezar <elezar@nvidia.com> * fix(podman): initialize rootless workspace ownership Signed-off-by: Evan Lezar <elezar@nvidia.com> * fix(sandbox): qualify NVIDIA Ubuntu default Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(podman): initialize rootful default workspace Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(sftp): add native sandbox adapter Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(sftp): gate runtime helper support to Linux Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(sftp): support standard OpenSSH file operations Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(sftp): harden rename and special file handling Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(runtime): remove community image dependencies Signed-off-by: Drew Newberry <anewberry@nvidia.com> * test(e2e): build provider readiness tool fixture Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(e2e): use a dedicated Noble fixture for Docker tests Signed-off-by: Evan Lezar <elezar@nvidia.com> --------- Signed-off-by: Akram Signed-off-by: Akram <akram.benaissi@gmail.com> Signed-off-by: Evan Lezar <elezar@nvidia.com> Signed-off-by: Drew Newberry <anewberry@nvidia.com> Co-authored-by: Evan Lezar <elezar@nvidia.com> Co-authored-by: Drew Newberry <anewberry@nvidia.com>
208 lines
6.1 KiB
Plaintext
208 lines
6.1 KiB
Plaintext
---
|
|
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
title: "Run the Gateway with Docker Compose"
|
|
sidebar-title: "Docker Compose Setup"
|
|
slug: "get-started/tutorials/docker-compose"
|
|
description: "Run the OpenShell gateway as a Docker Compose service and create agent sandboxes."
|
|
keywords: "Generative AI, Docker Compose, Gateway, Sandbox, OpenClaw, Docker, Installation"
|
|
---
|
|
|
|
This tutorial shows how to run the OpenShell gateway as a Docker Compose service on a Linux host or on a machine running Docker Desktop (Windows or macOS).
|
|
|
|
After completing this tutorial you have:
|
|
|
|
- An OpenShell gateway running as a Compose service.
|
|
- The `openshell` CLI registered against that gateway.
|
|
- An AI provider configured with your API key.
|
|
- A running agent sandbox.
|
|
|
|
## Prerequisites
|
|
|
|
- Docker Desktop (Windows or macOS) or Docker Engine with the Compose plugin (Linux).
|
|
- The `openshell` CLI installed on your workstation. See [Install the CLI](#install-the-cli) below.
|
|
- Port 8080 available on the host.
|
|
|
|
## Compose files
|
|
|
|
The Compose configuration lives at [`deploy/docker/`](https://github.com/NVIDIA/OpenShell/tree/main/deploy/docker) in the repository.
|
|
|
|
| File | Purpose |
|
|
|---|---|
|
|
| `docker-compose.yml` | Gateway service, volumes, and environment variables |
|
|
| `gateway.toml` | TOML reference for release builds with config-file support |
|
|
|
|
## Port note
|
|
|
|
The Docker supervisor uses host networking and connects to the gateway through
|
|
the host's loopback port. The gateway listens on port 8080 inside the container,
|
|
so **port 8080 must be published at the same number on the Docker host**.
|
|
Publishing it as a different host port (for example `18080:8080`) leaves the
|
|
supervisor unable to establish its gateway session and the sandbox remains in
|
|
the `Provisioning` phase.
|
|
|
|
If port 8080 is taken, change `OPENSHELL_SERVER_PORT` and update the port mapping to `<your-port>:8080`, then set `OPENSHELL_PORT=<your-port>` in an `.env` file.
|
|
|
|
## Data directory
|
|
|
|
The gateway extracts the `openshell-sandbox` supervisor binary from `ghcr.io/nvidia/openshell/supervisor:latest` on first start and caches it at:
|
|
|
|
```text
|
|
/var/lib/openshell/openshell/docker-supervisor/<digest>/openshell-sandbox
|
|
```
|
|
|
|
This path is used as a bind-mount source when Docker creates sandbox containers.
|
|
Docker resolves bind-mount sources against the **host filesystem**, not the container filesystem, so the data directory must be bind-mounted at the **same absolute path** in both the host and the container.
|
|
|
|
The Compose file uses `/var/lib/openshell` for this purpose and sets `create_host_path: true` so Docker creates it on first run.
|
|
|
|
## Start the gateway
|
|
|
|
```shell
|
|
cd deploy/docker
|
|
docker compose up -d
|
|
```
|
|
|
|
Verify the gateway is healthy:
|
|
|
|
```shell
|
|
curl -sf http://localhost:8080/healthz
|
|
```
|
|
|
|
## Install the CLI
|
|
|
|
**Binary (recommended — macOS / Linux / WSL):**
|
|
|
|
```shell
|
|
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh
|
|
```
|
|
|
|
<Note>
|
|
The `openshell` package on PyPI provides the Python SDK only and does not install the CLI.
|
|
|
|
On Windows without WSL, install the CLI inside a WSL 2 distribution (for example AlmaLinux or Ubuntu) and run all `openshell` commands from that distribution.
|
|
</Note>
|
|
|
|
## Register the gateway
|
|
|
|
Run this once after the gateway starts:
|
|
|
|
```shell
|
|
openshell gateway add http://localhost:8080 --name openshell-docker
|
|
```
|
|
|
|
Verify the connection:
|
|
|
|
```shell
|
|
openshell status
|
|
```
|
|
|
|
The output should show `Status: Connected`.
|
|
|
|
## Configure an AI provider
|
|
|
|
Import the provider profile for the service you use, then set your API key as an
|
|
environment variable and create a provider. A gateway serves only the profiles
|
|
you imported:
|
|
|
|
```shell
|
|
curl -LsSfO https://raw.githubusercontent.com/NVIDIA/OpenShell/main/providers/anthropic.yaml
|
|
openshell provider profile import -f anthropic.yaml --global
|
|
```
|
|
|
|
Use `openai.yaml` for the OpenAI tab below.
|
|
|
|
<Tabs>
|
|
<Tab title="Anthropic (Claude)">
|
|
|
|
```shell
|
|
ANTHROPIC_API_KEY=sk-ant-... \
|
|
openshell provider create --name anthropic --type anthropic --from-existing
|
|
```
|
|
|
|
</Tab>
|
|
<Tab title="OpenAI">
|
|
|
|
```shell
|
|
OPENAI_API_KEY=sk-... \
|
|
openshell provider create --name openai --type openai --from-existing
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
Confirm the provider was stored:
|
|
|
|
```shell
|
|
openshell provider list
|
|
```
|
|
|
|
## Pre-pull workload images (optional)
|
|
|
|
Workload images are pulled automatically on first use. Pre-pull the default
|
|
Ubuntu workload or your own agent image to avoid waiting during sandbox
|
|
creation:
|
|
|
|
```shell
|
|
docker pull nvcr.io/nvidia/base/ubuntu:24.04
|
|
docker pull registry.example.com/your-org/agent:latest
|
|
```
|
|
|
|
## Create a Sandbox
|
|
|
|
Create a minimal Ubuntu sandbox:
|
|
|
|
```shell
|
|
openshell sandbox create --name compose-demo
|
|
```
|
|
|
|
To run an agent, use an explicit OCI image that contains it:
|
|
|
|
```shell
|
|
openshell sandbox create \
|
|
--from registry.example.com/your-org/agent:latest \
|
|
--provider <provider-name> \
|
|
-- my-agent
|
|
```
|
|
|
|
OpenClaw runs through [NemoClaw](https://github.com/NVIDIA/NemoClaw), which
|
|
manages its sandbox image, model provider, and security policies. Follow the
|
|
[NemoClaw Quickstart](https://docs.nvidia.com/nemoclaw/latest/get-started/quickstart/)
|
|
for that workflow.
|
|
|
|
Wait for the phase to change from `Provisioning` to `Ready`:
|
|
|
|
```shell
|
|
openshell sandbox list
|
|
```
|
|
|
|
Then connect:
|
|
|
|
```shell
|
|
openshell sandbox connect <sandbox-name>
|
|
```
|
|
|
|
## Manage the gateway
|
|
|
|
| Command | Purpose |
|
|
|---|---|
|
|
| `docker compose up -d` | Start or restart the gateway |
|
|
| `docker compose down` | Stop the gateway and remove the container |
|
|
| `docker compose logs -f` | Tail gateway logs |
|
|
| `docker compose pull` | Pull a new gateway image version |
|
|
|
|
## Linux notes
|
|
|
|
On Linux, `host.docker.internal` and `host.openshell.internal` are not automatically resolvable from containers. Add the following under the `gateway` service in `docker-compose.yml`:
|
|
|
|
```yaml
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
- "host.openshell.internal:host-gateway"
|
|
```
|
|
|
|
## Next steps
|
|
|
|
- [First Network Policy](/get-started/tutorials/first-network-policy) — apply L7 policies to your sandbox.
|
|
- [GitHub Push Access](/get-started/tutorials/github-sandbox) — grant a sandbox scoped GitHub access.
|