#apache #perl #docker #environment-variables #cgi
#apache #perl #docker #переменные среды #cgi
Вопрос:
У меня есть следующий файл docker-compose:
version: '2'
services:
test:
image: httpd
container_name: inc_test
ports:
- "3000:80"
environment:
- PERL5LIB=/somedir
- PERLLIB=/somedir
command:
- bash
- -c
- |
cat /usr/local/apache2/conf/httpd.conf | grep modules/mod_cgid.so
sed -i 's,#(LoadModule cgid_module modules/mod_cgid.so),1,g' /usr/local/apache2/conf/httpd.conf
cat /usr/local/apache2/conf/httpd.conf | grep modules/mod_cgid.so
echo '#!/usr/bin/env perl' >> /usr/local/apache2/cgi-bin/test.pl
echo 'print "Content-type: text/htmlnn";' >> /usr/local/apache2/cgi-bin/test.pl
echo 'print join("n", @INC);' >> /usr/local/apache2/cgi-bin/test.pl
ls -lah /usr/local/apache2/cgi-bin/test.pl
cat /usr/local/apache2/cgi-bin/test.pl
httpd -M | grep -e cgid -e alias
chmod a x /usr/local/apache2/cgi-bin/test.pl
perl -le 'print for @INC'
echo "Which perl : "
which perl
httpd-foreground
Когда я захожу в http://localhost:3000/cgi-bin/test.pl Я вижу, что /somedir
этого нет в @INC
. Hovewer perl -le 'print for @INC'
содержит /somedir
.
WTF?
Комментарии:
1. У вас установлено более одной Perl-версии? Вы работаете под разными учетными записями пользователей? Среды не копируются от одного пользователя к другому при разных обстоятельствах. Протестируйте в командной строке с обоими пользователями и посмотрите, есть ли у них одинаковые вещи в
@INC
Ответ №1:
После изучения проблемы, которую я обнаружил, проверив, httpd.conf
что httpd запускается httpd-foreground
под daemon
пользователем, а не root.
У пользователя daemon
по умолчанию нет shebang:
$ docker run -it httpd cat /etc/passwd | grep daemon
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Но даже если мы добавим
runuser - daemon -c "export PERL5LIB=/somedir" -s /bin/bash
to command:
это не передало бы переменную в perl, поскольку httpd запускает CGI-скрипты в отдельных изолированных процессах, поэтому shell тоже изолирован. Мы можем управлять переменными ENV только с помощью mod_env SetEnv
и PassEnv
директив.
Итак, для передачи /somedir
в @INC
нам нужно добавить
echo "SetEnv PERL5LIB /somedir" >> /usr/local/apache2/conf/httpd.conf