Push Deploy
Deploy from a local directory with sh0 push. No Git repository required.
What is Push Deploy
sh0 push takes a local directory, detects the stack (Node.js, Python, Go, Rust, etc.), packages the files, uploads them to your server, builds a container, and returns a live URL. The entire flow happens in one command.
This is the fastest way to go from code to a running deployment. No Git setup, no repository configuration, no webhook integration -- just push and go.
Basic Usage
sh0 pushOutput:
Pushing my-app
Detected nodejs (Next.js) -- 85/100 health
Uploading 42 files (2.3 MB) ··· OK 0.8s
Building ··· OK 32.4s
Deploying ··· OK 2.1s
Live in 35.3s
-> https://my-app.sh0.appYou can also push a specific directory or customize the app name:
sh0 push ~/projects/api --name my-api --port 3000How It Works
The push flow has six steps:
- Resolve directory -- Defaults to the current directory. Verifies the path exists.
- Check link -- If
.sh0/link.jsonexists, this is a re-push to an existing app. - Detect stack -- Identifies the framework and language (20+ stacks supported).
- Run health check -- Scores the project on best practices. Warns on blocking issues.
- Package and upload -- Creates an in-memory ZIP, respecting ignore patterns. Uploads via multipart form.
- Build and deploy -- The server builds a container, starts it, and assigns a domain. Build logs stream in real time.
Options
| Flag | Default | Description |
|---|---|---|
| [path] | . | Directory to push |
| --name <name> | Directory name | App name (lowercase, alphanumeric, hyphens) |
| --project <id> | Default project | Project to deploy into |
| --port <port> | Auto-detected | Application port inside the container |
| --no-check | false | Skip the health check |
| --timeout <secs> | 600 | Maximum seconds to wait for deployment |
.sh0ignore
Control which files are excluded from the upload. Uses the same syntax as .gitignore. If no .sh0ignore exists, the CLI falls back to .dockerignore, then .gitignore.
# Build artifacts
node_modules/
dist/
.next/
# Environment
.env
.env.*
# IDE
.vscode/
.idea/The following directories are always excluded, regardless of ignore files:
.git/,node_modules/,__pycache__/,.env*target/,.next/,.nuxt/,.svelte-kit/,dist/venv/,.venv/,.sh0/,.DS_Store
.sh0/link.json
After the first push, the CLI creates .sh0/link.json in your project directory. This file links the local directory to the remote app so subsequent pushes update the same deployment.
{
"app_id": "a1b2c3d4",
"app_name": "my-app",
"server_url": "https://panel.example.com"
}.sh0/ to your .gitignore. The link file contains server-specific information and should not be shared across environments.Health Checks
Before uploading, sh0 push runs the same Code Health Check available via sh0 check. It scores your project from 0 to 100 and warns about issues that could cause build failures.
Skip the health check with --no-check if you know what you're doing.
Re-push Behavior
When .sh0/link.json exists, running sh0 push uploads to the existing app instead of creating a new one. The server creates a new deployment, builds the updated code, and performs a blue-green swap if configured.
To deploy as a new app instead, use --name new-app-name or delete .sh0/link.json.
Auto-Push with sh0 watch
For development, use sh0 watch to automatically re-push on file changes:
sh0 watch --debounce 3000This watches the current directory and re-pushes after 3 seconds of inactivity. Respects .sh0ignore patterns and runs an initial push on start. See the Commands Reference for all options.
CI/CD Integration
Use sh0 push in CI/CD pipelines for projects that don't use Git-based deployment. Here's a GitHub Actions example:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install sh0
run: curl -fsSL https://get.sh0.dev | bash
- name: Deploy
env:
SH0_API_URL: ${{ secrets.SH0_API_URL }}
SH0_API_TOKEN: ${{ secrets.SH0_API_TOKEN }}
run: sh0 push --name my-app