Getting Started

Setting up PonControl on a fresh server - OS packages, the web server, PHP, and MySQL.

Written for Ubuntu/Debian. Package names below are Debian/Ubuntu's apt names; adjust for another distro (dnf/yum package names differ, e.g. php-snmp instead of php8.1-snmp).

PHP 7.4 or newer is required (arrow functions are the oldest language feature this codebase actually uses - nothing here needs 8.x). Examples below use php8.1-* package names purely as a placeholder; substitute whichever PHP version you're actually installing or already have (php7.4-*, php8.2-*, ...) - there's no reason to chase a specific newer version if an older supported one is what your server already has.

1. Install packages

Apache (recommended)

This is what the app's own .htaccess files are written for.

sudo apt update
sudo apt install apache2 libapache2-mod-php8.1 \
    php8.1-cli php8.1-mysql php8.1-snmp php8.1-curl php8.1-mbstring \
    mysql-server git

That's the full module list this codebase actually needs - confirmed by checking every PHP file for the extension-specific function it calls:

PackageWhy
php8.1-mysqlmysqli_* - every DB query in the app
php8.1-snmpsnmp2_get()/snmprealwalk() - all OLT/ONU polling
php8.1-curlGoogle Sign-In token exchange, a few other outbound HTTP calls
php8.1-mbstringmulti-byte string length checks on user search input

Everything else the app touches - sessions, JSON, password hashing, and gzip compression (used by Backup/Restore) - is core PHP already. In particular, no need for php8.1-zip: backups are gzip'd JSON, not zip files, specifically because this class of deployment often has no ZipArchive extension available. Nothing here touches GD, LDAP, XML, bcmath, gmp, or intl either.

Nginx (alternative)

The app ships .htaccess files that Apache reads automatically. Nginx ignores .htaccess entirely - if you go this route you must hand-write the equivalent rules in your server block, or some folders end up wide open over HTTP:

  • Whole site: HTTP Basic Auth
  • /api/: no Basic Auth (a separate Bearer-token API for the mobile app)
  • /backups/, /update_procedure/, /config/: deny all direct HTTP access
location / {
    auth_basic "Authorize, please!";
    auth_basic_user_file /var/www/poncontrol2/.htpasswd;
    try_files $uri $uri/ /index.php?$query_string;
}
location /api/ {
    try_files $uri =404;
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ ^/(backups|update_procedure|config)/ {
    deny all;
    return 403;
}
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

2. Apache virtual host

The one setting Ubuntu's default Apache config does not give you, and that this app genuinely needs, is AllowOverride AuthConfig - without it, every .htaccess file above is silently ignored and the whole site is served with no protection at all.

<VirtualHost *:80>
    ServerName pon.example.org
    DocumentRoot /var/www/poncontrol2

    <Directory /var/www/poncontrol2>
        AllowOverride AuthConfig
        Require all granted
    </Directory>
</VirtualHost>
sudo a2ensite pon.example.org.conf
sudo systemctl reload apache2

HTTPS is not optional

The login session cookie is set with secure => true - browsers won't send it back over plain HTTP, so logging in will silently appear to do nothing. Put the site behind TLS before testing login (certbot --apache is the easy path for a public hostname).

Create the site-wide HTTP Basic Auth file

sudo htpasswd -c /var/www/poncontrol2/.htpasswd youradminuser

3. Create the MySQL database

CREATE DATABASE poncontrol CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'poncontroluse'@'localhost' IDENTIFIED BY 'poncontrolpassword';
GRANT ALL PRIVILEGES ON poncontrol.* TO 'poncontroluse'@'localhost';
FLUSH PRIVILEGES;

You don't need to create any tables yourself - every table this app uses is created automatically, on demand, the first time something needs it. An empty database with the right grants is a complete starting point.

4. Deploy the code

sudo mkdir -p /var/www/poncontrol2
sudo git clone https://github.com/<your-fork>/poncontrol2.git /var/www/poncontrol2
sudo chown -R www-data:www-data /var/www/poncontrol2

5. First-run setup wizard

Visit https://your-domain/setup.php and fill in your MySQL host/db/user/pass and your OLTs' telnet credentials (used for the FDB table and per-ONU speed limits). Submitting writes config/vars.php and creates the base olts table.

Default login

The very first page load after this seeds one account: admin / admin1234. Log in and change the password immediately - this default is public.

6. Add an OLT and start polling

Add your first OLT from the UI (IP + SNMP community), then set up the polling loop as a cron job:

# Every 2 minutes is a reasonable starting point for a handful of OLTs
*/2 * * * * php /var/www/poncontrol2/ping_all.php > /dev/null

What's next

  • Once the site is confirmed working, PonControl can be set up to update itself automatically from a deploy key + cron.
  • Zabbix/Telegram alerting, UserSide integration, and Google Sign-In are all optional and configured entirely through the Settings UI - none of it is required to get core OLT/ONU monitoring working.