#!/usr/bin/env bash set -euo pipefail ## # toes installer # Usage: curl -fsSL https://toes.dev/install | sh # # Installs or updates toes on a Raspberry Pi. # Must be run as the 'toes' user with passwordless sudo. REPO="https://git.nose.space/defunkt/toes" DEST=~/toes APPS_DIR=~/apps DATA_DIR=~/data BUNDLED_APPS="clock code cron env git metrics" # ── Helpers ────────────────────────────────────────────── quiet() { "$@" > /dev/null 2>&1; } info() { echo ">> $1"; } fail() { echo "ERROR: $1" >&2; exit 1; } # ── Preflight ──────────────────────────────────────────── echo "" echo " ╔══════════════════════════════════╗" echo " ║ 🐾 toes - personal web appliance ║" echo " ╚══════════════════════════════════╝" echo "" [ "$(whoami)" = "toes" ] || fail "Must be run as the 'toes' user." sudo -n true 2>/dev/null || fail "Requires passwordless sudo." # ── System packages ────────────────────────────────────── info "Updating system packages" quiet sudo apt-get update quiet sudo apt-get install -y git libcap2-bin avahi-utils fish unzip if [ "$(getent passwd toes | cut -d: -f7)" != "/usr/bin/fish" ]; then info "Setting fish as default shell" quiet sudo chsh -s /usr/bin/fish toes fi # ── Bun ────────────────────────────────────────────────── BUN="$HOME/.bun/bin/bun" if [ ! -x "$BUN" ]; then info "Installing bun" curl -fsSL https://bun.sh/install | bash > /dev/null 2>&1 [ -x "$BUN" ] || fail "bun installation failed." fi sudo ln -sf "$BUN" /usr/local/bin/bun sudo setcap 'cap_net_bind_service=+ep' "$BUN" # ── Clone or pull ──────────────────────────────────────── if [ -d "$DEST/.git" ]; then info "Pulling latest toes" git -C "$DEST" fetch origin main git -C "$DEST" reset --hard origin/main else info "Cloning toes" git clone "$REPO" "$DEST" fi # ── Directories ────────────────────────────────────────── mkdir -p "$APPS_DIR" "$DATA_DIR" "$DATA_DIR/toes" # ── Dependencies & build ───────────────────────────────── cd "$DEST" info "Installing dependencies" quiet bun install info "Building" quiet bun run build # ── Bundled apps ───────────────────────────────────────── info "Installing bundled apps" for app in $BUNDLED_APPS; do [ -d "$DEST/apps/$app" ] || continue echo " $app" cp -r "$DEST/apps/$app" "$APPS_DIR/" if [ -f "$APPS_DIR/$app/package.json" ]; then quiet bun install --frozen-lockfile --cwd "$APPS_DIR/$app" || quiet bun install --cwd "$APPS_DIR/$app" fi done # ── Systemd ────────────────────────────────────────────── info "Installing toes service" sudo install -m 644 "$DEST/scripts/toes.service" /etc/systemd/system/toes.service sudo systemctl daemon-reload sudo systemctl enable toes info "Restarting toes" sudo systemctl restart toes # ── Done ───────────────────────────────────────────────── VERSION=$(git describe --tags --always 2>/dev/null || echo "unknown") echo "" echo " toes $VERSION is running!" echo " http://$(hostname).local" echo "" echo " Install the CLI on your local machine:" echo " curl -fsSL http://$(hostname).local/install | bash" echo ""