Wordpress Site and W3 Total Cache through Apache PHP-FPM FastCGI - php

I've setup an Apache server with Wordpress and after installing several plugins I noticed the page load times went up to 30 seconds or more so I followed several guides to fine-tune and Speed up Apache by removing modules, enabling deflate, changing worker processes, etc...
One of the changes I made was removing mod-php and using php-fpm through mod-fastcgi, afterwards I noticed several bizarre errors. W3 Total Cache reported that htaccess was not writeable despite the fact it belongs to the same user and group and I even made it world-writable (777 Permissions) and minify can't work because it can't write any changes to htaccess.
Not only that but Minify is giving off 2 more bizarre messages
Minify Auto encountered an error. The filename length value is most likely too high for your host. It is currently 150. The plugin is trying to solve the issue for you
To which it sits there trying to fix and then says
Minify Auto does not work properly. Try using Minify Manual instead or try another Minify cache method. You can also try a lower filename length value manually on settings page by checking "Disable the Minify Auto automatic filename test”
Also the compatibility check produces strange messages as well claiming that a number of modules aren't detected which are loaded, I did some quick research and found that the modules are just simply difficult to detect through fast-gi but I wonder if the plugin is doing anything given it cant detect them.
Any help would be appreciated

W3 Total Cache 'Minify Auto' under Apache/PHP-FPM
I experienced the same issue with W3 Total Cache (W3TC) and its 'Minify Auto' feature under Apache with PHP-FPM.
Problem in brief
When PHP is invoked in FastCGI mode, some CGI variables such as SCRIPT_NAME and PATH_INFO are not always set to the values expected by script developers. In my case, the value of SCRIPT_NAME was the path of the php5-fcgi executable (/usr/lib/cgi-bin/php5-fcgi), rather than that of the PHP script itself.
The minify module code in the W3TC plugin expects SCRIPT_NAME to be set correctly, and fails when it isn't.
Solution
The php.ini directive, cgi.fix_pathinfo, works around this 'CGI variables' issue when enabled. In my case, I had disabled this setting, and reenabling it resulted in generation of the correct SCRIPT_NAME and resolved the minification issue.
Instructions for a Debian/Ubuntu system
To reenable, change the setting in /etc/php5/fpm/php.ini:
cgi.fix_pathinfo = 1
And reload the php-fpm service:
sudo service php-fpm reload
Caveat
Note there have been security concerns dating from 2010 regarding the use of the cgi.fix_pathinfo setting in misconfigured Nginx sites (see here for details), however I haven't been able to reproduce this under an Apache setup.
Since PHP 5.3.9, a (poorly documented) new FPM configuration directive, security.limit_extensions has been introduced. This defaults to limiting execution to .php files only, and as far as I can tell this should mitigate the historical security issues.
Problem in detail (for those who care)
The broken CGI variables cause a problem in the W3TC function that derives the cache directory path.
This in turn causes the minify .htaccess file to be written to disk with the malformed cache path in the RewriteBase directive.
In my case, it was:
RewriteBase inify/
Rather than:
RewriteBase /wp-content/cache/minify/
This affects the subsequent rewrite rules, which ultimately prevents the minification code (which relies on these rules) from being invoked correctly.

Related

How to diagnose file upload failures in SilverStripe running on Apache

I am facing a pretty common situation judging from the questions either here on SO or in the SilverStripe forums: file uploads fail.
However, my situation seems to stem from an issue that I haven't met yet on the Web; from reading other questions and many blog articles or forum threads, I have ruled out:
Permission problems
upload_max_filesize and post_max_size in the PHP configuration (both set to 8M)
LimitRequestBody in the Apache Configuration (default value of 0, meaning "unlimited")
I have ruled these out for many reasons but this picture shows with an example of three consecutive uploads that the uploads are sometimes working:
I have also started a thread on the SilverStripe forums for this problem, but I have little hope of having luck solving the problem there.
I have set up breakpoints in the Upload, UploadField and File classes, and stepped through the code for hours without succeeding in identifying the cause of the error.
My finding so far is that any file above 128 kiB causes an internal server error. Any file below this size threshold gets uploaded as expected.
All logs (Apache, PHP, SilverStripe) are totally mute when this error occurs.
A permission issue seems very unlikely because:
PHP runs in Fast-CGI mode as a user (web1) created by ISPConfig
Apache runs as user apache:apache
I have added apache to the group of user so that groups web1 gives me web1 : client1 sshusers and groups apache gives me apache : apache ispapps ispconfig client1
the upload folder (assets) is owned by web1:client1 and has permissions 775
the temporary upload folder (upload_tmp_dir) is owned by web1:client1 and permissions are 775.
I believe what I'm looking is a means of somehow getting information about where and why the uploads fail. Is it possible to set the loglevel of Apache to "debug" or "trace"?
NOTE: an entry in the "Similar Questions" led me to this answer, which hints at SSLRenegBufferSize being by default at exactly 128 kiB. Unfortunately, whether the protocol is HTTPS or HTTP has no influence: the problem shows up.
[EDIT] I had later on set the LogLevel directive to trace but I still had no message about this error in the server logs.
Quick googling took me to the following articles:
Debian Jessie - Apache2 / PHP 5.6, can't upload more than 128kb
https://wordpress.org/support/topic/cant-upload-images-larger-than-128kb-http-error
Those suggest to check FcgidMaxRequestLen setting value.
This doesn't answer how to debug that correctly but helps solve the original issue.

phpBB 500 Internal Server Error and no log outputs

Good morning. I'm having a major issue with my phpBB installation.
I've transfered it to my computer to develop some plugins, so i'm running it on localhost, but, i've created a vHost with the exact same domain he is running online, so, i don't need to change the cookies configuration, and the database connection information is correct already.
Regard all of that, i'm getting a 500 internal server error, which displays no error on the screen nor the logs from apache and php.
I have error reporting on php as E_ALL also. What could be possible causing this, and what the solution might be?
Thanks in advance, Jorge Ferrari.
If you're getting nothing in the Apache / PHP error logs, then it's more likely to be a server configuration issue. I would suspect the problem is in a file called .htaccess in the phpBB folder. It can be used to customize the configuration in various ways, including things like setting up redirects and URL rewriting.
If the htaccess file tries to use an Apache feature which isn't available on the server, then it can generate a 500 error. You can test this by temporarily removing the file, and seeing if the website works at all (albeit possibly with some glitches).
If you've confirmed that it's the source of the problem, then ideally you'll need to enable the missing feature in the server's configuration (or possibly update the Apache installation). Alternatively, you can delete or comment-out the problematic bits of the htaccess file.
Either way, it sounds more like a webserver admin issue than programming. You might have more luck asking on the phpBB forums, or on a different Stack Exchange Q&A site (possibly Server Fault?).
Check whether you have Rewrite module enabled?(most of the this will be the reason)
In httpd.conf and uncomment
LoadModule rewrite_module modules/mod_rewrite.so
If you try to use module which is not loaded you will get 500 internal server error.
Check your modules used in .htaccess file and check httpd.conf whether used modules are loaded

PHP is adding the drive name to the start of all URLs

Short version: PHP (or Apache??) is appending "C:" to the start of all relative URLs. How can I make it stop doing this?
Detail:
I'm trying to set up an AMP stack by hand on Windows Vista. This is just for internal use on my home network.
I've installed Apache 2.2, MySQL, and PHP 5.4. Everything's good except that PHP is appending "C:" to the beginning of every single URL. For example, even calling php_info() shows that php is adding "C:" to the start of SCRIPT_PATH and PHP_SELF. This is despite the fact that the DOCUMENT_ROOT variable is correct (C:\Apache2\htdocs):
From the PHP Variables section:
Variable Value
------------------------ ---------------
_SERVER["REQUEST_URI"] /test.php
_SERVER["SCRIPT_PATH"] C:/test.php
_SERVER["PHP_SELF"] C:/test.php
_SERVER["DOCUMENT_ROOT"] C:/Apache2/htdocs
Is there some setting I need to change in php.ini to correct this? It's totally screwing up links, such that I get lots of error messages like this in my Apache logs:
[error] [client 10.0.0.4] (20023)The given path was above the root path: Cannot map GET /C:/<rest of the actual path>
I've compared both php.ini and the Apache httpd.conf to the same files for an XAMPP installation on my laptop (which does not have this problem) and I cannot see any differences that seem like they would cause such a phenomenon.
This problem has ocurred with both Apache 2.4 + PHP 5.5 (both compiled with VC11) and with Apache 2.2 + PHP 5.4 (both compiled with VC9).
I just had this same problem and I fixed it by setting "FcgidFixPathinfo" to 0 in Apache's httpd.conf file. Here's a link to where I found this.
http://www.apachelounge.com/viewtopic.php?p=18659
There must be something subtley wrong with your config I would assume, what it is I cannot guess.
However if you are not interested in the challenge of installing an AMP stack manually and you just want something that does it all in one simple ready to go install, can I suggest you have a look at WAMPServer.
This installs Apache/MySQL and PHP in a one click install.
I suggest you make sure you have uninstalled all your other attempts at installing Apache and MySQL before you try WAMPServer as they will undoubtedly cause confusion.
Just a suggestion!

How to clear php's gettext cache without restart Apache nor change domain?

This is a little code snippet from php manual:
putenv('LC_ALL=zh_CN');
setlocale(LC_ALL, 'zh_CN');
bindtextdomain('domain', './locale');
textdomain('domain');
echo gettext('Hello');
Which will output 你好 as defined in domain.mo file, but the problem is as long as the Apache is running, gettext() always return the cached result.
If I change the translation of Hello to 您好 in domain.mo, it will still output 你好.
However there is a fix for this by changing the domain argument of bindtextdomain() and textdomain() to a new name. Like from "domain" to "domain2". But this is really painful to edit the php file every time I updated the .mo file.
Is there a better way for doing this, like remove some folders or calling some php functions to do the job? So that I can write a little script for this purpose.
Every solution (1, 2, 3) suggests changing the domain to get rid of the cache problem, but this will create lots of out-of-date cache in memory.
So I dug into the gnu-gettext source for details on the cache strategy (bindtextdom.c:78.)
When bindtextdomain(domain, dirname) is called, it will check whether domain exists in the cache; if so, it will then check if dirname is the same with the one in the cache. If this fails, it will force a cache flush for the same domain, instead of creating a new one in memory.
The fix is incredibly simple, first create a dummy link to the locale folder where your .mo file is stored:
cd locale
ln -s . nocache
Then add one single line before bindtextdomain()
bindtextdomain('domain', './locale/nocache');
bindtextdomain('domain', './locale');
Now the cache is forced to flush every time.
Updates:
This hack may not works in some cases (Can't figure out the exact conditions.) This solution is NOT something you should use in production environment, but only for those who need to fix something while keeping httpd running!
Whenever you can, please avoid using gettext from very beginning, this is really something ancient and should be deprecated for good.
I called clearstatcache(); function after translating from messages.po to messages.mo and its working fine without restarting apache. Loading each change what I am making in any language file.
ok, in my case I needed to restart phpfpm by doing service php5.6-fpm-sp restart.
If you are using php-fpm you MUST restart phpfpm in order to clear gettext's cache, restarting apache2 doesn't work.
Hope is useful to someone else.
The solution for me was to save the files with a different name, using the date for example, and then changing the domain:
#the path for a domain, the .mo files must match the domain
#the trick to avoid permanent caching, is to use different names for the domain, like the date messages_180320151250
$domain = 'messages_180320151300';
#sets the path for a domain, the .mo files must match the domain
bindtextdomain($domain, $_SERVER['DOCUMENT_ROOT']."/apps/cp/locale");
textdomain($domain);
There is IMHO no direct way to do that (besides domain workaround you've mentioned), that's reason why we're using php-gettext.
Update: Which we've started to maintain as motranslator, installable by Composer and compatible with all PHP versions.
Use apachectl graceful command to ask the process to re-read the config.
It will end the request AFTER the request finished serving. So it looks safe.
According to Apache HTTP Server 2.2 Documentation
The USR1 or graceful signal causes the parent process to advise the children to exit after their current request (or to exit immediately if they're not serving anything). The parent re-reads its configuration files and re-opens its log files. As each child dies off the parent replaces it with a child from the new generation of the configuration, which begins serving new requests immediately.
It worked for me.

How can I set up error_log by folder?

My company has a large hosting, but it’s not managed by us, we don't see configuration files, but I want to reply this feature on our local test server.
I’m new in my company and want to start some debug of applications to fix some minors and majors issues to clients, but the amount of files is so big that single error_file is huge.. and there are many people working on this so each time I check log (like 30 secs to 1 min) has hundreds of added lines.
I don’t know if this is set up on Apache, through .htaccess files or in php.ini.
I am talking about PHP errors, but I don't know if this is set in PHP, Apache, or maybe using a third-party library.
I'm not talking about setting a specific folder error_log. I'm talking about if errors are logged in the scripts folder.
Example: I create a folder named test1. Inside it I make some buggy PHP script that throws some errors. When I run the script I can see an error_log file created in the folder. So it works on the fly.
I have tried to ask the hosting company support how they do this, but they haven’t answered me.
I don't know if maybe could be some kind of cPanel setting (BTW, the hosting support stuff doesn't understand this question either, but well.. usually level 1 of support can’t handle technical stuff).
I found it.
You have to set a directive in the php.ini file as follows, string "error_log". On the right side is the file name you want for the log,
error_log = error_log
This will generate a PHP error log in the folder where script executed are,
I'll try to explain.
Script test.php in folder /www/site/lib:
include "./db_conn.php";
If file db_conn.php is not located in the same directory, this will fire a warning and error. Usually this will be lead to the servers/vhost log, but using this directive you will get an error_log file under the /www/site/lib directory.
Why was I looking or this? Well, as I wrote, I'm working on a huge application, with thousands of files many fires warnings, notices, etc. I'm not the only one in the project and the site error_log file was so huge it was hard to keep tracking debug evolution for one or just some files. Now I just have to track the log from directories where I'm working.
You can manage the logs by adding this to your vhost or htaccess file
ErrorLog /path/to/a/writable/directory/error.log
For more information, have a look at this article on advanced PHP error handling via htaccess.
To do this in PHP, edit file php.ini and add the line
error_log = /path/to/where/you/want/your/php-errors.log
Then restart the web server. This should give you PHP errors, and only PHP errors, to that file. Provided, of course, that the scripts aren't written to throw away all errors.
To do it in Apache, you can use SetEnvIf to add an environment variable to any request ending in PHP, and then printing all logs with that particular environment variable. E.g.:
SetEnvIf Request_URI "\.php$" phplog
CustomLog /path/to/php.log env=phplog
To use this in multiple folders, make one environment variable per folder and one CustomLog per folder, like this:
SetEnvIf Request_URI "/folder1/.*\.php$" log_folder1
Customlog /path/to/folder1/php.log env=log_folder1
SetEnvIf Request_URI "/folder2/.*\.php$" log_folder2
Customlog /path/to/folder2/php.log env=log_folder2

Categories