English / 中文

Lightweight · Stable · Reproducible WNMP One‑Click Stack

Install Nginx, PHP, and MariaDB (bundled with the Mroonga search engine) with a single command. Kernel/network tuning, WebDAV, and certificate configuration are automated. A ready‑to‑run production base for small/medium sites, edge nodes, and on‑prem projects.

Window11(WSL) Debian 13 Debian 12 Ubuntu 22.xx Ubuntu 24.xx Ubuntu 25.xx
Nginx 1.28.0 PHP 8.2–8.5 MariaDB 10.6 / 10.11 BBR / FQ · THP Off acme.sh One‑Click SSL WebDAV Drive No FTP SSH Key Login
Install
apt install -y curl curl -fL https://wnmp.org/wnmp.sh -o wnmp.sh chmod +x wnmp.sh bash wnmp.sh

Script open-source license: GPLv3. Please execute commands using the root account on a completely clean system.

v1.10 Modify SSH key logic: When multiple SSH keys are requested, only the latest public-private key pair remains valid. Older public keys are backed up and preserved.

v1.09 Delete the default site's .pem file to avoid confusion. The default site will only generate a .pem certificate file after formally applying for a certificate.

v1.05 Perform an overlay installation or execute `bash wnmp.sh remariadb`. First, create a full database backup at: /home/all_databases_backup_[time].sql.gz

v1.04 Pure Cloud Storage Site Blocking.php File, Preventing Source Code Download

v1.03 Optimize Nginx parameters to accelerate SSL certificate validation

v1.02 Added --pcntl extension, compatible with workerman

WNMP:

1、Windows11(WSL)+Nginx+Mariadb+PHP

(Deployed in a Linux subsystem running on Windows 11 - WSL, **not** an .exe environment package)

2、(Linux)WebDav+Nginx+Mariadb+PHP

Core Features

Ready‑to‑Use Web Runtime

Compiles Nginx 1.28.0 (dav‑ext / http2 / stream modules), optional PHP 8.2–8.5 and MariaDB 10.6 / 10.11, with sensible defaults.

Kernel / Network Tuning

Enables BBR/FQ, reasonable somaxconn and file descriptors, disables THP; writes sysctl and limits automatically with safe downgrades for WSL.

Certificate Automation

Integrated acme.sh. Prefers Cloudflare DNS‑01; automatically falls back to webroot; installs certs and reloads Nginx.

Multi‑Site & WebDAV

One‑click vhost creation, built‑in phpMyAdmin protection, WebDAV account management; supports separate password files per domain.

Maintainable Structure

Unified, straightforward directories:

/usr/local/nginx /usr/local/php /home/wwwroot

Secure Defaults

Blocks hidden paths and dangerous extensions; sensible timeouts and cache; turns off unnecessary PHP options by default.

Common Commands

Normal Install

bash wnmp.sh

Check Status

bash wnmp.sh status

SSH Key Login

bash wnmp.sh sshkey

Add WebDAV Account

bash wnmp.sh webdav

Default Site & Certificate

bash wnmp.sh default

Create Virtual Host (with SSL)

bash wnmp.sh vhost

Kernel/Network Tuning Only

bash wnmp.sh tool

Restart Services

bash wnmp.sh restart

One‑Click Cleanup

bash wnmp.sh remove # clean everything bash wnmp.sh renginx # clean Nginx only bash wnmp.sh rephp # clean PHP only bash wnmp.sh remariadb # clean MariaDB only

WSL Initialization

bash wnmp.sh wslinit

Footer Badge (Optional)

Place the following HTML into your website footer:

<small>This server is built by the <a href="https://wnmp.org" target="_blank" rel="noopener">wnmp.org</a> one‑click installer</small>

Frequently Asked Questions

Is it open source? Can I use it in commercial projects?

The script is released under GPLv3. Commercial use and redistribution are allowed, but derivative works must remain open under the same license. Please follow the licenses of third‑party dependencies.

Which systems are supported?

Primarily aimed at Debian 12/13 and Debian‑like systems. Verified on Windows11(WSL), (Linux)Debian 13, Debian 12, Ubuntu 22.04, Ubuntu 24.04, and Ubuntu 25.10. WSL (Debian recommended) receives safe downgrades.

For production, Debian13 is recommended. WNMP does not plan to support non‑Debian‑like distributions or EOL Debian variants.

How do I install and use WMMP on Windows?

Confirm you are using the Windows 11 operating system. First, you need to install the WSL subsystem.

Press Win+R to open the Run dialog box, then type cmd. Press Shift+Ctrl+Enter to enter the Administrator mode console.

wsl -l -o # Check if the remote system list can be read. If it reads normally, WSL is functioning correctly.

wsl --install debian # (Begin installing the Debian 13 subsystem. The first time you run this command, you may be prompted to restart your computer or notified that CPU virtualization support is disabled. Follow the on-screen instructions accordingly.)

After a normal installation, you will be prompted to configure a standard account and password. Once configured successfully, simply type: exit to exit the subsystem.

wsl -d debian -u root # Log in to the Debian system as the root user.

cd ~ apt update && apt install -y curl && curl -fL https://wnmp.org/wnmp.sh -o wnmp.sh && chmod +x wnmp.sh && bash wnmp.sh wslinit

In the address bar of this computer task, navigate to and open C:\Users\[username]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup # Replace [username] with your actual Windows login username.

Create a new wsl.vbs file and write the following content:

Set ws = CreateObject("Wscript.Shell") ws.run "wsl -d debian", 0

After initialization completes, the subsystem has installed the SSH server. Restart your computer as prompted, and you can then log in to your WSL Debian subsystem using an SSH client just like a regular server VPS.

Login address: 127.0.0.1 Port: 22

Additional WSL commands: In the Windows CMD environment, non-subsystem shell console

wsl -l -v # View list of installed systems

wsl --shutdown # Stop Subsystem

wsl --unregister debian # Uninstall Subsystem

If you need to access the subsystem via a local area network, open C:\Users\[username] # Please replace with your actual Windows login username.[username]

Create a new .wslconfig file and write the following content:

[wsl2] networkingMode=Mirrored dnsTunneling=true firewall=true autoProxy=true [experimental] hostAddressLoopback=true

Run the following command in an administrator PowerShell window to configure Hyper-V firewall settings to allow inbound connections:

Set-NetFirewallHyperVVMSetting -Name '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' -DefaultInboundAction Allow

Restart your computer again. You can now log into the subsystem using the same LAN IP address as your local Windows system. Enter `ipconfig` in the Command Prompt to view your local LAN IP address.

Why doesn’t WNMP provide a control panel?

Because the most secure server is the one without a control panel.

GUI-based panel software (such as BT Panel) makes server management easier, but it also brings:

🔓 Extra open ports (e.g., 8888) that expand the attack surface;

⚠️ Retaining SSH password login, which increases brute-force attack risks;

🧩 Long-running panel daemons that may be exploited or escalated;

🔄 Auto-update and plugin systems that reduce auditability.

WNMP follows a completely different philosophy:

✅ SSH key-only login by default (the most secure authentication method);

✅ No web panel ports — after deployment, almost zero persistent processes;

✅ Fully transparent configuration — scriptable, versionable, and auditable;

✅ Focus on host-level performance and security baseline, not GUI convenience.

WNMP’s goal is not to “replace BT Panel,” but to provide a clean, engineer-oriented environment template — the command line itself is the control panel, where security and control always come first.

Panels are for beginners; WNMP is for engineers.

Why not adapt to Docker?

WNMP does not simply “package Nginx + PHP + MariaDB into a container.” Instead, it enables one-click host-level performance tuning and security baseline configuration (kernel network parameters, ulimit restrictions, SSH key setup, compilation optimizations, etc.) within a clean system environment.

These host-level capabilities are often uncontrollable within containers or require high privileges like --privileged, which undermines the original intent of container isolation.

Therefore, WNMP is recommended for use within KVM virtual machines, cloud servers, or KVM virtual systems running on Proxmox (PVE) to fully leverage its performance tuning and system optimization advantages.

What is the minimum hardware requirement?

Without MariaDB: minimum 512 MB RAM on Debian (the OS itself uses ~200 MB). On Ubuntu, minimum 768 MB RAM (the OS uses ~500 MB).

With MariaDB installed: at least 1 GB RAM is required for a proper installation.

Which PHP versions are supported?

Only PHP 8.2 – 8.5 are supported.

WNMP intentionally does not support EOL legacy versions.

How do I install PHP extensions myself?

pecl install xxx

After installation, edit /usr/local/php/php.ini and add extension=xxx.so.

Verify with php -m.

Run bash wnmp.sh restart or systemctl restart php-fpm to reload PHP‑FPM and enable the extension.

Where are the download sources for Nginx, PHP, MariaDB, phpMyAdmin?

WNMP uses official download sources only. No third‑party mirrors are used.

If your download speed is extremely slow, try switching to a different system update source or install via proxy. For security reasons, always use the official download source!

Why compile Nginx/PHP/MariaDB instead of using binaries or apt?

Upstream releases appear first on official websites/GitHub, while Debian/Ubuntu repos may lag. Compiling also allows optional modules.

For example, WebDAV requires nginx-dav-ext-module.

As another example, Swoole supports PHP 8.5 on GitHub already, while some package repos lag; with WNMP you can use Swoole on PHP 8.5 immediately.

Which PHP extensions does WNMP enable by default? Why no switches?

WNMP builds PHP with swoole, apcu, inotify, and redis enabled by default.

Since the WNMP author is also the LOWPHP author, WNMP ensures LOWPHP runs well. Traditional PHP‑FPM projects also run normally on WNMP.

apcu is an official optional extension. It offers excellent single‑process performance but is unsuitable for PHP‑FPM’s short‑lived workers; your code still runs normally though.

inotify is also an official optional extension for real‑time file change monitoring.

LOWPHP is a persistent‑memory runtime that leverages native C extensions for caching and hot‑reload. It’s similar in spirit to FrankenPHP (Go‑style) but built natively for PHP. It is both a runtime and a framework, enabling high‑performance apps with a familiar PHP‑FPM‑like development model and multi‑site support. Coming soon.

How are certificates issued?

For DNS‑01 via Cloudflare: after compiling/installing Nginx with wnmp.sh, go to Cloudflare → My Profile → API Tokens → Create Token, choose “Edit zone DNS” to generate a token, then on the server run:

echo "SAVED_CF_Token='YOUR_TOKEN_HERE'" >> ~/.acme.sh/account.conf

If valid Cloudflare creds and dns_cf.sh are detected, DNS‑01 is preferred; otherwise it falls back to webroot. After issuance WNMP writes cert paths and reloads Nginx.

We recommend DNS‑01. With webroot, if a CDN is enabled, renewals may fail because the origin may not be reachable directly.

Can certificate applications be skipped in an internal network environment?

Yes. The script detects internal network environments and prompts whether to force certificate application. Selecting "No" skips certificate application, ideal for development environment installation and debugging. Selecting "Yes" enables certificate application similar to installing within a PVE NAT IPv4 virtual LAN. As long as the PVE host forwards ports 80 and 443 to the current internal KVM virtual machine, certificates can be applied normally.

Why WebDAV instead of FTP?

FTP is plaintext by default, making credentials easy to intercept. Even with TLS it’s cumbersome. Disable FTP server software entirely.

WebDAV rides on HTTPS (443) with SSL protection.

On Windows, use WinSCP (as with FTP) or RaiDrive (map as a local drive). On Linux, use Rclone to mount.

WebDAV supports multiple accounts per site. Run bash wnmp.sh webdav repeatedly for the same domain to add more accounts. Password files are stored under /home/passwd/.

WinSCP settings: Protocol: WebDAV; Host: [domain]/webdav; Encryption: TLS/SSL implicit; Port: 443.

Other clients: https://[domain]/webdav.

Replace [domain] with your real domain.

Can I use WNMP as a WebDAV‑only cloud drive?

Yes. When creating a site with bash wnmp.sh vhost or adding WebDAV via bash wnmp.sh webdav, choose “public directory: yes”. WNMP will disable all .php execution and serve any extension as a downloadable file.

If used purely as a drive, you can install Nginx only (skip PHP and MariaDB).

Why MariaDB instead of MySQL?

MariaDB is an open‑source fork by the original MySQL authors. It is highly compatible with MySQL syntax—migrate/import and it should just work.

Why only MariaDB 10.x, not 11.x?

To support low‑spec VPS (e.g., 1 GB RAM) and because the divergence between MariaDB and MySQL grows in newer releases (e.g., default collations/encodings differ).

WNMP ships MariaDB with Mroonga. The Mroonga project officially supports up to MariaDB 10.x.

Databases need not always be the newest. For compatibility and resource constraints, WNMP supports actively maintained MariaDB 10.x branches. If you need other versions, modify WNMP as needed.

What is the Mroonga search engine?

MariaDB includes an optional Mroonga engine in multiple versions, but those are often outdated. WNMP disables the built‑in variant and installs the latest Mroonga separately.

MariaDB’s Mroonga page: https://mariadb.com/docs/server/server-usage/storage-engines/mroonga/about-mroonga

Mroonga official site: https://mroonga.org/

For MySQL/MariaDB projects, performance bottlenecks often come from query speed. Avoid LIKE fuzzy search—it’s slow!

Switch your table engine to Mroonga and add full‑text indexes on varchar/text columns. Example:

SELECT name FROM users WHERE MATCH (name) AGAINST ('+Hello Word' IN BOOLEAN MODE); (Replace field/table names with your own.)

See the Mroonga site for more documentation. https://mroonga.org/

Why do I get 403 at http://[ip]/phpmyadmin?

Many Nginx installs don’t consider a default site certificate. If only port 80 is served, a request to https://[ip]/ may be routed to the first 443 vhost, risking MITM.

Therefore, the WNMP default site listens on both ports 80 and 443. To prevent database access via the incorrect methods http://[ip]/phpmyadmin or https://[ip]/phpmyadmin, which pose a man-in-the-middle attack risk, Accessing the default site requires executing `bash wnmp.sh default`. Only after configuring a subdomain for the default site and successfully obtaining a certificate can the database be accessed via `https://[domain]/phpmyadmin`.

How to manage MariaDB?

After running bash wnmp.sh default (bind a subdomain + certificate), visit https://[domain]/phpmyadmin. Nginx Basic Auth is enabled by default. Username: wnmp. Password: [needpasswd] or your MariaDB root password (depending on setup).

To change BasicAuth for the default site: htpasswd -bc /home/passwd/.default [user] [password]. (The default site supports a single account.)

Once BasicAuth succeeds, log in to phpMyAdmin as root with your MariaDB root password.

MariaDB listens on localhost (not 127.0.0.1); use localhost in your app configs.

Alternatively, manage via the shell by running mysql.

For Mroonga tables, do not import/export via phpMyAdmin (it does not consider Mroonga specifics).

Prefer mysqldump for import/export on the server:

All databases (with accounts/privileges/routines/events): mysqldump --all-databases --single-transaction --default-character-set=utf8mb4 --routines --events --flush-privileges | gzip > all_databases_backup.sql.gz

Single DB: mysqldump --single-transaction --default-character-set=utf8mb4 --databases test | gzip > test.sql.gz

Import: gunzip < all_databases_backup.sql.gz | mysql --default-character-set=utf8mb4

Import: gunzip < test.sql.gz | mysql --default-character-set=utf8mb4

Can I perform an overwriting installation? Is there a backup of the database data?

Yes. Version v1.05 now supports overwriting installations. Alternatively, run `bash wnmp.sh remariadb` to perform a full database backup to: /home/all_databases_backup_[time].sql.gz

Is it compatible with the in-memory architecture of Swoole and Workerman?

Yes. Version 1.02 has just added the --pcntl extension, making it compatible with Workerman.

Can I use only part of the stack?

Yes. Install or remove components individually, or run only the kernel/network tuning.

Does it support one-click generation of SSH login keys?

Yes. Run bash wnmp.sh sshkey

===

⚠️ Important reminder: Before confirming you have saved the private key to your own computer

⚠️ Do not disconnect the current SSH session, or you will be unable to log back into the server!

===

Save the private key to your local computer. You can then load the key in an SSH client for password-less login.

After configuring key-based login, the server will block all username/password logins.

How is WNMP different from other scripts? Why choose it?

WNMP auto‑tunes parameters based on your hardware and OS for strong production performance.

Benchmark with ab, wrk, etc.

On identical hardware, compare with other scripts. Results may vary and are for reference only.

Note: When testing concurrency, disable CDN caching, use HTTP, and run e.g. ab -n100000 -c1000 -k http://... — the -k flag (Keep‑Alive) better simulates real browsers and yields higher performance.

Will the wnmp.org domain ever be sold?

No. The author commits to open‑source principles; wnmp.org is the only official website.

How can I report bugs?

QQ Group: 1075305476

Telegram Group: https://t.me/wnmps

Github: https://github.com/lowphpcom/wnmp

The community source code is being built on LOWPHP — stay tuned!