Command reference and what is where
This page lists the commands that come with the software, what each does, and where a running site keeps its files. It is for whoever runs the server.
Running a command
The commands are npm run scripts from the folder where you unpacked the download. They read the same settings as the server, so give them the same environment.
| Where | How |
|---|---|
| Node, settings in a file | node --env-file=choirmaster.env scripts/<script>.js, as in the examples below |
| Node, settings already in the environment | npm run <name> (for example in a shell where you have loaded them, or under a systemd ExecStart) |
| Docker | docker compose exec app npm run <name> (add -f docker-compose.sqlite.yml for the SQLite stack) |
| Cloudflare Workers | There is no server to run scripts against. The equivalent wrangler commands are in the table below. |
Passing arguments through npm run needs --: npm run admin:add -- someone@example.org "Their Name".
The commands
| Command | What it does | Cloudflare equivalent |
|---|---|---|
npm start | Starts the site through the launcher (node server/launcher.js). Runs the server, can install updates and go back. This is what production uses. | npx wrangler deploy |
npm run start:direct | Starts the server alone (node server/entry/node.js), with no launcher. No one-click updates (UPDATE_MODE is notify). For a platform that supervises the process itself, or for trying something. | Not applicable |
npm run db:migrate | Creates or updates the database schema. Only adds what is missing, so it is safe to run again. The server does this by itself at start-up unless DB_AUTO_MIGRATE=false. | npx wrangler d1 execute <database> --remote --file=./server/db/schema/sqlite.sql |
npm run db:seed-demo | Puts sample content into an empty database: three concerts, announcements, a weekly rehearsal and links. Does nothing if concerts already exist. | None |
npm run admin:add -- <email> ["Full Name"] | Adds an admin to the admins table, or re-enables one that is there. Used for the first admin when ADMIN_AUTH=table and no username and password are set. | npx wrangler d1 execute <database> --remote --command "INSERT INTO admins (email, full_name) VALUES ('someone@example.org', 'Their Name')" |
npm run config:check | Prints the settings the server would use (secrets masked) and lists problems. Exit code 1 if there are any. | None. Read the [config] lines in npx wrangler tail after a deploy. |
config:check
node --env-file=choirmaster.env scripts/check-config.js
Prints the settings in effect as JSON and then either No configuration problems found. or a list headed Problems:, and sets exit code 1 when there are problems. Its output, every setting and every problem message are on Check your configuration. Because it is not started by the launcher, its "mode" under updates reads notify even where the running site is in self mode.
db:migrate
$ node --env-file=choirmaster.env scripts/migrate.js
Schema applied to the sqlite database.
The last words are the database in use: sqlite, postgres or mysql. See How the database schema is kept up to date.
admin:add
$ node --env-file=choirmaster.env scripts/add-admin.js treasurer@example.org "Pat Example"
treasurer@example.org added as an admin.
Note: ADMIN_AUTH is not "table", so the admins table is not in use yet.
Run again for the same address it prints treasurer@example.org is already an admin; the account is active. and re-enables the account. Without a valid email address it prints Usage: npm run admin:add -- <email> ["Full Name"] and exits with code 1. The note appears whenever ADMIN_AUTH is not table: the admin is added but the table is not used until you set ADMIN_AUTH=table. See Add the first admin, and get back in when locked out.
db:seed-demo
$ node --env-file=choirmaster.env scripts/seed-demo.js
Demo content added.
Run on a database that already has concerts, it prints The database already has concerts; nothing seeded. Use it on a trial site. Do not run it on a real one.
After a one-click update
Commands you run by hand use the installed code, not a release the site downloaded for itself. This is harmless for these commands: a database schema from a newer version is only ever added to. If it matters (for example to run config:check against the new version's rules), unpack the new version and run it from there.
Scripts that are not for operators
package.json lists more scripts than the table above. These need the source code and its development tools, or belong to the publisher:
dev:client, dev:server, dev:worker, build, preview, test, deploy:cloudflare (builds from source), release, release:bundle, notices, start:hosted, tenant, tenants:migrate.
The hosted service's scripts (start:hosted, tenant, tenants:migrate) are for the multi-site hosted mode and are not used on a site of your own.
What is where on a running Node site
Two places matter: the install folder (code you replace on update) and the data directory (everything that is yours).
/srv/choirmaster/
choirmaster.env your settings (yours to keep)
app-1.6.12/ the install folder (the download unpacked)
dist/ the built site
server/ shared/ scripts/ node_modules/
site.config.json default settings, if you ship your own
package.json CHANGELOG.md LICENSE.md LICENSE.fr.md NOTICES.md
wrangler.toml.example wrangler.hosted.toml.example
data/ DATA_DIR, with the defaults:
choir.sqlite the database
choir.sqlite-wal recent changes (present while the site runs)
choir.sqlite-shm shared memory (present while the site runs)
storage/
public/images/ posters/ gallery/ past-events/ public files
private/member-files/ rehearsal-tracks/ member files and tracks
(each file is <timestamp>-<random>.<ext>, with a .meta.json beside it holding its content type)
releases/ downloaded releases, after a one-click update
state.json which release is in use
1.6.12/ a downloaded release
backups/
before-1.6.12-20261011T130500.sqlite copies made before updates (last three)
With PostgreSQL, MySQL or S3 storage, the matching parts are not on disk at all. With a different SQLITE_PATH, STORAGE_LOCAL_DIR or DATA_DIR, they are where those say. Each stored file has a .meta.json beside it; copy them together or the content type is guessed from the file name. See What to back up.
CM_RELEASES_DIR is set by the launcher for the server it starts, to tell it where downloaded releases are. It is internal. Never set it yourself. If you set it, the site believes the launcher is in charge, shows Update now, and then asks to be restarted into a release that nothing will start.
Useful addresses on your site
| Address | What it is |
|---|---|
/admin/login | The admin login. /admin leads to the dashboard, after login. |
/admin/dashboard | The admin dashboard. |
/admin/updates | The Updates page (Site Admins and Admins). |
/api/health | The health check: {"status":"ok","platform":"node","version":"1.6.12"}. No login needed. |
/member/login | The member portal login, where the portal is switched on. |
/files/<key> | A public file stored by the site, such as /files/images/1791738420452-05dc....png. Private files are never served from here. |
/p/<address> | A page an admin created under Pages; the address is the one set for the page. |
/unsubscribe | The page an email's "stop these emails" link leads to. |
/tickets, /donate, /gallery, /past-events, /auditions, /resources, /past-directors | Public pages that exist when their feature is switched on. |
The full list for visitors and admins is in Addresses on your site.