Score:0

Start Apache on-demand using systemd socket activation

mo flag

I have a local website on Debian 11 which is rarely used so I thought I might want to start Apache using systemd socket activation when visiting the site and then shut down after few minutes of inactivity.

After installing apache on debian I stop and disable the service with systemctl disable --now apache2.service, then create /etc/systemd/system/apache2.socket with the following content, reload systemd with systemctl daemon-reload, and start the socket with systemctl start systemd.socket.

[Unit]
Description=Apache Server Socket

[Socket]
ListenStream=80

[Install]
WantedBy=sockets.target

I can confirm systemd is actually listening, and apache is started when visiting the site, but it stops immediately with error

apachectl[2794]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
apachectl[2794]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80

According to this answer it should work.

in flag
Actually, according to the linked answer it does not work. Read the comment as well.
Matteo avatar
mo flag
@GeraldSchneider though the comment to the first answer mentions this function https://github.com/apache/httpd/blob/f8450023c14656f20e964e75afdb3a16f4f38430/server/listen.c#L296 which uses https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html as recommended for socket activation.
in flag
`This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.`. It's highly probable this code never ended up in Apache httpd.
in flag
Just configure Apache to spawn a single process and some more when needed and be done with it.
in flag
From my understanding of the linked answer this should be available in httpd 2.5.
au flag
According to the httpd 2.5 mod_systemd documentation - `This module does not provide support for Systemd socket activation.`
Score:0
pt flag

You can use systemd socket activation with Apache 2.4. The Fedora package has this configuration available by default; you just need to systemctl enable httpd.socket instead of systemctl enable httpd.service.

This example is from Fedora 37, which includes Apache 2.4.55.

The socket file look like:

[Unit]
Description=Apache httpd Server Socket
Documentation=man:httpd.socket(8)

[Socket]
ListenStream=80
NoDelay=true
DeferAcceptSec=30

[Install]
WantedBy=sockets.target

And the service unit is just the standard httpd.service:

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

[Service]
Type=notify
Environment=LANG=C

ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
# Send SIGWINCH for graceful stop
KillSignal=SIGWINCH
KillMode=mixed
PrivateTmp=true
OOMPolicy=continue

[Install]
WantedBy=multi-user.target

With this in place, when I activate the socket (systemctl start httpd.socket) there are no httpd processes running:

# ps -fe |grep httpd
root        1303     944  0 15:11 pts/0    00:00:00 grep --color=auto httpd
#

But systemd is listening on port 80:

# ss -tlnp | grep :80
LISTEN 0      4096               *:80              *:*    users:(("systemd",pid=1,fd=52))

If I connect to the socket:

# curl localhost

I can see that Apache is now handling connections:

[root@localhost system]# ps -fe | grep httpd
root        1309       1  0 15:12 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache      1310    1309  0 15:12 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache      1311    1309  0 15:12 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache      1312    1309  0 15:12 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache      1313    1309  0 15:12 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
root        1494     944  0 15:13 pts/0    00:00:00 grep --color=auto httpd
Matteo avatar
mo flag
Well I replaced the unit using systemctl edit --full apache2.service with this version, changing /usr/sbin/httpd to /usr/sbin/apache2. I fixed all configuration using variables in /etc/apache2/envvars, and started the socket. I'm still getting "address already in use" though.
pt flag
It sounds like you're using Ubuntu. I took a look at the Ubuntu apache2 package, and it looks like it was built without [`HAVE_SYSTEMD`](https://github.com/apache/httpd/blob/01055edef2d317de0b292af60e5a51349ccce9a4/server/listen.c#L740) defined, which means it doesn't have support for socket activation. This is an issue with how the package was built; Apache httpd itself does have the necessary support.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.