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"
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;
- Start the containers in the background with
docker-compose up -d
. - Browse to the index of the app and a timestamp will be written to the session which will be stored in memcached.
- Restart just the Lucee container with
docker-compose restart lucee
- 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
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
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
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.
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
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
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
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:
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!
My original post? No, no issues at all with specific versions of the extension. I was just after some confirmation on those 3 points;
- Can we pin the version number of an extension at install time (answer is yes)
- Why do automatic upgrades of plugins happen (answer, because they are available and the version is not pinned)
- 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
“lucee.extensions.install” is a nice trick… but it’s not documented here:
Is it an official feature?