Is it possible to use ColdBox only to load CFMigrations, and render nothing else?

I have legacy code (non-mvc) that I’ve been bringing to CommandBox (which I love!), and one upgrade is bringing versioning to databases with migrations. CFMigrations looks like a perfect fit, and so I set up commandbox-migrations CLI on my local machine. It’s working great.

What I’m trying to do is figure how to call the up and down functions from within the app now. For that, I need the ColdBox module cfmigrations. But I don’t want to use the MVC framework otherwise, only for using this module.

Is it possible to use ColdBox only to load the cfmigrations module with custom module settings, and let the legacy code render otherwise?

Just to clarify, are you trying to avoid using the up and down commands available from the CLI?
@elpete should be able to confirm if there is a way to call the up/down from inside of a non-ColdBox app. I know the CLI commands don’t care since they are done entirely from the CLI without touching the app.

1 Like

If I could call those CLI commands from the app, that would actually be a better solution.

A little context: I’m aiming to build containers that can migrate a database if needed. This would enable development environments to have local SQLite databases spun up with seeds, and production environments have other SQL database connections migrated to the proper version.

If I can do that with a CLI added into a container, that would be perfect. Can that be included in box.json as a dependency?

So without ColdBox, would I do something like:

  • add commandbox-migrations as a dependency in box.json
  • ensure box install --production is in the docker file

But then, how would I call the following shell script, box script, task (or just the CLI commands) from the app to execute:

box migrate install
box migrate up
box migrate seed run

(using the configurations already saved in .cfmigrations.json)

Oh, wait. I would use cfexecute, wouldn’t I? :crazy_face:

So the part I’m stuck on right now is how to call the cfexecute command. Right now, I have it used as:

variables.cli = findNoCase( "Windows", server.os.name ) > 0 ? "box.exe" : "box";
variables.rootDirectory = expandPath( "../" ); /* using multi-site mode, where the webroots are one sub-folder deep within the project root */

var execResult = "";
cfexecute( name=variables.cli, directory=variables.rootDirectory, arguments="migrate install", variable="execResult" );

On Windows (non-container), it’s working great. But when running in a container, it’s throwing an error:
Error invoking external process

Any ideas what could be the reason?

Not at all - it could be anything. File permissions, execute permissions, database query error, missing dependency error… we can only guess since those four words (Error invoking external process) tell us absolutely nothing.

I would take at least three steps back and ask yourself: Do I NEED to run cfmigrations from within the ColdBox app? So far I haven’t seen this requirement outlined. There are many ways to run a command from a docker container deployment process, which are generally more straightforward and easier to debug than a cfexecute() call.

1 Like

Thanks, I appreciate the insight. So then, this error just says “something went wrong when calling the executable”, got it. It’s too bad that cfexecute’s errorVariable doesn’t seem to provide any information after erroring.

So I took steps to debug this. To confirm that calling the CLI works in using cfexecute, I’m able to call

<cfexecute name="box" arguments="version"...>
<cfexecute name="box" arguments="migrate help"...>

and it works, but using migrate install, migrate up, migrate seed run as the arguments is where things break down.

And to confirm that creating the SQLite database and queries works, the following succeeds:

queryExecute("CREATE TABLE IF NOT EXISTS `HelloWorld` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` TEXT NOT NULL)");

and I can interact with the table.

Do you have any suggestions how to further go about debugging this?

Regarding the introspection, it would be nice to have migrations as part of the container to avoid separating the database versioning from the app versioning. So then, when deploying a container, whatever database it is connected with can be upgraded to the latest migrations. And if it’s a local development db (like SQLite), it would just spin one up on the fly that could also be seeded or refreshed.

FYI, this is not halting any work now. I’ve written a migration mechanism that is compatible with how cfmigrations works, so everything is working now. This has become more a curiosity for me to solve, but I think I’ll approach this mystery at a later time.

Thank you so much @bdw429s for helping me explore calling the CLI from the program, and thank you @MichaelBorn for the insight and introspective question–it got me to think about solving this in a simpler way that in the end was more efficient and versatile.

1 Like

I would guess you need to break those into different commands:

but that’s just a guess. :slight_smile:

Welcome! Good luck! Glad you’ve gotten it sorted for now.

1 Like

You’re right, and I should’ve clarified, but that is how I was calling them. I don’t know why it didn’t work.