| |
| |
|
|
| FROM node:22-bookworm |
|
|
| ARG OPENCLAW_VERSION=2026.3.11 |
|
|
| RUN apt-get update && \ |
| DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates curl dnsutils git && \ |
| apt-get clean && rm -rf /var/lib/apt/lists/* |
|
|
| ENV NODE_ENV=production |
| ENV NPM_CONFIG_UPDATE_NOTIFIER=false |
| ENV NPM_CONFIG_FUND=false |
| ENV NPM_CONFIG_AUDIT=false |
| ENV OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1 |
| ENV OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first |
|
|
| RUN npm install -g openclaw@${OPENCLAW_VERSION} @google/gemini-cli |
|
|
| WORKDIR /app |
| COPY setup-hf-config.mjs /app/setup-hf-config.mjs |
| COPY resolve-telegram-host.mjs /app/resolve-telegram-host.mjs |
| COPY resolve-discord-host.mjs /app/resolve-discord-host.mjs |
| COPY discord-bot-init.mjs /app/discord-bot-init.mjs |
| COPY discord-pairing-approve.mjs /app/discord-pairing-approve.mjs |
| COPY discord-startup-notify.mjs /app/discord-startup-notify.mjs |
| COPY import-auth-profiles.mjs /app/import-auth-profiles.mjs |
| COPY startup-notify.mjs /app/startup-notify.mjs |
| COPY sync-external-storage.mjs /app/sync-external-storage.mjs |
|
|
| EXPOSE 7860 |
|
|
| RUN printf '%s\n' \ |
| '#!/bin/sh' \ |
| 'set -e' \ |
| 'run_optional() {' \ |
| ' step="$1"' \ |
| ' shift' \ |
| ' echo "[openclaw-entrypoint] step=${step} status=start"' \ |
| ' if "$@"; then' \ |
| ' echo "[openclaw-entrypoint] step=${step} status=ok"' \ |
| ' else' \ |
| ' code=$?' \ |
| ' echo "[openclaw-entrypoint] step=${step} status=failed exit=${code} (continuing)"' \ |
| ' fi' \ |
| '}' \ |
| 'echo "[openclaw-entrypoint] status=start node=$(node --version 2>/dev/null || echo missing) openclaw=$(openclaw --version 2>/dev/null || echo missing)"' \ |
| 'if mkdir -p /data/.openclaw 2>/dev/null; then' \ |
| ' export OPENCLAW_HOME=/data' \ |
| 'else' \ |
| ' export OPENCLAW_HOME=/home/user' \ |
| ' mkdir -p /home/user/.openclaw' \ |
| 'fi' \ |
| 'echo "[openclaw-entrypoint] openclaw_home=${OPENCLAW_HOME}"' \ |
| 'if [ -n "${OPENCLAW_TELEGRAM_PROXY}" ]; then' \ |
| ' export HTTPS_PROXY="${HTTPS_PROXY:-$OPENCLAW_TELEGRAM_PROXY}"' \ |
| ' export HTTP_PROXY="${HTTP_PROXY:-$OPENCLAW_TELEGRAM_PROXY}"' \ |
| ' export ALL_PROXY="${ALL_PROXY:-$OPENCLAW_TELEGRAM_PROXY}"' \ |
| ' echo "[openclaw-entrypoint] telegram_proxy=1"' \ |
| 'fi' \ |
| 'run_optional resolve-telegram-host node /app/resolve-telegram-host.mjs' \ |
| 'run_optional resolve-discord-host node /app/resolve-discord-host.mjs' \ |
| 'echo "[openclaw-entrypoint] step=setup-hf-config status=start"' \ |
| 'node /app/setup-hf-config.mjs' \ |
| 'echo "[openclaw-entrypoint] step=setup-hf-config status=ok"' \ |
| 'run_optional discord-bot-init node /app/discord-bot-init.mjs' \ |
| 'echo "[openclaw-entrypoint] step=import-auth-profiles status=start"' \ |
| 'node /app/import-auth-profiles.mjs' \ |
| 'echo "[openclaw-entrypoint] step=import-auth-profiles status=ok"' \ |
| 'run_optional startup-notify node /app/startup-notify.mjs' \ |
| 'echo "[openclaw-entrypoint] step=discord-pairing-approve status=start background=1"' \ |
| 'node /app/discord-pairing-approve.mjs 2>&1 &' \ |
| 'run_optional discord-startup-notify node /app/discord-startup-notify.mjs' \ |
| 'install_skill() {' \ |
| ' skill="$1"' \ |
| ' run_optional "skills-add:${skill}" npx --yes skills add "$skill" --agent "github-copilot" --yes' \ |
| '}' \ |
| 'if [ "${OPENCLAW_AUTO_INSTALL_SKILLS:-1}" = "1" ]; then' \ |
| ' echo "[openclaw-entrypoint] step=skills-add status=start background=1"' \ |
| ' (' \ |
| ' install_skill "charon-fan/agent-playbook@self-improving-agent"' \ |
| ' install_skill "useai-pro/openclaw-skills-security@skill-vetter"' \ |
| ' install_skill "theagentservice/skills@openclaw-backup"' \ |
| ' install_skill "epiral/bb-browser@bb-browser"' \ |
| ' install_skill "vercel-labs/agent-browser@agent-browser"' \ |
| ' install_skill "joeseesun/opencli-skill@opencli"' \ |
| ' install_skill "aradotso/trending-skills@openclaw-control-center"' \ |
| ' echo "[openclaw-entrypoint] step=skills-add status=done"' \ |
| ' ) 2>&1 &' \ |
| 'fi' \ |
| 'if [ "${OPENCLAW_ENABLE_GEMINI_CLI_AUTH:-1}" = "1" ]; then' \ |
| ' echo "[openclaw-entrypoint] step=enable-gemini-cli-auth status=start"' \ |
| ' if openclaw plugins enable google-gemini-cli-auth >/tmp/openclaw-gemini-cli.log 2>&1; then' \ |
| ' echo "[openclaw-entrypoint] step=enable-gemini-cli-auth status=ok log=/tmp/openclaw-gemini-cli.log"' \ |
| ' else' \ |
| ' code=$?' \ |
| ' echo "[openclaw-entrypoint] step=enable-gemini-cli-auth status=failed exit=${code} log=/tmp/openclaw-gemini-cli.log (continuing)"' \ |
| ' fi' \ |
| 'fi' \ |
| 'if [ -n "${SUPABASE_URL}" ] && [ -n "${SUPABASE_KEY}" ]; then' \ |
| ' echo "[openclaw-entrypoint] step=sync-external-storage status=start background=1"' \ |
| ' node /app/sync-external-storage.mjs 2>&1 &' \ |
| 'fi' \ |
| 'echo "[openclaw-entrypoint] step=gateway status=exec port=7860 bind=lan"' \ |
| 'exec openclaw gateway --allow-unconfigured --bind lan --port 7860 "$@"' \ |
| > /app/entrypoint.sh \ |
| && chmod +x /app/entrypoint.sh |
|
|
| RUN mkdir -p /home/user && chown -R node:node /app /home/user |
|
|
| ENTRYPOINT ["/app/entrypoint.sh"] |
|
|