Hardware Setup — Raspberry Pi

Step-by-step Agrogat edge gateway installation on Raspberry Pi 4/5 with Ubuntu 24.04 Server, Apache, PHP, and PostgreSQL.

Step-by-step guide to deploy Agrogat as a field edge gateway on Raspberry Pi 4 or 5 running Ubuntu 24.04 LTS Server (64-bit).

> Software-only reference (.env, migrations, sync): see setup.md.


What you will build

Component Role
Raspberry Pi 4/5 Edge compute node (local ingest + dashboard)
Ubuntu 24.04 Server OS (headless, no desktop)
Apache + PHP 8.3 Web server and application runtime
PostgreSQL 16 Local time-series and config store
Agrogat IoT gateway application (this repository)

Typical use: LoRaWAN or HTTP sensors → local ingest.php → PostgreSQL → optional sync to a central server.


Step 1 — Hardware and SD card

Minimum recommended

  • Raspberry Pi 4 (4 GB+) or 5 (4 GB+)
  • MicroSD 32 GB+ (Class 10 / A2) or USB SSD (preferred for production)
  • Stable 5 V power supply (official Pi PSU recommended)
  • Ethernet cable or reliable Wi-Fi (field sites: prefer Ethernet)
  • Optional: LoRaWAN concentrator / packet forwarder on the same LAN or USB

Flash Ubuntu Server 24.04 for Raspberry Pi

  1. Download Ubuntu Server 24.04 LTS (64-bit) for Raspberry Pi from Ubuntu Raspberry Pi images.
  2. Flash with Raspberry Pi Imager or dd to the SD card / SSD.
  3. In Imager OS customisation (recommended):
  • Set hostname, e.g. agrogat-edge-01
  • Create user, e.g. agrogat
  • Enable SSH with password or public key
  • Configure Wi-Fi if not using Ethernet
  1. Insert media, power on the Pi, wait ~2 minutes for first boot.

Step 2 — First login and system update

From your workstation:

BASH
ssh agrogat@<PI_IP_ADDRESS>

Replace <PI_IP_ADDRESS> with the address from your router or raspberrypi.local if mDNS works.

On the Pi:

BASH
# System packages up to date
sudo apt update && sudo apt upgrade -y

# Useful tools
sudo apt install -y git curl unzip software-properties-common

# Set timezone (example: Norway)
sudo timedatectl set-timezone Europe/Oslo

# Optional: set a descriptive hostname
sudo hostnamectl set-hostname agrogat-edge-01

Reboot if the kernel was updated:

BASH
sudo reboot

Step 3 — Install Apache, PHP, and PostgreSQL

Ubuntu 24.04 provides PHP 8.3 — compatible with Agrogat (requires PHP 8.1+).

BASH
sudo apt install -y \
  apache2 \
  libapache2-mod-php \
  php-cli \
  php-pgsql \
  php-json \
  php-mbstring \
  php-xml \
  postgresql \
  postgresql-contrib

Enable Apache modules:

BASH
sudo a2enmod rewrite headers
sudo systemctl enable --now apache2 postgresql

Verify versions:

BASH
php -v
apache2 -v
sudo -u postgres psql -c "SELECT version();"

Step 4 — Create PostgreSQL database and user

Choose a database name (example: agrogat_iot). Use a strong password.

BASH
sudo -u postgres psql -v ON_ERROR_STOP=1 <<'SQL'
CREATE ROLE trat_admin WITH LOGIN PASSWORD 'CHANGE_ME_STRONG_PASSWORD';
CREATE DATABASE agrogat_iot OWNER trat_admin;
GRANT ALL PRIVILEGES ON DATABASE agrogat_iot TO trat_admin;
SQL

Test connection as the app user:

BASH
psql -h localhost -U trat_admin -d agrogat_iot -c "SELECT 1;"

Step 5 — Clone the Agrogat application

Install under /var/www/html/agrogat (matches project conventions and Apache examples).

BASH
sudo mkdir -p /var/www/html
sudo chown $USER:www-data /var/www/html

cd /var/www/html
git clone git@github.com:monsegaard/agrogat.git agrogat
cd agrogat

Private repository: add your SSH deploy key to GitHub first, or clone via HTTPS with a Personal Access Token.

If the directory already exists, use git pull instead.


Step 6 — Configure Apache

Option A — Access by IP or local hostname (typical edge node)

Create a site config:

BASH
sudo tee /etc/apache2/sites-available/agrogat-edge.conf <<'EOF'
<VirtualHost *:80>
    ServerName agrogat-edge.local
    DocumentRoot /var/www/html/agrogat

    ErrorLog ${APACHE_LOG_DIR}/agrogat-error.log
    CustomLog ${APACHE_LOG_DIR}/agrogat-access.log combined

    <Directory /var/www/html/agrogat>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
EOF

sudo a2dissite 000-default.conf
sudo a2ensite agrogat-edge.conf
sudo apache2ctl configtest && sudo systemctl reload apache2

Open http://<PI_IP_ADDRESS>/ in a browser — you should see the Agrogat welcome page.

Option B — Public domain with TLS

If the Pi has a public DNS name, copy the project template and run Certbot:

BASH
sudo cp /var/www/html/agrogat/deploy/apache-agrogat.com.conf /etc/apache2/sites-available/agrogat.conf
# Edit ServerName if needed
sudo a2ensite agrogat.conf
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d your-domain.example.com

Step 7 — Create .env (application configuration)

BASH
cd /var/www/html/agrogat
cp .env.example .env
nano .env

Minimum values for an edge gateway:

INI
DB_HOST=localhost
DB_PORT=5432
DB_NAME=agrogat_iot
DB_USER=trat_admin
DB_PASS=CHANGE_ME_STRONG_PASSWORD

INGEST_API_KEY=GENERATE_WITH_COMMAND_BELOW
GATEWAY_CODE=TRAT-GATEWAY-001
GATEWAY_CLUSTER=TRAT

# Mark this node as an edge gateway (welcome page badge)
IS_EDGE_GATEWAY=1

# Optional: push readings to central server
# CENTRAL_SYNC_URL=https://central.example.com/api/sync_receive.php
# SYNC_API_KEY=same_secret_on_central_and_edge

Generate API keys:

BASH
php -r "echo bin2hex(random_bytes(32)) . PHP_EOL;"

Run twice if you need separate values for INGEST_API_KEY and SYNC_API_KEY.

Secure the file:

BASH
chmod 640 .env
sudo chown $USER:www-data .env

Step 8 — File permissions for data/

The simulator and LIVE mode store settings in data/settings.json:

BASH
cd /var/www/html/agrogat
mkdir -p data
sudo chown -R www-data:www-data data
chmod 775 data

Ensure Apache can read the rest of the tree:

BASH
sudo chown -R $USER:www-data /var/www/html/agrogat
find /var/www/html/agrogat -type d -exec chmod 775 {} \;
find /var/www/html/agrogat -type f -exec chmod 664 {} \;

Step 9 — Run database migrations

Use the bundled script (runs 001001b002005 in order):

BASH
cd /var/www/html/agrogat
sudo ./scripts/migrate_postgres.sh agrogat_iot

Expected output ends with: Migrasjoner fullført for database «agrogat_iot».

Manual alternative — see setup.md.


Step 10 — Create the first administrator

BASH
cd /var/www/html/agrogat
php scripts/create_admin.php admin@example.com 'YourStrongPassword'

Sign in at http://<PI_IP_ADDRESS>/login.php.


Step 11 — Register this gateway in the database

After login, open the dashboard → Gateways tab and confirm a row exists with code matching GATEWAY_CODE in .env (default seed: TRAT-GATEWAY-001).

For a dedicated edge node, create a new gateway code, e.g. FIELD-GW-01, and update .env:

INI
GATEWAY_CODE=FIELD-GW-01
GATEWAY_CLUSTER=TRAT

New ingest readings will then link to the correct gateway.


Step 12 — Optional: firewall (UFW)

If the Pi is exposed on a network, allow SSH and HTTP only:

BASH
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
# If using HTTPS:
# sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status

Do not expose PostgreSQL (5432) to the internet.


Step 13 — Optional: cron sync to central server

When CENTRAL_SYNC_URL and SYNC_API_KEY are configured, add cron jobs:

BASH
sudo crontab -u www-data -e

Add:

CRON
*/5 * * * * /usr/bin/php /var/www/html/agrogat/scripts/sync_push_to_central.php >> /var/log/agrogat-sync.log 2>&1
*/15 * * * * /usr/bin/php /var/www/html/agrogat/scripts/sync_push_entities_to_central.php >> /var/log/agrogat-sync-entities.log 2>&1

Test manually:

BASH
sudo -u www-data php /var/www/html/agrogat/scripts/sync_push_to_central.php

Details: setup.md.


Step 14 — Verify the installation

Welcome page (guest):

BASH
curl -s -o /dev/null -w "%{http_code}\n" http://localhost/

Expect 200.

Ingest API:

BASH
cd /var/www/html/agrogat
set -a && source .env && set +a

curl -s -X POST http://localhost/ingest.php \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ${INGEST_API_KEY}" \
  -d '{"sensor_id":"test-001","payload":{"vwc":42.5,"temperature_c":12.3}}'

Expected:

JSON
{"status":"success","id":"1"}

Dashboard: log in, check tabs (Clients, Sensors, Gateways, Data). Set Simulator or LIVE under Operations if needed.

API docs: http://<PI_IP_ADDRESS>/docs/api.php


Step 15 — Connect field sensors

  1. Point LoRaWAN network servers or sensor gateways to http://<PI_IP_ADDRESS>/ingest.php with header X-API-Key.
  2. Register each sensor_id under Sensors in the dashboard (or via seed scripts).
  3. For Dragino LSE01 soil probes, see sensors-dragino-lse01.md.
  4. For RS485 / piezometer hex payloads, see api.md.

Troubleshooting

Problem Solution
403 Forbidden on web Check Apache DocumentRoot and directory permissions
500 or blank page sudo tail -f /var/log/apache2/agrogat-error.log
Database connection failed Verify .env credentials; sudo systemctl status postgresql
401 on ingest Wrong or missing X-API-Key; must match INGEST_API_KEY
Migration fails on role Create trat_admin first (Step 4)
sensor_data missing before 002 Run 001b_sensor_data.sql or use migrate_postgres.sh
Git clone fails (private repo) Add SSH key to GitHub or use HTTPS + token
Slow SD card Move to USB SSD; enable log rotation for sync logs

Maintenance

Update application code:

BASH
cd /var/www/html/agrogat
git pull
# Run any new migrations:
sudo ./scripts/migrate_postgres.sh agrogat_iot
sudo systemctl reload apache2

Backup database:

BASH
sudo -u postgres pg_dump agrogat_iot > agrogat_iot_$(date +%F).sql

Document Contents
setup.md .env reference, sync, migrations detail
api.md Ingest and REST endpoints
examples.md Sample curl and client code
sensors-dragino-lse01.md Dragino LSE01 integration