Ctrl-C works on httpd:latest, but not on similar custom apache image?

Hi folks, I’m struggling to work this out and can’t find the magic sauce

If I use the official httpd:latest image, it runs in the foreground and I can kill it with ctrl-c. Quick and smooth.

If I build my own image, set up the same way, ctrl-c does not work. I’ve tried to emulate the httpd image’s basics, but it’s not working for me. Not having a ‘polite’ container is annoying to work with and also slows down iteration.

Simplifying my dockerfile to just the basics:

FROM debian:bullseye-slim

RUN apt-get update \
    && apt-get install --yes \
        apache2

COPY --chmod=755 httpd-foreground /usr/local/bin/httpd-foreground

#CMD httpd-foreground
CMD [ "httpd-foreground" ]
#CMD [ "apache2ctl", "-D", "FOREGROUND" ]

The httpd-foreground script is pulled from httpd:latest, and updated only to switch the name of the launch item (httpd binary → apache2ctl wrapper)

Whether I use the direct command (apache2ctl wrapper script) or the cloned launch script (httpd-foreground), or the script in ‘array’ format (["httpd-foreground"]), the ctrl+c function does not work.

I can’t see any meaningful difference when I docker inspect the two images - there are differences, but not in things I thought would be relevant. I also tried adding STOPSIGNAL SIGWINCH (httpd has this) but that didn’t work either - the custom build ignores it and does not exit when I resize the terminal.

Extra puzzling is that looking at the Dockerfile for httpd, we’re both using debian:bullseye-slim as a base. Both images are using a launch script (apache2ctl is a wrapper script, as is httpd-foreground) rather than calling the binary directly. The httpd dockerfile is here for reference

What am I doing wrong here? How do I get the container gracefully accepting a SIGINT/ctrl-c and shutting down?

Thanks

Hello,

It seems that your custom Docker image, which is based on debian:bullseye-slim and uses a modified launch script (httpd-foreground), does not respond to the SIGINT signal (generated by pressing Ctrl+C) as expected. You have tried different approaches, including using the apache2ctl wrapper script, but none of them seem to work.

One possible reason for this behavior could be that the modified launch script (httpd-foreground) in your custom image is not handling the SIGINT signal properly or forwarding it to the underlying Apache server process. In the official httpd:latest image, the launch script is specifically designed to handle the SIGINT signal and gracefully shut down the Apache server when it receives this signal.

To resolve this issue, you can examine the launch script (httpd-foreground) from the official httpd:latest image more closely and ensure that it properly handles the SIGINT signal. Make sure that the script forwards the signal to the Apache server process, allowing it to shut down gracefully.

Additionally, you might consider comparing the differences between the Docker images generated from the official httpd:latest image and your custom image using the docker inspect command. Look for any discrepancies in the configurations or settings that could be relevant to the SIGINT signal handling.

By ensuring that your custom image’s launch script handles the SIGINT signal correctly and that there are no significant differences in the image configurations, you should be able to gracefully shut down the Apache server within the container using Ctrl+C.

I hope this will help you.

Thanks for the ideas, Eden.

I worked out the problem - it’s the apache2ctl launch/wrapper script in Debian. It doesn’t pass through the signals to the binary it launches. Whether called directly in the CMD or in a wrapper script, apache2ctl doesn’t pass the signals through.

I ended up putting the relevant Apache env vars into the Dockerfile (APACHE_RUN_DIR etc) and running a launch script that does a pidfile cleanup (for re-used containers) and then a direct launch of the binary, and now I can ctrl-c/SIGINT properly.

This works for me, for reference:

FROM debian:bullseye-slim

ENV APACHE_RUN_DIR=/var/run/apache2
ENV APACHE_PID_FILE=/var/run/apache2/apache2.pid
ENV APACHE_LOCK_DIR=/var/lock/apache2
ENV APACHE_RUN_USER=www-data
ENV APACHE_RUN_GROUP=www-data
ENV APACHE_LOG_DIR=/var/log/apache2

RUN apt-get update \
    && apt-get install --yes \
        apache2 \
    && mkdir -p /var/run/apache2

COPY --chmod=755 apache2-foreground /usr/local/bin/

CMD [ "/usr/local/bin/apache2-foreground" ]

with this foreground wrapper script (just there to clean up pids for reused containers, same as in httpd:latest)

#!/bin/sh

rm -f /var/run/apache2/apache2.pid

exec /usr/sbin/apache2 -D FOREGROUND "$@"

The above dockerfile does need more config for real use (vhosts, logging to stdout, html content, etc), but it does do the minimal amount to work with the default debian apache.conf + conf/* files while providing a clean exit with ctrl-c/SIGINT.

TL;DR: don’t launch with apache2ctl if you want ctrl+c functionality in docker