Skip to content

Latest commit

 

History

History

.devcontainer

README.md

Development Environment

This folder contains the Docker-based development environment for Poweradmin with multi-database support.

Quick Start

The VS Code devcontainer creates the stack as compose project poweradmin_devcontainer. Reuse that name when driving it by hand, otherwise compose forks a second project with empty volumes and aborts on container-name conflicts:

docker compose -f .devcontainer/docker-compose.yml --project-directory .devcontainer \
  --project-name poweradmin_devcontainer up -d

Then load the fixtures: .devcontainer/scripts/import-test-data.sh

Each database family runs its own PHP version (set in .env), so one E2E sweep over the three SQL instances covers three versions at once:

Family Instances PHP
MySQL/MariaDB 8080, 8083, 8086, 8088, 8089 PHP_VERSION_MYSQL = 8.2 (the supported floor)
SQLite 8082, 8085 PHP_VERSION_SQLITE = 8.3
PostgreSQL 8081 (Apache), 8084 PHP_VERSION_PGSQL = 8.4 (same as the production image)
German-only 8087 PHP_VERSION_DE = 8.5 (newest release)

The images are tagged poweradmin-devcontainer-fpm:<version>; the first service of a family builds, the others reuse the tag. After editing .devcontainer/Dockerfile or a version in .env, run docker compose ... build and recreate the app services.

Xdebug is off by default. Set PHP_XDEBUG=1 in .env, rebuild the fpm images and recreate the app services; conf/xdebug.ini holds the client settings (host.docker.internal, port 9003).

Only the web instances (8080-8089) listen on all interfaces. Databases, LDAP, the PowerDNS DNS/API ports, Adminer and phpLDAPadmin are bound to 127.0.0.1, so they are unreachable from other machines on your network.

Architecture

Each database has two Poweradmin instances - one using direct SQL and one using the PowerDNS REST API backend (experimental). Every instance has its own database and its own PowerDNS server (DNSSEC enabled), so the two instances of a family can run at the same time without writing to the same zones, domains or records rows.

SQL Backend (default - direct database access)

Port Web Server Database PowerDNS DNS PowerDNS API
8080 Nginx MySQL/MariaDB 1053 8181
8081 Apache PostgreSQL 1054 8182
8082 Caddy SQLite 1055 8183

API Backend (experimental - writes via PowerDNS REST API)

Port Web Server Database PowerDNS DNS PowerDNS API
8083 Nginx MySQL/MariaDB (poweradmin_api + pdns_api) 1058 8186
8084 Nginx PostgreSQL (pdns_api) 1059 8187
8085 Nginx SQLite (/data/pdns-api.db) 1057 8185

Special-purpose instances (MySQL/MariaDB, SQL backend)

Port Purpose
8086 Subfolder deployment, served under http://localhost:8086/poweradmin/
8087 German-only interface (enabled_languages restricted to de_DE)
8088 Web server authentication: nginx asks for a password and Poweradmin signs in REMOTE_USER (users remote-alice, remote-bob and admin, password Poweradmin123; admin is a local account, so it is refused)
8089 OIDC and SAML sign-in against the mock-oidc (localhost:9080, any username, claims typed in) and mock-saml (localhost:9081, users samlmanager/samlmanagerpass and samlnobody/samlnobodypass) containers; account lockout is enabled only here, so run only npm run test:e2e:sso against it (the wider login specs fail admin on purpose and would lock it)

Port Mappings

Poweradmin Web Interfaces (SQL backend)

Poweradmin Web Interfaces (API backend)

Installer

Every instance serves the installer at /install/ (subfolder: http://localhost:8086/poweradmin/install/). It only runs while config/settings.php is absent; with the file in place it reports that the installation is skipped. Browsers cache 301 redirects, so if /install once sent you to http://localhost/install/ without the port, open the URL with the trailing slash or clear the site data for that origin.

PowerDNS Servers (with DNSSEC)

  • MySQL backend (SQL instance, pdns): DNS port 1053, API port 8181
  • MySQL backend (API instance, pdns_api): DNS port 1058, API port 8186
  • PostgreSQL backend (SQL instance, pdns): DNS port 1054, API port 8182
  • PostgreSQL backend (API instance, pdns_api): DNS port 1059, API port 8187
  • SQLite backend (SQL instance, /data/pdns.db): DNS port 1055, API port 8183
  • SQLite backend (API instance, /data/pdns-api.db): DNS port 1057, API port 8185
  • LMDB backend (opt-in, the only backend with views and network mappings): DNS port 1056, API port 8184. Start it with docker compose --profile lmdb up -d pdns-lmdb (same -f/--project-name flags as above).

Admin Tools

Databases

  • MariaDB: localhost:3306
  • PostgreSQL: localhost:5432
  • LDAP: localhost:389, 636 (LDAPS)

Configuration Files

Web Server Configs

  • conf/nginx.conf.template - Nginx configuration shared by every nginx front (FPM_UPSTREAM selects the PHP-FPM container)
  • conf/nginx-subfolder.conf - Nginx configuration for the subfolder instance
  • conf/apache-vhost.conf - Apache virtual host (PostgreSQL + SQL)
  • conf/Caddyfile - Caddy configuration (SQLite + SQL)

PowerDNS Configs (DNSSEC enabled)

  • conf/pdns-mysql.conf - PowerDNS for MySQL (SQL instance)
  • conf/pdns-mysql-api.conf - PowerDNS for MySQL (API instance)
  • conf/pdns-pgsql.conf - PowerDNS for PostgreSQL (SQL instance)
  • conf/pdns-pgsql-api.conf - PowerDNS for PostgreSQL (API instance)
  • conf/pdns-sqlite.conf - PowerDNS for SQLite (SQL instance)
  • conf/pdns-sqlite-api.conf - PowerDNS for SQLite (API instance)

Poweradmin Settings (SQL backend)

  • conf/settings-mysql-sql.php - MySQL + SQL backend
  • conf/settings-pgsql-sql.php - PostgreSQL + SQL backend
  • conf/settings-sqlite-sql.php - SQLite + SQL backend

Poweradmin Settings (API backend)

  • conf/settings-mysql-api.php - MySQL + API backend
  • conf/settings-pgsql-api.php - PostgreSQL + API backend
  • conf/settings-sqlite-api.php - SQLite + API backend

Docker Files

  • Dockerfile - PHP-FPM container (for Nginx/Caddy)
  • apache.Dockerfile - Apache with PHP container
  • docker-compose.yml - Main orchestration file

Database Access

Via Adminer

Access Adminer at http://localhost:8090

Direct Connection

  • MariaDB: user: pdns, pass: poweradmin, db: pdns (app tables in poweradmin db); the API instance uses pdns_api and poweradmin_api; root password uberuser
  • PostgreSQL: user: pdns, pass: poweradmin, db: pdns; the API instance uses pdns_api
  • SQLite: /data/pdns.db for the SQL instance, /data/pdns-api.db for the API instance (both mounted in containers)

Test Credentials

After importing test data (.devcontainer/scripts/import-test-data.sh):

  • Username: admin, manager, client, viewer, noperm, inactive
  • Password: Poweradmin123

LDAP Test Users

The ldap container bootstraps ldap/bootstrap/*.ldif on first start (users, the dns-admins group and a memberof overlay for groupOfNames). The MySQL import adds the matching Poweradmin accounts, so LDAP login works on the MySQL instances (8080, 8083, 8086):

  • testuser / testpass123 (Administrator template, member of dns-admins)
  • testuser2 / testpass456 (Zone Manager template)

Check the whole chain with .devcontainer/scripts/verify-ldap-test-setup.sh. phpLDAPadmin: http://localhost:8443 (login DN cn=admin,dc=poweradmin,dc=org, password poweradmin).