How to set proxy in PHP-FPM

One of our clients server lives inside of tight security VPC.

Therefore, all of our EC2 web server must use HTTP_PROXY, HTTPS_PROXY.

When I try to use Concrete CMS (formally concrete5) to fetch the latest language files from remote server, I’ve got the curl timeout error and couldn’t update the language.

So I need to set the proxy for PHP-FPM.

If you use Apache’s PHP module or CLI, PHP will use server’s environment settings.

However, for php-fpm you must also configure in php.d/www.conf.

Checked & tested with Amazon Linux 2 with PHP7.4 installed via amazon-linux-extra.

Condition

For example, you have your proxy set for both http and https.

http://10.0.0.1:8080

STEP 1. Set environment globally

Although php-fpm doesn’t reference to server’s global setting, you may still want to use PHP-CLI to run via SSH. So let’s set it.

$ sudo vi /etc/environment
export http_proxy="http://10.0.0.1:8080"
export https_proxy="http://10.0.0.1:8080"
export HTTP_PROXY="http://10.0.0.1:8080"
export HTTPS_PROXY="http://10.0.0.1:8080"
export no_proxy="127.0.0.1,localhost"
export NO_PROXY=$no_proxy

Some middleware may use lowercase or capitol variable, so let’s set both.


STEP 2. Set php-fpm environment

Set it to your php-fpm config.

$ sudo vi /etc/php-fpm.d/www.conf
# Add the following two lines anywhere
env[HTTP_PROXY] = 10.0.0.1:8080
env[HTTPS_PROXY] = 10.0.0.1:8080

STEP 3. Set php-fpm environment

Then, reload php-fpm service

sudo service php-fpm reload

STEP 4. Test run

I’ve prepared the sample PHP script.
Change $proxy variable to your proxy.
And save it to your webroot.

<?php
 
// URL to test
$url = 'https://google.com';
 
$curlrequest = curl_init($url);
 
// Address:port
$proxy = '10.0.0.1:8080';
// curl_setopt($curlrequest, CURLOPT_HTTPPROXYTUNNEL, true);
// curl_setopt($curlrequest, CURLOPT_PROXY, 'http://' . $proxy);
curl_setopt($curlrequest, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlrequest, CURLOPT_TIMEOUT, 16);
curl_setopt($curlrequest, CURLOPT_LOW_SPEED_LIMIT, 8);
curl_setopt($curlrequest, CURLOPT_LOW_SPEED_TIME, 3);
curl_setopt($curlrequest, CURLOPT_FAILONERROR, true);
$result = curl_exec($curlrequest);
 
if (!$result) {
  echo "NG\rError: " . curl_error($curlrequest);
} else {
  echo 'OK';
}
 
curl_close($curlrequest);

Run the test by accessing this test PHP via browser.

You may also want to run via SSH & PHP-CLI, if STEP 1 was successfully set.

$ php curltest.php
OK

If it says “OK”, you are success!

If it doesn’t work, uncomment the lines of CURLOPT_HTTPPROXYTUNNEL & CURLOPT_PROXY above, then run to see if it works,

If worked, there is something wrong at php-fpm config or forgot to reload new php-fpm config.

Good luck