Viewer guide
Run without Docker
A systemd unit that runs the Viewer from a checkout, the four settings that unit gets wrong by default, and how to update it later.
Docker is the shortest path; see Deploy the Viewer. This page is for a Linux host where you would rather run the process directly.
There is no bundled process manager and no published package: the Viewer runs from a monorepo checkout. A systemd unit is the shortest path on a Linux host.
You need Node 24 or newer and git on the host. The Viewer needs git of its own too: it clones each repository it builds.
Clone the repository once, at /opt/desde:
git clone https://github.com/desde-design/desde.git /opt/desdeThen, from /opt/desde:
npm installnpm install --prefix viewernpm run build --prefix viewerThere is no bridge to build. The script the Viewer adds to every prototype it serves is committed, and kept current with its source on every commit.
The last command is next build. It is required: the start script sets NODE_ENV=production, which makes the process serve the prebuilt .next directory instead of compiling on demand. Skip it and routes go missing with no error.
Note that start does not read viewer/.env.local; only the :local scripts do. So systemd supplies the environment:
[Unit]
Description=Desde Viewer
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=desde
WorkingDirectory=/opt/desde
EnvironmentFile=/etc/desde/viewer.env
ExecStart=/usr/bin/npm run start --prefix viewer
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetPut that at /etc/systemd/system/desde-viewer.service, then:
sudo systemctl enable --now desde-viewerA few notes on that unit:
- Set
VIEWER_DATA_DIRto an absolute path in the environment file. Its default,.desde-viewer, is relative and resolves against the working directory. Start the process from two different directories and you get two different databases with no warning. - Confirm the npm path with
which npm: it is not/usr/bin/npmon every distribution or under a version manager. EnvironmentFilehas the same one-line-values constraint as Docker's--env-file, so use the base64 form of the App private key here too.- The process handles
SIGTERMand shuts down cleanly: it marks any in-flight buildfailed(otherwise it staysbuildingforever in the UI) and closes the database. Do not configureKillMode=processor a shortTimeoutStopSec.
Updating#
Updating a checkout is a pull, the same install and build commands, and a restart. Take a backup first, for the reason on Upgrading: the database is migrated forward at startup and there is no way back except the backup.
From /opt/desde:
git pullnpm install && npm install --prefix viewernpm run build --prefix viewersudo systemctl restart desde-viewerDo not skip the build. next build is what the production start script serves, so an old build means old screens with no error to tell you so. The pull brings the new bridge script with it, and the restart loads it.
systemctl restart stops the process cleanly, so a build running at that moment is recorded as failed rather than left half done. Run it again afterwards.
Upgrading covers the rest, and all of it applies here: keeping the data directory and any VIEWER_SESSION_SECRET you set unchanged so nobody is signed out, and why rolling back means restoring the backup rather than checking out an older commit.