Compare commits
No commits in common. "99a3a25131999daab56676869380905d3a2ed82f" and "21c6c27c9238c2940593d0dbf826aa664f6a4f3c" have entirely different histories.
99a3a25131
...
21c6c27c92
|
|
@ -22,8 +22,10 @@
|
||||||
"cli:install": "bun cli:build && sudo cp dist/toes /usr/local/bin",
|
"cli:install": "bun cli:build && sudo cp dist/toes /usr/local/bin",
|
||||||
"cli:link": "ln -sf $(pwd)/src/cli/index.ts ~/.bun/bin/toes",
|
"cli:link": "ln -sf $(pwd)/src/cli/index.ts ~/.bun/bin/toes",
|
||||||
"cli:uninstall": "sudo rm /usr/local/bin",
|
"cli:uninstall": "sudo rm /usr/local/bin",
|
||||||
|
"deploy": "./scripts/deploy.sh",
|
||||||
"debug": "DEBUG=1 bun run dev",
|
"debug": "DEBUG=1 bun run dev",
|
||||||
"dev": "bun run templates && rm -f pub/client/index.js && bun run --hot src/server/index.tsx",
|
"dev": "bun run templates && rm -f pub/client/index.js && bun run --hot src/server/index.tsx",
|
||||||
|
"remote:deploy": "./scripts/deploy.sh",
|
||||||
"remote:migrate": "bun run scripts/migrate.ts",
|
"remote:migrate": "bun run scripts/migrate.ts",
|
||||||
"remote:install": "./scripts/remote-install.sh",
|
"remote:install": "./scripts/remote-install.sh",
|
||||||
"remote:logs": "./scripts/remote-logs.sh",
|
"remote:logs": "./scripts/remote-logs.sh",
|
||||||
|
|
|
||||||
70
scripts/deploy.sh
Executable file
70
scripts/deploy.sh
Executable file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#!/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"
|
||||||
|
|
||||||
|
git push origin main
|
||||||
|
|
||||||
|
# SSH to target: pull, build, sync apps, restart
|
||||||
|
ssh "$SSH_HOST" bash <<'SCRIPT'
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DEST="${DEST:-$HOME/toes}"
|
||||||
|
APPS_DIR="${APPS_DIR:-$HOME/apps}"
|
||||||
|
DATA_DIR="${DATA_DIR:-$HOME/data}"
|
||||||
|
REPOS_DIR="$DATA_DIR/repos"
|
||||||
|
|
||||||
|
cd "$DEST" && git checkout -- bun.lock && git pull origin main && bun install && rm -rf dist && bun run build && bun run cli:build && sudo cp dist/toes /usr/local/bin/toes
|
||||||
|
|
||||||
|
echo "=> Syncing default apps..."
|
||||||
|
for app_dir in "$DEST"/apps/*/; do
|
||||||
|
app=$(basename "$app_dir")
|
||||||
|
[ -f "$app_dir/package.json" ] || continue
|
||||||
|
target="$APPS_DIR/$app"
|
||||||
|
mkdir -p "$target"
|
||||||
|
cp -a "$app_dir"/. "$target"/
|
||||||
|
echo " $app"
|
||||||
|
(cd "$target" && bun install --frozen-lockfile 2>/dev/null || bun install)
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "=> Initializing bare repos..."
|
||||||
|
mkdir -p "$REPOS_DIR"
|
||||||
|
for app_dir in "$DEST"/apps/*/; do
|
||||||
|
app=$(basename "$app_dir")
|
||||||
|
[ -f "$app_dir/package.json" ] || continue
|
||||||
|
bare="$REPOS_DIR/$app.git"
|
||||||
|
|
||||||
|
if [ ! -d "$bare" ]; then
|
||||||
|
git init --bare -b main "$bare" > /dev/null
|
||||||
|
git -C "$bare" config http.receivepack true
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp=$(mktemp -d)
|
||||||
|
cp -a "$app_dir"/. "$tmp"/
|
||||||
|
git -C "$tmp" init -b main > /dev/null 2>&1
|
||||||
|
git -C "$tmp" add -A > /dev/null
|
||||||
|
git -C "$tmp" -c user.name=toes -c user.email=toes@localhost commit -m "deploy" > /dev/null 2>&1
|
||||||
|
git -C "$tmp" push --force "$bare" main > /dev/null 2>&1
|
||||||
|
rm -rf "$tmp"
|
||||||
|
echo " $app"
|
||||||
|
done
|
||||||
|
|
||||||
|
sudo systemctl restart toes.service
|
||||||
|
SCRIPT
|
||||||
|
|
||||||
|
b=$'\033[1m' d=$'\033[2m' g=$'\033[32m' c=$'\033[36m' r=$'\033[0m'
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " ${b}${g}🐾 Deployed${r} to ${b}$SSH_HOST${r}"
|
||||||
|
echo " ${d}─────────────────────────────${r}"
|
||||||
|
echo ""
|
||||||
|
echo " Dashboard: ${c}$URL${r}"
|
||||||
|
echo ""
|
||||||
|
echo " ${d}Grab the CLI:${r}"
|
||||||
|
echo " ${c}curl -fsSL $URL/install | bash${r}"
|
||||||
|
echo ""
|
||||||
|
|
@ -4,11 +4,10 @@
|
||||||
#
|
#
|
||||||
# This script:
|
# This script:
|
||||||
# 1. Creates a `cli` system user with /usr/local/bin/toes as shell
|
# 1. Creates a `cli` system user with /usr/local/bin/toes as shell
|
||||||
# 2. Suppresses login banner via .hushlogin
|
# 2. Sets an empty password on `cli` for passwordless SSH
|
||||||
# 3. Sets an empty password on `cli` for passwordless SSH
|
# 3. Adds a Match block in sshd_config to allow empty passwords for `cli`
|
||||||
# 4. Adds a Match block in sshd_config to allow empty passwords for `cli`
|
# 4. Adds /usr/local/bin/toes to /etc/shells
|
||||||
# 5. Adds /usr/local/bin/toes to /etc/shells
|
# 5. Restarts sshd
|
||||||
# 6. Restarts sshd
|
|
||||||
#
|
#
|
||||||
# Run as root on the toes machine.
|
# Run as root on the toes machine.
|
||||||
# Usage: ssh cli@toes.local
|
# Usage: ssh cli@toes.local
|
||||||
|
|
@ -28,16 +27,11 @@ else
|
||||||
echo " cli user already exists"
|
echo " cli user already exists"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2. Suppress login banner (MOTD, last login, etc.)
|
# 2. Set empty password
|
||||||
touch /home/cli/.hushlogin
|
|
||||||
chown cli:cli /home/cli/.hushlogin 2>/dev/null || true
|
|
||||||
echo " Created .hushlogin"
|
|
||||||
|
|
||||||
# 3. Set empty password
|
|
||||||
passwd -d cli
|
passwd -d cli
|
||||||
echo " Set empty password on cli"
|
echo " Set empty password on cli"
|
||||||
|
|
||||||
# 4. Add Match block for cli user in sshd_config
|
# 3. Add Match block for cli user in sshd_config
|
||||||
if ! grep -q 'Match User cli' "$SSHD_CONFIG"; then
|
if ! grep -q 'Match User cli' "$SSHD_CONFIG"; then
|
||||||
cat >> "$SSHD_CONFIG" <<EOF
|
cat >> "$SSHD_CONFIG" <<EOF
|
||||||
|
|
||||||
|
|
@ -50,7 +44,7 @@ else
|
||||||
echo " sshd_config already has Match User cli block"
|
echo " sshd_config already has Match User cli block"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 5. Ensure /usr/local/bin/toes is in /etc/shells
|
# 4. Ensure /usr/local/bin/toes is in /etc/shells
|
||||||
if ! grep -q "^${TOES_SHELL}$" /etc/shells; then
|
if ! grep -q "^${TOES_SHELL}$" /etc/shells; then
|
||||||
echo "$TOES_SHELL" >> /etc/shells
|
echo "$TOES_SHELL" >> /etc/shells
|
||||||
echo " Added $TOES_SHELL to /etc/shells"
|
echo " Added $TOES_SHELL to /etc/shells"
|
||||||
|
|
@ -64,7 +58,7 @@ if [ ! -f "$TOES_SHELL" ]; then
|
||||||
echo " Create it with: ln -sf /path/to/toes/cli $TOES_SHELL"
|
echo " Create it with: ln -sf /path/to/toes/cli $TOES_SHELL"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 6. Restart sshd
|
# 5. Restart sshd
|
||||||
echo " Restarting sshd..."
|
echo " Restarting sshd..."
|
||||||
systemctl restart sshd || service ssh restart || true
|
systemctl restart sshd || service ssh restart || true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -234,19 +234,4 @@ program
|
||||||
await shell()
|
await shell()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Hide and disable commands that don't work over SSH
|
|
||||||
if (process.env.USER === 'cli') {
|
|
||||||
const disabled = ['shell', 'get', 'open']
|
|
||||||
for (const name of disabled) {
|
|
||||||
const cmd = program.commands.find((c) => c.name() === name)
|
|
||||||
if (!cmd) continue
|
|
||||||
cmd.helpInformation = () => ''
|
|
||||||
;(cmd as any)._hidden = true
|
|
||||||
cmd.action(() => {
|
|
||||||
console.error(`"${name}" is not available over SSH`)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { program }
|
export { program }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user