This repository has been archived on 2024-09-12. You can view files and clone it, but cannot push or open issues or pull requests.
svrjs-blog/source/_posts/SVR-JS-can-now-run-PHP-and-also-WordPress.md

171 lines
8.5 KiB
Markdown
Raw Normal View History

2024-03-15 23:24:27 +01:00
---
title: SVR.JS can now run PHP (and also WordPress!)
date: 2023-08-02 15:53:31
tags:
- php
- wordpress
categories:
- [News]
- [Tips]
---
**SVR.JS - a web server software running on Node.JS can now run PHP through PHP-CGI and RedBrick mod.**
Because SVR.JS can run PHP, SVR.JS can also run WordPress. Keep in mind, that it comes with CGI overhead. This post will instruct you, how to set up PHP and WordPress on SVR.JS.
## Installing PHP
First, [download](https://svrjs.org) and install SVR.JS per [documentation](https://svrjs.org/docs). You can also use `create-svrjs-server` tool to do that.
Since neither SVR.JS nor Node.JS has native PHP library, we're using and installing PHP-CGI. To do this, first download and install [RedBrick](https://svrjs.org/dl/mods) (2.3.2 or newer) into *mods* directory. RedBrick is a CGI runtime written in JavaScript running on SVR.JS.
After we have installed CGI runtime, we're installing PHP-CGI. You can [download PHP manually](https://www.php.net/downloads.php), however in many GNU/Linux distributions it is available in package manager. For Debian/Ubuntu you can run `sudo apt install php-cgi`. For Red Hat/CentOS/Fedora you can run `sudo yum install php-cgi` or `sudo dnf install php-cgi`. For Arch/Manjaro you can run `sudo pacman -S php-cgi`.
Once you have installed PHP-CGI, you can create *cgi-bin* directory inside the web root and create *test.php* file with those contents:
```php
<?php phpinfo(); ?>
```
Run SVR.JS using `node svr.js ` or `bun run svr.js` and visit test page, most probably *http://localhost/cgi-bin/test.php*. You will then see this page:
![PHP CGI warning](/images/php-cgi-warning.png)
To enable PHP-CGI, locate PHP-CGI configuration file (in GNU/Linux is usually */etc/php/&lt;php version&gt;/cgi/php.ini*) and set `cgi.force_redirect` property to `0`.
After configuration, visit test page again, and you will see this:
![PHP information page](/images/php-cgi-info.png)
**We have installed PHP!**
## Installing WordPress
Now we have installed PHP, so let's move on to WordPress installation.
First, delete *test.php* file that you created earlier. Then [download WordPress .zip file](https://wordpress.org/download/) and extract all of it's contents to *cgi-bin* directory.
You need to also install MySQL/[MariaDB](https://mariadb.org/download/) relational database server and *mysqli* PHP library. These packages are also available in package manager. For Debian/Ubuntu you can run `sudo apt install php-mysql mariadb-server`. For Red Hat/CentOS/Fedora you can run `sudo yum install php-mysql mysql mysql-server` or `sudo yum install php-mysql mysql mysql-server`. For Arch/Manjaro you can run `sudo pacman -S mysql`.
Then configure MySQL/MariaDB to listen to port 3306. Add this to configuration file:
```
port = 3306
```
And restart MySQL/MariaDB using `sudo systemctl restart mysql` or using `/etc/init.d/mysql restart`.
Then you can run sequence of SQL commands to create database and user using MySQL/MariaDB console (invoked by `sudo mysql`):
```sql
CREATE DATABASE your_database_name;
CREATE USER 'your_username'@'localhost' IDENTIFIED BY 'your_password';
CREATE USER 'your_username'@'%' IDENTIFIED BY 'your_password';
GRANT ALL ON your_database_name.* TO 'your_username'@'localhost';
GRANT ALL ON your_database_name.* TO 'your_username'@'%';
```
After running this sequence, visit WordPress page (in this example *http://localhost/cgi-bin/wordpress/*). You'll see this:
![WordPress setup screen](/images/wordpress-setup.png)
First, click "Let's go!" button. Then put in database data (that points to your database you just created).
Example data:
- **Database Name** - *your_database_name*
- **Username** - *your_username*
- **Password** - *your_password*
- **Database Host** - *localhost*
- **Table Prefix** - *wp_*
Click "Submit" and then click "Run the installation". In this screen, you will need to input data about your WordPress website.
Example data:
- **Site Title** - *WordPress blog on SVR.JS*
- **Username** - *svrjs-wp*
- **Password** - Your chosen password
- **Your Email** - Your e-mail address
- **Search engine visibility** - Don't discourage search engines from indexing this site
After inputting the data, click "Install WordPress". **WordPress is now installed!**
After installation, click "Log in" and type in your chosen username and password.
After logging in, you'll see WordPress administration panel:
![WordPress administration panel](/images/wordpress-admin.png)
**You can now create posts, manage comments and install WordPress plugins!**
To visit your WordPress site, navigate yourself into WordPress index page (for example *http://localhost/cgi-bin/wordpress*). You'll see this:
![WordPress website home page](/images/wordpress-homepage.png)
**It's important to kill CGI code execution (except PHP) inside WordPress installation folder. It's also recommended to kill PHP code execution inside wp-content directory.** You can do this using non-standard status code functionality of SVR.JS, or by modifying *redbrick-interpreters.json* configuration file inside SVR.JS installation folder.
If you want to edit RedBrick configuration file, you can change interpreters to "UNKNOWN_COMMAND", for example:
```json
{
".pl": ["UNKNOWN_COMMAND"],
".py": ["UNKNOWN_COMMAND"],
".sh": ["UNKNOWN_COMMAND"],
".pyw": ["UNKNOWN_COMMAND"],
".rb": ["UNKNOWN_COMMAND"]
}
```
Restart SVR.JS server. After those changes, attempts to execute those files will result in 500 Internal Server Error code. Keep in mind, that it will break CGI scripts outside WordPress installation directory. You can also point those to custom CGI script serving static files instead of "UNKNOWN_COMMAND", for example:
```bash
#!/bin/bash
if [ -f "$SCRIPT_FILENAME"]; then
echo "Status: 200 OK"
echo
cat "$SCRIPT_FILENAME"
else
echo "Status: 404 Not Found"
echo "Content-Type: text/plain"
echo
echo "404 Not Found"
fi
```
If you want to modify SVR.JS configuration file though, you can add two non-standard code properties (to *nonStandardCodes* property in *config.json* inside SVR.JS installation directory), for example:
```json
{
regex: "/^\\/cgi-bin\\/wordpress\\/(?:(?!\\.(?:pl|pyw?|sh|rb)($|[?#]))[^?#])*\\.(?:pl|pyw?|sh|rb)($|[?#])/",
scode: 403
},
{
regex: "/^\\/cgi-bin\\/wordpress\\/wp-content\\/(?:(?!\\.(?:pl|pyw?|sh|rb|php[345]?)($|[?#]))[^?#])*\\.(?:pl|pyw?|sh|rb|php[345])($|[?#])/",
scode: 403
}
```
Restart SVR.JS server. After those changes, attempts to execute those files will result in 403 Forbidden code.
For even more security, you can disable directory listings by setting *enableDirectoryListing* property in *config.json* inside SVR.JS installation directory to `false`.
You can also make WordPress website home page into for example *http://localhost*, by using URL rewriting feature of SVR.JS and by modifing WordPress settings to point to new URL.
To do this, first navigate to WordPress administration panel, then go into Settings -> Permalinks. Then change Permalink structure to Custom Structure, and remove "/index.php" from custom structure field. After applying those settings, go into Settings -> General menu. Then change WordPress address and site address into for example *http://localhost/*. After submitting those settings, you'll see 404 Not Found page. This is because we didn't set up URL rewrites yet. To fix that, add URL rewrite rules to URL rewrite map (*rewriteMap* property in *config.json*), for example:
```json
{
"definingRegex": "/^\\/(?!favicon\\.ico(?:$|[?#]))/",
"replacements": [
{
"regex": "/^\\/(?!$|[?#]|wp-[a-z]+)(.*)/",
"replacement": "/cgi-bin/wordpress/index.php/$1"
},
{
"regex": "/^\\/($|[?#].*|wp-[a-z]+.*)/",
"replacement": "/cgi-bin/wordpress/$1"
}
]
}
```
Restart SVR.JS server. Afterwards, you will get a clean URL for your WordPress website.
**UPDATE**: In order for *wp-content* to be more secure (prevent execution of ELF executables and scripts with shebang), you can move *wp-content* outside of *cgi-bin* directory and create symlink to moved *wp-content* like this:
```bash
ubuntu@ubuntu:~/svrjs/cgi-bin/wordpress$ mv wp-content ../../
ubuntu@ubuntu:~/svrjs/cgi-bin/wordpress$ ln -s ../../wp-content wp-content
```
For moved *wp-content* you can use URL rewite rules for SVR.JS like this:
```json
{
"definingRegex": "/^\\/(?!favicon\\.ico(?:$|[?#])|wp-content(?:$|[?#\\/]))/",
"replacements": [
{
"regex": "/^\\/(?!$|[?#]|wp-[a-z]+)(.*)/",
"replacement": "/cgi-bin/wordpress/index.php/$1"
},
{
"regex": "/^\\/($|[?#].*|wp-[a-z]+.*)/",
"replacement": "/cgi-bin/wordpress/$1"
}
]
}
```