TrafeX / docker-php-nginx

Docker image with PHP-FPM 8.3 & Nginx 1.26 on Alpine Linux
https://hub.docker.com/r/trafex/php-nginx
MIT License
1.37k stars 736 forks source link

PHP sys_temp_dir does not match Nginx client_body_temp_path #93

Closed alexmaurer-madis closed 2 years ago

alexmaurer-madis commented 2 years ago

During HTTP File Upload (POST), nginx write the temporary files into /tmp/client_temp as a non-privileged user (per the configuration in nginx.conf).

But in PHP, the global variable $_FILES contains the path /tmp (in $_FILES['userfile']['tmp_name']).

/tmp as returned by sys_get_temp_dir() is wrong here and move_uploaded_file() will fail.

A simple change in [PHP] section sys_temp_dir=/tmp/client_temp will do the trick.

I also added the tzdata package to be able to set the timezone with the TZ environnement variable (for example "Europe/Paris". It's a plus for displaying the correct timestamp in the logs output /dev/stdout

TrafeX commented 2 years ago

Hi @alexmaurer-madis,

First of all, thank you for your contribution! I had a feeling that your solution wasn't the answer for the problem you're facing so I tried to reproduce it. In my reproduction scenario I'm uploading a file of 200MB. I had to increase the default upload limits but didn't need to configure the sys_temp_dir in PHP for a successful upload.

What I did;

The index.php only contains this;

var_dump($_FILES);
var_dump(move_uploaded_file($_FILES['data']['tmp_name'], '/tmp/data.bin'));

When I upload a file of +/- 200MB this is result;

array(1) {
  ["data"]=>
  array(5) {
    ["name"]=>
    string(12) "testfile.bin"
    ["type"]=>
    string(24) "application/octet-stream"
    ["tmp_name"]=>
    string(14) "/tmp/phpADcOma"
    ["error"]=>
    int(0)
    ["size"]=>
    int(171861856)
  }
}

bool(true)

The nginx logs shows it actually buffered the body to a temporary file:

 [warn] 9#9: *1 a client request body is buffered to a temporary file /tmp/client_temp/0000000001, client: 172.19.0.1, server: _, request: "POST / HTTP/1.1", host: "localhost:8888"

So changing sys_temp_dir shouldn't be needed.

What was the issue you did ran into? Maybe I can help to find the root cause.

alexmaurer-madis commented 2 years ago

Hi @TrafeX !

First of all, thank you for the time you spent testing !!

I'm very very confused because I tried reproducing my behavior and I can't !!

I tried both with a fresh build of your image, and then from your advice, I increased the related variables both in Nginx and PHP to correspond with my needs.

All is working fine.....

p.s. Nginx docker is behind a nginx proxy manager

I got the following log from Nginx : 2022/05/26 08:47:50 [warn] 11#11: *3 a client request body is buffered to a temporary file /tmp/client_temp/0000000001

As you can see, per the Nginx configuration, the file is uploaded in /tmp/client_temp and the php variable $_FILES points to /tmp/phpmeHhIH.

["tmp_name"]=>
array(1) {
[0]=>
string(14) "/tmp/phpmeHhIH"
}

That file effectively exists, and I can move it ! (before, my problem was right here. The file was not available under /tmp)

Again, thank you for your time.

In the mean time, if I found why, I will give you a feedback.