{"id":30725140,"url":"https://github.com/hunvreus/devpush","last_synced_at":"2026-02-04T07:13:39.870Z","repository":{"id":311843874,"uuid":"917559301","full_name":"hunvreus/devpush","owner":"hunvreus","description":"Like Vercel, but open source and for all languages.","archived":false,"fork":false,"pushed_at":"2026-01-21T11:14:28.000Z","size":1967,"stargazers_count":4353,"open_issues_count":19,"forks_count":151,"subscribers_count":19,"default_branch":"main","last_synced_at":"2026-01-21T21:56:36.961Z","etag":null,"topics":["continuous-deployment","deployment","django","fastapi","flask","github","nextjs","nodejs","php","python","vercel"],"latest_commit_sha":null,"homepage":"https://devpu.sh","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hunvreus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-01-16T08:11:40.000Z","updated_at":"2026-01-21T16:48:07.000Z","dependencies_parsed_at":"2025-08-27T08:57:29.906Z","dependency_job_id":"e0153b37-d9e7-4277-841f-48dd17f0e9fc","html_url":"https://github.com/hunvreus/devpush","commit_stats":null,"previous_names":["hunvreus/devpush"],"tags_count":24,"template":false,"template_full_name":"hunvreus/flask-basics","purl":"pkg:github/hunvreus/devpush","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunvreus%2Fdevpush","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunvreus%2Fdevpush/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunvreus%2Fdevpush/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunvreus%2Fdevpush/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hunvreus","download_url":"https://codeload.github.com/hunvreus/devpush/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunvreus%2Fdevpush/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28744419,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T02:46:29.005Z","status":"ssl_error","status_checked_at":"2026-01-25T02:44:29.968Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["continuous-deployment","deployment","django","fastapi","flask","github","nextjs","nodejs","php","python","vercel"],"created_at":"2025-09-03T12:08:19.342Z","updated_at":"2026-02-04T07:13:39.863Z","avatar_url":"https://github.com/hunvreus.png","language":"Python","readme":"# /dev/push\n\nAn open-source and self-hostable alternative to Vercel, Render, Netlify and the likes. It allows you to build and deploy any app (Python, Node.js, PHP, ...) with zero-downtime updates, real-time logs, team management, customizable environments and domains, etc.\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://devpu.sh/media/screenshot-dark.png\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://devpu.sh/media/screenshot-light.png\"\u003e\n  \u003cimg alt=\"A screenshot of a deployment in /dev/push.\" src=\"https://devpu.sh/media/screenshot-dark.png\"\u003e\n\u003c/picture\u003e\n\n## Key features\n\n- **Git-based deployments**: Push to deploy from GitHub with zero-downtime rollouts and instant rollback.\n- **Multi-language support**: Python, Node.js, PHP... basically anything that can run on Docker.\n- **Environment management**: Multiple environments with branch mapping and encrypted environment variables.\n- **Real-time monitoring**: Live and searchable build and runtime logs.\n- **Team collaboration**: Role-based access control with team invitations and permissions.\n- **Custom domains**: Support for custom domain and automatic Let's Encrypt SSL certificates.\n- **Self-hosted and open source**: Run on your own servers, MIT licensed.\n\n## Documentation\n\nSee [devpu.sh/docs](https://devpu.sh/docs) for installation, configuration, and usage. For technical details, see [ARCHITECTURE.md](ARCHITECTURE.md).\n\n## Prerequisites\n\n- **Server**: Ubuntu 20.04+ or Debian 11+ with SSH access and sudo privileges. A [Hetzner CPX31](https://devpu.sh/docs/guides/create-hetzner-server) works well.\n- **DNS**: We recommend [Cloudflare](https://cloudflare.com).\n- **GitHub account**: You'll create a GitHub App for login and repository access.\n- **Email provider**: A [Resend](https://resend.com) account or SMTP credentials for login emails and invitations.\n\n## Quickstart\n\n\u003e ⚠️ Supported on Ubuntu/Debian. Other distros may work but aren't officially supported (yet).\n\n1. **Install** on a fresh server:\n\n```bash\ncurl -fsSL https://install.devpu.sh | sudo bash\n```\n\n2. **Create a GitHub App** at [devpu.sh/docs/guides/create-github-app](https://devpu.sh/docs/guides/create-github-app)\n\n3. **Configure** by editing `/var/lib/devpush/.env` with: `APP_HOSTNAME`, `DEPLOY_DOMAIN`, `LE_EMAIL`, `EMAIL_SENDER_ADDRESS`, `RESEND_API_KEY` (or SMTP settings), and your GitHub App credentials.\n\n4. **Set DNS**:\n   - `A` `example.com` → server IP (app hostname)\n   - `A` `*.example.com` → server IP (deployments)\n\n5. **Start** the service:\n\n```bash\nsudo systemctl start devpush.service\n```\n\nFor more information, including manual installation or updates, refer to [the documentation](https://devpu.sh/docs/installation).\n\n## Development\n\n**Prerequisites**: Docker and Docker Compose v2+. On macOS, [Colima](https://github.com/abiosoft/colima) works well as an alternative to Docker Desktop.\n\n```bash\ngit clone https://github.com/hunvreus/devpush.git\ncd devpush\nmkdir -p data\ncp .env.dev.example data/.env\n# Edit data/.env with your GitHub App credentials\n```\n\nStart the stack:\n\n```bash\n./scripts/start.sh\n```\n\nThe stack auto-detects development mode on macOS and enables hot reloading. Data is stored in `./data/`.\n\n## Registry catalog\n\nDefault runner/preset definitions ship in `registry/` and are copied to `DATA_DIR/registry/` during install/update.\nSee `registry/README.md` for the catalog format and override rules.\n\n**Key scripts**:\n\n- `./scripts/start.sh` / `stop.sh` / `restart.sh` — manage the stack\n- `./scripts/compose.sh logs -f app` — view logs\n- `./scripts/db-generate.sh` — create database migration\n- `./scripts/clean.sh` — remove all Docker resources and data\n\nSee [ARCHITECTURE.md](ARCHITECTURE.md) for codebase structure.\n\n## Scripts\n\n| Script                     | What it does                                                                                                                                                                      |\n| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `scripts/backup.sh`        | Create backup of data directory, database, and code metadata (`--output \u003cfile\u003e`, `--verbose`)                                                                                     |\n| `scripts/clean.sh`         | Stop stack and remove all Docker resources and data (`--keep-docker`, `--keep-data`, `--yes`)                                                                                     |\n| `scripts/compose.sh`       | Docker compose wrapper with correct files/env (`--`)                                                                                                                              |\n| `scripts/db-generate.sh`   | Generate Alembic migration (prompts for message)                                                                                                                                  |\n| `scripts/db-migrate.sh`    | Apply Alembic migrations (`--timeout \u003csec\u003e`)                                                                                                                                      |\n| `scripts/install.sh`       | Server setup: Docker, user, clone repo, .env, systemd (`--repo \u003curl\u003e`, `--ref \u003cref\u003e`, `--yes`, `--no-telemetry`, `--verbose`)                                                     |\n| `scripts/restart.sh`       | Restart services (`--no-migrate`)                                                                                                                                                 |\n| `scripts/restore.sh`       | Restore from backup archive (`--archive \u003cfile\u003e`, `--no-db`, `--no-data`, `--no-code`, `--no-restart`, `--no-backup`, `--remove-runners`, `--timeout \u003csec\u003e`, `--yes`, `--verbose`) |\n| `scripts/start.sh`         | Start stack (`--no-migrate`, `--timeout \u003csec\u003e`, `--verbose`)                                                                                                                      |\n| `scripts/status.sh`        | Show stack status                                                                                                                                                                 |\n| `scripts/stop.sh`          | Stop services (`--hard`)                                                                                                                                                          |\n| `scripts/uninstall.sh`     | Uninstall from server (`--yes`, `--skip-backup`, `--no-telemetry`, `--verbose`)                                                                                                   |\n| `scripts/update.sh`        | Update by tag (`--ref \u003ctag\u003e`, `--all`, `--full`, `--components \u003ccsv\u003e`, `--no-migrate`, `--no-telemetry`, `--yes`, `--verbose`)                                                    |\n\n## Environment variables\n\n| Variable                            | Description                                                                                                                              |\n| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |\n| `SECRET_KEY`                        | App secret for sessions/CSRF. Auto-generated by install.sh.                                                                              |\n| `ENCRYPTION_KEY`                    | Fernet key for encrypting secrets. Auto-generated by install.sh.                                                                         |\n| `POSTGRES_PASSWORD`                 | PostgreSQL password. Auto-generated by install.sh.                                                                                       |\n| `SERVICE_UID`                       | Container user UID. Auto-set to match host user.                                                                                         |\n| `SERVICE_GID`                       | Container user GID. Auto-set to match host user.                                                                                         |\n| `SERVER_IP`                         | Public IP of the server. Auto-detected by install.sh.                                                                                    |\n| `CERT_CHALLENGE_PROVIDER`           | ACME challenge provider: `default` (HTTP-01) or `cloudflare`, `route53`, `gcloud`, `digitalocean`, `azure` (DNS-01). Default: `default`. |\n| `GITHUB_APP_ID`                     | GitHub App ID.                                                                                                                           |\n| `GITHUB_APP_NAME`                   | GitHub App name.                                                                                                                         |\n| `GITHUB_APP_PRIVATE_KEY`            | GitHub App private key (PEM format, use `\\n` for newlines).                                                                              |\n| `GITHUB_APP_WEBHOOK_SECRET`         | GitHub webhook secret.                                                                                                                   |\n| `GITHUB_APP_CLIENT_ID`              | GitHub OAuth client ID.                                                                                                                  |\n| `GITHUB_APP_CLIENT_SECRET`          | GitHub OAuth client secret.                                                                                                              |\n| `APP_HOSTNAME`                      | Domain for the app (e.g., `example.com`).                                                                                                |\n| `DEPLOY_DOMAIN`                     | Domain for deployments (wildcard root). No default—set explicitly (e.g., `deploy.example.com`).                                          |\n| `LE_EMAIL`                          | Email for Let's Encrypt notifications.                                                                                                   |\n| `EMAIL_SENDER_ADDRESS`              | Email sender for invites/login.                                                                                                          |\n| `RESEND_API_KEY`                    | API key for [Resend](https://resend.com). Optional if SMTP is configured.                                                               |\n| `SMTP_HOST`                         | SMTP host. When set with username/password, SMTP is used instead of Resend.                                                             |\n| `SMTP_PORT`                         | SMTP port. Default: `587`.                                                                                                              |\n| `SMTP_USERNAME`                     | SMTP username. Required when using SMTP.                                                                                                |\n| `SMTP_PASSWORD`                     | SMTP password. Required when using SMTP.                                                                                                |\n| `GOOGLE_CLIENT_ID`                  | Google OAuth client ID (optional).                                                                                                       |\n| `GOOGLE_CLIENT_SECRET`              | Google OAuth client secret (optional).                                                                                                   |\n| `APP_NAME`                          | Display name. Default: `/dev/push`.                                                                                                      |\n| `APP_DESCRIPTION`                   | App description.                                                                                                                         |\n| `EMAIL_SENDER_NAME`                 | Sender display name. Default: `/dev/push`.                                                                                               |\n| `POSTGRES_DB`                       | Database name. Default: `devpush`.                                                                                                       |\n| `POSTGRES_USER`                     | Database user. Default: `devpush-app`.                                                                                                   |\n| `REDIS_URL`                         | Redis URL. Default: `redis://redis:6379`.                                                                                                |\n| `DOCKER_HOST`                       | Docker API. Default: `tcp://docker-proxy:2375`.                                                                                          |\n| `DATA_DIR`                          | Data directory. Default: `/var/lib/devpush`.                                                                                             |\n| `APP_DIR`                           | Code directory. Default: `/opt/devpush`.                                                                                                 |\n| `DEFAULT_CPUS`                      | Default CPU limit per deployment. No limit if not provided.                                                                              |\n| `MAX_CPUS`                          | Maximum allowed CPU override per project. Used only when `DEFAULT_CPUS` is set. Required to let user customize CPU.                      |\n| `DEFAULT_MEMORY_MB`                 | Default memory limit (MB) per deployment. No limit if not provided.                                                                      |\n| `MAX_MEMORY_MB`                     | Maximum allowed memory override per project. Used only when `DEFAULT_MEMORY_MB` is set. Required to let user customize memory.           |\n| `JOB_TIMEOUT_SECONDS`               | Job timeout (seconds). Default: `320`.                                                                                                   |\n| `JOB_MAX_TRIES`                     | Max retries per background job. Default: `3`.                                                                                            |\n| `DEPLOYMENT_TIMEOUT_SECONDS`        | Deployment timeout (seconds). Default: `300`.                                                                                            |\n| `CONTAINER_DELETE_GRACE_SECONDS`    | Wait before deleting containers after stop/failure to let logs ship. Default: `3`.                                                       |\n| `LOG_STREAM_GRACE_SECONDS`          | Grace window for deployment log streaming (when to connect/close SSE around terminal states). Default: `5`.                              |\n| `LOG_LEVEL`                         | Logging level. Default: `WARNING`.                                                                                                       |\n| `MAGIC_LINK_TTL_SECONDS`            | Magic link validity (seconds). Default: `900`.                                                                                           |\n| `AUTH_TOKEN_TTL_DAYS`               | Auth cookie/JWT lifetime (days). Default: `30`.                                                                                          |\n| `AUTH_TOKEN_REFRESH_THRESHOLD_DAYS` | Refresh auth token when expiring within N days. Default: `1`.                                                                            |\n| `AUTH_TOKEN_ISSUER`                 | JWT issuer for auth_token. Default: `devpush-app`.                                                                                       |\n| `AUTH_TOKEN_AUDIENCE`               | JWT audience for auth_token. Default: `devpush-web`.                                                                                     |\n\n## Support the project\n\n- [Contribute code](/CONTRIBUTING.md)\n- [Report issues](https://github.com/hunvreus/devpush/issues)\n- [Sponsor me](https://github.com/sponsors/hunvreus)\n- [Star the project on GitHub](https://github.com/hunvreus/devpush)\n- [Join the Discord chat](https://devpu.sh/chat)\n\n## License\n\n[MIT](/LICENSE.md)\n","funding_links":["https://github.com/sponsors/hunvreus"],"categories":["Python","后端开发框架及项目"],"sub_categories":["后端项目_其他"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhunvreus%2Fdevpush","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhunvreus%2Fdevpush","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhunvreus%2Fdevpush/lists"}