Dockerizing a Liferay Bundle, Part 1

A Brief Overview of the official Liferay Docker images

Jonas Choi
Jonas Choi
2 Minute Read

While the official Liferay Docker images have been out and available for many years now, and I'm sure many people are making use of them, I haven't been able to find documentation or a guide that talks about using them, so I wrote this. This is the result of my own experimentation and usage of said images.

In this part, we will cover what the Liferay Docker image offers and the features/functions that are unique to the official Docker images. The official Docker images can be found here: https://hub.docker.com/r/liferay/dxp and the Overview tab provides all the information here. I am using the DXP version, but the equivalent Portal CE version will be the same. Of course, people are free to make their own Docker images to suit their needs, but this puts the burden of maintenance of said bundle on them, not on Liferay. I have also rolled my own Docker image of Liferay, and maintenance was not easy, especially when considering repeatability and distributing copies to others.

import {graphql} from "gatsby"; import React from "react"; import Layout from "../components/layout" export default class News extends React.Component{ render() { const { data } = this.props; const { liferayStructuredContent: { contentFields, dateModified, creator: { name }, title, description } } = data; function createMarkup(html) { // console.log("createMarkup-->" + html); return {__html: html}; } return( <Layout> <div className="news"> <div className="container-fluid"> <div className="row"> <div className="intro blog-intro text-center col"> <div className="container-fluid container-fluid-max-lg"> <h1 className="h1">News</h1> <h2 className="h3">Latest updates from an external Liferay</h2> </div> </div> </div> </div> <div className="container"> <div className="row"> <div className="col-md-12"> <article> <small> {dateModified} {name} </small> <div dangerouslySetInnerHTML={createMarkup(description) } /> <h1>{title}</h1> <div dangerouslySetInnerHTML={createMarkup(contentFields[0].value.data) } /> </article> </div> </div> </div> </div> </Layout> ) } } export const pageQuery

Assumptions= graphql` query($slug: String!){ liferayStructuredContent(slug:{eq: $slug }) { key dateModified(formatString: "MMMM DD, YYYY") title description slug creator { name familyName givenName } contentFields{ value{ data } } } } `;

 

Great, now we have our template. It is time to test everything.

We can get a listing of our pages by triggering a 404. Go ahead and enter a bogus URL for your Gatsby site. You should see something like the following.

 

All our web content articles are listed now as site pages, very cool!

Click on one of them and you will see the contents just as if it originated from the site.

 

Click back and try another. You will notice all the html styling (h1, h2, ul, etc..) created in Liferay is present. You can even use CSS class names when authoring the content in Liferay. You would just have to include the styling definitions in your Gatsby site.

Environment VariablesLastly, remember we tagged our web content articles as “news”. If you look back at part 1, the curl output shows tags listed as an array in the keywords field. We could add a filter to the web service to only pull articles with our tag.

For example)

curl "http://localhost:8080/o/headless-delivery/v1.0/sites/20123/structured-contents/?fields=title,keywords&filter=keywords/any(k:contains(k,'news'))" -u 'test@liferay.com:test'

 

Conclusion

What I really liked was how easy I could use Liferay to author content and use the Headless API to easily have it rendered elsewhere. This was a vastly different experience than if I had attempted to use the traditional JSON webservice to accomplish this solution. 

Great job Liferay!

I hope this is example is useful.

https://github.com/mountc/gatsby-liferay-site

The exact entries can be found in the Liferay portal.properties file with the key is ALL_CAPS_WITH_UNDERSCORES. Not all portal.properties values will have equivalent Docker environment settings, but some will be useful when setting up things like JVM options or database connections.

My personal preference is to keep the environment settings to a minimum and do the rest in portal-ext.properties.

Environment Variable Example:
For example, if you want to provide only English and Portuguese, you could create a portal-ext.properties with the entry:
locales.enabled=en_US,pt_BR
Or, you could set the environment variable:
LIFERAY_LOCALES_PERIOD_ENABLED=en_US,pt_BR

These environment variables go into the docker-compose.yml file of the Docker images. Underneath the section for the Liferay image, there will be a portion of environment variables. This will become clearer when we look at the docker-compose.yml file in Part 2

File System

This caused the most confusion for me and took some experimentation to figure out. The Docker Hub documentation lists 4 directories that can be mapped and used. All of these directories will be copied into the Docker image and will some way interact with the image itself.

   - mount (head directory)
        - deploy
        - files
        - patching
        - scripts

If we understand how these directories work in relation to the Docker container, we can use it to patch or even “Dockerize” a bundle.

Deploy

Hot deploy directory for the image. Place files here and they will be deployed into the image. This is good for testing things out on a running image. If you deploy something here, it will not persist if the image volumes are cleared.

Files

Internal file mapping for the bundle. This is where you interact with the file system of the application server (Tomcat). Inside here is where the portal-ext.properties file goes, and anything you want to add to the app server deployment, such as JDBC drivers and custom plugins that you want to persist. In Part 2, the bulk of the work to convert a bundle to Docker will be here.

Patching

This is where you need to deploy any hotfixes that Support will hand out. You COULD deploy fixpacks here, but you'll need the Patching Files for the baseline bundle that you are using. Patching Files is 1 GB itself, and adding in 600 MB for the fixpack, you're adding 1.6 GB to the bundle that you can save by specifying the fixpack version as your baseline image.

Scripts

Executable scripts can be deployed here. They are run alphabetically. These scripts are run after all the files in the other directories are processed. I have yet to execute a script.

In Part 2, I will show the process I went through to convert one of the demo bundles that was created into a Docker setup. I used this Docker setup along with GitHub to distribute the demo to other Liferay Sales Engineers and affiliated parties.

 

Page Comments

The Technicalities of Static Sites

David Oliveira Montenegro
View Blog >

Customization is Dead! Long Live Customization!

David H Nebinger
View Blog >
customization banner image.png

Public Bug Bounty Program

David H Nebinger
View Blog >
bugbounty.png
Showing 1 to 3 of 3 entries.