Self-hosted service
hunvreus/devpush avatar
hunvreus/devpush

/dev/push: a self-hosted Vercel alternative you run on your own server

Like Vercel, but open source and for all languages.

4,757 stars184 forksPythonMIT

At a glance

What is it?
/dev/push builds and deploys Docker-based apps from GitHub on your own Ubuntu or Debian box. The install is a single curl command, but you supply the server, the DNS and a GitHub App before anything ships.
Who is it for?
Adopt /dev/push if you already run Ubuntu or Debian servers, want GitHub push-to-deploy and Let's Encrypt SSL without a per-seat bill, and can maintain a box yourself. Do not adopt it if you want a managed platform, Windows hosting, or a tool that installs without a GitHub App and two DNS records.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 7 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem /dev/push solves, and who feels it

Vercel, Render and Netlify give you push-to-deploy, preview environments and managed TLS, and they charge per seat or per build minute. /dev/push takes the same workflow and moves it onto a server you own. The README describes it as "an open-source and self-hostable alternative to Vercel, Render, Netlify and the likes," with zero-downtime updates, real-time logs, team management and customizable environments. The target reader is a small team or a solo developer who already pays for a VPS and would rather spend that money on a machine than on a platform subscription. The language list is deliberately open: Python, Node.js, PHP, and, in the README's words, "basically anything that can run on Docker." That is a different promise from a platform that only supports a fixed set of runtimes. It also means the build contract is a Dockerfile or a preset from the registry catalog, not a vendor-specific buildpack. If your stack is a Django app, a FastAPI service, a Next.js site and a PHP backend, /dev/push does not care that they differ. The trade-off is that you inherit the operational work the hosted platforms were absorbing: server provisioning, DNS, certificate renewal through the configured challenge provider, and upgrades.

How deployment works: GitHub App, Docker runners, per-deployment domains

The pieces visible in the repository are a Python application under app/, a Docker Compose stack under compose/, runner definitions under registry/, and a scripts/ directory that wraps the lifecycle. Deployments are triggered from GitHub. The install guide has you create a GitHub App, and .env.example carries GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY, GITHUB_APP_WEBHOOK_SECRET, GITHUB_APP_CLIENT_ID and GITHUB_APP_CLIENT_SECRET. The webhook secret is what lets the app react to repository events, which is how a push becomes a build. The README states that default runner and preset definitions ship in registry/ and are copied to DATA_DIR/registry/ during install and update, so the build environment is data on disk rather than code baked into the image. That is the mechanism behind multi-language support: a preset describes how a project is built and run, and the catalog format and override rules live in registry/README.md. Runtime limits are configuration, not constants. .env.example lists DEFAULT_CPUS=0.5, MAX_CPUS=4.0, DEFAULT_MEMORY_MB=2048, MAX_MEMORY_MB=8192 and DEFAULT_DB_SIZE_LIMIT_BYTES=5368709120, alongside JOB_TIMEOUT_SECONDS=320, JOB_MAX_TRIES=3 and DEPLOYMENT_TIMEOUT_SECONDS=300. Those defaults matter more than they look: a build that exceeds the job timeout fails, and the retry count bounds how many times it will try again. Domains come from two variables. APP_HOSTNAME points at the control panel, DEPLOY_DOMAIN at the deployments, and the README's DNS step maps both example.com and *.example.com to the server IP, which is what makes per-deployment subdomains work. Certificates are issued through Let's Encrypt, with CERT_CHALLENGE_PROVIDER selecting default, cloudflare, route53, gcloud, digitalocean or azure, and CF_DNS_API_TOKEN available for the Cloudflare path.

Installing /dev/push on a fresh Ubuntu server

The README states the supported platforms plainly: Ubuntu 20.04+ or Debian 11+ with SSH access and sudo privileges, and it notes that other distributions may work but are not officially supported. You also need a GitHub account for the GitHub App and an email provider, either a Resend account or SMTP credentials, for login emails and invitations. Step one is the install script, which the README gives as a single command run on a fresh server.

bash
curl -fsSL https://install.devpu.sh | sudo bash

That script is scripts/install.sh in the repository, and its documented flags include --repo, --ref, --yes, --no-telemetry and --verbose. It sets up Docker, creates the service user, clones the repository and writes the environment file. Step two is creating a GitHub App through the guide at devpu.sh/docs/guides/create-github-app. Step three is editing /var/lib/devpush/.env. The template in the repository shows the shape of that file, and the README names the values you must fill: APP_HOSTNAME, DEPLOY_DOMAIN, LE_EMAIL, EMAIL_SENDER_ADDRESS, RESEND_API_KEY or the SMTP settings, and the GitHub App credentials. Secrets such as SECRET_KEY, ENCRYPTION_KEY and POSTGRES_PASSWORD are described as auto-generated by install.sh, so you normally leave those blank. Step four is DNS: an A record for example.com to the server IP and a wildcard A record for *.example.com to the same address. Step five starts the service.

bash
sudo systemctl start devpush.service

After that, the first real use is connecting a repository through the GitHub App and pushing a commit. The README's feature list says the result is a zero-downtime rollout with instant rollback and live, searchable build and runtime logs. If you prefer to run it from source instead, the development path uses Docker and Docker Compose v2+, with Colima suggested on macOS, and starts with ./scripts/start.sh after copying .env.dev.example to data/.env.

Where /dev/push is the wrong tool

The prerequisites are the first real limit. You need a server you administer, with sudo, on Ubuntu or Debian. If your team has no one who can SSH into a box, patch it and read systemd logs, a hosted platform is the cheaper answer regardless of licence. The GitHub App requirement is a second constraint. Login and repository access both flow through it, so GitLab, Bitbucket or a self-hosted Git server are not covered by the README. The email dependency is easy to underestimate: without Resend or SMTP credentials, login emails and team invitations do not go out, and the README treats an email provider as a prerequisite rather than an option. DNS is not optional either. The wildcard A record is what gives each deployment its own hostname, and if you cannot create one, the deployment model loses a piece. There is also a resource ceiling built into the defaults. MAX_CPUS=4.0, MAX_MEMORY_MB=8192 and DEFAULT_DB_SIZE_LIMIT_BYTES=5368709120 cap what a single deployment can consume, and DEPLOYMENT_TIMEOUT_SECONDS=300 caps how long a rollout may take. Those numbers are tunable in the environment file, but on a small VPS the ceiling is the machine, not the config. Finally, the README documents Ubuntu and Debian only and says other distributions are not officially supported yet. If your fleet is RHEL or Alpine, you are on your own.

How it differs from Dokploy and from Vercel itself

The searches around this project keep returning Dokploy, so the comparison is worth making concrete. Dokploy is the other self-hosted deployment panel that shows up in the same searches, and the related queries people type include Dokploy traefik, Dokploy postgres, Dokploy license and Dokploy update. The architectural difference visible in this repository is the runner catalog. /dev/push ships default runner and preset definitions in registry/, copies them to DATA_DIR/registry/ on install and update, and documents the catalog format and override rules in registry/README.md. That design makes the build environment something you can inspect and override on disk rather than something fixed by the panel. The second difference is the entry point: /dev/push is built around a GitHub App with a webhook secret, so the trigger is a repository event, and DEPLOY_DOMAIN plus a wildcard DNS record give each deployment its own subdomain. Against Vercel, the difference is not features but ownership. Vercel runs the build machines; /dev/push runs them on your server, which is why .env.example exposes CPU, memory, database size, job timeout and retry limits as settings. You get control over the ceiling and you get the bill for the machine. The README does not claim feature parity with any of these platforms, and the honest reading is that you are trading managed convenience for a stack you can read, fork and run yourself.

Maintenance, updates and the MIT licence

The last push to the repository was on 2026-03-03, and the most recent release listed is 0.4.6 from 2026-02-16, described as a fix for domains. That is roughly six months before today, so treat the project as one that ships occasionally rather than continuously. The repository is not archived. Upgrades are scripted, and the scope of an upgrade is the part to read carefully. The README's script table says scripts/update.sh updates by ref and that it defaults to the app component only, with --all, --full or --components available to widen the scope. If you assume a bare ./scripts/update.sh refreshes everything, you may leave database migrations or runner definitions behind. The same table lists scripts/db-migrate.sh for applying Alembic migrations with an optional --timeout, scripts/db-generate.sh for creating them, and scripts/backup.sh for archiving the data directory, the database and code metadata with --output and --verbose. A matching scripts/restore.sh takes --archive and can skip the database, data, code or restart steps. Backup and restore being first-class scripts is a point in the project's favour; the absence of a documented rollback procedure for a failed migration is a gap. The licence is MIT, which permits commercial and private use and modification, and the install script accepts a --no-telemetry flag. This is a description of the licence text, not legal advice; check the LICENSE.md file in the repository for the exact terms before you rely on them.

Editorial conclusion

Adopt /dev/push if you already run Ubuntu or Debian servers, want GitHub push-to-deploy and Let's Encrypt SSL without a per-seat bill, and can maintain a box yourself. Do not adopt it if you want a managed platform, Windows hosting, or a tool that installs without a GitHub App and two DNS records. Before you commit, verify that your server matches the stated Ubuntu 20.04+ or Debian 11+ prerequisite, decide whether you will use Resend or your own SMTP credentials, and read the update script's default scope, because scripts/update.sh updates the app component only unless you pass --all or --components.

Frequently asked questions

What is /dev/push?

/dev/push is an open-source, self-hostable deployment platform that the README describes as an alternative to Vercel, Render and Netlify. It builds and deploys apps written in Python, Node.js, PHP or anything else that runs on Docker, from GitHub, onto a server you control. It is MIT licensed.

What are the prerequisites for installing /dev/push?

The README lists a server running Ubuntu 20.04+ or Debian 11+ with SSH access and sudo privileges, a DNS provider (Cloudflare is recommended), a GitHub account for creating a GitHub App, and an email provider such as Resend or SMTP credentials. Other distributions may work but are not officially supported.

Does /dev/push support zero-downtime deployments and rollback?

The README's feature list states that Git-based deployments from GitHub use zero-downtime rollouts with instant rollback. The repository does not document a rollback procedure for a failed database migration, so that case is not covered by the README.

How do I update a /dev/push installation?

The README documents scripts/update.sh, which updates by ref and by default updates the app component only. Use --all, --full or --components to widen the scope. Database migrations are applied separately through scripts/db-migrate.sh.

What licence does /dev/push use?

The repository is MIT licensed, which allows commercial and private use and modification. The exact terms are in LICENSE.md; the install script also accepts a --no-telemetry flag.

Official sources

  1. hunvreus/devpush on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hunvreus-devpush.svg)](https://hysenlabs.com/projects/hunvreus-devpush)