Builds
Apprail turns your repository into an immutable image — from your Dockerfile, or from your framework when there isn’t one — and deploys it through the normal health-checked path. Or bring an image you built yourself.
Deploy on every push with GitHub
On a service’s page, choose Connect GitHub, install the Apprail GitHub app on the repositories you pick, then choose the repository, branch, build context, and Dockerfile path. Apprail builds and deploys right away and then on every push to that branch. Private repositories work; the app only asks to read contents and write commit statuses.
- Each commit gets an
apprail/buildstatus on GitHub: pending while building, success once the image is built and its deployment is queued, failure if the build fails. - Only the branch’s current head is built. A delayed or out-of-order push for an older commit is ignored.
- Rebuild now in the console, or
apprail build shop/web --rebuild, builds the linked branch without a push. - Removing the app, or a repository from it, stops automatic deploys for that repository.
apprail build shop/web --rebuildBuild any public repository
Without the GitHub app, build a public HTTPS repository on GitHub, GitLab, or Bitbucket by URL. Give the exact branch, tag, or commit; Apprail doesn’t guess.
apprail build shop/web --git https://github.com/acme/shop --ref main --context services/webWith a Dockerfile
If the build context contains a Dockerfile (or the path you configured), Apprail builds exactly that with BuildKit. Nothing is changed or added. This is the most predictable option for anything unusual.
Without a Dockerfile
When there’s no Dockerfile, Apprail looks for a known framework in the build context and generates one:
| Found | Built as | Started with |
|---|---|---|
package.json | Node.js 22. Installs with npm, pnpm, or yarn depending on the lockfile, then runs the build script if there is one | scripts.start, or a Procfile |
go.mod | A Go binary in a minimal image | The binary, or a Procfile command |
requirements.txt | Python 3.13 with pip | A Procfile; Django projects fall back to manage.py runserver |
- A
Procfile’sweb:line always wins over the default start command. - If the lockfile has drifted from
package.json, the strict install falls back to a normal one instead of failing the build. - If Apprail finds a framework but no way to start it, the build fails straight away and says what’s missing.
- Not covered yet: pnpm/yarn workspaces, Poetry, and Pipenv. Add a Dockerfile for those.
Static sites
Vite, Astro, Create React App, and Next.js with output: "export" — when they have no production start command — are built and served as static files from a small, unprivileged web server.
- Files with a content hash in their name are cached for a year; HTML and everything else are never cached, so a new deploy or a rollback is visible immediately with nothing to purge.
- Vite and Create React App fall back to
index.htmlfor client-side routes; Astro and Next exports return a real 404. - Add a Netlify-style
_redirectsfile (up to 100 rules,301/302/303/307/308,/*and:splat) and a_headersfile with a/*section (up to 20 headers) at the repository root or inpublic/. A mistake fails the build with the line that’s wrong.
# _redirects /blog/* /articles/:splat 301 /old https://example.com/new 308 # _headers /* X-Frame-Options: DENY Referrer-Policy: strict-origin-when-cross-origin
Monorepos
Link several services to the same repository and branch, each with its own build context (services/api, services/web). A push rebuilds only the services whose context contains a changed file. If a service also depends on shared code elsewhere, add up to 20 watch paths (such as packages/shared) to its GitHub settings. A service whose context is the repository root rebuilds on every push, and so does every service when GitHub doesn’t say which files changed.
Deploy an image
Skip the build and deploy any image by tag or digest. Tags are resolved to a digest when you deploy, so a release always runs exactly the image it was created with.
apprail deploy shop/web --image ghcr.io/acme/web:1.4Private registries
Add a credential once per registry host; deployments from that host use it automatically. Passwords are stored encrypted and never shown again. Rotating updates it in place, so older releases can still be pulled for rollback, and a credential that retained releases depend on can’t be deleted.
echo "$GHCR_TOKEN" | apprail registries add ghcr --registry ghcr.io --username acme --password-stdin
apprail registriesBuild limits
| Limit | Value |
|---|---|
| Time | 30 minutes per build |
| Resources | 2 CPUs and 4 GB of memory, 20 GB of scratch disk |
| Network | Public HTTPS only — fetching packages works; reaching private networks doesn’t |
| Logs | The build output is kept with the build and shown in the console |
A failed or cancelled build never changes what’s live. Build minutes are counted in usage.