opencode-ai / startup.sh
Bjo53's picture
Update startup.sh for persistence
729deb0 verified
Raw
History Blame Contribute Delete
4.46 kB
#!/bin/bash
echo "===== Startup $(date) ====="
umask 077
pip3 install --no-cache-dir -q huggingface_hub==0.23.0 --break-system-packages 2>/dev/null
if ! command -v node &> /dev/null; then
echo "[Install] Node.js..."
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - 2>/dev/null
apt-get install -y nodejs 2>/dev/null
fi
echo "[Install] Claude CLI..."
npm install -g @anthropic-ai/claude-code 2>/dev/null
echo "[Install] Codex CLI..."
npm install -g @openai/codex 2>/dev/null
mkdir -p /persistent/.secrets /persistent/sessions
chmod 700 /persistent/.secrets
# Restore from dataset
if [ -n "$HF_TOKEN" ] && [ -n "$HF_USERNAME" ]; then
echo "[Storage] Restoring from dataset..."
python3 -c "
import os
from huggingface_hub import snapshot_download
token = os.environ.get('HF_TOKEN')
username = os.environ.get('HF_USERNAME')
repo_id = f'{username}/vps-storage'
try:
snapshot_download(repo_id=repo_id, repo_type='dataset', local_dir='/persistent', token=token, ignore_patterns=['.gitattributes','README.md','.git/*'])
print('[Storage] Restored!')
except: print('[Storage] Fresh start')
" 2>/dev/null
fi
# Reinstall packages
if [ -s /persistent/installed_packages.txt ]; then
echo "[Packages] Reinstalling tracked packages..."
while IFS= read -r pkg; do
[ -z "$pkg" ] && continue
if [[ "$pkg" == apt:* ]]; then
apt_pkg="${pkg#apt:}"
apt-get install -y -qq "$apt_pkg" 2>/dev/null
else
pip3 install -q "$pkg" --break-system-packages 2>/dev/null
fi
done < /persistent/installed_packages.txt
echo "[Packages] Done!"
fi
# Auto-save every 3 minutes
python3 -c "
import os, time, threading
def auto_save():
while True:
time.sleep(180)
token = os.environ.get('HF_TOKEN')
username = os.environ.get('HF_USERNAME')
if token and username:
try:
from huggingface_hub import HfApi
api = HfApi(token=token)
api.upload_folder(
folder_path='/persistent',
repo_id=f'{username}/vps-storage',
repo_type='dataset',
token=token,
commit_message='auto-save',
ignore_patterns=['.secrets/', '*.key', '*.pem', '.env', '.git/*']
)
except: pass
threading.Thread(target=auto_save, daemon=True).start()
" &
# Package tracker
python3 -c "
import os, time, json, threading
def watch_pkgs():
seen = set()
if os.path.exists('/persistent/installed_packages.txt'):
with open('/persistent/installed_packages.txt') as f:
seen = {l.strip() for l in f if l.strip()}
while True:
time.sleep(15)
try:
result = os.popen('pip3 list --format=json 2>/dev/null').read()
if result:
pkgs = json.loads(result)
for pkg in pkgs:
name = pkg.get('name','')
if name and name not in seen:
with open('/persistent/installed_packages.txt', 'a') as f:
f.write(name + '\n')
seen.add(name)
except: pass
threading.Thread(target=watch_pkgs, daemon=True).start()
" &
# Keep-alive ping
python3 -c "
import os, time, random, threading, requests
def ping():
while True:
try:
host = os.environ.get('SPACE_HOST','')
if host:
requests.get(f'https://{host}/', headers={'User-Agent': 'Mozilla/5.0'}, timeout=10)
except: pass
time.sleep(random.randint(600, 1800))
threading.Thread(target=ping, daemon=True).start()
" &
# Bashrc for persistent env
cat > /root/.bashrc << 'EOF'
export HISTFILE=/persistent/.bash_history
export HISTSIZE=10000
export HISTFILESIZE=20000
export HISTCONTROL=ignoredups:erasedups
shopt -s histappend
alias pip='pip3'
alias install='track_pkg'
track_pkg() {
pip3 install "$@"
pkg_name=$(echo "$@" | awk '{print $1}' | sed 's/[^a-zA-Z0-9_-]//g')
if [ -n "$pkg_name" ] && ! grep -q "^${pkg_name}$" /persistent/installed_packages.txt 2>/dev/null; then
echo "$pkg_name" >> /persistent/installed_packages.txt
echo "[Tracking] Added: $pkg_name"
fi
}
EOF
cat > /root/.profile << 'EOF'
if [ -f /root/.bashrc ]; then . /root/.bashrc; fi
EOF
echo "[Startup] Ready!"
exec uvicorn app:app --host 0.0.0.0 --port 7860 --ws websockets --proxy-headers --forwarded-allow-ips="*"