sha256:b68561664dd39f7cbfe67ab8928ba9dd8cf4f7c7917c1028a5c6e8071bfa81e9
Last pushed
7 days by 4lejandrito
Type
Compose
Manifest digest
sha256:b68561664dd39f7cbfe67ab8928ba9dd8cf4f7c7917c1028a5c6e8071bfa81e9
# The two portals the talk ran on, empty and with the MCP server on, in fresh
# containers every time:
#
# docker compose -f oci://docker.io/4lejandrito/liferay-dxp:devcon-2026 up --pull always --force-recreate --renew-anon-volumes
#
# Then http://localhost:8081 for dev and http://localhost:8082 for live, signing
# in as [email protected] / test, and the MCP server at /o/mcp on each.
#
# The portals see each other on the portals network, so live imports dev's
# exports by downloading them from http://liferay-dev:8080. Every portal has its
# own Elasticsearch, on a network of its own where it answers as elasticsearch:
# two fresh portals get the same company id, so on a shared one their indexes
# would collide. Elasticsearch runs from its own multi architecture image
# because it installs a seccomp sandbox that an emulated amd64 container cannot
# provide, which keeps it native on Apple Silicon.
#
# Live also answers the room through a Cloudflare Tunnel (../tunnel.sh): it takes
# any host name and trusts the X-Forwarded headers, so the pages it serves through
# the tunnel link to its https address, while here it stays plain localhost. Its
# home is the quiz, so the slide's QR code only needs the domain, and it takes far
# more than the 100 guest entries a day Liferay allows by default, one per player.
#
# All the configuration is here, as environment variables. The portal reads every
# LIFERAY_ one as the portal property above it, and configuration.override.<pid>_<key>
# as that key of that OSGi configuration.
x-elasticsearch: &elasticsearch
image: 4lejandrito/liferay-dxp:7.4.13-devcon-2026-elasticsearch
environment:
cluster.name: LiferayElasticsearchCluster
discovery.type: single-node
ES_JAVA_OPTS: -Xms1g -Xmx1g
xpack.security.enabled: "false"
healthcheck:
test: ["CMD-SHELL", "curl --fail --silent http://localhost:9200/_cluster/health || exit 1"]
interval: 5s
retries: 60
start_period: 30s
x-liferay-environment: &liferay-environment
# admin.email.from.address
LIFERAY_ADMIN_PERIOD_EMAIL_PERIOD_FROM_PERIOD_ADDRESS: [email protected]
# admin.email.from.name
LIFERAY_ADMIN_PERIOD_EMAIL_PERIOD_FROM_PERIOD_NAME: Test Test
# captcha.enforce.disabled and
# configuration.override.com.liferay.captcha.configuration.CaptchaConfiguration_maxChallenges
LIFERAY_CAPTCHA_PERIOD_ENFORCE_PERIOD_DISABLED: "true"
LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_CAPTCHA_PERIOD_CONFIGURATION_PERIOD__UPPERCASEC_APTCHA_UPPERCASEC_ONFIGURATION_UNDERLINE_MAX_UPPERCASEC_HALLENGES: I"-1"
# company.default.locale
LIFERAY_COMPANY_PERIOD_DEFAULT_PERIOD_LOCALE: en_US
# company.security.strangers.verify
LIFERAY_COMPANY_PERIOD_SECURITY_PERIOD_STRANGERS_PERIOD_VERIFY: "false"
# enterprise.product.notification.enabled
LIFERAY_ENTERPRISE_PERIOD_PRODUCT_PERIOD_NOTIFICATION_PERIOD_ENABLED: "false"
# jdbc.default.*: the MySQL the image starts beside the portal
LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_DRIVER_UPPERCASEC_LASS_UPPERCASEN_AME: com.mysql.cj.jdbc.Driver
LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_PASSWORD: root
LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_URL: jdbc:mysql://127.0.0.1/lportal?characterEncoding=UTF-8&dontTrackOpenResources=true&holdResultsOpenOverStatementClose=true&serverTimezone=GMT&useFastDateParsing=false&useUnicode=true
LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_USERNAME: root
# passwords.default.policy.change.required
LIFERAY_PASSWORDS_PERIOD_DEFAULT_PERIOD_POLICY_PERIOD_CHANGE_PERIOD_REQUIRED: "false"
# passwords.encryption.algorithm
LIFERAY_PASSWORDS_PERIOD_ENCRYPTION_PERIOD_ALGORITHM: NONE
# setup.wizard.enabled
LIFERAY_SETUP_PERIOD_WIZARD_PERIOD_ENABLED: "false"
# terms.of.use.required
LIFERAY_TERMS_PERIOD_OF_PERIOD_USE_PERIOD_REQUIRED: "false"
# users.reminder.queries.enabled
LIFERAY_USERS_PERIOD_REMINDER_PERIOD_QUERIES_PERIOD_ENABLED: "false"
# The Liferay MCP Server: feature.flag.LPD-63311 and
# configuration.override.com.liferay.mcp.server.rest.internal.configuration.MCPServerConfiguration_enabled
LIFERAY_FEATURE_PERIOD_FLAG_PERIOD__UPPERCASEL__UPPERCASEP__UPPERCASED__MINUS_63311: "true"
LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_MCP_PERIOD_SERVER_PERIOD_REST_PERIOD_INTERNAL_PERIOD_CONFIGURATION_PERIOD__UPPERCASEM__UPPERCASEC__UPPERCASEP__UPPERCASES_ERVER_UPPERCASEC_ONFIGURATION_UNDERLINE_ENABLED: B"true"
# Site export and import at the instance level, which ships the quiz's object
# and its whole site to live in a single export, and the flag it depends on:
# feature.flag.LPD-57655 and feature.flag.LPD-85946
LIFERAY_FEATURE_PERIOD_FLAG_PERIOD__UPPERCASEL__UPPERCASEP__UPPERCASED__MINUS_57655: "true"
LIFERAY_FEATURE_PERIOD_FLAG_PERIOD__UPPERCASEL__UPPERCASEP__UPPERCASED__MINUS_85946: "true"
# configuration.override.com.liferay.portal.search.elasticsearch8.configuration.ElasticsearchConfiguration_networkHostAddresses
# and _productionModeEnabled
LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_PORTAL_PERIOD_SEARCH_PERIOD_ELASTICSEARCH8_PERIOD_CONFIGURATION_PERIOD__UPPERCASEE_LASTICSEARCH_UPPERCASEC_ONFIGURATION_UNDERLINE_NETWORK_UPPERCASEH_OST_UPPERCASEA_DDRESSES: '["http://elasticsearch:9200"]'
LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_PORTAL_PERIOD_SEARCH_PERIOD_ELASTICSEARCH8_PERIOD_CONFIGURATION_PERIOD__UPPERCASEE_LASTICSEARCH_UPPERCASEC_ONFIGURATION_UNDERLINE_PRODUCTION_UPPERCASEM_ODE_UPPERCASEE_NABLED: B"true"
services:
elasticsearch-dev:
<<: *elasticsearch
networks:
dev:
aliases: [elasticsearch]
liferay-dev:
image: &liferay 4lejandrito/liferay-dxp:7.4.13-devcon-2026
depends_on:
elasticsearch-dev:
condition: service_healthy
environment:
<<: *liferay-environment
# virtual.hosts.valid.hosts: the defaults, and liferay-dev for live's downloads
LIFERAY_VIRTUAL_PERIOD_HOSTS_PERIOD_VALID_PERIOD_HOSTS: localhost,127.0.0.1,[::1],[0:0:0:0:0:0:0:1],liferay-dev
networks: [dev, portals]
ports:
- "8081:8080"
elasticsearch-live:
<<: *elasticsearch
networks:
live:
aliases: [elasticsearch]
liferay-live:
image: *liferay
depends_on:
elasticsearch-live:
condition: service_healthy
environment:
<<: *liferay-environment
# com.liferay.portal.servlet.filters.gzip.GZipFilter
LIFERAY_COM_PERIOD_LIFERAY_PERIOD_PORTAL_PERIOD_SERVLET_PERIOD_FILTERS_PERIOD_GZIP_PERIOD__UPPERCASEG__UPPERCASEZ_IP_UPPERCASEF_ILTER: "true"
# company.default.home.url
LIFERAY_COMPANY_PERIOD_DEFAULT_PERIOD_HOME_PERIOD_URL: /web/zelda-quiz/quiz
# configuration.override.com.liferay.object.configuration.ObjectConfiguration_maximumNumberOfGuestUserObjectEntriesPerObjectDefinition
LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_OBJECT_PERIOD_CONFIGURATION_PERIOD__UPPERCASEO_BJECT_UPPERCASEC_ONFIGURATION_UNDERLINE_MAXIMUM_UPPERCASEN_UMBER_UPPERCASEO_F_UPPERCASEG_UEST_UPPERCASEU_SER_UPPERCASEO_BJECT_UPPERCASEE_NTRIES_UPPERCASEP_ER_UPPERCASEO_BJECT_UPPERCASED_EFINITION: I"10000"
# Live downloads dev's exports from http://liferay-dev:8080, a private
# address it only fetches from when allowed:
# configuration.override.com.liferay.portal.security.configuration.URLFetchSecurityCompanyConfiguration_urlHostsAllowed
# and _urlLocalNetworkAccessEnabled
LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_PORTAL_PERIOD_SECURITY_PERIOD_CONFIGURATION_PERIOD__UPPERCASEU__UPPERCASER__UPPERCASEL__UPPERCASEF_ETCH_UPPERCASES_ECURITY_UPPERCASEC_OMPANY_UPPERCASEC_ONFIGURATION_UNDERLINE_URL_UPPERCASEH_OSTS_UPPERCASEA_LLOWED: '["liferay-dev"]'
LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_PORTAL_PERIOD_SECURITY_PERIOD_CONFIGURATION_PERIOD__UPPERCASEU__UPPERCASER__UPPERCASEL__UPPERCASEF_ETCH_UPPERCASES_ECURITY_UPPERCASEC_OMPANY_UPPERCASEC_ONFIGURATION_UNDERLINE_URL_UPPERCASEL_OCAL_UPPERCASEN_ETWORK_UPPERCASEA_CCESS_UPPERCASEE_NABLED: B"true"
# virtual.hosts.valid.hosts, any for the tunnel
LIFERAY_VIRTUAL_PERIOD_HOSTS_PERIOD_VALID_PERIOD_HOSTS: "*"
# web.server.forwarded.*.enabled
LIFERAY_WEB_PERIOD_SERVER_PERIOD_FORWARDED_PERIOD_HOST_PERIOD_ENABLED: "true"
LIFERAY_WEB_PERIOD_SERVER_PERIOD_FORWARDED_PERIOD_PORT_PERIOD_ENABLED: "true"
LIFERAY_WEB_PERIOD_SERVER_PERIOD_FORWARDED_PERIOD_PROTOCOL_PERIOD_ENABLED: "true"
networks: [live, portals]
ports:
- "8082:8080"
networks:
dev:
live:
portals:
docker compose -f oci://4lejandrito/liferay-dxp:devcon-2026 upUse the above command to pull and run the Compose file. Learn more.