And this is the final one for now…any pointers or suggestions for any of the above would be very welcome!
These are all done from the repo copies, with env vars at end of this message, and variation for each server as noted.
From ketty server logs:
Node.js v18.18.2
+ node_modules/.bin/coko-server migrate
+ node scripts/runners/createGlobalTeams.js
Seeding global teams...
Global team "productionEditor" already exists
Global team "admin" already exists
+ node scripts/runners/createAdmin.js
### CREATING ADMIN USER ###
>>> checking if admin user with provided email and username already exists...
>>> an admin user already exists with that credentials in the system
+ node scripts/runners/createApplicationParameters.js
truncate table application parameter
New Application Parameter created: "VANILLA"
New Application Parameter created: [{"title":"Upload","type":"upload"},{"title":"File Prep","type":"file_prep"},{"title":"Edit","type":"edit"},{"title":"Review","type":"review"},{"title":"Clean Up","type":"clean_up"},{"title":"Page Check","type":"page_check"},{"title":"Final","type":"final"}]
New Application Parameter created: [{"name":"Frontmatter","showNumberBeforeComponents":[],"allowedComponentTypes":[{"value":"component","title":"Component","predefined":true,"visibleInHeader":true},{"value":"introduction","title":"Introduction","predefined":true,"visibleInHeader":false},{"value":"preface","title":"Preface","predefined":true,"visibleInHeader":false},{"value":"halftitle","title":"Half Title","predefined":true,"visibleInHeader":false},{"value":"titlepage","title":"Title Page","predefined":true,"visibleInHeader":false},{"value":"cover","title":"Cover","predefined":true,"visibleInHeader":false}],"defaultComponentType":"component"},{"name":"Body","showNumberBeforeComponents":["part","chapter"],"allowedComponentTypes":[{"value":"part","title":"Part","predefined":true,"visibleInHeader":true},{"value":"chapter","title":"Chapter","predefined":true,"visibleInHeader":true},{"value":"unnumbered","title":"Unnumbered","predefined":true,"visibleInHeader":true}],"defaultComponentType":"chapter"},{"name":"Backmatter","showNumberBeforeComponents":[],"allowedComponentTypes":[{"value":"component","title":"Component","predefined":true,"visibleInHeader":true},{"value":"appendix","title":"Appendix","predefined":true,"visibleInHeader":false},{"value":"endnotes","title":"notes placeholder","visibleInHeader":true,"predefined":true}],"defaultComponentType":"component"}]
New Application Parameter created: true
New Application Parameter created: false
New Application Parameter created: "10000"
+ exec node ./startServer.js
executing locks clean-up procedure
Registered component @coko/server/src/models/serviceCredential
Registered component @coko/server/src/models/user
Registered component @coko/server/src/models/identity
Registered component @coko/server/src/models/team
Registered component @coko/server/src/models/teamMember
Registered component @coko/server/src/models/file
Registered component @coko/server/src/services/chatGPT
Registered component ./models/applicationParameter
Registered component ./models/book
Registered component ./models/lock
Registered component ./models/bookCollection
Registered component ./models/bookCollectionTranslation
Registered component ./models/bookComponent
Registered component ./models/bookComponentState
Registered component ./models/bookComponentTranslation
Registered component ./models/bookSettings
Registered component ./models/invitations
Registered component ./models/bookTranslation
Registered component ./models/customTag
Registered component ./models/division
Registered component ./models/template
Registered component ./models/file
Registered component ./models/team
Registered component ./models/teamMember
Registered component ./models/user
Registered component ./models/dataloader
Registered component ./models/serviceCredential
Registered component ./models/serviceCallbackToken
Registered component ./models/exportProfile
Registered component ./api/graphql
Registered component ./api/rest
Registered server component ./api/rest
Coko server => Registering graphql middleware...
Coko server => Middleware: Registered authorization middleware
Starting HTTP server
App is listening on port 3000
Subscribing job callbacks to the job queue
Job refresh-token-expired: subscribed
/home/node/server/startServer.js:64
throw new Error(e)
^
Error: SyntaxError: Unexpected end of JSON input
at init (/home/node/server/startServer.js:64:11)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Env vars:
export THIS_HOST=<local-host-ip>
export SERVER_SERVE_CLIENT=false
export FEATURE_POD=true
export SERVER_IDENTIFIER=main_server_id
# SERVER-specific:
export KETIDA_FLAVOUR=LULU
export PUBSWEET_SECRET=server_pubsweet_secret
export ADMIN_USERNAME=admin
export ADMIN_PASSWORD=<secret>
export ADMIN_SURNAME=<surname>
export ADMIN_GIVEN_NAME=<given_name>
export ADMIN_EMAIL=<some-email>
export FEATURE_UPLOAD_DOCX_FILES=true
export FEATURE_BOOK_STRUCTURE=false
# SERVER_PROTOCOL, SERVER_HOST and SERVER_PORT are the parts of the server url, as in http://localhost:3000
SERVER_PROTOCOL=http
SERVER_HOST=${THIS_HOST}
KETTY_SERVER_PORT=3000
# This varies based on caontainer!
SERVER_PORT=${KETTY_SERVER_PORT}
# Client????
export CLIENT_PORT=4000
export CLIENT_HOST=${THIS_HOST}
export CLIENT_PROTOCOL=http
export CLIENT_URL=${CLIENT_PROTOCOL}://${CLIENT_HOST}:${CLIENT_PORT}
# The url that the client can be found at. This exists for two reasons: (a) to whitelist the client url at the CORS
# configuration, so that we don’t run into cross-origin errors in the browser and (b) to construct links that could
# eg. be constructed on the server, but shown in an email
export CLIENT_URL=
# SERVER_PROTOCOL, SERVER_HOST and SERVER_PORT are the parts of the server url, as in http://localhost:3000
export SERVER_PROTOCOL=http
export SERVER_HOST=${THIS_HOST}
export SERVER_PORT=3000
# The url (including port), where the server can be found. This is necessary for implementing callbacks from external services
export SERVER_URL=${SERVER_PROTOCOL}://${SERVER_HOST}:${SERVER_PORT}
# WEBSOCKET????
# - Port
export WS_SERVER_PORT=3333
export WS_PROTOCOL=ws
export WS_HOST=${THIS_HOST}
export WS_HEARTBEAT_INTERVAL=3000
# - URL
# The url (including port) where the websocket server can be found. The websocket server currently exists for handling
# locks, i.e. to know when a user is editing a chapter so that other users cannot edit it.
# ????
export WEBSOCKET_SERVER_URL=${WS_PROTOCOL}://${WS_HOST}:${WS_SERVER_PORT}
# DB connection
export POSTGRES_USER=ketty_prod
export POSTGRES_PASSWORD=ketty_prod
export POSTGRES_HOST=10.158.1.128
export POSTGRES_DB=ketty_prod
export POSTGRES_PORT=5432
# NODE Environment -- seems to be hard coded in places?
export NODE_ENV=production
# How often the heartbeat event for the lock-related socket connections will be happening
export WS_HEARTBEAT_INTERVAL=
# How often the server should check for expired locks that might need to be cleaned up
export FAIL_SAFE_UNLOCKING_INTERVAL=12000
# MAILER_*** variables:
# these can be left empty, but you will have trouble signing up with new users and verifying their accounts. I would
# recommend using a free service like https://ethereal.email/ to get some credentials and “receive” emails as a link
# in the terminal where you’re running the app
#MAILER_USER=${MAILER_USER}
#MAILER_PASSWORD=${MAILER_PASSWORD}
#MAILER_SENDER=${MAILER_SENDER}
#MAILER_HOSTNAME=${MAILER_HOSTNAME}
# the location of your s3 compatible server, protocol is http or https
export S3_PROTOCOL=https
export S3_HOST=<aws-s3-host-name>
export S3_PORT=443
export S3_ACCESS_KEY_ID_USER=<aws_id>
export S3_SECRET_ACCESS_KEY_USER=<aws-secret>
export S3_BUCKET=<bucket-name>
# the SERVICE_*** vars are location and authentication credentials of the microservices
# Get from each!????
export SERVICE_EPUB_CHECKER_PORT=3001
export SERVICE_EPUB_CHECKER_CLIENT_ID=<client-id-1>
export SERVICE_EPUB_CHECKER_SECRET=<secret-1>
export SERVICE_EPUB_CHECKER_URL=${SERVER_PROTOCOL}://${SERVER_HOST}:${SERVICE_EPUB_PORT}
export SERVICE_PAGEDJS_PORT=3003
export SERVICE_PAGEDJS_CLIENT_ID=<client-id-2>
export SERVICE_PAGEDJS_SECRET=<secret-2>
export SERVICE_PAGEDJS_URL=${SERVER_PROTOCOL}://${SERVER_HOST}:${SERVICE_PAGEDJS_PORT}
export SERVICE_XSWEET_PORT=3004
export SERVICE_XSWEET_CLIENT_ID=<client-id-3>
export SERVICE_XSWEET_SECRET=<secret-3>
export SERVICE_XSWEET_URL=${SERVER_PROTOCOL}://${SERVER_HOST}:${SERVICE_XSWEET_PORT}
# The secret used for signing and verifying jwt tokens
export PUBSWEET_SECRET=foobar
# Whether or not to periodically clean up the temp directory of any potential leftover files
export TEMP_DIRECTORY_CLEAN_UP=
# A valid cron value that specifies how often the temp directory should run
export TEMP_DIRECTORY_CRON_JOB_SCHEDULE=
# The minimum amount of time (in milliseconds) a file should exist before being cleaned up
export TEMP_DIRECTORY_CRON_JOB_OFFSET=
# TODO when we see what it can do!
export AI_ENABLED=
export CHAT_GPT_KEY=
Then for each server I have (which builds on the above vars):
export SERVER_IDENTIFIER=<name>_server_id
export PUBSWEET_SECRET=<secret-for-this-server>
export SERVER_PORT=<server-port>
export PUBLIC_URL=${SERVER_PROTOCOL}://${SERVER_HOST}:${SERVER_PORT}
export SERVER_URL=${PUBLIC_URL}