Liferay PaaS Experience

Liferay PaaS Experience: Builds and Deployment

In Liferay PaaS Experience, customizations are delivered as overlays rather than as custom Liferay container images. An overlay is a set of artifacts applied to the Liferay runtime filesystem at pod startup, and it can include OSGi modules, client extensions, configuration files, and site initializers.

An init container named liferay-overlay runs before the main application container and copies these files into place.

Liferay operates the build pipeline and the storage behind it. Your part is committing source to your repository and referencing the resulting artifacts from liferay.yaml.

How Overlays Work

The overlay mechanism has three parts:

  • Pushing to your customer repository triggers a build pipeline that compiles your customizations and uploads the artifacts to your project’s overlay bucket.
  • You reference those artifacts from liferay.yaml in your GitOps repository.
  • At pod startup, the liferay-overlay init container uses rclone (pre-installed in the init container, no setup needed) to copy the referenced files from the bucket into the container’s runtime working directory.

The platform provisions one overlay bucket per project, shared by every environment in that project, and grants each environment’s runtime service account read-only access to it. The bucket name reaches the pod automatically through the overlay-bucket-details secret, as the LIFERAY_OVERLAY_BUCKET_NAME environment variable, so you never specify it yourself.

Files are applied at startup time and are not persisted on a separate PVC. Overlays are disabled by default and must be enabled per environment.

Building and Uploading Customizations

Your customer repository ships a cloudbuild.yaml that defines the build pipeline. When you push to the repository, Google Cloud Build runs that pipeline: it builds your Liferay Workspace (a Gradle project structure for developing Liferay modules and client extensions) by running ./gradlew deploy into a cloudbuild-tmp/ directory, then uploads the resulting artifacts to your project’s overlay bucket.

Liferay manages the pipeline’s credentials and its target bucket. The bucket is supplied to the build through a pre-configured _OVERLAY_BUCKET substitution, so there’s no CI authentication for you to set up and no service account to create.

Each run uploads under its own build ID:

gs://<overlay-bucket>/<BUILD_ID>/

Within that prefix, artifacts keep the layout the Liferay Workspace build produced:

PathContents
deploy/Built OSGi modules
osgi/client-extensions/Built client extensions

Note the build ID for the run whose artifacts you want to deploy. You use it as the path prefix in the next step.

To follow a build’s progress and result, open the Builds dashboard in Grafana. It shows the build ID and status, a link to the commit that triggered the build, and searchable, downloadable build logs. See Metrics.

Enabling Overlays

Configure overlays in your environment’s liferay.yaml, at liferay/projects/<project-id>/environments/<environment-id>/liferay.yaml in your GitOps repository.

FieldDefaultDescription
overlay.enabledfalseEnables the overlay init container. No files are copied while this is false.
overlay.type""The storage provider. Set to gcs for the GCS-backed platform.
overlay.copy[]A list of copy instructions. Each entry has a from path (relative to the bucket root, glob supported) and an into destination path (relative to the Liferay working directory in the container).

Add one entry for each destination path. This example loads both OSGi modules and client extensions from build 12ab34cd-5678-90ef-1234-567890abcdef:

liferay-default:
    overlay:
        copy:
            - from: "12ab34cd-5678-90ef-1234-567890abcdef/deploy/*"
              into: deploy
            - from: "12ab34cd-5678-90ef-1234-567890abcdef/osgi/client-extensions/*"
              into: osgi/client-extensions
        enabled: true
        type: gcs

Always nest these values under liferay-default, the Helm subchart that configures the Liferay runtime. Quote any from value containing a glob.

Each from path matches where the build placed those artifacts, and each into path is relative to the Liferay working directory in the container. To deploy a later build, update the build ID in these paths and push again.

Commit and push the change. Argo CD reconciles it on the next sync, and the overlay loads on the next Liferay pod startup.

Rolling Back to an Earlier Build

Because the deployed build is whatever liferay.yaml currently references, rolling back is a Git operation rather than an action in Argo CD. Revert the commit that changed the build ID, then push. Argo CD reconciles the earlier build on the next sync.

Argo CD’s own Sync, History and Rollback, and Delete controls are hidden from customer logins, which reserves those actions for the GitOps flow. Earlier builds stay in the overlay bucket under their own build IDs, so pointing back at one doesn’t require rebuilding it.

Verifying the Overlay

After Liferay restarts, check the liferay-overlay init container’s logs in Grafana to confirm your files were copied. See Logs.

The init container logs in JSON. A successful copy opens and closes with lines like these, with the rclone copy output in between:

{"message": "Copying from \":gcs,env_auth=true:my-deployment-overlay-acme-2225eb/12ab34cd-5678-90ef-1234-567890abcdef/osgi/client-extensions\" to \"/temp/osgi/client-extensions\".", "script": "overlay-sync.sh", "severity": "INFO", "timestamp": "2026-01-01T00:00:00Z"}
...
{"message": "Copy completed successfully.", "script": "overlay-sync.sh", "severity": "INFO", "timestamp": "2026-01-01T00:00:01Z"}

If the logs show errors, confirm that overlay.enabled is true and that the from path matches the build ID and folder structure the pipeline uploaded. Check the Builds dashboard to confirm the build succeeded and produced the artifacts you expect.