Viewer Proxy & Auth
🔐 Viewer Proxy & Camera Mode#
First-Person vs Third-Person#
prismarine-viewer sets camera mode when the Node viewer starts — not from a browser query string:
# Third-person (default)
VIEWER_FIRST_PERSON=false
# First-person
VIEWER_FIRST_PERSON=true
Switch: set VIEWER_FIRST_PERSON=true on moincraft-viewer → pm2 reload ecosystem.config.cjs --update-env → pm2 save.
There is no supported ?view=first on the Prismarine web UI alone without changing server options or running a second viewer process on another port.
Securing /viewer/ Behind Nginx#
The Svelte app proxies /viewer/ to the viewer HTTP server. Put TLS + basic auth on the public hostname while keeping the viewer bound to localhost:
location /viewer/ {
auth_basic "Moincraft viewer";
auth_basic_user_file /etc/nginx/.htpasswd_viewer;
proxy_pass http://127.0.0.1:55669/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
Generate htpasswd:
sudo htpasswd -c /etc/nginx/.htpasswd_viewer youruser
Dashboard Iframe Security#
The dashboard uses VITE_USE_VIEWER_PROXY (default: on) so the iframe hits /viewer/ on the same origin as Vite, avoiding mixed-content issues when the dashboard is HTTPS and the viewer is HTTP.
Without the proxy:
- Dashboard at
https://moincraft.de+ viewer athttp://moincraft.de:55669= blocked by browser - Per-agent viewer ports always use direct
http(s)://<host>:<port>— if the dashboard is HTTPS, these must also be proxied
Full Viewer Config Reference#
PORT=55669 # web server port
VIEWER_USERNAME=Spectator # bot login name
VIEWER_VIEW_DISTANCE=8 # chunk radius
VIEWER_FIRST_PERSON=false # camera mode
VIEWER_RENDER_VERSION=1.21.4 # compat layer for 1.21.11 server
VIEWER_VERSION_FALLBACK=true # auto-fallback on version kick
VIEWER_RECONNECT_BASE_MS=5000 # reconnect start delay
VIEWER_RECONNECT_MAX_MS=60000 # reconnect cap
VIEWER_RECONNECT_JITTER_MS=1500 # random jitter
VIEWER_INITIAL_CONNECT_JITTER_MS=2000