Skip to content

Deployment

Run mikan under PM2 with persistent state, managed sandbox images, graceful shutdown, and an optional health endpoint.

PM2 supervisor

PM2 daemonizes mikan, restarts it after failures, retains stdout/stderr logs, and can start it on boot.

Managed image sandbox

The mikan host process uses Docker to create per-conversation tool containers from the selected sandbox image.

Persistent state

Keep one host-only state directory for settings, session-independent runtime state, vaults, and GitHub polling watermarks.

  • Node.js >=22.19.0
  • at least one complete Slack, Telegram, Discord, or GitHub credential set
  • a persistent state directory (default ~/.mikan); the working directory defaults to <state-dir>/workspace
  • Docker available to the PM2 user when using image:* or container:*

The published mikan-sandbox image is a tool runtime, not a standalone mikan server image. PM2 runs mikan on the host; image mode creates and manages containers through the host Docker daemon.

  1. Install mikan and PM2:

    Terminal window
    npm i -g @geminixiang/mikan pm2
  2. Create the global settings file in the exact state directory the service will use:

    Terminal window
    mkdir -p /srv/mikan/workspace
    mikan --onboard --state-dir=/srv/mikan/state

    Review /srv/mikan/state/settings.json. The directory must be owned by the PM2 process user and must not be world-writable; chmod 0700 /srv/mikan/state is recommended.

  3. Create the secrets file. All platform tokens, provider keys, and other secrets live in ~/.mikan/mikan.env — mode 0600, outside any repo tree — and the ecosystem file loads it at start. Never put secrets in the ecosystem file or PM2’s own environment:

    Terminal window
    curl -o ~/.mikan/mikan.env https://raw.githubusercontent.com/geminixiang/mikan/main/deploy/pm2/mikan.env.example
    chmod 600 ~/.mikan/mikan.env

    Fill in at least one complete platform credential set plus an LLM provider key. Run mikan env to see the full annotated inventory and what is currently set.

  4. Pull the managed sandbox image:

    Terminal window
    docker pull ghcr.io/geminixiang/mikan-sandbox:latest

    Do not also start a long-lived container when the selected mode is image:*. A pre-existing container is needed only for container:<name> mode.

  5. Download the ecosystem file:

    Terminal window
    curl -O https://raw.githubusercontent.com/geminixiang/mikan/main/deploy/pm2/ecosystem.config.cjs

    The ecosystem file is supervision-only: process name, restart policy, graceful-shutdown timeout, and the mikan.env loader. Behavior (model, sandbox limits, reply modes) stays in <state-dir>/settings.json.

  6. Edit args to use absolute paths and one sandbox mode (run mikan --help for the flag reference):

    args: "--state-dir=/srv/mikan/state --sandbox=image:ghcr.io/geminixiang/mikan-sandbox:latest /srv/mikan/workspace",

    The working-directory argument is optional; without it mikan uses <state-dir>/workspace and creates it on first start.

  7. Start and persist the process:

    Terminal window
    pm2 start ecosystem.config.cjs
    pm2 save
    pm2 startup
  8. Run the command printed by pm2 startup to enable boot startup.

Relative workspace paths are resolved from PM2’s current working directory. Absolute paths avoid silently opening a different workspace after service migration or reboot.

Terminal window
npm i -g @geminixiang/mikan
pm2 reload mikan

After editing ~/.mikan/mikan.env, reload through the ecosystem file so the environment is re-read:

Terminal window
pm2 reload ecosystem.config.cjs

The portal server exists only when LINK_PORT is set, or when LINK_URL causes the default port 8181 to be used:

Terminal window
curl http://127.0.0.1:8181/health
# {"ok":true}

/health is a liveness check for the HTTP process only. It does not verify platform connections, Docker, sandbox provisioning, LLM providers, or event delivery, so do not use it as the only readiness signal.

See the maintained PM2 ecosystem file on GitHub and Sandbox modes for mode-specific requirements.