How to Host Multiple Websites with Ubuntu Linux and Lucee

Note: This is configured to work with Ubuntu 16.04LTS

Step 1:

git clone

Step 2:

Set permissions on install script

cd ubuntu-nginx-lucee
chmod u+x

Step 3:

Execute the install script and answer y to any install prompts


Step 4:

Configure nginx for your domain

nano /etc/nginx/sites-enabled/

server {
	listen 80;
	root /web/;
	access_log /var/log/nginx/;
	error_log /var/log/nginx/;
	include lucee.conf;

Create the symbolic link in sites-enabled to enable the site:

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

After making changes you need to restart or reload nginx:

sudo service nginx restart

Tips/Tricks & FAQ

Q: How do I access the Lucee admin?

Edit /etc/nginx/lucee.conf

location ~* /lucee/ {
    deny all;
    include lucee-proxy.conf;

Q: What's the Lucee default password?

The password is automatically generated for you on install and is stored in /root/lucee-admin-password.txt

cat /root/lucee-admin-password.txt


Resize gDrive Images On The Fly

Note: I have taken down the image server used for testing, however everything else here can be used as reference.



Private S3 Server with Docker+Scality S3 Server

docker run -d \
--name mys3server \
-p 8000:8000 \
-e SCALITY_SECRET_ACCESS_KEY=mySuperSecretKey123 \
-v s3data:/usr/src/app/localData \
-v s3metaData:/usr/src/app/localMetadata \

Connection Options:

I prefer the s3cmd.

Once you configured ~/.s3cfg you here's some commands you can run.

#This will create the bucket webfiles
s3cmd mb s3://webfiles

#This will upload a test.txt file from the mac desktop to the  webfiles bucket.
s3cmd put ~/Desktop/test.txt  s3://webfiles

#This will List All objects (buckets, files inside buckets)
s3cmd la

#This will list all files in the webfiles bucket.
s3cmd ls s3://webfiles

Private Bitbucket Repo's with CommandBox and Mac

ssh-keygen -f ~/.ssh/privatebitbucket -C "privatebitbucket"

Edit the ~/.ssh/config file.

Host privatebitbucket
 IdentityFile ~/.ssh/privatebitbucket

Copy the new key to clipboard to add to bitbucket.

pbcopy < ~/.ssh/

Login to bitbucket and add the ssh key:

List the currently loaded keys:

$ ssh-add -l

If necessary, add your new key to the list:

$ ssh-add ~/.ssh/privatebitbucket

List the keys again to verify the add was successful:

$ ssh-add -l

   _____                                          _ ____             
  / ____|                                        | |  _ \            
 | |     ___  _ __ ___  _ __ ___   __ _ _ __   __| | |_) | _____  __ 
 | |    / _ \| '_ ` _ \| '_ ` _ \ / _` | '_ \ / _` |  _ < / _ \ \/ / 
 | |___| (_) | | | | | | | | | | | (_| | | | | (_| | |_) | (_) >  <  
  \_____\___/|_| |_| |_|_| |_| |_|\__,_|_| |_|\__,_|____/ \___/_/\_\   v3.7.0-SNAPSHOT+00685

Welcome to CommandBox!
Type "help" for help, or "help [command]" to be more specific.

CommandBox:you> install git+ssh://git@privatebitbucket:[BITBUCKETUSERNAME]/[privaterepo].git

Docker Swarm + Portainer + mySQL + NGINX + CommandBox/ContentBox

start docker swarm

docker swarm init

add the docker portainer service for easy management

docker service create \
    --name portainer \
    --publish 9000:9000 \
    --constraint 'node.role == manager' \
    --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
    portainer/portainer \
    -H unix:///var/run/docker.sock

login to port 9000, add two named volumes to be used below:

  1. mysqldata
  2. nginx

docker swarm join info coming soon

create overlay network (details coming soon)

This may not be necessary now that I'm running all containers as a service (even though I only have 1 instance running)

add mysql service

docker service create \
--name mysql \
--network bluewater \
-p 3306:3306 \
--mount type=volume,source=mysqldata,target=/var/lib/mysql,readonly=false \
--env MYSQL_ROOT_PASSWORD=superSecretPassword! \

You will need to login and create a database.

start docker contentbox image

docker service create \
--name docker_blusol_io \
--network bluewater \
-e 'installer=true' \
-e 'rewrites=true' \
-e 'cfconfig_whitespaceManagement=white-space-pref' \
-e 'cfconfig_adminPassword=superSecretCFMPassword! \
-e "DB_CONNECTION_STRING=jdbc:mysql: //mysql:3306/blusol_docker?useUnicode=true&characterEncoding=UTF-8&useLegacyDatetimeCode=true" \
-e '' \
-e 'DB_USER=root' \
-e 'DB_PASSWORD=superSecretPassword! \

adding nginx for reverse proxy

docker service create \
--name nginx \
--network bluewater \
-p 80:80 \
-p 443:443 \
--mount type=volume,source=nginx,target=/etc/nginx,readonly=false \


       	listen 80;
        location / {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_pass "http://docker_blusol_io:8080";



Flexible and Advanced ContentBox Layouts for Custom Modules

UPDATE: Check out ColdBox CBT instead.

Origional Post:

I had an epiphany today trying to figure out a flexible way to re-use a ContentBox module in such a way that each view could be customized per client without the need of creating hundreds of individual "view" files.

If you have not already created a custom ContentBox Themed Module let me suggest you stop what you're doing and head over to and get started.

Sample Handler:

component {

	// DI
	property name='ContactService' inject='ContactService';
	property name='MessageBox' inject='MessageBox@cbMessageBox';

	function index() {
		list( argumentCollection=arguments );

	function list(event,rc,prc){
		// Query our data just like normal.
		prc.qContacts		=	contactService.list();
		// To use the data in ContentBox as a dynamic variable we need to flatten things out a bit.
		prc.demoName 		=;
		prc.demoAddress1 	=	prc.qContacts.address1;
		prc.demoCity 		=;
		prc.demoState 		=	prc.qContacts.state;
		prc.demoZip 		=;
		event.setView( "home/list" );


Sample View home/list.cfm

#cb.contentStore('demo-list', 'ContentStore item not found')#

The above view will look for a ContentStore item slug called demo-list.

ContentBox ContentStore demo-list

This is where you will create the layout for your data that can be edited and modified without having to edit the core view files. This concept is a work in progress, but it does work and I have a feeling it will be expanded on in the future.

<div class="row">
	<div class="col-md-8">
		<h1>$ {prc:demoName}</h1>
		$ {prc:demoAddress1}<br />
		$ {prc:demoCity},&nbsp; $ {prc:demoState} $ {prc:demoZip}<br />
	<div class="col-md-4">
		<h4>Custom/Editable Section</h4>
		<p>This section can contain specific information outside of the module.</p>
<div class="row">
	<div class="col-md-12">
		{ {{RenderView view='home/demoView' module='myModule' cache='false'}} }

RenderView demoView

Renders the above view.

Live Demo

Below is an example of the finished result I've been working on:

Editor Preview

NOTE: This was put together quickly so I wouldn't forget about it, check back later for updates

ContentBox CRUD with CommandBox

install crud-cbadmin

contentbox create module directory=modules/contentbox/modules_user name=quickCRUD

cd modules/contentbox/modules_user/quickCRUD

coldbox create orm-entity entityName=Property properties=first,last,email,updated_at:timestamp,created_at:timestamp table=myProperties primaryKey=id generator=native

contentbox create crud-cbadmin entity=models.Property pluralName=Properties moduleName=quickCRUD table=myProperties



To access the newly created CRUD page visit: