Deployment
The marketing/docs site and the local dashboard app are different
deploy surfaces. The Astro site deploys to Cloudflare for
neondeck.dev. The local app runs on the user's machine.
Astro site
The site lives in docs/ and builds to static assets.
npm run docs:build
npm run docs:preview
Cloudflare deploy
npm run docs:deploy
Wrangler config lives at docs/wrangler.jsonc. It deploys
the built docs/dist assets to the
neondeck-site Worker with custom domains for
neondeck.dev and www.neondeck.dev. Merges to main that change the site or its build inputs are automatically built and deployed
by the docs deployment workflow. Use npm run docs:deploy for
a controlled manual redeploy.
Validation
cd docs
npx wrangler deploy --dry-run
Use a dry run before important deploys to validate the Worker config and asset bundle without publishing.
Local app packaging
The local app builds the React dashboard and Flue Node server. It uses runtime-home config and secrets on the user's machine, not Cloudflare Worker secrets.
npm run build:dashboard
npm run package:app
npm run release:app
Use SSH forwarding for remote access
SSH forwarding is the simplest option for one operator and keeps
Neondeck inside its default loopback trust boundary. It requires
neither nginx nor server.trustedOrigins. First, keep the
packaged Neondeck service running on the exe.dev instance:
neondeck service install
neondeck service status
From the computer running the browser, forward a local port to
Neondeck's loopback port on the instance. Replace
user@instance with the SSH destination used for that exe.dev
instance:
ssh -N \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=30 \
-L 8000:127.0.0.1:3583 \
user@instance
Leave that SSH process running and open
http://127.0.0.1:8000/ in the local browser. The left side
of -L is the local browser port; change it if port
8000 is already in use. The right side remains
127.0.0.1:3583, the packaged Neondeck server on the
remote instance.
curl http://127.0.0.1:8000/api/health
Run Neondeck on exe.dev with nginx
A packaged Neondeck server exposes the complete dashboard and API on
loopback port 3583. Port 5173 belongs only to
the Vite source-development dashboard. On an exe.dev instance, nginx can
accept the instance's authenticated HTTPS traffic on port
8000 and proxy it to Neondeck. Unlike SSH forwarding, this
stable external origin must be explicitly trusted by Neondeck.
Trust the external browser origin
Add the exact exe.dev origin to runtime-home
config.json, replacing the example hostname with the one
assigned to the instance. Merge the server block into the existing
file rather than replacing its generated token or other settings:
{
"version": 1,
"server": {
"trustedOrigins": ["https://example.exe.xyz"]
}
}
Configure nginx
Preserve the public Host header so Neondeck can match it to
the configured origin. Disable proxy buffering and extend the read timeout
for dashboard server-sent events and long-poll responses. WebSocket upgrade
headers are not required.
server {
listen 8000;
server_name _;
location / {
proxy_pass http://127.0.0.1:3583;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 1h;
proxy_send_timeout 1h;
}
}
Restart and validate
sudo nginx -t
sudo systemctl reload nginx
neondeck service install
neondeck service status
curl -i \
-H 'Host: example.exe.xyz' \
http://127.0.0.1:8000/api/health
Restart or reinstall the Neondeck service after changing
server.trustedOrigins; the trust policy is loaded at
process startup. The health request should return a successful
response instead of the intentionally opaque 404 used for untrusted
hosts.
Domain
The public docs domain is neondeck.dev. The local
packaged dashboard normally runs at http://127.0.0.1:3583/. During source development, Vite serves the dashboard on
http://127.0.0.1:5173/ and proxies API traffic to port
3583.