Skip to content

Latest commit

Β 

History

106 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

RAMPP

Build License: GPL v3 Platform Release Rust Buy Me A Coffee

A deterministic local development stack manager for Windows x64

βš™οΈ Deterministic State Machine β€’ 🧱 Apache Β· MySQL Β· PHP β€’ πŸ›‘οΈ Job-Object Isolation β€’ πŸ¦€ Rust

Features β€’ Installation β€’ Architecture β€’ License


RAMPP is a deterministic local development stack manager for Windows x64. It orchestrates Apache, MySQL, and PHP through a formally defined state machine β€” no race conditions, no orphaned processes, no partial config writes.

Replace XAMPP or Laragon with something you can read, audit, and trust.


✨ Features

  • Deterministic β€” every state transition is explicit: STATE + EVENT β†’ NEW STATE + SIDE EFFECTS
  • Safe β€” every service runs inside a Windows Job Object; killing RAMPP kills the entire process tree, no zombies
  • Observable β€” all transitions logged; events are replayable for debugging
  • Fast β€” sub-second UI, Apache ready in ≀ 3 s, MySQL ready in ≀ 5 s
  • Self-provisioning β€” generates httpd.conf, my.ini, php.ini, phpmyadmin.conf and config.inc.php, and initialises the MySQL data directory on first run; marker-gated so hand-edited files are never clobbered
  • phpMyAdmin integration β€” optional one-click admin toggle, wired automatically to the running MySQL + PHP instances
  • System tray β€” lives quietly in the tray; full egui status window on demand
  • Crash recovery β€” automatic restart with exponential backoff (1 s β†’ 2 s β†’ 4 s β†’ 8 s β†’ Error)
  • Quick access β€” open localhost in the browser or jump straight to a service config file from each row
  • Live uptime β€” each running service shows elapsed uptime; startup progress shown during Starting
  • Log tools β€” copy the full log to clipboard or clear it with one click; error badges are dismissible

πŸ“‹ Requirements

Requirement Notes
Windows 10/11 x64 Only supported platform
Apache HTTP Server 2.4 (Win64, VS17) From Apache Lounge
MySQL 9.x Community (ZIP) ZIP archive, not installer
PHP 8.x Thread Safe (ZIP) TS x64 ZIP β€” required for PHP-CGI FastCGI
phpMyAdmin (ZIP) Optional β€” enables the built-in admin toggle
Visual C++ Redistributable 2022 x64 Required by Apache Lounge builds

πŸ“¦ Installation

1. Download the release binary

Grab rampp.exe from the latest release and place it at:

C:\rampp\rampp.exe

2. Extract Apache and MySQL

Extract the Apache ZIP so that httpd.exe ends up at:

C:\rampp\apache\bin\httpd.exe

Extract the MySQL ZIP so that mysqld.exe ends up at:

C:\rampp\mysql\bin\mysqld.exe

Extract the PHP ZIP so that php-cgi.exe ends up at:

C:\rampp\php\php-cgi.exe

Optionally, extract phpMyAdmin so that index.php ends up at:

C:\rampp\phpmyadmin\index.php

phpMyAdmin is not required for Apache, MySQL or PHP to run β€” it only unlocks the admin toggle in the status window (see Configuration ownership below for the files RAMPP generates for it).

The final layout should look like:

C:\rampp\
  rampp.exe
  apache\
    bin\httpd.exe
    modules\
    ...
  mysql\
    bin\mysqld.exe
    lib\
    share\
    ...
  php\
    php-cgi.exe
    ext\
    ...
  phpmyadmin\        (optional)
    index.php
    ...

3. Install the Visual C++ Redistributable

Run vc_redist.x64.exe if you haven't already.

4. Run RAMPP

Double-click rampp.exe. On first launch RAMPP will:

  1. Generate rampp.toml (ports 8080 + 3306 + 9000)
  2. Create apache\conf\httpd.conf, apache\htdocs\index.php, mysql\my.ini, php\php.ini, and (if phpmyadmin\ exists) apache\conf\phpmyadmin.conf + phpmyadmin\config.inc.php
  3. Run mysqld --initialize-insecure (~10–20 s, once only), then create a 127.0.0.1 account so RAMPP's own TCP connections (health checks, phpMyAdmin) can authenticate β€” see the note below
  4. Show the system tray icon and status window

Click Start All to bring up all three services. Apache will be at http://127.0.0.1:8080/, MySQL at 127.0.0.1:3306 (root, no password), and PHP-CGI will be listening on 127.0.0.1:9000 (FastCGI, proxied from Apache).

Why a second MySQL account? mysqld --initialize-insecure only ever creates root@localhost. RAMPP's own connections β€” health checks, phpMyAdmin, anything in rampp.toml's [phpmyadmin] section β€” are TCP to 127.0.0.1 (the loopback-only security constraint), which is a distinct grant from localhost and would otherwise be refused outright. First-run initialization also grants <mysql_user>@'127.0.0.1' (default user root, empty password) full privileges β€” but not WITH GRANT OPTION β€” so this works out of the box.

Configuration ownership

RAMPP generates httpd.conf, my.ini, php.ini, phpmyadmin.conf and phpMyAdmin's config.inc.php, and each one carries a marker line on its first line identifying it as generated.

  • Keep the marker and RAMPP keeps the file in sync β€” ports, document root and phpMyAdmin wiring all follow your settings automatically. Your previous content is saved beside it as .bak whenever RAMPP changes it.
  • Remove the marker and the file becomes yours. RAMPP will never write it again. If a port then needs to move because something else holds it, the affected service reports an error naming the file instead of silently misconfiguring itself.

Upgrading to 1.5.0: before 1.5.0, php.ini and my.ini were never regenerated once created. If you edited either of them while leaving the marker line intact, your changes will be replaced on first run and saved to php.ini.bak / my.ini.bak. Remove the marker line first if you want RAMPP to leave the file alone permanently.

phpMyAdmin during a service crash: phpMyAdmin now stays enabled if MySQL or PHP crashes, rather than switching itself off and requiring a manual re-toggle. If PHP crashes, Apache's mod_proxy_fcgi can't reach the PHP-CGI backend and returns 503 until auto-retry restarts it; if MySQL crashes while Apache/PHP stay up, phpMyAdmin's own PHP code hits the failed connection instead, which surfaces as an in-page connection error, not an Apache-level 503.


βš™οΈ Configuration

Edit C:\rampp\rampp.toml to change ports:

install_dir = "C:\\rampp"

[apache]
port = 8080

[mysql]
port = 3306

[php]
port = 9000

[phpmyadmin]
mysql_user = "root"
mysql_password = ""

RAMPP validates the entire file before accepting it β€” an invalid config is rejected completely and the last valid config is preserved. After editing, restart the affected service from the UI.

[phpmyadmin] sets the credentials RAMPP uses for its own MySQL connections β€” health checks and phpMyAdmin's config.inc.php β€” and the account that first-run initialization grants at 127.0.0.1, described above. It does not need to match any account you create yourself for other tools.

See Configuration ownership above for which files RAMPP regenerates and which it leaves alone.


πŸ—οΈ Architecture

RAMPP is a single binary built around a pure reducer:

STATE + EVENT β†’ NEW STATE + SIDE EFFECTS
Layer File Role
Types state.rs AppState, ServiceState machine, all constants
Events events.rs Event enum + SideEffect enum
Logic reducer.rs Pure function β€” no I/O, fully unit-tested
I/O executor.rs Translates SideEffects into process ops and threads
Processes process.rs Windows Job Object spawn/kill
Health health.rs Apache HTTP + MySQL TCP + PHP TCP readiness and health checks
Config config.rs rampp.toml load/validate + atomic write
Paths paths.rs Install-dir contract, traversal rejection, symlink rejection
Log logger.rs Bounded ring buffer (1 000 lines)
Apache conf apache_conf.rs Generate httpd.conf with PHP FastCGI proxy
MySQL conf mysql_conf.rs Generate my.ini, initialize data dir, grant the 127.0.0.1 account
PHP conf php_conf.rs Generate php.ini for PHP-CGI
phpMyAdmin conf phpmyadmin_conf.rs Generate phpmyadmin.conf and config.inc.php
Provisioning provision.rs Marker-gated, diff-driven reconciler for every managed config file
Tray tray.rs Windows system tray
UI ui.rs egui status window

Service state machine

Stopped ──START──► Starting ──PROCESS_READY──► Running
                      β”‚                           β”‚
               PROCESS_EXIT                 PROCESS_EXIT
                      β”‚                           β”‚
                      └──────────► Crashed β—„β”€β”€β”€β”€β”€β”€β”˜
                                     β”‚
                               AUTO_RETRY (Γ—4, backoff)
                                     β”‚
                                  Starting
                                     β”‚
                             (max retries exceeded)
                                     β”‚
                                   Error

Any state ──FATAL_ERROR──► Error
Running   ──STOP──► Stopping ──PROCESS_EXIT──► Stopped

Process isolation

Every service spawns inside a dedicated Windows Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. Dropping the job handle terminates the entire process tree β€” Apache child workers, MySQL threads, everything β€” with no orphans.

If AssignProcessToJobObject fails the service transitions directly to Error and never starts.

Health checks

Service Check Pass condition Interval Fail threshold
Apache HTTP GET 127.0.0.1:port/ 200–399 + Server: Apache 2 s 3 consecutive
MySQL TCP connect + 4-byte greeting Handshake starts 2 s 3 consecutive
PHP TCP connect to FastCGI port Connection succeeds 2 s 3 consecutive

Three consecutive failures trigger HEALTH_CHECK_FAIL, which kills the service and schedules a retry.


πŸ”¨ Building from source

# Prerequisites: Rust stable toolchain (rustup.rs), MSVC build tools
git clone https://github.com/rbenzing/RAMPP.git
cd rampp
cargo build --release
# Binary at target\release\rampp.exe

Run the test suite:

cargo test
cargo clippy -- -D warnings
cargo fmt -- --check

πŸ”’ Security model

  • Services bind to 127.0.0.1 only β€” no external exposure by default
  • All binary paths are absolute and validated against the install directory β€” no PATH-based execution
  • Environment variables are sanitised before spawning child processes
  • Config writes are atomic (temp β†’ fsync β†’ rename) β€” a crash during write cannot corrupt the config
  • Symlinks are rejected for the config directory, binaries, and data directory
  • MySQL is initialised with --initialize-insecure (no root password); first run also grants <mysql_user>@'127.0.0.1' full privileges (no WITH GRANT OPTION) so RAMPP's own loopback connections authenticate β€” suitable for local development only

πŸ“„ License

RAMPP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3.0.


πŸ‘€ About the Author

Built by Russell Benzing. RAMPP is a deterministic, auditable alternative to XAMPP/Laragon for local Windows development.


πŸ†˜ Support

If RAMPP is useful to you, you can support the work:

Buy Me A Coffee

About

Portable Rust-Powered Apache, MySQL, PHP & PhpMyAdmin Development Stack for Windows

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages