Skip to content

CLI Deploy

Deploy compiled binaries and built artifacts from your local machine. No git history needed — just build, then deploy.

When to Use CLI Deploy

Language Deploy method Why
Node.js, Python Git Push Plitho needs source to run npm install / pip install
Go, Rust, C CLI Deploy Build locally, deploy the binary — no build step needed on server
Static sites (built) CLI Deploy Build locally with your toolchain, deploy the output
CI/CD pipelines CLI Deploy Pack artifacts and stream them, no git remote needed

Setup

1. Create the Script

Create a file at ~/.local/bin/plitho:

cat > ~/.local/bin/plitho << 'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail

CONFIG="./plitho.yml"
TARGET_HOST=""
STREAM_LOGS="--stream"
SKIP_ASK=false

usage() {
    cat << EOF
Usage: plitho deploy [OPTIONS] <files...>

Deploy files to a Plitho server via tar stream.

Commands:
  deploy    Deploy files to a remote server (default)

Options:
  --config <path>   Path to config file (default: ./plitho.yml)
  --at <host>       Target SSH host alias or user@host (required)
  --nostream        Disable streaming server logs after deployment
  -y, --yes         Skip confirmation prompt (auto-approve)
  -h, --help        Show this help message

Examples:
  # Go: build and deploy binary
  go build -o server .
  plitho deploy --at server -y ./server

  # Static site: build and deploy output
  npm run build
  plitho deploy --at server -y ./dist

  # Deploy multiple files
  plitho deploy --at server -y ./server ./config/

  # Deploy everything in current directory
  plitho deploy --at server -y ./
EOF
    exit 1
}

# Handle subcommand
CMD="${1:-}"
if [[ "$CMD" == "deploy" ]]; then
    shift
elif [[ "$CMD" == "-h" || "$CMD" == "--help" || "$CMD" == "help" ]]; then
    usage
elif [[ "$CMD" == -* ]]; then
    # No subcommand, treat as deploy (backwards compat)
    :
else
    echo "Unknown command: $CMD" >&2
    echo "Usage: plitho deploy [OPTIONS] <files...>" >&2
    exit 1
fi

FILES=()
while [[ $# -gt 0 ]]; do
    case "$1" in
        --config) CONFIG="$2"; shift 2 ;;
        --at) TARGET_HOST="$2"; shift 2 ;;
        --nostream) STREAM_LOGS=""; shift ;;
        -y|--yes) SKIP_ASK=true; shift ;;
        -h|--help) usage ;;
        -*) echo "Error: Unknown option $1" >&2; usage ;;
        *) FILES+=("$1"); shift ;;
    esac
done

if [[ -z "$TARGET_HOST" ]]; then echo "Error: Missing --at <host>" >&2; exit 1; fi
if [[ ${#FILES[@]} -eq 0 ]]; then echo "Error: No files specified." >&2; exit 1; fi
if [[ ! -f "$CONFIG" ]]; then echo "Error: Config '$CONFIG' not found." >&2; exit 1; fi

REMOTE_APP=$(awk '/^[[:space:]]*-[[:space:]]+name:/ {print $3; exit}' "$CONFIG")
if [[ -z "$REMOTE_APP" ]]; then echo "Error: Could not parse app name from '$CONFIG'." >&2; exit 1; fi

echo "=================================================="
echo "Ready to Deploy"
echo "=================================================="
echo "Target Host : $TARGET_HOST"
echo "App Name    : $REMOTE_APP (from $CONFIG)"
echo "Payload     : ${FILES[*]}"
echo "Log Stream  : $( [[ -n "$STREAM_LOGS" ]] && echo "Enabled" || echo "Disabled" )"
echo "=================================================="

if [ "$SKIP_ASK" = false ]; then
    read -p "Proceed? (y/N): " -r CONFIRMATION
    if [[ ! "$CONFIRMATION" =~ ^[Yy]$ ]]; then echo "Aborted."; exit 0; fi
fi

TMP_STAGE=$(mktemp -d)
trap 'rm -rf "$TMP_STAGE"' EXIT

cp "$CONFIG" "$TMP_STAGE/plitho.yml"
for item in "${FILES[@]}"; do cp -R "$item" "$TMP_STAGE/"; done

REMOTE_CMD="tar-deploy $REMOTE_APP $STREAM_LOGS"
REMOTE_CMD=$(echo "$REMOTE_CMD" | xargs)

echo "Packing and streaming to $TARGET_HOST..."
tar -cf - -C "$TMP_STAGE" . | gzip | ssh "$TARGET_HOST" -p 2222 "$REMOTE_CMD"
SCRIPT

2. Make It Executable

chmod +x ~/.local/bin/plitho

3. Add to PATH

If ~/.local/bin isn't in your PATH:

# For bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# For zsh
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

4. Verify

plitho --help

How It Works

  1. Parses the app name from your plitho.yml
  2. Shows a confirmation prompt (skip with -y)
  3. Stages all files into a temp directory with your plitho.yml
  4. Streams the tarball to the server via SSH
  5. Server receives the stream and deploys

Next Steps

See CLI Deploy Usage for examples and workflows.