Skip to content
Levelrail

Deploy a Next.js app on every git push with Levelrail

Once a repository is an app's git source, a push is the deploy button. This guide prepares a Next.js app for a container build, connects the repository with a webhook, and follows a push from delivery to live traffic.

  • Practitioner
  • 3 min read
On this page

Before you start

  • A Levelrail control plane on your server with the CLI signed in. Deploy a Next.js app on your own server covers the install.
  • A primary domain set in the control plane's ingress settings, because GitHub needs a reachable callback address.
  • A Next.js app in a GitHub repository.

What happens on a push

Connecting the repository registers a webhook on it. Each push posts to the control plane, which checks the signature against the app's own webhook secret. A push to the tracked branch is queued, built and deployed, and traffic moves to the new release only after it passes its readiness check. Every delivery is recorded, so a push that did not deploy leaves a trace you can read.

Prepare the app

  1. Step 1Build a standalone server

    Set output to standalone in the Next.js config. The build then emits a small self contained server, which keeps the runtime image small.

    next.config.ts
    import type { NextConfig } from "next";
    
    const nextConfig: NextConfig = {
      output: "standalone",
    };
    
    export default nextConfig;
  2. Step 2Write the Dockerfile from the preset

    The CLI prints the Next.js preset's multi stage Dockerfile, which runs the server as a non root user. Save it at the repository root and commit it.

    bash
    levelrail-cli build frameworks nextjs --dockerfile > Dockerfile
    git add Dockerfile next.config.ts
    git commit -m "build: add a container build"

Connect the repository

  1. Step 3Connect GitHub to the control plane

    In the dashboard, open the GitHub App settings page (/settings/github-app), choose the account or organization that owns the repository, and create the App. The browser goes to GitHub and the credentials come back on their own. Install the App on the repository you want to deploy.

  2. Step 4Create the app from the repository

    Create the app with the git build path. This runs the first build and deploy. For a private repository, pick it in the dashboard's new app wizard instead, which lists the repositories the connected App can see.

    bash
    levelrail-cli apps create --name storefront --port 3000 \
      --repo https://github.com/acme/storefront.git --image-repo storefront
  3. Step 5Make the repository the app's git source

    use-as-source connects the repository and registers the push webhook in the same call. The output shows the webhook address and webhook_registered: true. If it says false with a webhook_error, the App installation predates the webhook permission: update its permissions on GitHub and run the command again.

    bash
    levelrail-cli github-app use-as-source acme storefront --app-name storefront --branch main
  4. Step 6Check that deploys can read the branch

    validate reads the branch with the credential a deploy would use and names the fix when it cannot: a missing credential, a rejected token, a missing branch or an unreachable host.

    bash
    levelrail-cli apps git-source validate storefront
  5. Step 7Set runtime secrets

    Values the server reads at runtime go in the app's encrypted secrets. --apply restarts the app so the running container gets them.

    bash
    levelrail-cli apps secrets set storefront AUTH_SECRET "$AUTH_SECRET" --apply

Push and watch

  1. Step 8Push a commit

    Push to the tracked branch. The webhook is answered with 202 deploy queued as soon as the attempt is recorded, and the build runs in the background.

    bash
    git push origin main
  2. Step 9Follow the release until it takes traffic

    deploy status --watch prints the release's gate timeline: readiness passes, the stable window, cutover and the post deploy watch. It exits 0 when the release is healthy and 7 when it failed or was rolled back, so it also works in a script.

    bash
    levelrail-cli deploy status storefront --watch

Give it a domain

Point a DNS record at the server, then add the domain to the app. The built in ingress requests and renews the certificate.

bash
levelrail-cli domains add storefront shop.example.com

If a push does not deploy

  • Open the app's Source tab. Its recent webhook deliveries panel lists every request, with a bad signature, an ignored ref or a failed deploy marked as such.
  • A push to another branch is accepted and ignored. Pull requests deploy previews only when previews are turned on for the app.
  • With the trigger mode set to release, branch pushes never deploy; only a tag push or a published GitHub release does.
  • A push whose commit is already deployed or in flight is ignored, so pushing the same commit again does nothing.
Questions

Frequently asked questions

Does a push to another branch deploy?

No. A push whose branch does not match the git source is accepted and ignored. Pull request events are handled separately and deploy previews when previews are enabled.

Can I deploy only when I publish a release?

Yes. Set the git source's trigger mode to release. Then only a tag push, or on GitHub a published release, deploys, and branch pushes never do.

Which git hosts can trigger deploys?

GitHub, GitLab, Bitbucket and Gitea, with Forgejo connecting like Gitea. All of them post to the same webhook route, and the provider is detected from the request headers.

Keep going
Next steps

Take it further with Levelrail

The product page covers what it does, how to install it and where the docs live.