Skip to main content
Lovable builds the app. Ankra runs it, on your cluster, behind HTTPS, with every change built and scanned first. You do not stop prompting in Lovable. Lovable commits to your GitHub repository, and Ankra builds every commit.
An app built in Lovable is synced to your GitHub repository. One Ankra command builds it, scans it, deploys it to your cluster and prints a live HTTPS address. The app keeps talking to its Supabase project, and every later edit in Lovable is rebuilt and redeployed.

One command from a Lovable repository to a live address


Ship it in four steps

1

Connect Lovable to GitHub

In Lovable, open the project’s GitHub settings and connect a repository. Lovable commits every change to it from then on. This is the only link between the two.
2

Add one file

Ankra builds whatever Dockerfile it finds, and a Lovable project has none. Add this one at the repository root and commit it to the branch Lovable tracks.
It builds the app with Vite and serves the result with nginx. The try_files line is what makes a refresh on /dashboard/settings return the app instead of a 404, and /healthz gives the cluster something to probe. The Supabase address Lovable committed in .env is built into the app, so it keeps talking to the same backend.
3

Ship it

From a clone of the repository, with the CLI logged in:
Ankra registers the repository, builds the image in your cluster, scans it, applies your organisation’s image gate, deploys it, waits until it is running and prints:
The address comes from the cluster’s generated ankra.cc domain, with a certificate. If you run the command again it carries on from where it stopped.
Ankra pipelines need a person to approve the pipeline definition once. If the build stops with a refused step, run ankra pipeline get --application <name> --latest, which prints the exact approve command, and run it as yourself.
4

Tell Supabase where the app lives

In your Supabase project, open Authentication then URL Configuration. Set Site URL to the live address and add it to Redirect URLs. A sign-in that bounces to the wrong host is almost always this list.
That is the whole setup. Edit in Lovable, Lovable commits, Ankra builds and deploys.

Use your own domain

Add one option to the same command:
Ankra’s DNS automation covers the generated subdomain only. For a zone of your own, store a DNS credential and serve the zone from the cluster once:
If the name currently points at Lovable’s own hosting, remove it there first. Then add the new address to Supabase’s redirect list. See Domains and DNS.

What you get without asking

  • Scans on every change. Semgrep over the source, Checkov over the manifests and Trivy over the image, judged against your organisation’s gate before anything is published. A generated app is mostly code you did not write, so this is where an unsafe pattern or a leaked key shows up.
  • An immutable tag per commit. Every deployment is a sha- tag, so going back is deploying an earlier one.
  • Tests when you add them. Ankra adds a test stage only when package.json has a test script. Lovable projects usually have none, so the pipeline starts at the build, and a test stage appears the day you add a script.
  • An AI review. Ankra reads every pull request and watches every run, and opens a fix when a build breaks.
Check what was found with ankra pipeline findings <run-id> --application <name>.
The Supabase address and the publishable key are public by design, because every visitor’s browser holds them and Row Level Security protects the data. The service role key is the opposite. It must never be in the repository or in any VITE_ variable. If it appears anywhere in the tree, rotate it in Supabase before you go on.

Add a development environment

Everything above gives you one running copy. When real users depend on the app, add a second cluster and a second Supabase project so each change is proved before production sees it.
An app built in Lovable is committed to GitHub. An Ankra pipeline tests, builds, scans and gates it and publishes an immutable tag. The tag is deployed to a development cluster and proved there, then promoted unchanged to a production cluster. Each environment talks to its own Supabase project, and one image serves both because the backend address is injected when the container starts.

One image, two environments: the backend address is injected when the container starts

Vite builds the Supabase address into the JavaScript, so an image built for one project cannot serve another. The fix is to build with two placeholders and let the container fill them in when it starts. Replace the Dockerfile with this one, still a single file:
Variables that exist in the environment take priority over the .env Lovable commits, so the placeholders win and the committed address never reaches the bundle. A container started without either variable exits at once, naming the one that is missing. Check the variable names against your .env: older projects use VITE_SUPABASE_ANON_KEY.
1

Give each cluster its own values

Each cluster holds a small Secret with its project’s address and publishable key. Add it to that cluster’s file, then seal it:
The stack that declares it also needs a shop-web namespace manifest as its parent, with names prefixed lovable-runtime- because manifest names are unique across a cluster. See SOPS Encryption.
2

Deploy to development

3

Promote the tag that passed

Turn auto-deploy off so production never follows a push, then deploy the exact tag you tested:
Nothing is rebuilt, so what you tested is what runs. To roll back, deploy an earlier tag the same way. A rollback changes the running image only; it does not undo a Supabase migration.
The database lives in Supabase, so its backups and point-in-time recovery are Supabase settings. Switch them on for the production project before the first real user.

Verify

Then open the address, reload a nested page, and sign up and sign in once. A green deployment is not a working app; the sign-in is the check that catches the Supabase redirect list.

Troubleshooting

Expected for a Lovable project: its package.json has no start script, so there is nothing for Ankra to guess. Add the Dockerfile from step 2 and run ship again. Ankra builds whatever Dockerfile it finds and never overwrites it.
The try_files $uri /index.html; line is missing from the nginx config, or the config was not copied into the image.
The Supabase Site URL or Redirect URLs do not include the new address. Fix them in the project that environment uses.
The function allows a fixed list of origins that does not include the new address. Add it and redeploy the functions with supabase functions deploy.
A scanner found something above your threshold. ankra pipeline findings <run-id> --application <name> lists it, worst first. Fix the dependency or the code, or accept it deliberately and write down why.
Only the two-environment Dockerfile does this, on purpose. The Secret is missing from the namespace or env_from_secrets was not passed. ankra cluster get resources Secret --namespace shop-web --cluster <cluster-id> shows what exists.
The zone was not declared for that cluster, so no record was published. Run ankra cluster custom-dns-zones list <cluster> and add it with its credential.

Next steps

Ship an application

The general route from a repository to a deployment, for apps that did not start in Lovable.

Ankra Pipelines

What every stage does, how the gate decides, and how authority is approved.

Prompt to Production

The same development-then-production discipline for apps you build from a written plan.

Pull request previews

A live preview and an AI review on every pull request.