-
Notifications
You must be signed in to change notification settings - Fork 59
Deployment
Milady runs locally by default, but can also be deployed as a container (Railway, Docker, VPS). This page covers container deployment using the included Dockerfile.
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.
docker build -t milady .docker run -d \
-p 2138:2138 \
-v /data/.milady:/data/.milady \
-e MILADY_API_TOKEN=your-secure-token \
miladyThe container CMD is:
MILADY_PORT=2138 node milady.mjs startRailway sets PORT dynamically; the CMD maps it to MILADY_PORT.
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.
Mount /data as a persistent volume so config, the database, and agent state survive redeploys:
docker run -v /host/path:/data miladyOn Railway, attach a persistent volume at /data.
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.
In container/server deployments, always run headless:
milady start --headlessThis suppresses the TUI and browser popup. The Dockerfile CMD already does this.
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.
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 --headless
Restart=on-failure
Environment=MILADY_API_TOKEN=your-token
[Install]
WantedBy=multi-user.targetpm2:
pm2 start "milady start --headless" --name milady
pm2 saveThe Dockerfile handles Git LFS assets (VRM avatars, animations) with a multi-step fallback:
- Runs
git lfs pullif.gitis present in the build context - Falls back to cloning from the origin repo if LFS pointers remain unresolved
- Falls back to
media.githubusercontent.comfor 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 .