# Containers

> Learn how to use containers for secure and isolated execution of untrusted code with Docker in software development.

Containers, like [Docker](https://www.docker.com/), are a way to package software and its dependencies into a standardized unit for software development. Containers are lightweight, standalone, and executable software packages that include everything needed to run an application: code, runtime, system tools, system libraries, and settings.

Untrusted Code Execution

If you are planning to execute code generated by an LLM, you **should** treat it as **untrusted** and use containers to isolate the execution environment.

## Requirements

[Section titled “Requirements”](#requirements)

GenAIScript uses Docker to orchestrate the containers.

* [Install docker](https://docs.docker.com/engine/install/)

## Start a container

[Section titled “Start a container”](#start-a-container)

Start by creating and starting a new container. GenAIScript will pull the container image on demand, removing the container when it is no longer needed.

```js
const container = await host.container()
```

### Custom image

[Section titled “Custom image”](#custom-image)

By default, the container uses the [python:alpine](https://hub.docker.com/_/python/) image, which provides a minimal python environment. You can change the image using the `image` option.

```js
const container = await host.container({ image: "node:20" })
```

### Building images

[Section titled “Building images”](#building-images)

Use [docker build](https://docs.docker.com/build/) to create reusable images.

You can build a custom image from a GitHub repository with a single command in your scripts.

```js
const repo = "codelion/optillm" // GitHub repository = image name
const branch = "main"
const dir = "."
await host.exec(
    `docker build -t ${repo} https://github.com/${repo}.git#${branch}:${dir}`
)
```

Then use the repo as your image name

```js
const container = await host.container({ image: repo, ... })
```

### Disable auto-purge

[Section titled “Disable auto-purge”](#disable-auto-purge)

By default, the container is removed when it is no longer needed. You can disable this behavior using the `persistent` option.

```js
const container = await host.container({ persistent: true })
```

### Enable network

[Section titled “Enable network”](#enable-network)

By default, the container network is disabled, and web requests won’t work. This is the safest solution; if you need to install additional packages, it is recommended to create an image with all the necessary software included.

You can enable network access using `networkEnabled`.

```js
const container = await host.container({ networkEnabled: true })
```

### Port bindings

[Section titled “Port bindings”](#port-bindings)

You can bind container ports to host ports and access web servers running in the container.

For example, this configuration will map the host `8088` port to `80` on the container and you will be able to access a local web server using `http://localhost:8088/`.

```js
const container = await host.container({
    networkEnabled: true,
    ports: {
        containerPort: "80/tcp",
        hostPort: 8088,
    }, // array also supported
})
```

Then

## Run a command

[Section titled “Run a command”](#run-a-command)

You can run a command in the container using the `exec` method. It returns the exit code, standard output and error streams.

```js
const { stdout } = await container.exec("python", ["--version"])
```

## Read and write files

[Section titled “Read and write files”](#read-and-write-files)

The container has a volume mounted in the host file system, allowing reading and writing files to the container.

```js
await container.writeText("hello.txt", "Hello, world!")
const content = await container.readText("hello.txt")
```

## Copy files to container

[Section titled “Copy files to container”](#copy-files-to-container)

You can also copy files from the host to the container.

```js
// src/* -> ./src/*
await container.copyTo("src/**", ".")
```

## Disconnect network

[Section titled “Disconnect network”](#disconnect-network)

If you created the container with network enabled, you can disconnect the network to isolate the container.

```js
await container.disconnect()
```

## Using containers in tools

[Section titled “Using containers in tools”](#using-containers-in-tools)

The [containerized tools](/genaiscript/guides/containerized-tools) guide shows how to use containers in tools to handle untrusted text securely.