SOLVED - How to use reverse proxy in docker

I’ve spent hours trying to get this to work so I’d really appreciate your help. All the examples I can find are from people using a single host that has both ttrss and nginx installed so their proxy can point to 127.0.0.1, but my situation has ttrss in one docker container and nginx in another docker container. This setup works fine for other apps, like portainer, but tt-rss seems to be made differently and I can’t figure it out. Both containers are attached to the same Docker Network. The error I get on the proxy logs says “111 connection refused” so it seems like tt-rss is refusing the connection from nginx. I am able to connect directly to tt-rss using the docker host’s IP like this “http : / / 192.168.4.112:8280/tt-rss/” though it gives a red warning since the URL uses the IP instead of the intended hostname. Please help!

I tried to list the 5 different forum pages and readme files I’ve already read, but this forum blocks me from posting links. Trust me that I’ve searched hard for the answer. That’s also why I had to insert spaces in all the other links in this post.

Docker-Compose

version: ‘3’

services:
db:
image: postgres:12-alpine
container_name: ttrss-db
hostname: ttrss-db
restart: on-failure
volumes:
- db:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_USER=${POSTGRES_USER}
networks:
- nginx_default

app:
image: cthulhoo/ttrss-fpm-pgsql-static
container_name: ttrss-app
hostname: ttrss-app
restart: on-failure
environment:
- DB_TYPE=pgsql
- DB_HOST=db
- DB_NAME=${POSTGRES_USER}
- DB_USER=${POSTGRES_USER}
- DB_PASS=${POSTGRES_PASSWORD}
- OWNER_UID=${OWNER_UID}
- OWNER_GID=${OWNER_GID}
- SELF_URL_PATH=${SELF_URL_PATH}
volumes:
- html:/var/www/html
depends_on:
- db
networks:
- nginx_default

updater:
image: cthulhoo/ttrss-fpm-pgsql-static
container_name: ttrss-updater
hostname: ttrss-updater
restart: on-failure
environment:
- DB_TYPE=pgsql
- DB_HOST=db
- DB_NAME=${POSTGRES_USER}
- DB_USER=${POSTGRES_USER}
- DB_PASS=${POSTGRES_PASSWORD}
- OWNER_UID=${OWNER_UID}
- OWNER_GID=${OWNER_GID}
- SELF_URL_PATH=${SELF_URL_PATH}
volumes:
- html:/var/www/html
depends_on:
- app
command: /updater.sh
networks:
- nginx_default

web:
image: cthulhoo/ttrss-web
container_name: ttrss-web
hostname: ttrss-web
restart: on-failure
ports:
- ${HTTP_PORT}:2015
volumes:
- html:/var/www/html:ro
depends_on:
- app
networks:
- nginx_default

volumes:
db:
html:
certs:

networks:
nginx_default:
external: true

.env

BUILD_TAG=latest

POSTGRES_USER=ttrss
POSTGRES_PASSWORD=mypasswordhere

OWNER_UID=1000
OWNER_GID=1000

HTTP_HOST=localhost

SELF_URL_PATH=htt p ://ttrss.mydomain . c o m /tt-rss/

HTTP_PORT=8280

TZ=America/New_York

nginx conf file

server {
listen 80;
server_name ttrss.mydomain . c o m;

allow all;
access_log /var/log/nginx/ttrss_access.log;
error_log /var/log/nginx/ttrss_error.log;

location / {
	proxy_pass hxxp:xxttrss-web:8280/;
}

}

  1. don’t pass root (/) to /tt-rss, pass /tt-rss instead
  2. don’t proxy to docker container ip, expose port on localhost instead
  3. make sure self url path is correct

ah your nginx proxy is also inside docker? then you might want to put them on one virtual network and use host names because ip might change on restart.

I’ve never ran this scenario so I can’t help any further I’m afraid. you probably don’t want to expose ttrss nginx on localhost as per default .env.

e: my personal opinion here is that having ssl terminating nginx on the outside is the best practice, because it makes everything so much easier -you expose outside stuff on localhost in a same way and don’t need to dig into per-container networks. I could be wrong though.

Thank you so much for your help. It still isn’t working though. Both docker containers are on the same docker network. I don’t have any SSL right now. It seems like the problem is ttrss is being super strict about the SELF_URL_PATH setting and maybe the HTTP_HOST and HTTP_PORT settings. Is that something you could fix in the code so that it just lets us access ttrss using any URL?

I’ve tried many combinations of localhost, ip addresses, docker container names, and public URLs.
Here’s the latest attempt (with spaces added to links so the forum would allow me to post)

I’m trying to access ttrss with this URL in my browser:

h t t p : / / ttrss . mydomain .c o m /

nginx proxy setting:

location / {
proxy_pass h t t p : / / 192.168.4.112 : 8280 / tt-rss/;
}

.env file

BUILD_TAG=latest
POSTGRES_USER=ttrss
POSTGRES_PASSWORD=mypassword
OWNER_UID=1000
OWNER_GID=1000
HTTP_HOST=localhost
SELF_URL_PATH=h t t p : / / 192.168.4.112 : 8280 / tt-rss/
HTTP_PORT=8280

Error in nginx log:

2020/06/08 09:35:21 [error] 405#405: *153 upstream timed out (110: Connection timed out) while connecting to upstream, client: 192.168.4.1, server: ttrss . mydomain . com, request: “GET / HTTP/1.1”, upstream: “h t t p : / / 192.168.4.112 : 8280 / tt-rss/”, host: “ttrss . mydomain .com”"

i think i see what you did there. SELF_URL_PATH should be set to your outside url not 192.168.whatever. also, yes you need to pass Host through the proxy. there should be an example nginx config right in the readme. SELF_URL_PATH is also explained in the readme.

i must note that maybe reading the readme instead of trying to ad-hoc your way in might have been a good idea.

Trust me, I respect your time and I read the readme, wiki, FAQ, other forum posts, and several other websites. I’ve also previously tried passing $host through the proxy and setting the SELF_URL_PATH to public names and various internal names.

Here’s the latest:

attempted URLs in browser:

h t t p : / / ttrss . mydomain . c o m / tt-rss/
h t t p : / / ttrss . mydomain . c o m /

nginx proxy setting:

location /tt-rss/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass h t t p : / / ttrss-web : 8280 / tt-rss/; # the name of the docker container
}

.env

BUILD_TAG=latest
POSTGRES_USER=ttrss
POSTGRES_PASSWORD=mypassword
OWNER_UID=1000
OWNER_GID=1000
HTTP_HOST=localhost
SELF_URL_PATH=h t t p : / / ttrss . mydomain . c o m /
HTTP_PORT=8280
TZ=America/New_York

nginx error:

2020/06/08 10:07:46 [error] 414#414: *166 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.4.1, server: ttrss . mydomain . c o m, request: “GET /tt-rss/ HTTP/1.1”, upstream: “h t t p : / / 192.168.192.7 : 8280 / tt-rss /”, host: “ttrss . mydomain . c o m”

Looks like the nginx error says it’s reaching the correct IP (the ttrss-web container IP) and sending in the correct hostname (ttrss . mydomain . c o m) which matches the SELF_URL_PATH, but ttrss is refusing the request for some reason.

Progress!

I changed the nginx proxy to use the ttrss container’s internal port instead of the port that docker exposes to the host, and now I can access the ttrss site using the correct public URL.

proxy_pass h t t p : / / ttrss-web : 2015 / tt-rss/; (instead of port 8280)

Then, ttrss gave the red warning page telling me:

Please set SELF_URL_PATH to the correct value detected for your server: h t t p : / / ttrss . mydomain . com / tt-rss/

So I did that, and finally, I can access ttrss successfully using the public URL.

Problem solved! I hope this thread helps others who are trying to do the same thing. Thank you for your help. You give great, fast support for free, which is greatly appreciated.

I had a similar idea but you solved it first :slight_smile: