0

I need to have a PHP file execute whenever the httpd service starts or restarts. I found that Systemd has a configuration setting called **ExecStartPost, which looks perfect for what I need to do.

I updated the /etc/systemd/system/multi-user.target.wants/httpd.service file to reflect the following:

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecStartPost=/bin/php /usr/sbin/php_test
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

The content of /usr/sbin/php_test is:

#!/bin/php

<?php
echo "Writing to /tmp/php-test.txt...\n";

$myfile = fopen("/tmp/php-test.txt", "w") or die("Unable to open file!");
$txt = "TEST! " . date("F j, Y, g:i a") . PHP_EOL;
fwrite($myfile, $txt);
fclose($myfile);

echo "Done!!\n";
?>

Then I chmod 777 the php file and reloaded the daemon files via systemctl daemon-reload. But when I restart httpd, it doesn't create the /tmp/php-test.txt file that I was expecting to see.

If I execute /bin/php /usr/sbin/php_test via the command line, it works perfectly fine.

I found a separate StackOverflow thread stating that Systemd reads the .service files from bottom to top, so I moved the ExecStartPost line to right above the ExecStart line, reloaded the daemon files and restarted apache again, with no success...

What am I doing wrong here?

Thanks!

Update 1

I changed the httpd.service file to the following:

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecStartPost=/bin/bash -c "/bin/php -f /tmp/php_test"
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

And now I get an error (at least that's something to go on!). When I review the logs via journalctl -xe, I see the following:

Apr 19 12:47:46 silo-stg-a01.cymedica.com systemd[1]: Starting The Apache HTTP Server...
-- Subject: Unit httpd.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit httpd.service has begun starting up.
Apr 19 12:47:46 silo-stg-a01.cymedica.com bash[13268]: Could not open input file: /tmp/php_test
Apr 19 12:47:46 silo-stg-a01.cymedica.com systemd[1]: httpd.service: control process exited, code=exited status=1
Apr 19 12:47:47 silo-stg-a01.cymedica.com systemd[1]: Failed to start The Apache HTTP Server.
-- Subject: Unit httpd.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit httpd.service has failed.
--
-- The result is failed.
Apr 19 12:47:47 silo-stg-a01.cymedica.com systemd[1]: Unit httpd.service entered failed state.
Apr 19 12:47:47 silo-stg-a01.cymedica.com systemd[1]: httpd.service failed.

The error is Could not open input file: /tmp/php_test.. Not sure what that means yet though.

And I'm aware that prefixing the command with a hyphen would let the process move on even if the PHP file fails to execute, but that's not what I'm trying to fix. I need the PHP script to execute properly.

FYI, if you're wondering why I have it execute /bin/bash -c "/bin/php -f /tmp/php_test"

and not just /bin/php -f /tmp/php_test

I was just playing around with trying to have it execute the php script from a bash command. But if I change it to just /bin/php -f /tmp/php_test, I get the exact same error in journalctl

Update 2

I notice that if I replace the ExecStartPost line with the PHP command with just:

ExecStartPost=/bin/logger "ExecStartPost 1"

(which goes just after the ExecStart line), it logs ExecStartPost 1 to the logs just fine... So I think its related to how the php file itself is executed

1

You have in your unit file:

PrivateTmp=true

This means systemd will create a separate namespace for the unit's /tmp and /var/tmp directories. Remove the line to use the usual /tmp.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.