Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions .image-garden.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Ubuntu 24.04 instances

# snapd-no-docker: snapd only, no docker.
# install.sh chooses the "snap" install path.
$(eval $(call define-instance,ubuntu-cloud-24.04,snapd-no-docker))
define UBUNTU_24.04@snapd-no-docker_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- snap wait system seed.loaded
- snap install snapd
packages:
- snapd
endef

# snapd-classic-docker: snapd + native docker (docker.io deb package).
# install.sh chooses the "classic" install path because native docker is detected.
$(eval $(call define-instance,ubuntu-cloud-24.04,snapd-classic-docker))
define UBUNTU_24.04@snapd-classic-docker_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- snap wait system seed.loaded
- snap install snapd
packages:
- snapd
- docker.io
endef

# no-snapd: snapd removed, docker.io installed.
# install.sh chooses the "classic" install path because snapd is absent.
$(eval $(call define-instance,ubuntu-cloud-24.04,no-snapd))
define UBUNTU_24.04@no-snapd_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- apt-get purge -y snapd
packages:
- docker.io
endef

# Ubuntu 26.04 instances

# snapd-no-docker: snapd only, no docker.
# install.sh chooses the "snap" install path.
$(eval $(call define-instance,ubuntu-cloud-26.04,snapd-no-docker))
define UBUNTU_26.04@snapd-no-docker_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- snap wait system seed.loaded
- snap install snapd
packages:
- snapd
endef

# snapd-classic-docker: snapd + native docker (docker.io deb package).
# install.sh chooses the "classic" install path because native docker is detected.
$(eval $(call define-instance,ubuntu-cloud-26.04,snapd-classic-docker))
define UBUNTU_26.04@snapd-classic-docker_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- snap wait system seed.loaded
- snap install snapd
packages:
- snapd
- docker.io
endef

# no-snapd: snapd removed, docker.io installed.
# install.sh chooses the "classic" install path because snapd is absent.
$(eval $(call define-instance,ubuntu-cloud-26.04,no-snapd))
define UBUNTU_26.04@no-snapd_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- apt-get purge -y snapd
packages:
- docker.io
endef

# Debian 13 instances

# snapd-no-docker: snapd only, no docker.
# install.sh chooses the "snap" install path.
$(eval $(call define-instance,debian-cloud-13,snapd-no-docker))
define DEBIAN_13@snapd-no-docker_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- snap wait system seed.loaded
- snap install snapd
packages:
- snapd
endef

# snapd-classic-docker: snapd + native docker (docker.io deb package).
# install.sh chooses the "classic" install path because native docker is detected.
$(eval $(call define-instance,debian-cloud-13,snapd-classic-docker))
define DEBIAN_13@snapd-classic-docker_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- snap wait system seed.loaded
- snap install snapd
packages:
- snapd
- docker.io
endef

# no-snapd: snapd removed, docker.io installed.
# install.sh chooses the "classic" install path because snapd is absent.
$(eval $(call define-instance,debian-cloud-13,no-snapd))
define DEBIAN_13@no-snapd_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- apt-get purge -y snapd
packages:
- docker.io
endef

# Fedora 44 instances

# snapd-no-docker: snapd only, no docker.
# install.sh chooses the "snap" install path.
$(eval $(call define-instance,fedora-cloud-44,snapd-no-docker))
define FEDORA_44@snapd-no-docker_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- systemctl enable --now snapd.socket
- snap wait system seed.loaded
packages:
- snapd
endef

# snapd-docker: snapd + native docker (docker rpm package).
# install.sh chooses the "classic" install path because native docker is detected.
$(eval $(call define-instance,fedora-cloud-44,snapd-docker))
define FEDORA_44@snapd-docker_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- systemctl enable --now snapd.socket
- snap wait system seed.loaded
packages:
- snapd
- docker
endef

# no-snapd: just docker, no snapd.
# install.sh chooses the "classic" install path because snapd is absent.
$(eval $(call define-instance,fedora-cloud-44,no-snapd))
define FEDORA_44@no-snapd_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
packages:
- docker
endef
11 changes: 11 additions & 0 deletions .image-garden/.gitignore

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simply ignore the entire .image-garden/ folder from the root gitignore?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

*.img
*.iso
*.lock
*.log
*.meta-data
*.qcow2
*.run
*.user-data
83 changes: 74 additions & 9 deletions docs/about/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ Install OpenShell with a single command:
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh
```

The script detects your operating system and installs the OpenShell CLI and gateway with your native package manager. It then starts the local gateway server so you can begin creating sandboxes.
The script detects your operating system and installs the OpenShell CLI and
gateway. On Linux, the Snap path is preferred when `snapd` is available;
otherwise the script uses the native DEB or RPM package. The gateway then
starts automatically so you can begin creating sandboxes.

You can also download release artifacts directly from the [OpenShell GitHub Releases](https://github.com/NVIDIA/OpenShell/releases) page.

Expand Down Expand Up @@ -51,6 +54,13 @@ brew services restart openshell

## Linux

On distributions that ship with `snapd`, the install script uses the Snap path
described below, provided no non-snap Docker is detected. If a native Docker
package is present, the installer silently falls back to DEB or RPM. On hosts
without `snapd` (or with
`OPENSHELL_INSTALL_METHOD=classic` set), the script falls back to the classic
Comment on lines +58 to +61

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
described below, provided no non-snap Docker is detected. If a native Docker
package is present, the installer silently falls back to DEB or RPM. On hosts
without `snapd` (or with
`OPENSHELL_INSTALL_METHOD=classic` set), the script falls back to the classic
described below, unless one of the following is true:
- a native (non-snap) Docker package is present (the `openshell` snap requires the `docker` snap, for now)
- `snapd` is not present
- `OPENSHELL_INSTALL_METHOD=classic` is set in the environment

package manager.

On Fedora and RHEL, the install script uses RPM packages. The RPM installs the `openshell` CLI, the `openshell-gateway` daemon, and a systemd user service.

On Debian and Ubuntu, the install script uses a Debian package. The Debian package installs the `openshell` CLI, the `openshell-gateway` daemon, VM sandbox support, and a systemd user service.
Expand All @@ -77,10 +87,15 @@ sudo loginctl enable-linger $USER

## Snap

Install the OpenShell snap from the Snap Store:
On Linux distributions that ship with `snapd`, the install script installs
OpenShell from the Snap Store. The OpenShell snap bundles the CLI, the terminal
UI, and a managed gateway daemon. snapd handles upgrades and rollback; the

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
UI, and a managed gateway daemon. snapd handles upgrades and rollback; the
UI, and a managed gateway daemon. `snapd` handles upgrades and rollback; the

gateway runs as a system service inside the snap.

You can also install the snap directly:

```shell
sudo snap install openshell --classic
sudo snap install openshell

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the docker snap is currently required, should we include this here as well?

Suggested change
sudo snap install openshell
sudo snap install docker
sudo snap install openshell

```

The snap defines two apps: the `openshell` CLI and the `openshell.gateway`
Expand All @@ -89,19 +104,35 @@ stores its database at `$SNAP_COMMON/gateway.db` (typically
`/var/snap/openshell/common/gateway.db`). Create `$SNAP_COMMON/gateway.toml`
when you need to override gateway settings.

The snap requires the Docker snap. `default-provider: docker` on the OpenShell
snap installs the Docker snap automatically on first use, but you can install
it up front with:
Comment on lines +107 to +109

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The snap requires the Docker snap. `default-provider: docker` on the OpenShell
snap installs the Docker snap automatically on first use, but you can install
it up front with:
The OpenShell snap requires the Docker snap, which you can install with:


```shell
sudo snap install docker
```

### Snap store installs

When installing from the Snap Store, snapd automatically connects the `home`,
`network`, `network-bind`, and `ssh-keys` plugs. The `docker` plug still
requires manual connection:
When installing from the Snap Store, snapd automatically connects the `home`
and `network` plugs. The remaining plugs — `network-bind`, `ssh-keys`,
`log-observe`, `system-observe`, and `docker` — still require manual connection:
Comment on lines +117 to +119

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe network-bind auto-connects as well

Suggested change
When installing from the Snap Store, snapd automatically connects the `home`
and `network` plugs. The remaining plugs — `network-bind`, `ssh-keys`,
`log-observe`, `system-observe`, and `docker` — still require manual connection:
When installing from the Snap Store, snapd automatically connects the `home`,
`network`, and `network-bind` plugs. The remaining plugs — `docker`,
`log-observe`, `ssh-keys`, and `system-observe` — still require manual
connection:


```shell
sudo snap connect openshell:docker docker:docker-daemon
sudo snap connect openshell:log-observe
sudo snap connect openshell:ssh-keys
sudo snap connect openshell:system-observe
```

The snap declares `default-provider: docker` on the Docker plug so snapd will
offer to install the Docker snap, but the connection itself must be made
manually.
The Docker slot is the Docker snap's `docker-daemon` slot; OpenShell does not
work with a host-installed Docker Engine. The snap declares `default-provider:
docker` on the Docker plug so snapd will offer to install the Docker snap, but
the connection itself must be made manually. The installer runs these
connections for you on Snap installs; run them by hand if you install the snap
manually. The installer is best-effort: if a connect fails (for example because
the Docker snap is not yet running), the snap still installs and the installer
prints a warning.
Comment on lines +128 to +135

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no default-provider anymore, and I think the wording can be simplified a bit.

Suggested change
The Docker slot is the Docker snap's `docker-daemon` slot; OpenShell does not
work with a host-installed Docker Engine. The snap declares `default-provider:
docker` on the Docker plug so snapd will offer to install the Docker snap, but
the connection itself must be made manually. The installer runs these
connections for you on Snap installs; run them by hand if you install the snap
manually. The installer is best-effort: if a connect fails (for example because
the Docker snap is not yet running), the snap still installs and the installer
prints a warning.
The `docker` interface is used to connect the `openshell` snap's `docker` plug
to the `docker` snap's `docker-daemon` slot; the `openshell` snap does not yet
work with a host-installed Docker Engine. The installer runs this and the other
interface connections for you after installing the `openshell` snap; run them
by hand if you install the snap manually. The installer is best-effort: if a
connect fails (for example because the `docker` snap is not yet running), the
snap still installs and the installer prints a warning.


### Locally built snap packages

Expand All @@ -123,6 +154,26 @@ to read logs and inspect system processes. The `docker` plug requires the
`docker:docker-daemon` slot from the Docker snap and does not work with
system-installed Docker.

### Verify the gateway

The snap-managed gateway service is `openshell.gateway`. Inspect it with:

```shell
snap services openshell
snap logs -n 100 openshell.gateway
```

Register the gateway with the CLI:

```shell
openshell gateway add http://127.0.0.1:17670 --local --name openshell
openshell status
```

The gateway listens on `http://127.0.0.1:17670` and stores its state under
`/var/snap/openshell/common/`. Override gateway settings by creating
`/var/snap/openshell/common/gateway.toml`.

### Gateway service

The gateway runs as a snap daemon with `refresh-mode: endure`, meaning snapd
Expand All @@ -134,6 +185,20 @@ a snap refresh when you need the updated binary:
sudo systemctl restart snap.openshell.gateway
```

### When to choose Snap

Use Snap when `snapd` is available and no native Docker Engine is installed,
and you want atomic upgrades and rollback, a single self-contained install that
bundles the Docker provider, or a desktop launcher that surfaces the OpenShell
terminal UI in the application menu.
Comment on lines +190 to +193

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docker is not specified as a default-provider anymore, so we should remove that language here.

Suggested change
Use Snap when `snapd` is available and no native Docker Engine is installed,
and you want atomic upgrades and rollback, a single self-contained install that
bundles the Docker provider, or a desktop launcher that surfaces the OpenShell
terminal UI in the application menu.
Use the `openshell` snap when `snapd` is available and no native Docker Engine
is installed, and you want atomic upgrades and rollback, a single self-contained
and sandboxed install, or a desktop launcher that surfaces the OpenShell
terminal UI in the application menu.


Use DEB or RPM when `snapd` is unavailable or when you already run Docker Engine
from a non-snap source. The installer falls back to DEB or RPM on hosts with
native Docker.
Comment on lines +195 to +197

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Use DEB or RPM when `snapd` is unavailable or when you already run Docker Engine
from a non-snap source. The installer falls back to DEB or RPM on hosts with
native Docker.
Install via the `.deb` or `.rpm` when `snapd` is unavailable or when you already
run Docker from a non-snap source. The installer falls back to these methods on
hosts with native Docker.


Set `OPENSHELL_INSTALL_METHOD=classic` to force the classic package on hosts
that also have `snapd` available.
Comment on lines +199 to +200

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of OPENSHELL_INSTALL_METHOD=classic, how about we enumerate all the valid installation methods?

Eg OPENSHELL_INSTALL_METHOD=apt|homebrew|rpm|snap


## Kubernetes

Kubernetes deployments use the OpenShell Helm chart. For step-by-step installation, refer to [Kubernetes Setup](/kubernetes/setup). For chart values and packaging details, refer to the [Helm chart README](https://github.com/NVIDIA/OpenShell/blob/main/deploy/helm/openshell/README.md).
Expand Down
Loading
Loading