DEXBot2 now ships container images only for release tags matching v*.*.*.
latest- most recent stable release build (not updated for pre-release tags)vX.Y.Z- release tag imagesha-<commit>- immutable commit build
Images are published to:
ghcr.io/froooze/dexbot2
docker build -t dexbot2:local .
docker run --rm -it dexbot2:local node dist/dexbot.js --helpFor production and best secret hygiene without PM2, use the bundled unlock launcher:
tsx unlock.ts- Enter the master password once interactively.
- Password stays in daemon memory (RAM) and is not stored in
.env. - Bot processes request private keys through the daemon socket.
- If the credential daemon stops, rerun the launcher to unlock it again.
To start only one bot:
tsx unlock.ts <bot-name>For environments without an interactive TTY (Docker containers, PaaS platforms), use
--headless with a password source:
# Via environment variable (less secure — see security note)
DEXBOT_MASTER_PASSWORD=<password> tsx unlock.ts --headless
# Via secret file (recommended — works with Docker secrets)
tsx unlock.ts --headless --password-file /run/secrets/bot-passwordThe same flags work with PM2:
DEXBOT_MASTER_PASSWORD=<password> node pm2 --headless
node pm2 --headless --password-file /run/secrets/bot-password
⚠️ Security note: Environment variables are visible via/proc/<pid>/environfor the lifetime of the process. The--password-filepath is safer — use Docker secrets or a mounted file withchmod 400. In both cases, the master password is used only to derive the vault key and is not retained after unlock.
For claw-only workflows that only need credentials, use:
tsx unlock.ts --claw-onlyFor PM2-managed credential-daemon-only startup:
node pm2 claw-only- Create a
.envfile in the project root for non-secret Docker Compose runtime values:
BOT_NAME=my-bot
OPEN_ORDERS_SYNC_LOOP_MS=5000
# Optional: match container user to host UID/GID for volume permissions
DEXBOT_UID=1000
DEXBOT_GID=1000
# Optional: pin a specific image tag instead of `latest`
# DEXBOT_IMAGE=ghcr.io/froooze/dexbot2:sha-<commit>- Ensure the host directories exist with matching ownership:
mkdir -p profiles market_adapter/data market_adapter/state- Start the bot:
docker compose upThis compose mode runs unlock.ts, which starts the credential daemon and may prompt for the master password. If BOT_NAME is empty, it starts all active bots from profiles/bots.json.
For non-interactive environments (CI, headless servers), pass the master password via an env var or secret file override:
# Using a Docker secret (recommended)
DEXBOT_MASTER_PASSWORD=$(cat /run/secrets/bot-password) docker compose up
# Or override the command entirely
docker compose run dexbot node dist/unlock.js --headless --password-file /run/secrets/bot-password- View logs:
docker compose logs -f dexbot- Stop:
docker compose down- Persist bot state/config by mounting
./profiles:/app/profiles. - Persist market adapter runtime state and candle caches by mounting
./market_adapter/state:/app/market_adapter/stateand./market_adapter/data:/app/market_adapter/data. - The image runs as the bundled
nodeuser (UID 1000 by default). To avoid permission issues with bind mounts, either:- Pre-create host directories (
mkdir -p profiles market_adapter/data market_adapter/state) so they inherit your host user's ownership, or - Set
DEXBOT_UIDandDEXBOT_GIDin.envto match your host user (id -u/id -g).
- Pre-create host directories (
- Keep
.envfor non-sensitive runtime values (for exampleBOT_NAME,OPEN_ORDERS_SYNC_LOOP_MS). - Do not store the master password in
.env. The secure launchers prompt once and keep it only in process memory. If you must use non-interactive startup, use--headless --password-filewith a Docker secret (see Headless startup above). - If you prefer immutable pinning, set
DEXBOT_IMAGE=ghcr.io/froooze/dexbot2:sha-<commit>in.env(no edit todocker-compose.ymlneeded). The compose file defaults to${DEXBOT_IMAGE:-ghcr.io/froooze/dexbot2:latest}. - Release images are multi-arch (
linux/amd64,linux/arm64); they run on both x86 and ARM hosts without additional setup.