Deploy a Lovable export
Take the app Lovable built you and put it on a live HTTPS URL of your own.
Lovable exports a standard Vite + React project, so deploying it on Dockhold is the Vite path with two export-specific steps: get the code onto GitHub, and carry over any environment variables Lovable used. This recipe is the whole path.
1. Get the code on GitHub
In Lovable, connect the project to GitHub (the GitHub option in your project's settings) so your code lives in a repository you own. That repo is what Dockhold deploys.
2. Add a start command that serves the build
A Lovable export already has a build script. Add a small static
server so the built app is served on the port Dockhold assigns:
npm install --save-dev serve Then make sure package.json has:
{
"scripts": {
"build": "vite build",
"start": "serve -s dist -l $PORT"
}
}
Your app must listen on 0.0.0.0 and read its port from the
PORT environment variable — never localhost, never a
hardcoded port. Dockhold assigns PORT at runtime; an app that
ignores it can't receive traffic.
Then add a Dockerfile at the repo root so the export is built before it's served:
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
RUN npm install -g serve@14
COPY --from=build /app/dist ./dist
# Shell form so $PORT expands at runtime
CMD serve -s dist -l $PORT Without the Dockerfile, the build system can serve an exported SPA as raw source — you'll get a blank page. The Dockerfile builds it first.
3. Carry over your Supabase config
A Lovable app talks to Supabase using a project URL and an
anon key. By default the export reads them from
VITE_-prefixed variables that Vite inlines into the build, which
means baking them into the repo. The cleaner path on Dockhold is to set them
in the dashboard and read them at runtime:
the container writes your dashboard values into the page when it starts, and
your code reads them from window.__APP_CONFIG__ instead of
import.meta.env. You can then change or rotate them in the
dashboard with no rebuild. The
full-stack recipe and the
fullstack-web template
show the exact setup — point your Supabase client at the runtime values the
same way.
A Supabase anon key is designed to be public, so it's safe in the browser — but a service-role key is not, and neither is any other real secret. Keep those on a server (your own API or a Next.js route handler), never in the frontend bundle.
4. Connect the repo and deploy
- Open the dashboard, connect GitHub, and pick the repo.
- Dockhold builds from your Dockerfile and runs it.
Your app goes live at https://<your-app>.dockhold.app
with HTTPS handled for you. Every later push to your main branch redeploys.
Troubleshooting
- Blank page, and the browser is fetching
/src/main.jsx: the un-built source is being served — make sure theDockerfileis at the repo root so the export is built first. - 404 on refresh of a client route: keep the
-sflag (serve -s dist) — it sends client-side routes toindex.html. - "Failed to fetch" / Supabase calls fail: the Supabase URL
or anon key isn't reaching the app. Set them as dashboard variables and
make sure your client reads the runtime values (
window.__APP_CONFIG__), then restart.
Next
- The full Vite + React recipe
- Agent rules — make your AI tool generate Dockhold-ready apps.
- All recipes