This repository stores the setup information needed to run the server for the Ethos project. The system uses Nginx for SSL termination and as a reverse proxy, with Certbot for automatic SSL certificate renewal.
The root path (/) redirects to CouchDB running on port 5984.
The path (/server/) redirects to the Node.js instance (internally on HTTP port 8080).
Surveys can be sent to clients by running:
curl -u user:password -d '{"newValue": true}' -H "Content-Type: application/json" -X POST https://your-domain.com/server/displayBomSurvey
(Replace user:password with your USERNAME and PASSWORD from .env, and your-domain.com with your actual domain if different).
-
Docker: This repo requires a pre-existing installation of Docker. Rootless mode is recommended.
- Install Docker:
curl -fsSL https://get.docker.com -o get-docker.shand thensudo sh ./get-docker.sh. - For rootless Docker (refer to official Docker docs for the most up-to-date instructions):
- Install prerequisites:
sudo apt-get update && sudo apt-get install -y dbus-user-session uidmap systemd-container fuse-overlayfs - Allow low-port binding for rootless user (e.g., for ports 80, 443): Add
net.ipv4.ip_unprivileged_port_start=80to/etc/sysctl.confthen runsudo sysctl -p. - Create a dedicated user:
sudo adduser docker-user - Disable system-wide Docker:
sudo systemctl disable --now docker.service docker.socket,sudo rm -f /var/run/docker.sock. - Log in as the
docker-user:sudo machinectl shell docker-user@(orsu - docker-user). - Install rootless Docker:
dockerd-rootless-setuptool.sh install. - Start user Docker service:
systemctl --user start docker. - Enable linger for the user:
sudo loginctl enable-linger docker-user. More information: Docker Rootless Mode Docs
- Install prerequisites:
- Install Docker:
-
Node.js Server Configuration: Ensure your Node.js application (the
serverservice) is configured to listen on HTTP port 8080. It should not attempt to handle HTTPS itself.
-
Generate DH Parameters: This strengthens SSL. It can take a few minutes.
openssl dhparam -out ./certbot/conf/ssl-dhparams.pem 2048
-
Configure SSL Options File (
./nginx/ssl_common/options-ssl-nginx.conf): Use a strong configuration. You can generate one from the Mozilla SSL Configuration Generator. Select Nginx, your server version, and "Modern" compatibility. Example content for./nginx/ssl_common/options-ssl-nginx.conf:# Modern configuration, tweak as necessary ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; ssl_session_tickets off;
-
(If running docker rootless) Login to your
docker-useraccount:sudo machinectl shell docker-user@ -
Clone this repository.
-
Navigate into the cloned directory.
-
Copy
.env.exampleto.env(cp .env.example .env) and fill out all the fields (nano .env).- Ensure
COUCHDB_ADMIN_USER,COUCHDB_ADMIN_PASSWORD,REDIS_PASSWORD,USERNAME,PASSWORDetc. are set.
- Ensure
-
Configure
./nginx/conf/nginx.confwith your correct domain name for$primary_domain. -
Initial Certificate Generation (First Time Only):
-
Start Nginx temporarily to serve the ACME challenge:
docker compose -p ethos-server --profile prod up -d nginx
-
Run Certbot to obtain certificates. Replace
your-email@example.comwith your actual email andyour-domain.comwith your domain:docker compose --profile prod run --rm certbot certonly \ --webroot \ --webroot-path /var/www/certbot/ \ -d your-domain.com -d www.your-domain.com \ --email your-email@example.com \ --agree-tos --no-eff-email \ --force-renewal # Use --force-renewal only if re-running for existing domains and need to force it -
If successful, Nginx (which is already running) should now have the certs. You can stop it and restart all services, or just proceed.
# Optional: docker compose --profile prod stop nginx
-
-
Start all services (including Nginx with certs, and Certbot for auto-renewal): The
prod_start_server.shordev_start_server.shscripts can handle starting services for you. Alternatively a general command for production:docker compose -p ethos-server --profile prod up -d
-p ethos-serversets a consistent project name which is needed for the certbot entrypoint script to reload nginx
- Copy
users.csv.exampletousers.csvand populate the file with usernames and passwords. - Run
sh prod_create_users_from_csv.shto create CouchDB users and views. This script likely runs a command likedocker compose exec couchdb ...or similar.
All endpoints marked with [AUTH] require authentication using the authMiddleware.
All endpoints marked with [AUTHDB] require authentication against the couchdb database. The authenticated user's identity must match the identity or userId provided in the request body for applicable endpoints.
-
URL:
/displayBomSurvey -
Method: GET
-
Description: Retrieves the current status of whether to display a BOM survey.
-
Response:
{ "displaySurvey": boolean }
-
URL:
/displayBomSurvey -
Method: POST
-
Description: Updates the BOM survey display status.
-
Body:
{ "newValue": boolean } -
Response: String confirming the update.
-
URL:
/displayUserHeatSurvey -
Method: GET
-
Description: Retrieves the current status of whether to display a BOM survey for given user passed in credentials.
-
Response:
{ "displaySurvey": boolean }
-
URL:
/displayUserHeatSurvey -
Method: POST
-
Description: Updates the BOM survey display status of current user passed in credentials.
-
Body:
{ "newValue": boolean } -
Response: String confirming the update.
-
URL:
/displayUserHeatSurvey -
Method: GET
-
Description: Retrieves the current status of whether to display a Heat Alert survey for given user passed in credentials.
-
Response:
{ "displaySurvey": boolean }
-
URL:
/displayUserHeatSurvey -
Method: POST
-
Description: Updates the Heat Alert survey display status of current user passed in credentials.
-
Body:
{ "newValue": boolean } -
Response: String confirming the update.
-
URL:
/registerDevice -
Method: POST
-
Description: Registers a device for push notifications. If device is undefined, it will default to iOS. Set tag as 'research_participant' for those users who will be receiving surveys.
-
Body:
{ "identity": string, "address": string, "tag": "research_participant" | undefined, "device": "android" | "ios" | undefined } -
Response: String confirming registration.
-
URL:
/removeDevice -
Method: POST
-
Description: Removes a device for push notifications.
-
Body:
{ "identity": string, "address": string, } -
Response: String confirming removal.
-
URL:
/sendAlertPushNotification -
Method: POST
-
Description: Sends a heat alert push notification to a registered device.
-
Body:
{ "identity": string, "roomName": string, "severity": "medium" | "high" } -
Response: String confirming the notification was sent.
-
URL:
/sendSurveyPushNotification -
Method: POST
-
Description: Sends a survey push notification to a registered device.
-
Body:
{ "identity": string, "surveyType": "alert" | "bom" | "both" } -
Response: String confirming the notification was sent.
-
URL:
/sendSMSNotification -
Method: POST
-
Description: Sends an SMS notification.
-
Body:
{ "userId": string | number, "phoneNumber": string, "roomName": string, "severity": "medium" | "high" } -
Response: String confirming the SMS was sent.
- All authenticated routes require a valid authentication token to be included in the request header.
- For endpoints that require an
identityoruserIdin the request body, thisidentitymust match the authenticated user's identity. - Error responses will include appropriate HTTP status codes and error messages.
- The
sendPushNotificationandsendSMSfunctions are available for use within the application but are not directly exposed as API endpoints.