rpi deploy scripts/setup

This commit is contained in:
Chris Wanstrath 2026-01-30 15:28:52 -08:00
parent 557ea669fb
commit e6c9751f7d
9 changed files with 169 additions and 1 deletions

View File

@ -14,7 +14,15 @@
"cli:build": "bun run scripts/build.ts",
"cli:build:all": "bun run scripts/build.ts --all",
"cli:install": "bun cli:build && sudo cp dist/toes /usr/local/bin",
"cli:uninstall": "sudo rm /usr/local/bin"
"cli:uninstall": "sudo rm /usr/local/bin",
"deploy": "./scripts/deploy.sh",
"dev": "bun run --hot src/server/index.tsx",
"remote:install": "./scripts/remote-install.sh",
"remote:restart": "./scripts/remote-restart.sh",
"remote:start": "./scripts/remote-start.sh",
"remote:stop": "./scripts/remote-stop.sh",
"start": "bun run src/server/index.tsx",
"test": "bun test"
},
"devDependencies": {
"@types/bun": "latest"

8
scripts/config.sh Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# It isn't enough to modify this yet.
# You also need to manually update the toes.service file.
HOST="${HOST:-toes@toes.local}"
URL="${URL:-http://toes.local}"
DEST="${DEST:-~/.toes}"
APPS_DIR="${APPS_DIR:-~/apps}"

23
scripts/deploy.sh Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -e
# Get absolute path of this script's directory
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$SCRIPT_DIR/.."
# Load config
source "$ROOT_DIR/scripts/config.sh"
# Make sure we're up-to-date
if [ -n "$(git status --porcelain)" ]; then
echo "=> You have unsaved (git) changes"
exit 1
fi
git push origin main
# SSH to target and update
ssh "$HOST" "cd $DEST && git pull origin main && bun run build && sudo systemctl restart toes.service"
echo "=> Deployed to $HOST"
echo "=> Visit $URL"

71
scripts/install.sh Executable file
View File

@ -0,0 +1,71 @@
#!/usr/bin/env bash
##
# installs systemd files to keep toes running on your Raspberry Pi
set -euo pipefail
quiet() { "$@" > /dev/null 2>&1; }
SYSTEMD_DIR="/etc/systemd/system"
SERVICE_NAME="toes"
SERVICE_FILE="$(dirname "$0")/${SERVICE_NAME}.service"
SYSTEMD_PATH="${SYSTEMD_DIR}/${SERVICE_NAME}.service"
BUN_SYMLINK="/usr/local/bin/bun"
BUN_REAL="$HOME/.bun/bin/bun"
echo ">> Updating system libraries"
quiet sudo apt-get update
quiet sudo apt-get install -y libcap2-bin
quiet sudo apt-get install -y avahi-utils
echo ">> Ensuring bun is available in /usr/local/bin"
if [ ! -x "$BUN_SYMLINK" ]; then
if [ -x "$BUN_REAL" ]; then
quiet sudo ln -sf "$BUN_REAL" "$BUN_SYMLINK"
echo "Symlinked $BUN_REAL -> $BUN_SYMLINK"
else
echo ">> Installing bun at $BUN_REAL"
quiet sudo apt install unzip
quiet curl -fsSL https://bun.sh/install | bash
quiet sudo ln -sf "$BUN_REAL" "$BUN_SYMLINK"
echo "Symlinked $BUN_REAL -> $BUN_SYMLINK"
fi
else
echo "bun already available at $BUN_SYMLINK"
fi
echo ">> Setting CAP_NET_BIND_SERVICE on $BUN_REAL"
quiet sudo setcap 'cap_net_bind_service=+ep' "$BUN_REAL"
quiet /usr/sbin/getcap "$BUN_REAL" || true
echo ">> Creating apps directory"
mkdir -p ~/apps
echo ">> Building client bundle"
bun run build
echo ">> Installing toes service"
quiet sudo install -m 644 -o root -g root "$SERVICE_FILE" "$SYSTEMD_PATH"
echo ">> Reloading systemd daemon"
quiet sudo systemctl daemon-reload
echo ">> Enabling $SERVICE_NAME to start at boot"
quiet sudo systemctl enable "$SERVICE_NAME"
echo ">> Starting (or restarting) $SERVICE_NAME"
quiet sudo systemctl restart "$SERVICE_NAME"
echo ">> Enabling kiosk mode"
quiet mkdir -p ~/.config/labwc
cat > ~/.config/labwc/autostart <<'EOF'
chromium-browser --noerrdialogs --disable-infobars --kiosk http://localhost
EOF
echo ">> Done! Rebooting in 5 seconds..."
quiet systemctl status "$SERVICE_NAME" --no-pager -l
sleep 5
quiet sudo nohup reboot >/dev/null 2>&1 &
exit 0

12
scripts/remote-install.sh Executable file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
# Get absolute path of this script's directory
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$SCRIPT_DIR/.."
# Load config
source "$ROOT_DIR/scripts/config.sh"
# Run remote install on the target
ssh "$HOST" "git clone https://git.nose.space/defunkt/toes $DEST && cd $DEST && ./scripts/install.sh"

9
scripts/remote-restart.sh Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$SCRIPT_DIR/.."
source "$ROOT_DIR/scripts/config.sh"
ssh "$HOST" "sudo systemctl restart toes.service"

9
scripts/remote-start.sh Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$SCRIPT_DIR/.."
source "$ROOT_DIR/scripts/config.sh"
ssh "$HOST" "sudo systemctl start toes.service"

9
scripts/remote-stop.sh Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$SCRIPT_DIR/.."
source "$ROOT_DIR/scripts/config.sh"
ssh "$HOST" "sudo systemctl stop toes.service"

19
scripts/toes.service Normal file
View File

@ -0,0 +1,19 @@
[Unit]
Description=Toes - Personal Web Appliance
After=network-online.target
Wants=network-online.target
[Service]
User=toes
WorkingDirectory=/home/toes/.toes/
Environment=PORT=80
Environment=NODE_ENV=production
Environment=APPS_DIR=/home/toes/apps/
ExecStart=/home/toes/.bun/bin/bun start
Restart=always
RestartSec=1
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target