Skip to content

Instantly share code, notes, and snippets.

@mtongnz
Created March 8, 2024 03:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mtongnz/f3ca13c7ff8472e54bbb7ff8cec265e1 to your computer and use it in GitHub Desktop.
Save mtongnz/f3ca13c7ff8472e54bbb7ff8cec265e1 to your computer and use it in GitHub Desktop.
Unraid user script to run docker compose manager commands
#!/usr/bin/php
<?php
#description=Docker Compose functions
#argumentDescription=arg1: action (up, down, stop, update, down_up) arg2+: compose project names
#argumentDefault=down_up dns tunnels websites multimedia downloads websites automation essentials
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once("/usr/local/emhttp/plugins/compose.manager/php/defines.php");
require_once("/usr/local/emhttp/plugins/compose.manager/php/util.php");
require_once("/usr/local/emhttp/plugins/dynamix/include/Wrappers.php");
// define("SHELL_FORMAT", [
// 'green' => "\033[32m",
// 'yellow' => "\033[33m",
// 'red' => "\033[31m",
// 'bold' => "\033[1m",
// 'default' => "\033[0m",
// ]);
# Split out args
$args = preg_split('/(".*?")/', $argv[1],-1,PREG_SPLIT_DELIM_CAPTURE);
for ($key=0; $key<count($args); $key++) {
$arg = trim($args[$key]);
if ($arg == '') {
array_splice( $args, $key, 1);
$key-=1;
} else if (!str_contains($arg,'"')) {
$a = explode(' ', $arg);
array_splice( $args, $key, 1, $a );
$key+=count($a)-1;
} else {
$args[$key] = str_replace('"', "", $arg);
}
}
for ($a = 1; $a < count($args); $a++) {
$project = $args[$a];
echo "Compose project $project ";
switch ($args[0])
{
case 'up':
echo "going up...\n";
$cmd = echoComposeCommand('up', $project);
system($cmd);
break;
case 'down':
echo "going down...\n";
$cmd = echoComposeCommand('down', $project);
system($cmd);
break;
case 'down_up':
echo "going down...\n";
$cmd = echoComposeCommand('down', $project);
system($cmd);
echo "\n\nCompose project $project going up...\n";
$cmd = echoComposeCommand('up', $project);
system($cmd);
break;
case 'stop':
echo "stopping...\n";
$cmd = echoComposeCommand('stop', $project);
system($cmd);
break;
case 'update':
echo "updating...\n";
$cmd = echoComposeCommand('update', $project);
system($cmd);
break;
case 'checkUpdates':
echo "checking for updates...\n";
$cmd = echoComposeCommand('checkUpdates', $project);
system($cmd);
break;
default:
echo "INVALID ACTION!\n";
exit;
}
echo "\n\n";
}
function echoComposeCommand($action, $project)
{
global $plugin_root;
$path = "/boot/config/plugins/compose.manager/projects/$project";
$unRaidVars = parse_ini_file("/var/local/emhttp/var.ini");
if ($unRaidVars['mdState'] != "STARTED" ) {
echo $plugin_root."/scripts/arrayNotStarted.sh";
}
else
{
$composeCommand = array($plugin_root."scripts/compose.sh");
$projectName = basename($path);
if ( is_file("$path/name") ) {
$projectName = trim(file_get_contents("$path/name"));
}
$projectName = sanitizeStr($projectName);
$projectName = "-p $projectName";
$action = "-c $action";
$composeCommand[] = $action;
$composeCommand[] = $projectName;
$composeFile = "";
if( isIndirect($path) ) {
$composeFile = getPath($path);
$composeFile = "-d $composeFile";
}
else {
$composeFile .= "$path/docker-compose.yml";
$composeFile = "-f $composeFile";
}
$composeCommand[] = $composeFile;
if ( is_file("$path/docker-compose.override.yml") ) {
$composeOverride = "-f $path/docker-compose.override.yml";
$composeCommand[] = $composeOverride;
}
if ( is_file("$path/envpath") ) {
$envpath = "-e " . trim(file_get_contents("$path/envpath"));
$composeCommand[] = $envpath;
}
$i = 0;
$composeCommand = array_reduce($composeCommand, function($v1, $v2) use (&$i) {
if ($v2[0] == "-") {
$i++; // increment $i
return $v1." ".$v2;
}
else{
return $v1.$v2;
}
}, "");
return $composeCommand;
}
}
?>
@mtongnz
Copy link
Author

mtongnz commented Mar 8, 2024

Add this script to your user scripts on unraid. It allows you to start/stop/restart/update your docker compose manager projects. Note that you need to have docker compose manager plugin installed.

Change #argumentDefault (line 5) to have whatever you want the default action to be. In my case, I want it to "down" all my projects and then "up" them. This effectively restarts the projects. I have this script so to stay on array start to ensure my services are all started in the correct order.

Note it takes the argument "action" followed by one or more projects you want to perform the action on.

@lordraiden
Copy link

lordraiden commented Mar 9, 2024

I get this error, ¿any idea why?

Script location: /tmp/user.scripts/tmpScripts/Docker compose autostart/script
Note that closing this window will abort the execution of this script
Compose project AdGuardHome5 going down...

Fatal error: Uncaught Error: Call to undefined function echoComposeCommand() in /tmp/user.scripts/tmpScripts/Docker compose autostart/script:59
Stack trace:
#0 {main}
thrown in /tmp/user.scripts/tmpScripts/Docker compose autostart/script on line 59

imagen
These are the paths to the compose files
(/boot/config/plugins/compose.manager/projects/PROYECTS)

#!/usr/bin/php
<?php
#description=Docker Compose functions
#argumentDescription=arg1: action (up, down, stop, update, down_up)  arg2+: compose project names
#argumentDefault=down_up AdGuardHome5 AdGuardHome6 Administration Backup HomeAutomation Media Monitoring WebProxyDMZ 

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

require_once("/usr/local/emhttp/plugins/compose.manager/php/defines.php");
require_once("/usr/local/emhttp/plugins/compose.manager/php/util.php");
require_once("/usr/local/emhttp/plugins/dynamix/include/Wrappers.php");

// define("SHELL_FORMAT", [
//   'green' => "\033[32m",
//   'yellow' => "\033[33m",
//   'red' => "\033[31m",
//   'bold' => "\033[1m",
//   'default' => "\033[0m",
// ]);


# Split out args
$args = preg_split('/(".*?")/', $argv[1],-1,PREG_SPLIT_DELIM_CAPTURE);
for ($key=0; $key<count($args); $key++) {
    $arg = trim($args[$key]);
    if ($arg == '') {
        array_splice( $args, $key, 1);
        $key-=1;
    } else if (!str_contains($arg,'"')) {
        $a = explode(' ', $arg);
        array_splice( $args, $key, 1, $a );
        $key+=count($a)-1;
    } else {
        $args[$key] = str_replace('"', "", $arg);
    }
}


for ($a = 1; $a < count($args); $a++) {
    $project = $args[$a];
    echo "Compose project $project ";

    switch ($args[0])
    {
        case 'up':
            echo "going up...\n";
            $cmd = echoComposeCommand('up', $project);
            system($cmd);
            break;
        case 'down':
            echo "going down...\n";
            $cmd = echoComposeCommand('down', $project);
            system($cmd);
            break;
        case 'down_up':
            echo "going down...\n";
            $cmd = echoComposeCommand('down', $project);
            system($cmd);

            echo "\n\nCompose project $project going up...\n";
            $cmd = echoComposeCommand('up', $project);
            system($cmd);

            break;
        case 'stop':
            echo "stopping...\n";
            $cmd = echoComposeCommand('stop', $project);
            system($cmd);
            break;
        case 'update':
            echo "updating...\n";
            $cmd = echoComposeCommand('update', $project);
            system($cmd);
            break;
        case 'checkUpdates':
            echo "checking for updates...\n";
            $cmd = echoComposeCommand('checkUpdates', $project);
            system($cmd);
            break;
        default:
            echo "INVALID ACTION!\n";
            exit;
    }
    echo "\n\n";
}
?>

@mtongnz
Copy link
Author

mtongnz commented Mar 9, 2024

It looks like you haven't copied the function echoComposeCommand() from line 101 onwards

@lordraiden
Copy link

how could I add a delay, in seconds, at the beginning of the script, so the script waits 20 secs after array start before launching the docker compose?

thanks in advance

@mtongnz
Copy link
Author

mtongnz commented Apr 22, 2024

You could try adding sleep(20); on line 23 but this would always add a delay to the script. I'm also not sure if it would make the script time out. Give it a go and see if it works for you.
https://www.php.net/manual/en/function.sleep.php

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment