When running PHP-FPM in Docker containers, environment variables defined in docker-compose.yml often fail to propagate to PHP scripts due to PHP-FPM's security-focused design. The clear_env = yes
default setting actively prevents environment inheritance.
First, modify your PHP-FPM pool configuration. For PHP 7.x, edit /etc/php/7.x/fpm/pool.d/www.conf
:
[www]
; Disable environment clearing
clear_env = no
; Ensure proper variable order (optional but recommended)
env[MY_ENV_VAR] = $MY_ENV_VAR
In your Dockerfile or docker-compose.yml, ensure proper environment variable passing:
# docker-compose.yml example
services:
php-fpm:
environment:
- MY_ENV_VAR=production_value
- DB_HOST=db-container
Create a test script env_test.php
:
<?php
header('Content-Type: text/plain');
echo "Direct env access: " . getenv('MY_ENV_VAR') . PHP_EOL;
echo "PHP global access: " . ($_SERVER['MY_ENV_VAR'] ?? 'Not set') . PHP_EOL;
echo "All environment: " . print_r(getenv(), true);
If variables still don't appear:
- Check container rebuild with
docker-compose up --build
- Verify FPM restart with
service php7.x-fpm restart
- Inspect actual environment with
docker exec -it container_name env
For development environments where you need all variables:
; In www.conf
clear_env = no
; In php.ini
variables_order = "EGPCS"
When running PHP applications in Docker containers, you might encounter situations where environment variables defined in your docker-compose.yml
or through docker run -e
commands aren't accessible in your PHP scripts. The getenv()
function returns false, even though the variables are visible when you check them in the container's shell.
PHP-FPM (FastCGI Process Manager) by default clears the environment before starting worker processes. This security measure prevents potentially sensitive environment variables from being exposed to PHP applications. While this is good for security, it breaks the expected behavior when running in containers where we want to pass configuration through environment variables.
Here's how to properly configure your PHP-FPM setup to preserve environment variables:
# First, edit your PHP-FPM pool configuration
# Typically located at /etc/php/7.x/fpm/pool.d/www.conf
[www]
; Preserve environment variables
clear_env = no
# Then ensure PHP is configured to read environment variables
# In /etc/php/7.x/fpm/php.ini
variables_order = "EGPCS"
When running in Docker, you need to ensure the environment variables are actually reaching the PHP-FPM process. Here's a complete Docker example:
# docker-compose.yml example
version: '3'
services:
php:
image: php:7.4-fpm
environment:
APP_ENV: production
DB_HOST: database
volumes:
- ./php-fpm.conf:/usr/local/etc/php-fpm.d/www.conf
- ./php.ini:/usr/local/etc/php/php.ini
Create a simple test script to verify your configuration:
<?php
// test.php
header('Content-Type: text/plain');
echo "APP_ENV: " . getenv('APP_ENV') . "\n";
echo "All environment variables:\n";
print_r(getenv());
?>
If you're still having problems:
- Ensure you restarted PHP-FPM after configuration changes (
service php7.0-fpm restart
) - Check that the variables are actually set in the container (
docker exec -it container_name env
) - Verify the configuration files are being properly mounted in Docker
- Check for typos in both the variable names and configuration files
For production deployments, consider using .env files:
# .env file
APP_ENV=production
DB_HOST=database
# docker-compose.yml
services:
php:
env_file:
- .env