Skip to content

Deployment

dEXploarer edited this page Mar 27, 2026 · 2 revisions

Deployment

Milady runs locally by default, but can also be deployed as a container (Railway, Docker, VPS) or connected to Eliza Cloud.

Hosting modes

On first run, onboarding asks where the backend should live:

  • Local — run the backend on the current machine (the default local flow)
  • Cloud — use Eliza Cloud or attach to a Remote Milady backend

If you choose Eliza Cloud, the app provisions and connects to a managed backend at elizacloud.ai. If you choose Remote Milady, the frontend rebinds to the backend you specify.

Remote backend deployment

Use this when you want the Milady frontend to connect to a backend running on a VPS, homelab, or another machine.

  1. Install Milady on the target machine
  2. Bind the API to a reachable address
  3. Generate a strong API token
  4. Allow the frontend origin explicitly
  5. Expose the backend over HTTPS or a private Tailscale URL

Recommended server environment:

export MILADY_API_BIND=0.0.0.0
export MILADY_API_TOKEN="$(openssl rand -hex 32)"
export MILADY_ALLOWED_ORIGINS="https://app.milady.ai,https://milady.ai,https://elizacloud.ai,https://www.elizacloud.ai"
milady start

The access key entered in onboarding is the value of MILADY_API_TOKEN.

Tailscale

For private remote access without opening the backend publicly:

tailscale serve --https=443 http://127.0.0.1:2138

If you intentionally want a public Tailscale URL:

tailscale funnel --https=443 http://127.0.0.1:2138

Use the Tailscale HTTPS URL as the backend address in onboarding and keep using the same MILADY_API_TOKEN as the access key.

Docker

A Dockerfile is included at the repo root. It uses node:22-bookworm as the base, installs Bun, builds the project, and starts Milady in headless mode.

Build

docker build -t milady .

Run

docker run -d \
  -p 2138:2138 \
  -v /data/.milady:/data/.milady \
  -e MILADY_API_TOKEN=your-secure-token \
  milady

The container CMD is:

MILADY_PORT=2138 node milady.mjs start

Railway sets PORT dynamically; the CMD maps it to MILADY_PORT.

Environment variables (container-specific)

The Dockerfile sets these defaults for container deployments:

Variable Container default Description
NODE_ENV production Node environment
MILADY_API_BIND 0.0.0.0 Bind to all interfaces (required in containers)
MILADY_STATE_DIR /data/.milady State directory (config, db, logs)
MILADY_CONFIG_PATH /data/.milady/milady.json Config file path
PGLITE_DATA_DIR /data/.milady/workspace/.eliza/.elizadb PGLite database directory

Important: Always set MILADY_API_TOKEN when MILADY_API_BIND=0.0.0.0. Without it, anyone who can reach the server has full access.

Persistent volume

Mount /data as a persistent volume so config, the database, and agent state survive redeploys:

docker run -v /host/path:/data milady

On Railway, attach a persistent volume at /data.

Railway

Deploy directly from the GitHub repo. Recommended env vars:

MILADY_API_TOKEN=<generated>
ANTHROPIC_API_KEY=<your-key>
TELEGRAM_BOT_TOKEN=<your-token>

Attach a persistent volume at /data.

Headless mode

In container/server deployments, always run headless:

milady start

This suppresses the TUI and browser popup. The Dockerfile CMD already does this.

Logs

In headless/daemon mode, logs go to ~/.milady/logs/ (or MILADY_STATE_DIR/logs/ in containers). Use --verbose for log level info or --debug for debug.

Daemonizing (non-container)

Milady does not ship a built-in daemon manager. Use your preferred process manager.

systemd:

[Unit]
Description=Milady AI Agent
After=network.target

[Service]
ExecStart=/usr/local/bin/milady start
Restart=on-failure
Environment=MILADY_API_TOKEN=your-token

[Install]
WantedBy=multi-user.target

pm2:

pm2 start "milady start" --name milady
pm2 save

Git LFS (Docker builds)

The Dockerfile handles Git LFS assets (VRM avatars, animations) with a multi-step fallback:

  1. Runs git lfs pull if .git is present in the build context
  2. Falls back to cloning from the origin repo if LFS pointers remain unresolved
  3. Falls back to media.githubusercontent.com for VRM files as a last resort

VRM pointer files that are still unresolved after all fallbacks will fail the build. Animation pointer files will produce a warning but not fail.

Pass GITHUB_TOKEN as a build arg for private repo access:

docker build --build-arg GITHUB_TOKEN=ghp_... -t milady .

Pass MILADY_DOCKER_APT_PACKAGES to install additional system packages:

docker build --build-arg MILADY_DOCKER_APT_PACKAGES=ffmpeg -t milady .

Clone this wiki locally