Put it online
Publish the dashboard and its API on a server with Docker, or the dashboard on Vercel or any Node.js host.
For the Full Stack package
Before you deploy
Before going live. Every seed (yarn seed, yarn seed:prod and the first Docker start) creates sample admins whose passwords are printed in the guides. Change their passwords or delete them, and set your own JWT_SECRET, before the dashboard is reachable by anyone else.
- Run the API with
NODE_ENV=production, your ownJWT_SECRET, andCORS_ORIGINandFRONTEND_URLset to the dashboard's public address. A production API refuses to start without the first two. - Behind a reverse proxy (Nginx, Caddy, a load balancer), set
TRUST_PROXY=1, so the sign-in limit counts visitors instead of the proxy. - Leave
DEMO_MODEandNEXT_PUBLIC_DEMO_MODEoff, unless the deployment is a public demo.
Before you deploy
Built without an API address, the dashboard runs on its mock API: the sample accounts are in the app's code and are checked in the browser, so anyone can read them and sign in, and every change stays in the visitor's browser. Point it at your API before real users or real data reach it.
The built-in mock APILeave NEXT_PUBLIC_DEMO_MODE off unless the deployment is a public demo.
Both apps on one server with Docker
The docker-compose.yml that runs the template locally also runs it on a server. Give each app its own domain behind a web server that adds HTTPS, such as Caddy or Nginx, forwarding the dashboard's domain to port 3030 and the API's to port 8000.
Name the two addresses
Create
.envin thedashboard-2-full-stackfolder, besidedocker-compose.yml. The dashboard compiles the API's address into its JavaScript, and the API allows the dashboard's address inCORS_ORIGINandFRONTEND_URL, both from these two lines.dashboard-2-full-stack/.envDASHBOARD_URL=https://admin.your-domain.com API_URL=https://api.your-domain.comAdd your keys
The API also reads
back-end/.envwhen it exists, for the AI provider keys, R2 and the MCP key. Create it from.env.exampleand addTRUST_PROXY=1behind your web server. The compose file sets the database, the port andNODE_ENV=productionitself, and the API generates aJWT_SECRETinto the data volume when you give none.Terminalindashboard-2-full-stackcp back-end/.env.example back-end/.envStart it in the background
Terminalindashboard-2-full-stackdocker compose up --build -dExpected result:
https://api.your-domain.com/api/healthanswers"status":"ok", and the dashboard's domain opens the sign-in page.
The services restart with the server. The database lives in the dashboard-2-data volume. After you change DASHBOARD_URL, API_URL or a port, run docker compose up --build -d again: the dashboard has to be built with the new address.
The API on its own
back-end has its own Dockerfile, so any host that builds from a Dockerfile can run the API alone. The container keeps its SQLite database in /data: mount a volume there, or the data is lost with the container. On a new volume it creates the database with the sample data once.
back-enddocker build -t dashboard-api .
docker run -d --restart unless-stopped -p 8000:8000 -v dashboard-data:/data -e CORS_ORIGIN=https://admin.your-domain.com -e FRONTEND_URL=https://admin.your-domain.com dashboard-apiThe image already runs with NODE_ENV=production and its SQLite file in /data. Pass only the values you need, each with -e, such as -e GOOGLE_API_KEY=.... The usual way to run the API is still docker compose up --build at the package root, which starts it with the dashboard.
On a Node.js host without Docker, the build command is yarn build, the start command yarn start:prod, and yarn seed:prod runs once to create the tables. A SQLite file needs a persistent disk there; on a host without one, use MySQL.
The dashboard on Vercel
Put the dashboard in a private Git repository
Push the dashboard's folder (
front-endin the Full Stack,dashboard-2-front-endin the Admin Dashboard package) to a private repository on GitHub, GitLab or Bitbucket. Your licence does not allow sharing the source code publicly.Import it in Vercel
Add a new project from that repository. Vercel detects Next.js; keep the default build settings. In the Full Stack repository, set the project's root directory to
front-end.Add the environment variables
Add
ENABLE_EXPERIMENTAL_COREPACKwith the value1, so Vercel installs with the Yarn versionpackage.jsonpins. ThenNEXT_PUBLIC_API_BASE_URL(your API with/api),NEXT_PUBLIC_WEBSOCKET_BASE_URL(the same address without/api) andNEXT_PUBLIC_BASE_URL(the dashboard's own address).WEATHER_API_KEYis optional.Deploy
Start the deployment, then add your domain in the project's Domains settings, and add that address to the API's
CORS_ORIGINandFRONTEND_URL.Expected result: Your domain opens the sign-in page.
After you change a NEXT_PUBLIC_* variable, deploy again: the running app keeps the values it was built with.
The dashboard on a Node.js server
With your settings in the dashboard's .env, install, build and start:
corepack enable
yarn install
yarn build
yarn startIt answers on port 3030, or on PORT when the host sets one. Put a web server in front of it for your domain and HTTPS, and keep yarn start running with a process manager or a system service.
The dashboard as a Docker image
The dashboard's Dockerfile builds a standalone server on port 3030, run as a user without admin rights. The API's address is a build argument:
docker build -t dashboard-2 --build-arg NEXT_PUBLIC_API_BASE_URL=https://api.your-domain.com/api --build-arg NEXT_PUBLIC_WEBSOCKET_BASE_URL=https://api.your-domain.com --build-arg NEXT_PUBLIC_BASE_URL=https://admin.your-domain.com .
docker run -d --restart unless-stopped -p 3030:3030 dashboard-2WEATHER_API_KEY is read when the container runs: add -e WEATHER_API_KEY=... to docker run.
After it is online
- Sign in at your dashboard's address, with
/enand/ar, and check both languages. - Every page tells search engines not to index it, through an
X-Robots-Tag: noindex, nofollowheader set innext.config.js, because a signed-in dashboard does not belong in search results.