Skip to main content
The backend self-hosting guide gets the Flexprice API and its infrastructure running. This guide covers the other half: running the Flexprice dashboard (flexprice-front) yourself and pointing it at that backend.
Complete the backend self-hosting guide first. The frontend is a static single-page app that talks to the API over HTTP; it has no database or infrastructure of its own.

Self-hosting options

Docker Compose

Run the dashboard in a container alongside your self-hosted backend. Best for a single server.

Manual build

Build static files with npm run build and serve them with nginx or any static host.

Vercel

Deploy the same repo to Vercel using the bundled vercel.json.

Self-hosted environment configuration

Before you build or deploy anything, set these. They’re the three variables that actually change how the app behaves in a self-hosted setup, and getting them wrong is the single most common way this deployment breaks:
The .env.example file defaults VITE_AUTH_PROVIDER to supabase and leaves VITE_APP_ENV unset (which falls back to local). If you skip setting these two values, login and signup will silently try to reach Supabase instead of your backend.
With VITE_APP_ENV=self-hosted set, you do not need to fill in VITE_SUPABASE_URL or VITE_SUPABASE_ANON_KEY — leave them blank.
Vite bakes every VITE_* variable into the static bundle at build time, not at container start. Whenever you change .env, you must rebuild (docker compose up -d --build, or npm run build again) before the change takes effect. This trips people up more than anything else in this guide, see Troubleshooting.

Full environment variable reference


First login: create your account

A self-hosted instance starts with no dashboard users. There’s no default username or password: every account, including your first one, is created through Sign Up against your own backend:
1

Open the dashboard

Once your container or dev server is running, visit it in a browser (e.g. http://localhost:3000).
2

Use Sign Up, not Login

On the auth screen, switch to the Sign Up tab and enter an email and password (6+ characters).
3

You're in immediately

In self-hosted mode, sign-up skips email verification entirely: the app posts straight to your backend’s /auth/signup endpoint and logs you in right away using the returned session token. There’s no confirmation email to wait for.
If Sign Up fails with a network or CORS error instead of a validation error, that’s almost always VITE_API_URL or backend CORS, not the auth flow itself. See Troubleshooting.

Docker Compose

Prerequisites

Node.js 20+ and npm (only needed for a manual build; skip if you’re using Docker exclusively)
A running Flexprice backend, reachable over HTTP from wherever the frontend runs. See the backend self-hosting guide.

Quick start

Edit .env with at least the three variables from self-hosted environment configuration above, then build and start the container:
Use --build here, and every time you change .env afterward. docker compose up -d alone reuses a cached image if one already exists, which silently keeps your old environment variables since Vite bakes them in at build time.
The docker-compose.yml in the repo builds the image from the included Dockerfile (a multi-stage Node 20 build) and exposes the dashboard on port 3000 with a built-in healthcheck.
Visit http://localhost:3000 once the container reports healthy, then follow First login to create your account.

Manual build and serve

If you’d rather not use Docker, build static files and serve them yourself.
This produces a static dist/ folder. Serve it with any of the following:
Copy the repo’s nginx.conf (SPA fallback already configured) and point it at dist/:
Whatever you use to serve the built files, it must fall back to index.html for unknown paths (a single-page app client-side router). The bundled nginx.conf handles this with try_files $uri $uri/ /index.html;. If you configure your own web server, replicate this rule or client-side routes like /customers/123 will 404 on a hard refresh.

Deploying on Vercel

The repo includes a vercel.json with the SPA rewrite already configured (/(.*) → /), so you can deploy directly:
  1. Import the flexprice-front repository into Vercel.
  2. Set the environment variables from the reference above in the Vercel project settings (VITE_APP_ENV=self-hosted, VITE_AUTH_PROVIDER=flexprice, VITE_API_URL, and any optional ones you need).
  3. Deploy. Vercel runs npm run build automatically and serves the dist/ output.
Your backend must be reachable from the public internet (or accessible to wherever your Vercel deployment resolves VITE_API_URL) since Vercel doesn’t proxy to a private network by default.

Connecting to the backend

  • VITE_API_URL is baked into the JavaScript bundle and fetched by the end user’s browser, not by the Docker container or server that built it. Use an address the browser can actually reach: the host machine’s real IP or domain, not a Docker-internal hostname. http://localhost:8080/v1 only works if the person opening the dashboard is on the same machine as the backend.
  • CORS: the Flexprice API needs to allow requests from the origin the dashboard is served on. If you’re serving the frontend from a different domain or port than the API expects, configure the backend’s CORS allow-list accordingly (see the backend self-hosting guide and configuration reference).
  • Login and signup (/auth/login, /auth/signup) are public endpoints: they don’t require an API key. After you log in, the dashboard authenticates every other request with the session token from that login, not with a Flexprice API key. You only need an API key (e.g. for testing with curl) if you’re calling the API directly, outside the dashboard.

Troubleshooting

VITE_APP_ENV is not set to self-hosted, or VITE_AUTH_PROVIDER is still supabase (the .env.example default). Set both explicitly and rebuild, since Vite environment variables are baked in at build time, not read at container start.
Confirm VITE_APP_ENV=self-hosted was set at build time. If it wasn’t, sign-up falls back to the Supabase flow and waits for an email confirmation that will never arrive on a self-hosted instance with no email provider configured.
The web server isn’t falling back to index.html for unknown paths. Use the bundled nginx.conf, or add an equivalent SPA fallback rule to your own server config.
  1. Confirm VITE_API_URL is reachable from your browser, not just from the container network:
  1. Check the browser console for a CORS error. If present, add the frontend’s origin to the backend’s CORS configuration.
  2. Remember Vite bakes VITE_* variables in at build time. Changing .env after npm run build requires rebuilding.
Vite environment variables are compiled into the static bundle at build time, they aren’t read at runtime. Rebuild the image (docker compose up -d --build) or rerun npm run build, then restart the container or server.
The bundled healthcheck curls http://localhost:3000 inside the container; a non-2xx response usually means the build failed or the app crashed on start. Check the logs above for the actual error.

Need help?

Additional resources

Backend Self-Hosting Guide

Run the Flexprice API and infrastructure

Configuration Reference

Complete list of Flexprice environment variables

Contribution Guidelines

Learn how to contribute to the frontend

Flexprice Website

Visit our official website