PHP failing on an NGinX/Apache localhost setup

Hi. After half of year of intending to get around to it, I’m on a mission right to finally understand how all the backend stuff works. So I’m playing around with NGinX and Apache on an Ubuntu 20.04 VM (hosted on Windows, for what it’s worth, but anyway that’s probably irrelevant). I think, no… I KNOW that I’m really close to getting it all working. I managed to figure out serving separate domains (eg blog.local, design.local, etc) from both NGinX and Apache, and got them all redirecting to HTTPS. But there’s something wrong somewhere, as PHP isn’t working. Instead of parsing the PHP, the browser downloads the file. There was one fleeting moment when info.php actually did load on one of the sites, but then I tried changing the settings for another one, and for whatever reason that seemed to knock everything out again.

I was up until some silly hour last night talking to ChatGPT about all this. It’s pretty useful up to a certain point, for sure, but I have the feeling that it sends you off down blind alleys and causes more confusion in the end. It was certainly pretty maddening at the end, as I was in an unending loop. Let’s perhaps not call it a “doom” loop, but it was starting to feel like that by about 2:30 am :woozy_face: The trouble is that it “forgets” the original intention. At one point it told me how to set up NGinX to handle PHP, and I had to “remind” it that Apache was supposed to be doing that. In the midst of this confusion, I suppose that it’s maybe told me to change some PHP settings which are leading to the current situation.

Anyway, I now need to talk to a human or two, but I thought it might be helpful to show part of the conversation, as a summary of where I am right now. This was pretty close to the moment that I crashed last night! I suppose that maybe not every detail is here, but it’s near enough 90% of everything that I was tearing my hair out over :grimacing:

Here we go - very polite AI:

I understand your frustration. Let’s take a step-by-step approach to debug the current setup and ensure PHP files are processed correctly.
Recap of the Current Setup

Nginx is set up to proxy requests to Apache on port 8080.
Apache is set up to handle PHP files using PHP-FPM.

Steps to Verify and Debug

Verify Nginx Configuration:
Ensure your Nginx configuration is correct and contains no syntax errors.

sudo nginx -t

Verify Apache Configuration:
Ensure your Apache configuration is correct and contains no syntax errors.

sudo apache2ctl configtest

Check PHP-FPM Status:
Ensure PHP-FPM is running and properly configured.

sudo systemctl status php8.0-fpm

Check Permissions:
Ensure the PHP-FPM socket has the correct permissions and is accessible by the necessary services.

sudo ls -l /run/php/php8.0-fpm.sock

Logs Analysis:
Check the logs for any errors that might indicate what’s going wrong.

Nginx Logs:

sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log

Apache Logs:

sudo tail -f /var/log/apache2/error.log
sudo tail -f /var/log/apache2/access.log

PHP-FPM Logs:

sudo tail -f /var/log/php8.0-fpm.log

Test with a Simple PHP File:
Create a simple PHP file in your web root to test PHP processing.

echo "<?php phpinfo(); ?>" > /var/www/localhost/info.php

Access it via https://localhost/info.php.

Checking Response Headers

Using curl, you can check the headers to see how the file is being served.

curl -I https://localhost/info.php

The output should not have Content-Type: application/octet-stream.
Sample Apache and Nginx Configurations
Nginx Configuration:

server {
    listen 80;
    server_name localhost;

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name localhost;

    ssl_certificate /etc/ssl/certs/localhost.crt;
    ssl_certificate_key /etc/ssl/private/localhost.key;

    root /var/www/localhost;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ @proxy_to_apache;
    }

    location @proxy_to_apache {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Apache Configuration:

<VirtualHost *:8080>
    ServerName localhost
    DocumentRoot /var/www/localhost

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.0-fpm.sock|fcgi://localhost/"
    </FilesMatch>

    <Directory /var/www/localhost>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/localhost_error.log
    CustomLog ${APACHE_LOG_DIR}/localhost_access.log combined
</VirtualHost>

Final Diagnostic Commands

Restart All Services:

sudo systemctl restart nginx
sudo systemctl restart apache2
sudo systemctl restart php8.0-fpm

Test Again with Curl:

curl -Ik https://localhost/info.php

If the issue persists, please provide:

The exact output of the curl -Ik https://localhost/info.php command.
Any relevant entries from the error logs.

So… the AI has given you the ‘default’ configurations… what do YOUR configuration files look like? (We cant debug the defaults.)

Hi, and thanks for answering. Maybe I didn’t explain properly, as I was very tired yesterday, and taking a break from this, but anyway… Those are not the default settings. They were a resumé of my current setup. The nginx and apache2 settings are for my localhost setup. This bit here, for instance, was suggested by the AI, but it felt like it was flying off the handle a bit:

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.0-fpm.sock|fcgi://localhost/"
    </FilesMatch>

When the PHP didn’t work, the AI told me to change a few settings in the PHP files, but I was too tired to understand what it was telling me to do. I guess that the setting above was some attempt to integrate the PHP changes. Anyway, I’ll come back here with that information if I hit the same issues again, but right now I’m going to go back and reset the PHP to its default settings, and also I’m going to make sure that there’s only one version of PHP installed, as that might have been causing some interference. I’ll also go back to the Apache-only setup, and see if I can ensure that that’s working with PHP. After that, having this time properly backed up all those settings (I always forget :roll_eyes:), I’ll get back to attempting to integrate NGinX.

Before anyone asks, I’m pretty sure that the ports are all OK, and not conflicting, and that it’s just a PHP issue at this point.

So… you have a folder on your system called /var/www/localhost ? And you dont have separate Directory headers for, and i quote…

OK, hold on… Let me find the settings… Back in a bit.

Well, I’m not sure what you mean by directory headers - presumably not the same as the root directories, which are in the settings. Anyway, I’m going to show the current config for three sites that I’m testing (this is with the changes suggested by the AI)

Here’s the NGinX config for the localhost

server {
    listen 80;
    server_name localhost;

    location / {
		# Redirect all HTTP requests to HTTPS
		return 301 https://$host$request_uri;
    }
}


server {
    listen 443 ssl;
    server_name localhost;

    ssl_certificate /etc/ssl/certs/localhost.crt;
    ssl_certificate_key /etc/ssl/private/localhost.key;

    root /var/www/localhost;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ @proxy_to_apache;
    }

    location @proxy_to_apache {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

And here’s the Apache config for that, as it currently stands:

<VirtualHost *:8080>
    ServerName localhost
    DocumentRoot /var/www/localhost

	<FilesMatch \.php$>
		SetHandler "proxy:unix:/run/php/php8.0-fpm.sock|fcgi://localhost/"
	</FilesMatch>

    <Directory /var/www/localhost>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/localhost_error.log
    CustomLog ${APACHE_LOG_DIR}/localhost_access.log combined
</VirtualHost>

OK, here’s the same NGinX and Apache config for the blog.local test. First with NGinX:

server {
    listen 80;
    server_name blogtest.local;

    location / {
        # Redirect all HTTP requests to HTTPS
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name blogtest.local;
    root /var/www/blogtest;

    ssl_certificate /etc/ssl/certs/blogtest.crt;
    ssl_certificate_key /etc/ssl/private/blogtest.key;

    location / {
        try_files $uri $uri/ @proxy_to_apache;
    }

    location @proxy_to_apache {
        proxy_pass http://127.0.0.1:8082;  # Apache will handle this site on port 8082
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Apache

<VirtualHost *:8082>
    ServerName blogtest.local
    DocumentRoot /var/www/blogtest

	<FilesMatch \.php$>
		SetHandler "proxy:unix:/run/php/php8.0-fpm.sock|fcgi://localhost/"
	</FilesMatch>

    <Directory /var/www/blogtest>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/blogtest_error.log
    CustomLog ${APACHE_LOG_DIR}/blogtest_access.log combined
</VirtualHost>

And one more, just to clarify what I’m doing:

server {
    listen 80;
    server_name mysite.local;

    location / {
        # Redirect all HTTP requests to HTTPS
        return 301 https://$host$request_uri;
    }
}


server {
    listen 443 ssl;
    server_name mysite.local;
	root /var/www/mysite;

    ssl_certificate /etc/ssl/certs/mysite.crt;
    ssl_certificate_key /etc/ssl/private/mysite.key;

    location / {
        try_files $uri $uri/ @proxy_to_apache;
    }

    location @proxy_to_apache {
        proxy_pass http://127.0.0.1:8081;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

<VirtualHost *:8081>
	ServerName mysite.local
        DocumentRoot /var/www/mysite

	<FilesMatch \.php$>
		SetHandler "proxy:unix:/run/php/php8.0-fpm.sock|fcgi://localhost/"
	</FilesMatch>

    <Directory /var/www/mysite>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/mysite_error.log
    CustomLog ${APACHE_LOG_DIR}/mysite_access.log combined
</VirtualHost>

Anyway… I’m going to reset the PHP to its default values now, simply to Apache-only (obviously not those settings) and see what happens…

NGiNX is generally considered to be easier to configure than Apache. So if you go with just one server, I’d go with NGiNX.

1 Like

Well, thanks, but I want to figure out how to use them both together, since many seem to recommend them in combination. I’m nearly there. Just got the PHP working, with Apache only (hence established that PHP wasn’t ever really the problem), so now just to figure out how to pass the php requests from NGinX to Apache. Back to where I was on Friday evening!

OK, Gooooooood news. I have three sites now working on the VM. PHP OK, redirect to HTTPS OK, and no apparent port conflicts. And definitely I’ll have a break now from talking to AI, even though it is disarmingly helpful :melting_face:

Anyway, here are the NGinX and Apache configs of two out of three sites. Please comment if there’s anything that you think would be problematic at some point on a live server. Thanks :~}

1a. NGinX config for localhost

server {
    listen 80;
    server_name localhost;
    return 301 https://$host$request_uri;  # Redirect all HTTP requests to HTTPS
}

server {
    listen 443 ssl;
    server_name localhost;

    root /var/www/localhost;
    index index.html index.htm;

    ssl_certificate /etc/ssl/certs/localhost.crt;
    ssl_certificate_key /etc/ssl/private/localhost.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://127.0.0.1:8080;  # Forward requests to Apache
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~ /\.ht {
        deny all;  # Deny access to any files that start with .ht
    }
}

1b.Apache config for localhost

<VirtualHost *:8080>
    ServerName localhost
    DocumentRoot /var/www/localhost

	<FilesMatch \.php$>
		SetHandler "proxy:unix:/run/php/php8.0-fpm.sock|fcgi://localhost/"
	</FilesMatch>

    <Directory /var/www/localhost>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/localhost_error.log
    CustomLog ${APACHE_LOG_DIR}/localhost_access.log combined
</VirtualHost>

2a. NGinX config for blogtest.local

server {
    listen 80;
    server_name blogtest.local;
    return 301 https://$host$request_uri;  # Redirect all HTTP requests to HTTPS
}

server {
    listen 443 ssl;
    server_name blogtest.local;

    root /var/www/blogtest;
    index index.html index.htm;

    ssl_certificate /etc/ssl/certs/blogtest.crt;
    ssl_certificate_key /etc/ssl/private/blogtest.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://127.0.0.1:8082;  # Apache will handle this site on port 8082
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~ /\.ht {
        deny all;  # Deny access to any files that start with .ht
    }
}

2b.Apache config for blogtest.local

<VirtualHost *:8082>
    ServerName blogtest.local
    DocumentRoot /var/www/blogtest

	<FilesMatch \.php$>
		SetHandler "proxy:unix:/run/php/php8.0-fpm.sock|fcgi://localhost/"
	</FilesMatch>

    <Directory /var/www/blogtest>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/blogtest_error.log
    CustomLog ${APACHE_LOG_DIR}/blogtest_access.log combined
</VirtualHost>

Still? :thinking: I know they did way back when NGiNX was relatively new, but I’m fairly certain nobody does that anymore :person_shrugging:

1 Like

Well, that’s what I’ve been reading, but I don’t know. I’m new to all this :man_shrugging:t4: Anyway, it’s good to understand both from the start, eh.

1 Like

in a live environment i think you’d want to specify a default_server since you’re doing all of it on one port with different server name identifications, but thats not really a… ‘breaking’ thing so much as it is a cover-the-bases one?

OK, that’s cool. I’m going to spend a bit of time building and testing on the local machine, so no rush to figure everything out!

Aaaaaah, I’m BACK, unfortunately :roll_eyes: :cold_face:

After I had everything working, I played around a bit, tried installing PHPMyAdmin (successfully), and then Joomla, less successfully. It was giving me compatibility issues, so then I tried changing the PHP version, and when that was still a problem, based on some info on a Joomla info page I tried upgrading NGinX (1.26) and Apache (but I think that Apache was already more or less up to date). Anyway, that just broke everything. I just gave up and resolved to purge and reinstall NGinX Apache and PHP today, hopefully to get a clean slate. Alas no. I’ve got the HTML working OK, but no PHP. When I try a simple php page with phpinfo() or some “Hello World” stuff, I’m just getting a blank screen :sob: I’ve been all around the houses looking at php.ini files (there are a few!), and none of the changes that I’ve made have helped.

Well, here are the sample settings for one of the sites in NGinX and Apache (I don’t think they’ve changed too much, but anyway I’ll put them here again)

server {
    listen 80;
    server_name blogtest.local;
    return 301 https://$host$request_uri;  # Redirect all HTTP requests to HTTPS
}

server {
    listen 443 ssl;
    server_name blogtest.local;

    root /var/www/blogtest;
    index index.php index.html index.htm;

    ssl_certificate /etc/ssl/certs/blogtest.crt;
    ssl_certificate_key /etc/ssl/private/blogtest.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://127.0.0.1:8082;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~ \.php$ {
        proxy_pass http://127.0.0.1:8082;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~ /\.ht {
        deny all;
    }
}

<VirtualHost *:8082>
    ServerName blogtest.local
    DocumentRoot /var/www/blogtest

    <Directory /var/www/blogtest>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted

        <FilesMatch \.php$>
            SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost/"
        </FilesMatch>
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/blogtest_error.log
    CustomLog ${APACHE_LOG_DIR}/blogtest_access.log combined
</VirtualHost>

“Just getting a blank screen” = Go look at all the error logs (probably PHP’s), something’s barfing.

It’s driving me mad! I’ve been a million times around the houses now, and of course checking error logs. I’m quite sure that there’s nothing wrong with the NGinX/Apache config. It was fine before I started playing with Joomla, and had to fiddle with PHP for compatibility reasons.

Anyway, I uninstalled and purged every instance of PHP, and now I’m very slowly putting it back. Trying to understand what everything is doing (good luck with that, right??? :cold_face:)

OK, I’ve done everything I can to purge and build back, but still getting that blank screen. Here are some error logs. Are there any others to be looking at?

sudo tail /var/log/php8.3-fpm.log 
[11-Jun-2024 20:13:52] NOTICE: Terminating ...
[11-Jun-2024 20:13:52] NOTICE: exiting, bye-bye!
[11-Jun-2024 20:13:52] NOTICE: fpm is running, pid 26864
[11-Jun-2024 20:13:52] NOTICE: ready to handle connections
[11-Jun-2024 20:13:52] NOTICE: systemd monitor interval set to 10000ms
[11-Jun-2024 20:33:20] NOTICE: Terminating ...
[11-Jun-2024 20:33:20] NOTICE: exiting, bye-bye!
[11-Jun-2024 20:33:21] NOTICE: fpm is running, pid 28787
[11-Jun-2024 20:33:21] NOTICE: ready to handle connections
[11-Jun-2024 20:33:21] NOTICE: systemd monitor interval set to 10000ms
sudo tail /var/log/apache2/error.log 
[Tue Jun 11 19:23:50.693420 2024] [core:notice] [pid 8430] AH00094: Command line: '/usr/sbin/apache2'
[Tue Jun 11 19:36:38.877696 2024] [mpm_prefork:notice] [pid 8430] AH00169: caught SIGTERM, shutting down
[Tue Jun 11 19:36:38.974417 2024] [mpm_prefork:notice] [pid 20680] AH00163: Apache/2.4.41 (Ubuntu) OpenSSL/1.1.1f configured -- resuming normal operations
[Tue Jun 11 19:36:38.974462 2024] [core:notice] [pid 20680] AH00094: Command line: '/usr/sbin/apache2'
[Tue Jun 11 20:13:52.716944 2024] [mpm_prefork:notice] [pid 20680] AH00169: caught SIGTERM, shutting down
[Tue Jun 11 20:13:52.813425 2024] [mpm_prefork:notice] [pid 26883] AH00163: Apache/2.4.41 (Ubuntu) OpenSSL/1.1.1f configured -- resuming normal operations
[Tue Jun 11 20:13:52.813469 2024] [core:notice] [pid 26883] AH00094: Command line: '/usr/sbin/apache2'
[Tue Jun 11 20:33:12.979175 2024] [mpm_prefork:notice] [pid 26883] AH00169: caught SIGTERM, shutting down
[Tue Jun 11 20:33:13.063635 2024] [mpm_prefork:notice] [pid 28773] AH00163: Apache/2.4.41 (Ubuntu) OpenSSL/1.1.1f configured -- resuming normal operations
[Tue Jun 11 20:33:13.063686 2024] [core:notice] [pid 28773] AH00094: Command line: '/usr/sbin/apache2'
sudo tail /var/log/nginx/error.log 
2024/06/11 18:35:37 [notice] 128722#128722: worker process 128723 exited with code 0
2024/06/11 18:35:37 [notice] 128722#128722: exit
2024/06/11 18:59:33 [warn] 1020#1020: conflicting server name "localhost" on 0.0.0.0:80, ignored
2024/06/11 18:59:33 [notice] 1020#1020: using the "epoll" event method
2024/06/11 18:59:33 [notice] 1020#1020: nginx/1.26.1
2024/06/11 18:59:33 [notice] 1020#1020: built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2) 
2024/06/11 18:59:33 [notice] 1020#1020: OS: Linux 5.15.0-107-generic
2024/06/11 18:59:33 [notice] 1020#1020: getrlimit(RLIMIT_NOFILE): 1024:524288
2024/06/11 18:59:33 [notice] 1041#1041: start worker processes
2024/06/11 18:59:33 [notice] 1041#1041: start worker process 1042

What about your PHP errors?
Do you have anything like Xdebug installed?

Eh, no :thinking: First i’ve heard of that! Is that a normal install?

Anyway, there isn’t any code to debug at this point! There’s just a “Hello World” and a phpinfo(). It’s all about config stuff. Two or three days already i’m trying to understand this stuff.

Well, I honestly have no idea what to do now. I was wondering if Firefox was doing something weird, but I just checked things in a different browser (Brave), and it’s the same situation. HTML loads fine, PHP doesn’t.