Starting as service fails, but not when starting from CLI

Good morning. I am using ComnandBox on Ubuntu 22.04, and working from singleServerMode being set true. I’m having trouble starting my CommandBox server as a system service. I’ve followed the steps on this page, but I’m having an issue.

My webroot is located at /web/default/wwwroot/. My server.json is located at /web/default/server.json.

My mySite.service looks like this:

[Unit]
Description=mySite.com Web Service

[Service]
User=ubuntu
Group=ubuntu
ExecStart=/usr/local/bin/box server start /web/default/server.json
Type=forking

[Install]
WantedBy=multi-user.target

When I try to start this with sudo systemctl start mySite.service, I get this error, revealed with sudo systemctl status mySite.service:

ubuntu@ip-172-26-9-15:~$ sudo systemctl status mySite.service
× mySite.service - mySite.com Web Service
     Loaded: loaded (/lib/systemd/system/mySite.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Sun 2024-02-11 18:42:34 UTC; 21s ago
    Process: 3224 ExecStart=/usr/local/bin/box server start /web/default/server.json (code=exited, status=1/FAILURE)
        CPU: 23.174s

Feb 11 18:42:33 ip-172-26-9-15 box[3224]: called from /system/services/CommandService.cfc: line 443
Feb 11 18:42:33 ip-172-26-9-15 box[3224]: called from /system/services/CommandService.cfc: line 245
Feb 11 18:42:33 ip-172-26-9-15 box[3224]: called from /system/Shell.cfc: line 862
Feb 11 18:42:33 ip-172-26-9-15 box[3224]: called from /system/Bootstrap.cfm: line 124
Feb 11 18:42:33 ip-172-26-9-15 box[3224]: 
Feb 11 18:42:33 ip-172-26-9-15 box[3224]: To enable full stack trace, run config set verboseErrors=true
Feb 11 18:42:34 ip-172-26-9-15 systemd[1]: mySite.service: Control process exited, code=exited, status=1/FAILURE
Feb 11 18:42:34 ip-172-26-9-15 systemd[1]: mySite.service: Failed with result 'exit-code'.
Feb 11 18:42:34 ip-172-26-9-15 systemd[1]: Failed to start mySite.com Web Service.
Feb 11 18:42:34 ip-172-26-9-15 systemd[1]: mySite.service: Consumed 23.174s CPU time.
ubuntu@ip-172-26-9-15:~$ /usr/local/bin/box server start /web/default/server.json
 × | Starting Server
   | > key [WEBROOT] doesn't exist
   |------------------------------                                                                                                                                                                              


ERROR (5.9.1+00767)

key [WEBROOT] doesn't exist


/modules/commandbox-dotenv/interceptors/LoadEnvPreServers.cfc: line 11
9: 
10: 	function preServerStart(interceptData) {
11: 		var webRoot = variables.fileSystemUtil.normalizeSlashes( arguments.interceptData.serverDetails.serverInfo.webRoot );
12: 		var webRootEnvFile = webRoot.listAppend( variables.moduleSettings.fileName, "/", false );
13: 		var envStruct = variables.envFileService.getEnvStruct( webRootEnvFile );
called from /system/wirebox/system/core/events/EventPool.cfc: line 121
called from /system/wirebox/system/core/events/EventPool.cfc: line 95
called from /system/wirebox/system/core/events/EventPoolManager.cfc: line 59
called from /system/services/InterceptorService.cfc: line 57
called from /system/services/InterceptorService.cfc: line 61
called from /system/services/ServerService.cfc: line 352
called from /system/modules_app/server-commands/commands/server/start.cfc: line 171
called from /system/services/CommandService.cfc: line 443
called from /system/services/CommandService.cfc: line 245
called from /system/Shell.cfc: line 862
called from /system/Bootstrap.cfm: line 124

Just as additional hepful info, I tried running this command: /usr/local/bin/box server start /web/default/server.json from the Ubuntu shell, and ran into the same error.

However, and this is the weird part, when I navigate in my shell to cd /web/default/ and just run box, I am able to start CommandBox and run server start, and the server starts with no trouble whatsoever.

My /web/default/server.json looks like this:

{
    "web":{
        "webroot":"/web/default/wwwroot",
        "HTTP":{
            "enable":true,
            "port":"8080"
        },
        "host":"0.0.0.0",
        "welcomeFiles":"default.cfm",
        "rewrites":{
            "enable":"true"
        },
        "SSL":{
            "certFile":"/etc/ssl/certs/mySite_com_chain.crt",
            "keyFile":"/etc/ssl/private/mySite_com.key",
            "enable":"true",
            "port":"8081",
            "forceSSLRedirect":"true"
        },
        "blockCFAdmin":"false",
        "accessLogEnable":"true",
        "gzipEnable":"true",
        "blockSensitivePaths":"true",
        "directoryBrowsing":"false"
    },
    "profile":"production",
    "name":"wwwroot",
    "openbrowser":"false",
    "app":{
        "cfengine":"lucee@5.4.4.38"
    },
    "env":{
        "AWS_ACCESS_KEY_ID":"not_posting_this_obviously",
        "AWS_SECRET_ACCESS_KEY":"not_posting_this_obviously"
    },
    "JVM":{
        "heapSize":"512",
        "properties":{
            "java.awt.headless":"true"
        },
        "args":[
            "-XX:+UseConcMarkSweepGC"
        ]
    },
    "fusionreactor":{
        "port":"8088",
        "enable":"false"
    }
}

So I’m very, very confused as to what’s happening here. Any ideas or thoughts on why I’m able to start the server normally through the CommandBox CLI, but can not when it comes to running this as a service?

Thank you kindly for any help anybody can offer.

That is odd. That webroot variable should never NOT be defined. I would start by checking the user the server is running as. If it’s different from the user you use in bash, you have two different CommandBox homes, with potentially different settings and modules. If you need to run under another user, I recommend “pinning” the CommandBox home to a shared folder so all users share the same CommandBox installation.

It could be related to the single server mode. Are you on the latest version of the dotenv module?

Good afternoon, and thank you for the reply.

I am using the most current CommandBox installed within the last two months, so I don’t think the dotenv module is the concern.

My mysite.service file is supposed to run as:

[Service]
User=ubuntu
Group=ubuntu
ExecStart=/usr/local/bin/box server start /web/default/server.json

But … that is not working. I’ve even tried to just go to the Ubuntu shell and execute:

/usr/local/bin/box server start /web/default/server.json

This just gives the same error. So … I’m not sure what’s to blame/account for this.

I have looked for any other instances of the directory .CommandBox on the machine and there is only one, located at /home/ubuntu/.CommandBox/

Also, for reference, these are the permissions structures for the /web/default/ directory and its contents

drwxr-xr-x 3 ubuntu ubuntu 4096 Feb 13 00:41 /web/default/
-rw-rw-r--  1 ubuntu ubuntu   88 Jan 17 00:14 box.json
-rw-r--r--  1 ubuntu ubuntu 1226 Feb 11 18:41 server.json
drwxr-xr-x 49 ubuntu ubuntu 4096 Feb 12 00:57 wwwroot

Just to say it again: when I navigate to the directory cd /web/default/ and run box from the shell, CommandBox loads just fine and I can start my server, no trouble at all. The issue is when trying to run a server start /web/default/server.json from the shell. For example:

ubuntu@ip:/web/default$ box server start /web/default/server.json
(Error pasted above in earlier post.)

Even this causes problems:

box server list  /web/default/server.json
Processing (1) servers, please wait...
No server configurations found with the incoming filters!

But, again, just running box, alone, is fine, and then when I am in the CommandBox shell, and run server start, it starts Lucee up just fine, no trouble.

To be clear, that’s not how the server list command works. Check out the command help for it (run it with a question mark after it) and you’ll see there’s no option to pass the path to a serverConfigFile to it. That command will only filter on the name of the server.

I would run

server list

by itself and see what all servers are defined. Specifically do you have two servers pointing to the same server.json file or with the same name, etc? Also, run

server info serverConfigFile=/web/default/server.json --verbose

and see what file it’s finding.

Good afternoon, @bdw429s.

My apologies for misapplying the server list command. I’ve tried some things with server info and I’ll share the results, here:

ubuntu@ip:~$ /usr/local/bin/box server info /web/default/server.json --verbose

ERROR (5.9.1+00767)

key [ID] doesn't exist

/home/ubuntu/.CommandBox/cfml/system/modules_app/server-commands/commands/server/status.cfc: line 93
91: 
92: 			// If this is a server  match OR are we just showing everything
93: 			if( thisServerInfo.id == serverInfo.id || arguments.showAll ){
94: 
95: 				// Null Checks, to guarantee correct struct.
called from /home/ubuntu/.CommandBox/cfml/system/services/CommandService.cfc: line 443
called from /home/ubuntu/.CommandBox/cfml/system/services/CommandService.cfc: line 245
called from /home/ubuntu/.CommandBox/cfml/system/Shell.cfc: line 862
called from /home/ubuntu/.CommandBox/cfml/system/Bootstrap.cfm: line 124

lucee.runtime.exp.ExpressionException: key [ID] doesn't exist

But notice the difference when I run this (with serverConfigFile= added):

ubuntu@ip:~$ /usr/local/bin/box server info serverConfigFile=/web/default/server.json --verbose
Looking for server JSON file by convention: /web/default/server.json
webroot pulled from server's JSON: /web/default/wwwroot/

wwwroot (running)  0.0.0.0:8080 --> /web/default/wwwroot/
  CF Engine: lucee 5.4.4+38
  Last Started: 13-Feb-2024 17:40:56

So, it looks like things work when I use the serverConfigFile=.

Next, I went into the mySite.service and updated this line:

ExecStart=/usr/local/bin/box server start /web/default/server.json

And updated it to this:

ExecStart=/usr/local/bin/box server start serverConfigFile=/web/default/server.json

The service works now!

If this is expected behavior, I might recommend updating the documentation at this page to reflect the necessity of the serverConfigFile= tag when referencing a specific .json file.

If this is still unexpected behavior, how might I be able to help diagnose the issue for you?

Thank you again.

Hold on. I don’t know where you got that syntax from, but you didn’t get it from me. That’s totally invalid to pass the path to a server.json in as the name parameter. Only the server start command has that shortcut. If you look back at my previous message, I said to run this:

which uses serverConfigFile=.

Now, I actually forgot you were using single server mode (which I’m 90% sure is related to your issues). And in single server mode, whatever name or serve config file you pass in is actually totally ignored. I’m not sure how you even got the

error because when no server is found the server info command usually just outputs nothing. But again, I think this is an issue related to single server mode.

What I was really interested in was the output from server list

But you seemed to skip entirely over that suggestion :confused:

Yeah, that makes zero sense, lol. For two reasons, really.

  • The server start command specifically allows the first param to be the name OR the serverConfigFile so changing the argument literally should have done nothing
  • Again, you’re in single server mode, so it really shouldn’t even matter what name or server config file you pass, CommandBox should start the one and only server that is supposed to be defined.

Now maybe there’s more than one server somehow defined? Hard to say. That’s why I wanted the server list output.

I was attempting different commands to run from the shell to test this issue, based on the command provided in the “Starting as a Service” documentation.

Oh! Sorry, yeah, I guess I didn’t do that because there was definitely only one server defined:

CommandBox:default> server list
Processing (1) servers, please wait...

wwwroot (running)
  http://0.0.0.0:8080
  https://0.0.0.0:8081
  CF Engine: lucee 5.4.4+38
  Webroot: /web/default/wwwroot/
  Last Started: 13-Feb-2024 17:40:56

There definitely has always been only one server listed, so I didn’t think much of not running that, but I understand how you wouldn’t be able to know that without me saying something!

I mean, sure, but, I’m telling you, that’s how it’s functioning. The change by adding serverConfigFile= made the service function normally. Here’s an example for you, see this. When I run:

ubuntu@ip:~$ /usr/local/bin/box server start /web/default/server.json

I get this response:

 × | Starting Server
   | > key [WEBROOT] doesn't exist
   |------------------------------                                                                                


ERROR (5.9.1+00767)

key [WEBROOT] doesn't exist

But, when I run this:

ubuntu@ip:~$ /usr/local/bin/box server start serverConfigFile=/web/default/server.json

The server starts just fine, no problems at all.

So, I understand you’re saying that this is a ‘lol’ behavior, but, that’s how it’s behaving. I’m not sure why. I’m happy to help diagnose what appears to be a bug, or at least an unexpected behavior.

I’m curious where are the server settings for the single server mode are held? How does CommandBox know to go to /web/default/server.json for the info to start the server when it’s set to single server mode? (By the way, I set single server mode because CommandBox has trouble properly stopping and starting servers during crashes/hangs/shutdowns and other weird events when running as a service, and on a test server I was getting lots of duplicate server issues, and errors with CommandBox thinking the server never actually shut down.)

This is the output of config show:

CommandBox:default> config show
{
    "modules":{
        "commandbox-cfconfig":{
            "exportOnStop":"true"
        },
        "commandbox-fusionreactor":{
            "licenseKey":"key"
        },
        "commandbox-update-check":{
            "dateLastChecked":"February, 13 2024 20:46:30 +0000"
        }
    },
    "server":{
        "singleServerMode":"true"
    },
    "verboseErrors":"true"
}

The only other thing that might be some kind of weird issue is that I have placed server.json in a directory above the webroot, so, it’s /web/default/server.json and the web root is /web/default/wwwroot/.