Skip to content

Deployment Guide

Tiffany Bennett edited this page Jul 1, 2025 · 4 revisions

Deployment

Building

Create a production build and place it in build/.

npm run build

Create a directory called deps and copy package.json and package-lock.json into it.

mkdir deps
cd deps
cp ../package* .
npm install --omit=dev

Copy build/, deps/node_modules/, data/, and package.json to your webserver.

rsync -rav build deps/node_modules data package.json package-lock.json your_server:/srv/unicode.link

Configuring + Running

The server can be started using node build/. It's configured by passing environment variables. Defaults:

PORT=3000 # The port to run on
NODE_ENV=production # You want this to be production
ORIGIN=https://your-instance.xyz # If you have it behind a reverse proxy, this is necessary to get the correct host name

systemd

Recommended config is to create a new user account for running this, to keep it from having any special privileges. I'm using /srv/unicode as the example home directory from here on.

You can then create a systemd unit file and install + enable it.

[Unit]
Description=Unicode Visualizer

[Service]
User=unicode # The user you want to run as.
Group=unicode
Environment=PORT=3000 # You'll probably want to pick a new one.
Environment=NODE_ENV=production
Environment=ORIGIN=https://your-instance.xyz # Change to your domain name.
ExecStart=/usr/bin/node /srv/unicode/build # Location of the files.
WorkingDirectory=/srv/unicode/
Restart=on-failure
RestartSec = 5

[Install]
WantedBy=multi-user.target

Reverse proxy

You'll want to serve this behind a web server for a couple of reasons:

  1. HTTPS.
  2. They're much faster at serving static files than anything possible to build in Node.
  3. I assume this is not the only thing running on your server.

nginx

location / {
  root /srv/unicode/build/client;
  # Tries each location in order.
  # 1. $uri means it tries to find a file named $uri in the root (above).
  # 2. @proxy then falls back to the Node server.
  try_files $uri @proxy;
}

location /_app/immutable {
  # All files under this subdir are content hash addressed, so they are completely immutable. No need to try the proxy for this subdir either.
  root /srv/unicode/build/client;
  add_header Cache-Control 'max-age=31536000, immutable';
}

# Named location for try_files to refer to.
location @proxy {
  proxy_pass http://127.0.0.1:3000;
}
Clone this wiki locally