Blog

Blog Archives - 14 Record(s)

Year: '2015' - Month: '2'

04
February 2015

Gavin Pickin

How to write your very own CLI Commands in CFML

CFML Language, CFML Server, CommandBox, Lucee, Node.js, Server Admin, Tools and IDEs


I bet half of my audience just tuned out, seeing CFML in the title, but this is easier than writing Node as a Javascript Developer… of course you can prove me wrong. In case you have been sleeping under a rock, I’ll let you know that CommandBox went gold today… which apparently means it made it to 1.0. Its not like musical going gold, where you sold so many copies, going gold meant you made it to 1.0, and your api is solid enough to use in production or something. CommandBox is a CLI, a CFML REPL, Package Manager, and includes a tiny Java Servlet Container, which means you can even spin up a server in any directory. Ortus Solution listened to the cries for a CLI and Package manager, and with Forgebox being extended to other any CFML library or module, not just Ortus / Coldbox libraries and modules, the CFML community finally has it.

I will not go into all the details of what it can do… to be honest there are some great videos already, including the cool Snake game that is built in, great documentation and more coming all the time. There are lots of content on the COOLness of it, let me show you what I have been playing with.

Command Box Demo - released June 2014
Coldbox Developer Week 2014 - Package Management & Automation with CommandBox
CommandBox Site on Ortus Solution’s Website
CommandBox Documentation

Disclosure time, before Feb 1 of 2015… I had only watched the videos, and downloaded the beta, tried out a couple of the simple commands and the REPL. I had not tired to write a recipe, or command, or anything under the covers… so everything I am about to show you, I picked up through the docs, the google group, and maybe some twittering.

My last few blog posts have been about the new CFML engine, LUCEE, and how to configure Lucee and Tomcat, configure apache, and get up and running quickly. I have even had a request to help others to get their dev environments setup so they can avoid conf headaches, so I thought to myself, maybe I can write some commands for this. I encourage you to download CommandBox, and code along with me.

Now, if you are running commandbox from terminal, outside of the commandbox shell, you can write a type a command like this

$ box server list

 

If you run just box, it will load up the CommandBox shell, and then you can enter commands like

$ server list

 

without needing to prefix it with box for each command.

I am going to assume you ran box first, now we do not need to prefix it.
The command we just used is a built in command, and you can see all the server commands are namespaced in the server namespace. For this example I’m going to make a set of commands in the kiwiSays namespace. Our goal is to make some commands like this

$ kiwiSays addWebsite param1 param2
$ kiwiSays startLucee
$ kiwiSays stopLucee

 

So, how do we make our own commands in CommandBox?

CommandBox when run, installs into your user directory, in a hidden folder… called CommandBox. Inside that folder, is a folder for you to add your own commands, called Commands. Anything you put in there, will get read on start up of CommandBox and be available to run. Folders create namespaces… so if we want to make a namespace called kiwiSays, we make a folder in /Users/Gavin/.CommandBox/Commands/kiwiSays/

Inside of that folder, we put any actual commands we want to run. Of course, we do not have to namespace them, but that would be a mess. If we want to have a few levels deep, we could too, but we don’t want to make things too difficult… so lets just leave it as this.
Now, a command is just a cfc… so lets add 3 cfcs into our folder

/Users/Gavin/.CommandBox/Commands/kiwiSays/
addWebsite.cfc
startLucee.cfc
stopLucee.cfc

Inside of those 3 cfcs, to be commands, we simple need to do 2 things… make sure the component extended the BaseCommand, and has a function called run().
As simple as

component extends="commandbox.system.BaseCommand" {
     function run() {
          print.line( ‘Hello World’);
     }

}

 

You can copy that template into each of the 3 cfcs, and modify the comments that print.line prints to the command line, and we can restart CommandBox, and try them out.

$ kiwiSays addWebsite
$ kiwiSays startLucee
$ kiwiSays stopLucee

 

Tada, you built your first commands. Awesome, my job is done.

Wait, you want to learn more than that? Ok, he’s a little more.

So, lets make your code a little better… in the addWebsite command, we want to ask for a websiteURL, and a websitePath.
So lets do that.

//addWebsite.cfc
component extends="commandbox.system.BaseCommand" {
function run( ){
        var websiteURL = ask('Please enter URL: ');
        var websitePath = ask('Please enter file path: ');
               print.line(‘The URL is: ‘ & websiteURL);
               print.line(‘The Path is: ‘ & websitePath);
     }
}

 

Now, when you reset CommandBox and run the following command
$ kiwiSays addWebsite

We get this output, I added the responses as it prompted me, line by line.

$ kiwiSays addWebsite
Please enter URL: www.gpickin.com
Please enter file path: /www/www.gpickin.com
The URL is: www.gpickin.com
The Path is: /www/www.gpickin.com

 

Now, thats pretty cool, we can use the Ask function to ask for info… but it would be nice if we could use tab completion in our paths, right?
Well, unfortunately, you can’t do that in the Ask function currently… but… you can at the command line… so lets change those 2 asks, into arguments.

// addWebsite.cfc
component extends="commandbox.system.BaseCommand" {
      function run( required string websiteURL, required string websitePath ){
           print.line('The URL is: ' & websiteURL);
           print.line('The Path is: ' & websitePath);
     }
}

 

So restart CommandBox and run our command with the 2 arguments

$ kiwiSays addWebsite www.gpickin.com /www/www.gpickin.com
The URL is: www.gpickin.com
The Path is: /www/www.gpickin.com

 

Very cool, and if you try it, tab completion works.
Note: you can do ordered arguments, or named, so thats pretty slick.

EDIT: I just found out that they have some built in tools to help with paths, so I will go ahead and add this to the code, to resolve the path, so you can use relative or full paths.
arguments.websitePath = fileSystemUtil.resolvePath( arguments.websitePath );

What if people don’t know you need to add the arguments, and run it without them… will it error?
No, CommandBox sees they are required, and prompts you for them… slick or what?
So lets see what that looks like.

$ kiwiSays addWebsite
Enter websiteURLwww.gpickin.com
Enter websitePath/www/www.gpickin.com
The URL is: www.gpickin.com
The Path is: /www/www.gpickin.com

 

Well, that is cool, but its ugly, its showing the variable name, no spacing… wouldn’t it be cool if… yes, yes it would be, and it is. You can use javadoc annotations to give hints to the arguments, and those same hints power the awesome HELP features too. This is how we add that.

component extends="commandbox.system.BaseCommand" {
        /**
* @websiteURL.hint The Website URL
* @websitePath.hint Path to the Website Directory
*/
    function run( required string websiteURL, required string websitePath ){
        arguments.websitePath = fileSystemUtil.resolvePath( arguments.websitePath );
        print.line('The URL is: ' & websiteURL);
        print.line('The Path is: ' & websitePath);
    }
}

 

Now, restart and run again, and lets see what that does.

$ kiwiSays addWebsite
Enter websiteURL (The Website URL) :www.gpickin.com
Enter websitePath (Path to the Website Directory) :/www/www.gpickin.com
The URL is: www.gpickin.com
The Path is: /www/www.gpickin.com

 

That is much better. It still shows the argument name, but thats ok, if its a terrible argument name, change it… but the hint works.
What about the help I mentioned… lets see how that looks.

$ kiwiSays addWebsite help
**************************************************
* CommandBox Help for kiwiSays addWebsite
**************************************************

kiwiSays addWebsite

Arguments:
required string websiteURL (The Website URL)
required string websitePath (Path to the Website Directory)

 

Ok, what if they want help for the whole namespace?

$ kiwiSays help
**************************************************
* CommandBox Help for kiwiSays
**************************************************
Here is a list of commands in this namespace:
kiwiSays addWebsite
kiwiSays startLucee
kiwiSays stopLucee

 

To get further help on any of the items above, type "help command name".
Impressed yet?

After using linux, and bash, I’m just loving how easy this is, its fast, and we have only scratched the surface. 
Lets jump ahead a little bit, and do something useful.

Thats pretty cool, simple, but cool. So now, lets output a Virtual Host for Apache. We’ll use the same arguments, but output a Virtual Host Definition.

// addWebsite.cfc
component extends="commandbox.system.BaseCommand" {
/**
* @websiteURL.hint The Website URL
* @websitePath.hint Path to the Website Directory
*/
function run( required string websiteURL, required string websitePath ){
          var apacheConf = "";
          arguments.websitePath = fileSystemUtil.resolvePath( arguments.websitePath );
          apacheConf = apacheConf & '<virtualhost :80="">';
          apacheConf = apacheConf & 'DocumentRoot "#websitePath#"';
          apacheConf = apacheConf & 'ServerName #websiteURL#';
          apacheConf = apacheConf & 'Include /www/_servers/conf/inc_lucee_conn.inc';
          apacheConf = apacheConf & '</virtualhost>';
          print.line().line( apacheConf );
     }
}

 

Just a simple Virtual Host, we use our websitePath for the DocumentRoot, we use the websiteURL for the ServerName, and I have an include in there which would contain my Lucee Connection Information (I’m planning ahead). Lets run it and see what happens.
Without arguments

$ kiwiSays addWebsite
Enter websiteURL (The Website URL) :www.gpickin.com
Enter websitePath (Path to the Website Directory) :/www/www.gpickin.com
<virtualhost *:80>
ServerAdmin myemail@mydomain.com
DocumentRoot "/www/www.gpickin.com"
ServerName www.gpickin.com
Include /www/_servers/conf/inc_lucee_conn.inc
</virtualhost>

 

With arguments and tab completion for the path :)

$ kiwiSays addWebsite  www.gpickin.com /www/www.gpickin.com
<virtualhost *:80>
ServerAdmin myemail@mydomain.com
DocumentRoot "/www/www.gpickin.com"
ServerName www.gpickin.com
Include /www/_servers/conf/inc_lucee_conn.inc
</virtualhost>

 

So, you can copy and paste that into your httpd.conf or you could put it in a virts.conf file… or if you read my previous article, I make a directory for all my individual Virtual Host conf files, and then use the following line in my httpd.conf file to include them all
//httpd.conf - bottom of the file

Include /www/apacheconfs/*.conf

So you could copy from the CLI and then paste them into a new file called www.gpickin.com.conf in that folder… but why do all that work, when the command can do that. 
How long would that take you in Node, or Bash? 
I don’t know, but I’ll tell you how long with CFML… 1… 2… done!

// addWebsite.cfc
component extends="commandbox.system.BaseCommand" {
         
        /**
* @websiteURL.hint The Website URL
* @websitePath.hint Path to the Website Directory
*/
    function run( required string websiteURL, required string websitePath ){
        var apacheConf = "";
        arguments.websitePath = fileSystemUtil.resolvePath( arguments.websitePath );
        apacheConf = apacheConf & '<virtualhost *:80>#CR#';
        apacheConf = apacheConf & 'ServerAdmin myemail@mydomain.com#CR#';
        apacheConf = apacheConf & 'DocumentRoot "#websitePath#"#CR#';
        apacheConf = apacheConf & 'ServerName #websiteURL##CR#';
        apacheConf = apacheConf & 'Include /www/_servers/conf/inc_lucee_conn.inc#CR#';
        apacheConf = apacheConf & '</virtualhost>#CR#';

        print.line().line( apacheConf );
        fileWrite( '/www/apacheconfs/# websiteURL#.conf', apacheConf );
    }
}

 

Restart CommandBox and run it, and hey presto… file created, with the #CR# it even inserted the OS's carriage return for me so it formatted nicely, you can open it up and see it. 
Awesome, simple, easy to write, easy to use… if it restarted Apache, it would be the ultimate command. So I’ll show you how to do that.
Of course, you have to make sure you can stop and start apache without having to add a password, so you could just add your user to the SuDoers file like this SuperUser.com post mentions.
http://superuser.com/questions/381337/passwordless-sudo-apachectl

Running a shell command from inside of CFML, not easy normally right? Well, we are in a turbo charged shell, like Ask and print.line() we have a lot of tools at our command, read the docs for more info, but we can run a command, so lets do that.
In a normal shell we would do this:

$ sudo apachectl restart

In commandbox’s shell, we would do the following:
$ run ‘sudo apachectl restart'

From a command running in command box’s shell, we need to do this
$ runCommand( “run ‘sudo apachectl restart’”);

So it looks like this

// addWebsite.cfc
component extends="commandbox.system.BaseCommand" {
         
        /**
* @websiteURL.hint The Website URL
* @websitePath.hint Path to the Website Directory
*/
    function run( required string websiteURL, required string websitePath ){
        var apacheConf = "";
        apacheConf = apacheConf & '<virtualhost *:80>#CR#';
        apacheConf = apacheConf & 'ServerAdmin myemail@mydomain.com#CR#';
        apacheConf = apacheConf & 'DocumentRoot "#websitePath#"#CR#';
        apacheConf = apacheConf & 'ServerName #websiteURL##CR#';
        apacheConf = apacheConf & 'Include /www/_servers/conf/inc_lucee_conn.inc#CR#';
        apacheConf = apacheConf & '</virtualhost>#CR#';

        print.line().line( apacheConf );
        fileWrite( '/www/apacheconfs/# websiteURL#.conf', apacheConf );
        runCommand( "run 'sudo apachectl restart’" );

    }
}

 

Restart commandbox, and now, we run our command, and as well as output to the screen, and write a file, it now restarts apache for us.
Its taken me a lot longer to write this post than just to build the whole thing.

Now, me being me, and you being you, you probably saw a lot of things in there that aren’t perfect. If I was going to release this command onto forge box, it wouldn’t work for most people, since i hardcoded paths, etc… so thats not very useful. You are right, but I could pass those in as params, or better yet, have defaults set in a json file that my command reads, and uses them, so you could modify the json, or, I could make a command to save settings in the json.

All good answers, but what I plan on doing is this… if you try to use a command that needs a setting, that isn’t set yet, I can ask you for it the first time, and then save it in the json for future requests, unless you override it in a one off command, or set a new default with a settings namespace of commands.

I think we did pretty good today… we have a useful tool built, in minutes, next time, we’ll build commands for startLucee and stopLucee, and we’ll call them from our addWebsite command, after producing the XML snippet we need for Tomcat.

If you don’t think that is cool enough, maybe I’ll make a new command that does the following

  • Check if the directory you enter exists, if not, create it.
  • Install ColdBox to that directory
  • Create the Apache Conf
  • Restart Apache
  • Create the Lucee XML
  • Restart Lucee
  • Launch a Browser and point it at that URL and see your new Coldbox app installed and running.

 

See the power in CommandBox yet?

Maybe you’re thinking, I don’t use ColdBox… well, you’re right… because we don’t use ColdBox for everything we do, but we use some type of template. What about some Git Integration to pull down a Template for your company… maybe choose a Starter Template of your own… the power is in your hands, and with it being as simple as CFML, but as powerful as a CLI… the options are endless.

If you didn’t follow along, try it out, its pretty cool to spin up something so quick, with no real learning curve.
Its better than I thought, and I’ve only played with it for a couple of hours… I wonder what I can build with some time.

Thanks for reading… start playing today.
 

03
February 2015

Gavin Pickin

Adding Lucee Connection Configuration so Apache can Serve Lucee Sites

Apache, CFML Server, Lucee, Server Admin

Working with Apache can be daunting for some, simple for others, we all have our ways to handle it. I really like having individual conf files for each site, to make it easy to update one VirtualHost at a time, and if I want to zap a site, or duplicate it, or automate it, its just simple file changes, I don’t need to parse a whole file.

I manage connections in a similar way, each connection type, CF9, CF10, CF11, Railo, Lucee, would all have its own connection file, that I can include in each of the Virtual Hosts. Easy to manage, update in one file, it extends to all hosts using that include, and of course, keeping it out of your main httpd.conf or the main folder structure helps for ease of update, and gives you automation options etc too. So lets look at how I do it.

I usually setup a folder for all my included conf files, for ColdFusion, Railo, and now Lucee, and inside of that same folder, I’ll make one for {{ServerConf}}/apache. Inside of that folder is each Sites own conf file, named www.domainname.com.conf. In my main include folder {{ServerConf}} I will have files for each connector, inc_lucee_conn.inc and inc_cf9_conn.inc etc. I am assuming you have your other engines under control, I am going to focus on Lucee today. If you need help with the other engines, look at my presentation on multi engine environments, or look through some of my other blog posts.

What do we put in the inc_lucee_conn.inc file?

<Proxy *>
Allow from 127.0.0.1
</Proxy>
ProxyPreserveHost On
ProxyPassMatch ^/(.+\.cf[cm])(/.*)?$ ajp://localhost:8024/$1$2

If you have a different AJP port… well, then you can update the port from 8024 to something else. Pretty straight forward, nothing special here, using a standard AJP port, matching an expression, and now, if we put this in any Virtual Host in apache, any .cfm / .cfc will route the request to Lucee. If you have your server.xml setup with a host pointed at the right location, your site will be served. Before we can do that, lets work on the other inc files, and how we get the includes into the httpd.conf file.

For simplicity sake, I always put my includes at the bottom of these conf files… they can get very long, so usually, thats the easiest place to put them. To include our Apache Virtual Hosts, we can just tell Apache to include all out *.conf files in the {{ServerConf/apache/ folder by adding this to the bottom of our httpd.conf file. Unlike xml, the conf files just end, so you can put this at the VERY BOTTOM without any issues.

#Load Virtual Hosts {{ServerConf}}/apache/*.conf
Include /www/_servers/conf/apache/*.conf

Now we have our virtual hosts being loaded, lets make one for our next Lucee site, and get it hooked up.
In the last post, I showed you how to setup an xml include for lucee hosts, so we’ll set one up for that. The xml gives us the details we need for apache too.

<Host name="justmockit.local.com" appBase="webapps">
     <Context path="" docBase="/www/JustMockIt"></Context>
</Host>

So the equivalent apache Virtual Host will be as follows

<VirtualHost *:80>
          ServerAdmin          myemail@mydomain.com
          DocumentRoot      "/www/JustMockIt/"
          ServerName          justmockit.local.com
          Include                     /www/_servers/conf/inc_lucee_conn.inc
</VirtualHost>

ServerAdmin email is your email
DocumentRoot is the website root, accessible by apache
ServerName      Accessible URL
ServerAlias        If you would like to use more than just the ServerName as the only url, you can add multiple ServerAlias
Include               We’re going to point to our inc_lucee_conn.inc file.

Restart Apache, and ta-daa, its working.

 

02
February 2015

Gavin Pickin

Adding Goodies to Server.xml to make life easier with Lucee

CFML Server, Lucee, Server Admin

As I mentioned in my last post, where we started installing and setting up Lucee, a lot of the setup here is repeated (for the most part) from the Multi Engine Environment blog posts, and presentation I did at last years CF.Objective() which is now known at Dev.Objective(). We looked at installing Lucee, and changing the HTTP Port, AJP Port, and the Shutdown port already, now, lets dive deeper into the Server.xml file, and make it easier to manage going forward.

Depending on your system, server.xml for your installation is not easily accessible, you usually have to sudo open it, and if you want to script setup into it, its just difficult. One of the first steps I do with an Engine like this, is use an Include for additional sites / hosts, similarly to how you do it in Apache. Apache has its own method Include you can use, but server.xml is standard xml, so we can use those tools.

At the top of your server.xml, found in {{ServerDir}}/conf/ you will see the following opening XML Tag… right about the License comments.

<?xml version='1.0' encoding='utf-8'?>

What we are going to do, is declare an xml variable here, known as entity, and point it to an xml file. This will load the xml from that file, and store it in the entity, and we can use that variable/entity elsewhere in the file. So lets add a few lines right below that first line.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE server-xml [
  <!ENTITY vhosts-config SYSTEM "file:///www/_servers/conf/inc_lucee_hosts.xml">
]>

SO here, you can see our variable / entity is called “vhosts-config” and we’re loading inc_lucee_hosts.xml from a file location. I keep all of my conf files in a general location… so apache virtual confs, apache inc files for engine connectors, worker.properties files for Adobe ColdFusion, but you can organize it how you see fit. I just make sure its somewhere I can easily edit and save, and I can make accessible for automation if i want. I built a simple editing tool, for outputting conf files from a database, but the UI is in limbo, if I finish it, I will release it.

PLEASE NOTE: There are three forward slashes, file:// is the resource location prefix, then the path is /www/_servers/conf so if you combine them, its file:///www/

The inc_lucee_hosts.xml file looks like this.
<Host name="justmockit.local.com" appBase="webapps">
     <Context path="" docBase="/www/JustMockIt"></Context>
</Host>
<Host name="meetthefamily.local.com" appBase="webapps">
     <Context path="" docBase="/www/ITB2014-Meet-The-Family"></Context>
</Host>

This is just simple Host configs that go further down the server.xml file. Anytime you want to add a new Site, you can just add the config here. Usually I place my includes at the bottom of the Engine container… so essentially, 3-4 lines from the bottom. The bottom of my Lucee server.xml file fresh from install looks like this.


    <Engine name="Catalina" defaultHost="localhost">
      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->
      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->
        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

As you can see, there is one HOST container defined, it is the localhost, with appBase set to web apps, and includes some comments, and a valve. Instead of editing this file every time we want to add a new Host, we want to edit the inc_lucee_hosts.xml file, and have that variable / entity definition we created at the top of the file allow us to include those hosts automatically.
So below the </Host> we want to make a little space, and add output the contents of that variable / entity, i.e. the file.
 
  &vhosts-config;
    </Engine>
  </Service>
</Server>

Now, whenever you start your Lucee server, the Host containers will be inserted into your Server.xml without needing to touch it again.
 

01
February 2015

Gavin Pickin

Setting up Lucee in my Dev Environment - Changing Ports

CFML Server, cfObjective, Lucee, Migrating to Railo, Server Admin, Tools and IDEs

A while back now, I released a series of posts on setting up Apache along with  Railo, ColdFusion, in a multi engine setup, including some ways to make it easier to maintain virtual hosts in Apache, and Railo. Now, I’m getting the Lucee Express setup on my Dev environment, so I thought it would be a good time to rehash some of that, and see whats different, or what I’m doing differently these days.

Lucee was just announced a few days ago, so the Express is designed for all OSes, the installers are in the queue, but they have not been released yet, so this does not cover an installer options. We’re assuming you went to www.lucee.org and clicked on downloads, and downloaded and unzipped the Lucee Express Folder.

For the sake of simplicity, I’m going to set a few blog variables
{{ServerDir}} - Home Directory for the Lucee Express Directory

I’m running on Mac OSX, so unless you’re on Windows, most of these commands should line up similarly.

I open up my terminal and browse to 
{{ServerDir}}/bin

Then run
./startup.sh

The default port is 8888 so I open a browser, and type in the following:
http://127.0.0.1:8888

Hey PRESTO - Lucee is up and running, and you can see the prettier start page… shown below.



Diving into the Lucee Configuration - 3 ports to configure.

Not usually an issue with conflicts, but depending what you intend to run… you might need to consider a naming convention. Last year I spoke at CF.Objective() about setting up a multiple engine environment, so I’m going to steal a little info from there to see what ports CF10 and CF11 default to.
I usually use a system with these ports, so it makes sense and you reduce conflicts. There are 3 types of ports.

HTTP Port
This is the port you add to the browser to view sites using this server. For example, above i browsed to 127.0.0.1:8888 to view the Lucee startup page. CF9 CF10 and CF11 usually default to 8500, and Railo is 8080 or 8500 depending on the install you have. 
To be safe, I usually use 8500 + Version. Since Lucee is starting at 4.5 I’m going to assign Lucee 4.
CF9 would be 8509
CF10 would be 8510
CF11 would be 8511
Railo would be 8501
Lucee would be 8504

AJP Port
This is the port that Apache or nginx would communicate on, for passing requests from the web server through to the Servlet engine. This is commonly 8009 for Railo / Lucee, CF10 is 8012, and CF11 is usually 8014, so again I assign a numbering convention.
AJP Ports are 8020 + Version
CF9 would be 8029
CF10 would be 8030
CF11 would be 8031
Railo would be 8021
Lucee would be 8024

Shutdown Port
This is the port that the CFML Servlet listens to, for stopping and restarting the engine… this is obviously vitally important as the other 2, so we’ll implement a numbering system for them too.
Shutdown port is 8000 + Version
CF9 would be 8009
CF10 would be 8010
CF11 would be 8011
Railo would be 8001
Lucee would be 8004

If you want to learn how to adjust all the other CFML engines, you can look up my previous posts, and pull up my slides… available at www.gpickin.com/cfo2014/

Lets update Lucee to follow my numbering system.

First, run the following to shutdown lucee
{{ServerDir}}/bin/shutdown.sh

Edit {{ServerDir}}/conf/server.xml

HTTP Port
Approximately line 69 you will see the following line
<Connector port="8888" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

Update the port to 
<Connector port=“8504" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

AJP Port
Approximately line 91 you will see the following line
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

Update the port to 
<Connector port="8024" protocol="AJP/1.3" redirectPort="8443" />

Shutdown
Approximately Line 22 you will see the following line
<Server port="8005" shutdown="SHUTDOWN">

Update to 
<Server port="8004" shutdown="SHUTDOWN">

Once you have made these changes, save server.xml

If you forgot to shut down the server before making the changes, and you run the shutdown.sh command now, it will try and shut lucee down on the new port, where its not listening, so you can force shutdown or reset the port temporarily.

Then, run the following to startup lucee with the new settings
{{ServerDir}}/bin/startup.sh

If you still have lucee’s startup page open, on 127.0.0.1:8888 reload the browser, and you’ll see no response.
Change the port to 8504 and you’ll see the startup page, running on the new http port.

Check back in the next posts for how to make the Server.xml file easier to add sites with includes, and adding config for Apache Virtual Sites.

Thanks for reading.
 

Blog Search