Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
One of the most useful features of CommandBox is the ability to start an ad-hoc server quickly and easily. Any folder on your hard drive can become the web root of a server. To start up the server, cd into a directory containing some CFML code, and run the start command. An available port will be chosen by default and in a few seconds, a browser window will open showing the default document (index.cfm).
To stop the embedded server, run the stop command from the same directory.
You can start as many embedded server instances as you want. Each running server will add an icon in your system tray with the logo of your currently running engine. Click on it for options:
Stop Server
Open Browser
Open Admin
Open File System
If you don't want the tray integration, then you can turn it off in your server.json with this setting.
Or turn it off at a global level in your config settings.
CommandBox's embedded server does not require any prior installations of any CFML engine to work. It does not use Apache, IIS, or Nginx. A very lightweight Java web server called is used and a context is programmatically deployed via a WAR file.
You should still have all the options you need to set up most local development servers quickly. The web-based administrator is available to you where you can edit any setting, add data sources, CF mappings, and mail servers. To see a list of all the parameters you can pass to the server start command, refer to the or run server start help command directly from the CLI.
Any ComandBox environment variables present in the shell will automatically be passed to the environment of the server process. This means, given an example like this:
The CFML code running that server process will be able to "see" the foo environment variable.
CommandBox> cd C:\sites\test
CommandBox> startCommandBox> stopserver set trayEnable=falseconfig set server.defaults.trayEnable=falseset foo=bar
server startYou can specify the CFML engine via the command line arguments:
This will start an Adobe ColdFusion 2018 server in your webroot. That's it!
By default, CommandBox uses the cfengine slug to search for the engine on ForgeBox. The format is slug@version where the version is optional. Ortus Solutions maintains the versions of the engines available on ForgeBox.
Supported engines are:
Adobe ColdFusion 9 **
Adobe ColdFusion 10
Adobe ColdFusion 11
Adobe ColdFusion 2016
Adobe ColdFusion 2018
Adobe ColdFusion 2021
Railo 4.2
Lucee 4.5
Lucee 5
Here are some examples:
Engines are downloaded and stored in your CommandBox artifacts folder. You can view your engines and clear them using the standard artifacts commands:
** Note: . To run ColdFusion 9 you must use an older version of CommandBox 3.x on Java 7 or run CommandBox 4.x on Java 8 update 92 or earlier. Several people are doing this, but beware your mileage may vary.
While Lucee asks for a password the first time running the admin, ColdFusion requires a username and password when CommandBox sets it up. The default username and password for the Adobe ColdFusion servers used are:
Username: admin
Password: commandbox
Additionally, CommandBox can start any WAR given to it using the WARPath argument.
If you run a regular start command inside of a folder that has a /WEB-INF/web.xml file, CommandBox will treat that folder as a WAR.
The cfengine parameter can accept any valid CommandBox endpoint ID. That means it can be an HTTP URL, a Git repo, a local folder path to your company's network share, or a custom ForgeBox entry you've created. As long as that endpoint resolves to a package that contains these files, you're good:
box.json
Engine.[zip|war] (file name doesn't matter)
CommandBox will download the package, unzip it and use the WAR/zip file as the engine for your app.
Normally, the artifacts cache isn't used for non-ForgeBox packages, but CommandBox will only download the engine once per server and then assume the file hasn't changed. You will need to forget the server to trigger a new download.
Here's an example of starting up a web server using a direct download link to a package containing a WAR file:
You can set the cfengine and other related configuration options in your server.json to use them every time you start your app.
These commands would create the following server.json
Just a reminder that starting a server with any command line arguments will save the arguments to your server.json by default.
This command would add adobe@9 to your server.json. If this is not what you want, you can append saveSettings=false or even --!saveSettings when you start your server and CommandBox will not save the arguments you specify to your server.json.
CommandBox> start cfengine=adobe@2018# Start the default engine
CommandBox> start
# Start the latest stable Railo engine
CommandBox> start cfengine=railo
# Start a specific engine and version
CommandBox> start [email protected]
# Start the most recent Adobe server that starts with version "11"
CommandBox> start cfengine=adobe@11
# Start the most recent adobe engine that matches the range
CommandBox> start cfengine="adobe@>9.0 <=11"CommandBox> artifacts list
# Removes all adobe servers currently in the artifacts
# These servers will need to be re-downloaded the next time they are started
CommandBox> artifacts remove adobeCommandBox> start WARPath=/var/www/myExplodedWAR
CommandBox> start WARPath=/var/www/myWAR.warCommandBox> start cfengine=http://downloads.ortussolutions.com/adobe/coldfusion/9.0.2/cf-engine-9.0.2.zipCommandBox> server set app.cfengine=adobe
CommandBox> server set app.WARPath=/var/www/my-app{
"app":{
"cfengine":"adobe",
"WARPath":"/var/www/my-app"
}
}CommandBox> start cfengine=adobe@9It's important to note that each server you start opens a new Java process on your host operating system. This allows each server to have it's own settings and configuration independent of any other server. Start as many as you need and simply stop them when you're done. Just keep in mind each server gets its own heap space so keep an eye on your available RAM.
The embedded server instances are also a separate process from the actual CommandBox CLI process, which also runs on Java. This means you can open the interactive shell, start a few servers, then quit the shell, yet the servers will still continue to run. You can use the CLI to issue a stop command in the servers web root, or just right click on the tray icon.
There is currently no way to have servers start automatically when your computer boots, though there's nothing preventing you from setting up a local script to run the start commands for you.
You may be used to having your server's WEB-INF folder living in your web root. The CommandBox embedded server still has a dedicated WEB-INF folder for each server you start, but it lives under the main CommandBox installation directory in your user folder. Changes you make to the WEB-INF such as adding jars or new tas will be persisted until you issue a server forget command.
The Undertow-based web server built into CommandBox will only serve up static files if they are in a list of valid extensions. This is to prevent prying eyes from hitting files they shouldn't be able to access on your server.
The current list of valid extensions is:
3gp,3gpp,7z,ai,aif,aiff,asf,asx,atom,au,avi,bin,bmp,btm,cco,crt,css,csv,deb,der,dmg,
doc,docx,eot,eps,flv,font,gif,hqx,htc,htm,html,ico,img,ini,iso,jad,jng,jnlp,jpeg,jpg,
js,json,kar,kml,kmz,m3u8,m4a,m4v,map,mid,midi,mml,mng,mov,mp3,mp4,mpeg,mpeg4,mpg,msi,
msm,msp,ogg,otf,pdb,pdf,pem,pl,pm,png,ppt,pptx,prc,ps,psd,ra,rar,rpm,rss,rtf,run,sea,
shtml,sit,svg,svgz,swf,tar,tcl,tif,tiff,tk,ts,ttf,txt,wav,wbmp,webm,webp,wmf,wml,wmlc,
wmv,woff,woff2,xhtml,xls,xlsx,xml,xpi,xspf,zip,aifc,aac,apk,bak,bk,bz2,cdr,cmx,dat,
dtd,eml,fla,gz,gzip,ipa,ia,indd,hey,lz,maf,markdown,md,mkv,mp1,mp2,mpe,odt,ott,odg,
odf,ots,pps,pot,pmd,pub,raw,sdd,tsv,xcf,yml,yaml If you have a common static file you need to serve, you can add your own custom extensions to the list like so:
server set web.allowedExt=jar,exe,dllHere are some settings for performance tuning your servers
This setting limits how many requests will be passed through the Undertow listener to your app server. It defaults to 30. Please note that your web server connector and Adobe ColdFusion may also have their own max request setting.
server set web.maxRequests=100Or as a global setting for all servers:
config set server.defaults.web.maxRequests=100CommandBox allows you full control over the servers you start. This includes the port and host, custom JVM args, URL rewriting, web aliases, custom error pages, and custom welcome files.
Configuration can be set at several different levels:
Passed as parameters to the server start
You can customize the error page that CommandBox servers return. You can have a setting for each status code including a default error page to be used if no other setting applies.
Create an errorPages object inside the web object in your server.json where each key is the status code integer or the word default and the value is a relative (to the web root) path to be loaded for that status code.
This is what you server.json might look like:
You can set error pages via the server set command like this:
If a server isn't starting, the first thing to run is the server log command. It will show you the console log for that server. Note, this dumps the entire log file to the console, which may be very large. We recommend using the tail or --follow tricks below.
If the log is very large, use the tail command to just see the last few lines of it.
CommandBox's web server supports enabling Basic Auth on your sites.
That will create the following data in your server.json, which will be picked up the next time you start your server.
And to test/debug your rules, start your server with the trace flag and tail the console output. Every hit in your browser will output several lines of debugging for each rule that is processed.
With the custom rule above, you'd see something like this:
CommandBox uses JBoss Undertow to power it's lightweight servlet containers. Undertow also powers JBoss Wildfly and has a lot of configurable options, not all of which have first-class CommandBox settings. These low-level settings come in two different categories:
Undertow Options - Settings that apply to the servlet and web server aspects of Undertow
XNIO Options - Part of the underlying XNIO library which powers all low-level I/O in undertow
If you have custom jar files that you want to be available to a server, we recommend you use the this.javaSettings functionality in your Application.cfc to load those jars. If that isn't an option for you, or you want to include libs for a JDBC drivers then we offer a feature for you to specify a list of directories for which CommandBox will load jars from. This prevents you from worrying about getting your jars inside the WEB-INF/lib which starts fresh anytime you forget a server.
To load in your jar files, the first method is to use the libDirs parameter to the server start command.
And the way to specify this in a portable manner in your `server.json` is like so:
Remember, paths to the start command are relative to your current working directory and paths in your
server.json allows you to package up an app that requires special start settings such as rewrites, JVM args, or heap size, and anyone can run it with the same settings you do by simply typing server start. Make sure to not deploy the server.json file to your production server where it may be web-accessible.
server.json outside the web rootTo help with this, you can store your
The default welcome files are the usual index.cfm, index.htm, index.html, etc but you can override this with the welcomeFiles setting in your server.json by providing a comma-delimited list of files that you would like CommandBox to look for when a user hits a directory on a running server.
This setting is a complete override of the defaults, so you need to specify the full list.
By default, a CommandBox server will not show the contents of a directory that doesn't have an index file. You can enable directory browsing for a single server with
Stored in a server.json file for that server
Global defaults in the server.defaults config setting
Internal defaults from the ServerService
Settings will be used in that order. Also, any parameters passed to the start command will automatically be saved to your server.json file unless you pass the --noSaveSettings flag.
A lot of settings used to start a server involve file paths. Paths starting with a drive letter like C:/, a UNC network path like \\, or a leading slash like / are considered absolute paths and will not be expanded. Try to avoid absolute paths if you want to make your server config portable.
Paths that start with a file/folder name like foo/bar.jar or ../../lib/my.jar are relative and the root folder that they are relative to depends on where there are specified.
If the path is passed as a parameter to the start command, the path is relative to the current working directory
If the path is in the server.json file, it is relative to the folder containing the JSON file. (Remember the server.json doesn't have to be in the web root!)
If the path is in a global server.defaults config setting, it is relative to the web root of the server.
server set web.basicAuth.enabled=true
server set web.basicAuth.users.brad=pass
server set web.basicAuth.users.luis=pass2{
"web":{
"basicAuth":{
"users":{
"brad":"pass",
"luis":"pass2"
},
"enabled":"true"
}
}
}server start --trace --console [DEBUG] requested: '/CFIDE/main/ide.cfm'
[TRACE] io.undertow.predicate: Path(s) [/CFIDE/main/ide.cfm] MATCH input [/CFIDE/main/ide.cfm] for HttpServerExchange{ GET /CFIDE/main/ide.cfm}.
[TRACE] io.undertow.predicate: Predicate [path( '/CFIDE/main/ide.cfm' )] resolved to true. Next handler is [done] for HttpServerExchange{ GET /CFIDE/main/ide.cfm}.
[TRACE] io.undertow.predicate: Predicate chain marked done. Next handler is [Runwar PathHandler] for HttpServerExchange{ GET /CFIDE/main/ide.cfm}.
[WARN ] responded: Status Code 200 (/CFIDE/main/ide.cfm)CommandBox is designed to allow you to start, stop, and manage as many servers as you like. However, when using CommandBox in an environment such as Docker containers where you only ever want to have a single server, this can cause issues where warming up the server with different names creates more than one server. You can enable Single Server Mode which will only allow CommandBox to have a single server that shows when you run the server list command.
config set server.singleServerMode=trueThis is a global setting that takes immediate effect. If you already have more than one server defined, it will not remove the extra ones, it will simply re-use the first server it finds. In this mode, the server name becomes essentially meaningless. Each of these commands would use the same default server
start name=foo
stop name=bar
restart name=bradThe built in REST implementation in Adobe ColdFusion and Lucee is usually something you either love or hate. If you love it, you can enable it and customize the paths so it doesn't collide with your app's routes. if you hate it, you can turn it off. The REST servlet will be disabled unless you include a setting like so:
server set app.restMappings=/rest/*,/api/*Note that the above setting will take over any URLs starting with /rest or api and you cannot use those routes or folders in your code. This is why it's handy to be able to modify or remove these. On a typical server, this is done via the web.xml, but CommandBox will do it all for you with just the setting above.
The web server in CommandBox is capable of enabling GZIp compression to reduce the size of HTTP responses. To enable GZip compress on your CommandBox server, add a web.gzipEnable setting in your server.json file.
server set web.gzipEnable=trueBy default GZip compression will be applied to any file over 1500 KB in size. This is because 1500 KB or smaller can fit inside a single network packet, so there's no real benifit in zipping small files and it just causes CPU overhead.
If you wish to customize the file size or any other aspect of when GZip compression is applied, you can specify a custom Undertow Predicate that, when true, will trigger GZip for the request.
server set web.gzipPredicate="request-larger-than(500)"Since ANY valid Undertow predicate language can be used here you can combined predicates to control exactly when GZip compression is applied. This example would apply GZip compression to any CSS files over 500 KB that were not in the /admin folder.
server set web.gzipPredicate="not path-prefix( admin ) and regex( '(.*).css' ) and request-larger-than(500)"You can set the starting heap size for the server (-Xms) by passing the minHeapSize parameter to the start command. This parameter defaults to megabytes but you can specify any valid suffix.
In server.json
You can specify ad-hoc JVM args for the server with the JVMArgs parameter.
In server.json
You can specify ad-hoc options for the underlying Runwar library using the RunwarArgs parameter.
In server.json
start heapSize=1024If your error page points to a CFM file, you can get access to the original path being accessed for 404s and the error that was thrown for 500s. To see all the request headers that are available, use the following snippet of code:
An example of getting the original missing path in a 404 in Lucee would look like this:
In Adobe ColdFusion, you can access ServletRequest Attributes directly via the CGI scope:
{
"web" : {
"errorPages" : {
"404" : "/path/to/404.html",
"500" : "/path/to/500.html",
"default" : "/path/to/default.html"
}
}
}server set web.errorPages.404=/missing.htmreq = getPageContext().getRequest();
names = req.getAttributeNames();
while( names.hasMoreElements() ) {
name = names.nextElement();
writeOutput( name & ' = ' & req.getAttribute( name ) & '<br>' );
}To get a live stream of the console log from a running server, use the --follow flag and the command will continue streaming new lines to the console until you press Ctrl-C to stop.
You can also look at your server's access log (if enabled) and rewrite log (if enabled).
You can use the --console flag to the server start command to start a server in the foreground. The console log will be live-streamed to the CLI and the log will continue streaming as long as the server is running. Press Ctrl-C to stop the server and stop streaming the log file.
You can get additional information about a server start with the --debug flag. When debug is set, the start command will not exit immediately, but wait for the server to come up and live stream the debugging information and server logs to the console while the server is coming up.
You may still really be having issues getting your server to start up correctly due to a setting not getting picked up, rewrites not working, or maybe a jar not loading. You can "drink from the firehose" so to speak by turning on trace level logging. This works best when starting the server via the console so you can watch the logging as it streams past.
server log
server log serverNameserver.jsonserver.jsonHave a bunch of servers and they ALL need the same jars, you can add your `libDirs` to the global server defaults config settings. Your global lib directories won't be overwritten by server-level config dirs, but instead appended to. Relative paths in your config settings are relative to the respective web root of the server. CommandBox will also ignore missing lib dirs to give you some flexibility in this.
server start libDirs=path/to/libs,another/path/to/libsserver set app.libDirs=path/to/libs,another/path/to/libs
server startconfig set servers.defaults.app.libDirs=/path/to/global/libsserver.jsonweb.webrootWhen you start the server, you can run the start command from the same directory that the server.json file lives, or specifiy the path to the JSON file like so:
If there is no web root in your server.json, CommandBox will use the folder that the JSON file is stored in. If there is no JSON file at all, the current working directory is used.
server set web.webroot=wwwstart /path/to/server.jsonAnd you can enable it for all servers by default with
server set web.welcomeFiles='go.cfm,main.cfm,index.html'server set web.directoryBrowsing=trueconfig set server.defaults.web.directoryBrowsing=trueserver set JVM.heapSize=1024
server set JVM.heapSize=2G
server show JVM.heapSizestart minHeapSize=1024server set JVM.minHeapSize=1024
server set JVM.minHeapSize=2G
server show JVM.minHeapSizestart JVMArgs="-XX:MaxGCPauseMillis\=200"server set JVM.args="-XX:MaxGCPauseMillis\=200"
server show JVM.argsstart RunwarArgs="--sendfile-enable false"server set runwar.args="--sendfile-enable false"
server show runwar.argsvar originalPath = getPageContext().getRequest().getAttribute( "javax.servlet.error.request_uri" );var originalPath = cgi[ 'javax.servlet.error.request_uri' ];server log | tail
server log | tail lines=100server log --followserver log --follow -access
server log --follow --rewriteserver start --consoleserver start --debug
server start --debug --consoleserver start --trace --consoleUndertow has its own set of options which can be found here:
To set an XNIO option that CommandBox doesn't already expose with a first-class setting, you can set them into your server.json like so:
You can also set global XNIO objects that will apply to all servers. Global options will be appended to server-level options.
XNIO (which is a refined version of NIO (Non-blocking I/O) has its own set of options that apply to the low level network transport functions it provides. You can find the full set of XNIO options here:
To set an XNIO option that CommandBox doesn't already expose with a first-class setting, you can set them into your server.json like so:
You can also set global XNIO objects that will apply to all servers. Global options will be appended to server-level options.
server set runwar.undertowOptions.ALLOW_UNESCAPED_CHARACTERS_IN_URL=trueconfig set server.defaults.runwar.undertowOptions.WORKER_NAME=myWorkerCommandBox bundles some custom predicates and handlers to make your life easier.
The predicate cf-admin() will returns true if the incoming URL is to the Lucee or ColdFusion admin:
cf-admin() -> set-error( 404 );
// Is the equivalent of
regex(pattern='^/(CFIDE/administrator|CFIDE/adminapi|CFIDE/AIR|CFIDE/appdeployment|CFIDE/cfclient|CFIDE/classes|CFIDE/componentutils|CFIDE/debug|CFIDE/images|CFIDE/orm|CFIDE/portlets|CFIDE/scheduler|CFIDE/ServerManager|CFIDE/services|CFIDE/websocket|CFIDE/wizards|lucee/admin)/.*', case-sensitive=false) -> set-error(404)
The handler block-external() blocks any request not from localhost with a 404 response code. You can pair this with any predicate you choose.
cf-admin() -> block-external()
// Is the equivalent of
cf-admin() -> ip-access-control( default-allow=false, failure-status=404, acl={ 127.*.*.* allow } ) The handler block-cf-admin() blocks any request to the Lucee or ColdFusion admin with a 404 response code.
block-cf-admin()
// Is the equivalent of
cf-admin() -> set-error( 404 ); You can build your own predicates and handlers by compiling java classes that implement the io.undertow.predicate.PredicateBuilder or io.undertow.server.handlers.builder.HandlerBuilder interfaces. If the proper service metadata is present in your jar's META-INF folder, undertow will automatically find and register your builders via Java's service loader.
This isn't super difficult but involves a few moving parts. If you're interested in writing your own handlers and predicates to use in your server rules, reach out on the mailing list and we'll walk you through it.
You can see the custom handlers and predicates documented above in our Runwar source code here:
Custom handlers:
Custom Predicates:
Every server setting can be overridden by convention by creating environment variables in the shell where you run box. This is idea for CI builds were you want to easily set ports, or tweak settings for your build. You set set these as actual environment variables or Java system properties of the CLI.
The var must start with the text box_server_ and will be followed by the name of the setting.
box_server_profile=productionFor nested settings inside of a struct or array you can use underscores to represent dots.
box_server_web_http_port=8080The overrides are applied using the same mechanism that the config set command uses, which means you can also pass JSON directly for complex values.
# JSON which will be parsed
box_server_web_ssl={ "enabled" : true, "port": 443 }On OS's like Windows which allow for any manner of special characters, you can provide any string which would also be valid for the config set command. Ex:
When you provide JSON, the append flag will be set to true when adding the configuration to what's already in CommandBox.
Overridden env vars will not be written to the server.json file and will be lost when box stops. They will also take precedence and override any explicit server.json settings already set but will NOT override actual parameters to the server start command.
CommandBox stores information about each of the servers you've ever started inside ~/.CommandBox/servers.json so it can remember settings from one run to the next.
You can see an overview of your servers and what state they're in with the server list command.
If you have many servers, you can provide parameters to help filter the results from server list
Sometimes you may wish to start a server on a computer that doesn't have access to the Internet. However, you may notice that running a command such as the following will throw an error trying to connect to ForgeBox:
That is because 5.x is a semver range and not a specific version. CommandBox must connect to ForgeBox to see what versions of the CF engine lucee can be found to use the latest one.
If you know that a CF engine is already downloaded in your server's artifacts directory, start your server with a specific major, minor, patch, and build version to skip the ForgeBox check.
Turning on SSL in your web server will will enable SSL without an approved SSL certificate. If you need an official certificate so you don't have to confirm your SSL connection you can add these entries
Although free certificates are available (e.g LetsEncrypt) this is not very convenient, because these certs are valid only for three months. Automatic renewal it is difficult if your dev site is not accessible from the web. For a few dollars a year (< 10) you can apply for a domain validated certificate from companies like Comodo, RapidSSL, Trustwave, Digicert, Geotrust and others or a reseller for these certs. For a domain validated certificate you need a valid domain which is under your control which means (depending on provider):
mail is sent to domain owner
or mail is sent to well-known administrative contact in the domain, e.g. (admin@, postmaster@, etc.)
When using a CommandBox web server in production, you may wish to force your users to visit your site over HTTPS for security (and for HTTP/2 to work). However, it is desirable to still have your web server listening on HTTP so a user just typing your address in his browser can still connect to HTTP and then redirect.
CommandBox can be configured to redirect all HTTP traffic over to HTTPS with the following rule. The redirect will use a 301 status code and will include the URL and query string. The redirect will only fire for GET HTTP requests since redirecting a form POST
There are many ways to pass environment variables into a server. You can set them in your actual OS shell before starting box, set them as CommandBox env vars, use the commandbox-dotenv module to read them from a .env file or many Docker-based options. Just in case you wanted one MORE way to do it, you can also set env vars directly in your server.json file.
These env vars will not be visible in the CommandBox shell like a .env file is, but will be used exclusively when starting the server. They will be visible inside the running server and also present in CommandBox to any interception points or CFConfig while the server is starting.
Note the two CFConfig examples above do the same thing (assuming you have commandbox-cfconfig installed. Any nested keys will be concatenated with underscores when the actual env var is set. Therefore the cfconfig key and nested requestTimeout
When using CommandBox on a staging or production server, you may wish to start up servers as a service when the OS comes online. The recommended approach is to use the , which is a commercial module that handles all major operating systems (Linux, Mac, Windows) automatically.
See screencast here:
Alternatively, you can manually do so following one of these community guides.
See screencast here:
When you start an Adobe or Lucee CF Engine, the WAR CommandBox uses has a stock web.xml baked into it. Sometimes you may want to add custom servlets, servlet mappings, etc into your server. You can override the stock web.xml in part or in total with a file of your own which you specify in the server.json like so:
The path can be absolute or relative to the server.json file. CommandBox will still load the default web.xml from the CF engine, and then it will load your override file on top of the previous settings. This means additional items in your override will be merged into the existing settings, and servlets with the same name as existing default servlets will be completely overridden and replaced.
Here is a list of all the top level items CommandBox will look for in your web.xml file:
server set runwar.XNIOOptions.WORKER_NAME=myWorkerconfig set server.defaults.runwar.XNIOOptions.WORKER_NAME=myWorker# dot-delimited keys
box_server_web.http.port=8080
# array indexes too
box_server_web_rules[1]=path-suffix(/box.json) -> set-error(404)
box_server_web_rules[2]=disallowed-methods(trace)To list only the servers that have been started in a given directory, use the --local flag.
You can take a quick look at the what's been happening with the server log command or use the server status command to see more detailed information including the arguments used previously to start/stop the server.
Servers are uniquely identified by their full path, but they also have a short name which defaults to the immediate folder containing their web root. The stop, start, etc commands can be run in the web root for a server, or in any working directory as long as you reference the server's short name.
Another handy shortcut is the server cd command that will change the current working directory of the interactive shell to the web root of a named server.
Info Server name is the first parameter to all server commands and tab completion works too, making it as easy as possible for you.
You can get information about a server using the server info command. Add the --JSON flag to get the data back in a JSON format. The property parameter will allow you to retrieve a single value for scripting mashups.
If you want to wipe all configuration, logs, and WEB-INF files for a server, use the server forget command. This will also remove any administrator settings you may have saved including data sources, mail servers, and server mappings.
You can forget all your servers at once too if you want to start with a clean slate. This command will stop and forget all servers.
You can easily forget all servers which have not been started for a certain period of time with the server prune command. It accepts the number of days that need to have passed since a server was last started in order to prune it.
You can also get back just a JSON representation of servers matching the filter with the --json flag. The JSON will be in the same format as the server list --json command.
NOTE: If this fails, check the location of the folder structure below the artifacts folder for it's exact path. e.g. /artifacts/lucee/5.0.0+252/lucee.zip - The box command for this would be: start [email protected]+252 This follows the pattern: /artifacts/[server-type]/[server-version]/[server-type].zip Useful if you've manually downloaded the file from forgebox and need to rename it.
If CommandBox needs to connect to ForgeBox to resolve a version number and ForgeBox is unavailable, it will look in your local artifacts cache to try and find a cached version of that CF engine that satisfies your semver range. This means you may not get the latest version of that CF Engine, but at least your server will start up.
start [email protected]start [email protected]+252or you can publish a DNS TXT record
So, now you have a valid domain, you have to generate a SSL key and a SSL Certificate Signing Request. With the CSR you can apply for the certificate. Generating a key and CSR with openSSL
This will generate output and some questions, and will finally result in a key file named dev_mydomain_com.key and a certificate signing request (csr) named dev_mydomain_com.csr
You have to enter Country Name, State and City. Organization Name is preferably the same as the domain owner. Organizational Unit Name will not be checked, so enter something simple such as ICT Common Name is the host name for your site, such as dev.mydomain.com You can skip Email Address and optional company name. For development you don't need a challenge password, which means your key file is NOT protected. But don't give this key to others or protect it with a challenge password. If you protect your key you have to server set web.SSL.keyPass=MyChallengePassword Now you have a CSR, which you can submit at your SSL provider. They will send you a certificate file (*.csr), and probably one or more intermediate certificates. Create a new my.csr file and copy everything from your certificate file into it, and append the intermediate certificate(s). Now you have a valid my.csr certificate file and a key file. Place both files in a location accessible for your CommandBox and enter the corresponding paths to web.SSL.certFile and web.SSL.keyFile
server set web.SSL.certFile=/path/to/dev_mydomain_ext.crt
server set web.SSL.keyFile=/path/to/dev_mydomain_ext.keyopenssl req -utf8 -nodes -sha256 -newkey rsa:2048 -keyout dev_mydomain_com.key -out dev_mydomain_com.csrOr in the server.json as:
If you want to customize how this redirect happens, you can skip this setting and manually add the following Server Rule, which is basically what the setting above does automatically:
If you want to go one step further, you can add a Strict-Transport-Security header to your site. This instructs the browser to automatically use HTTPS every time the user visits your site again. With an HSTS header, once your browser has cached the fact that you want HTTPS to always be used, even if the user just types your domain and hits enter, the browser will change it over to HTTPS before sending the request. This prevents having an initial HTTP request before the redirect kicks in.
HSTS headers can have a "max age" set, which tells the browser how long to "remember" to use HTTPS. This defaults to 1 year if you do not override the value. The max age is set in second. So 31,536,000 is one year. You can also set whether you want the HSTS header to apply to all sub domains of your site. The default is false for this setting.
Here is how you enable HSTS. Only the first web.SSL.HSTS.enable setting is required. The rest are optional.
Or in the server.json as:
The HSTS header is added via a Server Rule. Here is what the rule looks like in case you want to manually add the rule to customize it.
server set web.SSL.forceSSLRedirect=truecfconfig_requestTimeoutYou can see that the web.http.port is using an env var from the env block above it. All env vars in the env block will be added to CommandBox's environment BEFORE the rest of the JSON file is expanded. Env vars in the env block can ALSO reference other pre-existing env vars. In the example above, ${brad} is assuming there is a pre-existing env var of that name set outside this file.
In case anyone is wondering, it's actually possible to override your server.json settings from inside the env block like so:
but we can't imagine why you'd ever want to do that :) That would be the equivalent of setting the following env vars outside of CommandBox:
{
"name" : "My server",
"env":{
"brad":"wood",
"cfconfig":{
"requestTimeout":"1,2,3,4"
},
"cfconfig_secureJSON" : false,
"luis":{
"majano":"${brad}"
},
"myPort":"1234"
},
"web":{
"HTTP":{
"port":"${myPort}"
}
}
}Servlets
Servlet mappings
Servlet filters
Server filter mappings
Listeners
Context params
welcome files (only if not in server.json)
error pages (only if not in server.json)
mime types
session config
So if you wanted to replace the default servlet mapping for a Lucee server to also process .html files, you could use an override file like this:
The default behavior is to add or update existing configurations. If you want to remove a servlet or listener from the base file, you can enable the app.webXMLOverrideForce flag.
This will completely remove any configuration from the web.xml that is explicitly provided in your override file. For example, if the default web.xml specifies two servlet filters and you provide an override web.xml with one servlet filter and the force flag is true, both of the default servlet filters will be removed in favor of your one servlet filter from your override file.
If you need something more complex than this-- e.g. simply removing default settings without replacing them, you'll need to create a custom CF engine with a default web.xml of your own design.
server list
site1 (starting)
https://127.0.0.1:8081
C:\site1
site1 (running)
https://127.0.0.1:8082
C:\site2
site3 (stopped)
https://127.0.0.1:8083
C:\site3# All servers containing the word "foo"
server list foo
# Running servers
server list --runningserver list --localstart site1
start site2
restart site3
stop site2
stop --allserver cd site1
start
server cd site2
install myPackage
restartserver info
server info --JSON
server info property=serverHomeDirectory
server info property=consoleLogPathserver forgetserver stop --all --forgetserver prune days=30
# Skip the confirmation check
server prune --forceserver prune 100 --jsonYou are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:NL
State or Province Name (full name) [Some-State]:YourState
Locality Name (eg, city) []:YourCity
Organization Name (eg, company) [Internet Widgits Pty Ltd]:YourCompany
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:dev.mydomain.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:{
"web": {
"ssl" : {
"enable" : true,
"port" : 443,
"forceSSLRedirect" : true
}
}
}not secure() and method(GET) -> redirect('https://%{LOCAL_SERVER_NAME}%{REQUEST_URL}%{QUERY_STRING}' )server set web.SSL.HSTS.enable=true
server set web.SSL.HSTS.maxAge=31536000
server set web.SSL.HSTS.includeSubDomains=true{
"web": {
"ssl" : {
"enable" : true,
"port" : 443,
"HSTS" : {
"enable" : true,
"maxAge" : 31536000,
"includeSubDomains" : true
}
}
}
}set(attribute='%{o,Strict-Transport-Security}', value='max-age=31536000; includeSubDomains'){
"env":{
"box":{
"server":{
"web":{
"HTTP":{
"port":"8080"
}
}
}
},
"box_server_web_SSL_port" : "1443"
},
"web":{
"HTTP":{
"enable":true
}
}
}box_server_web_HTTP_port=8080
box_server_web_SSL_port=1443{
"app" : {
"webXMLOverride" : "path/to/web-override.xml"
}
}<?xml version="1.0" encoding="utf-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" metadata-complete="true" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<web-app>
<servlet-mapping>
<servlet-name>CFMLServlet</servlet-name>
<url-pattern>*.cfc</url-pattern>
<url-pattern>*.cfm</url-pattern>
<url-pattern>*.cfml</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>/index.cfc/*</url-pattern>
<url-pattern>/index.cfm/*</url-pattern>
<url-pattern>/index.cfml/*</url-pattern>
</servlet-mapping>
</web-app>server set app.webXMLOverrideForce=trueComing soon...
Create a .service file
as follows:
Start the service
Give the service about a minute to load up, then check its status
Once you've verified the service is running as expected, enable the service to load at boot
nano /usr/lib/systemd/system/mySite.serviceThere are endless combinations of predicates and handlers you can apply to your apps. Here's an assortment of examples to get you going. Many of these are contrived, but are just mean to show the range of syntax and functionality.
Rewrite a URL:
path('/healthcheck') -> rewrite('/healthcheck.cfm')Stop processing rules for a given request:
path(/healthcheck) -> done
path(/healthcheck) -> response-code(503) // This rule is skippedFor all GET requests, set a response header called type with a value of get
If the incoming path ends with .css it will rewrite the request to .xcss and set a response header called rewritten to true.
Redirect all jpg requests to the same file name but with the png extension. The ${1} exchange attribute is used to reference the first regex group.
Set a request header for all requests that you can access in your CFML app just like a normal HTTP header.
Set a Cache-Control response header only for default index pages(ie: index.html or index.cfm) in any folder.
Set a response header for a specific file.
Match certain SES-style URLs and store the place holders (referenced as exchange attributes) into HTTP request headers.
In this example, hitting the server with /restart skips the first rule, the second rule rewrites the request and then restarts back at the first rule which fires the second time through.
Block access to a URL unless coming from a specific IP.
For more control over IP address matches, use the ip-access-control() handler.
Leading slash is NOT required. Both of these rules are the same:
It is not required to include .*_ at the end of a regex path unless you’ve set full-match=true _
Perform a regex a case insensitive search like so:
When attribute values are not quoted, all leading and trailing whitespace will be trimmed. The following are all the same:
But this example is different. The leading and trailing spaces will be preserved in the path string.
Basic MVC rewrite:
Add a CORs header to every request
Rewrite requests to a sub folder based on the domain
Custom SES URL rewrite that turns 6 digit product code into a query string. (If this rule goes in your server.json, you'll need \\ in front of the dollar sign to escape it twice. Once for the system setting expansion and once for the JSON file.)
Reject requests using an unknown host header.
Create reverse proxy
By Default, your servers start using the same version of Java that the CommandBox CLI is using. For people needing to run Adobe ColdFusion 9, or who just want to do some testing on different JREs, you can point each of your servers at a custom JRE and CommandBox will use it when starting the server.
if you already have a JRE downloaded somewhere on your hard drive, you can manually point the server at it, or you can simply tell CommandBox which version of java you'd like, at it will automatically download that version of OpenJDK for your server to use (if it's not already downloaded)
Point CommandBox to an existing java install like so:
To set the default version of Java for all the servers you start on your machine, use the global config setting defaults.
To let CommandBox take over and acquire Java for you, pass an installation endpoint ID to the start command
or set it in your server.json
or set a default for all servers
To review what possible IDs you can use to dial in your exact Java version, read the . You don't need to manually install Java CommandBox will do that for you. You just need to provide a valid ID so CommandBox knows what you want.
In some cases you might not want to interact with the command line manually to setup an environment, in particular in production setups. If you prefer to setup your server via a server.json file, the same syntax for valid IDs applies to setting your JVM ID:
To make it easier for you to manage the Java installations CommandBox makes for you, we have a namespace of commands you can use. The Java versions CommandBox installs automatically for your servers to use are stored in a folder under your CommandBox home. CommandBox manages this folder for you. You can change where the system Java installation go like so:
Search the AdoptOpenJDk API for available versions of Java for you to use.
You can filter the version, jvm, os, CPU arch, type, and release. Most of those parameters default to match your local system. For instance, running this command on Windows will only return Windows versions. To open up the search, pass nothing to that filter.
List the installed Java installations for you to start servers with. If you have set a global default Java version it will be marked in the list.
You may change the global default Java version for your servers with this command.
The ID follows the format from the . If the version you set as the default isn't installed yet, CommandBox will install it for you the next time a server starts or you can use the --install flag.
You can pre-install a Java version so it's ready to go the next time you start a server with this command. This differs from the normal package install command in that it doesn't install to the current working directory, but into the core server JRE folder that CommandBox manages for you. Use the --setDefault flag to also set the newly installed Java version as the global default for all servers.
You can remove a java installation so it doesn't take up space on your hard drive. Use the FULL ID that shows in the java list command to uninstall.
Note, the download will still be in your artifacts cache. Also, if you start a server up again that asks for a Java installation you've uninstalled, CommandBox will simply re-install it again.
CommandBox has profiles you can assign to a server when you start it to configure the default settings. This is to provide easy secure-by-default setups for your production servers, and to make it easier to switch between a development mode and production mode.
There are 3 currently supported profiles. Custom profiles will be added as a future feature.
Production - Locked down for production hosting
Development - Lax security for local development
None - For backwards compat and custom setups. Doesn't apply any web server rules
You can set the profile for your server in your server.json
Which create this property
Or you can specify it when starting the server like so:
If a profile is not set, these rules are used to choose the default value:
If there is an env var called environment, it is used to set the default profile (same convention as ColdBox MVC)
If the site is bound on localhost, default the profile to "development". Localhost is defined as any IP address starting with 127.
If neither of the above are true, the default profile is "production
When profile is set to "production", the following defaults are provided:
web.directoryListing = false
web.blockCFAdmin = external
web.blockSensitivePaths = true
When profile is set to "development", the following defaults are provided:
web.directoryListing = true
web.blockCFAdmin = false
web.blockSensitivePaths = true
When profile is set to "none", the following defaults are provided:
web.directoryListing = true
web.blockCFAdmin = false
web.blockSensitivePaths = false
The defaults above only apply if you do not have am explicit server.json or server.defaults config setting. If you have an explicit setting, it will override the profile's default. Therefore, if you set the profile toproduction but set web.blockCFAdmin to false, your CF administrator will be public, but the remaining production defaults will still be applied. This allows even the default profiles to be customizable.
The start command will scan your system and find a random port that is not currently in use to start the server on. This ensures that multiple embedded servers can run at the same time on the same host without collisions. Ensure any redirects in your applications take the port into account.
You may want to set a specific port to use-- even port 80 if nothing else is using it. Pass the HTTP port parameter to the start command like so:
It is also possible to save the default port in your server.json. Add a
CommandBox servers have a method of locking down secure URLs and or implementing any of the Undertow predicate and handlers via a nice text based language. Undertow supports a “predicate language” that allows a string to be parsed into a graph of predicates (conditions) and handlers (actions to take). Ex:
These rules can be used for any of the following:
Security - Block paths, IPs, or users
URL rewrites - Rewrite incoming URLs to something different
When you start a CF server in CommandBox, the default behavior is that the WAR for that version is expanded into a folder inside the server directory inside your CommandBox home. There is a sub folder containing an MD5 hash of the server name and web root concatenated with the server name. Inside of that, is a folder containing the name of the CF Engine followed by the engine version. The result is something like this:
When you start a new version of the CF engine, the old folder is left in place, and a new one is created containing the new WAR. e.g.
This allows you to easily revert back to the previous version as CommandBox automatically handles the server homes for you. Running server forget will remove the entire top level folder containing all the engine versions.
[Unit]
Description=mySite Service
[Service]
ExecStart=/usr/bin/box server start /var/www/mySiteAPI/server.json
Type=forking
[Install]
WantedBy=multi-user.targetsystemctl start mySite.servicesystemctl status mySite.servicesystemctl enable mySite.servicemethod(GET) -> set(attribute='%{o,type}', value=get)server set jvm.javaHome="C:\Program Files\Java\jdk1.8.0_25"regex('(.*).css') -> { rewrite('${1}.xcss'); set(attribute='%{o,rewritten}', value=true) } regex('(.*).jpg$') -> redirect('${1}.png')web.blockFlashRemoting = true
web.blockFlashRemoting = true
web.blockFlashRemoting = false
You may want to start up a local server that does not have a CF Engine such as Lucee or Adobe ColdFusion installed. You can do this as of CommandBox 5.1.0 by setting the cfengine parameter to none like so:
server start cfengine=noneOr in your server.json like this
server set app.cfengine=none
server startThis server will support everything that you are used to including the server.json file, heap settings, ports, and virtual directories. The only difference is it will server everything as static files. (.cfm or .cfc files will not be processed)
web.http.portNow every time you start your server, the same port will be used.
If the server won't start or is unreachable, make sure it's port is free with your operating system's netstat command. On Unix-based OS's:
You can start your server to listen for SSL connections too.
HTTP/2 is a newer standard of HTTP supported by all modern browsers. HTTP/2 is enabled by default any time you are using an HTTP/HTTPS listener, however all major browsers will only allow the server to negotiate HTTP/2 over an HTTPS connection. HTTP/2 runs over the same port and only changes the exchange between the server and browser. You can disable HTTP/2 support like so:
If you want to confirm whether your browser is using HTTP/2, you can open your debugging tools and look at the network requests. You may need to add the "protocol" column in the UI. HTTP/2 will usually show up as something like "h2" in the protocol column.
You can start your server to listen for AJP connections too.
CommandBox's AJP listener (provided by Undertow) is already protected against the Ghostcat vulnerability. However, if you would like to set up an AJP secret as well to ensure all requests coming into the AJP listener are from a trusted source, you can do by setting the web.ajp.secret property.
For this to work, you must also configure your AJP proxy in your web server to send the same secret! For requests received to the AJP listener which do not contain the secret, a 403 status code will be returned. You can customize the output of the 403 page via the Error Pages settings.
The AJP secret is implemented via a Server Rule. Feel free to add your own server rule instead of this setting if you want to customize how it works.
Your application may rely on a specific host name other than the default of 127.0.0.1. You can set the host to anything you like, but you must add a host file entry that resolves your host name to an IP address assigned to your network adapter (usually 127.0.0.1)
If you have multiple IP addresses assigned to your PC, you can bind the server to a specific IP using the host parameter.
A server configuration can only have one host entry. If you require your server to be available on multiple IP addresses of the machine it runs on, you can set the host to 0.0.0.0. This will effectively bind the server to all network interfaces (including local).
Or save in server.json
Most modern browsers allow you to make up any subdomain you want before localhost such as mySite.localhost and will simply resolve them to localhost (127.0.0.1) even without a hosts file entry. CommandBox now supports using these domains and will bind your server's ports to localhost even without using the commandbox-hostupdater module.
By default, CommandBox will open your browser with the host and port of the server. You can customize the exact URL that opens. This setting will be appended to the current host and port.
Or you can completely override the URL if your setting starts with http://.
web.blockSensitivePaths - Returns 404 error page for common config files such as box.json or .env
web.blockFlashRemoting - Blocks all paths related to Flash and Flex remoting calls
If you want to customize the rules above, simply turn them off and include the rules directly in your server.json where you can modify them as you see fit.
This setting has three possible settings:
true - Block ALL access to ColdFusion and Lucee admins
false - Do not block anything
external - Only block access not coming from localhost.
The exact rule activated when you set this property to true is:
The exact rule activated when you set this property to external is:
This setting only allows true/false. This is a bit of a catch-all rule for any sort of paths that a user should never be able to make on production that could reveal information or access secret parts of your CF installation. When set to true, the following rules are activated:
When the profile is set to production, the following rule is also added which blocks the ColdFusion RDS access from CF Builder and access to TestBox runners:
If you need to legitimately access any of these paths, you'll need to turn off this setting and custom-add the rules that you want to keep. This setting is a convenience that adds several rules at once.
This setting only allows true/false. When set to true, the following rules are activated:
If you need to legitimately access any of these paths, you'll need to turn off this setting and custom-add the rules that you want to keep. This setting is a convenience that adds several rules at once.
What if you want to go one step deeper? For instance, the blockSensitivePaths setting blocks a whole bunch of stuff all in one shot. An example might be wanting to open up JUST the RDS IDE integration for your developers, which funnels through the /CFIDE/main/ide.cfm path which you can see is blocked above.
The solution to this is quite simple and is all based on the ORDER in which your rules are processed. Built-in CommandBox rules are the last to process. This means that if you hijack the predicates with a custom rule FIRST, you can override the behavior of the built in rules. So, if we want to allow access to the /CFIDE/main/ide.cfm path, we just need to add a custom rule that matches that path and then aborts the predicate chain so no further rules fire.
Which gives you the following server.json
The done handler is what bypasses all subsequent rules for the request.
Since your custom rules are processed BEFORE the built-in rules, that also means that you have the ability to accidentally bypass security rules by applying another rule that intercepts the request! By default a custom rule won't block subsequent rules from firing unless you rewrite the request or use the special done handler.
Modifying HTTP requests on the fly - Set headers, cookies, or response codes
Much of this functionality overlaps with the existing Tuckey-based rewrites in CommandBox, but this functionality is built directly into Undertow, has a more streamlined syntax, and allows for easier ad-hoc rules to be layered into a server that allows for you to have custom rules layered on top of built in rules. It can be used to replace what Tuckey does, or added on top.
Unlike custom Tuckey-based rewrites that must be placed in a single XML file, server rules can be provided ad-hoc in a variety of locations. They are combined and passed to the server in the order defined. This allows you to easily "layer" custom rules along with out-of-the-box lockdown profiles.
For maximum configuration options, the following mechanisms are supported for specifying the rules for a given server. Rules are processed in the order listed. i.e., a rule defined in your server.json is processed prior to a rule in your server.default config setting.
Ad-hoc rule array in server.json
External rules files in server.json in the order defined
Ad-hoc rule array in config setting server.defaults
External rules files in config setting server.defaults in the order defined
CommandBox built-in rules (web.blockCFAdmin, web.blockConfigPaths)
Any module listening to server interceptions can inject their rules wherever they please in the array.
You can specify ad-hoc rules in the web.rules property as an array of strings in your server.json as well as specify one or more external rule files in the web.rulesFile property as an array or list of file glob patterns.
External rule files with a .json suffix will be expected to be a valid JSON file containing an array of strings. Ex:
External rule files with any extension OTHER than .json will be expected to be a raw text file with one rule per line. Emtpy lines are ignored and the rules are processed in the order defined.
Rules specified directly in the server.json or in an external JSON file must be escaped for the JSON they are a part of. Using a plain text external file can help readability since no additional escaping is required for the rules.
Like all other config server defaults, they follow the same pattern as the server.json file.
You can comment out any rule (whether it's in JSON or a text file) by proceeding it with a pound sign (#).
When you start a new server version to replace a previous version, you will get a new server home which also means all settings and manual changes to the old server home will not exist in the new one. if you have commandbox-cfconfig installed, it will automatically copy over all CF config settings that it can handle into the new server home. Any other custom changes you've made such as license files, logs, jars or web.xml modifications will not be brought over.
You can move the server home to a custom folder of your choice with the following setting:
Note, the relative path is relative to the folder that the server.json lives in. This can give you a predictable server home, but comes with a few caveats:
CommandBox will NOT auto-upgrade new versions of the CF engine
If you ask for a new version of the engine, CommandBox will ignore it
You must server forget and remove the server home before you can start a new server in your custom server home.
There is an option that will give you a mix of a custom server home and the default behavior where the server home is automatically placed inside the CommandBox home. This is the app.singleServerHome setting. It defaults to false.
This will create a folder similar to the default behavior above, but WITHOUT the version number appended to the folder name. An example server home would be:
This has the convenience of auto-managing the server home for you, but still come with all the caveats listed above for a custom server home such as requiring you to server forget to upgrade or change versions via CommandBox.
This setting is a CLI-wide config setting that forces CommandBox to only have a single server. This setting was created to simplify our Ortus Docker Images and you likely DON'T want to use this outside of a scenario such as a Docker image where only one server exists. When this is enabled, the first server that is started will be remembered as the only serer that exists. No matter what directory you run start and stop commands from and no matter what name you pass, CommandBox will always perform that action against the single server it has. You can server forget and start another server elsewhere, but there can only be one server at a time. This setting was added to help prevent duplicate servers from getting created in different folders during Docker builds which mixed up the settings.
set(attribute='%{i,someHeader}', value=someValue)regex('.*/index\..*') or path-suffix('/') -> set(attribute='%{o,Cache-Control}', value='no-cache')path('/freshcontent.html') -> set(attribute='%{o,Cache-Control}', value='no-cache')path-template('/product/{productid}') -> set(attribute='%{i,productid}', value='${productid}')path(/foo/a/b) -> response-code(503)
path(/restart) -> { rewrite(/foo/a/b); restart; }path-prefix(/admin/) and not equals('%{REMOTE_IP}', 127.0.0.1) -> set-error( 404 )path-prefix(value="/admin/") -> ip-access-control[default-allow=false, acl={'127.0.0.* allow'}, failure-status=404]path(box.json) -> set-error( 404 )
path(/box.json) -> set-error( 404 )regex( "^/tests/" ) -> set-error( 404 )
regex( pattern='^/tests/.*", full-match=true ) -> set-error( 404 )regex(pattern="Googlebot", value="%{i,USER-AGENT}", case-sensitive=false ) -> set-error( 404 )path( "/foobar" )
path(/foobar)
path( /foobar )path( " /foobar " )not regex( pattern='.*\.(bmp|gif|jpe?g|png|css|js|txt|xls|ico|swf|cfm|cfc|html|htm)$', case-sensitive=false ) -> rewrite('/index.cfm/%{RELATIVE_PATH}')set(attribute='%{o,Access-Control-Allow-Origin}', value='*')equals( %{LOCAL_SERVER_NAME}, 'site1.com' ) -> rewrite( '/site1/%{REQUEST_URL}' )
equals( %{LOCAL_SERVER_NAME}, 'site2.com' ) -> rewrite( '/site2/%{REQUEST_URL}' )
equals( %{LOCAL_SERVER_NAME}, 'site3.com' ) -> rewrite( '/site3/%{REQUEST_URL}' )regex( '^/product/([A-Z]{6})$' ) -> rewrite( '/product.cfm?productID=${1}' )not equals( %{LOCAL_SERVER_NAME}, 'www.myDomain.com' ) -> set-error( 403 )path-prefix('/reports') -> reverse-proxy({'http://reports1.mydomain.com','http://reports2.mydomain.com'})config set server.defaults.jvm.javaHome="C:\Program Files\Java\jdk1.8.0_25"server start javaVersion=openjdk8server set jvm.javaVersion=openjdk8config set server.defaults.jvm.javaVersion=openjdk8{
"JVM":{
"javaVersion":"openjdk11_jre_x64_linux_hotspot_jdk-11.0.13+8"
}
}config set server.javaInstallDirectory=C:/path/to/JREs/java search version=openjdk8java search version=openjdk8 os=java listserver java setDefault openjdk11server java install openjdk11 --setDefaultserver java uninstall openjdk9_jre_x64_windows_hotspot_jdk-9.0.4+11server set profile=production{
"profile": "production"
}server start profile=production{
"profile": "production",
"web": {
"blockCFAdmin": false
}
} start port=8080server set web.http.port=8080
server show web.http.port $> netstat -pan | grep 80start SSLEnable=true SSLPort=443server set web.SSL.enable=true
server set web.SSL.port=8080
server show web.SSL.enable
server show web.SSL.portserver set web.http2.enable=falsestart AJPEnable=true AJPPort=8009server set web.AJP.enable=true
server set web.AJP.port=8009
server show web.AJP.enable
server show web.AJP.portserver set web.AJP.secret=mySecretequals(%p, 8009) and not equals(%{r,secret}, 'mySecret') -> set-error(403) start host=mycoolsite.local start host=192.168.10.15 port=80 start host=0.0.0.0 port=80server set web.host=mycoolsite.local
server show web.hostserver set web.host=mySite.localhostserver set openBrowserURL=/bar.cfmserver set openBrowserURL=http://127.0.0.1:59715/test.cfmblock-cf-admin()cf-admin() -> block-external()// track and trace verbs can leak data in XSS attacks
disallowed-methods( methods={trace,track} )
// Common config files and sensitive paths that should never be accessed, even on development
regex( pattern='.*/(box.json|server.json|web.config|urlrewrite.xml|package.json|package-lock.json|Gulpfile.js)', case-sensitive=false ) -> set-error(404)
// Any file or folder starting with a period
regex('/\.')-> set-error( 404 )
// Additional serlvlet mappings in Adobe CF's web.xml
path-prefix( { '/JSDebugServlet','/securityanalyzer','/WSRPProducer' } ) -> set-error( 404 )
// java web service (Axis) files
regex( pattern='\.jws$', case-sensitive=false ) -> set-error( 404 )regex( pattern='.*/(CFIDE/multiservermonitor-access-policy.xml|CFIDE/probe.cfm|CFIDE/main/ide.cfm|tests/runner.cfm|testbox/system/runners/HTMLRunner.cfm)', case-sensitive=false ) -> set-error(404)// These all map to web.xml servlet mappings for ACF
path-prefix( { '/flex2gateway','/flex-internal','/flashservices/gateway','/cfform-internal','/CFFormGateway' } ) -> set-error( 404 )
// Files used for flash remoting
regex( pattern='\.(mxml|cfswf)$', case-sensitive=false ) -> set-error( 404 )server set web.rules="['path(/CFIDE/main/ide.cfm)->done']" --append {
"web":{
"rules":[
"path(/CFIDE/main/ide.cfm)->done"
]
}
}path-suffix(/box.json) -> set-error(404){
"web" : {
"rules" : [
"path-suffix(/box.json) -> set-error(404)",
"path-suffix(hidden.js) -> set-error(404)",
"path-prefix(/admin/) -> ip-access-control(192.168.0.* allow)",
"path(/sitemap.xml) -> rewrite(/sitemap.cfm)",
"disallowed-methods(trace)"
],
"rulesFile" : "../secure-rules.json"
// Or...
"rulesFile" : ["../security.json","../rewrites.txt","../app-headers.json"]
// Or...
"rulesFile" : "../rules/*.json"
}
}[
"path-suffix(/box.json) -> set-error(404)",
"path-suffix(hidden.js) -> set-error(404)"
]path-suffix(/box.json) -> set-error(404)
path-suffix(hidden.js) -> set-error(404)config set server.defaults.web.ruleFile=/path/to/rules.json# Here is a comment that will be ignored
# The following rule also won't be run
# path-suffix(hidden.js) -> set-error(404)server {
server_name example.net www.example.net;
root /app;
index index.cfm index.html index.htm;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
location ~ /WEB-INF/ { access_log off; log_not_found off; deny all; }
location ~ /META-INF/ { access_log off; log_not_found off; deny all; }
location ~ /META-INF/ { return 404; }
location ~ /WEB-INF/ { return 404; }
location ~ \.config$ { return 404; }
location ~ /\. { return 404; } ## e.g. .htaccess, .gitignore etc.
location ~ ~$ { return 404; }
location ~ \.aspx?$ { return 404; } ## most likely hackers testing the site
location ~ \.php$ { return 404; }
# this prevents hidden files (beginning with a period) from being served
location ~ /\. {
access_log off; log_not_found off; deny all;
}
# Do not log missing favicon.ico errors
location ^/(favicon\.ico|apple-touch-icon.*\.png)$ {
access_log off; log_not_found off;
}
location = /robots.txt {
access_log off; log_not_found off;
}
location / {
try_files $uri $uri/ @rewrites;
}
#set indexfileinurls=0 in Mura's settings.ini.cfm
location @rewrites {
rewrite ^/(.*)? /index.cfm/$1 last;
rewrite ^ /index.cfm last;
}
# Main Railo/Lucee proxy handler
location ~ \.(cfm|cfml|cfc|jsp|cfr)(.*)$ {
proxy_pass http://127.0.0.1:8080;
}
# Some basic cache-control for static files to be sent to the browser
location ~* \.(?:jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|eot|mp4|ogg|ogv|webm|js|css)$ {
expires 1M;
#expires modified +90d;
access_log off;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
listen 443 ssl http2; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.net/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host ~ ^[^.]+\.example\.net$) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.net) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name example.net www.example.net;
return 404; # managed by Certbot
}~/.CommandBox/server/C3D9460AC18B18AC462BBBF1E02425C8-cfconfig/lucee-5.3.7.48~/.CommandBox/server/C3D9460AC18B18AC462BBBF1E02425C8-cfconfig/lucee-5.3.8-RC+139server set app.serverHomeDirectory=/absolute/path/to/serverHome
# Or...
server set app.serverHomeDirectory=relative/serverHomeserver set app.singleServerHome=true~/.CommandBox/server/C3D9460AC18B18AC462BBBF1E02425C8-cfconfig/luceeconfig set server.singleServerMode=trueCommandBox's server rules are based directly on the "Predicate Language" feature of JBoss Undertow. All of the official documentation for Undertow's predicate language applies to CommandBox. CommandBox doesn't limit the power of what Undertow provides at all. In fact, we give you some additional out-of-the box predicates and handlers you can use.
There are three concepts you need to understand and you'll be writing your own rules in no time.
Handler - A wrapper around the request that takes some sort of action such as returning a status code or rewriting the request.
Predicate - A conditional that evaluates to true or false. Used to Conditionally apply a handler
Exchange Attribute - An abstracted way to refer to any piece of information about the request or response. Can include URL, query string, cookies, headers, or CGI variables.
Since the parsing of your rules is handled by Undertow, it is case sensitive in many areas and CommandBox cannot control this. The following must always be lower case:
Predicate names
Handler names
Parameter names
Keywords like and, or
The full undertow docs can be found here:
A handler will take action on the request. This can redirect the request, rewrite it, abort it, or modify attributes of the request such as setting an HTTP header or status code. If the predicate is omitted, the handler will always fire for all requests. Ex:
set() - Sets an exchange attribute (see below)
rewrite() - Rewrite the request URL
redirect() - Redirect to another URL
header()
A handler is called using the “name” from the docs and passing any required parameters. Params can be named or positional (if there is only one). Quoting values is only required if they have a space, comma or brace. The following are all equivalent:
Handler parameters that accept an array use the Java array literal syntax which is a comma-delimited list of values in curly braces.
More than one handler can be run by wrapping them in curly braces and using semicolons between them
A chain of handlers can be configured for the true AND false evaluation of a single predicate using the “else” keyword.
A predicate is a condition that must be matched for the handler to kick in.
path() - match the incoming request path
path-suffix() - match full file/folder names at the end of the path like file.cfm
path-prefix() - match full file/folder names at the start of the path like /lucee/admin
A predicate is called by placing parentheses after the name and passing in the required arguments as specified in the docs for that predicate. Quoting values is only required if they have a space, comma or brace. The following are all equivalent:
Complex conditions can be constructed with more than one predicate using the keywords “and” or “or”.
A predicate can be negated with the keyword “not”
Exchange attributes are an abstraction Undertow provides to reference any part of the HTTP request or response. There is a textual placeholder that can be used in predicates and handlers that will be expanded in-place.
%{REMOTE_IP} - Remote IP address
%{PROTOCOL} - Request protocol
%{METHOD} - Request method
%{REMOTE_USER}
Use an exchange attribute like you would a variable as the parameter to a handler or predicate.
These are all equivalent:
Your CF engine (Lucee, Adobe, etc) or Java app may have application logs of its own and their locations will vary based on what you have running. In any case, they will most likely be located under the server home directory.
You can find out where your server home is by running:
You can also get the full path to your servlet's "out" log with this command:
This log file is the equivalent of your catalina.out file on a typical Lucee/Tomcat install or the equivalent of your coldfusion-out.log file on a typical ColdFusion install.
The Servlet's "out" log can be tailed with this command:
Your console "out" log will auto-rotate every 10MB to keep it from getting too big. Don't use the --debug or --trace flag on a production server or you'll get a lot of logging information! Without those flags, the "out" log doesn't log anything for each request. With debug enabled, you'll get basic information for each request that comes in as well as whether a rewrite rule fired, and with trace, you'll get a ton of information about every request as well as every local path resolution by the path resource manager.
There are many log files for Lucee. For the guide below, I'm assuming you haven't set a custom serverConfigDir or webConfigDir for your servers. If you have, adjust the paths for the server and web context to be whatever it is you've configured. Here are the three locations you'll find log file and is pretty much the same for Lucee 4 and Lucee 5.
Lucee's server context log files - The server context is located under the server home which you can find with the command server info property=serverHomeDirectory. Open that directory and then navigate to WEB-INF/lucee-server/context/logs/.
Lucee's web context log files - The web context is also located under the server home. Open that directory and then navigate to WEB-INF/lucee-web/logs/.
So, to give real examples-- a Lucee server I just looked at on my machine has the three folders of log files I just covered above in these locations:
Since Adobe doesn't have the separation of server and web contexts, it only has two log locations which are as follows on all versions.
ColdFusion server log files - The remaining log files are located under the server home which you can find with the command server info property=serverHomeDirectory. Open that directory and then navigate to WEB-INF\cfusion\logs/.
So, to give real examples-- a ColdFusion server I just looked at on my machine has the two folders of log files I just covered above in these locations:
CommandBox servers use a powerful Java-based web server which we've tested to have throughput just as good as Apache or IIS. You can enable "access" logs which output one line for each HTTP request (even for static assets like JS or image files) in the same "common" format that Apache web server uses.
View the location of this log or tail the log contents like so:
Your access log will be auto-rotated every day.
CommandBox servers use the java-based Tuckey rewrite engine for easy URL rewriting. There's a lot of good debugging information available to help figure out why your rewrites aren't working. You can enable a separate rewrite log to view this information. Keep in mind this can generate a lot of logging output.
View the location of this log or tail the log contents like so:
Your rewrites log will be auto-rotated every 10MB. The amount of information that appears in the rewrites log will be affected by the --debug and --trace flags when you start the server.
With the advent of Multi-server functionality, you may want to regularly start up the same web site with different settings (such as different CF engine's). To help with this, you can have more than one JSON file.
anything.jsonThe default server configuration file is server.json, but you can actually call the file anything you want as long as you use the file's path (or unique name) when starting the server.
Let's say we want to test our app in Lucee 4, Lucee 5 and Adobe 2016. Let's start 3 servers. Note we give each server a unique name. This will come in handy when we want to start/stop the servers by name later.
Info It's important to always use a name when starting more than one server. Otherwise, the settings will override each other and only the last server will be saved. Also, you will only be able to stop the last server via the
stopcommand.
You can have full control over the name of the JSON files by using the serverConfigFile parameter, but when CommandBox sees us use the name parameter, it will automatically create a file called server-{name}.json. In this case, we'll have 3 new files:
server-lucee4.json
server-lucee5.json
server-adobe2016.json
If you run the server show command, you'll see it returns {}. This is because it looks for a file called server.json by default. Not to worry, you can still programmatically manipulate your JSON files like so:
Info The property name and server config file path are interchangeable for the
server showandserver clearcommands for your convenience.
Now that you have 3 JSON files-- one for each server, you can use the path to the JSON file (absolute or relative to your CWD) to control each server.
For your convenience, if you pass in a path to an existing JSON for the server name, we'll use it as the serverConfigFile parameter.
This trick works on any server commands
After you've started a server at least once, you can use its server name to control it as well which is a great shortcut. CommandBox will recognize the server name and remember where the server JSON for that server name is stored. Then it will pull the correct web root from the JSON file.
server info property=serverHomeDirectoryserver info property=consolelogPath
elseset-error() - Set HTTP response code and returns the corresponding error page
ip-access-control() - Configure IP-based allow/deny rules (wildcards and IP ranges allowed)
done - Skips remaining rules
request-limit() - Limits concurrent requests
restart - Restarts process back at start of predicate rule chain (combine with rewrite, etc)
reverse-proxy() - Creates a round robin reverse proxy to a list of URLs
allowed-methods() / disallowed-methods() - Enforces whitelist/blacklist of HTTP methods on current request
regex() - Match a regular expression against any exchange attribute
equals() / contains() - Do a text compare on any exchange attribute
path-template() - match a path with placeholders like /foo/{bar} and the placeholders become variables for use in later predicates or handlers in the chain.
%{RESPONSE_TIME} - Time taken to process the request, in ms
%{c,cookie_name} - Any cookie value
%{q,query_param_name} - Any query parameter
%{i,request_header_name} - Any request header
%{o,response_header_name} - Any response header
${anything-here} - Any value from the predicate context (such as regex capture groups or path-template placeholders)
disallowed-methods(trace)set-error(404)
set-error("404")
set-error(response-code=404)
set-error(response-code="404")reverse-proxy( { 'http://host.com', 'http://host2.com' } )path(/restart) -> { rewrite(/foo/a/b); restart; }regex('(.*).css') -> set(attribute='%{o,css}', value='true') else set(attribute='%{o,css}', value='false');method(GET)
method("GET")
method(value=GET)
method(value="GET")path-prefix(/tests/) OR path-prefix(/workbench)not method(POST)set(attribute='%{o,someHeader}', value=myValue)
not equals('%{REMOTE_IP}', 127.0.0.1) -> set-error(403)regex(pattern="/(MSIE 6\.0)", value="%{i,user-agent}" ) -> response-code( 404 )
regex(pattern="/(MSIE 6\.0)", value="%{i,USER-AGENT}" ) -> response-code( 404 )
regex(pattern="/(MSIE 6\.0)", value="%{i,UsEr-AgEnT}" ) -> response-code( 404 )server log --follow
server log myServerName --followC:/users/brad/.CommandBox/server/{hash}-cfconfig/lucee-4.5.5.006/logs/server.out.txt
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/application.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/datasource.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/deploy.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/gateway.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/mapping.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/memory.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/orm.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/remoteclient.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/rest.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/scope.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/search.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/thread.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/application.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/datasource.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/deploy.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/gateway.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/mapping.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/memory.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/orm.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/remoteclient.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/rest.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/scope.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/search.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/thread.logC:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/logs/server.out.txt
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/application.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/audit.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/eventgateway.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/exception.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/monitor.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/scheduler.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/server.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/websocket.logserver set web.accessLogEnable=trueserver info property=accessLogPath
server log --follow --access
server log myServername --follow --accessserver set web.rewrites.logEnable=trueserver info property=rewritesLogPath
server log --follow --rewrites
server log myServername --follow --rewritesstart cfengine=lucee@4 name=lucee4
start cfengine=lucee@5 name=lucee5
start cfengine=adobe@2016 name=adobe2016{
"app":{
"cfengine":"lucee@4"
},
"name":"lucee4"
}{
"app":{
"cfengine":"lucee@5"
},
"name":"lucee5"
}{
"app":{
"cfengine":"adobe@2016"
},
"name":"adobe2016"
}# Show all properties
server show server-lucee5.json
# Show one property
server show server-lucee5.json name
# named args are required to set properties
server set serverConfigFile=server-lucee5.json jvm.heapSize=1024
# Clear properties
server clear server-lucee5.json jvmstart serverConfigFile=server-lucee4.jsonstart server-lucee4.json
stop server-lucee4.json
start server-adobe2016.json# Open your Lucee 5 site in the browser
server log server-lucee5.json
# cd into the web root for your Adobe 2016 web
server cd /path/to/server-adobe2016.jsonstart lucee4
start lucee5
start adobe2106
restart adobe2016
stop lucee4Once you start using the embedded server for your development projects, you may wish to enable URL rewriting. Rewrites are used by most popular frameworks to do things like add the index.cfm back into SES URLs.
You may be used to configuring URL rewrites in Apache or IIS, but rewrites are also possible in CommandBox's embedded server via a Tuckey servlet filter which uses an xml configuration.
Commandbox also exposes a way to do url rewrites with the Undertow predicate language. If you missed the Server Rules section, go there to learn how to do url rewrites, security, and http header modification in a nice text based language (non-xml).
We've already added the required jars and created a default rewrite that will work out-of-the-box with the ColdBox MVC Platform. To enable rewrites, start your server with the --rewritesEnable flag.
Now URLs like
can now simply be
In server.json
info The default rewrite file can be found in
~\.CommandBox\cfml\system\config\urlrewrite.xml
If you want to customize your rewrite rules, just create your own XML file and specify it when starting the server with the rewritesConfig parameter. Here we have a simple rewrite rule that redirects /foo to /index.cfm
customRewrites.xml
Then, fire up your server with its custom rewrite rules:
In server.json
You can place your custom rewrite rule wherever you like, and refer to it by using either a relative path or an absolute path. CommandBox will start looking relative to where the server.json file resides.
or
If you're coming from Apache, Tuckey supports a large subset of the mod_rewrite style rules like what you would put in .htaccess. You can simply put your rules in a file named .htaccess and point the web.rewrites.config property to that file.
Note: The name of the file matters with mod_rewrite-style rules. It must be called .htaccess. With xml rewrites, the filename is not important, only the content.
Here are some simple rewrite rules:
Please see the docs here on what's supported:
info For more information on custom rewrite rules, consult the .
Your servers come ready to accept SES-style URLs where any text after the file name will show up in the cgi.path_info. If rewrites are enabled, the index.cfm can be omitted.
SES URLs will also work in a sub directory, which used to only work on a "standard" Adobe CF Tomcat install. Please note, in order to hide the index.cfm in a subfolder, you'll need a custom rewrite rule.
The Tuckey Rewrite engine has debug and trace level logging that can help you troubleshoot why your rewrite rules aren't (or are) firing. To view these logs, simply start your server with the --debug or --trace flags. Trace shows more details than debug. These options work best when starting in --console mode so you can watch the server logs as you hit the site. Alternatively, you can follow the server's logs with the server log --follow command.
The Tuckey Rewrite library that CommandBox uses under the hood. It has some extra settings that CommandBox allows you to use.
To monitor your custom rewrite file for changes without needing to restart the server, use this setting.
To enable the inbuilt Tuckey status page, use the following setting. Note, debug mode needs to be turned on for the Tuckey status page to work. Also, you'll need to customize your rewrite file if you use a path other than /tuckey-status.
For every server you start, there is a corresponding icon in your PC's system tray. In addition to the menu options you get out of the box, you can add in custom menu items. Menus are defined as nested arrays of structs, where each struct represents a single menu item. A menu item can be informational, have an action, or contain sub menus.
You can customize the tray menus for a server via 3 different methods:
The trayOptions array in a specific server's server.json file. These menu additions will be specific to that server.
The server.defaults.trayOptions config setting. These menu additions will be added to every server you start
A custom CommandBox Module with an interceptor listening to the onServerStart interception point that modifies the serverInfo.trayOptions array.
Each menu item struct can have the following keys. Only label is required.
label - This text appears on the menu and is the unique name
action - This controls what the menu item does when clicked. Possible options are:
openfilesystem - Opens a folder on the file system. Requires path to be set as well.
Commands executed by the run action will display their output in a popup window. The PID of the process is available if running on Java 9 or later. Also, there is a button to kill the process, but your mileage may vary. Only use this option to run command line apps that have console output you want to see.
Commands executed by the runAsync action work like the run action except there is no windows to show you the output. This is what you want to use to fire off an app such as an IDE.
Commands executed by the runTerminal action work like the run action except a new terminal window is opened to run the command. The terminal windows stays open and you can continue to interact with it when the command finishes.
You can customize how your command is run by setting the optional workingDirectory and shell properties. If not set, the working directory will be the web root of the server.
You can nest menus by supplying another array of structs in the items property of a menu. A menu cannot have an action and have sub menus.
Menu items are layered "on top" of existing options whichs mean you can add new sub menu items to an existing top level menu. You can even override the action or image of a built-in menu. Menu items are registered in this order:
Built-in menus
Config setting server defaults
server.json trayOptions
onServerStart interceptor
This example server.json will add a new sub menu into the existing "Open..." top level menu.
There is no way to remove existing menu items via your config settings or server.json. To do that, you'd need to directly manipulate the trayOptions array in an interceptor.
FusionReactor is a popular tool for monitoring performance and gathering metrics for ColdFusion and Java J2EE applications. You may wish to use FusionReactor with the servers you start up via CommandBox. We've created a CommandBox module that will add FusionReactor support to your CommandBox servers which you can view here on ForgeBox.
The CommandBox FusionReactor module is a separate project that you can optionally install by typing this:
That's it-- now every server you start with the start
[
{
"label" : "My Custom Menu Item!",
"disabled" : true
}
]openbrowser - Opens a URL in your default browser. Requires url to be set as well.
stopserver - Stops the current server
run - Runs an arbitrary native command synchronously. Requires command to be set as well.
runAsync - Runs an arbitrary native command asynchronously Requires command to be set as well.
runTerminal - Runs an arbitrary native command in a new Terminal window. Requires command to be set as well.
path - The file system path to use for the openfilesystem action.
url - The HTTP URL to use for the openbrowser action
image - A custom image file to use for the icon. Relative paths in the server.json will be relative to the JSON file Relative paths in the global config will be relative to the web root of the server.
command - The native command to run for the run, runAsync, or runTerminal actions.
workingDirectory - The working directory to use for the run, runAsync or runTerminal actions.
shell - Override the native shell to use on your OS. Defaults to your nativeShell config setting.
items - An array that contains a struct of sub menus.
disabled - Boolean that greys out menu item and disables any action. Use for informational items.
There's nothing special you have to do in order for FusionReactor to load. A random port will be chosen for FusionReactor to use so you can have more than one server running at a time and each of them will have their own FusionReactor instance running. When you start a server, you should see some output similar to this:
To open FusionReactor in your browser, you can run the following command:
If you right click on the tray icon for this server, you'll see there is a new menu item at the bottom called Open Fusion Reactor that will do the same thing.
FusionReactor is a commercial product and requires a license to use. If your company has a license for you to use on your PC, then you can register your CommandBox FusionReactor license with this command:
If you don't have a license, you can sign up for a trial and purchase a license from the http://www.fusion-reactor.com/ website.
By default, the license key will always be displayed on the home page after login. You can turn off the display of the key on a per-server basis or at a global level for all servers.
By default, the module always picks a random port to start FusionReactor on. You can also set your FusionReactor port on a per-server basis, or at a global level for all servers (if using the fancy host updater module which prevents port conflicts by binding each site to its own IP). The default behavior will still be to pick a random port if you don't specify one.
By default, the module will bind FR's port to the same host as your CommandBox web server. You can ask FR to bind to a separate host/IP on a per server basis, or a global basis.
You may want to turn the FusionReactor functionality on or off based on your testing or for specific sites. There is now an enable flag for just that. It can be set per server and for all servers as well.
You can set a license key per server if you wish like so:
The module is regularly updated to use the latest version of FusionReactor. Note however that your license key may not be for the latest FR version. When the internal default version of FR is updated for a major release, the version of the actual FR module will also have a "major" version increment. This is so you can always run upgrade --system and you won't have to worry about suddenly getting a major FR upgrade one day that doesn't work with your license key.
If you want to upgrade your CommandBox FusionReactor module to a new major release, just re-run the installation command.
If you have an older FR license you want to use, you can specify the version of FR you'd like like so:
The installID setting can be any valid CommandBox endpoint installation ID, which means you can point to a custom HTTP URL, or ForgeBox slug, etc.
As of version 4.0 of this module, the debugger libs will be added automatically for you based on your OS. To disable the debugger libs use the following setting:
There are a handful of JVM args we can use to set things like license key or password, but there are many many settings inside of FusionReactor that have no corresponding method to externalize them. These are stored in a file called conf/reactor.conf inside of the FusionReactor home directory. If you want to script out settings such as
E-mail servers
Notification settings
Profiler settings
Request history settings
Then you can make a copy of a reactor.conf file that contains the settings you want the point this module at the file to be copied over when starting the server so FR will pick it up and use it. Just need in mind that this setting will override any manual setting changes you make in the FR web admin every time you start the server.
Point your server.json to the new file. Remember, non-absolute paths are relative to the directory the server.json lives in.
Now, a fresh new server will have these settings.
Note: the reactor.conf file may contain passwords or other sensitive information. It is in a java properties file format, so feel free to edit it and remove items you don't want. Also, take care when committing it to a source repo or making it web accessible so you don't reveal information. There is currently no support for environment variable expansions in this file, but perhaps we'll add it if it's useful.
The CommandBox FusionReactor module has passthrough settings for every documented JVM arg. Here are the remaining ones we haven't covered. If you want to know what some of these do, read the official FR docs on them.
Here's the module setting, followed by the JVM arg it creates. Remember, you can use environment variables in your server.json to control these dynamically on a per-server basis!
fusionreactor.password - fradminpassword
fusionreactor.RESTRegisterURL - frregisterwith
fusionreactor.RESTShutdownAction - frshutdownaction
fusionreactor.RESTRegisterHostname - frregisterhostname
fusionreactor.RESTRegisterGroup - frregistergroup
fusionreactor.licenseDeactivateOnShutdown - frlicenseservice.deactivateOnShutdown
fusionreactor.licenseLeaseTimeout - frlicenseservice.leasetime.hint
fusionreactor.cloudGroup - fr.cloud.group
fusionreactor.requestObfuscateParameters - fr.request.obfuscate.parameters
fusionreactor.autoApplicationNaming - fr.application.auto_naming
fusionreactor.defaultApplicationName - fr.application.name
By default, FusionReactor is only available on the FR port, and not the HTTP or HTTPS port. If you want to hit FusionReactor's web UI through your main web server on the standard HTTP port, then enable the external server setting. This completely bypasses the custom port and custom host discussed above.
This can provide a convenient method to make FR accessible, but remember to put appropriate lock-down rules on your external web server so FR is not publicly accessible. Also note if you have a web server such as Nginx only proxying traffic to .cfm URLs to CommandBox, you'll need to modify it to also proxy requests to /fusionreactor/ to CommandBox as well or this feature will not work and you'll just get an Nginx/etc 404 instead.
start --rewritesEnablehttp://localhost/index.cfm/mainhttp://localhost/mainserver set web.rewrites.enable=true
server show web.rewrites.enable<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "http://tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite>
<!-- this will redirect the user from /foo to /index.cfm -->
<rule>
<from>^/foo$</from>
<to type="redirect">/index.cfm</to>
</rule>
<!-- internally redirect the requested URL from /gallery to /index.cfm?page=gallery with query string appended -->
<rule>
<from>^/gallery</from>
<to type="passthrough" qsappend="true">/index.cfm?page=gallery</to>
</rule>
</urlrewrite>start --rewritesEnable rewritesConfig=customRewrites.xmlserver set web.rewrites.enable=true
server set web.rewrites.config=customRewrites.xml
server show web.rewrites.enable
server show web.rewrites.configserver set web.rewrites.enable=true
server set web.rewrites.config=/my/custom/path/customRewrites.xmlserver set web.rewrites.enable=true
server set web.rewrites.config=~\.CommandBox\cfml\system\config\customRewrites.xmlRewriteEngine on
#The ColdBox index.cfm/{path_info} rules.
RewriteRule ^$ index.cfm [QSA,NS]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.cfm/%{REQUEST_URI} [QSA,L,NS]
RewriteRule ^/foo/ /
# Defend your computer from some worm attacks
RewriteRule .*(?:global.asa|default\.ida|root\.exe|\.\.).* . [F,I,O]
# Redirect Robots to a cfm version of your robots.txt
RewriteRule ^/robots\.txt /robots.cfm
# Change your default cfm file to index.cfm
RewriteRule ^/default.cfm /index.cfm [I,RP,L]
RewriteRule ^/default.cfm((\?.+)|())$ /index.cfm$1 [I,RP,L]
RewriteRule ^/News.html((\?.+)|())$ /News/index.cfm$1 [I,RP,L]
# redirect mozilla to another area
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*
RewriteRule ^/no-moz-here$ /homepage.max.html [L]site.com/index.cfm/home/loginsite.com/myFolder/index.cfm/home/loginstart --debug
server log --followserver set web.rewrites.configReloadSeconds=30server set web.rewrites.statusPath=/tuckey-status[
{
"label" : "Open Downloads",
"action" : "openfilesystem",
"path" : "D:/downloads",
"image" : "C:/pictures/folder.png"
}
][
{
"label" : "Open Google",
"action" : "openbrowser",
"url" : "https://www.google.com",
"image" : "C:/pictures/cat.png"
}
][
{
"label" : "Kill it!",
"action" : "stopserver",
"image" : "images/bomb.png"
}
][
{
"label" : "Does the Internet work?",
"action" : "run",
"command" : "ping google.com"
}
][
{
"label" : "Math is math!",
"action" : "runAsync",
"command" : "calc.exe"
}
][
{
"label" : "Update dependencies",
"action" : "runTerminal",
"command" : "box update"
}
][
{
"label" : "Clear Temp Dir",
"action" : "runAsync",
"command" : "rm -rf",
"workingDirectory" : "/var/tmp",
"shell" : "/bin/zsh"
}
][
{
"label" : "Top menu",
"items" : [
{
"label" : "Sub 1"
},
{
"label" : "Sub 2"
},
{
"label" : "Sub 3"
}
]
}
]{
"trayOptions":[
{
"label":"Open...",
"items":[
{
"action":"runAsync",
"command":"calc.exe",
"label":"Calculator"
}
]
}
]
}install commandbox-fusionreactor******************************************
* CommandBox FusionReactor Module Loaded *
******************************************
FusionReactor will be available at the URL http://127.0.0.1:2871fr openfr register "myLicenseKey"# Server specific
server set fusionreactor.hideLicenseKey=true
# global default
config set server.defaults.fusionreactor.hideLicenseKey=true# Server specific port
server set fusionreactor.port=8088
# global default port
config set server.defaults.fusionreactor.port=8088# Server specific host
server set fusionreactor.host=0.0.0.0
# global default hsot
config set server.defaults.fusionreactor.host=0.0.0.0server set fusionreactor.enable=false
config set server.defaults.fusionreactor.enable=falseserver set fusionreactor.licenseKey=XXXXX-XXXXX-XXXXX-XXXXX-XXXXXinstall commandbox-fusionreactor# Server specific version
server set [email protected]
# global default version
config set [email protected]# Server specific version
server set fusionreactor.debugEnable=false
# global default version
config set server.defaults.fusionreactor.debugEnable=falseinstall commandbox-fusionreactor
server startfr opencp "`server info property=FRHomeDirectory`conf/reactor.conf" ./reactor.confserver set fusionreactor.reactorconfFile=reactor.confserver stop
server forget --force
server start# Server specific version
server set fusionreactor.externalServerEnable=true
# global default version
config set server.defaults.fusionreactor.externalServerEnable=trueCommandBox allows you to create web aliases for the web server that are similar to virtual directories. The alias path is relative to the folder the server.json lives in, but can point to any folder on the hard drive. Aliases can be used for static or CFM files.
To configure aliases for your server, create an object under web called aliases. The keys are the web-accessible virtual paths and the corresponding values are the relative or absolute path to the folder the alias points to.
Here's what your server.json might look like.
Here's how to create aliases from the server set command:
info On Adobe ColdFusion servers, .cfm files will be run automatically from inside an aliases directory. On Railo and Lucee servers, you'll need to create a CF mapping that maps the alias name and path for .cfm files to work.

{
"web" : {
"aliases" : {
"/foo" : "bar",
"/js" : "C:\static\shared\javascript"
}
}
}server set web.aliases./foo = bar
server set web.aliases./js = C:\static\shared\javascriptInteracting with the server.json file uses the commands server set, server show, and server clear, which work the same as the package set/show/clear commands.
Set the port for your server:
server set web.http.port=8080View the port:
server show web.http.portView the port with JMESPath:
server show jq:web.http.portRemove the saved setting:
server clear web.http.portThere are a few experimental features in Runwar that are available for your servers.
CommandBox uses a custom resource manager in Undertow to resolve "real" paths (relative) in the servlet context with the path on the file system (absolute). This includes log concerning where the root of the WAR is, where the CF engine web root is, and any web aliases. If you enable a --debug or --trace server start, it is possible to get additional low-level information in the logs about every single file path that is resolved through the servlet context's resource manager. This logging is disabled by default since it is quite verbose.
Or in the server.json as:
By default, the web server in CommandBox will follow the case sensitivity of the underlying file system. So, when on Windows /FiLe.TxT will still load an actual file called /file.txt. But on Linux, the case in the browser would need to match that of the file system. CommandBox allows you to force case sensitivity to be ON or OFF for a server, overriding the server's file system.
Note, this controls all access of static file, such as images, js, css, txt, etc as well as the initial lookup of .cfm files. It will also affect all internal usage of ServletContext.getRealPath( "/myPath.txt" ). It will NOT affect CFML file operations such as <CFFile>, <CFDirectory>, fileRead(), directoryList(), etc. It will also not affect core CF engine functionality such as creating CFCs or cfincluding CFM templates. Any code directly accessing the file system will use the file systems case sensitivity. And creating CFC instance is never case sensitive in CFML.
To force CommandBox's web server to be case sensitive, even on operating systems like Windows, use the following setting. There is a nominal performance benifit in doing this and can allow a Windows CommandBox server to mimic a Linux server for testing.
To force CommandBox's web server to be case insensitive, even on operating systems like Linux, use the following setting. There is a nominal performance overhead in doing this and can allow a Linux CommandBox server to mimic a Windows IIS server. In this mode, CommandBox will use an internal cache of file system lookups to improve performance. If there are two files of the same name using different case, then you will get whatever file is found first.
You can activate a cache for all file path resolution in the resource manager by activating this setting. This is only for production and will eliminate repeated file system hits by your CF engine, such as checking for an Application.cfc file on every request, or testing where the servlet context root is. This will NOT affect any of the CFML fileRead() sort of commands or any code in the CF engine that bypasses the ServletContext and directly hits the file system. The default is false.
Standard Adobe ColdFusion installations have a similar cache of "real" paths from the servlet context that is tied to a setting in the administrator called "Cache Webserver paths" but that setting is not available and does not work on CommandBox servers for some reason..
One minor difference to keep in mind is Lucee server and Adobe ColdFusion use a typical versioning scheme for java projects which looks like this:
However, and use the (semver) which is slightly different. Basically the build ID is moved to the end after a plus (+) sign.
The important thing to remember is, when starting a server via CommandBox always use the second format shown above since that is how ForgeBox recognizes each release.
server set runwar.args="--resource-manager-logging=true"As of version 5.3.0, CommandBox will also recognize the fourth digit in 1.2.3.4 as a build ID if there is no plus sign in the version. This makes 5.3.4+80 and 5.3.4.80 equivalent.
Questions about what versions are available? No problem! Here are some ways you can find out:
Visit the ForgeBox listing for the Lucee package and view all the versions in the versions tab https://www.forgebox.io/view/lucee#versions https://www.forgebox.io/view/adobe#versions
View the last few versions via the CLI with the command
forgebox show lucee
Start typing your cfengine and hit the <tab> key to invoke the tab-completion feature. This actually phones out to ForgeBox as you hit tab to get the current valid list of versions that match what you've typed so far
You can also follow the Lucee bleeding edge, which means every time you start your CommandBox server you'll get the very latest Lucee snapshot release. Please only use this for local development and not production!
It is a nice feature of CommandBox to have it automatically grab the latest version of your favorite CF engine every time it starts.
However, you may have good reason to NEVER want a new version automatically installed. In order to do this, you must specify a COMPLETE version number, including the build number, making sure to use the proper version format. This means you need a major, minor, patch, and build number.
Lucee has a modular core and comes bundled with a bunch of extensions that approximate the functionality that comes bundled with Adobe ColdFusion. But that means you are loading the Hibernate libraries, PDF libraries or JDBC drivers even if you don't need them. There is a second type of Lucee server called "Lucee Light" which contains all the core engine, but with zero extensions. People creating custom docker builds for example will start with Lucee Light and then add back only the extensions their app needs. To get a feel for all the Lucee extensions available, see this page that lists all official extensions.
We're now publishing CF Engines to ForgeBox based on the Lucee Light builds which allows you to start up a Lucee Light server. These are under a ForgeBox package named lucee-light and we've also backfilled all the same versions that exist for the normal lucee engine. Note, the three bullets points above apply to Lucee Light as well, Just replace lucee with lucee-light and you're good to go.
If you have questions about how to install extensions into a Lucee light server, please hit us up on Slack and we can show you several ways to manage that.
{
"runwar" : {
"args" : "--resource-manager-logging=true"
}
}server set runwar.args="--case-sensitive-web-server=true"{
"runwar" : {
"args" : "--case-sensitive-web-server=true"
}
}server set runwar.args="--case-sensitive-web-server=false"{
"runwar" : {
"args" : "--case-sensitive-web-server=false"
}
}server set runwar.args="--cache-servlet-paths=true"{
"runwar" : {
"args" : "--cache-servlet-paths=true"
}
}<major>.<minor>.<patch>.<build>[-<preReleaseID>]
# Ex of an unstable build
5.3.4.84-SNAPSHOT
# Or a stable build
5.3.4.80<major>.<minor>.<patch>[-<preReleaseID>]+<build>
# Ex of an unstable build
5.3.4-SNAPSHOT+84
# Or a stable build
5.3.4+80server start cfengine=lucee@be# Latest Lucee 5.3.7 build
server start [email protected]
# Latest Adobe 2018 update
server start cfengine=adobe@2018
# Lucee bleeding edge-- latest snapshot
server start cfengine=lucee@be# Pinned exact Adobe version
server start [email protected]+320417
# Pinned exact Lucee version
server start [email protected]+48# Latest stable
server start cfengine=lucee-light
# Specific version
server start [email protected]
# Bleeding edge
server start cfengine=lucee-light@beEvery time you start a server, the settings used to start it are saved in a server.json file in the web root. Any parameters that aren't supplied to the start command are read from this file (if it exists) and used as defaults. Here are the possible properties for a server.json file:
/server.json
{
"name": "",
"openBrowser": true,
"openBrowserURL" : "http://localhost/admin/login",
"startTimeout": 240,
"stopsocket": 50123,
"debug": false,
"trace": false,
"console": false,
"profile": "prod",
"dockEnable": true,
"trayEnable": true,
"trayicon": "/path/to/trayicon.png",
"env" : {
"ANYTHING_HERE" : "you want",
"THESE_ARE_ADDED" : "As environment variables to the server"
}
"trayOptions": [
{
"label": "Foo",
"action": "openbrowser",
"url": "http://${runwar.host}:${runwar.port}/foobar.cfm",
"disabled": false,
"image": "/path/to/image.png"
},
{
"label":"Open VScode",
"action":"runAsync",
"command":"code .", //command is run relative to webroot, for box commands begin command with `box`
"disabled": false,
"image": "/path/to/image.png"
},
{
"label":"Open Webroot",
"action":"openfilesystem",
"path":"./", //path is relative to your webroot
"disabled": false,
"image": "/path/to/image.png"
}
],
"jvm": {
"heapSize": 512,
"minHeapSize": 256,
"args" : [ //can be a string or an array
"-XX:+UseG1GC",
"-XX:-CreateMinidumpOnCrash",
"--add-opens=java.base/java.net=ALL-UNNAMED"
],
"javaHome" : "/path/to/java/home",
"javaVersion" : "openjdk11"
},
"web": {
"host": "127.0.0.1",
"webroot": "src/cfml",
"directoryBrowsing": true,
"accessLogEnable": true,
"maxRequests":30,
"gzipEnable": true,
"gzipPredicate": "regex( '(.*).css' ) and request-larger-than( 500 )",
"aliases": {
"/foo": "../bar",
"/js": "C:/static/shared/javascript"
},
"errorPages": {
"404": "/path/to/404.html",
"500": "/path/to/500.html",
"default": "/path/to/default.html"
},
"welcomeFiles": "index.cfm,main.cfm,go.cfm",
"HTTP": {
"enable": true,
"port": 8080
},
"SSL": {
"enable": false,
"port": 443,
"certFile": "",
"keyFile": "",
"keyPass": ""
},
"AJP": {
"enable": false,
"port": 8009
},
"rewrites": {
"enable": true,
"logEnable": true,
"config": "/path/to/config.xml",
"statusPath": "/rewriteStatus",
"configReloadSeconds": 60
},
"basicAuth": {
"enable": true,
"users": {
"userName1": "password1",
"userName2": "password2"
}
},
"rules": [
"path-suffix(/box.json) -> set-error(404)",
"path-prefix(.env) -> set-error(404)",
"path-prefix(/admin/) -> ip-access-control(192.168.0.* allow)",
"path(/sitemap.xml) -> rewrite(/sitemap.cfm)",
"disallowed-methods(trace)"
],
//3 ways to specify rulesFile
"rulesFile": "../secure-rules.json",
// Or...
"rulesFile": [
"../security.json",
"../rewrites.json",
"../app-headers.json"
],
// Or...
"rulesFile":"../rules/*.json",
"blockCFAdmin": false,
"blockSensitivePaths": true,
"blockFlashRemoting": true
},
"app": {
"logDir": "",
"libDirs": "",
"webConfigDir": "",
"serverConfigDir": "",
"webXML": "",
"WARPath": "",
"cfengine": "[email protected]",
"restMappings": "/rest/*,/api/*",
"serverHomeDirectory": "",
"sessionCookieSecure": true,
"sessionCookieHTTPOnly": true,
"webXMLOverride" : "path/to/web.xml",
"webXMLOverrideForce" : false
},
"runwar": {
"jarPath": "/path/to/runwar.jar",
"args" : [ //can be a string or an array
"--runwar-option",
"value",
"--runwar-option2",
"value2"
]
"XNIOOptions": {
"WORKER_NAME": "MyWorker"
},
"UndertowOptions": {
"ALLOW_UNESCAPED_CHARACTERS_IN_URL": true
}
}
}