Sign inSign up

arogarth/wp-manager

By arogarth

•Updated 5 months ago

Small, simple Wordpress manager

Image
API management
Developer tools
Web servers
0

258

arogarth/wp-manager repository overview

WP Manager

⁠WP Manager

A self-hosted dashboard for managing multiple WordPress sites from a single interface. Tracks WordPress core, plugin, and theme versions across all your sites, detects available updates, and records full version history over time.

PHP MariaDB Docker Bootstrap

⁠Features

  • Multi-site overview — dashboard with sync status, WP version, and update counts per site
  • Plugin & theme inventory — cross-site views that group the same plugin/theme across sites, highlight version divergences, and show current → latest version arrows for pending updates
  • Version history — append-only snapshot log for every site, plugin, and theme; changes are only recorded when something actually differs from the previous sync
  • Update detection — queries WordPress.org APIs for latest core, plugin, and theme versions
  • Automated sync — Docker cron container syncs all active sites every 6 hours; manual "Sync All" button also available
  • Dual authentication — local username/password accounts alongside OpenID Connect (Keycloak, Authentik, or any standard OIDC provider)
  • User management — admin users can create, edit, and delete local accounts and assign admin roles
  • First-run setup — redirects to a guided admin-creation page when no users exist yet
  • Encrypted credentials — WordPress application passwords are stored with AES-256-GCM encryption

⁠Screenshots

Dashboard · Sites · Plugin Overview · Theme Overview · Version History

⁠Requirements

  • Docker & Docker Compose
  • A WordPress site with the REST API enabled and an Application Password⁠ created for a user with admin rights

⁠Quick Start

1. Clone and configure

git clone https://github.com/arogarth/wp-manager.git
cd wp-manager
cp .env.example .env

Edit .env and set at minimum:

ENCRYPTION_KEY=        # 64 hex characters (openssl rand -hex 32)
APP_URL=http://localhost:8080

2. Start the stack

docker compose up -d

3. Open the app

Navigate to http://localhost:8080⁠. On first visit you will be prompted to create an admin account.

4. Add a WordPress site

Go to Sites → Add Site and provide:

  • A display label
  • The site's base URL (e.g. https://example.com)
  • A WordPress username and its Application Password

Hit Sync to pull the first snapshot.

⁠Configuration

All configuration is done via environment variables (.env file or Docker environment).

VariableDefaultDescription
APP_URLhttp://localhost:8080Public base URL of this app
APP_ENVdevelopmentdevelopment or production
HTTP_PORT8080Host port mapped to nginx
ENCRYPTION_KEY—Required. 64-char hex key for credential encryption
DB_NAMEwp_managerMariaDB database name
DB_USERwp_managerMariaDB user
DB_PASSsecretMariaDB password
DB_ROOT_PASSrootsecretMariaDB root password
OIDC_ISSUER_URL—OIDC provider base URL (e.g. https://auth.example.com/realms/myrealm)
OIDC_CLIENT_ID—OIDC client ID
OIDC_CLIENT_SECRET—OIDC client secret
OAUTH_REDIRECT_URIhttp://localhost:8080/auth/callbackMust match your OIDC client config

OIDC is optional. If OIDC_CLIENT_ID is not set, the "Sign in with OpenID Connect" button is hidden and only local login is available.

⁠OIDC Setup

Configure your OIDC provider with:

  • Redirect URI: https://your-domain/auth/callback
  • Scopes: openid profile email

The app merges claims from both the ID token and the userinfo endpoint, so email, preferred_username, name, and picture are picked up regardless of which source your provider uses.

⁠Architecture

nginx (port 8080)
  └── PHP-FPM (app container)
        ├── public/index.php      front controller & router
        ├── src/Controller/       request handlers
        ├── src/Service/          database, encryption, WordPress API, sync logic
        ├── src/Auth/             session management, OIDC handler
        └── src/View/             PHP templates (Bootstrap 5)

MariaDB 11 (db container)
  └── migrations/001_initial_schema.sql   full schema

cron container
  └── bin/sync-all.php            runs every 6 hours via crond
  • No framework — vanilla PHP 8.2+, PSR-4 autoloading via Composer
  • Front controller pattern with a simple regex router (config/routes.php)
  • Append-only snapshots — site state is never mutated; each sync either adds a new snapshot row or skips if nothing changed
  • Change detection — SyncService::hasChanges() compares full plugin/theme state before inserting a snapshot

⁠Database Schema

TablePurpose
usersLocal and OIDC accounts, admin flag
sitesManaged WordPress sites (credentials encrypted)
site_snapshotsWP/PHP version per sync, with error log
pluginsPlugin registry per site
plugin_snapshotsPlugin version state per snapshot
themesTheme registry per site
theme_snapshotsTheme version state per snapshot
schema_migrationsTracks applied DB migration files

⁠Manual Sync

To trigger a sync from the command line (e.g. for testing):

docker compose exec app php bin/sync-all.php

⁠Resetting the Database

docker compose down -v   # removes the db_data volume
docker compose up -d

⁠Development

docker compose up -d
# Source is bind-mounted; PHP changes are reflected immediately.
# Composer dependencies live in the named 'vendor' volume built into the image.

To add a Composer dependency:

docker compose exec app composer require vendor/package

⁠Security Notes

  • WordPress application passwords are encrypted with AES-256-GCM before storage; the key never touches the database
  • All POST forms use CSRF tokens
  • Passwords are hashed with bcrypt
  • Session cookies are HttpOnly and SameSite=Lax; Secure flag is set automatically when the request arrives over HTTPS

⁠License

MIT

Tag summary

Content type

Image

Digest

sha256:85e2f08fd…

Size

43.9 MB

Last updated

5 months ago

docker pull arogarth/wp-manager