How to configure Umbrel LNbits app without Tor

Thanks for the info. After a lot of searching I found this thread which helped me set up proxy https in apache web server.
I quote the apache config in case it is usefull to other members of the community:

    <VirtualHost *:443>

    ServerName lightning.domain.com

    SSLProxyEngine on
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off

    ProxyRequests On
    ProxyPreserveHost On

    <Location / >

    ProxyPass http://10.13.37.5:3007/
    ProxyPassReverse http://10.13.37.5:3007/

    </Location>

    SSLCertificateFile /etc/letsencrypt/live/lightning.domain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/lightning.domain.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

    </VirtualHost>

With the new update out for LNBits I was able to finally resolve this issue.

  1. First update to LNbits version: 0.10.6
  2. Use this guide to ensure your NGINX proxy is configured properly.

Something important to note, because Umbrel is already using port 80, you can’t set up a listener in NGINX to forward HTTP traffic to HTTPS. You can however skip using LetsEncrypt to issue your SSL certificates and instead install Origin Server certificates issued by Cloudflare.
On the SSL / TLS Overview page, ensure your SSL/TLS encryption mode is Full (strict).
Under the Edge Certificate tab, enable Always Use HTTPS. This will take care of managing your SSL certificates, proxy your node’s IP address, and redirect HTTP traffic.

At this stage you should be able to access LNBits over clearnet and on your local network. When using LNaddress or LNURLs you should be getting:

Error: 2 validation errors for LnurlPayResponse callback URL host invalid, top level domain required (type=value_error.url.host) callback URL scheme not permitted (type=value_error.url.scheme; allowed_schemes={‘https’})

Edit the docker compose file for the app:

~/umbrel/app-data/lnbits/docker-compose.yml

First, you need to turn off Admin UI to force LNBits to use the environment variables set in the docker compose file, when Admin UI is enabled, it stores and uses the settings configured in the database.
Restart the app with the following command:

~/umbrel/scripts/app restart lnbits

Under #Global add the following:
HOST: "mydomain.com"
(don’t add https:// or www., etc.)

Under #App add the following:
FORWARDED_ALLOW_IPS: "*"

Finally, restart the app once again. Once it finishes restarting you should be able to use LNURLs and LN addresses. If you are still having issues, try debugging by reading the logs of the docker container.

Use this command to list all the docker containers, look for one called lnbits_web_1, copy the container ID.

docker ps

Then use this command to follow the logs. This can be useful to tell which IP is being interpreted by pydantic- which is what is throwing this error.
You know its working when you see the IP address of the container in the Umbrel app network when accessing LNbits from your local network. It should show your nodes public IP address when receiving traffic from using the LNURL or LNaddress.

1 Like

Thank you for this guide. I was able to follow it easily but run into two issues that needed more research.

The nginx config noted here is slightly out of date now. If anyone is following it and getting the “unsupported upgrade request” from nginx, then update the config file by commenting out:
#proxy_set_header Connection ‘Upgrade’; as it’s no longer required post v0.10

If you’re getting error when starting nginx then make sure the brackets and semicolons are set properly as they way it’s written here causes the start procedure to fail.

1 Like

For anyone reading this and a little overwhelmed with all the command line stuff. If you are already running a synology NAS, you can use the built in reverse proxy and create a certificate. very easily using this guide:

I used noip.com to create a DDNS entry (make sure to enable wildcards - so that you can do something like https://lnbits.yourdomain.noip.com and https://webserver.yourdomain.noip.com both will be sent to your firewall - make sure to forward 443 to NAS then your reverse proxy on NAS will redirect each subdomain to correct location on LAN

Hi everyone,

It is probably a stupid question but why do I need to configure a reverse proxy? Can I just configure a port forwarding to redirect the traffic to my LNbits instance?

Instead of

[Internet] - [Home Router/Firewall] - [Front-End Gateway] - [Umbrel]

I will have

[Internet] - [Home Router/Firewall] - [Umbrel]

What do you think about that?

Edit : OK I found that it is better for privacy and DDOS attack protection to use a reverse proxy so that the umbrel node is never requested directly

Thanks for posting this! I’m trying to follow it myself (Umbrel 1.2.2 and LNBits 0.12.11). My goal is to enable LNURLP over clearnet. My current setup:

  • Cloudflare tunnel app installed
  • SSL/TLS encryption mode for my domain configured to “full (strict)”
  • “Always use HTTPS” setting enabled under Edge Certificates
  • Cloudflare tunnel set up to route lnbits.mydomain.com to http://umbrel.local:3007
  • Added HOST: 'lnbits.mydomain.com' to docker-compose
  • Added FORWARDED_ALLOW_IPS: '*' to docker-compose

With these settings (and actually without those above additions to docker-compose, too), I get the following message when I load the LNURLP extension UI:

LNURLs need to be delivered over a publicly accessible https domain or Tor onion.
426

I also get a 500 error when I attempt to create an LNURL.

Can anyone point me in the right direction?

EDIT

I got it working.
A deep googling rabbit hole brought me to this github issue.

In particular, this comment links to this docker-compose file with recommended updates to get LNURL functions to work over clearnet via reverse proxy (or Cloudflare tunnel in my case; again note my domain SSL/TLS setting above in my post).

Specifically, the two docker-compose file additions that got it working for me given the above setup were:

  1. Adding PROXY_TRUST_UPSTREAM: "true" in the app_proxy service
  2. Adding command: uvicorn lnbits.__main__:app --port "3007" --host "0.0.0.0" --forwarded-allow-ips="*" in the web service

Note in #2 above I replaced $APP_LNBITS_PORT from that linked example docker-compose file with "3007" because in the version of the LNBits docker-compose file for Umbrel 1.2.2 / LNBits 0.12.11, ports and IPs are hard-coded rather than being defined as variables. YMMV.

Now to get zapping!

I am unable to get it working. May you share your docker-composer.yml please?

Trying this in 2025: it looked so hopeful! ..but it didn’t work. the env variable doesn’t make a difference on its own (see also LNURLs need to be delivered over a publicly accessible `https` domain or Tor onion. 426 · Issue #3151 · lnbits/lnbits · GitHub , issue with LNURLw · Issue #612 · lnbits/lnbits · GitHub , etc) and when I add the suggested command to the web service and restart the app, it simply becomes inaccessible with logs like this:

lnbits_app_proxy_1  | Error waiting for port: "The address 'lnbits_web_1' cannot be found"
lnbits_app_proxy_1  | Retrying...
lnbits_app_proxy_1  | Error waiting for port: "The address 'lnbits_web_1' cannot be found"
lnbits_app_proxy_1  | Retrying...
lnbits_web_1        |   File "/app/lnbits/app.py", line 458, in check_and_register_extensions
lnbits_web_1        |     await check_installed_extensions(app)
lnbits_web_1        |   File "/app/lnbits/app.py", line 260, in check_installed_extensions
lnbits_web_1        |     installed_extensions = await build_all_installed_extensions_list(False)
lnbits_web_1        |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lnbits_web_1        |   File "/app/lnbits/app.py", line 293, in build_all_installed_extensions_list
lnbits_web_1        |     for ext_dir in Path(settings.lnbits_extensions_path, "extensions").iterdir():
lnbits_web_1        |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lnbits_web_1        |   File "/usr/local/lib/python3.12/pathlib.py", line 1056, in iterdir
lnbits_web_1        |     for name in os.listdir(self):
lnbits_web_1        |                 ^^^^^^^^^^^^^^^^
lnbits_web_1        | FileNotFoundError: [Errno 2] No such file or directory: 'lnbits/extensions'
lnbits_web_1        | 
lnbits_web_1        | 2025-05-14 20:03:19.88 | ERROR | Application startup failed. Exiting.

Extremely frustrating!

Interesting… if I make those changes to the docker-compose file (stopping and re-starting the app in between via the UI), I can no longer launch LNBits at all even after undoing the ‘command’ changes:

lnbits_app_proxy_1  | yarn run v1.22.19
lnbits_app_proxy_1  | $ node ./bin/www
lnbits_app_proxy_1  | [HPM] Proxy created: /  -> http://lnbits_web_1:3007
lnbits_app_proxy_1  | Waiting for lnbits_web_1:3007 to open...

If I restart the Umbrel, LNBits works again (but of course the LNURLp extension still has the same problem)

Got it working eventually! Summary here: LNURLs need to be delivered over a publicly accessible `https` domain or Tor onion. 426 · Issue #3151 · lnbits/lnbits · GitHub

Copy of the above comment here for the lazy:

I’m going to write it up more fully, but I think the following (all from this thread: How to configure Umbrel LNbits app without Tor - #44 by madara) were instrumental:

  • Important: turn off the “Admin UI” feature in LNBits. When this is on, the environment variables are ignored. I think this was causing a lot of my problems in the multiple times I re-installed and reconfigured with different approaches
  • in the umbrel app’s docker-compose.yml:
    • under app_proxy environment: PROXY_TRUST_UPSTREAM: 'true'
    • under environment:
      • HOST: '<my domain here>'
      • FORWARDED_ALLOW_IPS: '*'

I’m not sure if all three of those env variables are needed, but with them all present it works. Make sure to restart the umbrel app after setting these!

Here is my entire working nginx config. This lives on a server within my LAN, proxying to my Umbrel:

server {
    server_name <my domain>;
    listen 443 ssl;
      
    ssl_certificate <my certbot cert>;
    ssl_certificate_key <key>;
      
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    location / {
        proxy_pass http://<my umbrel local IP>:3007;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Ssl on;
        proxy_set_header X-Forwarded-Host $host;
        proxy_pass_request_headers on;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header Host $host;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
    }
}