Creating a node.js proxy using platform.sh
We've been using platform.sh for several years but never really used it for much more than the standard PHP container and associated services such as Redis and MariaDB.
Our client Decksaver needed to improve the search experience on their website, which had recently been developed and handed over from another agency. The search implementation gave slow and unpredictable responses to users.
The search had to provide the following functions.
- Type ahead functionality (Already implemented).
- Fuzzy search.
- Search a custom ACF field that contained the "Also fits data".
There are several ways to implement this in Wordpress.
- Pay a subscription to a a search company such Algolia
- Use an off the shelf or custom plugin of some variety that uses the standard database.
- Use an Elasticsearch plugin such as ElasticPress that leverages Elasticsearch.
We decided to go with the Elasticpress solution. This route enabled us to quickly get the product data into Elasticsearch and then just work out how to get the returned results served to the customer quickly.
The ElasticPress plugin comes with it's own implementation of an instant search but this is only supported on their paid for tier as ultimately they want you to sign up to this for a monthly fee. There a few blog posts about how to make this work with a standard Wordpress installation but these entailed creating an endpoint and using a Wordpress hook. However using a Wordpress hook would mean that every time the search is used, an FPM process is performed and the caching layer is bypassed. The website was already suffering from performance issues and moving the search was one step to solve part of the performance issues - so this approach wouldn't work.
We decided to use the same proxy technique, but instead of using Wordpress hooks, we used a platform.sh container running a node.js server that communicated directly with elasticsearch.
Platform allows you to create as many containers as your resource allocation allows, you just need to create a platform.app.yml file in a subdirectory of the repo to get a node server running.
The server can have the same relationships as the main PHP container and thus could communicate with Elasticsearch directly while not bootstrapping Wordpress or using an FPM process. Keeping the network request between the user and the search container means that full page caching is kept in tact and we don't need to run expensive SQL queries or initiate a PHP session.
The node container YAML file.
name: nodesearch
type: nodejs:14
relationships:
search: 'search:elasticsearch'
# The configuration of app when it is exposed to the web.
web:
commands:
start: "node index.js"
mounts:
'run':
source: local
source_path: run
disk: 128
size: S
This runs a single js file called index.js which we haven't included here. There are also some other configuration that is shared between both applications including the routes.yaml and services.yaml.
If you have any questions about setting up Elasticsearch, Wordpress and Platform.sh in this way get in touch.