Skip to main content

Install on a Linux server with Node

This page takes you from a bare Linux server to a site that starts and answers. It is for whoever manages the server. The commands assume Debian or Ubuntu and a user who can use sudo; adapt them to your system. The next two pages make it run permanently and put HTTPS in front of it.

You need the download and a licence key and Node.js 22.13 or newer on the server:

node --version

1. Make a user and unpack the software​

Run the site as its own user with no login, so it can write only to its own data folder.

sudo useradd --system --no-create-home --shell /usr/sbin/nologin choirmaster
sudo mkdir -p /opt/choirmaster
sudo tar -xzf choirmaster-cms-1.6.12.tar.gz -C /opt/choirmaster

The archive has no top-level folder, so -C into a folder that already exists is what keeps your files tidy. See What is in the download.

2. Make the data folder​

Everything the site keeps (the database, uploaded files, downloaded updates and copies made before an update) goes in a data folder. Make it, and give it to the site's user:

sudo mkdir -p /opt/choirmaster/data
sudo chown -R choirmaster:choirmaster /opt/choirmaster/data
sudo chmod 750 /opt/choirmaster/data

The code in /opt/choirmaster can stay owned by root. The site writes only inside data. A one-click update unpacks the new version into data/releases, not over the code.

warning

Where the data folder is depends on the folder the server is started from. SQLITE_PATH, STORAGE_LOCAL_DIR, DATA_DIR and the built website are all found relative to the working directory unless you give a full path. Either always start from /opt/choirmaster (the systemd unit on the next page does) or use full paths, as the file below does.

3. Write the settings file​

Keep the settings in a file only the site's user and root can read, because it holds passwords.

sudo mkdir -p /etc/choirmaster
sudo install -m 640 -o root -g choirmaster /dev/null /etc/choirmaster/env
sudo nano /etc/choirmaster/env

A starting point:

SITE_URL=https://choir.example.org
ADMIN_USERNAME=admin
ADMIN_PASSWORD=change-me-to-something-long-and-random
LICENSE_KEY=cmk_your_key_here

# Where things live: full paths, so the working directory does not matter
DATA_DIR=/opt/choirmaster/data
SQLITE_PATH=/opt/choirmaster/data/choir.sqlite
STORAGE_LOCAL_DIR=/opt/choirmaster/data/storage

# Email: choose a real service before you go live
EMAIL_PROVIDER=log
EMAIL_FROM="Harmony Community Choir <noreply@example.org>"

PORT (default 3001) and DATA_DIR must be real environment variables, as they are here. The launcher reads them before the server starts, so it does not see values that arrive only through a secrets manager or a NAME_FILE variable.

4. Check the settings​

cd /opt/choirmaster
sudo -u choirmaster node --env-file=/etc/choirmaster/env scripts/check-config.js

It prints what the server will use, with secrets hidden, then lists problems. Until you have a real email service you will see the log warning; that is expected. Anything else needs fixing. The command ends with a failure exit code whenever it lists any problem, even a warning. See Check your configuration.

5. Start it once by hand​

cd /opt/choirmaster
sudo -u choirmaster node --env-file=/etc/choirmaster/env server/launcher.js

You should see these lines, with some [config] warnings between the first two until the settings are complete:

[launcher] starting 1.6.12
[db] schema is up to date (sqlite)
[server] version 1.6.12 listening on http://localhost:3001 (production)

In a second terminal on the server:

curl http://localhost:3001/api/health
{"status":"ok","platform":"node","version":"1.6.12"}

Stop it with Ctrl+C. The server finishes what it is doing and exits. Now make it run for good: Run it as a systemd service.

npm start or start:direct​

CommandWhat it runsOne-click updates
npm startThe launcher, server/launcher.js, which starts the server.Yes.
npm run start:directThe server itself, server/entry/node.js.No: the site can only tell you about a new version and show the steps.

Use the launcher (the commands on this page do) unless you have a reason not to. npm does not read your settings file, so with either command you must provide the settings another way; that is why the examples use node --env-file=... directly.

Things to know​

  • The server listens on all network interfaces, and there is no setting to limit it to the local machine. Firewall port 3001 from the outside and let only your proxy reach it. Open ports 80 and 443 for the proxy.
  • Logs go to the terminal's standard output and standard error. There is no log file. systemd keeps them for you: see Logs and health checks.
  • Stopping with SIGTERM or SIGINT makes the server stop taking requests, close the database and exit, in at most five seconds.
  • A second copy on the same port fails with EADDRINUSE.

If something goes wrong​

What you seeWhat to do
Permission denied or unable to open database fileThe site's user cannot write to the data folder. Check step 2.
It starts, but the data is in the wrong placeYou started from a different folder and used relative paths. Use full paths as above.
[config] lines when it startsEach one names a setting to fix. See The site will not start, or ignores my settings.

Next​

  1. Run it as a systemd service
  2. Put it behind HTTPS
  3. After installing: first login and go-live checklist