0

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.

Matteo
  • 101
  • Actually, according to the linked answer it does not work. Read the comment as well. – Gerald Schneider Jan 31 '23 at 12:12
  • @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. – Matteo Jan 31 '23 at 12:18
  • `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. – Gerald Schneider Jan 31 '23 at 12:21
  • Just configure Apache to spawn a single process and some more when needed and be done with it. – Gerald Schneider Jan 31 '23 at 12:22
  • 1
    From my understanding of the linked answer this should be available in httpd 2.5. – Gerald Schneider Jan 31 '23 at 12:24
  • According to the httpd 2.5 mod_systemd documentation - `This module does not provide support for Systemd socket activation.` – USD Matt Jan 31 '23 at 13:23

1 Answers1

0

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
larsks
  • 43,623
  • 14
  • 121
  • 180
  • 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. – Matteo Jan 31 '23 at 18:25
  • 1
    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. – larsks Feb 01 '23 at 12:46