Acho que o proxy reverso externo é a chave — não creio que isso seja solucionável de forma alguma, ou pelo menos não facilmente, apenas dentro do contêiner Docker.
Resolvi o problema fazendo o Docker do Discourse ouvir em um socket Unix e colocando um Caddy na mesma máquina (fora do Docker). A configuração do Caddy é trivial, inclui o Let’s Encrypt e agora funciona conforme o esperado também para IPv6.
forum.example.com {
proxy / unix:/var/discourse/shared/web-only/nginx.http.sock {
transparent
websocket
}
}