Looking for guides/tutorials on using CommandBox to run Lucee in production

I’ve been using Lucee 6 and 7, installing Lucee with the Windows Installer and using IIS as a reverse proxy with the BonCode Connector in various capacities for a while now.

Aside from possibly using CommandBox in production for a many-IIS website set up to a single-site Lucee 7 instance, we might run another instance of Lucee for some long running tasks that work with our Python code running via cfexecute related to some AI Engineering we are doing.

We like Python for our AI Engineering work, don’t want to use any other language but Python for that. Eventually, we will run that Python code in a microservice or something and not use cfexecute in remote components.

As a result of possibly needing a second Lucee instance, I’ve looked into CommandBox. Running a Lucee server looks simple for development, but working through all the settings for production with server.json, running multiple Lucee instances on a single server, and using IIS as a reverse proxy with Lucee is a little more involved.

Are there some good instructions aside from the links I provided that are a little more detailed and focus for using CommandBox in a multi-Lucee instance in a production capacity for Windows? I’m reading the ortusbooks site and trying out things in my homelab, but digesting this information is a little more work than I’d like. Any good videos, tutorials, etc, would be appreciated.

https://docs.lucee.org/guides/getting-started/commandbox.html

https://commandbox.ortusbooks.com/embedded-server

I did get BoxLang working with CommandBox and running IIS as a reverse proxy for BoxLang using Brad Wood’s youtube video a while back (see below). I’m sure this will translate to Lucee as well.

https://www.youtube.com/watch?v=8q7sSZ7gK3E

It took a lot of work to absorb the setup, configuration, and maintenance process of running production-ready Lucee via the Windows installer. Just feeling a little underwhelmed at the documentation I’m finding online for using CommandBox in a similar capacity and not looking forward to all the work it will entail to feel comfortable running that in a production capacity as well.

What’s making you lean towards commandbox rather than a setup with Docker? I know the Ortus folks are great at advocating their stack, but the configs for running Lucee in Docker containers, separated out is pretty straight forward.

Unfortunately, this is going on a bare metal Windows Server. Docker really isn’t an option in this scenario. I realize that there numerous cloud and container options for Lucee available, those just won’t work for me in this scenario.

Most likely I will make some notes as I work through this config and run it for a while. Maybe I’ll share those if they end up being worth sharing.

I’m with quetwo on this.

CommandBox is fine for development, but consider using Docker for production. It has become the industry standard, even Brad Wood would agree.

This is especially true if you are running apps with various runtimes. Such as Python and CFML. They can easily share the same host if resources allow.

While Docker can be installed on Windows, using Linux makes much more sense.

If you want to use a Windows box, your best bet is to install Lucee and configure it to work with IIS. I don’t recommend this because it’s not immutable and you’ll be stuck with what you’re willing to do for maintenance. I’ve managed many of these types of installs and it’s no fun.

My understanding is that running a Lucee app with Commandbox is meant to be a developer recipe and I don’t think you’re going to want to use it for production. Maybe @Brad_Wood might have more to say on this since he’s the main Commandbox developer.

If I were you, I would seriously look into running Lucee on a Linux box with nginx as your web server, which will be cheaper than Windows. Perhaps this is not feasible, but I believe it’s the best production environment for Lucee. You can quite easily use Ai to build a immutable instances using Terraform, and then your server is built with code and you can destroy it and create a new one (with tweaks) as many times as you want.

As with many topics, this is one about which there are a variety of opinions. And if Brad or anyone at Ortus had seen this, they’d certainly welcome the chance to prop you up on your desire run Commandbox in production. :slight_smile:

Can you? Of course. Many do.

Do you need to integrate with iis? Well, no. They would explain how the undertow web server built into Commandbox should suffice even for prod needs. Still, some simply favor using IIS or feel compelled to due to existing configuration, etc.

Anyway, you were asking for resources (videos, tutorials) to help set it up/deal with Commandbox in prod, and while I still suspect someone at Ortus may point out a better one for your specific interests, here are a few to consider in the meantime, different from what you’d listed. Each presents a slightly different perspective on your question:

Let us know of any of those pique your interest or grease the skids.

Finally, rather than wait and hope for a response from Ortus here, this might have been better raised on their community instead: https://community.ortussolutions.com

If you do that, it may help to leave a link to that thread here, as a breadcrumb for future (or current) readers who may be interested in more on the topic. I realize some may disdain such cross posting, but it’s approaching 3 days for you already.

This will save you a lot of headache, do not use undertow (The java web engine) in production - If uptime, reliablity, or your sanity are items that matter to you, your design is flawed and you’re trading a minor performance gain for security and stability issues.

That’s the first I’ve heard that, Terry. Would you please elaborate? I couldn’t find public resources that made that argument; indeed, I found the opposite contention. It’s also the embedded web server tor jBoss Wildly.

Are you really saying that anyone using Commandbox to deploy any cfml engine (or boxlang) for production should always be proxying that with some other web server, on any OS?

Sure,

Publishing documents saying something can do something, sure, it “can” do something. I could fill a 1974 Ford Pinto with kittens and boxes of explosives and drive it in heavy traffic, doesnt meen its the best idea.

For Dev, one of the nicest modern tools out there that has hit the CFM space, hands down. For small sites, where business-critical workflows can afford downtime or data leaks, go ahead; it should be fine.

For an enterprise application stack, under no circumstances would that be worth the risk.

That is actually my concern.

I am not saying CommandBox cannot serve production traffic. Ortus clearly says it can. Their docs say CommandBox may be used in production and can either be proxied through IIS, Apache, or Nginx, or bound directly to ports 80/443 “if you choose.” So yes, direct exposure is supported as an option.

But “supported” is not the same thing as “the best internet edge pattern for every production system.” – That’s Enterprise risk, not worth it for anyone willing to lose a job over a gaggle of people saying “It’s supported, and you should be ok…”

The argument that “it is Undertow, and Undertow is used by WildFly/JBoss” does not really settle the architecture question. Undertow is a real web server, but it also has a real vulnerability history. NVD lists CVE 2025 9784 as an Undertow flaw where malformed requests can create excessive server workload and denial of service risk, with Red Hat’s CVSS 3.1 score shown as 7.5 High. NVD also lists CVE 2025 12543 affecting Undertow core, used in WildFly and JBoss EAP, where malformed or malicious Host headers may be processed, enabling cache poisoning, internal network scans, or session hijacking.

That does not mean “Undertow is bad.” It means “Undertow is not magically exempt from normal edge hardening just because it is embedded in a respected Java stack.”

Even the Undertow release notes show routine security and stability work: CVE 2024 4109, CVE 2025 9784, HTTP/2 DDoS handling, buffer leak work, WebSocket NPEs, multipart parser fixes, ProxyHandler NPEs, and regression fixes. Again, that is normal for serious software. But it weakens the claim that putting it directly on the public edge is an obvious default.

So my position is narrower:

For small apps, controlled environments, internal systems, containers behind a cloud load balancer, or properly locked down deployments, CommandBox directly serving traffic can be reasonable.

For enterprise internet-facing production, especially anything exposed to unknown traffic, compliance pressure, WAF requirements, centralized TLS policy, rate limiting, request filtering, bot filtering, header normalization, static asset offload, and operational logging, I would still expect a purpose-built front door such as Nginx, Apache, IIS, a cloud load balancer, or a WAF in front.

Anything else is not only bad design, but internationally bad design.

CommandBox being capable of direct serving does not erase the sea of bad actors. It just means the choice is available. My objection is to treating “Undertow is embedded in WildFly” as if that ends the risk discussion. It does not.

So back to driving with explosives and kittens, in a 1974 Ford Pinto.

Oh my. This is clearly some sort of sore spot for you.

First, I didn’t lead with the mention of wildfly, I concluded with it. You may still dismiss the mention as tantamount to stolen valor, but I brought it up because many wondering about undertow’s suitability for production may well simply give credence to the fact that such an enterprise platform embeds it. Call that being lazy if you want. And If you’ve never been guilty of such trust by association, good on you.

As for your elaboration on its vulns, virtually everything we use has some vulns, some trivial, some significant. It seems curious to lamabast undertow as if it’s unique. Seriously, Terry, I could ask where all this angst is coming from.

But moving on, it’s not really what Alex asked about originally, which was for resources on how to run Commandbox on prod. When no one offered any, I stepped in to offer some. I only mentioned its use of undertow in passing, anticipating how others would also. :slight_smile: I’d offered resources that don’t involve undertow also.

I’ll leave others to take up debating or contending with you on that. I’m not here to defend it’s honor. But I’ll be watching the thread, of course.

@alex.m
I am not sure about web guides or automation. Focusing on using Windows and IIS as is.

I think if you run the Lucee Windows installer (don’t connect to IIS during install) a second time it will ask your for different port numbers and service names.

Similarly you can create a new website on IIS with a different host name and/or IP.

Then, run the connector installer using the site specific install mode and enter the port numbers for the Lucee instances and pick the IIS site to connect to.

Now to the longer part, On the non-automated side here is

the procedure to manually stand up multiple isolated Lucee instances on a single Windows machine and route them through IIS.

  1. Install the Base Instance:

Run the standard Lucee Windows Installer once. Install it to a clear root directory, such as C:\Lucee_Main. During the installation wizard, skip the BonCode connector integration. You want to handle BonCode manually per-site later to avoid entangling your global IIS configuration.

  1. Clone the Tomcat Engine: Requires stopping the service.

Open your Windows Services snap-in and stop the “Lucee” (or Apache Tomcat) service.

Navigate to your C:\Lucee_Main (assuming this is where the installtion was), copy the entire C:\Lucee_Main folder, and paste it. Rename the copied folder to represent your second instance, for example, C:\Lucee_AI.

  1. Resolve Port Conflicts: Modify the secondary server.xml.

Both instances cannot listen on the same ports. Navigate to your cloned directory at C:\Lucee_AI\tomcat\conf\server.xml and open it in a text editor. You must change three specific ports to avoid collisions with your main instance:

  • Server Shutdown Port: Find port="8005" and change it to 8015.

  • HTTP Connector Port: Find port="8888" (used for the Lucee Admin) and change it to 8889.

  • AJP Connector Port: Find port="8009" and change it to 8019. This is the critical port BonCode will use to communicate with this specific instance.

  1. Install the Secondary Windows Service: Run via Command Prompt as Administrator.

Your cloned folder needs to be registered as its own Windows Service. Open an elevated Command Prompt and set the environment variables so Tomcat targets your new folder, then install the service:


set CATALINA_HOME=C:\Lucee_AI\tomcat

set CATALINA_BASE=C:\Lucee_AI\tomcat

cd C:\Lucee_AI\tomcat\bin

service.bat install Lucee_AI_Service

You now have two fully independent Lucee services in Windows. You can start them both.

  1. Configure Site-Specific BonCode Routing:

Set up your “Main” and “AI” websites in IIS, ensuring they have separate Hostnames/Ips and Application Pools.

Instead of running a global installer, manually place the BonCode connector files (specifically the BIN folder) into the web root of each IIS site. In each site’s BIN folder, edit the BonCodeAJP13.settings file to route traffic to the correct instance:

For the Main Site:


<Port>8009</Port>

For the AI Site:


<Port>8019</Port>

Note Don’t forget to copy the secret: Your server.xml has an AJP secret defined, ensure you also add <RequestSecret>your-secret-here</RequestSecret> to the BonCode settings file.

This architecture gives you a complete backend isolation for your Python/AI tasks, separate front-end IIS worker processes.

The BonCode installer docs outline some of this process as well (BonCode Apache Tomcat AJP 1.3 Connector).

So you now should have a few options to play with.

Hope this helps,

Bilal

1 Like

I’m on PTO and away from a computer this week, but I will just add for now that CommandBox is a very secure and capable server which can be used behind iis/apache/nginx using either a simple reverse proxy or BonCode (supported natively) or it can support multi-site out of the box with its full-featured java web server all by itself. Commandbox is deployed in prod on bare metal, VMs, or Docker. Docker is not an alternative to CommandBox, box lives comfortably inside the container, giving you a consistent config strategy from dev to prod. You can even force case sensitivity or insensitivity to ensure consistent behavior across all environments. The majority of docker-based CF prod deploys run in CommandBox (per the last SoTCFU survey). It’s the only servlet option which allows your entire web server and servlet container to be configured in a single JSON file with complete env var overrides and CFConfig built in. Happy to answer any other CommandBox questions here or over in the Ortus forums when I’m back from PTO.

call me “old fashioned” but this isnt the first time We have had some new comer, in here, we both state everything roughly the same conversation, Brad pipes up, (like he did below) I point out yet again, that their very latest binary downloaded from their website is at least a quarter or more out of phase with patching, making the whole, it is secure point, moot.

IMPLEMENTOR=“Eclipse Adoptium”
IMPLEMENTOR_VERSION=“Temurin-11.0.29+7”
JAVA_RUNTIME_VERSION=“11.0.29+7”
JAVA_VERSION=“11.0.29”
JAVA_VERSION_DATE=“2025-10-21”

This is from a binary off their website as of today.

It’s not secure.
https://nvd.nist.gov/vuln/detail/CVE-2025-21587

Ill just leave it at that.

Let’s do (please leave it at that). We’ve heard from many but not Alex. Alex, has your original question been answered to your satisfaction? If not, what else do you seek?

Or what do you think of the many replies to you? It’s been a week since you opened this discussion.

I feel my question has been answered. Thank you all for your input.

3 Likes

For a variety of reasons I ended up going with using the Lucee installer for the second instance. If I was running numerous Lucee instances on the box, I would probably use CommandBox. However, since I’m only using this second instance and this really should be temporary until I put the Python code this instance calls in a Python microservice (or whatever), I erred for using the WIndows installer like I did for the first instance. Here’s what I did to set it up:

Standard C:\Lucee instance ports:
HTTP Connector Port: 8888
Server Shutdown Port: 8005
AJP Connector Port: 8009

New C:\LuceeAI instance ports:
HTTP Connector Port: 8889
Server Shutdown Port: 8015
AJP Connector Port: 8019

I ran the Lucee Windows installer. Making sure to not install the boncode connector.
We are calling the instance “LuceeAI” and installing Lucee server to “C:\LuceeAI”.

Do not install the IIS (BonCode) Connector. Install it after manually.

#To see the LuceeAI instance service parameters:
C:\luceeAI\tomcat\bin\Luceew.exe //ES//LuceeAI

#To see a default instance of Lucee’s service parameters:
C:\lucee\tomcat\bin\Luceew.exe //ES//Lucee

You don’t have to do an extra configuration of the service. The Windows installer does an adequate job, however, if you want to do it for any reason, here’s what you would do:

run cmd.exe as administrator, run the following commands:

#delete the existing LuceeAI instance and check to make sure it's gone after deleting it
sc query LuceeAI
sc stop LuceeAI
sc delete LuceeAI
sc query LuceeAI

#set up the new version of the Lucee AI service
set CATALINA_HOME=C:\Lucee_AI\tomcat
set CATALINA_BASE=C:\Lucee_AI\tomcat
cd C:\LuceeAI\tomcat\bin
service.bat install LuceeAI

Setup up IIS website for LuceeAI:
luceeai.foobar.com
X:\inetpub\wwwrootLuceeAI

Set up the website in IIS for the AI code.
I’m calling the website LuceeAI in IIS. HTTP and HTTPS bindings set up appropriately.

Install the boncode connector separately.
Use the 8019 AJP port.
Choose specific IIS sites to apply it to. In this case just the LuceeAI site.

Set the secrets in X:<IIS-LuceeAI-webroot>\BIN\BonCodeAJP13.settings:

<Settings>
<Server>localhost</Server>
<Port>8019</Port>  
...
<RequestSecret>ajp.secret</RequestSecret>
<ModCFMLSecret>modcfml.valve.secret</ModCFMLSecret>
</Settings>

You can find the secrets in:
C:\LuceeAI\tomcat\conf\server.xml

2 Likes

On a side note, in my homelab the new Lucee instance is using a different version of the BonCode connector than the old Lucee instance. Since there is per-site configuration of the BonCode connector this works. However, one thing I noticed is that looking at the properties of the BonCode dlls in the site’s BIN folders, there’s no way to distinguish dll versions. The properties tab on the dlls all show version 1.0.0. The filesizes are different. The dates are from the dates of install. Not a big deal. In prod, I will update the BonCode connector for all sites. Just something I thought I’d pass along.

To be clear, Java is not part of CommandBox, nor do we take responsibility for the version of java you use. We have a JRE-included download on our site with a recent Java build out of convenience, but we don’t bump a new version of CommandBox every time Java releases a version and we make no promises it will be the latest version of Java. You are free to run CommandBox on any version of Java you wish and if our convenience-bundled version isn’t new enough for you, then you should be capable to get a version you prefer.

We DO cut new releases for bundled libraries such as Undertow. In fact we cut one just last month to include the latest Undertow security updates.

1 Like

I stand corrected… I never knew commandbox is used in production. I’m always amazed at what people have done. Cheers everyone!!!

By the way, I just found this in the BonCode documenation:

Adding a query string of BonCodeConnectorVersion=true to a CF page will display the version of BonCode in use for that IIS site (and also let you know what settings file is being used):
https://luceeai.foobar.com/index.cfm?BonCodeConnectorVersion=true

I’m sure the regulars all know this, but it was new to me and answered an earlier point I made.