ECS环境下php-fpm无法传递环境变量的问题求助
"entryPoint": [ "/usr/local/bin/entrypoint.sh" ], "portMappings": [ { "hostPort": 0, "protocol": "tcp", "containerPort": 9000 } ], ...
]
容器运行Symfony应用,采用php-fpm,我的`entrypoint.sh`脚本内容: ```sh #!/bin/sh export TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") export DD_AGENT_HOST=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/local-ipv4) echo "Datadog agent host: ${DD_AGENT_HOST}" php-fpm -F
CloudWatch日志中echo语句能输出正确的DD_AGENT_HOST值,但进入容器执行php -i命令时,却看不到该环境变量。我已确保www.conf配置文件中设置了clear_env = no,但问题仍未解决。
我的Dockerfile内容:
# Multi stage build. We first run composer install, and later copy it over in the 2nd image FROM composer:2 as vendor WORKDIR "/app/platform" COPY ["./app/composer.json", "./app/composer.lock*", "/app/platform/"] RUN composer install --no-interaction --no-dev --prefer-dist --ignore-platform-reqs FROM php:8.1-fpm-buster as platform RUN \ # Symfony needs write access to some folders. We need to pre generate these mkdir -p "/app/platform/var" \ && chmod 777 -R "/app/platform/var" \ # Install necessary binaries and packages && apt-get update \ && apt-get install -y gnupg g++ procps openssl git unzip zlib1g-dev libzip-dev libfreetype6-dev libpng-dev libjpeg-dev libicu-dev libonig-dev libxslt1-dev acl libjpeg62-turbo-dev libmcrypt-dev zip vim \ # Install php extensions #&& pecl install redis \ #&& docker-php-ext-enable redis \ && docker-php-ext-install pdo pdo_mysql zip xsl gd intl opcache exif mbstring soap \ # Install Composer && curl -sS https://getcomposer.org/installer | php -- --install-dir="/usr/local/bin" --filename=composer && chmod +x "/usr/local/bin/composer" # Datadog ARG DD_ENV_ARG=placeholder ENV DD_ENV=$DD_ENV_ARG ENV DD_VERSION=1 ENV DD_SERVICE=platform-aws ENV DD_PROFILING_ENABLED=true COPY "./.docker-prod/platform/datadog-setup.php" "/app/platform/datadog-setup.php" RUN php /app/platform/datadog-setup.php --php-bin=all --enable-profiling COPY "./app" "/app/platform" RUN perl -pi -e 's#^(?=access\.log\b)#;#' /usr/local/etc/php-fpm.d/docker.conf COPY "./.docker-prod/platform/php.ini" "/usr/local/etc/php/conf.d/docker-php-config.ini" COPY "./.docker-prod/platform/www.conf" "/usr/local/etc/php-fpm.d/www.conf" COPY --from=vendor "/app/platform/vendor" "/app/platform/vendor" WORKDIR "/app/platform" RUN \ composer dump-autoload --optimize --classmap-authoritative \ && composer run-script post-install-cmd # Entrypoint COPY "./.docker-prod/platform/entrypoint.sh" "/usr/local/bin/entrypoint.sh" RUN chmod +x "/usr/local/bin/entrypoint.sh"
解决思路
1. 区分CLI与FPM的环境变量隔离
php -i查看的是PHP CLI模式的环境变量,而Symfony应用运行在php-fpm进程下,二者的环境变量空间完全隔离。要验证FPM进程是否能获取到DD_AGENT_HOST,不要用php -i,而是通过以下方式:
- 在Symfony中添加一个测试接口,输出
getenv('DD_AGENT_HOST')或$_ENV['DD_AGENT_HOST']的结果 - 查看php-fpm的慢日志或应用日志,直接打印该环境变量的值
2. 显式将环境变量注入php-fpm配置
即使设置了clear_env = no,php-fpm可能不会完全继承entrypoint父进程的所有环境变量。可以修改entrypoint.sh,在启动php-fpm前将DD_AGENT_HOST写入php-fpm的额外配置文件:
#!/bin/sh export TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") export DD_AGENT_HOST=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/local-ipv4) echo "Datadog agent host: ${DD_AGENT_HOST}" # 将环境变量写入php-fpm的配置片段 echo "env[DD_AGENT_HOST] = ${DD_AGENT_HOST}" >> /usr/local/etc/php-fpm.d/dd-agent.conf php-fpm -F
默认情况下,php-fpm会加载/usr/local/etc/php-fpm.d/目录下所有.conf后缀的文件,该配置会确保FPM进程能读取到这个变量。
3. 检查php-fpm启动时的用户切换
如果entrypoint脚本中启动php-fpm时切换了用户(比如默认的www-data),要确保环境变量被传递。比如将启动命令改为:
su - www-data -c "php-fpm -F"
这里的-参数会让su命令加载目标用户的环境,同时继承父进程的环境变量。
4. 直接配置Datadog扩展参数
如果环境变量传递仍有问题,可以绕过环境变量,直接在php.ini或fpm配置中设置Datadog扩展的参数:
datadog.trace.agent_host = ${DD_AGENT_HOST}
你也可以用entrypoint脚本动态生成这个配置,比如:
echo "datadog.trace.agent_host = ${DD_AGENT_HOST}" >> /usr/local/etc/php/conf.d/datadog.ini
内容的提问来源于stack exchange,提问作者Raf Rasenberg
相关产品推荐
相关产品推荐

