Skip to main content...

Install ChroGPS Dash Manually

Recommended

Use the One-Line Installer Instead

If you just want ChroGPS Dash running, the single-line installer handles all of this automatically - Nginx, PHP, sudo permissions, log access, systemd units, and more. Only continue here if you have a specific reason to set things up manually.
Quick Installer

If you prefer to set things up manually, ensure you have the following:

Prerequisites
  • Web Server: Nginx or Apache
  • PHP: Version 8.1 or newer, with the php-json extension
  • System Utilities: sudo (required for executing chronyc commands), curl (required by the poller service)
  • NTP/GPS: Chrony and GPSd installed and running

Configuration Details

Sudo Permissions

The dashboard requires permission to execute chronyc commands to fetch timing data. The installer creates a drop-in file at /etc/sudoers.d/chrogps-dash with the following content:

www-data ALL=(ALL) NOPASSWD: /usr/bin/chronyc sources, /usr/bin/chronyc tracking, /usr/bin/chronyc serverstats, /usr/bin/chronyc -n clients, /usr/bin/chronyc clients, /usr/bin/chronyc makestep, /usr/local/bin/cgpsd-purge-logs, /usr/local/bin/cgpsd-restart-gpsd, /usr/local/bin/cgpsd-restart-chrony, /usr/local/bin/cgpsd-restart-poller

For a manual setup, create that file yourself rather than editing /etc/sudoers directly:

sudo tee /etc/sudoers.d/chrogps-dash > /dev/null << 'EOF'
www-data ALL=(ALL) NOPASSWD: /usr/bin/chronyc sources, /usr/bin/chronyc tracking, /usr/bin/chronyc serverstats, /usr/bin/chronyc -n clients, /usr/bin/chronyc clients, /usr/bin/chronyc makestep, /usr/local/bin/cgpsd-purge-logs, /usr/local/bin/cgpsd-restart-gpsd, /usr/local/bin/cgpsd-restart-chrony, /usr/local/bin/cgpsd-restart-poller
EOF
sudo chmod 440 /etc/sudoers.d/chrogps-dash

The additional entries cover the System tab actions in the admin panel. See Log Purge Helper Script and Service Restart Helper Scripts below for how to create them.

Log File Access

  • The graphs are generated by parsing raw Chrony logs (tracking.log, statistics.log, measurements.log). The installer:
  • Adds the www-data user to the group that owns /var/log/chrony (detected at install time via stat; typically _chrony).
  • Sets chmod 770 on the /var/log/chrony directory and g+r on any existing log files inside it.
  • Configures Chrony to log the data if it’s not enabled.

…So you will need to perform these tasks if you wish to install ChroGPS Dash manually.

Raspberry Pi Throttle Status (Optional)

On Raspberry Pi, the Admin Panel’s Node Vitals tab reports under-voltage/frequency-cap/thermal-throttle status via vcgencmd get_throttled, which requires www-data to be in the video group:

sudo usermod -a -G video www-data

Skip this on non-Raspberry Pi systems – vcgencmd won’t be present, and the Pi Throttle field simply won’t appear in Node Vitals.

GPSD Integration

The dashboard connects to gpsd via a local socket on port 2947. Ensure gpsd is configured to listen on all interfaces or at least localhost.

History Graph Data Files

The satellite and PPS history graphs are always-on and appear automatically once their rolling log files contain data. You must create the files and set www-data ownership before starting the dashboard, otherwise the dashboard will attempt to create them itself (and may fail without the right permissions):

sudo touch /var/tmp/cgpsd-sat-counts.data \
           /var/tmp/cgpsd-gps-snr.data \
           /var/tmp/cgpsd-pps-offset.data \
           /var/tmp/cgpsd-dop.data \
           /var/tmp/cgpsd-snr-hist.data
sudo chown www-data:www-data /var/tmp/cgpsd-sat-counts.data \
                              /var/tmp/cgpsd-gps-snr.data \
                              /var/tmp/cgpsd-pps-offset.data \
                              /var/tmp/cgpsd-dop.data \
                              /var/tmp/cgpsd-snr-hist.data
sudo chmod 644 /var/tmp/cgpsd-sat-counts.data \
               /var/tmp/cgpsd-gps-snr.data \
               /var/tmp/cgpsd-pps-offset.data \
               /var/tmp/cgpsd-dop.data \
               /var/tmp/cgpsd-snr-hist.data

The installer handles this automatically; the above is only required for a fully manual setup.

Systemd Poller Timer

The installer automatically creates and enables two systemd units that poll the dashboard’s data endpoint (?ajax=1) every 30 seconds, keeping all history logs populated continuously without requiring an open browser tab:

  • /etc/systemd/system/chrogps-poller.service - oneshot service that runs curl against the local endpoint.
  • /etc/systemd/system/chrogps-poller.timer - fires the service every 30 seconds.

For a fully manual setup, create both unit files and enable the timer:

sudo tee /etc/systemd/system/chrogps-poller.service > /dev/null << 'EOF'
[Unit]
Description=ChroGPS Dash GPS/PPS Data Poller
After=network.target nginx.service

[Service]
Type=oneshot
ExecStart=/usr/bin/curl --silent --max-time 10 "http://127.0.0.1/?ajax=1" -o /dev/null
EOF

sudo tee /etc/systemd/system/chrogps-poller.timer > /dev/null << 'EOF'
[Unit]
Description=ChroGPS Dash GPS/PPS Data Poller - fires every 30 seconds
After=network.target

[Timer]
OnBootSec=30s
OnUnitActiveSec=30s
AccuracySec=5s

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now chrogps-poller.timer
Note
The poller service hits ?ajax=1 from 127.0.0.1 (localhost). If you have DASHBOARD_REQUIRE_AUTH enabled, localhost requests are always exempt from the authentication gate - history logging continues uninterrupted without any cookies or tokens. Remote browser sessions still require authentication.

Alternatively, use an equivalent cron job (every 30 seconds):

Caution
The systemd timer is the recommended approach. The cron job alternative is provided as a fallback for environments without systemd. If both exist, remove the cron entries to avoid double-polling.
* * * * * curl -s 'http://localhost/?ajax=1' >/dev/null
* * * * * sleep 30; curl -s 'http://localhost/?ajax=1' >/dev/null

Log Purge Helper Script

The admin panel’s System tab exposes a Purge Logs button that stops GPSd and Chrony, deletes all GPS and timing data logs, and restarts those services. The PHP backend calls this via sudo, so you must create the helper script and allow www-data to execute it.

Create the script:

sudo tee /usr/local/bin/cgpsd-purge-logs > /dev/null << 'EOF'
#!/bin/bash
systemctl stop gpsd.socket gpsd.service chrony.service 2>/dev/null || true
rm -f /var/tmp/cgpsd-* 2>/dev/null || true
rm -f /var/log/chrony/*.log 2>/dev/null || true
systemctl restart chrony.service 2>/dev/null || true
systemctl restart gpsd.service gpsd.socket 2>/dev/null || true
EOF
sudo chmod 755 /usr/local/bin/cgpsd-purge-logs
sudo chown root:root /usr/local/bin/cgpsd-purge-logs

The sudoers entry shown in Sudo Permissions above already includes this path. If you are adding it to an existing sudoers file by hand, make sure /usr/local/bin/cgpsd-purge-logs is appended to the www-data NOPASSWD line as shown there.

Caution
If you skip this step, the Purge Logs button will still appear in the admin panel but will return an error with instructions to run the installer.

Service Restart Helper Scripts

The admin panel’s System tab exposes three service restart buttons (Restart GPSd, Restart Chrony, Restart Poller Timer). Each calls a small helper script via sudo. Create all three:

sudo tee /usr/local/bin/cgpsd-restart-gpsd > /dev/null << 'EOF'
#!/bin/bash
systemctl restart gpsd.socket gpsd.service 2>/dev/null || true
EOF
sudo chmod 755 /usr/local/bin/cgpsd-restart-gpsd
sudo chown root:root /usr/local/bin/cgpsd-restart-gpsd

sudo tee /usr/local/bin/cgpsd-restart-chrony > /dev/null << 'EOF'
#!/bin/bash
systemctl restart chrony.service 2>/dev/null || true
EOF
sudo chmod 755 /usr/local/bin/cgpsd-restart-chrony
sudo chown root:root /usr/local/bin/cgpsd-restart-chrony

sudo tee /usr/local/bin/cgpsd-restart-poller > /dev/null << 'EOF'
#!/bin/bash
systemctl restart chrogps-poller.timer 2>/dev/null || true
EOF
sudo chmod 755 /usr/local/bin/cgpsd-restart-poller
sudo chown root:root /usr/local/bin/cgpsd-restart-poller

The Force Chrony Makestep button in the System tab calls chronyc makestep directly via sudo - no helper script is needed for that action, only the /usr/bin/chronyc makestep entry already included in the sudoers drop-in above.

Caution
If you skip creating the restart scripts, the corresponding Restart buttons will still appear in the admin panel but will return an error with instructions to run the installer.

Nginx & PHP-FPM Configuration

The dashboard needs a web server pointed at the install directory with PHP requests handed off to PHP-FPM. The installer automates this for Nginx; if you’re using Apache, adapt the equivalent mod_proxy_fcgi/mod_php configuration yourself.

First, determine your installed PHP-FPM socket path – it’s version-specific:

PHP_VER=$(php -v | head -n 1 | cut -d " " -f 2 | cut -d "." -f 1-2)
echo "/run/php/php${PHP_VER}-fpm.sock"

Create the vhost at /etc/nginx/sites-available/chrogps (substitute your actual socket path from above):

sudo tee /etc/nginx/sites-available/chrogps > /dev/null << EOF
server {
    listen 80 default_server;
    server_name _;
    root /var/www/chrogps-dash;
    index index.php;

    location / {
        try_files \$uri \$uri/ =404;
    }

    location ~ \.php\$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php${PHP_VER}-fpm.sock;
    }
}
EOF

Remove the default site (if present), enable the new one, and validate before reloading:

sudo rm -f /etc/nginx/sites-enabled/default
sudo ln -sf /etc/nginx/sites-available/chrogps /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx "php${PHP_VER}-fpm"
Caution
Always run sudo nginx -t before restarting – a bad config will otherwise take your web server down instead of just failing to reload.

ZeroConf / mDNS (Optional)

The one-line installer advertises the dashboard on your local network as chrogps-dash.local via Avahi/mDNS, unless run with the -np/--no-publish flag. This step is entirely optional – skip it if you don’t need the .local hostname and are fine reaching the dashboard by IP address.

Install Avahi:

sudo apt-get install -y avahi-daemon avahi-utils

Create the service advertisement at /etc/avahi/services/chrogps-dash.service:

sudo tee /etc/avahi/services/chrogps-dash.service > /dev/null << 'EOF'
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="yes">ChroGPS Dash on %h</name>
  <service>
    <type>_http._tcp</type>
    <port>80</port>
  </service>
</service-group>
EOF

Avahi’s service file above only advertises the HTTP service under the machine’s own hostname – it does not create the chrogps-dash.local alias itself. A small companion systemd unit publishes that alias:

sudo tee /etc/systemd/system/chrogps-cname.service > /dev/null << 'EOF'
[Unit]
Description=ChroGPS Dash mDNS Alias
After=network.target avahi-daemon.service
Requires=avahi-daemon.service

[Service]
Type=simple
ExecStart=/bin/bash -c '/usr/bin/avahi-publish -a -R "chrogps-dash.local" $(hostname -I | cut -d" " -f1)'
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now chrogps-cname.service
sudo systemctl restart avahi-daemon

Once running, the dashboard is reachable at http://chrogps-dash.local in addition to its IP address.

Settings File

The dashboard stores its configuration in cgpsd-settings.php, located in the same directory as index.php. On first run, the PHP script will attempt to auto-generate this file from built-in defaults - but only if www-data has write access to that directory.

The recommended web root is /var/www/chrogps-dash/. Create and set ownership before placing the script:

sudo mkdir -p /var/www/chrogps-dash
sudo chown www-data:www-data /var/www/chrogps-dash
sudo chmod 755 /var/www/chrogps-dash
Caution
If www-data cannot write to the directory (e.g. you placed index.php somewhere it doesn’t own), the dashboard will show an error modal on load instead of running.

Install The Script

Once you have everything setup, grab the script and place it at /var/www/chrogps-dash/index.php:

sudo curl -fsSL https://repo.w0chp.net/Chipster/ChroGPS-Dash/raw/branch/master/index.php \
    -o /var/www/chrogps-dash/index.php
sudo chown www-data:www-data /var/www/chrogps-dash/index.php
sudo chmod 644 /var/www/chrogps-dash/index.php
Success
Once the script is in place and your web server is pointing at /var/www/chrogps-dash/, navigate to the dashboard URL. On first load, the dashboard will auto-generate cgpsd-settings.php from built-in defaults. See the Configuration page to customize settings.
Important

The auto-generated cgpsd-settings.php ships with $ADMIN_TOKEN empty, which disables the Admin Panel and one-click updates. After the first load has created the file, set a token yourself using the same method the one-line installer uses:

sudo sed -i "s/\$ADMIN_TOKEN = '';/\$ADMIN_TOKEN = '$(openssl rand -hex 16)';/" /var/www/chrogps-dash/cgpsd-settings.php

Save the token somewhere – you’ll need it to access the Admin Panel and authenticate updates. See Configuration if you’d like to change it later.

Last Revision: 2026-07-12 -- Document Version: c242e6a
Permanent Link: <https://w0chp.radio/chrogps-dash/manual-installation/>