index.php:
<?php
$host = getenv('HOST');
$port = getenv('PORT');
echo "HOST is : $host";
echo "PORT is : $port";
?>
Dockerfile:
FROM php:7.4-cli
COPY . /var/www/php
EXPOSE 8000
RUN adduser rouser
CMD ["su", "-", "rouser", "-c", "cd /var/www/php && php -S 0.0.0.0:8000"]
I build a PHP docker image for my application.
docker build -t php-web-app:1.0.0 .
Running my PHP docker container:
docker run -e HOST='0.0.0.0' \
-e PORT='8084' \
-p 8000:8000 \
php-web-app:1.0.0
I made a curl request to my web application, and here the docker environment variable is not accessible by the PHP web application. It seems to be a security feature and how to do we access the docker environmental variable within a php web application.
$ curl http://0.0.0.0:8000/
HOST is : PORT is :
I'm going to guess that changing user does not preserve the environment variables of your execution.
You can check which variables are available in the environment with the env command.
There are however several things that are non-idiomatic going on with your Dockerfile.
You should not create users in your docker image. You can simply set the userid and groupid of your user in the container by setting the --user uid:gid flag in docker run.
You should not run interactive commands such as adduser in a Dockerfile. Unless you can provide all parameters in a single command so that it can run without user-intervention. Adding users is not one of them; how will you provide a password?
So to see the the environment, change your CMD line to the following:
CMD ["su", "-", "rouser", "-c", "env"]
You will see that it prints the following:
SHELL=/bin/bash
PWD=/home/rouser
LOGNAME=rouser
HOME=/home/rouser
USER=rouser
SHLVL=0
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
MAIL=/var/mail/rouser
_=/usr/bin/env
The environment variables you set are not available. However, if we change the CMD line to just print the env we get another output.
CMD ["env"]
shows us:
HOSTNAME=be0b41fed51e
PHP_INI_DIR=/usr/local/etc/php
PORT=8084
HOME=/root
PHP_LDFLAGS=-Wl,-O1 -pie
PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
PHP_MD5=
PHP_VERSION=7.4.6
GPG_KEYS=42670A7FE4D0441C8E4632349E4FDC074A4EF02D 5A52880781F755608BF815FC910DEB46F53EA312
PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
PHP_ASC_URL=https://www.php.net/distributions/php-7.4.6.tar.xz.asc
PHP_URL=https://www.php.net/distributions/php-7.4.6.tar.xz
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOST=0.0.0.0
PHPIZE_DEPS=autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c
PWD=/
PHP_SHA256=d740322f84f63019622b9f369d64ea5ab676547d2bdcf12be77a5a4cffd06832
Notice here that the user is not rouser, but the root user. You can change this by passing, for example, --user 1000:1000 in your docker run command.
So, to fix your problem, I propose you use the following Dockerfile:
FROM php:7.4-cli
COPY . /var/www/php
EXPOSE 8000
# RUN adduser rouser
# CMD ["su", "-", "rouser", "-c", "cd /var/www/php && php -S 0.0.0.0:8000"]
WORKDIR /var/www/php
CMD ["php", "-S", "0.0.0.0:8000"]
Then we get the following output:
$ curl http://0.0.0.0:8000
HOST is : 0.0.0.0PORT is : 8084
If you login to your docker container with
docker exec -it [container id] bash
and run
env
command, you will see that the passed variables are there.
I'm not a PHP expert, but try the same exercise locally (without docker) and see if you are able to print out any env variable via getenv
Related
I have a PHP server that I need to launch in a docker image along a Python service. Both of them need to be in the same image. At first, I wrote the Dockerfile to start the PHP server, by following a simple guide I found online, and I came up with this:
FROM php:7-apache
COPY ./www/ /var/www/html
WORKDIR /var/www/html
EXPOSE 70
Then, because I need a third service running on a second container, I created the following docker-compose file:
version: '3.3'
services:
web:
build: .
image: my-web
ports:
- "70:80"
secondary-service:
image: my-service
ports:
- "8888:8888"
Using only that, the website works just fine (except for the missing service on the web container). However, if I want to start a service inside the web container alongside the web, I need to start the website manually from a bash script, since docker can only have one CMD entry. This is what I tried:
FROM php:7-apache
COPY ./www/ /var/www/html
RUN mkdir "/other_service"
COPY ./other_service /other_service
RUN apt-get update && bash /other_service/install_dependenci172.17.0.1es.sh
WORKDIR /var/www/html
EXPOSE 70
CMD ["bash", "/var/www/html/launch.sh"]
And this is launch.sh:
#!/bin/bash
(cd /other_service && python3 /other_service/start.py &) # CWD needs to be /other_service/
php -S 0.0.0.0:70 -t /var/www/html
And that also starts the server without problems, along with other_service.
However, when I go to my browser (in the host) and browse to http://localhost:70, I get the error "Connection reset". The same happens when I try to do a request using curl localhost:70, which results in curl: (56) Recv failure: Connection reset by peer.
I can see in the log of the web that the php test server is running:
PHP 7.4.30 Development Server (http://0.0.0.0:70) started
And if I open a shell inside the container and I run the curl command inside of it, it gets the webpage without any problems.
I have been searching similar questions around, but none if them had an answer, and the ones that did didn't work.
What is going on? Shouldn't manually starting the server from a bash script work just fine?
Edit: I've just tried to only start the PHP server like below and it doesn't let me connect to the webpage either
#!/bin/bash
#(cd /other_service && python3 /other_service/start.py &) # CWD needs to be /other_service/
php -S 0.0.0.0:70 -t /var/www/html
I found the issue. It was as easy as starting the Apache server too:
#!/bin/bash
(cd /other_service && python3 /other_service/start.py &) # CWD needs to be /other_service/
/etc/init.d/apache2 start
php -S 0.0.0.0:70 -t /var/www/html
I try to rename transactions with newrelic_name_transaction in crons executed in Docker container but it doesn’t work. It looks like the cron is not catched in NewRelic (on Non Web Transactions)
If I execute the cron directly on SSH on Docker it’s work (I see it on Non Web Transactions with the new name). In any case, the function returns always true.
I have the same problem with the newrelic_custom_metric function.
I have this on my Dockerfile :
RUN
curl -L https://download.newrelic.com/php_agent/release/newrelic-php5-9.20.0.310-linux.tar.gz | tar -C /tmp -zx &&
export NR_INSTALL_USE_CP_NOT_LN=1 &&
export NR_INSTALL_SILENT=1 &&
/tmp/newrelic-php5-/newrelic-install install &&
rm -rf /tmp/newrelic-php5- /tmp/nrinstall* &&
sed -i -e ‘s/“REPLACE_WITH_REAL_KEY”/"[MY KEY]"/’
-e ‘s/newrelic.appname = “PHP Application”/newrelic.appname = “PHP Application”\nnewrelic.attributes.include = request.parameters.*/’
/usr/local/etc/php/conf.d/newrelic.ini
I use this parameters to launch the container :
spec:
restartPolicy: OnFailure
containers:
- name: cron-master
image: [MY IMAGE]
command: ["/bin/sh","-c"]
args:
- gcsfuse --key-file /root/secret/key.json -o allow_other,nonempty,rw --uid 33 --gid 33 goons-catella-prod /var/www/html/web/uploads;
php /var/www/html/bin/console scheduler:execute --env=prod -vvv;
fusermount -u /var/www/html/web/uploads;
It’s the line
php /var/www/html/bin/console scheduler:execute --env=prod -vvv;
that launch crons (it’s the Symfony Bundle jmose/command-scheduler-bundle). When I launch it manually on SSH it’s work.
However, the Agent works perfectly when i go on the website with my browser.
Could you help me please ?
Thanks a lot
I have a docker container (build on php:7.1-apache image) with a Drupal 7.56 plain installation.
My simpletest starts with this:
$this->account = $this->drupalCreateUser();
$this->drupalLogin($this->account);
But when I run the following command:
docker exec simpletest bash -c "php scripts/run-tests.sh --url http://simpletest \
--verbose --color --class MyOwnWebTest"
I get the following message a bit down:
Fail User login my_module 34
MyOwnWebTest->testWeb
User esxlZnK0 successfully logged in.
It doesn't make any sence - the user is created and logged in, but the code fails?!
Okay - figured it out for my self.
The container is setup to listen to port 83.
So Apache's port.conf must have a Listen 81 and Drupals settings.php must have the following setting:
$base_url = 'http://simpletest:83';
And I am calling the test with this code line:
docker exec simpletest bash -c "php scripts/run-tests.sh \
--url http://simpletest:83 --verbose --color --class MyOwnWebTest"
I want to run a script on my ubuntu server with a variable from php in it.
Here are some of the things i've tried to pass a variable to ubuntu...
shell_exec('vpsName=HI3');
vpsName=`mysql -D jake_db -h 127.0.0.1 -u jake -pXXXXXXX -se "SELECT vpsName FROM reinstalls WHERE status = 'pending'"`;
The final way in which i thought I could fix it was to avoid running the script through ubuntu all together and run it from shell_exec(); but it fails on running the guestfish commands.
Here is my entire reinstalls.sh script.
sudo rm /var/lib/libvirt/images/"$vpsName".qcow2 && sudo wget -O /var/lib/libvi$
guestfish -a /var/lib/libvirt/images/"$vpsName".qcow2 <<'EOF'
run
mount /dev/ubuntu-vg/root /
rm /etc/network/interfaces
EOF
sudo fusermount -u /mnt && virsh start "$vpsName" && echo "IT WORKED!"
I am open to any way of getting this to work, as long as its secure,
Thanks in advance,
Jake
EDIT:
If I run the script with a VPS name instead of a variable, it works. I just can't find a way to pass the variables from the website to the ubuntu16.04 OS.
Well one way would be to run each command from PHP:
shell_exec("sudo rm /var/lib/libvirt/images/" . $vpsName . ".qcow2");
shell_exec("sudo wget -O /var/lib/libvi ... etc");
The other would be to invoke your shell script from PHP, passing the vps name as a parameter:
shell_exec("reinstalls.sh " . $vpsName)
But then you'd have to rewrite the shell script to pick up the command line parameter and apply it as necessary. In the case of bash, this explains how to go about that.
I have a script in php that raises an image of docker (havnesvo / slimerjs) and it passes a .js since the slimer needs a js to boot. When I expose the container and try to see inside with vnc send an error: The host refuse the connection. My script look like:
bash
SCRIPT="script.js"
docker run -p 8080:8080 --rm -ti -v `pwd`:/scripts havnesvo/slimerjs bash -c "sed -i 's/640x480x8/1600x1400x8/' /usr/bin/xvfb-run && /usr/bin/slimerjs /scripts/$SCRIPT"
Any suggestion?