Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save johnmales/1b3c927f2a56aae640b4b2cd0298b1e7 to your computer and use it in GitHub Desktop.
Save johnmales/1b3c927f2a56aae640b4b2cd0298b1e7 to your computer and use it in GitHub Desktop.

Self Hosted Nightscout Instance

This document describes making a self hosted nightscout instance, with SSL encryption and certificate with Let's Encrypt.

Ubuntu Machine

Make a fresh instance of Ubuntu 16.04.1 LTS as a VM or on a physical machine Download from http://www.ubuntu.com/download/server/thank-you?version=16.04.1&architecture=amd64

VIrtual machine host options :

  1. Virtualbox - https://www.virtualbox.org/
  2. Parallels - https://www.parallels.com/
  3. Vmware - https://www.vmware.com/ - various options including vmware workstation, vmware player, ESXi

Alternatively, consider hosting your Ubuntu instance elsewhere, for example:

  1. https://www.digitalocean.com/
  2. https://linode.com/

Update the Ubuntu instance: sudo apt-get update && sudo apt-get upgrade

Update node:

sudo npm cache clean -f
sudo npm install -g n
sudo n stable

Install CGM-Remote-Monitor (Nightscout)

Install Node.js and npm sudo apt-get install nodejs npm

Download cgm-remote-monitor (nightscout) from github: git clone https://github.com/nightscout/cgm-remote-monitor.git Alternatively fork a copy of cgm-remote-monitor and clone your own copy.

cd cgm-remote-monitor

Install cgm-remote-monitor: git checkout dev npm install

setup your cgm-remote-monitor environment as you normally would, for example creating a file my.env :

MONGO_CONNECTION=MONGOCONNECTIONSTRING
DISPLAY_UNITS=mmol
BASE_URL=NIGHTSCOUT_SITE_URL
DEVICESTATUS_ADVANCED="true"
mongo_collection="mogocollection_name"
API_SECRET=AVeryLongString
ENABLE=careportal%20openaps%20iob%20bwp%20cage%20basal%20pump%20bridge
BRIDGE_SERVER=EU
BRIDGE_USER_NAME=USERNAME
BRIDGE_PASSWORD=PASSWORD

Install pm2 to monitor nightscout processs

sudo npm install pm2 -g

Start cgm-remote-monitor with pm2: env $(cat my.env) PORT=1337 pm2 start lib/server/server.js

Make pm2 start cgm-remote-monitor on startup pm2 startup ubuntu - this will give you a command you need to run as superuser to allow pm2 to start the app on reboot The command will be something like: sudo su -c "env PATH=$PATH:/usr/bin pm2 startup ubuntu -u username --hp /home/username" And then: pm2 save

Create Reverse nginx proxy

Install nginx:

sudo apt-get install nginx

edit this file:

sudo vi /etc/nginx/sites-available/default Delete the existing contents and replace with this: I'm assuming the proxy is on the same host as nightscout and the proxy_pass http://127.0.0.1:1337 line - 1337 is replaced with the port that nightscout is using

server {
    listen 80;

    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:1337;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Then restart the nginx service sudo service nginx restart

Let's Encrypt SSL

install Let's Encrypt sudo apt-get install letsencrypt python-certbot-nginx

Obtain SSL certificate using webroot plugin Allow access to /.well-known directory for Lets Encrypt sudo nano /etc/nginx/sites-available/default

Stop ngnix service sudo service nginx stop

Obtain letsencrypt certificate - sudo letsencrypt certonly enter your domain name when prompted. This will create the certificates for your domain name. The certificates should now be available at /etc/letsencrypt/live/your_domain_name

improve SSL security by generating a strong Diffie-Hellman group sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Add this to the etc/nginx/sites-enabled/defaults file:

server {
        listen       443 ssl;
      	 server_name   your_domain_name;
        root         /usr/share/nginx/html;
	
	ssl_certificate     /etc/letsencrypt/live/your_domain_name/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your_domain_name/privkey.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_dhparam /etc/ssl/certs/dhparam.pem;
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-E
CDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECD
HE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA3
84:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-
RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-S
HA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DE
S-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security max-age=15768000;

        location ~ /.well-known {
                allow all;
        }


        location / {
		proxy_pass http://localhost:1337/;  # Note port number for your cgm-remote-monitor should be changed if it isn't 1337
        }

}

restart nginx sudo service nginx restart

You can test the quality of the SSL connection using: https://www.ssllabs.com/ssltest/analyze.html?d=your_domain_name Unfortunately only works with port 443

Arrange auto renewal of certificates. Add this line to the su crontab sudo crontab -e

30 2 * * 1 certbot renew >> /var/log/le-renew.log

Hopefully that is now done!

@bewest
Copy link

bewest commented Aug 26, 2022

Looks good. We moved the entry point back to server.js.

@mkitchingh
Copy link

Hey @johnmales , this is great stuff! I think I will plan to follow this and your Oracle cloud guide. I've got Ubuntu instances running at home, but port 443 is already used, and I'd prefer to not rely on my home Internet connection. One question, is there anything tricky if I want to migrate my Atlas Mongo data to a local Mongo instance? Normally I wouldn't really care, but we are switching to a new Endo, and I'd like to have all the data possible. Thanks!

@mdoliver
Copy link

mdoliver commented Sep 9, 2022

Thanks for the great post @johnmales . I also found @lsandini gist most helpful for explaining the mongodB installation. I have everything going well with the exception of my Dexcom bridge. All login attempts fail (although I can successfully login via the web so I know my creds are correct).

my.env
MONGO_CONNECTION=mongodb://localhost/admin MONGO_COLLECTION=entries API_SECRET=secret AUTH_DEFAULT_ROLES=denied BRIDGE_SERVER=EU BRIDGE_USER_NAME=username BRIDGE_PASSWORD=password BG_HIGH=504 BG_TARGET_BOTTOM=90 BG_TARGET_TOP=144 BG_LOW=70.2 DISPLAY_UNITS=mmol ENABLE=careportal%20cors%20basal%20sage%20bridge SHOW_PLUGINS=careportal THEME=colors TIME_FORMAT=24
The error I receive:
Cannot authorize account: null 500 { Code: 'AccountPasswordInvalid', Message: 'Publisher account password failed', SubCode: '<OnlineException DateThrownLocal="2022-09-09T04:16:54.865" DateThrown="2022-09-09T04:16:54.865Z" ErrorCode="AccountPasswordInvalid" Type="13" Category="4" Severity="1" TypeString="InvalidPassword" CategoryString="Validation" SeverityString="Minor" HostName="" HostIP="" Id="{idgoeshere}" Message="Publisher account password failed" FullText="com.dexcom.udp.common.data.exception.OnlineException: Publisher account password failed" />', TypeName: 'FaultException' } Error refreshing token null 500 { Code: 'AccountPasswordInvalid', Message: 'Publisher account password failed',
It's almost like the server doesn't recognise I'm outside of the US even though the setting for EU is set in my.env

Any thoughts (apologies, don't know how to get line breaks into a code snippet)?

@felix-git-hub
Copy link

i am wondering , is there any possibility to host nightscout as a subfolder (e.g. www.XXXX.com/nightscout)

@johnmales
Copy link
Author

There is no problem with setting up the access url this way. It would involve a change to the nginx proxy setting or whichever proxy server you are using.

@johnmales
Copy link
Author

Thanks for the great post @johnmales . I also found @lsandini gist most helpful for explaining the mongodB installation. I have everything going well with the exception of my Dexcom bridge. All login attempts fail (although I can successfully login via the web so I know my creds are correct).

my.env MONGO_CONNECTION=mongodb://localhost/admin MONGO_COLLECTION=entries API_SECRET=secret AUTH_DEFAULT_ROLES=denied BRIDGE_SERVER=EU BRIDGE_USER_NAME=username BRIDGE_PASSWORD=password BG_HIGH=504 BG_TARGET_BOTTOM=90 BG_TARGET_TOP=144 BG_LOW=70.2 DISPLAY_UNITS=mmol ENABLE=careportal%20cors%20basal%20sage%20bridge SHOW_PLUGINS=careportal THEME=colors TIME_FORMAT=24 The error I receive: Cannot authorize account: null 500 { Code: 'AccountPasswordInvalid', Message: 'Publisher account password failed', SubCode: '<OnlineException DateThrownLocal="2022-09-09T04:16:54.865" DateThrown="2022-09-09T04:16:54.865Z" ErrorCode="AccountPasswordInvalid" Type="13" Category="4" Severity="1" TypeString="InvalidPassword" CategoryString="Validation" SeverityString="Minor" HostName="" HostIP="" Id="{idgoeshere}" Message="Publisher account password failed" FullText="com.dexcom.udp.common.data.exception.OnlineException: Publisher account password failed" />', TypeName: 'FaultException' } Error refreshing token null 500 { Code: 'AccountPasswordInvalid', Message: 'Publisher account password failed', It's almost like the server doesn't recognise I'm outside of the US even though the setting for EU is set in my.env

Any thoughts (apologies, don't know how to get line breaks into a code snippet)?

Not sure about this one, sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment