+## Up And Running
+
+Customize configuration within `config/${NODE_ENV}.js`. All envs inherit settings from `default.js` if not specified. Environment is selected using the `NODE_ENV` environment variable value, defaulting to `development` if unset.
+
+Database table initialization and schema version migrations are automated. Configure SQLite with a database file, or point PostgreSQL to a created database.
+
+Users currently need to be created via the cli, using the `bin/authAddUser.js` script.
+
+The bundled logger spews JSON to stdout.
+
+### Quickstart Example
+
+One way of deploying this server is behind nginx, with the pm2 package to manage the server process, and a local postgres database. Some details on this are presented here as a rough guide to any parts of this stack which may be unfamiliar.
+
+- Have NodeJS 20-ish available.
+- Have PostgreSQL available.
+- Clone the server repository.
+ ```git clone https://git.squeep.com/squeep-indie-auther```
+- Install the production dependencies.
+ ```cd squeep-indie-auther```
+ ```NODE_ENV=production npm i```
+- Create a ```config/production.js``` configuration file. See ```config/default.js``` for available settings.
+ > <pre>
+ > 'use strict';
+ > // Minimum required configuration settings
+ > module.exports = {
+ > encryptionSecret: 'this is a secret passphrase, it is pretty important to be unguessable',
+ > dingus: {
+ > selfBaseUrl: 'https://ia.squeep.com/', // it needs to know how to refer to itself
+ > },
+ > db: {
+ > connectionString: 'postgresql://indieauther:mypassword@localhost/indieauther',
+ > },
+ > chores: { // These are optional, but recommended
+ > scopeCleanupMs: 86400000, // remove unused scopes daily
+ > tokenCleanupMs: 864000000, // remove invalid tokens daily
+ > publishTicketsMs: 86400000, // retry queuing redeemed tickets daily
+ > },
+ > };
+ > </pre>
+- Prepare PostgreSQL with a user and database, using e.g. ```psql```.
+ > <pre>
+ > CREATE ROLE indieauther WITH CREATEDB LOGIN PASSWORD 'mypassword';
+ > GRANT indieauther TO postgres;
+ > CREATE DATABASE indieauther OWNER=indieauther;
+ > GRANT ALL PRIVILEGES ON DATABASE indieauther TO indieauther;
+ > \c indieauther
+ > CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
+ > </pre>
+- Install a process manager, system-wide.
+ ```npm i -g pm2```
+- Configure the process manager to keep the server logs from growing unbounded.
+ ```pm2 install pm2-logrotate```
+ ```pm2 set pm2-logrotate:rotateInterval '0 0 1 * *'``` (rotate monthly)
+ ```pm2 set pm2-logrotate:compress true```
+ ```pm2 startup``` (arrange to start process monitor on system boot)
+- Launch the server, running one process per available CPU, and persist it through reboots.
+ ```NODE_ENV=production pm2 start server.js --name indieauther -i max```
+ ```pm2 save```
+- Create a user.
+ ```NODE_ENV=production node bin/authUserAdd.js myusername```
+- Optional: Copy or link the static files to somewhere nginx will serve them from. This will vary greatly depending on your setup.
+ ```cp -rp static /home/indieauther/ia.squeep.com/html/static```
+- Expose the server through nginx.
+ > <pre>
+ > server {
+ > listen 443 ssl http2;
+ > ssl_certificate /etc/ssl/nginx/server-chain.pem;
+ > ssl_certificate_key /etc/ssl/nginx/server.key;
+ > server_name ia.squeep.com;
+ > root /home/indieauther/ia.squeep.com/html
+ > try_files $uri $uri/ @indieauther;
+ >
+ > location @indieauther {
+ > proxy_pass http://indieauther$uri;
+ > proxy_set_header Host $host;
+ > proxy_set_header X-Forwarded-For $remote_addr;
+ > proxy_set_header X-Forwarded-Proto $scheme;
+ > proxy_http_version 1.1;
+ > }
+ >
+ > location = / {
+ > proxy_pass http://indieauther$is_args$args;
+ > proxy_set_header Host $host;
+ > proxy_set_header X-Forwarded-For $remote_addr;
+ > proxy_set_header X-Forwarded-Proto $scheme;
+ > proxy_http_version 1.1;
+ > }
+ > }
+ > </pre>
+ ```nginx -s reload```
+- The IndieAuth IdP server should now be available!
+
+## Caveats
+
+While this service supports multiple users, currently these users must all be trusted due to profile registration being unconstrained. A future version may restrict profile assignment to a privileged user tier.
+