# Container by Aerovato Research: persistent Linux workspaces for coding agents

> A TypeScript CLI that gives each project its own Docker or Podman environment with coding harnesses preinstalled. The isolation is real, the persistence is real, and the security section says plainly that it does not make an agent trusted.

**aerovato/container** — Persistent Linux workspaces for agentic development.

- Repository: https://github.com/aerovato/container
- Website: https://container.aerovato.com
- Stars: 349 · Forks: 33
- Language: TypeScript
- License: BSD-3-Clause
- Published: 2026-09-14 · Updated: 2026-09-14 · Language: en
- Canonical page: https://hysenlabs.com/projects/aerovato-container

## The problem Container solves for agentic development

Running a coding agent directly on a laptop means the agent sees everything the user account sees. Home directory, SSH keys, browser profiles, every other repository. Installing harnesses system-wide also means version conflicts between projects: one repository wants a Node version the other cannot use. Container's answer is one environment per project, created from a shared image that already contains the coding harnesses and development tools, with the project mounted at /root/<project-name> and everything installed inside persisting between sessions. The README describes the target plainly: agents are isolated to that project with no access to the rest of the system. The audience is developers who drive Claude Code, Codex, opencode, Copilot and similar harnesses from a terminal and want the same Linux environment whether the host is Windows, macOS or Linux. It is a local tool with no account requirement, and the repository topics place it squarely in the vibe-coding toolchain rather than in CI or server infrastructure.

## How the CLI, the shared image and the user layer fit together

The architecture visible in the repository is a thin TypeScript CLI over a Docker or Podman runtime. package.json points bin.container at dist/js/main.js, so the published npm package is the CLI itself; the container work happens through the runtime on the host. During onboarding the CLI asks for coding harnesses, development tools, runtime and mounts, then builds an initial image. That image is layered. The README lists separate rebuild targets (container build, container build tools, container build harness, container build user), which implies a base layer, a tools layer, a harness layer and a user layer that stack on top of each other. The user layer is a Dockerfile at ~/.code-container/Dockerfile.User, so anything you add there is ordinary Dockerfile syntax. Settings live in two places: container settings for common choices, and ~/.code-container/settings.json for runtime flags, mounts and base-image settings. Multiple terminals can enter the same container, which means the workspace behaves like a shared machine rather than a one-shot process. The host-side skill exists because agents inside a managed container cannot reach Container's host configuration, so setup by an agent has to run outside the container.

## Installing Container and opening a first workspace

The README lists Docker or Podman as the only prerequisite, on Windows, macOS or Linux. On macOS and Linux the install is a shell script piped to sh; on Windows it is a PowerShell one-liner. The npm route installs the same CLI globally.

```bash
curl -fsSL https://container.aerovato.com/install.sh | sh
```

```bash
npm install -g @aerovato/container
```

After install, the guided onboarding flow asks for harnesses, tools, runtime and mounts, and then builds the initial image. Expect the first build to take a while; the README treats accepting it as part of onboarding.

```bash
container init
```

From there, cd into a project and run the bare command. The project appears at /root/<project-name> inside the container, and the README gives opencode and npm install as examples of what to do next.

```bash
cd /path/to/project
container
```

```bash
opencode
npm install <package>
```

To confirm the workspace was created, run container list. To pass runtime flags such as a published port, the README shows the double-dash form: container run /path -- -p 8080:80.

## What persists, and what the read-write mount actually means

Persistence is the feature the name promises and the one most likely to be misread. The README says the container and anything installed inside it persist between sessions, including packages and configuration. That is state inside the container image or its writable layer, not a snapshot of your project. The project itself is mounted read-write, and the README states it can be changed or deleted. An agent that runs a destructive command inside /root/<project-name> is operating on your working tree. The security section is unusually direct about the rest: enabled configurations and optional credentials may be available inside the container, containers retain network access, and Container does not protect against prompt injection or agent misalignment. So the boundary Container draws is between the project and the rest of the host, not between the agent and the project. The README's own guidance follows from that: keep important work under version control and only mount resources the agent needs. If your threat model requires the agent to be unable to modify the repository, this tool is pointed the wrong way by design.

## Customizing the user layer and rebuilding it

Beyond the guided settings, customization goes through the user Dockerfile. The README shows adding packages and setup commands to ~/.code-container/Dockerfile.User, then rebuilding that layer specifically.

```bash
container build user
```

The four build targets matter for cost. container build rebuilds the shared image, while build tools, build harness and build user rebuild individual layers. In practice, the user layer is where project-independent additions belong, because rebuilding it does not disturb the harness and tools layers underneath. More complex configuration, including runtime flags, mounts and base-image settings, goes into ~/.code-container/settings.json rather than the Dockerfile. The README points to two reference documents for the details, one for configuration and one for hands-off harness permissions, and both are shipped inside the repository under skills/container/references/. That is the honest state of the documentation: the README is a quickstart, and the settings schema is documented in files you have to open.

## Where Container is the wrong tool

Container is not a sandbox in the security sense, and the README says so. It limits what an agent can access but does not make the agent trusted, and it explicitly does not defend against prompt injection or agent misalignment. Anyone who needs hard isolation for untrusted code should look at a VM boundary or a purpose-built sandbox, not a Docker or Podman container with a read-write bind mount and retained network access. There is a second, quieter limitation: Container is not designed for headless or CI use. The workflow assumes a developer at a terminal running container init, accepting an image build, and entering an interactive workspace. The README does not document a non-interactive provisioning path, and the host-side skill exists precisely because an agent inside the container cannot configure Container from within. If your requirement is reproducible, ephemeral environments spun up by a pipeline, this is the wrong shape.

## How Container differs from a plain devcontainer setup

The closest alternative is the Dev Containers specification, which also builds a per-project environment from a Dockerfile and a JSON configuration. The difference is in who drives it and where the state lives. A devcontainer is typically opened by an editor, and the configuration lives in the repository as .devcontainer files that the team shares. Container is a standalone CLI that runs from any terminal, keeps its configuration on the host at ~/.code-container/, and builds a shared image with coding harnesses already installed so the first command inside the workspace can be the agent itself. That makes it a personal tool rather than a team artifact: the settings are yours, not checked in. The trade-off is portability of configuration. A devcontainer committed to the repository reproduces for every teammate who opens it; a Container user layer at ~/.code-container/Dockerfile.User has to be recreated on each machine, which is exactly why the README points at the portable host-side skill as the way to have an agent set it up.

## Licence, release cadence and the cost of keeping it current

The repository licence is BSD-3-Clause, and the LICENSE.md file is at the top level. That is permissive and imposes no copyleft obligation on your own code, but note the discrepancy worth checking before you rely on either: the README's licence section says BSD 3-Clause while package.json declares "license": "MIT". Both are permissive, so the practical difference for most users is small, but if you redistribute the package or need an unambiguous SPDX identifier, resolve which one governs. On maintenance, the last push was on 2026-09-02 and the most recent release was v3.5.6 on 2026-09-01, following v3.5.5 on 2026-08-22 and v3.5.4 on 2026-08-17. The upgrade path is the part to budget for: the shared image is rebuilt when tools or customizations change, and the README lists container build, container build tools, container build harness and container build user as separate operations. A harness or tools upgrade means a rebuild, and the README does not document rollback to a previous image, so pinning the CLI version is the only lever the material describes.

## Conclusion

Adopt Container if you run coding agents on real repositories and want the same Linux environment on Windows, macOS and Linux without handing the agent your whole filesystem. Skip it if your work cannot tolerate a read-write mount of the project, or if you need a hardened sandbox rather than a boundary: the README states the project does not protect against prompt injection or agent misalignment. Before committing, run container init and inspect ~/.code-container/settings.json to see exactly which mounts, credentials and runtime flags you are about to enable, and confirm your Docker or Podman install is the one the CLI picks up.

## FAQ

### Does Container work on Windows, macOS and Linux?

The README lists Windows, macOS or Linux as the requirements, alongside Docker or Podman. It states that the same Linux environment runs on all three, and gives a PowerShell install command for Windows and a shell script for macOS and Linux.

### How do I install Container?

On macOS and Linux the README gives a curl command piped to sh from container.aerovato.com, and on Windows a PowerShell command from the same host. Alternatively, npm install -g @aerovato/container installs the CLI globally.

### Does anything installed inside a Container workspace persist?

Yes. The README states that the container and anything installed inside it persist between sessions, including packages and configuration, and that multiple terminals can enter the same container.

### Is Container a secure sandbox for untrusted agents?

No. The README says Container limits what an agent can access but does not make the agent trusted, that the project is mounted read-write and can be changed or deleted, and that it does not protect against prompt injection or agent misalignment.

## Sources

- [aerovato/container on GitHub](https://github.com/aerovato/container)
- [License: BSD-3-Clause](https://github.com/aerovato/container/blob/main/LICENSE)
- [Project website](https://container.aerovato.com)
- [README](https://github.com/aerovato/container/blob/main/README.md)
- [Releases](https://github.com/aerovato/container/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/aerovato-container
