> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beam.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Containers

> Host a Dockerfile, registry image, or background worker with the CLI or Python

You can deploy a Dockerfile or registry image directly with `beam deploy`.

## Deploy a Dockerfile

Create a directory with this `Dockerfile`:

```dockerfile Dockerfile theme={null}
FROM python:3.12-slim
WORKDIR /app
RUN echo 'Hello from Beam' > index.html
EXPOSE 8000
CMD ["python", "-m", "http.server", "8000", "--bind", "0.0.0.0"]
```

From that directory, deploy and read the logs:

```bash theme={null}
beam deploy --dockerfile Dockerfile --name hello-web --port 8000 --cpu 1 --memory 1Gi
beam logs hello-web
```

Open the URL printed by the command. You can omit `--dockerfile` when the file is named `Dockerfile` in your current directory.

<Note>
  Services are public by default. Use `Service(authorized=True)` to require a Beam token, or add authentication in your app.
</Note>

## Ports and Commands

Bind your server to `0.0.0.0` or `::`. Repeat `--port` to expose multiple ports. Without it, Beam uses the Dockerfile's `EXPOSE` ports or defaults to 8000. The first port sets `PORT` unless you override it.

The image's `ENTRYPOINT` and `CMD` run by default. To override them:

```bash theme={null}
beam deploy --image python:3.12-slim --name static-site --port 8000 \
  --command 'python -m http.server 8000 --bind 0.0.0.0'
```

`--command` passes literal arguments. For shell syntax, use `--command 'sh -c "your command"'`.

## Background Workers

Use `--no-ports` for a background worker:

```bash theme={null}
beam deploy --dockerfile Dockerfile.worker --name worker --no-ports --replicas 1
```

Workers have no public URL. Set `--replicas 1` to keep one running.

## Configuration and Storage

```bash theme={null}
beam deploy --dockerfile Dockerfile --name web --port 8000 \
  --env LOG_LEVEL=info \
  --env DATABASE_URL='${{db.web-db.DATABASE_URL}}' \
  --secrets API_KEY \
  --disk web-data:/data:10Gi
```

Create the [database](/v2/data/databases) and secret first. See [references](/v2/hosting/references) and [durable disks](/v2/data/durable-disks) for details. Writable disks support one container at a time.

Use `.beamignore` to exclude local files from upload.

## Scaling and Idle Time

Services default to 0–1 replicas and shut down after 600 idle seconds. To change this:

```bash theme={null}
# Keep at least one replica running, with up to three replicas.
beam deploy --name web --min-replicas 1 --max-replicas 3

# A fixed replica count.
beam deploy --name web --replicas 2

# Allow idle containers to shut down after 60 seconds.
beam deploy --name web --min-replicas 0 --max-replicas 1 --keep-warm-seconds 60
```

These examples use the current directory's Dockerfile. Warm containers are billed while running.

## Python Service API

You can also deploy from Python:

```python app.py theme={null}
from beam import Service

web = Service.from_dockerfile(
    "Dockerfile",
    name="hello-web",
    port=8000,
    authorized=True,
)
```

```bash theme={null}
beam deploy app.py:web
```

Use `Service.from_registry("nginx:alpine", port=80)` for a registry image. A Python `command` string runs through a shell; a list passes literal arguments.
