How to Set Up a Liferay Portal with MySQL, Nginx, and SSL

Karthik S
3 min readJan 22, 2025

--

What is Liferay? A Gateway to Building Powerful Digital Experiences

Liferay is an open-source platform for building and managing websites, portals, and digital experiences. It offers tools for content management, collaboration, and integration, making it ideal for creating customized enterprise portals. Its modular design allows flexibility, while features like user management, workflows, and APIs enable seamless integration with other systems.

In this guide, I’ll walk you through the process of setting up a Liferay portal with a MySQL database, using Docker, Nginx as a reverse proxy, and securing it with SSL using Certbot.

Prerequisites

Before running Liferay, ensure you have the following:

  • Two Linux instances: one for Liferay and another for the database (MySQL). Debian or Ubuntu is recommended.
  • A domain name.
  • Docker installed on both instances.
  • Nginx installed on the Liferay instance.
  • Certbot installed on the Liferay instance for SSL configuration.

Preparing the Database

To secure the MySQL database, it should be deployed in a private subnet. In my setup, the MySQL instance is accessible only from the public Liferay instance.

Steps to Set Up MySQL

Create a Directory for Persistent Data
Log into the MySQL instance and create a directory to persist MySQL data

mkdir data

Create a Docker Compose File

Create a compose.yml file with the following content

services:
mysql:
image: mysql:5.7
container_name: liferay_database
restart: unless-stopped
environment:
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- ./data:/var/lib/mysql
deploy:
resources:
limits:
memory: 8g

Start the MySQL Container
Run the following command

docker compose up -d

Retrieve the Root Password
Once the container is running, get the generated root password

docker logs liferay_database 2>&1 | grep "GENERATED ROOT PASSWORD:"

Set Up the Liferay Database
Log into the container

docker exec -it <containerName-or-containerId> /bin/bash

Now connect the database

mysql -u root -p

paste the retrieved root password

Then execute these SQL commands

-- Step 1: Create the database
CREATE DATABASE lportal CHARACTER SET utf8;

-- Step 2: Create a user for the Liferay portal
CREATE USER '<username>'@'<ip-of-liferay-hosted-server>' IDENTIFIED BY '<password>';

-- Step 3: Grant privileges
GRANT ALL PRIVILEGES ON lportal.* TO '<username>'@'<ip-of-liferay-hosted-server>';

-- Step 4: Apply changes
FLUSH PRIVILEGES;

Replace <username>, <password>, and <ip-of-liferay-hosted-server> with your values.

Preparing the Liferay Instance

After setting up the database, configure the Liferay instance.

Steps to Set Up Liferay

Create Directories for Persistent Data

Log into the Liferay instance and create a directory to persist Liferay data

mkdir data deploy

Create a Docker Compose File
Create a compose.yml file with the following content

services:
liferay:
image: liferay/portal:7.4.3.120-ga120
container_name: liferay_portal
restart: unless-stopped
environment:
- JAVA_VERSION=zulu11
- LIFERAY_SETUP_PERIOD_WIZARD_PERIOD_ENABLED=false
- LIFERAY_WEB_PERIOD_SERVER_PERIOD_HOST=<liferay-host-domain-or-subdomain>
- LIFERAY_WEB_PERIOD_SERVER_PERIOD_HTTPS_PERIOD_PORT=443
- LIFERAY_WEB_PERIOD_SERVER_PERIOD_PROTOCOL=https
- LIFERAY_VIRTUAL_PERIOD_HOSTS_PERIOD_VALID_PERIOD_HOSTS=*
- LIFERAY_ADMIN_PERIOD_EMAIL_PERIOD_FROM_PERIOD_ADDRESS=<admin-mail-id>
- LIFERAY_ADMIN_PERIOD_EMAIL_PERIOD_FROM_PERIOD_NAME=<admin-name>
- LIFERAY_DEFAULT_PERIOD_ADMIN_PERIOD_PASSWORD=<default-admin-password>
- LIFERAY_DEFAULT_PERIOD_ADMIN_PERIOD_SCREEN_PERIOD_NAME=<admin-screen-name>
- LIFERAY_COMPANY_PERIOD_DEFAULT_PERIOD_WEB_PERIOD_ID=<your-organization-domain-name>
- LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_DRIVER_UPPERCASEC_LASS_UPPERCASEN_AME=com.mysql.cj.jdbc.Driver
- LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_URL=jdbc:mysql://<ip-of-mysql-hosted-server>:<port-of-mysql-hosted-server>/lportal?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
- LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_USERNAME=<username>
- LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_PASSWORD=<password>
ports:
- "8080:8080"
volumes:
- ./data:/opt/liferay/data
- ./deploy:/opt/liferay/deploy
deploy:
resources:
limits:
memory: 8g

Replace the placeholders with your values.

Start the Liferay Container

docker compose up -d

Configuring Nginx as a Reverse Proxy

Create an Nginx Configuration File

sudo nano /etc/nginx/sites-available/liferay

Add the following content

server {
listen 80;
server_name <liferay-host-domain-or-subdomain>;

location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 100M;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}

Enable the Configuration

sudo ln -s /etc/nginx/sites-available/liferay /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Configuring SSL with Certbot

Run the following command to secure the domain

sudo certbot --nginx

Follow the prompts

  • Enter your email address for renewal and security notices.
  • Agree to the terms of service.
  • Decide if you want to receive emails from EFF (optional).
  • Choose whether to redirect HTTP traffic to HTTPS (select option 2 to redirect all requests).

Accessing the Liferay Portal

You can now access your Liferay portal at <liferay-host-domain-or-subdomain>. Use the admin email (<admin-mail-id>) and the default password (<default-admin-password>) to log in. For security, change the default admin password immediately.

--

--

Karthik S
Karthik S

Written by Karthik S

🚀 DevOps Engineer | Exploring cloud, automation, and infrastructure

No responses yet