| title | Deployment Guide |
|---|---|
| sidebarTitle | Deployment |
| description | Deploy Eliza using Docker, Docker Compose, or cloud containers. Covers environment variables, port configuration, volumes, and security hardening. |
Eliza supports multiple deployment strategies: standalone Docker containers, Docker Compose orchestration, and cloud-managed containers for Eliza Cloud (Docker containers on dedicated Hetzner robot nodes, joined to the headscale tailnet).
The Docker deployment toolkit lives at `packages/app-core/deploy/` in this repo — `docker-setup.sh`, `docker-compose.yml`, `Dockerfile.ci` (image for prebuilt artifacts), `Dockerfile.cloud`, `deploy.defaults.env`, and the rollout scripts. The example commands below use `eliza/packages/app-core/deploy/...` paths, which apply when a downstream app vendors this repo under an `eliza/` subdirectory; working **inside** this repo, drop the `eliza/` prefix and run them from `packages/app-core/deploy/` directly.The fastest way to deploy Eliza is using the included setup script, which builds the image, generates authentication tokens, runs interactive onboarding, and starts the gateway.
Run from a checkout of this repo. Inside the repo the toolkit is at `packages/app-core/deploy/`; a downstream app that vendors eliza under `eliza/` uses the `../eliza/packages/app-core/deploy/...` paths.# Inside this repo:
bash packages/app-core/deploy/docker-setup.sh
# Or, from a downstream app that vendors eliza under eliza/:
cd deploy && bash ../eliza/packages/app-core/deploy/docker-setup.shApp-specific overrides (image name, ports, state paths) go in a repo-root deploy/deploy.env, merged over deploy.defaults.env (see packages/app-core/deploy/README.md).
The setup script performs the following steps:
- Builds the Docker image (
eliza:localby default) - Generates a random gateway token (via
openssl rand -hex 32, or Pythonsecrets.token_hex(32)as fallback) - Writes environment variables to
deploy/.env - Runs interactive setup (
eliza-cli setup) - Starts the gateway service in detached mode
The CI Dockerfile (eliza/packages/app-core/deploy/Dockerfile.ci) builds a production image from prebuilt artifacts:
FROM node:22-slim AS pruner
WORKDIR /app
COPY . .
# Replace workspace symlinks with actual compiled packages
# (bun workspace symlinks break in Docker)
# ... pruning and patching steps ...
FROM node:22-slim
# Install runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl ffmpeg libopus-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=pruner /app /app
ENV NODE_ENV=production
EXPOSE ${APP_PORT}
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
CMD sh -lc 'port="${PORT:-${APP_PORT:-${ELIZA_PORT:-2138}}}"; ...'
ENTRYPOINT ["sh", "./eliza/packages/app-core/scripts/docker-entrypoint.sh"]
CMD ["sh", "-lc", "exec ${APP_CMD_START:-node --import ./node_modules/tsx/dist/loader.mjs ${APP_ENTRYPOINT} start}"]Key characteristics:
- Base: Node.js 22 slim on Debian Bookworm
- Multi-stage build: Pruner stage replaces workspace symlinks and stubs heavy native deps
- Security: Health check on the API port
- Network: Bind address configurable via
APP_API_BINDbuild arg (default127.0.0.1) - Entrypoint: Uses
tsxto run the app entrypoint with TypeScript support
The CI image is built by the GitHub Actions release pipeline. To run it locally after building:
docker build \
--build-arg ELIZA_DOCKER_APT_PACKAGES="ffmpeg imagemagick" \
-t eliza:local \
-f eliza/packages/app-core/deploy/Dockerfile.ci \
.Mount persistent state to survive container restarts:
| Volume Mount | Container Path | Purpose |
|---|---|---|
~/.local/state/eliza |
/root/.local/state/eliza |
Configuration files (eliza.json), database, secrets |
~/.local/state/eliza/workspace |
/root/.local/state/eliza/workspace |
Agent workspace files, uploaded knowledge, generated content |
| Port | Service | Default | Environment Variable | Notes |
|---|---|---|---|---|
| 2138 | API Server + Dashboard UI | Always exposed inside container | ELIZA_PORT |
Production default; ELIZA_API_PORT (31337) is the dev-mode default |
| 18789 | Gateway (WebSocket + HTTP) | Host-mapped | ELIZA_GATEWAY_PORT |
Multiplexed WebSocket + HTTP with optional TLS |
| 18790 | Bridge (inter-service communication) | Host-mapped | ELIZA_BRIDGE_PORT |
Inter-container communication (WeChat webhook, etc.) |
| Variable | Description |
|---|---|
ELIZA_API_TOKEN |
Token-based auth for the API server. Set in production. |
| Variable | Default | Description |
|---|---|---|
ELIZA_API_BIND |
127.0.0.1 |
API server bind address (set to 0.0.0.0 for container networking) |
ELIZA_ALLOWED_ORIGINS |
(none) | CORS allowed origins for the API server |
ELIZA_GATEWAY_PORT |
18789 |
Gateway port |
ELIZA_GATEWAY_BIND |
lan |
Gateway bind mode (lan, localhost, 0.0.0.0) |
Pass your AI provider API keys as environment variables:
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...
ELIZAOS_CLOUD_API_KEY=eliza_xxxEliza Cloud schedules agent containers onto dedicated Hetzner robot Docker nodes
(docker_nodes node_id eliza-core-{env}-N, OS hostnames eliza-{env}-robot-N)
joined to the headscale tailnet, via the container control plane — not AWS ECS.
Shared-runtime (Tier-0) agents run with no dedicated container at all. The
Dockerfile.cloud-agent (in packages/app-core/deploy/) builds a slim container for deploying agents to Eliza Cloud:
FROM node:22-bookworm-slim
RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl ca-certificates && \
apt-get clean && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY deploy/cloud-agent-entrypoint.ts ./entrypoint.ts
RUN npm install -g tsx@4
ENV NODE_ENV=production
ENV PORT=2138
ENV BRIDGE_PORT=18790
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -f http://localhost:${PORT}/health || exit 1
EXPOSE ${PORT}
EXPOSE ${BRIDGE_PORT}
RUN useradd -m agent
USER agent
CMD ["tsx", "entrypoint.ts"]Key differences from the base Dockerfile:
| Aspect | Base | Cloud Agent |
|---|---|---|
| Base image | node:22-bookworm (full) |
node:22-bookworm-slim |
| Build step | Full source build with Bun | Single entrypoint file, run with tsx |
| Health check | None | curl to /health every 30s |
| User | node (existing) |
agent (custom created) |
| Ports | 2138 | 2138 + 18790 |
| Variable | Description |
|---|---|
ELIZAOS_CLOUD_API_KEY |
Eliza Cloud inference API key |
OPENAI_API_KEY |
OpenAI API key (BYOK mode) |
ANTHROPIC_API_KEY |
Anthropic API key (BYOK mode) |
SMALL_MODEL |
Model selection for small/fast tasks |
LARGE_MODEL |
Model selection for large/complex tasks |
PORT |
Health endpoint port (default: 2138) |
BRIDGE_PORT |
Bridge HTTP port (default: 18790) |
# Build the cloud agent image
docker build -f eliza/packages/app-core/deploy/Dockerfile.cloud-agent -t elizaos/agent:latest .
# Run with Eliza Cloud inference
docker run -p 2138:2138 -p 18790:18790 \
-e ELIZAOS_CLOUD_API_KEY=eliza_xxx \
elizaos/agent:latest
# Run with BYOK (Bring Your Own Key)
docker run -p 2138:2138 -p 18790:18790 \
-e OPENAI_API_KEY=sk-xxx \
-e LARGE_MODEL=gpt-5 \
elizaos/agent:latestThe sandbox provides a lightweight execution environment for agent shell commands and code execution. It runs as a sidecar:
FROM debian:bookworm-slim
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bash \
ca-certificates \
curl \
git \
jq \
python3 \
ripgrep \
&& rm -rf /var/lib/apt/lists/*
CMD ["sleep", "infinity"]This container provides:
- bash -- Shell execution environment
- git -- Version control operations
- python3 -- Python script execution
- curl + jq -- HTTP requests and JSON processing
- ripgrep -- Fast code search
The sandbox runs as a sidecar and sleeps indefinitely, ready to accept commands from the agent runtime.
docker compose -f eliza/packages/app-core/deploy/docker-compose.yml logs -f eliza-gatewaydocker compose -f eliza/packages/app-core/deploy/docker-compose.yml exec eliza-gateway \
node dist/index.js health --token "$ELIZA_GATEWAY_TOKEN"Configure connectors in your eliza.json instead of using CLI commands. See Configuration — Connectors for the full schema.
{
"connectors": {
"telegram": { "botToken": "<bot-token>" },
"discord": { "token": "<bot-token>" }
}
}Then restart the service:
docker compose -f deploy/docker-compose.yml restart eliza# Stop the gateway
docker compose -f eliza/packages/app-core/deploy/docker-compose.yml down
# Restart the gateway
docker compose -f eliza/packages/app-core/deploy/docker-compose.yml up -d eliza-gateway