Configuring System-wide Proxy Settings for PHP in Linux Environments


2 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"