SSH Commands

Interact with your projects via SSH. Push code, trigger rebuilds, and get shell access.

git push

The primary way to deploy. Push to Zippy like any git remote:

$ git push zippy main

Build output streams directly to your terminal. Each branch gets its own container, so you can push multiple branches simultaneously.

Force push

Force pushes work normally. The build runs with the new code:

$ git push zippy main --force

build

Re-run the build script in the existing container without touching it. Great for retrying failed tests or picking up environment changes:

# Re-run build for main branch
$ ssh git@zippy.sh build acme/webapp
# Re-run build for a specific branch
$ ssh git@zippy.sh build acme/webapp feature/new-ui

The build command:

  • Runs zippy.sh in the existing container (no recreation)
  • Respects the build queue (waits for other builds if needed)
  • Useful for retrying flaky tests or re-running after config changes
build output
⚡ zippy build starting...
⚡ zippy starting container...
⚡ zippy running zippy.sh

Note: Use build when you just want to re-run your script. Use rebuild when you need a fresh container from scratch.

rebuild

Re-run a build without pushing new code. Useful for retrying failed builds or picking up environment changes:

# Rebuild main branch
$ ssh git@zippy.sh rebuild acme/webapp
# Rebuild a specific branch
$ ssh git@zippy.sh rebuild acme/webapp feature/new-ui

The rebuild command:

  • Clears any pending builds in the queue
  • Removes the existing container (fresh start)
  • Runs the full build pipeline
rebuild output
⚡ zippy cleared pending builds
⚡ zippy removing existing container...
⚡ zippy build starting...
⚡ zippy cloning code...
⚡ zippy creating container...
⚡ zippy running zippy.sh

shell

Get an interactive shell inside your build container. Great for debugging:

# Shell into main branch container
$ ssh git@zippy.sh shell acme/webapp
# Shell into a specific branch
$ ssh git@zippy.sh shell acme/webapp feature/new-ui

You'll get a bash shell inside the container with your project mounted at /app:

interactive shell
$ ssh git@zippy.sh shell acme/webapp
root@acme-webapp:/app# ls
package.json src/ node_modules/ zippy.sh
root@acme-webapp:/app# npm test

Note: The container must exist before you can shell into it. Push code first to create the container.

add-member

Add a user to your organization by their SSH public key. Only the org owner can add members. Members can push to any project in the org.

# Add a team member by their public key
$ ssh git@zippy.sh add-member acme "$(cat ~/.ssh/id_ed25519.pub)"
added alice to acme

If the SSH key doesn't belong to an existing user, one is created automatically. The new member can then push to any project under the organization.

Note: Ask your team member for their public key (cat ~/.ssh/id_ed25519.pub) and paste it in the command. Only the org owner can add members.

git clone / fetch

Clone or fetch from Zippy to get code you've pushed:

# Clone a project
$ git clone git@zippy.sh:acme/webapp.git
# Or add as remote and fetch
$ git remote add zippy git@zippy.sh:acme/webapp.git
$ git fetch zippy

Command reference

Command Description
git push zippy <branch> Push code and trigger a build
ssh git@zippy.sh build <project> [branch] Re-run build script in existing container
ssh git@zippy.sh rebuild <project> [branch] Full rebuild with fresh container
ssh git@zippy.sh shell <project> [branch] Interactive shell in container
ssh git@zippy.sh add-member <org> <ssh-key> Add a user to an organization (owner only)
git clone git@zippy.sh:<project>.git Clone a project
git fetch zippy Fetch latest from Zippy remote

Tips

Use SSH config for convenience

Add Zippy to your SSH config to simplify commands:

~/.ssh/config
Host zippy
HostName zippy.sh
User git
IdentityFile ~/.ssh/id_ed25519

Now use ssh zippy rebuild acme/webapp

Parallel branch builds

Each branch gets its own container. Push multiple branches at once and they'll build in parallel.

Project naming

Use org/project format for project names (e.g., acme/webapp). This keeps projects organized and avoids naming conflicts.