Coldfusion/Lucee Running on MeLE Fanless Stick PC

I started out with a MeLE PCG02 Mini PC Stick Fanless Windows 11 Pro stick computer running Windows 11.

This is a great little computer for your TV.

You can check it out in action at http://blusol.ddns.net NOTE: It may not always be running as I'm constantly playing with it bringing it offline. Also, this is running on home internet and a dynamic dns service. 

But can you imagine the possibilities? I'm thinking of a dynamic system for displaying Real Estate on a TV for local Realtors.

What will you use yours for?

How to Host Multiple Websites with Ubuntu Linux and Lucee

Note: This is configured to work with Ubuntu 16.04LTS

Step 1:

git clone https://github.com/foundeo/ubuntu-nginx-lucee

Step 2:

Set permissions on install script

cd ubuntu-nginx-lucee
chmod u+x install.sh

Step 3:

Execute the install script and answer y to any install prompts

./install.sh

Step 4:

Configure nginx for your domain

nano /etc/nginx/sites-enabled/me.example.com.conf

server {
	listen 80;
	server_name me.example.com;
	root /web/me.example.com/wwwroot/;
	access_log /var/log/nginx/me.example.com.access.log;
	error_log /var/log/nginx/me.example.com.error.log;
	include lucee.conf;
}

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

sudo ln -s /etc/nginx/sites-available/me.example.com.conf /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/ {
    allow YOUR.EXTERNAL.DESKTOP.IP;
    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

References: 

https://github.com/foundeo/ubuntu-nginx-lucee

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.

![](http://marlin.blusol.io:8080/800x/https://drive.google.com/a/southeastern360.com/uc?id=0By5I5hN7xKMacEhONDVSeUw3RWc)
![](http://marlin.blusol.io:8080/800x/https://drive.google.com/a/southeastern360.com/uc?id=0By5I5hN7xKMabjNoYzRNYXlwNVE)
![](http://marlin.blusol.io:8080/800x/https://drive.google.com/a/southeastern360.com/uc?id=0By5I5hN7xKMaTWNfY29NVnI0WWs)

Resources:

Private S3 Server with Docker+Scality S3 Server

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

Connection Options: https://github.com/scality/S3/blob/master/README.md#command-line-tools

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
 HostName bitbucket.org
 IdentityFile ~/.ssh/privatebitbucket

Copy the new key to clipboard to add to bitbucket.

pbcopy < ~/.ssh/privatebitbucket.pub

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! \
mysql:latest 

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 'DB_CLASS=org.gjt.mm.mysql.Driver' \
-e 'DB_USER=root' \
-e 'DB_PASSWORD=superSecretPassword! \
ortussolutions/contentbox

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 \
nginx:latest 

/etc/nginx/conf.d/docker.blusol.io.conf

server{
       	listen 80;
        server_name docker.blusol.io;
        location / {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_pass "http://docker_blusol_io:8080";
        }

}

Resources

https://www.ortussolutions.com/blog/contentbox-docker-image-351-released

http://portainer.io/

Flexible and Advanced ContentBox Layouts for Custom Modules

UPDATE: Check out ColdBox CBT instead.

https://github.com/coldbox-modules/cbox-cbt

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 https://www.ortussolutions.com/blog/the-12-tips-of-contentbox-christmas-day-6-themed-modules 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.qContacts.name;
		prc.demoAddress1 	=	prc.qContacts.address1;
		prc.demoCity 		=	prc.qContacts.city;
		prc.demoState 		=	prc.qContacts.state;
		prc.demoZip 		=	prc.qContacts.zip;
		cbHelper.prepareUIRequest('pagesNoHeader');
		event.setView( "home/list" );

}		

Sample View home/list.cfm

<cfoutput>
#cb.contentStore('demo-list', 'ContentStore item not found')#
</cfoutput>

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>
	<div class="col-md-4">
		<h4>Custom/Editable Section</h4>
		<p>This section can contain specific information outside of the module.</p>
	</div>
</div>
<div class="row">
	<div class="col-md-12">
		{ {{RenderView view='home/demoView' module='myModule' cache='false'}} }
	</div>
</div>

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