Configuring System-wide Proxy Settings for PHP in Linux Environments


23 views

When deploying PHP applications (like Drupal) in enterprise environments, servers are often behind proxy gateways. The fundamental issue arises when PHP's built-in functions (file_get_contents, streams, etc.) or third-party libraries need internet access but lack proxy awareness.

For a non-intrusive solution that doesn't require code modification, these are the most effective approaches:

1. PHP INI Directives

Edit your php.ini file (locate with php --ini):

[PHP]
; For HTTP requests
proxy_enabled = On
proxy_host = "your.proxy.server"
proxy_port = 8080
proxy_user = "username"
proxy_pass = "password"

; For HTTPS requests
proxy_ssl_enabled = On
proxy_ssl_host = "your.proxy.server"
proxy_ssl_port = 8080

2. Environment Variables

Set these in your Apache/Nginx configuration or system profile:

export http_proxy="http://user:pass@proxy:port"
export https_proxy="http://user:pass@proxy:port"
export no_proxy="localhost,127.0.0.1,.internal"

For update checks and other external connections in Drupal:

// In settings.php
$settings['http_client_config']['proxy']['http'] = 'http://proxy:port';
$settings['http_client_config']['proxy']['https'] = 'http://proxy:port';
$settings['http_client_config']['proxy']['no'] = ['localhost', '127.0.0.1'];

Create a test script:

<?php
print_r(stream_context_get_default());
echo file_get_contents('http://example.com');
?>

Check the output for proxy headers and successful content retrieval.

  • Certificate errors: Set openssl.cafile in php.ini
  • Timeout issues: Adjust default_socket_timeout
  • Authentication failures: Verify credentials with curl -x http://proxy:port http://example.com

For cases where INI settings don't propagate:

// In auto_prepend_file
stream_context_set_default([
    'http' => [
        'proxy' => 'tcp://proxy:port',
        'request_fulluri' => true,
        'header' => "Proxy-Authorization: Basic " . base64_encode("user:pass")
    ]
]);

When running PHP applications on Linux servers behind corporate proxies, you often encounter connectivity issues when the code attempts to make external HTTP requests. This commonly affects operations like:

  • Package manager updates (e.g., Composer)
  • CMS update checks (Drupal/WordPress)
  • API integrations
  • Web service consumption

The most reliable approach is configuring proxy settings at the system level, which affects all PHP processes:

# Add to /etc/environment
http_proxy="http://proxy.example.com:8080/"
https_proxy="http://proxy.example.com:8080/"
ftp_proxy="http://proxy.example.com:8080/"
no_proxy="localhost,127.0.0.1,.internal"

# Then apply changes:
source /etc/environment

For PHP-specific settings, modify your php.ini file:

; /etc/php/8.2/cli/php.ini or relevant version
[PHP]
; HTTP context options
default_socket_timeout = 60
allow_url_fopen = On
allow_url_include = Off

; Proxy settings
auto_prepend_file = /etc/php/proxy_config.php

The auto_prepend_file approach lets you set proxy context globally:

// /etc/php/proxy_config.php
<?php
stream_context_set_default([
    'http' => [
        'proxy' => 'tcp://proxy.example.com:8080',
        'request_fulluri' => true,
        'header' => "Proxy-Authorization: Basic " . base64_encode("username:password")
    ],
    'https' => [
        'proxy' => 'tcp://proxy.example.com:8080',
        'request_fulluri' => true,
        'header' => "Proxy-Authorization: Basic " . base64_encode("username:password")
    ]
]);

Verify proxy functionality with this test script:

<?php
$response = file_get_contents('https://www.drupal.org');
var_dump($http_response_header);

For Drupal update checks, additional measures might be needed:

// settings.php
$settings['http_client_config'] = [
    'proxy' => [
        'http' => 'http://proxy.example.com:8080',
        'https' => 'http://proxy.example.com:8080',
    ],
    'verify' => false // Only if proxy uses self-signed certs
];

When using PHP-FPM, set environment variables in pool configuration:

; /etc/php/8.2/fpm/pool.d/www.conf
env[http_proxy] = http://proxy.example.com:8080
env[https_proxy] = http://proxy.example.com:8080
env[no_proxy] = "localhost,127.0.0.1"