Ubuntu 16.04 - NGINX - LetsEncrypt SSL - 502 Bad Gateway for first time visiting the site. Everything works if you visited the site earlier.

July 10, 2018 1.1k views
Nginx Let's Encrypt LEMP PHP WordPress Ubuntu 16.04

I set up a web server for two Wordpress websites. Installed NGINX, PHP, Mariadb, certbot for SSL, etc..

The problem I´m facing is that if I visited the website earlier than Certbot´s config, I can access it normally, load different pages, admin panel, php works perfectly and everything is displayed and working fine. Nervertheless, if you are a new user that tries to access the website (https://liventplanning.com) you get a 502 - Bad Gateway error.

Here´s NGINX's error.log:

2018/07/10 14:47:25 [error] 3425#3425: *1628 upstream sent invalid status "Service Unavailable" while reading response header from upstream, client: 37.9.113.120, server: liventplanning.com, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: "liventplanning.com".

And here´s NGINX´s ../sites-available/default file: (I removed all comments and most spaces, for simplicity)

server {
    server_name liventplanning.com;        
    root /var/www/liventplanning;
        index index.php index.html index.htm index.nginx-debian.html;
        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
                # proxy_pass http://localhost:8080;
                # proxy_http_version 1.1;
                # proxy_set_header Upgrade $http_upgrade;
                # proxy_set_header Connection 'upgrade';
                # proxy_set_header Host $host;
                # proxy_cache_bypass $http_upgrade;
        }

        location ~ \.php$ {
               include snippets/fastcgi-php.conf;

               # With php7.0-cgi alone:
               #fastcgi_pass 127.0.0.1:9000;
               # With php7.0-fpm:
               fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/liventplanning.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/liventplanning.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}


server {
       server_name megalaboratorio.com;
       root /var/www/megalaboratorio;
       index index.php index.html;
       location / {
               try_files $uri $uri/ =404;
       }
    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/liventplanning.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/liventplanning.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
        root /var/www/liventplanning;
        index index.php index.html index.htm index.nginx-debian.html;
    server_name www.megalaboratorio.com www.liventplanning.com; # managed by Certbot

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
                # proxy_pass http://localhost:8080;
                # proxy_http_version 1.1;
                # proxy_set_header Upgrade $http_upgrade;
                # proxy_set_header Connection 'upgrade';
                # proxy_set_header Host $host;
                # proxy_cache_bypass $http_upgrade;
        }

        location ~ \.php$ {
               include snippets/fastcgi-php.conf;

               # With php7.0-cgi alone:
               #fastcgi_pass 127.0.0.1:9000;
               # With php7.0-fpm:
               fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        }

    listen [::]:443 ssl ; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/liventplanning.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/liventplanning.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = liventplanning.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80 default_server;
        listen [::]:80 default_server;

        server_name liventplanning.com;
    return 404; # managed by Certbot
}

server {
    if ($host = megalaboratorio.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

       listen 80;
       listen [::]:80;

       server_name megalaboratorio.com;
    return 404; # managed by Certbot
}

server {
    if ($host = www.megalaboratorio.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = www.liventplanning.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80 ;
        listen [::]:80 ;
    server_name www.megalaboratorio.com www.liventplanning.com;
    return 404; # managed by Certbot
}

Any browser that has previously visited the site can use it perfectly, but if you are a new user, you get a 502 bad gateway.

Can someone point me in the right direction? I´ve been checking documentation, config files, forums and logs for a week and am still baffled by this. Thank you in advance for any help.

1 comment
  • Why don't you try virtualhost approach? Your nginx default file looks a bit messy.

4 Answers
mauriciolazo28 July 12, 2018
Accepted Answer

Hi again guys!

Just to close this topic, this is what I found out.

The culprit seems to be half wordpress half a bug in nginx. Reading NGINX´s log I found that an action from Wordpress (wp-cron.php) creates a cron job that checks for Wordpress or plugins updates every time a user loads the website, so while executing the cron job, Wordpress seems to drop the SSL socket before the data comes back and never notifies that if it started, completed or whatever.

That is, according to this Wordpress bug report. https://core.trac.wordpress.org/ticket/32306

Nevertheless, I disabled SSL, revoked the cert and still have the same 502 Bad Gateway error. After many days, I´ll just rebuild the server and install a LAMP stack instead of a LEMP stack and load the last Wordpress backup that was made, and finally issuing a new Let´s Encrypt cert.

That is really thorough documentation of your problem, which is helpful.

It works for old browsers - That is odd, it might just be a result of caching, does the site continue to work when you do a hard-refresh in your browser? (For example, on Chrome press ctrl-f5 or hold down ctrl and click the refresh button)

Here's how I would debug: Start with what is definitely working...

  1. nginx config - if there was a major syntax error in your config, nginx wouldn't even start, so your config is valid, you can confirm that by running nginx -t or sudo nginx -t if you're not root.
  2. nginx - nginx is responding with 502 Bad Gateway error means it is definitely running too. If it wasn't running at all you would just get a generic browser error page with a message like "This site can’t be reached"
  3. let's Encrypt - certbot successfully ran and generated valid SSL certs for the first domain you referenced! You can confirm this by going to the Wordpress login page (which even works from fresh browsers, I just checked) and clicking the green "🔒 Secure" tab in the browser bar in Chrome.
  4. ✅❓ php-fpm process - nginx talks to php-fpm to execute your wordpress php. I am 99% sure your PHP-FPM process is running because you can access your login page, but you can confirm it is running by typing service php7.0-fpm status on your machine (assuming Ubuntu) to check the status, if it is not running try service php7.0-fpm start - Also, check for any php-fpm logs at /var/log/php-fpm/error.log to get more information. Confirm that php-fpm is also listening on the same socket as is specified in nginx by viewing the config at: /etc/php-fpm.d/www.conf - there should be a line: listen = unix:/run/php/php7.0-fpm.sock;
  5. ❓ PHP Files - One potential problem is the File permissions on uploaded Wordpress PHP files. There's a complete guide to ensuring you have the correct file permissions set up here: https://codex.wordpress.org/Changing_File_Permissions - The quickest way to set correct permissions is to first make sure www-data owns the whole directory: sudo chown -R www-data:www-data /var/www and then to make sure the files can be read/write and executed by the www-data user with: sudo chmod -R 774 /var/www and if you are not root, make sure your user is part of the www-data group with: sudo usermod -aG www-data $USER
  6. ❓ MariaDB - Just to be sure MariaDB is running, run systemctl status mariadb

Hope this helps lead you to the solution!

As a side note, it looks like you are using the same cert files for both domains, you should run a separate let's encrypt process for your other domain and point to those files in nginx config.

  • Hello aha! Thank you for replying. Checking your suggestions I get the following:

    1. NGINX config. - ✅
    2. NGINX running - ✅
    3. Let´s Encrypt - ✅
    4. PHP-FPM: It´s running perfectly. This is the log from /var/log/php7.0-fpm.log [10-Jul-2018 18:37:15] NOTICE: fpm is running, pid 13226 [10-Jul-2018 18:37:15] NOTICE: ready to handle connections [10-Jul-2018 18:37:15] NOTICE: systemd monitor interval set to 10000ms
    5. PHP Files. These are the permissions for all files inside /var/www: -rwxr-xr-x 1 www-data www-data 418 Jul 2 13:20 index.php -rwxr-xr-x 1 www-data www-data 20 Jul 1 15:51 info.php -rwxr-xr-x 1 www-data www-data 19935 Jul 5 12:36 license.txt
    6. MariaDB. MariaDB is up and running: mysql.service - LSB: Start and stop the mysql database server daemon Loaded: loaded (/etc/init.d/mysql; bad; vendor preset: enabled) Active: active (running) since Mon 2018-07-09 14:28:47 CST; 1 day 4h ago
    7. www.conf File: The file in /etc/php/7.0/fpm/pool.d/www.conf does have the following line in the configuration: `listen = /run/php/php7.0-fpm.sock

    I´ve exhausted all my options to check for logs or services down :( and nginx error.log keeps just storing the same:

    2018/07/10 19:05:40 [error] 3425#3425: *2090 upstream sent invalid status "Service Unavailable" while reading response header from upstream, client: 190.62.251.250, server: liventplanning.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: "liventplanning.com"
    

I have been able to see a light into a solution for this. Everything is working fine in regards to NGINX, PHP, MariaDB or Linux. Nevertheless, in Wordpress there is a plugin installed, called "WP Super Cache" than when disabling it, it stops the 502 Bad Gateway error. For new users it displays a blank page, but when refreshing it works fine.

I´ll keep digging and sharing my findings when a complete solution is made.

  • Nice - glad you found the source of the error.

    If nothing else works and you need to delete WP-Super-Cache to reset it, here are some suggestions:

    • IN wp-config.php - Look for WPCACHEHOME and WP_CACHE, and delete/comment them out. Rename (or delete) folder listed in WPCACHEHOME, usually wp-content/cache
    • Look in wp-content folder for files with cache in the name (e.g. wp-cache-config.php, and rename (or delete).
Have another answer? Share your knowledge.