Skip to content

Instantly share code, notes, and snippets.

@Andries-Smit
Last active April 2, 2024 00:05
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save Andries-Smit/daac75cd4c06af78cde68c5dec941705 to your computer and use it in GitHub Desktop.
Save Andries-Smit/daac75cd4c06af78cde68c5dec941705 to your computer and use it in GitHub Desktop.
HOW-TO Install Nightscout on Raspberry PI 4 using docker

HOW-TO Install Nightscout on Raspberry PI 4 using docker

Setting up a Nightscout server on Raspberry PI 4 could be done directly on the OS or via docker containers. This page describes the containerized way. For an installation directly on the OS; follow one of the Linux installation guides.

This how-to includes a clean installation of a Raspberry Pi, and targets users with an interest in containerization with a basic knowledge on system administration. No expert knowledge is required to get started, however managing your own service come with a responsibility for security and data safekeeping. https://nightscout.github.io/nightscout/new_user/#security-and-safekeeping

1 Raspberry OS 64Bit

It is crucial to install the 64-bit OS to support the use of MongoDB. The official get-started guide can be used https://www.raspberrypi.com/documentation/computers/getting-started.html to get familiar with Raspberry Pi ecosystem.

Use the Raspberry Pi Imager to install the 64 Bit OS. Can be downloaded from https://www.raspberrypi.com/software/

  • Open the Image manager
  • Click the Choose OS
  • Open the list Raspberry Pi OS (Others)
  • Select: Raspberry Pi OS Lite (64-bit)
  • Choose Storage, and select your SD card. *(Prefer to use an SSD)
  • Write the image to the SD card
  • Insert the SD card into you Pi and start it up

2 Installation of Docker

Open the command line terminal to the Raspberry Pi, and make sure your OS is up-to-date

More information https://docs.docker.com/engine/install/debian/#install-docker-engine

$ sudo apt update
$ sudo apt upgrade

Install docker

$ sudo apt install docker.io
$ sudo usermod -aG docker pi
$ logout

Test if the docker installation succeeded.

$ groups
> Should include the docker group for the user
$ docker run hello-world
> Hello from Docker!

3 Installation of Portainer

Portainer will allow you to manage the containers via a web application For more information on installing docker Portainer see https://pimylifeup.com/raspberry-pi-portainer/

$ sudo docker pull portainer/portainer-ce:latest

Test if Portainer is running in a browser; navigate Pi's IP address on port 9000 http://PI_IO_ADDRESS:9000/

4 Create a Nightscout image*

This section is only needed if you want to build your own image. Starting from Nightscout 14.2.6 an image docker image Raspberry Pi is released on docker hub. https://hub.docker.com/layers/nightscout/cgm-remote-monitor/14.2.6/images/sha256-063c64dba9b5916070a52909b03d980725cca99f4ca018b533e64c065a4ce2e5?context=explore

Previously, Nightscout did not publish an image suitable for Raspberry Pi. If you want to build your own image, continue else go the next chapter.

For this how-to we can build our image using Portainer. See: https://docs.portainer.io/user/docker/images/build#method-1-using-the-portainer-web-editor

#
# CGM Remote Monitor Dockerfile
# Inspired by https://github.com/dhermanns/rpi-nightscout
#

# Pull base image.
FROM node:14-alpine

# Install Git and NPM
RUN apk update && apk add -y software-properties-common python g++ make git

# Upgrade
RUN apk upgrade -y

# Create node user
RUN mkdir -p /opt/app
WORKDIR /opt/app
RUN chown -R node:node /opt/app
USER node

# Install the application, and remove unused folders, to limit the image size
RUN git clone https://github.com/nightscout/cgm-remote-monitor.git . && \
git checkout tags/14.2.6 && \
npm install && \
npm run postinstall && \
npm run env && \
rm -rf node_modules && \
rm -rf tmp && \
rm -rf .git

EXPOSE 1337

CMD ["node", "lib/server/server.js"]

5 Building a stack

To spin up a set of docker images that together creates the Nightscout web site.

See: https://docs.portainer.io/user/docker/stacks/add#option-1-web-editor

  • Make sure the service > nightscout > image is matching with the image above
  • Update the YOUR_PUBLIC_HOST_URL
  • Update the environment variable YOUR_API_SECRET (The rest is done in the next chapter)

Inspired by https://github.com/nightscout/cgm-remote-monitor/blob/master/docker-compose.yml

version: '3.4'
services:
  nightscout:
    image: nightscout/cgm-remote-monitor:14.2.6
    environment:
      TZ: Europe/Berlin
      MONGO_CONNECTION: mongodb://mongo:27017/mycgmic
      API_SECRET: YOUR_API_SECRET
      BG_HIGH: 8
      BG_LOW: 3.9
      BG_TARGET_TOP: 7
      BG_TARGET_BOTTOM: 3.9
      AUTH_DEFAULT_ROLES: readable devicestatus-upload
      ENABLE: careportal boluscalc food bwp cage sage iage iob cob basal ar2 rawbg pushover bgi pump openaps cors"
      SHOW_FORECAST: openaps
      SHOW_PLUGINS: careportal openaps pump iob sage cage
      CUSTOM_TITTLE: Nightscout
      DISPLAY_UNITS: mmol
    ports:
      - "1337:1337"
    depends_on:
      - mongo    
    labels:
      - 'traefik.enable=true'
      # Change the below Host from `localhost` to be the web address where Nightscout is running.
      # Also change the email address in the `traefik` service below.
      - 'traefik.http.routers.nightscout.rule=Host(`YOUR_PUBLIC_HOST_URL`)'
      - 'traefik.http.routers.nightscout.entrypoints=websecure'
      - 'traefik.http.routers.nightscout.tls.certresolver=le'
    volumes:
      - /home/pi/docker/rpi-nightscout:/var/opt/ssl/:ro
    restart: always
    
  mongo:
    image: mongo:4.4.9
    volumes:
      - ./data:/data/db                                                                      
    ports:
      - "27017:27017"
      - "27018:27018"
      - "27019:27019"
      - "28017:28017"
    restart: always
    
  traefik:
    image: traefik:latest
    container_name: 'traefik2'
    command:
      - '--providers.docker=true'
      - '--providers.docker.exposedbydefault=false'
      - '--entrypoints.web.address=:80'
      - '--entrypoints.web.http.redirections.entrypoint.to=websecure'
      - '--entrypoints.websecure.address=:443'
      - "--certificatesresolvers.le.acme.httpchallenge=true"
      - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
      - '--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json'
      # Change the below to match your email address
      - '--certificatesresolvers.le.acme.email=YOUR_EMAIL'
    ports:
      - '443:443'
      - '80:80'
    volumes:
      - './letsencrypt:/letsencrypt'
      - '/var/run/docker.sock:/var/run/docker.sock:ro' 
    restart: always

Replace within the Stack your personal settings

  • YOUR_API_SECRET
  • YOUR_EMAIL
  • YOUR_PUBLIC_HOST_URL

To test, go to Nightscout URL and test if it is working!

6 Configure setup

Edit your stack and set the environment variables in the section services > nightscout > environment

If you migrate from Heroku, check the setting. https://devcenter.heroku.com/articles/config-vars#using-the-heroku-dashboard

Else check the documentation for environment variables. https://github.com/nightscout/cgm-remote-monitor#environment

7 Migrating data (optional)

Historical data can be migrated, there are 3 options; Accept the loss of your old data, backfill with your uploaders (see next chapter), or migrate the data fast from the old MongoDB to the new MongoDB with export and import.

Migrate MongoDB with data tools. https://www.mongodb.com/try/download/database-tools

  1. Install de data tools
  2. Check your MongoDB settings in Heroku settings the MONGODB_URI it contains a value similar to: mongodb+srv://USER:SECRET@cluster0.ilbqf.mongodb.net/mycgmic?retryWrites=true&w=majority
  3. Export the current DB with, update the URI and output file (Replace USER & SECRET)
cd "C:\Program Files\MongoDB\Tools\100\bin"
$ mongodump --uri mongodb+srv://USER:SECRET@cluster0.ilbqf.mongodb.net/mycgmic --out="C:\mongodump"
  1. Restore the DB, update the destination IP and dump the file (User the Pi's IP)
cd "C:\Program Files\MongoDB\Tools\100\bin"
mongorestore --host=YOUR_HOST --port=27017 "C:\mongodump"
  1. * When current data needs the be replace, use the parameter --drop
cd "C:\Program Files\MongoDB\Tools\100\bin"
mongorestore --host=YOUR_HOST --port=27017 --drop "C:\mongodump"

8 Change uploader

Make sure other tools that upload are configured with a new URL. See: https://nightscout.github.io/uploader/setup/ and https://nightscout.github.io/nightscout/downloaders/

  1. Android APS https://androidaps.readthedocs.io/en/latest/Installing-AndroidAPS/Nightscout.html?highlight=upload#androidaps-settings
  2. If you have Android APS as a follower, update the follower too
  3. xDrip https://xdrip.readthedocs.io/en/latest/use/cloud/#nightscout-sync-rest-api

Backfill (optional) If you migrated the database or did not care about the historical data, this step could be skipped. This process might be slow and should be done per uploader,

  1. Android APS uploads the treatments NS Client > ... (option menu) > Full synchronization
  2. xDrip to upload the BG values, use settings Cloud Upload > Extra Options > Back-fill data

9 Ready to go!

@jgslade
Copy link

jgslade commented Jan 14, 2023

Thank you for this guide. I have a running nightscout instance on my pi4 :). I am not able to upload to it from AAPS, I am getting ERROR io.socket.engineio.client.EngineIOException:xhr poll error every 5 seconds. do you have any suggestions on where I went wrong?

Thank you.

@KikiManjaro
Copy link

Thank you for this guide. I have a running nightscout instance on my pi4 :). I am not able to upload to it from AAPS, I am getting ERROR io.socket.engineio.client.EngineIOException:xhr poll error every 5 seconds. do you have any suggestions on where I went wrong?

Thank you.

This could be cause the link of the nightscout app is not the valid one in AAPS. Note that AAPS allows communication with https link only so you may have to install a ssl certificate for it to work.

@bordeb
Copy link

bordeb commented May 1, 2023

I would kindly ask for help.
I was following the guide and everything seems to work when looking inside portainer, but when trying to connect with the browser to the ip address of the RPi inside LAN there are errors:
connecting on port 443 the error is "404 page not found" , while
connecting on port 1337 the error is "SSL_ERROR_RX_RECORD_TOO_LONG"

EDIT:
I managed to open NS directly on port 1337 after adding
INSECURE_USE_HTTP: true
under service > nightscout > environment

@Kaazar
Copy link

Kaazar commented Jul 18, 2023

Hello guys, pls. send help. I'm a beginner with raspberry pi and docker/portainer. I stopped by point Update the YOUR_PUBLIC_HOST_URL. Which url must be stored here? Do you have an example? Thank you!

@Andries-Smit
Copy link
Author

Andries-Smit commented Jul 18, 2023

@Kaazar The YOUR_PUBLIC_HOST_URL is the URL to reach your Raspberry Pi from the public internet.

By default, your machine in your home network is unreachable via the public internet.
First, you have to forward a port from your network modem/router to your Pi, https://www.lifewire.com/how-to-port-forward-4163829

Second, your IP address from your network modem/router needs a DNS name to support HTTPS traffic.
You could register an URL with any domain server or use a service like https://dyn.com/. There might be some free services too.

@Kaazar
Copy link

Kaazar commented Jul 18, 2023

@Andries-Smit Thank for your fast Answer. I see, befor this works ... i must do some homework before. :)

@OGianni
Copy link

OGianni commented Aug 27, 2023

Good evening,
i have problem creating image in docker\portrainer through web editor, i get this error. Can you help me?
Step 1/10 : FROM node:14-alpine

---> d561716d42b6

Step 2/10 : RUN apk update && apk add -y software-properties-common python g++ make git

---> Running in da3f8a7f9ce6

fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/aarch64/APKINDEX.tar.gz

fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/aarch64/APKINDEX.tar.gz

v3.17.5-35-g351e56c8794 [https://dl-cdn.alpinelinux.org/alpine/v3.17/main]
v3.17.5-33-g59034473c39 [https://dl-cdn.alpinelinux.org/alpine/v3.17/community]
OK: 17694 distinct packages available

apk: unrecognized option: y

apk-tools 2.12.10, compiled for aarch64.

usage: apk add [...] PACKAGES...

Description:
apk add adds the requested packages to WORLD and installs (or upgrades)
them if not already present, ensuring all dependencies are met.

Global options:
-f, --force Enable selected --force-* options (deprecated)
-i, --interactive Ask confirmation before performing certain
operations
-p, --root Manage file system at ROOT
-q, --quiet Print less information
-U, --update-cache Alias for '--cache-max-age 1'
-v, --verbose Print more information (can be specified twice)
-V, --version Print program version and exit
-X, --repository
Specify additional package repository
--allow-untrusted Install packages with untrusted signature or no
signature
--arch ARCH Temporarily override architecture, to be combined
with --root
--cache-dir CACHEDIR Temporarily override the cache directory
--cache-max-age AGE Maximum AGE (in minutes) for index in cache before
it's refreshed
--force-binary-stdout
Continue even if binary data will be printed to the
terminal
--force-broken-world Continue even if WORLD cannot be satisfied
--force-non-repository
Continue even if packages may be lost on reboot
--force-old-apk Continue even if packages use unsupported features
--force-overwrite Overwrite files in other packages
--force-refresh Do not use cached files (local or from proxy)
--keys-dir KEYSDIR Override directory of trusted keys
--no-cache Do not use any local cache path
--no-network Do not use the network
--no-progress Disable progress bar even for TTYs
--print-arch Print default arch and exit
--progress Show progress
--progress-fd FD Write progress to the specified file descriptor
--purge Delete modified configuration files on package
removal and uninstalled packages from cache on cache
clean
--repositories-file REPOFILE
Override system repositories, see repositories
--wait TIME Wait for TIME seconds to get an exclusive repository
lock before failing

Commit options:
-s, --simulate Simulate the requested operation without making any
changes
--clean-protected Do not create .apk-new files in configuration
directories
--overlay-from-stdin Read list of overlay files from stdin
--no-scripts Do not execute any scripts
--no-commit-hooks Skip pre/post hook scripts (but not other scripts)
--initramfs-diskless-boot
Used by initramfs when it's recreating root tmpfs

Add options:
--initdb Initialize a new package database
-l, --latest Always choose the latest package by version
-u, --upgrade Upgrade PACKAGES and it's dependencies
-t, --virtual NAME Create virtual package NAME with given dependencies
--no-chown Do not change file owner or group

For more information: man 8 apk-add

The command '/bin/sh -c apk update && apk add -y software-properties-common python g++ make git' returned a non-zero code: 1

@jchoogeveen
Copy link

Maybe somebody can help me. I'm trying to follow the guide and managed to get Portainer running on the RPi4. Unfortunately I'm stuck at adding the nightscout image and get the following error: "no matching manifest for linux/arm/v7 in the manifest list entries" when I pull this image: "nightscout/cgm-remote-monitor:latest"

Can anybody help me pulling of the last few steps to get nightscout running?

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