Skip to main content

Add the first admin, and get back in when locked out

When each admin has a login of their own, someone has to be the first. This page shows the three ways to add an admin without being logged in, and what to do if email is down or the last admin has left. It is for whoever runs the server. It applies only to sites with ADMIN_AUTH=table; see Admin sign-in to choose.

Choose a way to start​

  • Keep the server's username and password. Set ADMIN_USERNAME and ADMIN_PASSWORD as well as ADMIN_AUTH=table. Log in at /admin/login with Use the server's username and password instead, open the Admins page and add the others. This needs no command line, and it leaves you a spare key. It is the easiest way.
  • Add an admin from the command line. Below. Use it when you chose not to set a password, or to add someone while locked out.

Add an admin from the command line​

The script puts the address in the admins table, creating the table first if it is missing. It does not send anything; the person then asks for a login link on the login page. Someone added this way is a Site Admin, the kind that can do everything.

On a Node server​

From the site's folder, with the settings that the server itself uses, so it finds the same database:

node --env-file=.env scripts/add-admin.js someone@example.org "Pat Example"

If your settings are already in the environment, the short form does the same:

npm run admin:add -- someone@example.org "Pat Example"

The name is optional. Settings reach scripts the same way as the server: see Give the server its settings. If the site's service runs as its own user, run the command as that user so that a SQLite database does not end up owned by someone else:

sudo -u choir node --env-file=.env scripts/add-admin.js someone@example.org "Pat Example"

In Docker​

The container already has the settings, so run the script inside it. For the Compose file in this guide the service is called app:

docker compose exec app npm run admin:add -- someone@example.org "Pat Example"

Without Compose, use the container's name or id: docker exec <container> npm run admin:add -- someone@example.org "Pat Example".

On Cloudflare​

The script cannot reach D1. Insert the row with Wrangler, using your D1 database's name from wrangler.toml:

npx wrangler d1 execute choir-db --remote --command "INSERT INTO admins (email, full_name) VALUES ('someone@example.org', 'Pat Example')"

The schema must already include the admins table; apply it first if you have just switched to table: Cloudflare D1. full_name can be left out. For an address already on the list this command fails; change it on the Admins page instead.

What the script says​

A terminal running the add-admin script with an address and name, printing that the address was added as an admin
A terminal running the add-admin script with an address and name, printing that the address was added as an admin
OutputMeaning
someone@example.org added as an admin.A new admin, active.
someone@example.org is already an admin; the account is active.The address (compared without regard to case) was on the list. It is now active again if it was disabled, and the name is updated if you gave one. Nothing else changes, including the kind of admin.
Note: ADMIN_AUTH is not "table", so the admins table is not in use yet.Printed after either line above. The admin is added, but the site still uses the shared username and password until you set ADMIN_AUTH=table.
Usage: npm run admin:add -- <email> ["Full Name"]The address is missing or is not an email address.

Node also prints a line saying SQLite is an experimental feature. That is harmless.

Log in as the new admin​

  1. Open /admin/login on your site.
  2. Enter the address in Email address and choose Email me a login link.
  3. Open the email within 15 minutes, on the device you want to use, and choose the Log in to the admin panel button in it. The login page then opens with a Log in button; choose that to finish.

If no email comes, Troubleshooting has the checks.

If you are locked out​

You are locked out when no admin can get a link, usually because email is down, the provider's key has expired, or the last admin has left. Any of these gets you back:

  1. Use the spare key. If ADMIN_USERNAME and ADMIN_PASSWORD are set on the server, log in with Use the server's username and password instead.
  2. Set them again. Add the two settings, restart (or deploy), and use them. Remove them again afterwards if you want links only.
  3. Add or re-enable an admin from the command line, as above, if the problem is the list and not email. Running the script for an existing address makes a disabled admin active again.
  4. Fix email. If it was email, nothing else is wrong: see the email pages and Check your configuration.

If the panel refuses a change because This is the only active admin. Add another admin first, or nobody could log in., that is the protection working: add a second admin, then make the change.