Installing specific versions of extensions in Lucee 5.2.x

Is there a way to uninstall specific extensions using the same mechanism?

Are there any docs about what each of the environment variables do? I am still trying to install the extension as defined by the the LUCEE_EXTENSIONS variables but it doesn’t seem to be working on Lucee 5.2.5.20

Some docs and clarity outside the LAS team members would be nice.

docker compose example:

version: "3"
services:
  web:
    image: ortussolutions/commandbox
    volumes:
      - ".:/app"
    ports:
      - 8080
    environment:
      - LUCEE_EXTENSIONS="16FF9B13-C595-4FA7-B87DED467B7E61A0;name=Memcached;version=3.0.2.28"
1 Like

With Docker it’s important that extensions are installed during the image build for a number of reasons (container startup time, removes the dependency on the extension server being contactable, consistent/repeatable builds, etc), so I’d avoid adding the LUCEE_EXTENSIONS environment variable to the Docker Compose file if possible since they are kind of run-time settings.

I think this is the most basic, working example that I can give as a starting point for installing Memcached, and then configuring it as a session store;

Dockerfile

FROM lucee/lucee52:latest

# install extensions by prewarming lucee
ENV LUCEE_EXTENSIONS "16FF9B13-C595-4FA7-B87DED467B7E61A0;name=Memcached;version=3.0.2.29"
RUN /usr/local/tomcat/bin/prewarm.sh

COPY www /var/www

docker-compose.yml

lucee:
  build: .
  volumes:
    - "/workbench/memcached/www:/var/www"
  ports:
    - "8888:8888"
  links:
    - "memcached:memcached"
memcached:
  image: memcached:alpine
  expose:
    - "11211"

(Note: Your volume paths may vary, the above is just what works for me in my environment).

www/Application.cfc

component {
	this.name = "memcached";

	this.cache.connections["sessions"] = {
		class: "org.lucee.extension.io.cache.memcache.MemCacheRaw",
		bundleName: "memcached.extension",
		bundleVersion: "3.0.2.29",
		storage: true,
		custom: {
			"socket_timeout":"30",
			"initial_connections":"1",
			"alive_check":"true",
			"buffer_size":"1",
			"max_spare_connections":"32",
			"storage_format":"Binary",
			"socket_connect_to":"3",
			"min_spare_connections":"1",
			"maint_thread_sleep":"5",
			"failback":"true",
			"max_idle_time":"600",
			"max_busy_time":"30",
			"nagle_alg":"true",
			"failover":"true",
			"servers": "memcached:11211"
		},
		default: ""
	};
	this.sessioncluster = true;
	this.sessionstorage  = "sessions";

}

www/index.cfm

<cfparam name="session.timestamp" default="#now()#">
<cfdump var="#session.timestamp#">

To test;

  1. Start the containers in the background with docker-compose up -d.
  2. Browse to the index of the app and a timestamp will be written to the session which will be stored in memcached.
  3. Restart just the Lucee container with docker-compose restart lucee
  4. Browse to the index of the app again and you should see that the timestamp remained the same, which means that the session was successfully persisted in memcached across Lucee restarts.

If you’re using CommandBox Docker images I don’t know the most efficient way of installing/prewarming Lucee there, there’s perhaps a command that will start and stop the server for you. I would start with barebones Lucee Docker images to prove it’s working, and then move back up the chain up from there.

Hope that helps :smiley:

2 Likes

This post makes reference to a spreadsheet tracking the state of all config options:
https://lucee.daemonite.io/t/lucee-configuration-options/321

What do you have in your pre-warm.sh script? is it

 RUN rm -rf /opt/lucee/web/logs/ && \
   /usr/local/tomcat/bin/catalina.sh start && \
   while [ ! -f "/opt/lucee/web/logs/application.log" ] ; do sleep 2; done && \
   /usr/local/tomcat/bin/catalina.sh stop

Yep, you can see the source here:
https://github.com/lucee/lucee-dockerfiles/blob/master/5.2/prewarm.sh

1 Like

Hi @markdrew I just noticed your comment. I don’t know if you figured it out, but the env var LUCEE_EXTENSIONS is not what Lucee proper looks for. I believe that name is specifically something looked for in the official lucee image that gets passed through to an env var or JVM prop of the name Lucee is actually looking for which is either lucee-extensions (deprecated) or lucee.extensions

The CommandBox image doesn’t provide a passthrough env var called LUCEE_EXTENSIONS. We could, but I’m not sure what the point would be since it’s almost exactly named as the built in env var, just non-standard. With the CommandBox image, just provide the environment variable in the format Lucee itself is looking for and everything should work.

Also, FWIW, since these links are so hard to find, I’ll leave them here as well. Here’s the docs for that env var (which seriously needs some love since it doesn’t even cover specific versions!):
http://docs.lucee.org/guides/running-lucee/configuring-lucee/system-properties.html

And here is the “living” Google Doc that lists all possible env vars and system props. The one in question is on line 5.

The Lucee settings that come from Java system properties are also supported as environment variables. From my original post above;

This means that the Java system property lucee.extensions can instead be specified as the environment variable LUCEE_EXTENSIONS, and the same should apply to all the other properties that are listed in the above spreadsheet :slight_smile:

Edit: just to clarify, the Lucee docker images don’t do anything special to find and pass through these environment variables as system properties, they are supported directly by Lucee and should work anywhere AFAIK.

2 Likes

We use

ENV LUCEE_EXTENSIONS "66e312dd-d083-27c0-64189d16753fd6f0;name=PDF;version=1.0.0.68,99a4ef8d-f2fd-40c8-8fb8c2e67a4eeeb6;name=MSSQL;version=6.2.2.jre8"

In our Dockerfile and that seems to work, as once we’ve prewarmed saved the image then spun the image up, going to the extensions area shows these as up-to-date.

It would be really good if Lucee would either use ExtensionStore ID’s as you are doing or forgebox stubs, I think this would look better no?

ENV LUCEE_EXTENSIONS pdf@1.0.0.68, memcached@3.0.2.25

Since using the UUID is such a pain for admins etc that would look at a random docker file (like I have) :

FROM ortussolutions/commandbox
COPY ./ $APP_DIR/
ENV HEADLESS true
ENV BOX_INSTALL true
ENV LUCEE_EXTENSIONS 16FF9B13-C595-4FA7-B87DED467B7E61A0

Prizes for anyone to know what extension that is :slight_smile:

At the end of the day, the point of this is to make configurations easily readable by humans.

In summary, add stub names for the existing extensions (store, since that is where they come from), if not found, look for them in forgebox.io

steps off soapbox

1 Like

Mine looks like

ENV LUCEE_EXTENSIONS "66e312dd-d083-27c0-64189d16753fd6f0;name=PDF;version=1.0.0.68,99a4ef8d-f2fd-40c8-8fb8c2e67a4eeeb6;name=MSSQL;version=6.2.2.jre8"

And that appears to install, whilst I can at least see what it’s going to do…

I get you, I see what it’s going to do, but it’s an abusive way to do it for the poor sys admin that I am going to hand off the docker file to.

And then I tell him about the box.json file that also downloads dependencies etc. I know you can read it but there is usually a chain of people that need to know this.

(I wasn’t having a go at you sir, just the implementation)

Micha explained above the reason for the current implementation is that it matches the OSGi syntax that is used in the manifest files for installing extensions;

e.g.

It’s not the nicest thing to read but the name and/or label does make it human readable, and I’m ok with it at least being consistent with what is already used in the manifests.

That said, I’d be happy to see a new identifier that wasn’t a UUID if Micha thinks that’s feasible to support :slight_smile:

2 Likes

FWIW, when using the CommandBox Lucee images, here’s the approach we take to bypass using the environment variables, but still install the extensions we need:

1 Like

Awesome project @mjclemente!

by setting “lucee.extensions.install” to false, the extension defined in the manifest not get installed, that way only extension defined with env variable get installed

Such a nicer solution

Circling back to your initial post here; just out of curiosity, does the 3.0.2.29 version of the Memcached plugin cause an issue for you?

Or was that example purely for the sake of example?

Thanks!

1 Like

My original post? No, no issues at all with specific versions of the extension. I was just after some confirmation on those 3 points;

  1. Can we pin the version number of an extension at install time (answer is yes)
  2. Why do automatic upgrades of plugins happen (answer, because they are available and the version is not pinned)
  3. Can we turn off automatic upgrades of extensions (answer seems to be yes if you set “lucee.extensions.install” to false though I haven’t tested this, OR you pin the version in the LUCEE_EXTENSIONS env var, OR you have the versions specified in the lucee XML files).

The reason behind all of that is that I need the extension installation to happen at build time in Docker images, so that I can have repeatable builds that always produce the same result, rather than having unexpected things like extension installation/upgrades happen during container startup. So for the past 15+ months we’ve been in a pretty good place I think :smiley:

2 Likes

“lucee.extensions.install” is a nice trick… but it’s not documented here:

Is it an official feature?