Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to have Lemmy and Lemmy UI on separate subdomains? #876

Closed
Cardinal8501 opened this issue Dec 11, 2022 · 7 comments
Closed

Comments

@Cardinal8501
Copy link

I was originally writing this issue out because I thought I had misconfigured something or encountered some bug, but re-reading it, thinking about it and looking at the Nginx config I'm not so sure. If this actually just isn't allowed everything written below doesn't matter. If it is intended to work then please read on.


I've been trying to set up a Lemmy instance on my domain. Lemmy itself seems to be working (I can use it through the Jerboa app). Lemmy UI hangs indefinitely when I try to log in. I can see errors in the console like this:

Firefox can’t establish a connection to the server at wss://lemmyui.thetamail.com/api/v3/ws. client.js:2:587370
Websocket closed. client.js:2:936775
Retrying websocket connection...

However, my Lemmy instance is actually hosted at activitypub.thetamail.com. From what I can tell lemmy-ui has no /api/v3/ws route but lemmy itself does so I think the requests should be going to, e.g., wss://activitypub.thetamail.com/api/v3/ws.

I can see that my lemmy-ui docker logs reference the websocket URI I'm expecting:

Attaching to activitypub_lemmy-ui_1
lemmy-ui_1 | Inferno is in development mode.
lemmy-ui_1 | httpbase: https://lemmy:8536
lemmy-ui_1 | wsUri: wss://activitypub.thetamail.com/api/v3/ws
lemmy-ui_1 | isHttps: true
lemmy-ui_1 | No JWT cookie found.
lemmy-ui_1 | http://0.0.0.0:1234

but the logs in the console do not:

httpbase: https://lemmyui.thetamail.com client.js:formatted:38958
wsUri: wss://lemmyui.thetamail.com/api/v3/ws client.js:formatted:38958
isHttps: true client.js:formatted:38961
No JWT cookie found.

Here's what the lemmy-ui section for my docker-compose.yml looks like. It's pretty similar to the sample one:

  lemmy-ui:
    image: dessalines/lemmy-ui:0.16.7
    networks:
      - proxynet
    environment:
      # this needs to match the hostname defined in the lemmy service
      - LEMMY_INTERNAL_HOST=lemmy:8536
      # set the outside hostname here
      - LEMMY_EXTERNAL_HOST=activitypub.thetamail.com
      - LEMMY_HTTPS=true
    depends_on:
      - lemmy
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxynet"
      - "traefik.http.routers.lemmyui.rule=Host(`lemmyui.thetamail.com`)"
      - "traefik.http.routers.lemmyui.entrypoints=websecure"
      - "traefik.http.routers.lemmyui.service=lemmyui"
      - "traefik.http.services.lemmyui.loadbalancer.server.port=1234"

I tried explicitly setting the LEMMY_UI_LEMMY_WS_HOST environment variable as well, made no difference.

I can see if I get a shell in the container that the correct environment variable is set. What's more the lemmy-ui pages even include a reference to activitypub.thetamail.com in their metatags:

<meta data-inferno-helmet="true" property="og:url" content="https://activitypub.thetamail.com/login">
<meta data-inferno-helmet="true" property="twitter:url" content="https://activitypub.thetamail.com/login">

but it's not using the right domain in the websocket URI.

@dessalines
Copy link
Member

docker-compose: https://github.com/LemmyNet/lemmy-ansible/blob/main/templates/docker-compose.yml

nginx: https://github.com/LemmyNet/lemmy-ansible/blob/main/templates/nginx.conf

It could be a port issue, I'm not sure. I don't use traefik so I can't help you there. We only support nginx.

@Cardinal8501
Copy link
Author

I don't think the issue was directly related to the nginx/traefik configuration. Both services were running and serving content. Lemmy UI was just trying to make websocket requests to itself rather than to Lemmy. So it was trying to connect to wss://lemmyui.thetamail.com/api/v3/ws instead of wss://activitypub.thetamail.com/api/v3/ws. With the sample nginx config this isn't a problem because it just splits requests between services based on path/request type.

I ended up just setting things up such that they both ran on the same domain similar to the sample nginx config. My updated docker-compose.yml with routing rules similar to the nginx config, in case anyone else comes across this:

version: '3.5'

services:
  lemmy:
    image: dessalines/lemmy:0.16.7
    hostname: lemmy
    networks:
      - postgres
      - proxynet
    restart: always
    environment:
      - RUST_LOG="warn,lemmy_server=info,lemmy_api=info,lemmy_api_common=info,lemmy_api_crud=info,lemmy_apub=info,lemmy_db_schema=info,lemmy_db_views=info,lemmy_db_views_actor=info,lemmy_db_views_moderator=info,lemmy_routes=info,lemmy_utils=info,lemmy_websocket=info"
    volumes:
      - ./lemmy.hjson:/config/config.hjson
    depends_on:
      - pictrs
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxynet"
      - "traefik.http.routers.activitypub.rule=Host(`activitypub.thetamail.com`) && (
                                                   (
                                                       Headers(`Accept`, `^application/.*$$`)
                                                   ) ||
                                                   (
                                                       Method(`POST`)
                                                   ) ||
                                                   (
                                                       PathPrefix(`/api`) ||
                                                       PathPrefix(`/pictrs`) ||
                                                       PathPrefix(`/feeds`) ||
                                                       PathPrefix(`/nodeinfo`) ||
                                                       PathPrefix(`/.well-known`)
                                                   )
                                               )"
      - "traefik.http.routers.activitypub.entrypoints=websecure"
      - "traefik.http.routers.activitypub.service=activitypub"
      - "traefik.http.services.activitypub.loadbalancer.server.port=8536"

  lemmy-ui:
    image: dessalines/lemmy-ui:0.16.7
    networks:
      - proxynet
    environment:
      # this needs to match the hostname defined in the lemmy service
      - LEMMY_INTERNAL_HOST=lemmy:8536
      # set the outside hostname here
      - LEMMY_EXTERNAL_HOST=activitypub.thetamail.com
      - LEMMY_HTTPS=true
    depends_on:
      - lemmy
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxynet"
      - "traefik.http.routers.lemmyui.rule=Host(`activitypub.thetamail.com`) && !(
                                                   (
                                                       Headers(`Accept`, `^application/.*$$`)
                                                   ) ||
                                                   (
                                                       Method(`POST`)
                                                   ) ||
                                                   (
                                                       PathPrefix(`/api`) ||
                                                       PathPrefix(`/pictrs`) ||
                                                       PathPrefix(`/feeds`) ||
                                                       PathPrefix(`/nodeinfo`) ||
                                                       PathPrefix(`/.well-known`)
                                                   )
                                               )"
      - "traefik.http.routers.lemmyui.entrypoints=websecure"
      - "traefik.http.routers.lemmyui.service=lemmyui"
      - "traefik.http.services.lemmyui.loadbalancer.server.port=1234"

  pictrs:
    image: asonix/pictrs:0.3.1
    # this needs to match the pictrs url in lemmy.hjson
    hostname: pictrs
    # we can set options to pictrs like this, here we set max. image size and forced format for conversion
    # entrypoint: /sbin/tini -- /usr/local/bin/pict-rs -p /mnt -m 4 --image-format webp
    networks:
      - proxynet
    environment:
      - PICTRS__API_KEY=API_KEY
    user: 991:991
    volumes:
      - ./volumes/pictrs:/mnt
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxynet"
      - "traefik.http.routers.pictrs.rule=Host(`pictrs.thetamail.com`)"
      - "traefik.http.routers.pictrs.entrypoints=websecure"
      - "traefik.http.routers.pictrs.service=pictrs"
      - "traefik.http.services.pictrs.loadbalancer.server.port=8080"

networks:
  proxynet:
    external:
      name: common_network
  postgres:
    external:
      name: postgres

Note that I'm still in the early stages of setup so this may not be fully functional. I know that I can browse around my instance, create posts, and federate with lemmy.ml well enough to at least subscribe to communities though.

@Nutomic Nutomic closed this as completed May 11, 2023
@jimmybrancaccio
Copy link

I just wanted to throw you a quick super big thanks @Cardinal8501. I can confirm this still works today with Traefik and Lemmy 0.17.2. 💙

@tgxn
Copy link
Contributor

tgxn commented Jun 11, 2023

You must now use HeadersRegexp instead of Headers for the Traefik rule.

@jimmybrancaccio
Copy link

@tgxn is correct, for my lemmy container I have:

- traefik.http.routers.lemmy.rule=Host(`lemmy.domain`) && ((HeadersRegexp(`Accept`, `^application/.*$$`)) || (Method(`POST`)) || (PathPrefix(`/api`) || PathPrefix(`/pictrs`) || PathPrefix(`/feeds`) || PathPrefix(`/nodeinfo`) || PathPrefix(`/.well-known`)))

and for my lemmy-ui container I have:

- traefik.http.routers.lemmy-ui.rule=Host(`lemmy.domain`) && !((HeadersRegexp(`Accept`, `^application/.*$$`)) || (Method(`POST`)) || (PathPrefix(`/api`) || PathPrefix(`/pictrs`) || PathPrefix(`/feeds`) || PathPrefix(`/nodeinfo`) || PathPrefix(`/.well-known`)))

@theRealBithive
Copy link

theRealBithive commented Jun 18, 2023

Hi! I came here looking for a working solution. It would be nice if we could back it in a seperate docker-compose.override.yml to leave original config intact.
Bonus would be if we also update the https://github.com/LemmyNet/lemmy-docs.

While writing this I wish I could do this stuff myself - but I have very little time at hands (children).

This is what GPT returned to me; I had no chance to verify until now

version: "3.3"

services:
  lemmy:
    networks:
      - proxynet
      - lemmyinternal
labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxynet"
      - "traefik.http.routers.activitypub.rule=Host(`<your-domain-name>`) && ((HeadersRegexp(`Accept`, `^application/.*$$`)) || (Method(`POST`)) || (PathPrefix(`/api`) || PathPrefix(`/pictrs`) || PathPrefix(`/feeds`) || PathPrefix(`/nodeinfo`) || PathPrefix(`/.well-known`)))"
      - "traefik.http.routers.activitypub.entrypoints=websecure"
      - "traefik.http.routers.activitypub.service=activitypub"
      - "traefik.http.services.activitypub.loadbalancer.server.port=8536"
      - "traefik.http.middlewares.activitypub-https-redirect.redirectscheme.scheme=https"


  lemmy-ui:
    networks:
      - proxynet
    environment:
      - LEMMY_INTERNAL_HOST=lemmy:8536
      - LEMMY_EXTERNAL_HOST=<your-domain-name>
      - LEMMY_HTTPS=true
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxynet"
      - "traefik.http.routers.lemmyui.rule=Host(`<your-domain-name>`) && !((HeadersRegexp(`Accept`, `^application/.*$$`)) || (Method(`POST`)) || (PathPrefix(`/api`) || PathPrefix(`/pictrs`) || PathPrefix(`/feeds`) || PathPrefix(`/nodeinfo`) || PathPrefix(`/.well-known`)))"
      - "traefik.http.routers.lemmyui.entrypoints=websecure"
      - "traefik.http.routers.lemmyui.service=lemmyui"
      - "traefik.http.services.lemmyui.loadbalancer.server.port=1234"
      - "traefik.http.middlewares.lemmyui-https-redirect.redirectscheme.scheme=https"

networks:
  proxynet:
    external:
      name: <your-proxy-network>
  lemmyinternal:

@Fmstrat
Copy link

Fmstrat commented Jun 24, 2023

This should be included in the default docker nginx.conf as well. It doesn't work out of the box without:

                location / {
                        resolver 127.0.0.11 ipv6=off;
                        set $proxpass "http://lemmy-ui:1234";  
                        if ($http_accept ~ "^application/.*$") {
                                set $proxpass "http://lemmy:8536";
                        }
                        if ($uri ~ "^(.*)/(api|pictrs|feeds|nodeinfo|.well-known)(.*)") {
                                set $proxpass "http://lemmy:8536";
                        }
                        if ($request_method = POST) {
                                set $proxpass "http://lemmy:8536";
                        }
                        proxy_pass $proxpass;
                }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants