Running a Node.js Application on eZ Platform Cloud

eZ Platform Cloud is Ibexa's integrated hosting solution for our Digital Experience Platform. It makes it easy to deploy an eZ Platform instance without having to worry about infrastructure maintenance. But it is not limited to this, and can host other apps and services as well.

In recent years, the availability of open APIs have become a requirement in software. Digital Experience Platforms and Content Management Systems are no exception. A contemporary platform must be able to deliver data through an API for consumption by mobile apps or other tools.

One trend is the emergence of headless implementations where the data management is separated from the presentation layer. In this setting, client applications merge data from one or more remote APIs. This can be done on server side or even within the client with something known as the Jamstack approach, putting the browser in the role of an integration platform.

While the browser capabilities and available APIs are make the front end very capable of acting as a melting pot to integrate data sources, a server component is still often useful. For example, for integrations and wrangling data from one format to another. This helps keep the client apps as simple as possible if you have multiple targets such mobile devices and the web.

This server component needs to be hosted, maintained and managed by someone. Whether you choose to run a server yourself, or rely on technologies like serverless functions it will add some complexity to your architecture and add to the bill that you pay for running your services.

Running multiple apps on eZ Platform Cloud

For clients running eZ Platform DXP on eZ Platform Cloud, a good option might be to run this server component in the same environment. eZ Platform Cloud offers the possibility for a single project to run multiple applications. Each application shares the same plan and resources. You can scale your multi-app installation just as you could if you were only running eZ Platform.

Each application you run on eZ Platform Cloud is sandboxed by default and is not aware of other apps running within the same project. However, you can define relationships that the different components have access to a shared database if needed. As each application is separate and has dedicated infrastructure, you're not tied to the Symfony/PHP stack eZ Platform is built on.

At the time of writing, eZ Platform Cloud supports running C#/.NET Core, Elixir, Go, Java, Lisp, Node.js, PHP, Python and Ruby apps. So you're free to run a Node.js data pump app written in asynchronous JavaScript to handle data conversions next to your eZ Platform instance under a single project. For the server software all the security patches, etc. are managed automatically.

All of the above is defined by configuration files stored in your project's version control system. The application and desired services are scaffolded during deployment based on the definition. This is not unique to multi-app projects as it is how eZ Platform Cloud always works. For multi-app projects, you will simply have a set of configurations for each discrete component.

Installing Next.js on eZ Platform Cloud

So, how does this all work in practice? Let's find out by installing eZ Platform and a Node.js application on the same eZ Platform Cloud project. We'll install Next.js, a popular JavaScript framework that uses React as its view library. Next can work without a dynamic server with static HTML, but we'll run the dynamic component in our example.

To save time we'll use two projects that come with eZ Platform Cloud compatible configuration out-of-the-box: eZ Platform and the Next.js demo app

Start with a clean project download the repository using the Platform.sh CLI app:

$ platform get not4u2know
Directory (default: jt-next-js-install): 
Creating project directory: jt-next-js-install
  Initialized empty Git repository in /Users/janit/Sites/jt-next-js-install/.git/

Your project has been initialized and connected to Platform.sh!

Commit and push to the master branch of the platform Git remote, and Platform.sh will build your project automatically.

Next enter the project directory and clone the eZ Platform and Next.js repositories there:

$ cd jt-next-js-install
$ git clone git@github.com:ezsystems/ezplatform.git
$ git clone https://github.com/platformsh-templates/nextjs.git

Checkout the version of eZ Platform you want to install and delete .git from both directories:

$ cd ezplatform
$ git checkout v3.1.2
$ cd ..
$ rm -rf ezplatform/.git
$ rm -rf nextjs/.git

Now we've got two projects with configurations in place. Both are called "app" by default, so we'll need to rename one to be something else. The Next.js application has no dependencies to other services, so it has a much simpler configuration. It is easier to rename it. Change the word "app" to "nextjs" in the main config file (nextjs/.platform.app.js):

# The name of this application, which must be unique within a project.
name: nextjs

The services needed by eZ Platform are defined in a configuration file in the project directory (.platform/services.yaml). To make them available in a multi-app project, we'll need to define them in at the root level. Move all contents from the ezplatform configuration to the root:

$ mv ezplatform/.platform/* .platform

Next open and view the routes configuration you just added:

"https://{default}/":
    type: upstream
    upstream: "varnish:http"
    cache:
        # As this does not support Vary, and purging, we can't use this as Sf Proxy drop in.
        # However it is possible to enable this for anonymous traffic when backend sends expiry headers.
        enabled: false

"https://www.{default}/":
    type: redirect
    to: "https://{default}/"

This defines the routing configuration, directing all requests to the eZ Platform app through varnish. In addition there's a redirect from www-prefixed domain to the non-www one.

If we were to continue with this, our Next.js app would initialize and run but there would be no way of accessing it through the external network. We'll want to make eZ Platform available in an admin-prefixed domain and expose the Next.js app on the top domain.

Merge and edit the root-level routes configuration with nextjs/.platform/routes.yaml to create the following routing definition:

"https://www.{default}/":
    type: upstream
    upstream: "nextjs:http"

"https://{default}/":
    type: redirect
    to: "https://www.{default}/"

"https://admin.{default}/":
    type: upstream
    upstream: "varnish:http"
    cache:
        # As this does not support Vary, and purging, we can't use this as Sf Proxy drop in.
        # However it is possible to enable this for anonymous traffic when backend sends expiry headers.
        enabled: false

"https://www.admin.{default}/":
    type: redirect
    to: "https://admin.{default}/"

Add the files, commit and push the changes to the remote repository to deploy your project:

$ git add *
$ git add .platform
$ git push --set-upstream platform master

The project will take some time to deploy as it is installing eZ Platform and Next.js. At the end of a successful deployment you can see a listing of deployed services and their URLs:

Environment routes
  http://admin.master.../ redirects to https://admin.master.../
  http://master.../ redirects to https://master.../
  http://www.admin.master.../ redirects to https://www.admin.master.../
  http://www.master.../ redirects to https://www.master.../
  https://admin.master.../ is served by application `varnish`
  https://master.../ redirects to https://www.master.../
  https://www.admin.master.../ redirects to https://admin.master.../
  https://www.master.../ is served by application `nextjs`

The admin prefix URL hosts eZ Platform and the others the Next.js demo app.

Conclusion

eZ Platform Cloud is a reliable and feature rich environment for hosting eZ Platform, but in addition it is versatile as it can host other applications as well. This allows running closely related services in a single environment, simplifying management and keeping costs under control.

With the technology agnostic approach you can employ the most suitable tools for individual tasks. Different teams can work on their perspective components using a shared toolkit, with the deployment pipeline being handled by shared infrastructure. Backups are also provided by a single provider, simplifying recovery from potential issues in a micro-services environment.

Learn out about all the capabilities of eZ Platform Cloud from the product page and developer documentation. If you're interested in learning more about what Next.js can do, we'll pick up from where we left in a future article where we integrate Next.js with eZ Platform using GraphQL.

Insights and News