Changing the Apache worker account changes which Unix permissions the web server inherits for reading site content and writing application data such as uploads, cache files, and Unix sockets. Matching that account to the deployment model avoids permission failures without opening directories to every local user.

On packaged Apache builds, the parent process starts as root so it can bind privileged ports, then worker processes answer requests as the configured User and Group. Current Debian and Ubuntu packages keep those directives in /etc/apache2/apache2.conf and feed them from APACHE_RUN_USER and APACHE_RUN_GROUP in /etc/apache2/envvars, while RHEL-family systems usually set User and Group directly in /etc/httpd/conf/httpd.conf.

Examples below use the apache2 service layout from Debian and Ubuntu. The replacement account and group must already exist, the web content and runtime paths must remain readable or writable as needed, and one root parent process in the final process list is normal; only the request-handling workers should switch to the new unprivileged account. When applications use PHP-FPM or another backend, that backend can still run under a different Unix account.

Steps to change Apache user and group:

  1. Print the active Apache run-time user and group.
    $ sudo apache2ctl -t -D DUMP_RUN_CFG
    ##### snipped #####
    User: name="www-data" id=33
    Group: name="www-data" id=33

    On CentOS, RHEL, Rocky Linux, and AlmaLinux, replace apache2ctl with httpd or apachectl if that is the installed control wrapper.

  2. Confirm that the packaged configuration reads User and Group from the environment file.
    $ sudo grep -nE '^[[:space:]]*(User|Group)[[:space:]]' /etc/apache2/apache2.conf
    115:User ${APACHE_RUN_USER}
    116:Group ${APACHE_RUN_GROUP}
  3. Check the current values exported by /etc/apache2/envvars.
    $ sudo grep -nE '^export APACHE_RUN_(USER|GROUP)=' /etc/apache2/envvars
    16:export APACHE_RUN_USER=www-data
    17:export APACHE_RUN_GROUP=www-data
  4. Open /etc/apache2/envvars in a text editor.
    $ sudoedit /etc/apache2/envvars

    sudoedit writes changes as root while editing with $EDITOR.

  5. Set APACHE_RUN_USER to the service account that should own Apache worker processes.
    export APACHE_RUN_USER=webworker

    The account must already exist before Apache is restarted.

    Do not set the worker account to root or to a personal login user.

  6. Set APACHE_RUN_GROUP to the matching group.
    export APACHE_RUN_GROUP=webteam

    A dedicated group makes it easier to grant controlled access to shared application paths.

  7. Verify that the replacement account and group exist on the system.
    $ getent passwd webworker
    webworker:x:999:995::/nonexistent:/usr/sbin/nologin
    
    $ getent group webteam
    webteam:x:995:

    The numeric UID and GID values vary by system; the lookup only needs to return matching entries.

    On RHEL-family systems, edit /etc/httpd/conf/httpd.conf instead of /etc/apache2/envvars when the User and Group directives are set directly.

  8. Adjust ownership or group access only on the content and runtime paths that Apache must read or write.
    $ sudo chown -R webworker:webteam /srv/www/example.com

    Changing ownership recursively on the wrong path can break unrelated content and services. Update only the document root, upload directories, cache directories, and socket directories that must follow the new account.

  9. Test the Apache configuration for errors before restarting.
    $ sudo apache2ctl configtest
    Syntax OK

    A warning such as AH00558: Could not reliably determine the server's fully qualified domain name does not usually block the change, but setting a global ServerName removes the noise.

  10. Restart the Apache service to apply the changes.
    $ sudo systemctl restart apache2

    On CentOS and RHEL, the service name is usually httpd (sudo systemctl restart httpd).

  11. Confirm that systemd reports the unit as active after the restart.
    $ sudo systemctl is-active apache2
    active
  12. Verify that the request-handling workers now run under the new user and group.
    $ ps -o user:12,group:12,pid,cmd -C apache2
    USER         GROUP          PID CMD
    root         root          3414 /usr/sbin/apache2 -k start
    webworker    webteam       3416 /usr/sbin/apache2 -k start
    webworker    webteam       3418 /usr/sbin/apache2 -k start

    One root parent process is normal; the child worker processes are the lines that should reflect the new User and Group values.