Solution to PHP FTP connection problem in containerized environment
P粉302484366
2023-08-28 23:03:17
<p>I'm trying to containerize my PHP script. </p><p>But for some reason it cannot connect to my FTP server when running in a container. </p><p>Run the script on my local machine without any problems. </p><p><strong>Dockerfile:</strong></p><pre class="brush:php;toolbar:false;">FROM php:8.1-cli
EXPOSE 8080
COPY ./var/www/html/
WORKDIR /var/www/html
ENTRYPOINT php -f serve.php</pre><p><strong>PHP script:</strong></p><pre class="brush:php;toolbar:false;">$ connection = ftp_connect(FTP_HOST, 21, 90);
ftp_pasv($connection, true);
if(ftp_login($connection, FTP_USERNAME, FTP_PASSWORD))
{
$stream = fopen('data://text/plain,','r');
ftp_fput($connection, $filename, $stream);
}
ftp_close($connection);</pre><p>After 90 seconds, it will give the following warning: </p><p><em>ftp_fput(): Connection timed out in /var/ www/html/ftp.php on line 16</em></p><p>I tried going into the container and installing the FTP client. </p><p>It gives me a similar timeout error - I can connect to the host, but running any command causes a pause. </p><p>I also tried running the container on a VPS to eliminate any local firewall/network issues. </p><p>But the problem still exists. </p><p>If you need further information to resolve the issue, please let me know. </p>
Pay attention to the documentation of PHP's
ftp_pasv
function (emphasis mine):Also note that you are not checking the status return value of the
ftp_pasv
call, so you won't notice whether the call actually succeeded (which it most likely won't). Therefore, your script will attempt to establish an active FTP connection. This does not work in containers (unless started with--network=host
), since containers run in a private network via NAT on the host machine.Solution: Log in first, then enable passive mode (also always check for error return values; many old functions from the PHP standard library do not throw exceptions but rely on error return values):