Requirements
Read this before you choose a server. It lists what the software needs from the machine, the network and your domain. It is for whoever sets up the server.
The software
| Requirement | Detail |
|---|---|
| Node.js 22.13.0 or newer | Set by the engines entry in package.json. The Docker route needs no Node on your machine, because the container brings its own. |
| Nothing to compile | The database module for SQLite is built into Node (node:sqlite), so there is no database driver to build. The download's dependencies are installed with install scripts switched off, and it runs as it is. |
| One process | A single Node process serves the API and the built website together, on port 3001 unless you set PORT. There is no separate web server for the site itself. |
The download is already built, and its node_modules folder holds everything the server needs. You do not run npm install or npm run build. The server's own dependencies are Hono and its Node adapter (the web server), aws4fetch (signed requests to S3 storage and Amazon SES), pg (PostgreSQL), mysql2 (MySQL and MariaDB), ioredis (Redis sessions) and nodemailer (SMTP email).
On Node 22, starting the server prints a warning that SQLite is "an experimental feature". It is harmless. The site works normally.
A domain with HTTPS
A real site must be served over HTTPS, on a domain name of its own.
In production the site marks its login cookies Secure, so a browser only keeps them over HTTPS. The flag is set from the site's own mode, not from what the proxy tells it, so a forwarded X-Forwarded-Proto: https header does not change it. Over plain http:// an admin or member logs in, and the next click sends them back to the login page.
The site does not provide HTTPS itself. You put a reverse proxy in front of it, or use a platform that provides HTTPS. See Put it behind HTTPS. Only a trial on your own computer runs over http://; see Try it on your own computer.
You also set SITE_URL to the site's public address, and the site builds every emailed link from it.
Email
Email is not optional on a working site. Members have no passwords: they log in with a link sent by email. Announcements, ticket confirmations and receipts are email too.
Until you set EMAIL_PROVIDER the site only writes each email to its log. Choose a service in Email: what the site sends and how to choose a provider. On Cloudflare Workers, SMTP is not available; every other provider works.
A disk that keeps its files
By default everything is kept in a data folder beside the code:
| What | Where | Setting |
|---|---|---|
| The SQLite database | ./data/choir.sqlite | SQLITE_PATH |
| Uploaded files (photos, posters, member files, rehearsal tracks) | ./data/storage | STORAGE_LOCAL_DIR |
| Releases the site downloaded for itself, and copies of the database made before an update | ./data/releases and ./data/backups | DATA_DIR |
Those folders must be writable by the user the server runs as, and they must survive a restart. A relative path is worked out from the folder the server is started in.
On a platform where the disk is thrown away when the app restarts or is redeployed (many container and "platform as a service" hosts), do not rely on ./data. Use instead:
- PostgreSQL or MySQL for the database: see Choose a database;
- S3-compatible storage for the files: see How files are stored;
UPDATE_MODE=notify, so the site does not try to unpack releases onto a disk that will be wiped: see How updates work.
Run one instance if you use SQLite. With several instances, use PostgreSQL or MySQL, S3 storage and UPDATE_MODE=notify.
What it needs from the network
- Inbound: the proxy reaches the app on its port (3001 by default). The app listens on all network interfaces, so firewall that port from the outside and open only 80 and 443.
- Outbound: to your email service, to your database and storage if they are elsewhere, and, once you set a licence key, to the release server at
updates.choirmastercms.comfor update checks. The optional writing assistant calls the Anthropic API when you give it a key.
How big a server
There are no sizing figures to give. Cloudflare's free plan is enough for a choir-sized site, and a small server is a reasonable place to start on the other routes. Start small and watch the logs.
Check yourself
node --version
The answer must be v22.13.0 or higher.