On the same server, I have a apache php application and a nodejs application (started via systemd).
For systemd/node, I put the following config:
[Service]
EnvironmentFile=/etc/environment
For apache, I have put the following line in /etc/apache2/envvars
. /etc/environment
My problem is:
It works in PHP and standalone node if I put export before each variable, but not in node via systemd
It works in node via systemd if I remove the export
Is there a way for me to write these variables in a single place that can be used by Apache/PHP and node started via systemd ?
You can use the export statement version of your environent file if you change your ExecStart= line to something like: ExecStart=/bin/sh -c ". /etc/environment && exec /PATH/TO/NODEJS/APPLICATION". This is kludgy though.
Related
I defined in httpd.conf(Apache) setEnv=prod
and call to ENV in php (using getenv() function)
while running from terminal(mac) php file.php the env is NULL
but when I run it from the web page its working; and print "prod"
There are several ways to set the environment of a program you run in the console (Terminal) in macOS and Linux. (The procedures are similar on Windows but the syntax is different.)
You can put env=prod in front of the command line to set the environment variable env with value prod only for the current execution of that command line:
$ env=prod php -f script.php
You can use export env=prod as a separate command line. It sets the environment value env with value prod for the current execution of the shell you are running in the console. The export keyword in front of it tells the shell to pass the variable to all processes it launches from now on (until you close the shell or unset the variable):
$ export env=prod
$ php -f script.php
If you want to set the variable permanently then you put the line export env=prod in ~/.profile or ~/.bashrc or the initialization script of your preferred shell (if it's not bash). All subsequent instances of the shell you launch execute the initialization script and set the env variable with value prod in their environment and mark it as exportable to the child processes that shell launches.
So I have hosted a webpage on my apache server and I'm trying to run some python and bash scripts when the user presses a button via PHP and AJAX.
Now my php file executes at python script (located in /var/www/html) which in turn executes a bash file (located in root/files).
On doing this manually in terminal, everything works perfectly fine.
But when I try to this via the webpage, the bash script isn't executed.
(I can't place the bash script in /var/www/html because it has the command to clone a git repository to the server and it gives private key shouldn't be public error when placed there)
I already tried suggestions in this answer by adding www-data to sudoers but it is still not working as expected.
Any help on this would be appreciated.
Thanks
PHP file :
if(isset($_POST['timestamp']))
{
$uid = $_POST['timestamp'];
echo "Please wait while the app is being generated".$uid;
exec("python /var/www/html/appgenserver.py $uid");
appgenserver.py
#! /usr/bin/env python
import os
import json,sys
from firebase import firebase
import requests
import subprocess
arg = sys.argv[1]
# Path to be created
path = "/root/files/"+str(arg)
print path
if not os.path.exists(path):
os.makedirs(path) #Gets executed
subprocess.call(['/root/Final/clone.sh', path) #Not getting executed
Most likeley because a bash script in its self won't be executable, it's just a plain textfile.
Your bash (and perhaps even appgenserver.py?) might be located under /root and apache probably runs as a non-priviliged user such as www-data, that user won't be able to access either your python script and in turn not the bash that the python would run.
Consider instead calling bash with the script as a parameter.
#! /usr/bin/env python
import os
import json,sys
from firebase import firebase
import requests
import subprocess
arg = sys.argv[1]
path = "/root/files/"+str(arg)
print path
if not os.path.exists(path):
os.makedirs(path)
subprocess.call(['/bin/bash', '/root/Final/clone.sh', path)
Now, this is NOT the most pretty of solutions.
But what you got before was probably a generic "Permission denied" error in the background (check your /var/log/apache/error.log).
What this does is start /bin/bash as a subprocess with the first parameter being the script you want to execute.
But you have zero error handling here and you can't interract with the process very much.
Consider doing something like this instead:
import subprocess
handle = subprocess.Popen(['/bin/bash', '/root/Final/clone.sh', 'parameter'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
while handle.poll() is None:
print(handle.stdout.read()) # There's some optimizations here to be done as well so it's not a blocking call etc.
handle.stdout.close()
handle.stdin.close()
And one last tip is not to place stuff in /root/ at all if you're integrating it into a web front-end/backend type of thing.
You're asking for trouble : )
Another way is to make use of sudo
If you modify your exec() in PHP to run exec("sudo ...") and enable your web-user to run the scripts without a password prompt it could work.
Bare in mind, it's not recommended to give www-data sudo access, rather do something like this:
# useradd -m -G www-data -s /bin/bash wwwexec
# echo "myuser ALL=NOPASSWD: /usr/bin/python" >> /etc/sudoers
and change your PHP script to have the following:
exec("sudo -u wwwexec python /var/www/html/appgenserver.py $uid");
That way at least your entire web service isn't given root access via the default username.
The way to do it
Would be to place your appgenserver.py under /var/www/cgi-bin/ instead, and create a CGI hook for .py in your apache configuration and hand over the user to the URL prividing you access to the CGI script.
That way everything should be according to best practices even tho, in theory, you could get your original solution to work.
For instance, this guide should get you started.
I would like to add a linux environment variable for my differents applications written in PHP and Ruby.
Its goal is to differntiate between 'production' and 'development' linux environment.
How to have an linux environment variable (ex : APPLICATION_ENV='production') that can be accessed with PHP and Ruby?
thanks
Edit 1 :
My first solution was :
for Apache/PHP in vhost :
SetEnv APPLICATION_ENV 'production'
for Ruby :
export APPLICATION_ENV='production'
puts ENV['APPLICATION_ENV']
However, this is two places to the same value... There are no solution to merge it in one place ? par exemple to use /etc/environment
Edit :
The answer of my question is detailed here : Inserting Variable Headers in Apache
A simple solution to have a central location for your variable would be to put it in /etc/environment and include it in /etc/init.d/httpd.
$ vim /etc/environment
APPLICATION_ENV=production
$ vim /etc/init.d/httpd
if [ -f /etc/environment ]; then
. /etc/environment
fi
Then restart apache with /etc/init.d/httpd restart and it should be OK.
If you are using ubuntu 16.04 or similar, replace /etc/init.d/httpd with /etc/init.d/apache2
If you don't want to include environment file to apache, you can directly put your code in /etc/apache2/envvars for example at the end of the file:
export HELLO='dear'
For the commandline, do a
export APPLICATION_ENV='production'
prior to calling your code, like Domon suggested. You can write a short wrapper bash script to do all of that in one line, like this
#!/bin/bash
export APPLICATION_ENV='production'
ruby /path/to/your/script.rb
For apache, make sure mod_env is loaded, and include the line
SetEnv APPLICATION_ENV production
in the site's vhost config or .htaccess.
Finally, you can set the APPLICATION_ENV globally on your system (using whatever your distri supports for that) and then simply pass the value to your web app by using
PassEnv APPLICATION_ENV
The most simple way is specifying environment variables directly in shell commands. Then you can access them through the ENV object in Ruby.
For example, create a file called env.rb:
puts ENV['APPLICATION_ENV']
And run it in the shell like this:
APPLICATION_ENV='production' ruby env.rb
It should print out the word "production".
Or, use the export command:
export APPLICATION_ENV='production'
ruby env.rb
You might want to add the export line to some config file. For example, if you use bash, add it to ~/.bashrc and it will get executed every time when you starts a new shell.
I have a php script. I am using nginx and spawn-fcgi.
spawn-fcgi -n -s /tmp/nginx9010.socket -u www-data -g www-data -f /usr/bin/php5-cgi -C 6
How can I test from the command line that spawn-fcgi is working with the script?
e.g. I have a script in /home/ubuntu/test.php
I am having issues with nginx and executing a php script. It prompts for a download.
I have #!/usr/bin/php in the file and did a chmod a+x as well.
Thanks
For testing a FastCGI backend you could try to create a CGI environment and use cgi-fcgi to connect to the backend
You could attach with strace to see what the backend does (for example whether it even receives a request from the web server); attach with -ff to the master process to see syscalls on all workers
php5-cgi in FastCGI mode doesn't need a shebang line nor +x on the files - it doesn't use the kernel to execute them, it just loads them as simple files
Firefox (and probably other browsers too) often cache the mime type, so you will see a download prompt even after you fixed the problem. Use curl for testing!
nginx won't serve the file it passes it to php, nginx only serves static files, So if it is downloading the php file you might need to check that your are sending php files to the correct place, are you using an IP and PORT in the php location block in the config file ?
Only a guess of the top of my head whilst on the train home.
FWIW, problems like that nginx offers the file to be downloaded are due Nginx serving the files itself without sending them to fastcgi backend, often because of try_files or wrong location {} block matching to the uri.
PHP 5.4 supports a built-in web server for development purposes. The app we are developing is configured via environment variables.
With Apache you'd do this:
SetEnv FAVORITE_COLOR white
With the normal CLI you can do this:
$ export FAVORITE_COLOR=black
$ php -a
php > echo $_SERVER['FAVORITE_COLOR'];
Is there a way to set these variables for the built-in web server?
Looks like E is excluded from variable_order setting running the built-in server. If you add the E to the variable_order setting, it works:
test.php
<?php
var_dump($_ENV['FOO']);
shell:
FOO=BAR php -d variables_order=EGPCS -S localhost:9090 /tmp/test.php
output:
string 'BAR' (length=3)
Tested on PHP 5.4.12
I use Window DOS to start the PHP server. I store my server startup commands in a text batch file (.bat) to save me from having to select and copy all of the commands at once and paste it into the DOS terminal (note the last blank line that I copy as well so the PHP server will automatically start when I paste the commands into DOS, otherwise I would need to manually use the Enter key to start the server).
Q:
cd Q:\GitLabRepos\myapps\test1
set APPLICATION_TITLE=My testing application with this first env variable
set SOME_OTHER_ENV_VAR2={"myJsonElement":"some value"}
E:\PHP8\php.exe -d variables_order=E -S localhost:8000 -c php.ini
The commands above explained:
The first line Q: changes to the drive where my code resides. The second line cd Q:\GitLabRepos\myapps\test1 changes directories to my root PHP application code (which is where I want to start the PHP server). Next I set some environment variables on lines 3 and 4. Then finally I start the PHP server with the -d variables_order=E parameter so I can use either $_ENV or getenv() to retrieve the environment variable values in my PHP code (eg. $_ENV['APPLICATION_TITLE'] or getenv('APPLICATION_TITLE')). If you exclude -d variables_order=E from the server startup command then you can only use getenv() to access the environment variables. I use the -c php.ini parameter to load additional PHP settings from a php.ini file but this can be excluded for simple server setup.
Then if I have a Q:\GitLabRepos\myapps\test1\index.php script with the following code:
<?php
echo getenv('APPLICATION_TITLE').'---'.$_ENV['APPLICATION_TITLE'].'...'.getenv('SOME_OTHER_ENV_VAR2');
?>
If I visit localhost:8000 in a web browser I should see
My testing application with this first env variable---My testing application with this first env variable...{"myJsonElement":"some value"}.
On Windows:
SET FOO=BAR
php -s localhost:9090