How to Run Apache as different User with mpm-itk

Run Apache as different User is quite useful in WordPress development and WordPress hosting.

Apache runs as www-data in Debian/Ubuntu.

However, this is not convenient in a WordPress installation:

On the production server

  • Many WordPress files must be owned by the SSH/SFTP user in order to apply changes
  • Most WordPress must be owned by the Web Server user, so WordPress updates can be applied

Even more so in a development environment

Except for the above reasons, Many WordPress files must be owned by the PC user in order

  • to process the code with your IDE
  • to use git (if needed)
  • to make backups easily

Run Apache as different User with mpm-itk

There are several solutions to this problem. One of these is mpm-itk.

According to the official page:

apache2-mpm-itk (just mpm-itk for short) is an MPM (Multi-Processing Module) for the Apache web server. mpm-itk allows you to run each of your vhost under a separate uid and gid—in short, the scripts and configuration files for one vhost no longer have to be readable for all the other vhosts.

Just install it:

apt-get install libapache2-mpm-itk

and use the following directives in your vhost config file:

<IfModule mpm_itk_module>
	AssignUserId your_user your_group
</IfModule>

For example:

<VirtualHost *:443>
        ServerName example.com
        ServerAdmin you@your_email.com

        DocumentRoot /var/www/html/example.com

        <IfModule mpm_itk_module>
            AssignUserId your_user your_group
        </IfModule>

        <Directory /var/www/html/example.com>
                Options -Indexes +FollowSymLinks +MultiViews
                AllowOverride All
                Require all granted
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/example.com_error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined

        SetOutputFilter DEFLATE
        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|ico|png)$ \ no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ \no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary

        BrowserMatch ^Mozilla/4 gzip-only-text/html
        BrowserMatch ^Mozilla/4\.0[678] no-gzip
        BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

        SSLEngine on
        SSLCertificateFile /etc/ssl-dev/your_cert.pem
        SSLCertificateKeyFile /etc/ssl-dev/your_cert_key.pem
</VirtualHost>

<VirtualHost *:80>
  ServerName  example.com
  Redirect permanent / https://example.com/
</VirtualHost>

Problems with Docker

It will not run in a Docker container.

In Apache error.log you will get an error like this:

[mpm_itk:warn] [pid 1783] (itkmpm: pid=1783 uid=33, gid=33) itk_post_perdir_config(): setgid(1000): Operation not permitted

The solution is to run the container with different permissions (less secure – not recommended on production)

docker run \
--name "my-container" \
--cap-add=SYS_NICE --cap-add=DAC_READ_SEARCH \
vendor/image

More info here.

Problems with PHP mail function and Exim4

The PHP mail function does not work with exim4 if you have libapache2-mpm-itk installed(!)

exim crashes when WordPress was trying to send email and in the paniclog (/var/log/exim4/paniclog) you will see something like this:

2023-01-30 19:25:27 unable to set gid=33 or uid=0 (euid=0): forcing real = effective

According to

the solution is to add LimitUIDRange 0 2000 in Apache configuration.

nano /etc/apache2/conf-available/mpm_itk_with_php_mail.conf

add the directive:

LimitUIDRange 0 2000

and finally:

a2enconf mpm_itk_with_php_mail
systemctl restart apache2.service

(probably insecure for production use)