Deploy an app from a Git repository
Create an instance from a Git repository: Nextify clones it at the first boot, builds it and runs it as a service. Use a read-only deploy key for private repositories, pass settings and secrets as environment variables, read the deploy's output, and redeploy after each push.
You can create an instance straight from a Git repository. At its first boot, Nextify clones the repository, builds it and runs your app as a service that restarts if it stops. When you push new code, Redeploy pulls it, builds it and restarts the app. Public repositories need only their URL; private ones use a deploy key that Nextify creates for you.
This article covers:
- Deploying a public repository
- Private repositories and deploy keys
- Runtime, build and start commands
- The port and the firewall
- Environment variables and secrets
- The deploy's output, and when a deploy fails
- Redeploying
- Doing it through the API
1. Deploy a public repository
- In the portal, open Instances → Create instance and choose the region, plan and SSH keys as usual. Choose an Ubuntu or Debian image: the deploy installs what your app needs with
apt. - Open 6. Startup script, labels and environment and choose Deploy from Git.
- Enter the Repository URL, for example
https://github.com/your-org/your-app.git. Leave the other fields as they are to start with. - Click Create instance.
A deploy from Git replaces the startup script: an instance has one or the other. An instance restored from a snapshot does neither.
Use the https:// URL exactly as your Git host shows it, without a user name or token in it. For a private repository, use its SSH URL and a deploy key instead (section 2).
2. Private repositories and deploy keys
A deploy key is an SSH key that gives read access to one repository. Nextify creates the key pair, keeps the private half encrypted and gives it only to the instances that use the key. You add the public half to your repository.
- Open Account → Deploy keys, enter a name (for example the repository's name) and click Create deploy key. You can also click Create a deploy key in the Deploy from Git form, without leaving it.
- Copy the public key that is shown. It starts with
ssh-ed25519. - Add it to the repository as a read-only deploy key:
- GitHub: the repository's Settings → Deploy keys → Add deploy key. Paste the key, give it a title and leave Allow write access unticked.
- GitLab: the project's Settings → Repository → Deploy keys → Add new key. Paste the key, give it a title and leave Grant write permissions to this key unticked.
- In the Deploy from Git form, enter the repository's SSH URL, for example
git@github.com:your-org/your-app.git, and choose the key under Deploy key.
Good to know:
- An SSH URL always needs a deploy key, and a deploy key only works with an SSH URL. The form tells you if they do not match, and offers the SSH form of an https URL.
- GitHub accepts each deploy key on one repository only. Create one key per repository.
- The page shows each key's fingerprint (
SHA256:...), the same one GitHub and GitLab show, so you can tell which key is which. - Deleting a key on Account → Deploy keys stops new instances from using it. Instances that already have it keep their copy and can still redeploy: remove the key from the repository to cut them off.
- An account can hold up to 50 deploy keys.
3. Runtime, build and start commands
Runtime is Auto by default: Nextify looks at the repository and picks one:
| The repository has | Runtime | Build, when left empty | Start, when left empty |
|---|---|---|---|
package.json | Node.js | npm ci (or npm install), then npm run build if there is one | npm start |
requirements.txt or pyproject.toml | Python | pip install into a virtualenv | none: give one |
go.mod | Go | go build | the built program |
Gemfile | Ruby | bundle install | bundle exec rackup on $PORT |
composer.json or index.php | PHP | none | PHP's built-in server on $PORT, from public/ if there is one |
| anything else | Static | none | a small web server for dist/, build/ or public/ (else the whole repository) |
- A
Procfilewith aweb:line sets the start command, unless you enter one. - Build command and Start command are one line each. To run several commands, join them with
&&, or put them in a script in your repository. - Both run as the user
appin the checkout (/opt/app/src), with your environment variables andPORTset. A Python app gets its own virtualenv, already on thePATH. - Python has no default start command: enter one, for example
gunicorn app:app --bind 0.0.0.0:$PORT, or add aProcfile. - The runtime comes from the image's own packages, for example the Node.js version that Ubuntu ships. If your app needs another version, install it in a startup script on a plain instance instead.
- Choose a runtime yourself when the detection picks the wrong one, for example a static site that has a
package.jsonfor its tooling.
4. The port and the firewall
Your app must listen on the port in the PORT environment variable, on all addresses (0.0.0.0). The Port field sets it: 8080 unless you change it. Port 22 is SSH and cannot be used.
Nextify opens that port to the internet for you: the security group app-tcp-<port> (for example app-tcp-8080), which allows inbound TCP on that port from anywhere, is created the first time it is needed and added to the instance. The instance's page links to http://<public IP>:<port>/.
To serve your app on port 80 or 443 with a domain and a certificate, put a load balancer in front of it.
5. Environment variables and secrets
Add settings under Environment & secrets, as for any instance: plain variables, and secrets for passwords and API keys, which Nextify stores encrypted and never shows again. The build and the app get them all in their environment. Keep secrets out of the repository.
When you change a variable later on the instance's Setup & environment tab, redeploy (section 7) so the app restarts with the new value.
See Startup scripts and secrets for how variables and secrets work.
6. The deploy's output, and when a deploy fails
On the instance's page, open Setup & environment. The App from Git card shows the repository, branch or tag, runtime, port and deploy key. Below it, the Setup log shows the deploy's status and output: the first boot's, or the last redeploy's. It is read from the server and follows the deploy while it runs.
A deploy ends when the app has started and is still running a few seconds later. If it fails, the end of the setup log says why. Common causes:
- The clone failed: the URL is wrong, the repository is private and has no deploy key, or the deploy key was not added to the repository (or not to this one).
- The build failed: read the build's error in the log. Run the same command on your own computer first.
- The app did not stay up: the log ends with the app's last lines of output. Often the app listens on another port than
PORT, or only on127.0.0.1, or a setting is missing. - No start command: add one, or a
Procfilewith aweb:line.
On the server itself: the app runs as the service nextify-app (journalctl -u nextify-app shows its output), the checkout is in /opt/app/src, and every deploy's output is in /var/log/nextify-app-deploy.log.
7. Redeploy
After you push to the branch or tag, click Redeploy on the App from Git card. Nextify pulls the latest commit, builds it and restarts the app. The card shows the progress, and the setup log shows the new deploy's output when it ends.
- The instance must be running. One deploy runs at a time.
- If the build fails, the app is not restarted.
- The repository, branch and commands are set when the instance is created. To change them, create a new instance.
8. Through the API
Create a deploy key with POST /v1/deploy-keys, then create the instance with source instead of user_data:
curl -sS -X POST https://api.nextifynow.com/v1/instances \
-H "Authorization: Bearer $NEXTIFY_TOKEN" -H "Content-Type: application/json" \
-d '{"name": "shop-1", "machine_type": "sm1.s1-1", "region": "us-west-1", "image": "ubuntu-24.04",
"source": {"git": {"url": "git@github.com:your-org/shop.git", "ref": "main", "port": 3000,
"deploy_key_id": "<id from POST /v1/deploy-keys>"}}}'
POST /v1/instances/{id}/redeploy redeploys and answers a job_id to follow. A webhook endpoint can get instance.app_deployed and instance.app_deploy_failed after every deploy, so you can redeploy from your CI pipeline and hear back. The API documentation has a complete example.
Good to know
- The first deploy runs at the first boot, so the app is up a few minutes after the instance is.
- The setup log keeps the last deploy's output only. The file
/var/log/nextify-app-deploy.logon the server keeps them all. - Deploying from Git sets up one app per instance. For several instances behind one address, create them from the same repository and add them to a load balancer.