Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save lsandini/2f94396cdeb62aacb2c454e5522d00f9 to your computer and use it in GitHub Desktop.
Save lsandini/2f94396cdeb62aacb2c454e5522d00f9 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/ (create a new "one-click app" droplet, select (Mongo 3.4 on 16.04)

  2. https://linode.com/

I recommend creating a non-root user with root privileges, at least that is what I did on my DigitalOcean droplet. Please read how to do it here: Initial Server Setup with Ubuntu 16.04

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

Install CGM-Remote-Monitor (Nightscout)

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

On DigitalOcean, I prefer to install nvm, and from there select the node.js version to install. Please take a look at this tutorial.

sudo apt-get update   
sudo apt-get install build-essential libssl-dev
curl -sL https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh -o install_nvm.sh
bash install_nvm.sh
source ~/.profile
nvm install 8.11.3 

... or any other version that fits your needs, but at least for the dev branch of Nightscout, you need a newer version of node.js than the one included in Ubuntu 16.04 Server LTS.

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 or git checkout master(probably not necessary) and npm install

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

MONGO_CONNECTION=mongodb://localhost/admin  (if mongodb is hosted on the same machine as NS, as in this case)
MONGO_CONNECTION=mongodb://user:password@ds2xxyyy.mlab.com:xxyyy/dbname  (if using mlab)
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
AUTH_DEFAULT_ROLES=readable%20devicestatus-upload
BG_HIGH=260
BG_TARGET_TOP=180
BG_TARGET_BOTTOM=80
BG_LOW=55
CUSTOM_TITLE=WHATEVER

Install mongodb

In case you are not using a DigitalOcean droplet with pre-installed mongodb, you will have to install mongodb manually. How to Install MongoDB on Ubuntu 16.04.

More details are available here: Install MongoDB Community Edition on Ubuntu. Once installed and started, the mongodb server is accessible on the host machine on port 27017. That's why when mongodb and Nightscout are hosted on the same computer (physical or virtual), the mongo connection string in Nightscout's preferences is MONGO_CONNECTION=mongodb://localhost/admin.

Two databases are active, "admin" and "local", none of which have any content yet. You can access the mongo shell by typing mongo, and after that issue commands like show dbs, show collections, show users, as in the mongo Shell Quick Reference.

If you prefer not to run your own mongodb server, then your mongo string will be in the form MONGO_CONNECTION=mongodb://user:password@ds2xxyyy.mlab.com:xxyyy/dbname, like in Azure or Heroku.

If you would like to also access your mongo database from the internet (for backup or analyzing them), you need to protect your database with a username and password, before making it available to the outside world.

Login to your host as root this time, or take on root priviliges with sudo -i. Then access the mono shell with the comman mongoand select the database you want to use, for example admin use admin. Then create a user :

use admin

db.createUser({ user: 'your_username', pwd: 'your_passwourd', roles: [{ role: 'readWrite', db:'admin'}] })

... and exit the mongo shell exit.

Edit the mongod.conf file nano /etc/mongod.conf, scroll down and uncomment the "security" line by removing the #, and add a line under it like this, then save and exit.

security: authorization: 'enabled'

You will have to modify your MONGO_CONNECTION string in my.env like this:

MONGO_CONNECTION=mongodb://your_username:your_password@localhost/admin

Accessing your mongo database from the internet

Making your database accessible from the internet is useful only for pulling data into other applications (like Studio 3T or Robo 3T), or if you want to use this personally hosted mongodb instead of the Mlab. You will have to open specifiy in the mongod.conf file, which IPs is the database:

bindIp: 127.0.0.1,206.189.xxx.xxx (or whatever your droplet's IP is).

Restart your mongodb server to make the changes active.

Opening a port on the firewall is not done using SSH, but in DigitalOcean's website where you need to link the firewall to your droplet and open the port mongodb is running on, to incoming TCP traffic (by default port 27017).

Your connection string will be: mongodb://your_username:your_password@yourdomain.com:2017/yourdatabase

Install pm2 to monitor nightscout process

sudo npm install pm2 -g

Start cgm-remote-monitor with pm2: env $(cat my.env) PORT=1337 pm2 start 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"

Finally in order to make pm2 remember what apps to start on next reboot:

pm2 save

Please note that every time you make modifications to your my.env file (your Nightscout environment variables), you will have to stop, delete and restart the server.js instance. Go to your /cgm-remote-monitor folder and :

pm2 list will show your current processes, and their id number.

pm2 stop 0 will stop the current server process with id "0".

pm2 delete 0 will delete the server process with id "0".

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

Create Reverse nginx proxy

Nginx is a server application. It will accept requests from clients, and when configured as a reverse proxy, it will forward these requests to another server. In our case, our Nightscout instance is available locally on the server at http://localhost:1337. Read more about Nginx for DigitalOcean here : Nginx Essentials: Installation and Configuration Troubleshooting

To make the connection more secure, we will protect it with SSL encryption using letsencrypt.

Install nginx:

sudo apt-get install nginx

edit this file:

sudo nano /etc/nginx/sites-available/default Delete all 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

Modify the etc/nginx/sites-enabled/defaults file, filling in your domain name as in the example below:

server {
    listen 80;

    server_name yourdomain.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;
    }

        listen       443 ssl;

    server_name   yourdomain.com;
        root         /usr/share/nginx/html;

        ssl_certificate     /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/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$
CDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AE$
HE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-EC$
84:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES$
RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-$
HA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aE$
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;
        }
}

Close the editor and check that your nginx configuration file is valid

sudo nginx -t

If there are errors in your configuration file, the command's output will tell you exactly where in the file the error was found.

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!

@nathanscrivener
Copy link

Thanks for your instructions on this. I have set up locally but have a problem that I am getting periodic application crashes when a pushover alert is triggered - it doesn't do this all the time so it's hard to work out why. Compounding this is when it happens PM2 keeps on restarting, but the error persists. The only way to fix it is to manually delete the pm2 instance and restart the application. Then it's back to normal. Any ideas?

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