A lightweight open source message board built with PHP and MySQL. It supports public posts, image/PDF attachments, comments, email verification hooks, basic admin moderation, optional bot protection, visitor metadata review, and a configurable Yahoo Finance market widget.
- Public message posting with optional title, author name, email, hashtags, SEO keywords, images, and PDFs.
- Comment threads for published posts, including optional image and PDF attachments.
- Admin moderation for reviewing posts, opening per-post comment drawers, and deleting content.
- MySQL schema with posts, images, attachments, comments, hashtags, and moderation logs.
- Configurable site name, base URL, timezone, upload limits, and allowed image/PDF types.
- Optional Cloudflare Turnstile verification.
- Visitor metadata capture for moderation: IP address, user agent, browser language, and browser timezone.
- Configurable Yahoo Finance ticker card with a cached one-month sparkline.
- Private application configuration kept outside the public web root.
- PHP 8.1 or newer with PDO MySQL enabled.
- MySQL 5.7 or newer, or a compatible MariaDB version.
- A web server such as Nginx, Apache, Caddy, or a PHP-capable hosting panel.
- Write access for the configured upload directory.
-
Upload or clone the project onto your server.
-
Point the web root or document root to the
web/directory.The
private/directory must not be publicly accessible. It contains configuration and database setup files. -
Create an empty MySQL database and database user for the application.
-
Visit the installer in your browser:
https://your-domain.example/install.php -
Fill in:
- site name, base URL, timezone, and mail sender
- MySQL host, port or socket, database name, database user, and password
- first admin username and password
- upload directory, if your host needs a custom path
- optional Cloudflare Turnstile keys
- optional Yahoo Finance ticker
The installer imports
private/schema.sql, createsprivate/config.php, generates the admin password hash, and checks that the upload directory is writable. -
After installation, delete or rename
web/install.php.The installer refuses to run while
private/config.phpexists, but removing it is still the safer production setup.
Use this if your host does not allow the web installer to write files.
-
Create a MySQL database and user for the application.
-
Import the database schema:
mysql -u message_board_user -p message_board < private/schema.sql -
Copy the sample configuration:
cp private/config.sample.php private/config.php
-
Edit
private/config.phpand set:site_namebase_urltimezone- database DSN, username, and password
- admin username and password hash
- mail sender settings
- market ticker and cache duration
- upload directory plus image and PDF limits
-
Generate an admin password hash:
php -r "echo password_hash('change-this-password', PASSWORD_DEFAULT) . PHP_EOL;"Put the generated value in
private/config.phpasadmin.password_hash. -
Create the upload directory if it does not already exist:
mkdir uploads chmod 750 uploads
The PHP process must be able to write to this directory. If your host uses a different deployment layout, set
uploads_dirinprivate/config.phpto an absolute path outside the public web root. -
If you want to update Turnstile or the market ticker from the admin panel, make sure the PHP process can write small override files in
private/.
To enable Turnstile:
- Create a Turnstile widget in your Cloudflare dashboard.
- Add the site key and secret key to
private/config.php. - Set
turnstile.enabledtotrue.
Leave Turnstile disabled for local development unless you have valid test keys.
The left rail can display a Yahoo Finance quote card. Configure it in private/config.php:
'market' => [
'ticker' => 'NVDA',
'cache_seconds' => 300,
],Admins can also change the ticker from the admin panel. Cached quote files are written under private/market-cache-*.json and should not be committed.
If you installed an earlier version before visitor metadata was added, run:
mysql -u message_board_user -p message_board < private/migrations/2026-06-22-visitor-metadata.sqlIf you installed an earlier version before unified attachments were added, run:
mysql -u message_board_user -p message_board < private/migrations/2026-06-22-attachments.sql- Keep
private/config.phpout of version control. - Keep the web root pointed at
web/; do not expose the repository root. - Delete or rename
web/install.phpafter installation. - Store uploads outside the public web root when possible, and serve them through application routes.
- Use a strong admin password and replace any default sample values before deployment.
- Use HTTPS in production.
- Review retention needs for IP addresses, user agents, browser language, browser timezone, email addresses, and moderation logs.
- Back up the database and uploaded files before upgrades.
- Limit database privileges to only what the application needs.
- When deployed behind Cloudflare, the app stores
CF-Connecting-IPonly when the direct peer address is in Cloudflare's published IP ranges; otherwise it falls back toREMOTE_ADDR.
For local testing, use PHP's built-in server from the project root:
php -S 127.0.0.1:8080 -t webThen open http://127.0.0.1:8080.
MIT License. See LICENSE for details.