Running PHP under NGINX on IBM i
NGINX is the modern alternative to Apache for IBM i PHP deployments. It performs noticeably better under concurrent load, configuration is more legible, and it’s the standard outside the IBM i world for new PHP work. The trade-off is that there’s no IBM-supplied admin UI — everything is hand-edited config files.
NGINX has a built-in FastCGI client, but no FastCGI process manager. For that, we use the standard PHP-FPM utility, which the Zend RPMs include.
The setup pattern below mirrors the NGINX team’s WordPress recipe, adapted for IBM i conventions.
1. Install NGINX
From the OSPM, install the nginx package. After installation, NGINX lives at /QOpenSys/pkgs/sbin/nginx and reads config from /QOpenSys/etc/nginx/.
2. Lay out the directory structure
We’ll mirror the IBM i Apache convention so the directory layout feels familiar:
| Path | Purpose |
|---|---|
/www/php |
Server base |
/www/php/logs |
NGINX access and error logs |
/www/php/htdocs |
Document root — your .php files go here |
Create those directories before starting the server.
3. Write the NGINX configuration
Create /QOpenSys/etc/nginx/php.conf:
error_log /www/php/logs/nginx.err.log;
pid /www/php/logs/nginx.pid;
events {
# required section, leave empty for defaults
}
http {
upstream php {
# default FPM listen address
server 127.0.0.1:9000;
}
server {
# set your actual hostname here
server_name mywebserver.example.com;
# listen port for this site
listen 6090 default_server;
# document root
root /www/php/htdocs;
# allow URLs without /index.php
index index.php index.html;
# case-sensitive .php match — use ~* for case-insensitive
location ~ \.php$ {
include /QOpenSys/etc/nginx/snippets/fastcgi-php.conf;
fastcgi_pass php;
}
}
}
Then create the FastCGI snippet referenced above at /QOpenSys/etc/nginx/snippets/fastcgi-php.conf:
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Verify the script exists before passing it
try_files $fastcgi_script_name =404;
# Restore $fastcgi_path_info after try_files (a known NGINX quirk)
# https://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi.conf;
4. Configure PHP-FPM
PHP-FPM’s main config file is /QOpenSys/etc/php/php-fpm.conf, which mostly just delegates to /QOpenSys/etc/php/php-fpm.d/www.conf. The defaults are fine for getting started — except for one thing.
FPM requires its worker processes to run under a real user and group. The default user is QTMHHTTP, but QTMHHTTP has no primary group. FPM detects this as an error:
[19-Jul-2019 13:27:35] ERROR: [pool www] please specify user and group other than root
[19-Jul-2019 13:27:35] ERROR: FPM initialization failed
You have two options:
- Give
QTMHHTTPa primary group:CHGUSRPRF USRPRF(QTMHHTTP) GRPPRF(GRP1) - Override user and group in the FPM pool config, by editing
/QOpenSys/etc/php/php-fpm.d/www.conf:user = qtmhhttp group = grp1
Either works. Pick the option that fits your shop’s user-management conventions.
5. Start everything
# NGINX, using the config you just wrote
/QOpenSys/pkgs/bin/nginx -c php.conf
# PHP-FPM (runs in the background)
/QOpenSys/pkgs/sbin/php-fpm
NGINX runs under the user profile that started it; FPM runs under whatever user/group is configured in www.conf.
6. Test
Drop an index.php into /www/php/htdocs:
<?php phpinfo(); ?>
Visit http://your-host:6090/. If you see the PHP info page, the stack is working.
Why NGINX over Apache?
For new IBM i PHP deployments, the reasons to prefer NGINX are practical:
- Better concurrency. NGINX is event-driven; Apache (in the IBM i FastCGI configuration) is process-per-request. Under load, NGINX handles more requests per CPU.
- Cleaner configuration. The config file is a single readable document, not a wizard-generated mix of Apache directives.
- First-class PHP-FPM integration. FPM is the de facto standard process manager for PHP, and it’s what every PHP performance article you’ll read assumes.
- Familiar to non-IBM-i developers. A new hire who’s never touched a 5250 will recognize an NGINX config immediately.
The reasons to stick with Apache:
- You already have it running. Existing Apache configs don’t need to be migrated unless there’s a problem to solve.
- You rely on the HTTP Admin UI. NGINX has no equivalent.
- You’re integrating with IBM-supplied modules that depend on the IBM HTTP Server — these are rare but exist.
For a new PHP application on a new partition, NGINX is the right default.
Where next
- Connecting to DB2 — the next question is how PHP talks to your database.
- Performance tuning — prestart jobs, exit programs, and traces that affect latency regardless of which web server you chose.