claw / Dockerfile
nikhtu10's picture
Update Dockerfile
01e197e verified
FROM node:22-slim
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
git openssh-client build-essential python3 python3-pip \
g++ make ca-certificates curl chromium tzdata \
libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 \
libgbm1 libasound2 libpangocairo-1.0-0 libpango-1.0-0 \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& rm -rf /var/lib/apt/lists/*
# Install Python packages
RUN pip3 install --no-cache-dir huggingface_hub --break-system-packages
# Git and CA config
RUN update-ca-certificates && \
git config --global http.sslVerify false && \
git config --global url."https://github.com/".insteadOf ssh://git@github.com/
ENV HOME=/root
ENV PORT=7860 \
OPENCLAW_GATEWAY_MODE=local \
OPENCLAW_BROWSER_PATH=/usr/bin/chromium
# Install OpenClaw
RUN npm install -g openclaw@latest zod --unsafe-perm
# Generate sync.py using a Heredoc to avoid syntax/escaping issues
RUN cat <<'EOF' > /usr/local/bin/sync.py
import os, sys, tarfile
from huggingface_hub import HfApi, hf_hub_download
from datetime import datetime, timedelta
api = HfApi()
repo_id = os.getenv("HF_DATASET")
token = os.getenv("HF_TOKEN")
def restore():
try:
print(f"--- [SYNC] Start recovery process, target repository: {repo_id} ---")
if repo_id and token:
files = api.list_repo_files(repo_id=repo_id, repo_type="dataset", token=token)
now = datetime.now()
found = False
for i in range(5):
day = (now - timedelta(days=i)).strftime("%Y-%m-%d")
name = f"backup_{day}.tar.gz"
if name in files:
print(f"--- [SYNC] Backup file found: {name}, Downloading... ---")
path = hf_hub_download(repo_id=repo_id, filename=name, repo_type="dataset", token=token)
with tarfile.open(path, "r:gz") as tar:
tar.extractall(path="/root/.openclaw/")
print(f"--- [SYNC] Recovery successful! ---")
found = True
break
if not found:
print("--- [SYNC] No backup packages found for the last 5 days---")
else:
print("--- [SYNC] Skip recovery: HF_DATASET or HF_TOKEN not configured ---")
# Clean up .lock files
count = 0
for root, dirs, fs in os.walk("/root/.openclaw/"):
for f in fs:
if f.endswith(".lock"):
try:
os.remove(os.path.join(root, f))
count += 1
except: pass
if count > 0:
print(f"--- [SYNC] {count} residual lock files cleaned up---")
return True
except Exception as e:
print(f"--- [SYNC] Recovery Exception: {e} ---")
def backup():
try:
day = datetime.now().strftime("%Y-%m-%d")
name = f"backup_{day}.tar.gz"
print(f"--- [SYNC] Performing a full backup: {name} ---")
def lock_filter(tarinfo):
if tarinfo.name.endswith(".lock"): return None
return tarinfo
with tarfile.open(name, "w:gz") as tar:
for target in ["sessions", "workspace", "agents", "memory", "plugins", "openclaw.json"]:
full_path = f"/root/.openclaw/{target}"
if os.path.exists(full_path):
tar.add(full_path, arcname=target, filter=lock_filter)
if repo_id and token:
api.upload_file(path_or_fileobj=name, path_in_repo=name, repo_id=repo_id, repo_type="dataset", token=token)
print("--- [SYNC] Backup upload successful! ---")
except Exception as e:
print(f"--- [SYNC] Backup failed: {e} ---")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "backup":
backup()
else:
restore()
EOF
# Create startup script
RUN cat <<'EOF' > /usr/local/bin/start-openclaw
#!/bin/bash
set -e
mkdir -p /root/.openclaw/{sessions,workspace,plugins,agents/main/sessions,credentials}
ln -s /root/.openclaw/workspace /root/.openclaw/memory || true
chmod 700 /root/.openclaw || true
python3 /usr/local/bin/sync.py restore || true
export OPENCLAW_GATEWAY_TOKEN="${OPENCLAW_GATEWAY_PASSWORD}"
CLEAN_BASE=$(echo "${OPENAI_API_BASE}" | sed "s|/chat/completions||g" | sed "s|/v1/|/v1|g" | sed "s|/v1$|/v1|g")
cat > /root/.openclaw/openclaw.json <<EOC
{
"models": {
"mode": "merge",
"providers": {
"zai": {
"baseUrl": "${CLEAN_BASE}",
"apiKey": "${OPENAI_API_KEY}",
"api": "openai-completions",
"models": [
{"id": "glm-4.7", "name": "GLM-4.7 Coding", "contextWindow": 200000, "maxTokens": 8192},
{"id": "glm-5", "name": "GLM-5", "contextWindow": 200000, "maxTokens": 8192}
]
}
}
},
"agents": {
"defaults": {
"model": {"primary": "zai/glm-4.7"},
"workspace": "~/.openclaw/workspace"
}
},
"gateway": {
"mode": "local", "bind": "lan", "port": ${PORT},
"trustedProxies": ["0.0.0.0/0"],
"auth": { "mode": "token", "token": "${OPENCLAW_GATEWAY_PASSWORD}" },
"controlUi": { "allowInsecureAuth": true }
}
}
EOC
(while true; do sleep 10800; python3 /usr/local/bin/sync.py backup || true; done) &
openclaw doctor --fix || true
exec openclaw gateway run --port ${PORT}
EOF
RUN chmod +x /usr/local/bin/start-openclaw
EXPOSE 7860
CMD ["/usr/local/bin/start-openclaw"]