Deploy from GitHub: take a web app live, step by step
Deploy a web app from your GitHub repository: connect GitHub, pick a branch, set build and start commands, and go live on HTTPS in India with auto-deploy.
To deploy a web app from GitHub on Voroa, connect your GitHub account, create a service from your
repository, confirm the build and start commands, and select Deploy. Voroa clones your branch,
builds it, starts it, and gives you a live HTTPS address such as your-app.onvoroa.com.
The short version:
- Connect GitHub and give Voroa access to the repository.
- Create a service and pick the repository and branch.
- Check the build and start commands (Voroa detects most apps for you).
- Add environment variables your app needs, such as a database URL or API key.
- Deploy and open the live URL.

The rest of this guide walks through each step, uses a web service as the example, and covers what to do when a deploy fails. Every step works the same way for the other service types.
What you need before you start
- A GitHub account and the repository you want to deploy. Private repositories work.
- An app that listens on a port. Voroa provides the port in the
PORTenvironment variable. Reading it (process.env.PORTin Node.js,$PORTin a shell command) is the most reliable setup. If your app listens on a fixed port of its own, Voroa detects that port and routes to it. - Your build and start commands, if your app needs anything beyond the defaults.
You do not need a Dockerfile, a server, or any hosting configuration. If you prefer to describe the build yourself, you can build from your own Dockerfile instead.
Choose your service type
Decide what Voroa should run for you. You can add more services later, and they can all live in the same workspace.
| Service type | What it runs | Typical frameworks |
|---|---|---|
| Web service | A server that answers HTTP requests. Gets a public URL and automatic HTTPS. | Express, Next.js, Django, Flask |
| Static site | Files you have already built and committed. Served directly, with no build step. | Any site whose output you commit |
| Background worker | A long-running process with no public URL, such as a queue consumer. | Any language |
| Cron job | A repository Voroa builds and runs on a schedule. | Any language |
| Scheduled task | A command run on a schedule inside a service you already have. | Any language |
Need a database as well? Voroa runs managed PostgreSQL and Key-Value as services you create the same way.
Step 1: Connect your GitHub account
From the dashboard, select Connect GitHub and install Voroa on the repositories you want to deploy. You also find the button on the new service form, under Git repository.

You can grant access to every repository or pick individual ones. You can change that list later from GitHub without touching your services.
Voroa reads only the repositories you select, and your code stays private.
Deploying a repository that belongs to a GitHub organization? GitHub may ask an organization owner to approve the installation before Voroa can see its repositories. If you are not an owner, GitHub sends them the request, and the repositories appear once they approve it.
Step 2: Create a service from your repository
Select New service and pick what you want to deploy.

Next, choose the repository, pick the branch to deploy, and give the service a name. The name becomes part of its default URL.

Two settings decide what Voroa builds:
- Branch. Voroa builds from this branch only and ignores pushes to every other branch until you
change the setting. Most teams deploy
main. - Root directory. Leave it as
/when the app sits at the top of the repository. In a monorepo, point it at the app’s folder, such as/apior/frontend.
You can change both later from Settings. See branch and root directory.
Step 3: Set your build and start commands
Voroa detects most apps and fills in these commands for you. Set them yourself when your app needs something specific, and change them at any time from Settings.
| Framework | Build command | Start command |
|---|---|---|
| Node.js | leave empty | npm start |
| Next.js | npm install && npm run build |
npm run start |
| Django | SECRET_KEY=collectstatic-only python manage.py collectstatic --noinput |
gunicorn myproject.wsgi --bind 0.0.0.0:$PORT |
| Flask | leave empty | gunicorn app:app --bind 0.0.0.0:$PORT |
Voroa installs your dependencies from package.json or requirements.txt on its own, so do not
repeat npm install or pip install unless the build needs it. Replace myproject with your Django
project’s name, and app:app with your Flask module and app object.
Two more settings sit under the commands on the same form:
- Pre-deploy command runs once after the build, before the new version goes live. Put database
migrations here, such as
python manage.py migrate --noinput. If it fails, the deploy stops and the current version keeps serving. - Health check path, such as
/healthz. If you set one, a deploy is marked Live only once that path answers with a 2xx status. Leave it blank to check only that the port answers.
Listen on the port Voroa gives you. Read
PORTfrom the environment and bind to0.0.0.0, not the loopback address, so traffic from outside the container reaches your app. If your app listens on a fixed port instead, Voroa detects it during the deploy and the deploy log names the port in use. An app that listens on more than one port is the one case Voroa cannot decide for you, and it asks which port serves your traffic.
See build and start commands for where each setting lives.
Step 4: Add your environment variables
Most real apps need configuration that should not live in the repository: a database connection
string, an API key, or a secret for signing sessions. Add these as environment variables on the
service before your first deploy, so the app has them the moment it starts. Open the service, go to
Environment, and select Add variable, or paste a whole .env file at once.

Voroa encrypts stored values, and nobody can read a value back after you save it. You can replace a value at any time. See environment variables, and use environment groups to share one set of variables across several services.
Step 5: Deploy and watch the build
Select Deploy. Voroa streams the build log live, and the timeline above it shows how far your deploy has got:
| Stage | What is happening |
|---|---|
| Queued | Waiting for a build slot. |
| Cloning | Fetching your branch from GitHub. |
| Building | Installing dependencies and running your build command. |
| Deploying | Starting the new version. |
| Live | The new version is serving traffic. |
If a stage fails, the log stops there, so you can see which step to fix. See deploy status for what each status means.
The service’s Deploys tab keeps every deploy, with its commit, status and duration:

Your app is live
Your service gets a free default address, your-app.onvoroa.com, with HTTPS already set up. Open
it and your app is running. The service Overview shows its status, plan and latest deployment:

Every service in a project appears in one list, with its status, runtime, plan and region:

Add a custom domain whenever you are ready.
Deploys do not take your site down
For web services and static sites, the version already running keeps serving until the new one is ready. A deploy that fails to start therefore leaves your site up. Background workers restart instead of overlapping, so a job is never picked up twice.
Roll back a bad deploy
If a new version goes live and misbehaves, open the service and select Manual Deploy > Rollback to previous version. Voroa brings back the version that was serving before, without rebuilding, so it completes in seconds. Rollback restores your code only; your environment variables and domains stay as they are. See deploy history and logs.

Deploy automatically on every git push
Turn on auto-deploy and every push to your branch ships a new build on its own. Pushes to other branches never deploy. See how to enable auto-deploy.
Common deploy problems and how to fix them
| What you see | Likely cause | What to do |
|---|---|---|
| The build fails while installing dependencies | A missing or outdated lock file, or a dependency that needs a newer runtime version | Read the last lines of the build log, fix the dependency, and push again |
| The build succeeds but the deploy never goes live | The app does not listen on the port, or it binds to the loopback address only | Read PORT from the environment and bind to 0.0.0.0 |
| The app crashes on start | A required environment variable is missing | Add the variable in Settings, then redeploy |
| Voroa builds the wrong app in a monorepo | The root directory points at the repository root | Set the root directory to the app’s folder |
| Your repository is missing from the list | Voroa does not have access to it yet | In GitHub, open Settings → Applications → Installed GitHub Apps, select Configure next to Voroa, and add the repository |
| A push does not trigger a deploy | Auto-deploy is off, or you pushed to a different branch | Check the service’s branch and turn on auto-deploy |
| The log says the new version was not ready in time | The app takes longer to start than the startup window | See the next section |
| The build succeeded but the service did not start | The app crashed or stopped while starting | Read the lines under Output from your service before it stopped in the deploy log |
If your service built but did not start
When a new version builds but does not come up, Voroa stops it and keeps your previous version serving. Before it stops the new version, Voroa copies its last 50 lines of output into the deploy log, under this heading:
==> Output from your service before it stopped
Each line starts with [app]. This is your own application’s output: an error, a stack trace, or a
missing environment variable usually shows up here. Fix it in your code or settings and deploy again.
If your service listens on a fixed port instead of reading PORT, Voroa detects the port it is
actually listening on. Depending on where your service runs, it either serves that port straight away
or the deploy log tells you the port and your next deploy uses it. Reading PORT from the environment
avoids both and is the simplest setup.
If your service is slow to start
After a build succeeds, Voroa starts the new version and waits for it to respond before it switches traffic across. If the new version does not respond within the startup window, Voroa abandons the deploy and the previous version keeps serving. The deploy log reads:
Deploy aborted - the new version was not ready within 180s.
Most services answer in a few seconds. Some take much longer on their first start: .NET and Java services, large JavaScript bundles, and apps that warm a cache or run a migration before they listen.
For a service like that, open it, go to Settings, and set Startup timeout to the number of seconds it actually needs. Leave the field blank to use the platform default. The new value applies from your next deploy.
Keep two things in mind before you raise it:
- A failed deploy is not an outage. The running version keeps serving, so a longer window costs you nothing on a service that is already live. The exception is your very first deploy, which has no previous version; the log says so plainly.
- Raise it to what you need, not to the maximum. Waiting time counts towards your build minutes and holds one of your account’s build slots. An over-long window on a broken service costs you minutes and delays the moment you learn it is broken.
If your service has an endpoint that answers only once it is truly ready, set Health check path as well. Voroa then waits for that path to return a success status instead of only checking that the port is open.
Frequently asked questions
Can I deploy a private GitHub repository?
Yes. When you connect GitHub, you choose exactly which repositories Voroa can read, private ones included. Voroa reads only those repositories, and your code is never made public. You can add or remove repositories later from your GitHub settings.
Does Voroa redeploy when I push to GitHub?
Yes, once you turn on auto-deploy. Every push to the service’s branch starts a new build, and pushes to other branches are ignored. With auto-deploy off, you deploy by selecting Deploy in the dashboard. See auto-deploy.
Do I need a Dockerfile to deploy from GitHub?
No. Voroa reads your repository and works out how to build most apps on its own. A Dockerfile is optional; use one when your app needs a system package, a runtime version Voroa does not detect, or a non-standard build. See deploy with Docker.
How do I deploy one app from a monorepo?
Create a service for each app and set its root directory to that app’s folder, for example
/api. Each service then builds and deploys only its own folder. See
branch and root directory.
Why can’t I see my repository after connecting GitHub?
Voroa sees only the repositories you granted it. In GitHub, open Settings → Applications → Installed GitHub Apps (use the organization’s settings for an organization repository), select Configure next to Voroa, and add the repository. You can also select Manage GitHub access next to the repository field in Voroa. See connect GitHub.
Can I switch a service to a different repository later?
Yes. Open the service, go to Settings, and edit Source under Build & Deploy. The service keeps its name, URL, domains and environment variables. See change a service’s repository.
Is this different from GitHub Pages?
Yes. GitHub Pages serves static files only, so it cannot run a Node.js, Python or other server. Voroa builds and runs your app as a real server process, and can also host static sites, background workers, cron jobs and managed databases next to it.
Do I need GitHub Actions to deploy from GitHub?
No. Voroa receives the push from GitHub directly, then builds and deploys, so there is no workflow file to write or maintain. If you already run tests in GitHub Actions and want to deploy only after they pass, turn auto-deploy off and call a deploy hook as the last step of your workflow.
Can I deploy from a Git host other than GitHub?
Yes, from any Git URL, public or private. See deploy from a Git URL.
Is deploying from GitHub free?
Yes, on the Free plan. It includes free web services that sleep when idle, one free database and monthly build minutes, with no credit card. See free instances for the exact limits.
Can I deploy a branch other than main?
Yes. Pick any branch when you create the service, and change it later from Settings. Voroa builds only from the branch you choose.
Will my site go down if a deploy fails?
No, as long as a previous version is running. For web services and static sites, the current version keeps serving until the new one is ready. If the new version fails, traffic never moves to it.
Deploy guides for your framework
Each guide covers the build, the start command, and going live: