Apache 2 Reverse Proxy and Certificate Renewal

After migrating one of my hosted service to a different subdomain using Docker and pointing to that running container via ProxyPass and ProxyPassReverse, I noticed that the automatic certificate renewal did not work correctly.

I tried to manually renew the certificate via certbot certonly -d $DOMAIN, but then noticed that it did not find the challenge it placed in the .well-known/acme-challenge folder. After checking some permissions and seeing that the challenge file is actually there, I noticed that the response returned by Apache 2 said that it came from 172.17.0.1.

Huh.

That is the network range for my Docker containers, so it seems that Apache does not automatically give precedence to local file if the reverse proxy configuration looks like this:

  ProxyPass / http://172.17.0.1:9001/
  ProxyPassReverse / http://172.17.0.1:9001/

I searched for a solution to this because I’m not that familiar with configuring Apache 2 as a reverse proxy and came upon the following solution: declare the .well-known/acme-challenge path to be exempt from being proxied. The configuration now looks like this and works like a charm:

  ProxyPass /.well-known/acme-challenge !
  ProxyPassReverse /.well-known/acme-challenge !

  ProxyPass / http://172.17.0.1:9001/
  ProxyPassReverse / http://172.17.0.1:9001/

The order actually matters, as Apache 2 evaluates the configuration options and executes them in the order they appear.