Tt-rss is selecting the wrong network for internal communication

Hi,

I'm setting up a server using traefik, learning stuff while I do it. While I could get most of the stuff working, tt-rss (tinytinyrss) escapes me. As soon as I add the external network to the docker-compose.yml of ttrss it stops working.

ttrss works fine when directly exposed - its just adding in traefik that won't.

I'm starting with the

 cat .env
TTRSS_DB_USER=postgres
TTRSS_DB_NAME=postgres
TTRSS_DB_PASS=***
TTRSS_SELF_URL_PATH=https://rss.mydomain.net/tt-rss
HTTP_PORT=127.0.0.1:8280

use
source .env

cat docker-compose.yml
version: '3'

services:
  db:
    image: postgres:12-alpine
    restart: unless-stopped
    environment:
      - POSTGRES_USER=${TTRSS_DB_USER}
      - POSTGRES_PASSWORD=${TTRSS_DB_PASS}
      - POSTGRES_DB=${TTRSS_DB_NAME}
    volumes:
      - db:/var/lib/postgresql/data

  app:
    build:
      context:
        ./app
    restart: unless-stopped
    env_file:
      - .env
    volumes:
      - app:/var/www/html
      - ./config.d:/opt/tt-rss/config.d:ro
    depends_on:
      - db

  backups:
    build:
      context:
        ./app
    restart: unless-stopped
    env_file:
      - .env
    volumes:
      - backups:/backups
      - app:/var/www/html
    depends_on:
      - db
    command: /opt/tt-rss/dcron.sh -f

  updater:
    build:
      context:
        ./app
    restart: unless-stopped
    env_file:
      - .env
    volumes:
      - app:/var/www/html
      - ./config.d:/opt/tt-rss/config.d:ro
    depends_on:
      - app
    command: /opt/tt-rss/updater.sh

  web-nginx:
    build: ./web-nginx
    restart: unless-stopped
    ports:
      - ${HTTP_PORT}:80
    volumes:
      - app:/var/www/html:ro
    depends_on:
      - app
    networks:
      - proxy
      - default
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.ttrss.entrypoints=http"
      - "traefik.http.routers.ttrss.rule=Host(`rss.mydomain.net`)"
      - "traefik.http.services.ttrss.loadbalancer.server.port=80"
      - "traefik.http.middlewares.ttrss-secured.redirectscheme.scheme=https"
      - "traefik.http.routers.ttrss-secured.rule=Host(`rss.mydomain.net`)"
      - "traefik.http.routers.ttrss-secured.entrypoints=https"
      - "traefik.http.routers.ttrss-secured.tls.certresolver=http"

volumes:
  db:
  app:
  certs:
  backups:

networks:
  proxy:
    external: true

and use docker-compose -up

The error I get is:

web-nginx_1  | 2022/05/18 12:23:31 [error] 32#32: *1064 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: , request: "GET /tt-rss/index.php HTTP/1.1", upstream: "fastcgi://172.20.0.5:9000", host: "localhost"
web-nginx_1  | 127.0.0.1 - - [18/May/2022:12:23:31 +0000] "GET /tt-rss/index.php HTTP/1.1" 502 157 "-" "curl/7.80.0"

172.20.0. is the "proxy" network, the external one. As soon as I comment that network out, the error disappears. Also traefik shows rss.mydomain.net in the dashboard. I can't reach the site from the outside anymore (obviously!)

Maybe you'll need a look at my traeffik setup:

cat docker-compose.yml
version: '3'
services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
      - ./data/dynamic_conf.yml:/dynamic_conf.yml
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`monitor.mydomain.net`)"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=***:***"
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`monitor.mydomain.net`)"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=http"
      - "traefik.http.routers.traefik-secure.service=api@internal"
      - "providers.file.filename=/dynamic_conf.yml"
      - "traefik.http.routers.traefik-secure.middlewares=secHeaders@file,traefik-auth"
networks:
  proxy:
    external: true

Thanks for reading this (long!) post - I appreciate all help!

I tried to use the priority setting, but that wasn't accepted by docker-compose.

networks:
proxy:
priority: 100

This dude seems to have had the very same problem, but while he outlines his solution, I can't replicate it.

I mad some progress!!!

\o/

I'm not entirely sure what did it in the end, but I added the proxy network (the external one) to the app container as well. This way app offered its 9000 port on the external network.

That is probably not a good idea, but at least I can use ttrss while I look for a better way to do this.

I have also run into the same issue. However, I am actually currently using NGINX as a reverse proxy in front of tt-rss. The behaviour is exactly the same.

I just registered to this forum in case any poor soul runs into this issue in the future.

There seems to be issue where the tt-rss nginx uses the wrong network, when connecting its container to an external network as well as the default network.
I have not found out if it behaves differently when the order of creation of these networks changes, or if it depends on the IP ranges of the networks or something.

Your workaround is working of course, but I didn't want to expose the app to the external network (though usually this should do no harm).

What I did is to add another non-external, but explicitly defined network called "att_rss_net" at the bottom of the compose file. This network replaces the default network. But what is important, is that it has a name and seemingly it has to come lexicographically before the other external network:

i.e.:

  db:
    networks:
      - att_rss_net

  app:
    networks:
      - att_rss_net

  web-nginx:
    ...
    networks:
      - att_rss_net
      - proxy

networks:
  att_rss_net:
    name: att_rss_net
  proxy:
    external: true
    name: proxy

Just a quickly note:

  1. When multiple networks are involved, make sure to set .docker.network globally in static config or per router in labels

  2. Note that docker compose will prefix a network when it’s not external and does not have a name:. So make sure the name is correct that you use

  3. Errors with 127.0.0.1 are usually related to a container trying to connect to localhost, where another process should be listening. But 127.0.0.1 is a separate localhost inside a container than on the node. Containers are for isolation