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 Answer 1

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.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .