Run docker in shell using PHP - php

Well, I need to run a Docker using a PHP function. I have a web page where pushing a link I execute a shell order using shell_exec or exec. This works for me if the execution is like an ls or something that expects a result. The problem is that if the command is to run the Docker (or for example a ping) it doesn't work.
What I want is when the user clicks the link, the shell will execute a command to run Docker in the browser, and the page will be redirected there.
For exemple, if I use shell_exec('firefox'); this should open a new firefox browser, but it doesn't work. It seems that the browser is opened but few seconds later is closed.
This is the Docker execution that doesn't work.
public function executeDocker() {
$result = shell_exec('docker run --rm -p 3838:3838 shiny/gsva_interactive /usr/bin/shiny-server.sh');
echo "<br><br>Execution: ".$result;
}

shell_exec will only return the output of a, in this case Docker, command only when the command has exited completely. In the case of ping (it will just keep pinging) and probably in the case of your Docker image, the process will never exit by itself, so it will never give a response.
Using passthru instead of shell_exec should give you the commandline output of your Docker script right back as a response.
If the Docker container is not meant to exit you should probably start it in detached mode with $containerId = shell_exec('docker run -d --rm -p 3838:3838 shiny/gsva_interactive /usr/bin/shiny-server.sh'), so the docker run command will exit. This will return the container id, which you can use with $result = shell_exec("docker ps -f \"id=$containerId\"") to check if the container is running correctly and redirect the user if it is.

i was having the same issue running docker exec via shell_exec.
shell_exec('docker exec -it containerid /usr/bin/cmd);
Getting rid of the -i option worked for me.

Finally I solved it. The problem was in the user group and permissions. In the system that I was using, CentOS, apache server uses a user called apache. This user needs to be in the docker group and reboot the services.
Now it works. Thanks to everyone who helped me.

Related

Problem executing docker exec command from php

I am trying to execute a command in a R-base Docker container and get the output parsed by my PHP code, if I run the docker sentence in console it works but in php it return an empty response.
The script that I want to run is:
docker exec -w /var/www/vhosts/httpdocs/webroot/code -it R_3.5.3 Rscript my_script.R /var/www/vhosts/httpdocs/webroot/media/transfer/tmp/filetoparse.txt
It works fine in console because the output is:
[{"id":"C1","type":"CONSTANT","value":"C1",....]
If I store the output in a var and then I do echo of it I can see the result, so the output is in the main console:
myvar=`docker exec -w /var/www/vhosts/httpdocs/webroot/code -it R_3.5.3 Rscript my_script.R /var/www/vhosts/httpdocs/webroot/media/transfer/tmp/filetoparse.txt`
echo $myvar
>>[{"id":"C1","type":"CONSTANT","value":"C1",....]
Well my problem is when I want to call the script from php served by apache:
I tried:
exec("docker exec -w /var/www/vhosts/httpdocs/webroot/code -it R_3.5.3 Rscript my_script.R /var/www/vhosts/httpdocs/webroot/media/transfer/tmp/filetoparse.txt", $outputs);
debug($outputs);
The result is:
APP/Controller/MyController.php (line 56)
''
I tried to log the output in a file but, nothing, so what I think is that the R script is not executing.
Any clue about what could be happening?
Note: apache user is added to Docker's group amd I logged with it and I can execute the script in console.

Docker containers do not stop and get removed after a script has been executed

We are having a Docker server 'Docker version 17.03.0-ce, build 60ccb22'. We have a number of workers, around 10,each one of them performs a really simple task that takes a few seconds to complete and exit. We decided that every one of them is going to start a docker container and when the script finishes, the container gets stopped and removed. What is more, crontabs deal with running So, we created a bash script for every worker that instantiates the container with the flags --rm and -d and also starts the script file in the bin/ folder
#! /bin/sh
f=`basename $0`
workerName=${f%.*} \\name of the bash script without the part after the .
//We link with the Docker host the folder of the worker and a log file that is going to be used for monitoring from outside the container.
docker run --rm -d --name $workerName -v `cat /mnt/volume-fra1-05/apps/pd-executioner/master/active_version`:/var/www/html -v /mnt/volume-fra1-06/apps/$workerName.log:/var/www/html/logs/$workerName.log iqucom/php-daemon-container php bin/$workerName
echo `date` $0 >> /var/log/crontab.log
So, we created a bash script for every worker that instantiates the container with the flags --rm and -d and also starts the script file in the bin/ folder. All the workers are very similar to the structure and the code and really simple, there are not big code differences. However, we have experienced the following behaviour: some containers (random ones every time) refuse to stop and be removed even after many hours. Inside the container, the process php bin/$workerName is still running with PID 1. There is nothing like an infinite loop in the code that could stop the script from finishing. It happens randomly and still cannot find a pattern. Do you have any idea on why this might be happening?
So this can be some issue related to your PHP script getting stuck somehow. But since you are sure it is suppose to timeout after lets assume 240secs then you should can change your container command to
docker run --rm -d --name $workerName -v cat /mnt/volume-fra1-05/apps/pd-executioner/master/active_version:/var/www/html -v /mnt/volume-fra1-06/apps/$workerName.log:/var/www/html/logs/$workerName.log iqucom/php-daemon-container timeout 240 php bin/$workerName
This will make sure that any stuck container will exit after a timeout if it doesn't exit on its own

Using PHP and Bash to log into an external server via SSH

I'm trying to set up a centralized server which is in charge of monitoring my other servers. This centralized server needs to be able to collect particular information/metrics about a specific server (such as df -h and service httpd status); but it also needs to be able to restart Apache if needed.
If it wasn't for the Apache restart, I could write a listening script to provide a means of giving the centralized server the data it needs without having to SSH in. But because I also want it to be able to restart Apache, it needs to be able to log in and initiate scripts through a combination of PHP and Bash.
At the moment, I'm using PHP's shell_exec to execute this (very simple) Bash script:
#!/bin/sh
ssh -i /path/to/keyFile.pem ec2-user#x.x.x.x;
I'm accessing the external server (which is an EC2 instance) through a private IP. If I launch this script, I can log in without any problem - the problem comes, however, when I then want to send back the output for commands like the ones I've listed above.
In a Bash script, how would I output a command like df -h after SSHing into another server? Is this possible?
There is a PECL extension for SSH.
Other than that you'll probably want to either use the &$output parameter of exec() to grab the output:
$output = array();
exec('bash myscript.sh', $output);
print_r($output);
Or use output redirection
$output = '/path/to/output.txt';
exec("bash myscript.sh > $output");
if( file_exists($output) && is_readable($output) ) {
$mydata = file_get_contents($output);
}
and, of coure, this all assumes your script looks like what jeroen has in his answer.
You could use:
ssh -i /path/to/keyFile.pem ec2-user#x.x.x.x 'df -h'
or for multiple commands:
ssh -i /path/to/keyFile.pem ec2-user#x.x.x.x 'ls -al ; df -h'
That works from the command line but I have not tried it via php's exec (nor on Amazon to be honest...).
If you're doing ssh I'd suggest phpseclib, a pure PHP SSH implementation. It's a ton more portable than the PECL SSH extension and more reliable too.

Can't open gnome-terminal with php

I actually try to laucnh a gnome-term with a php script, seems i have some problems with the users www-data;
my script make only a ls -l command in a directory (is just for a test) and i run it with a php page in my local-web site.
here the gnome-terminal command in my bash script (he run perfectly when i double-click on him) :
gnome-terminal --working-directory=/opt/cuckoo -x bash -c "ls -l"
and here is the call on the php-page :
system("/my/path/to/the/script/script.sh");
i have some echo in my script and i see them in the php page after i try to run the script with the php.page.
i think www-data don't have the right to do so i give the ownership of the script with the chown command, and at last a try the sudo visudo command and make the script execute like the user www-data is root (with NO PASSWD arg)
But i can't open the terminal and make a ls at last, i try with exec too, and show the result with $ouput butthe result is the same as well.
At last my question is : Php can really run a terminal or maybe a fool myself^^? Thanks for taking time to rescure me ;)
PHP can run everything, but depends who spawns it. Forget just running X apps from a web server - you'll need more than just executing them (permissions, DISPLAY and Xauth settings). Read more about the X clients and architecture.
Probably the right place to ask this is at SuperUser, since the problem is not in the coding itself.

Run crontab command from php

folks,
i am very new to PHP, on project that i do now(PHP + Linux), i need to schedule tasks. I know that i can do it using cron. How can i check crontab file from PHP(i have only ftp access to server)?
I mean i can run 'crontab -l' from terminal(on my local PC). But when i try to do :
echo exec('crontab -l'); - on local PC, it retrn nothing, why it happend ? How can i run command 'crontab -l' from PHP and get output ?
I've tried to use example http://ryanfaerman.com/read/php-crontab-manager, but get compile error.
I think crontab will open the user's crontab. Your webserver might be running as root or a different user than you would be.
Try this, but I doubt it will work for security reasons:
crontab -u root -l
I got nothing from exec('crontab -l'), because i haven't permissions to run crontab and error message is in error stream, so all i need redirect error stream to out stream.
exec('crontab -l 2>&1') - that is exactly i wanted.

Categories