简体   繁体   中英

Nginx 504 gateway timeout with Docker

I'm using PHP and Apache with nginx for a reverse proxy, all on Docker, and I have a couple of long running calls that are timing after 60 seconds, resulting in a 504 Gateway Time-out. I know my app is being called successfully because I'm tailing my PHP app's log and I can see it actively writing to the log. Every single time it's a 60 second timeout, but I can't seem to figure out where that setting is.

I tried the suggestions in this post , but nothing worked. I've updated my php.ini file with a few time related settings and I've verified they're being set with phpinfo

max_input_time = 0
max_execution_time = 500

I also increased the memory limit to 512, but considering it times out in about 60 seconds every single time I don't think that's the issue.

As far as updating nginx settings, I initially followed this tutorial on adjusting nginx-proxy timeout, but that didn't work. I undid the changes, then ssh'd into the container and manually updated /etc/nginx/nginx.conf, here's what the http section looks like

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout           500;
    proxy_connect_timeout       600;
    proxy_send_timeout          600;
    send_timeout                600;
    client_max_body_size        5000;
    client_header_timeout       600;
    client_body_timeout         600;
    fastcgi_read_timeout        300;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

I made sure to run nginx -s reload after updating the nginx.conf file. I'm not sure where else to look, because everything I've come across is pretty much what I've done already. What else could be causing nginx to timeout after 60 seconds? Thanks

Here's my PHP dockerfile

FROM php:7.2-fpm-alpine3.7

RUN apk update; \
    apk upgrade;

RUN docker-php-ext-install pdo_mysql

RUN apk add --no-cache php7-pear php7-dev gcc musl-dev make
RUN pecl install xdebug


RUN pecl install -o -f redis \
&&  rm -rf /tmp/pear \
&&  docker-php-ext-enable redis

The issue is that nginx has it's own timeouts. Ideally, you'd sync nginx and PHP. I can't speak to Apache here as I don't know what mode you're running it with (FPM or mod_php). I'm also not exactly sure why you're running Nginx and Apache, but, if you're getting a 504 response, and PHP is still processing the request, Nginx is terminating the request and returning the 504 response. Nginx doesn't run like Apache with mod_php where the processes are one in the same. Nginx is going to relay the request and wait for whatever process to return a response.

See the following settings from our configs regarding timeouts from Nginx.

# Timeouts
# The client_body_timeout and client_header_timeout directives are
# responsible for the time a server will wait for a client body or
# client header to be sent after request. If neither a body or header
# is sent, the server will issue a 408 error or Request time out.
#
# The keepalive_timeout assigns the timeout for keep-alive connections
# with the client. Simply put, Nginx will close connections with the
# client after this period of time.
#
# Finally, the send_timeout is a timeout for transmitting a response
# to the client. If the client does not receive anything within this
# time, then the connection will be closed. Send the client a "request
# timed out" if the body is not loaded by this time. Default 60.
client_body_timeout   32;
client_header_timeout 32;
# Every 60 seconds server broadcasts Sync packets, so 90 is a conservative upper bound. Default is 65
keepalive_timeout 90;
send_timeout 300;

This answer may help those who use cloud, placing reverse proxy NGINX instance within a subnet, with NAT Gateway associated.

I also struggled with 504 upstream timeout error. As described in the link, it was neither NGINX nor the backend API's failure.

NAT Gateway was only accepting limited number of connection at the same time.

This resulted in NGINX not being able to connect to the upstream.

This config solved the issue for me

upstream http_backend {
    server 127.0.0.1:8080;

    keepalive 16;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}

Especially adding proxy_set_header Connection "";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM