a final, detailed summary of my troubleshooting efforts. Despite trying multiple architectures, including the best practices recommended here and by both ChatGPT and Google AI Studio, the issue persists. I am now convinced this is a bug or an intractable issue within the Grist Omnibus image itself, as JordiGH initially suspected.
Summary of Actions Taken:
After restoring the server to a clean snapshot, we abandoned the old, separated setup and built a new, unified architecture from scratch, following standard Docker best practices.
1. Unified Architecture:
-
A single docker-compose.yml file was created to manage both Nginx and Grist.
-
A private bridge network (app-net) was defined in the compose file, ensuring both containers could communicate directly and reliably via their service names (grist-app and nginx-proxy).
-
The problematic network_mode: host on Nginx was removed. Nginx was configured to expose ports 80 and 443 in the standard way.
-
All data (Grist’s database, XWiki’s data, etc.) and configurations were moved to a single, organized directory structure (~/sistemaspavicon).
2. Network Connectivity Test (Successful):
-
We executed a shell inside the running nginx-proxy container .
-
From inside Nginx, we ran curl http://grist-app:80.
-
Result: The command was successful . Grist responded with a Moved Permanently redirect. This 100% confirms that the Docker networking is perfect and Nginx can successfully resolve and connect to the Grist container.
The Final Deadlock: The TRUSTED_PROXY_IPS Failure
Based on Dmitry’s feedback, the final attempt was to make Grist’s internal Traefik proxy explicitly trust Nginx within our new, clean architecture.
1. Grist Configuration:
-
HTTPS was set to external (as required by Grist).
-
URL was set to https://grist.example.com.
-
We found the internal IP of the nginx-proxy container on the app-net network (e.g., 172.22.0.5).
-
We set TRUSTED_PROXY_IPS=172.22.0.5/32 in Grist’s environment variables.
2. Nginx Configuration:
-
proxy_pass was set to http://grist-app:80;.
-
All X-Forwarded-* headers (including X-Forwarded-Proto) were correctly set.
3. The Resulting Error:
Despite this “perfect” configuration, the result was the same:
-
A 502 Bad Gateway error in the browser.
-
Nginx Error Logs: connect() failed (111: Connection refused) while connecting to upstream, client: …, server: grist.example.com, request: …, upstream: “http://grist-app:80/”.
Final Conclusion:
Even in a pristine, textbook Docker network environment, and even when explicitly telling Grist’s Traefik to trust the Nginx proxy’s internal IP address, Grist still fails to initialize or accept the connection correctly. It seems the HTTPS=external logic is fundamentally broken or has an unhandled edge case, causing it to refuse connections from the proxy instead of honoring the forwarded headers.
At this point, I have exhausted all logical configuration paths. I will be reverting to my pre-HTTPS snapshot to have a functional system. I believe this issue requires investigation from the Grist development team.