Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monnoval/6894336484613b02fafc9c75bc18656b to your computer and use it in GitHub Desktop.
Save monnoval/6894336484613b02fafc9c75bc18656b to your computer and use it in GitHub Desktop.
Running OpenWrt + NGINX + PHP7 + SQLite + Wordpress in Raspberry Pi4

Run OpenWrt + Nginx + PHP7 + SQLite + Wordpress in Raspberry Pi4

* 13 May 2021
Broke my initial build due to a sys upgrade then re did all of below. Not sure what caused the problem. The main blockage I experienced is the expanding of the second partion, see here for the update.
* 18 April 2021
More or less complete by now, any updates or workarounds I will just keep on adding here
* 13-16 April 2021
Content for this post is still in progress as I'm compiling all the workarounds, fixes and commands for all this to work



1. Introduction

OpenWrt is meant as an "embedded operating systems based on Linux" and using it for the goals I highlighted below is not as simple as using Ubuntu or CentOS. And still, OpenWrt is quite amazing at what it does.

1.1 Goals

  • To have a router + ads blocker (similar to pi-hole)
  • To be able to connect via wifi, use my mobile phone with ads block by default
  • To have a wordpress multisite environment
    • Having this as an external server is better so that it would not eat my local resources. I was using devilbox and it takes 4GB++ of ram.
  • Portable, of course, with the Pi I should be able to move from office and home

1.2 Before anything else

I almost read every information related to the tools listed and until now I'm still encountering weird things along the way. As problems arise I just put my mindset to be more patient. This page said "From now on, you're on your own..." which did stick in my mind in the days grinding for solutions per problem.

So keep in mind, OpenWrt is not as easy to work with compared to Ubuntu or CentOS. With that in mind
I still hope this page would help you on your adventure.

Do multiple tests

Every update you do, please do test by doing a servive {ur-service} reload and a full reboot. From there you would know if the updated settings in either luci or SSH does work.

Always check if the service is running, if not then read the errors. You need to do lots of trial-and-error plus deep reading on how a certian package work (can check the package readme or package repo), maybe a package has dependency or maybe the package is not compiled for arm cpu (which raspberry pi does use). Lots of things to check which would test your patience.

2. Prep

2.1 Hardware

Below are the hardware I do have

  • Raspberry Pi 4 Model B 8GB BCM2711 Quad core Cortex-A72
  • USB3 Ethernet Adapter (Vention brand, i think any brand would do)
  • SanDisk Extreme 64GB
  • 2x Ethernet cable (1 for lan, 1 for wan)
  • microSD card reader (used to flash/install OpenWrt)

2.2 Setup

  1. I use Raspberry Pi Imager from raspberrypi.org here to flash the SD Card
  2. The OpenWrt build I used is from here https://github.com/wulfy23/rpi4/tree/master/builds/

I would not go into step by step on how to flash OpenWrt into the microSD since there are lots of tutorials for that.

3. OpenWrt

Default lan IP Address for luci is 192.168.1.1
I did change the default to 192.168.7.1 (can be anything) to avoid conflict with the main router

  • Edit /etc/config/network change from 192.168.1.1 to 192.168.7.1
  • Run /etc/init.d/network restart

3.1 Internet

I needed to have internet via wan which would use the USB3 Ethernet Adapter. In Luci > Interfaces,

  • I did not touch the default LAN interface
  • I added a new "WAN" interface with
    • Name: WAN
    • Protocol: DHCP client
    • Interface: eth1
    • Firewall Settings > Create / Assign firewall-zone: wan

Wireless

For wireless to work I need to follow the comment in this page

wulfy23
This is the main glaringly obvious wifi alteration... so you could try remove wpad-openssl and put back plain wpad

Do a reboot and check if Wireless page in luci does show the wifi is enabled or you can enable it there.

3.2 Block ads using adblock

OpenWrt adblock readme

Initially adblock package was working without any setup. I just enabled it via luci. After more than two days I noticed that it is not working and I did the following

opkg update
opkg remove libustream-openssl20201210
opkg install libustream-mbedtls20201210
service adblock enable
service adblock start
/etc/init.d/adblock status

I'm still not sure why adblock does not start in my initial test after removing/installing libustream, i needed to do this three times before it did work. I did a couple of reboots to make sure that my setup for adblock works fully.

Currently I have the following in luci

  • Blocked Domains: 500K+
  • Startup Trigger Interface: wan

3.3 Block ads using simple-adblock

OpenWrt simple-adblock readme

I did try to use simple-adblock after having issues with adblock. It is installed by default and the only command I did run is

opkg update
opkg --force-overwrite install gawk grep sed coreutils-sort

Then I enables and started the service via luci here http://{ur.openwrt.ip.addr}/cgi-bin/luci/admin/services/simple-adblock

Do take note that when you reboot there is a delay of 120 seconds (default) before simple-adblock would start. This is the only drawback I noticed with simple-adblock other than this it is preferably simple than adblock.

3.4 Expand second partition

One of the hardest thing for me to accomplish is expanding the OpenWrt's second partition (ext4) to use the full 64GB of my microSD card.
I'm using macos and I did try using VirtualBox to detect the microSD and failed. When I tried to use Parallels (trial version) then booted GParted it was able to detect and expand the second partition of the microSD card.

Mainly, GParted is heaven sent but you need to find a way to boot it then detect the microSD card (with OpenWrt installed already), with this you should be able to expand the second partition.

Update, 13 May 2021

Expanding the second partion (ext4) does breaks the OpenWrt installed in the SD Card, tested this more than 5 times with lots of scenarios with the hope to find the problem.
The only solution I did do is to use an external thumb drive to be able to have more space.

4. Web development environment

This development environment is mainly focused on getting Wordpress to work well.

Initially I was focused on apache2+php7 but after I read this post and found that libphp7.so did not have an OpenWrt or an Arm Cortext 72 build while nginx is completely supported, I quickly tried to work with Nginx regardless of me not having any experience using it.

4.1 Nginx

Before installing Nginx, I updated the Luci to not use the default port 80. To do this just edit /etc/config/uhttpd then update the port like below

config uhttpd 'main'
	list listen_http '0.0.0.0:801'
	list listen_http '[::]:801'
	list listen_https '0.0.0.0:4431'
	list listen_https '[::]:4431'

Now I could have Nginx take the default port 80.

$ opkg update
$ opkg install nginx
$ nginx -v
nginx version: nginx/1.19.6 (x86_64-pc-linux-gnu)
$ service nginx start # /etc/init.d/nginx start #can be used also

Make sure to use /etc/nginx/nginx.conf

uci set nginx.global.uci_enable=false
uci commit
service nginx reload

Let's double check /etc/config/nginx by running cat /etc/config/nginx

# /etc/config/nginx
config main 'global'
	option uci_enable 'false'

Here is a sample of my /etc/nginx/nginx.conf
Do take note that I do not use httpS on this development environment.

I also learned a lot from the Nginx webserver guide. It is worth knowing how Nginx works in OpenWrt, mix that with non-OpenWrt Nginx tutorials and you should be able to configure it the way you needed.

4.2 PHP7

$ opkg update
$ opkg install php7 php7-cgi php7-cli php7-fastcgi php7-fpm php7-mod-mysqli php7-mod-pdo php7-mod-pdo-mysql
$ php-cli --version
PHP 7.4.16 (cli) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies

Here are the PHP modules that was required for some of the wordpress plugins I used

php7-mod-filter
php7-mod-ctype
php7-mod-pdo
php7-mod-pdo-mysql
php7-mod-pdo-sqlite
php7-mod-gd
php7-mod-mbstring
php7-mod-gettext
php7-mod-dom
php7-mod-simplexml
# just install any module depending on your needs

Here is my /etc/php.ini

4.3 SQLite

I failed to run mariadb inside OpenWrt which I looked for alternative which is SQLite. The good thing about SQLite is that it has no heavy dependency with other libraries plus it is super light.

$ opkg update
$ opkg install sqlite3-cli
$ sqlite3 --version
3.33.0 ...

Import mysql database to SQLite

Since I already have a wordpress multisite installed in my localhost now I needed to export then import the database inside SQLite.

  1. Do backup your all your localhost databases
  2. Use Search Replace DB to search/replace all ".localhost" to ".lan" (I do this inside my mac since Search-Replace-DB did not work inside OpenWrt)
  3. Dump the "ready for .lan" localhost database then copy to OpenWrt's /webdev/wpms/wp-content/database (I did this with nfsd)
  4. To import to SQLite I needed to use mysql2sqlite
  5. Below is to make mysql2sqlite executable, read the sql files, lastly let sqlite3 create a new database
chmod +x mysql2sqlite
./mysql2sqlite wordpress_localhost_mysqldump.sql | sqlite3 sample.db
mv sample.db .ht.sqlite

There are lots of weird problems when the sqlite database does not have the right permission.
Update all permissions using chmod -R 777 /webdev

Manual search and replace in SQLite database

If you just need to do a manual search and replace in the database. I use adminer

UPDATE wp_options  SET option_value = replace(option_value, 'yoursitename.localhost', 'yoursitename.lan') WHERE option_name = 'home' OR option_name = 'siteurl';
UPDATE wp_posts    SET post_content = replace(post_content, 'yoursitename.localhost', 'yoursitename.lan');
UPDATE wp_postmeta SET meta_value   = replace(meta_value,   'yoursitename.localhost', 'yoursitename.lan');

4.4 Wordpress

Wordpress does not support SQLite natively and we need to use wp-sqlite-db

  1. Download db.php
  2. Move db.php to /webdev/wpms/wp-content/db.php

Just a reference, here is my wp-config.php

// Since we are using sqlite, no need for database permission
define( 'DB_NAME', '' );
define( 'DB_USER', '' );
define( 'DB_PASSWORD', '' );
define( 'DB_HOST', '127.0.0.1' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );

/* That's all, stop editing! Happy publishing. */
define('DOMAIN_CURRENT_SITE', 'wpms.lan');

Wordpress Multisite subfolders

This took me a day to figure out since I do lack experience in Nginx. If you can make my nginx.conf better in the comments, I would really appreciate that.

The following code blocks are the most important sections in my nginx.conf

  1. map_hash_* and map $http_host $blogid
    • This requires Nginx Helper wordpress plugin to be installed
    • In the plugin, you need to Network Activate then in /wp-admin/network/settings.php?page=nginx check Enable Nginx Map.
  2. server locations

MacOS zip to OpenWrt

Whenever I copy a zip file then extract it inside OpenWrt there would be "._" files. These files may cause problem with either PHP or Wordpress. So to delete them I would run

cd /webdev
find . -name "._*" -exec rm '{}' \; -print

5. Workflow

5.1 MacOSX /etc/hosts

In my computer I just need to make sure that wpms.lan is mapped to OpenWrt's IP Address

{ur.openwrt.ip.addr}  wpms.lan

5.2 Share files with NFS

We need access to /webdev for us to read/write to files.
Inside OpenWrt's /etc/exports add the ip address of your computer.

/mnt  *(ro,all_squash,insecure,sync)
/webdev  ur.computer.ip.addr(rw,sync)
/webdev  another.computer.ip.addr(rw,sync)

You can make ip address static via luci so that it would not change just in case.

Enable and start nfsd

$ service nfsd enable && service nfsd start

In my case since I use mac, I mount nfs by running

# mount OpenWrt's /webdev in mac
sudo mount -t nfs -o resvport {ur.openwrt.ip.addr}:/webdev /private/nfs

References

Thanks to the people who contributed to each content below. They did ease the problems and solutions along the way

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment