Install Discourse on a residential internet with Cloudflare Tunnel

yo @Falco, is the real_ip (provided by cf as CF-Connecting-IP header) coming through for you in nginx logs? it’s not for me. i just see cloudflared’s ip.

i think one or both of these things need to be done (will follow up after investigation):

  • add a set_real_ip_from config line to nginx for cloudflared’s ip. if that turns out to be the problem, then i would guess none of the other set_real_ip_from lines (provided by templates/cloudflare.template.yml) are needed for argotunnel users. and in this case, maybe a separate argotunnel template should be added to the docker repo that pulls your cloudflared ip from an env var or something in your main app.yml.
  • fix the log_format. i think this is probably not the issue, though. confirmed unneeded

edit:

here’s what i’m doing to make it work:

don’t use the cloudflare template. there’s no point.
instead, merge this into your app.yml:

hooks:
  after_web_config:
    - file:
        path: /etc/nginx/conf.d/cloudflare_tunnel_real_ip.conf
        contents: |
          # restore original visitor IPs (ngx_http_realip_module)
          set_real_ip_from 10.100.20.200/32; # your cloudflared/argotunnel IP range
          real_ip_header CF-Connecting-IP;

that automatically ends up in the nginx http context btw which is appropriate.

PS: imo, for cleanliness, the cloudflare template should also generate its nginx config into a separate file instead of using sed -i to add it to /etc/nginx/conf.d/discourse.conf.

1 Like

yes @shyguy i follow the step mr @Falco
yes i on tunnel, before i get some ddos protection from cloudflare, ddos give my server get high on cpu, on access log 20mb and i see just my docker ip, i challange the visitor on url path / to protect server but expired cache give discoure error



i got same like falco website if got ddos, and get higher on cpu

2 Likes

@shyguy where can i get this ip range, sorry for asking

how about this…? i must use this command inside or outside container?

1 Like

in case it wasn’t clear, my post there was just about fixing nginx logging.

if you don’t fix it, all of the requests in your nginx logs will look like they’re coming from one ip (your cloudflared) instead of having the actual client IPs.

that ip (or ip range) is what your cloudflared is connecting to discourse from, so it depends on your setup. one way to be sure is to look in the nginx log file and grab the ip from there. and then add a /32 afterwards.

if you’re following his guide exactly, i would guess that it’s 127.0.0.1/32

nah, that was just a suggestion for the cloudflare.template.yml template – which you shouldn’t be using in this setup.

just follow his guide in the first post but ignore the step of adding that template to your config. instead of that, add the hook i provided.

1 Like

i have follow your setup. but didnt work

[27/May/2023:15:49:45 +0000] "sub.domain.ltd" 172.17.0.1 "POST /
[27/May/2023:15:49:45 +0000] "sub.domain.ltd" 172.17.0.1 "POST /
[27/May/2023:15:49:46 +0000] "sub.domain.ltd" 172.17.0.1 "GET /chat
[27/May/2023:15:49:46 +0000] "sub.domain.ltd" 172.17.0.1 "POST /message-bus
[27/May/2023:15:49:54 +0000] "sub.domain.ltd" 172.17.0.1 "POST /message-bus/

hooks:
  after_web_config:
    - file:
        path: /etc/nginx/conf.d/cloudflare_tunnel_real_ip.conf
        contents: |
          # restore original visitor IPs (ngx_http_realip_module)
          set_real_ip_from 172.17.0.1/32; # your cloudflared/argotunnel IP range
          real_ip_header CF-Connecting-IP;

where i got wrong? please help @shyguy

bummer. that looks correct to me, so i’m not sure what’s wrong.

here is how this is supposed to work:

  • cloudflare proxy adds a CF-Connecting-IP header containing the client’s IP
  • nginx in discourse has been compiled with ngx_http_realip_module – software that reads this header and fixes logs etc to show actual client IP
  • set_real_ip_from enables this feature for connections from IP ranges passed to it. this would normally be cloudflare’s IP ranges (supplied by the cloudflare.template.yml convenience template), but since you’re using argotunnel, you would just use argotunnel’s IP instead.

try disabling my hook. do you see the same IP in your nginx logs before/after?


probably the only difference in our setups is that i’m running argotunnel (cloudflared) in docker.

if you want to try that…

i created a network just for cloudflared:

docker network create --subnet 10.200.10.0/24 cf_tunnel

here is the compose file:

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    command: tunnel run
    restart: unless-stopped
    networks:
      wan:
      cf_tunnel:
        # for ngx_http_realip_module
        # set to a high IP so that hopefully docker doesn't DHCP assign
        #   another container that IP if it starts before cloudflared
        ipv4_address: 10.200.10.200 # this is the ip for `set_real_ip_from` in nginx

    volumes:
      # should be owned by uid:gid 65532:65532
      - ./conf:/home/nonroot/.cloudflared

networks:
  cf_tunnel:
    external: true # just means a network not managed by compose

# for performance:
# https://github.com/quic-go/quic-go/wiki/UDP-Receive-Buffer-Size
# sudo nano /etc/sysctl.conf
  # add this line:
  # net.core.rmem_max=2500000
  # (my old value was 212992 – check it with: sudo sysctl net.core.rmem_max)

you can transfer your config/cert to it in that conf dir (remember to chown like the note in the compose file says) or just go through the setup procedure again. you can run cloudflared commands to log in or whatever like this:

docker run -it --rm -v /path/to/conf:/home/nonroot/.cloudflared cloudflare/cloudflared:latest YOUR_CMD_HERE

and then you have to join your discourse container to the network. you can do that with this at the bottom of your container yml:

docker_args:
  - '--network=cf_tunnel' # optionally, you could set a static IP here too
1 Like

Does anyone have success getting the discourse incoming mail server container working over the cloudflare tunnel?

I’ve had trouble setting up another mail server behind the cloudflare tunnel in the past, but I can get apps running on my Pi that use ports 80 and 443 working fine.

I’ve set up Discourse on servers multiple times and I’m not too concerned about the main Discourse container for now.

I think this is related, but please create a new post from my reply if you feel that it’s off-topic.

Thank you.

I’m pretty sure that the cloudflare tunnel is only for web traffic and not any other ports.

This suggests that I’m right https://community.cloudflare.com/t/can-i-create-a-mail-server-with-cloudflare-tunnel/386089

2 Likes

I used the argo service. I gave up when I paid 28 euros for the first month. There was actually at least a 200ms difference. However, I canceled it because I could not afford to pay 28 euros every month for 200 ms. Larger sites will have more invoices, keep in mind.

The site’s hit is 800-1000 unique users. You can calculate accordingly.

1 Like

Also ever since I started using tunnel, uploading media has been a hassle or next to impossible
Uploads normally then I get this error

when running apt-get update I got this error

You need to run a 64 bit OS :sweat_smile:

That’s the thing lol it is 64bit. But I figured it out. I did apt get upgrade and restarted cloudflare service and it uploaded. Also do you know if cloudflare limit the upload of videos with tunnel? I’m having issues uploading like a 20MB video and I didn’t before

I have set up the Cloudflare tunnel and it is also active:

However, the error that Discourse cannot reach the domain always appears during installation.
I have written DISCOURSE_FORCE_HTTPS: true in the App.yml.

However, I did not cancel the installation, but it was automatically canceled before I could change the App.yml. Could this be the error?