matrixcloud / scripts /deploy-hf-space.sh
github-actions[bot]
Deploy from 4dfd54f2
857a91b
Raw
History Blame Contribute Delete
4.71 kB
#!/usr/bin/env bash
# Deploy the MatrixCloud demo to a Hugging Face Docker Space β€” self-contained.
#
# This ships the full committed source to the Space and builds matrix-runtime
# there (local build context), so it works whether or not the GitHub repo is
# public. The embedded console + all features come from the current commit.
#
# Usage:
# HF_TOKEN=hf_xxx ./scripts/deploy-hf-space.sh
#
# Optional env:
# HF_USERNAME account/org that owns the Space (default: ruslanmv)
# SPACE_NAME Space name (default: matrixcloud)
#
# The token is read only from the environment and used in-memory β€” never written
# to a file or committed. Pushing publishes a PUBLIC Space. Rotate the token
# afterwards if it was shared anywhere.
set -euo pipefail
HF_USERNAME="${HF_USERNAME:-ruslanmv}"
SPACE_NAME="${SPACE_NAME:-matrixcloud}"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
if [ -z "${HF_TOKEN:-}" ]; then
echo "❌ Set HF_TOKEN (a Hugging Face *write* token): HF_TOKEN=hf_xxx $0" >&2
exit 1
fi
for f in hf/README.md hf/requirements.txt hf/app/main.py; do
test -f "$f" || { echo "❌ missing $f" >&2; exit 1; }
done
echo "πŸ‘€ Verifying token..."
who="$(curl -fsS --max-time 30 -H "Authorization: Bearer ${HF_TOKEN}" \
https://huggingface.co/api/whoami-v2 | sed -n 's/.*"name":"\([^"]*\)".*/\1/p' | head -1 || true)"
echo " authenticated as: ${who:-unknown}"
echo "πŸš€ Ensuring Space ${HF_USERNAME}/${SPACE_NAME} exists (Docker SDK)..."
code="$(curl -s -o /dev/null -w '%{http_code}' -X POST \
-H "Authorization: Bearer ${HF_TOKEN}" -H 'Content-Type: application/json' \
-d "{\"type\":\"space\",\"name\":\"${SPACE_NAME}\",\"sdk\":\"docker\",\"private\":false}" \
https://huggingface.co/api/repos/create || true)"
case "$code" in
200|201) echo " created." ;;
409) echo " already exists β€” will force-update." ;;
*) echo " create returned HTTP ${code} (continuing; push will surface real errors)." ;;
esac
DEPLOY_DIR="$(mktemp -d)"
trap 'rm -rf "${DEPLOY_DIR}"' EXIT
echo "πŸ“¦ Exporting committed source β†’ ${DEPLOY_DIR} ..."
git archive --format=tar HEAD | tar -x -C "${DEPLOY_DIR}"
# Trim things the Space build doesn't need (docs/ holds PNGs that HF would
# require via Git LFS β€” and the Space never serves them).
rm -rf "${DEPLOY_DIR}/legacy" "${DEPLOY_DIR}/bin" "${DEPLOY_DIR}/coverage.out" \
"${DEPLOY_DIR}/.github" "${DEPLOY_DIR}/docs"
# HF Space config: README front-matter + python launcher + a self-contained,
# local-context Dockerfile (overrides the repo's root Dockerfile in the tree).
cp hf/README.md "${DEPLOY_DIR}/README.md"
cp hf/requirements.txt "${DEPLOY_DIR}/requirements.txt"
mkdir -p "${DEPLOY_DIR}/app"
cp hf/app/main.py "${DEPLOY_DIR}/app/main.py"
cat > "${DEPLOY_DIR}/Dockerfile" <<'DOCKER'
# Self-contained Space build: compiles matrix-runtime from the pushed source.
FROM golang:1.24-bookworm AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/matrix-runtime ./cmd/matrix-runtime
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl git nodejs npm python3 python3-pip pipx \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /out/matrix-runtime /usr/local/bin/matrix-runtime
COPY requirements.txt /app/requirements.txt
RUN pip3 install --no-cache-dir --break-system-packages -r /app/requirements.txt
COPY app /app/app
ENV MATRIX_RUNTIME_MODE=cloud-worker \
MATRIX_RUNTIME_PORT=7860 \
MATRIX_RUNTIME_DATA_DIR=/tmp/matrixcloud \
MATRIX_SHELL_ENABLED=false \
HF_HOME=/tmp/hf
EXPOSE 7860
ENTRYPOINT ["python3", "/app/app/main.py"]
DOCKER
cd "${DEPLOY_DIR}"
git init -q -b main
git config user.name "matrixcloud-deploy"
git config user.email "deploy@matrixhub.io"
git config commit.gpgsign false
git config tag.gpgsign false
git add -A
git -c commit.gpgsign=false commit -q -m "Deploy MatrixCloud ($(cd "$ROOT" && git rev-parse --short HEAD))"
echo "πŸ” Pushing β†’ HF Space main (force)..."
git push --force -q "https://${HF_USERNAME}:${HF_TOKEN}@huggingface.co/spaces/${HF_USERNAME}/${SPACE_NAME}" main
echo
echo "βœ… Deployed. The Space is building now:"
echo " https://huggingface.co/spaces/${HF_USERNAME}/${SPACE_NAME}"
echo " app URL (after build): https://${HF_USERNAME}-${SPACE_NAME}.hf.space"
echo
echo "Recommended Space secrets (Settings β†’ Variables and secrets) for durable accounts:"
echo " MATRIXCLOUD_DATABASE_URL=postgresql://…neon…?sslmode=require&channel_binding=require"
echo " MATRIXCLOUD_SECRET_KEY=\$(openssl rand -hex 32)"
echo " MATRIXCLOUD_APP_URL=https://${HF_USERNAME}-${SPACE_NAME}.hf.space"