├── .dockerignore ├── Dockerfile.template ├── README.md ├── dashboard.jpg ├── dot-mozilla └── firefox │ ├── profiles.ini │ └── rni0qukt.default │ ├── extensions.ini │ ├── extensions.json │ ├── extensions │ └── {4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}.xpi │ └── prefs.js ├── jodel-wallpaper.png └── run /.dockerignore: -------------------------------------------------------------------------------- 1 | dashboard.jpg 2 | -------------------------------------------------------------------------------- /Dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM resin/%%RESIN_MACHINE_NAME%%-python 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | iceweasel dropbear xserver-xorg-core xserver-xorg-video-fbdev x11-xserver-utils \ 7 | libgl1-mesa-dri xserver-xorg-video-modesetting xserver-xorg-video-vesa \ 8 | matchbox-window-manager openvpn xautomation feh \ 9 | && apt-get clean && rm -rf /var/lib/apt/lists/* 10 | 11 | ADD run /bin/run 12 | ADD jodel-wallpaper.png /etc/wallpaper.png 13 | ADD dot-mozilla /root/.mozilla 14 | 15 | ENTRYPOINT [ "/bin/run" ] 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Jodel Dashboard Viewer 2 | This [resin.io](https://resin.io/) based application runs on a raspberry pi to 3 | display our [grafana](http://grafana.org/) dashboards (powered by 4 | http://prometheus.io/). 5 | 6 | It's running firefox with the [R-kiosk](https://addons.mozilla.org/en-us/firefox/addon/r-kiosk/) 7 | extensions. Optionally it runs an openvpn client in case your dashboards are 8 | not accessible from the public internet. 9 | 10 | ![dashboard-at-jodel](dashboard.jpg) 11 | 12 | ## Use it 13 | Add your resin git remote and push the project. For details see 14 | [resin.io's getting started documentation](http://docs.resin.io/#/pages/installing/gettingStarted.md). 15 | 16 | Just clone this repo instead of the example. 17 | After that, you need to set some [environment variables](http://docs.resin.io/#/pages/management/env-vars.md): 18 | 19 | - `URL`: Dashboard URL to open 20 | - `PASS`: The dashboard runs dropbear, this var will be the root password. If unset, defaults to 'root' 21 | 22 | To use openvpn, set the following options: 23 | 24 | - `REMOTE_HOST`: Address of openvpn server 25 | - `REMOTE_PORT`: Port the openvpn server is running on 26 | - `VPN_USER`: VPN Username 27 | - `VPN_PASS`: VPN Password 28 | - `CERT`: Client certificate, newlines replaced by `\n` 29 | 30 | ## Limitations 31 | Especially the openvpn config is a bit specific to user setup, for example it 32 | uses TCP. It's not a priority for us to make it more generic, but PRs for that 33 | are welcome. 34 | -------------------------------------------------------------------------------- /dashboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jodel/dashboard-viewer/40206a1a7cec087a5657cc3580fdfd821852788b/dashboard.jpg -------------------------------------------------------------------------------- /dot-mozilla/firefox/profiles.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | StartWithLastProfile=1 3 | 4 | [Profile0] 5 | Name=default 6 | IsRelative=1 7 | Path=rni0qukt.default 8 | Default=1 9 | 10 | -------------------------------------------------------------------------------- /dot-mozilla/firefox/rni0qukt.default/extensions.ini: -------------------------------------------------------------------------------- 1 | [ExtensionDirs] 2 | Extension0=/root/.mozilla/firefox/rni0qukt.default/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}.xpi 3 | 4 | [ThemeDirs] 5 | Extension0=/usr/lib/iceweasel/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd} 6 | 7 | [MultiprocessIncompatibleExtensions] 8 | Extension0={4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B} 9 | -------------------------------------------------------------------------------- /dot-mozilla/firefox/rni0qukt.default/extensions.json: -------------------------------------------------------------------------------- 1 | {"schemaVersion":16,"addons":[{"id":"{972ce4c6-7e08-4474-a285-3208198ce6fd}","syncGUID":"6n-lXW2blEsa","location":"app-global","version":"38.5.0","type":"theme","internalName":"classic/1.0","updateURL":null,"updateKey":null,"optionsURL":null,"optionsType":null,"aboutURL":null,"iconURL":null,"icon64URL":null,"defaultLocale":{"name":"Default","description":"The default theme.","creator":"Mozilla","homepageURL":null,"contributors":["Mozilla Contributors"]},"visible":true,"active":true,"userDisabled":false,"appDisabled":false,"descriptor":"/usr/lib/iceweasel/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}","installDate":1454428552000,"updateDate":1454428552000,"applyBackgroundUpdates":1,"skinnable":true,"size":3175,"sourceURI":null,"releaseNotesURI":null,"softDisabled":false,"foreignInstall":false,"hasBinaryComponents":false,"strictCompatibility":true,"locales":[],"targetApplications":[{"id":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","minVersion":"38.5.0","maxVersion":"38.5.0"}],"targetPlatforms":[]},{"id":"{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}","syncGUID":"R3MIaJQYvOgA","location":"app-profile","version":"0.9.0.1-signed","type":"extension","internalName":null,"updateURL":null,"updateKey":null,"optionsURL":null,"optionsType":null,"aboutURL":null,"iconURL":null,"icon64URL":null,"defaultLocale":{"name":"R-kiosk","description":"RKiosk (Real Kiosk), fullscreen kiosk mode: all menus, keys etc. disabled","creator":"Kimmo Heinaaro","homepageURL":null},"visible":true,"active":true,"userDisabled":false,"appDisabled":false,"descriptor":"/root/.mozilla/firefox/rni0qukt.default/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}.xpi","installDate":1454431386000,"updateDate":1454431386000,"applyBackgroundUpdates":1,"bootstrap":false,"size":16125,"sourceURI":"file:///tmp/r_kiosk.xpi","releaseNotesURI":null,"softDisabled":false,"foreignInstall":false,"hasBinaryComponents":false,"strictCompatibility":false,"locales":[],"targetApplications":[{"id":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","minVersion":"2.0","maxVersion":"17.*"}],"targetPlatforms":[],"multiprocessCompatible":false}]} -------------------------------------------------------------------------------- /dot-mozilla/firefox/rni0qukt.default/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jodel/dashboard-viewer/40206a1a7cec087a5657cc3580fdfd821852788b/dot-mozilla/firefox/rni0qukt.default/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}.xpi -------------------------------------------------------------------------------- /dot-mozilla/firefox/rni0qukt.default/prefs.js: -------------------------------------------------------------------------------- 1 | # Mozilla User Preferences 2 | 3 | /* Do not edit this file. 4 | * 5 | * If you make changes to this file while the application is running, 6 | * the changes will be overwritten when the application exits. 7 | * 8 | * To make a manual change to preferences, you can visit the URL about:config 9 | */ 10 | 11 | user_pref("app.update.lastUpdateTime.addon-background-update-timer", 0); 12 | user_pref("app.update.lastUpdateTime.blocklist-background-update-timer", 0); 13 | user_pref("app.update.lastUpdateTime.browser-cleanup-thumbnails", 1454429236); 14 | user_pref("app.update.lastUpdateTime.experiments-update-timer", 0); 15 | user_pref("app.update.lastUpdateTime.search-engine-update-timer", 1454431143); 16 | user_pref("browser.cache.disk.capacity", 358400); 17 | user_pref("browser.cache.disk.smart_size.first_run", false); 18 | user_pref("browser.cache.frecency_experiment", 3); 19 | user_pref("browser.download.importedFromSqlite", true); 20 | user_pref("browser.migration.version", 27); 21 | user_pref("browser.newtabpage.enhanced", false); 22 | user_pref("browser.newtabpage.storageVersion", 1); 23 | user_pref("browser.pagethumbnails.storage_version", 3); 24 | user_pref("browser.places.smartBookmarksVersion", 7); 25 | user_pref("browser.search.countryCode", "DE"); 26 | user_pref("browser.search.region", "DE"); 27 | user_pref("browser.slowStartup.averageTime", 37461); 28 | user_pref("browser.slowStartup.samples", 4); 29 | user_pref("extensions.blocklist.pingCountVersion", 0); 30 | user_pref("extensions.bootstrappedAddons", "{}"); 31 | user_pref("extensions.databaseSchema", 16); 32 | user_pref("extensions.enabledAddons", "%7B4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B%7D:0.9.0.1-signed,%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D:38.5.0"); 33 | user_pref("extensions.getAddons.databaseSchema", 5); 34 | user_pref("extensions.lastAppVersion", "38.5.0"); 35 | user_pref("extensions.lastPlatformVersion", "38.5.0"); 36 | user_pref("extensions.pendingOperations", false); 37 | user_pref("extensions.shownSelectionUI", true); 38 | user_pref("extensions.xpiState", "{\"app-profile\":{\"{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}\":{\"d\":\"/root/.mozilla/firefox/rni0qukt.default/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}.xpi\",\"e\":true,\"v\":\"0.9.0.1-signed\",\"st\":1454431386000}},\"app-global\":{\"{972ce4c6-7e08-4474-a285-3208198ce6fd}\":{\"d\":\"/usr/lib/iceweasel/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}\",\"e\":true,\"v\":\"38.5.0\",\"st\":1454428552000,\"mt\":1450314979000}}}"); 39 | user_pref("gecko.buildID", "20151216080806"); 40 | user_pref("gecko.mstone", "38.5.0"); 41 | user_pref("idle.lastDailyNotification", 1454429374); 42 | user_pref("media.gmp-manager.buildID", "20151216080806"); 43 | user_pref("network.cookie.prefsMigrated", true); 44 | user_pref("network.predictor.cleaned-up", true); 45 | user_pref("pdfjs.migrationVersion", 2); 46 | user_pref("pdfjs.previousHandler.alwaysAskBeforeHandling", true); 47 | user_pref("places.history.expiration.transient_current_max_pages", 12595); 48 | user_pref("plugin.disable_full_page_plugin_for_types", "application/pdf"); 49 | user_pref("privacy.sanitize.migrateFx3Prefs", true); 50 | user_pref("signon.importedFromSqlite", true); 51 | user_pref("storage.vacuum.last.index", 0); 52 | user_pref("toolkit.startup.last_success", 1454431378); 53 | user_pref("toolkit.telemetry.previousBuildID", "20151216080806"); 54 | user_pref("dom.max_script_run_time", 0); 55 | -------------------------------------------------------------------------------- /jodel-wallpaper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jodel/dashboard-viewer/40206a1a7cec087a5657cc3580fdfd821852788b/jodel-wallpaper.png -------------------------------------------------------------------------------- /run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # set -euo pipefail 3 | set -x 4 | URL=${URL:-http://jodel-app.com} 5 | 6 | export PASS=${PASS:=root} 7 | echo "root:$PASS" | chpasswd 8 | 9 | rm -rf /tmp/* 10 | 11 | if [ -n "$REMOTE_HOST" ]; then 12 | cat < /etc/openvpn.conf 13 | client 14 | nobind 15 | remote-random 16 | remote $REMOTE_HOST $REMOTE_PORT 17 | proto tcp 18 | mute 5 19 | dev tun 20 | 21 | $( echo -e "$CERT" ) 22 | 23 | auth-user-pass /etc/openvpn.credentials 24 | EOF 25 | ( umask 0077; echo -e "${VPN_USER}\n${VPN_PASS}" > /etc/openvpn.credentials ) 26 | openvpn --config /etc/openvpn.conf & 27 | fi 28 | 29 | if ! [ -e "/etc/dropbear/dropbear_ecdsa_host_key" ]; then 30 | dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key 31 | fi 32 | 33 | dropbear -E -F & 34 | DB_PID=$! 35 | 36 | Xorg & 37 | X_PID=$! 38 | 39 | echo "Waiting for X to be ready" 40 | export DISPLAY=:0 41 | 42 | # Setting wallpaper and polling X in one! 43 | while ! feh --bg-scale /etc/wallpaper.png; do sleep 1; done 44 | matchbox-window-manager -use_cursor no & 45 | 46 | while ! curl -sf -o /dev/null "$URL"; do sleep 1; done 47 | 48 | xset -dpms 49 | xset s off 50 | xset s noblank 51 | 52 | iceweasel "$URL" 53 | 54 | sleep infinity 55 | --------------------------------------------------------------------------------