About Liferay CE
Liferay CE 7.4 is the last release of the Community Edition. Liferay has since shifted to a commercial-only model with Liferay DXP. CE 7.4 remains freely available and functional, but it no longer receives new features or updates. If you need long-term support and continued updates, consider Liferay DXP.Elasticsearch Enterprise required
Liferay requireselasticsearch-enterprise, not elasticsearch or opensearch.
Liferay’s bundled Elasticsearch client expects validation fields that are only present in the Enterprise edition.
Using the standard elasticsearch type or opensearch will cause search indexing failures.See the Elasticsearch documentation for more details on available types.Guaranteed resources recommended
Liferay is a resource-intensive application. It performs poorly with a single shared CPU. For production workloads, use guaranteed resources to ensure consistent performance.What you’re building
The deployment consists of three containers:- Liferay CE 7.4 running on Java 17 with Tomcat 9
- PostgreSQL 16 as the primary database
- Elasticsearch Enterprise 8.19 for full-text search with multilingual analysis plugins
Project setup
Create a new directory for your project and initialize a Git repository:Terminal
Project structure
Your project will contain five files:Upsun configuration
Create the.upsun/config.yaml file with the following content:
.upsun/config.yaml
Key configuration details
Container profile:HIGH_MEMORY allocates more memory relative to CPU, which suits Liferay’s runtime needs.
Mounts: The configuration separates persistent storage (storage) from ephemeral storage (instance):
dataanddeployusestorage— they survive redeployments and instance reprovisioning.- Logs, caches, and working directories use
instance— they persist across deploys but are cleared on reprovisioning, which is fine since they can be rebuilt.
pre_startgenerates configuration files from environment variables.startlaunches Tomcat.post_startpolls Liferay’s health endpoint. Upsun only routes traffic after this command returns, preventing requests to a still-booting instance.
Build process
Note on dependency management
This tutorial downloads the Liferay bundle and JDBC driver directly viacurl for simplicity.
In a production project, consider using a Liferay Workspace with Gradle to manage dependencies and build the bundle.build.sh file. This script runs during the build phase and prepares the Liferay bundle:
build.sh
- Downloads and caches the Liferay bundle (~1 GB). It uses
PLATFORM_CACHE_DIRso subsequent builds skip the download. - Installs the PostgreSQL JDBC driver, which isn’t included in the Community Edition bundle.
- Normalizes the Tomcat directory from
tomcat-9.0.xtotomcatso mount paths remain stable across versions. - Patches Tomcat’s port from hardcoded
8080to a${port.http}placeholder resolved at runtime via-Dport.http=$PORT. - Removes the bundled
setenv.shwhich hardcodes memory flags that conflict with container-aware values. - Installs a custom Log4j configuration for abbreviated stack traces in console output.
Runtime configuration
Create theconfigure-liferay.py file. This script runs as pre_start before Tomcat boots. It reads Upsun environment variables and generates the configuration files Liferay needs:
configure-liferay.py
- Generates
portal-ext.propertieswith PostgreSQL connection details, virtual host mappings, and HTTPS reverse-proxy settings. This file is written to thedatamount and loaded via-Dexternal-propertiesat runtime. - Creates an Elasticsearch OSGi configuration that points Liferay’s search connector to the remote Elasticsearch service.
- Updates the virtual host in the database so asset URLs use the real domain instead of
localhost. This runs silently on first boot when the database tables don’t exist yet.
Environment variables
Create the.environment file to configure Tomcat paths and JVM options:
.environment
- Memory: The maximum heap size (
-Xmx) is set to 80% of the container’s memory limit, read dynamically from/run/config.json. This ensures the JVM scales with the container size. --add-opensflags: Required for Java 17 compatibility. Liferay uses deep reflection that needs explicit module access.CATALINA_OUT=/dev/stderr: Sends Tomcat output to the container’s stderr stream, which Upsun captures in logs.-Dport.http=${PORT}: Resolves the${port.http}placeholder inserver.xmlto the dynamic port assigned by Upsun.
Log4j configuration
Create theportal-log4j-ext.xml file for cleaner console log output with abbreviated stack traces:
portal-log4j-ext.xml
%ex{short} pattern abbreviates exception stack traces, keeping logs readable without losing diagnostic value.
Create your Upsun project
Create a new project on Upsun and connect it to the repository:Terminal
Deploy
Commit and push to deploy:Terminal
After deployment
Once the deployment completes, open your site:Terminal
setup.wizard.enabled=false in the generated portal-ext.properties).
The default admin credentials are:
- Email:
test@liferay.com - Password:
test
Hot-deploying plugins
Thedeploy mount is a persistent directory where you can drop WAR/JAR files for hot deployment.
Use SSH to upload plugins:
Terminal