Does anybody do one to one help with setting up Zima OS?

Yes, that’s exactly the issue.

A 502 Bad Gateway from OpenResty means Nginx Proxy Manager can’t reach the backend service. This has nothing to do with DuckDNS or SSL anymore.

Port 86 is wrong unless your app is actually listening on 86 (almost none do).

Fix it:

  • In Nginx Proxy Manager, set the forward port to the app’s real internal port
    • Jellyfin > 8096
    • Jellyfin HTTPS (optional) > 8920
  • Scheme should be http
  • Host should be the container name or internal IP

Save, restart the proxy host, and refresh.

Once the port matches the app, the 502 disappears immediately.

One last question hopefully. The domain now works. Yay! Thank you. So when I put in my domain. :8096 for Jellyfin it takes me to zimaos login. I feel there is one more step. Thank you so much

Yes, this is expected, and you’re one step from done.

What’s happening is that port 8096 on the ZimaOS host is protected by ZimaOS itself, so when you hit
yourdomain:8096 you’re bypassing Nginx Proxy Manager and hitting the ZimaOS login instead.

Correct way to access Jellyfin externally:

  • Use only your domain:
    https://yourdomain.duckdns.org
  • Do not add :8096 in the browser

Nginx Proxy Manager listens on 443, then forwards traffic internally to Jellyfin on 8096. That’s the whole point of the proxy.

If you want to be extra clean:

  • Disable or unpublish Jellyfin’s external port
  • Let NPM be the only public entry point

Bottom line:
Domain only, no port.
If it loads Jellyfin without :8096, you’re fully done.

See that’s the deal. When I put in my domain, it drops me to Zima login page. Not Jellyfin.

That means Nginx Proxy Manager is still pointing at the ZimaOS host, not the Jellyfin container.

When NPM forwards to the host IP, ZimaOS catches it first and shows the Zima login.

Fix (this is the missing step):

  • In Nginx Proxy Manager > Proxy Host
    • Forward Hostname / IP > set this to:
      • the Jellyfin container name (preferred), or
      • the Jellyfin container’s internal Docker IP
    • Forward Port > 8096
    • Scheme > http
  • Enable Websockets Support
  • Save

Do not use:

  • localhost
  • the ZimaOS IP
  • 127.0.0.1

Once NPM forwards directly to the Jellyfin container instead of the host, the domain will open Jellyfin immediately.

Still no luck. I’m probably not putting in everything correctly in Nginx. Maybe an example. Also thinking of uninstalling Jellyfin in Zima and starting over. It’s probably got issues as well. I used to be better at this stuff. Old age is starting to set in. Put it this way, my high school had one computer on the Internet using Netscape navigator. Lol.

All good, you’re actually very close. Nothing is “broken” and you do not need to uninstall Jellyfin.

Think of this like mail delivery:

  • Your domain is the street address
  • Nginx Proxy Manager (NPM) is the mail sorter
  • Jellyfin is the room inside the house
    Right now, the mail is being delivered to the front desk (ZimaOS) instead of the room (Jellyfin).

We just need to tell NPM exactly where Jellyfin lives.

Step-by-step (slow and simple)

  1. Open Nginx Proxy Manager
  2. Go to Proxy Hosts
  3. Click Edit on your domain

Now fill it in exactly like this:

Details tab

  • Domain Names:
    yourdomain.duckdns.org
  • Scheme:
    http
  • Forward Hostname / IP:

type jellyfin
(this must be the container name, not the ZimaOS IP)

  • Forward Port:
    8096
  • Turn ON: Websockets Support
  • Everything else OFF

Click Save

Important checks (these matter)

  • Do NOT use:
  • localhost
  • 127.0.0.1
  • your ZimaOS IP (192.168.x.x)
  • The word jellyfin must match the container name exactly

You can confirm the name by running:

docker ps

Look under NAMES, whatever Jellyfin is called there is what goes in NPM.

How to test

  • Open a new browser tab
  • Go to:
    https://yourdomain.duckdns.org
  • Do NOT add :8096

If it’s correct, Jellyfin will load.
If you see Zima login, NPM is still pointing to the host instead of the container.

You’re not rusty, this stuff is genuinely confusing, and you’ve already done the hard parts. This is just the last wire to plug in.

Here is what I get when I do the docker ps

This is not a Jellyfin or Nginx problem.
You’re simply not allowed to talk to Docker yet.

Right now you are logged in as MrPenguin, and Docker only listens to root on ZimaOS.

That’s why you’re seeing permission denied.

What to do (very simple)

  1. In the terminal, type:
sudo su
  1. Enter your password
  2. Your prompt should change to:
root@ZimaOS

Now run:

docker ps

This time it will work and you’ll see the container list.

Why this matters

Until you run Docker as root, you:

  • can’t see container names
  • can’t point Nginx Proxy Manager to Jellyfin
  • will keep getting sent to the ZimaOS login page

Once docker ps works, we’ll take the exact Jellyfin name from that list and put it into Nginx Proxy Manager. That’s the final step.

Maybe this will help





Perfect, that screenshot does help, and it shows the exact problem.
I’ll explain this very simply.

What’s wrong (in plain words)

Jellyfin and Nginx Proxy Manager are not on the same Docker network.

Think of Docker networks like rooms:

  • Jellyfin is in one room
  • Nginx Proxy Manager is in another room
  • They can’t see each other, so NPM sends you to ZimaOS instead

That’s why:

  • Domain works
  • SSL works
  • But Jellyfin never loads

The fix (easy and safe)

We just put both containers in the same room.

Step 1: Pick the network

In Portainer, find the network that Nginx Proxy Manager is using
(common names: npm, proxy, or bridge)

Step 2: Add Jellyfin to that same network

In Portainer:

  1. Open Jellyfin
  2. Click Duplicate / Edit
  3. Scroll to Networks
  4. Add the same network NPM is using
  5. Keep bridge if it’s already there (that’s fine)
  6. Deploy

Step 3: Update NPM (one last time)

In Nginx Proxy Manager → Proxy Host:

  • Forward Hostname: jellyfin
  • Forward Port: 8096
  • Scheme: http
  • Websockets: ON

Save.

How you test

Open:

https://yourdomain.duckdns.org

No port.
No Zima login.
You should see Jellyfin.

Important reassurance

  • You do not need to reinstall Jellyfin
  • You did nothing wrong
  • This is the most common Docker + NPM mistake

So tired of me yet.

Was giving me an error when going to benshoff.duckdns.org
Here is the error:
ERR_SSL_KEY_USAGE_INCOMPATIBLE

Went back to NGIN
Tried to delete and redo the SSL Encrypt. Lets Encrypt:

Domain Names
benshoff.duckdns.com

Hit the test button and below it gave me this error info, which I never seen before.

CommandError: Saving debug log to /tmp/letsencrypt-log/letsencrypt.log
Some challenges have failed.

at /app/lib/utils.js:16:13
at ChildProcess.exithandler (node:child_process:430:5)
at ChildProcess.emit (node:events:518:28)
at maybeClose (node:internal/child_process:1104:16)
at ChildProcess._handle.onexit (node:internal/child_process:304:5)

Both Jellyfin and Ngin are on bridged.

So now we have returned back to the ssl error but deeper.

More info if it helps:


(__ )( )( / ) / \ / \ / )
/ / )( / / / \ ( O )_

(
)(__)_)(/_/_/ _/ (___/

─── Welcome to Zima OS, root ───
Date: Tuesday, December 23, 2025 | Uptime: up 1 week, 2 days, 8 hours, 4 minutes

root@ZimaOS:/root ➜ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2c87f954ed89 pihole/pihole:2025.11.1 “start.sh” 5 minutes ago Up 5 minutes (healthy) 67/udp, 0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp, :::53->53/tcp, :::53->53/udp, 123/udp, 0.0.0.0:8800->80/tcp, [::]:8800->80/tcp, 0.0.0.0:8443->443/tcp, [::]:8443->443/tcp pihole
2256a19b08f5 linuxserver/jellyfin:10.10.7 “/init” 27 hours ago Up 37 minutes 0.0.0.0:7359->7359/tcp, :::7359->7359/tcp, 0.0.0.0:8097->8096/tcp, [::]:8097->8096/tcp, 0.0.0.0:8921->8920/tcp, [::]:8921->8920/tcp jellyfin
55b4b19b8f1c lscr.io/linuxserver/duckdns:latest “/init” 9 days ago Up 9 days DuckDNS
a07df1f75063 jc21/nginx-proxy-manager:2.12.3 “/init” 9 days ago Up 9 days 0.0.0.0:80-81->80-81/tcp, :::80-81->80-81/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp nginxproxymanager
0a5e4cb84008 portainer/portainer-ce:2.31.3 “/portainer” 10 days ago Up 9 days 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp, 8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp portainer
f89783153613 lscr.io/linuxserver/plex:1.41.3 “/init” 2 weeks ago Up 9 days plex
8ec97a162ee3 openspeedtest/latest:v2.0.6 “/docker-entrypoint.…” 2 weeks ago Up 9 days 3001/tcp, 8080/tcp, 0.0.0.0:3004->3000/tcp, [::]:3004->3000/tcp openspeedtest
6f6170d97fad 2fauth/2fauth:5.4.3 “/usr/local/bin/entr…” 2 weeks ago Up 9 days 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp 2fauth
root@ZimaOS:/root ➜ #

This one is simple and clear.

The problem

You used the wrong domain when reissuing the SSL cert.

You entered:

benshoff.duckdns.com

But DuckDNS domains are .org, not .com.

That one letter difference is exactly why:

  • Let’s Encrypt validation fails
  • You get ERR_SSL_KEY_USAGE_INCOMPATIBLE
  • The challenge errors appear

The fix (do this exactly)

In Nginx Proxy Manager > SSL > Add Certificate:

  • Domain Names:
benshoff.duckdns.org

(not .com)

  • Email: anything valid
  • Agree to terms
  • DNS challenge OFF
  • HTTP challenge ON
  • Save

Important checks

  • Port 80 must be open to NPM
  • Port 443 must be open to NPM
  • No other container should be using port 80

What NOT to change

  • Do not reinstall Jellyfin
  • Do not change Docker networks
  • Do not touch DuckDNS

Why this happened

SSL is extremely strict.
.com and .org are completely different domains, Let’s Encrypt will always fail if they don’t match.

Fix the domain typo, reissue the cert, and it will work immediately.

Just as a general note: this stuff is very sensitive to exact characters. One wrong letter, extra space, or using .com instead of .org is enough to break things, and the error messages don’t always make that obvious.

It’s extremely common, I’ve done it myself many times. That’s why it’s always worth double-checking the exact spelling and characters when commands or domains don’t behave as expected.

Sorry, I just saw your last reply after I posted mine.

Thanks for sharing that output, it confirms the setup clearly.

Your Jellyfin container is running correctly. The important line is:
0.0.0.0:8097 -> 8096

That means Jellyfin listens internally on 8096. For Nginx Proxy Manager, you must always use the internal port, not the exposed one.

Please double-check NPM > Proxy Host is set exactly like this:

  • Domain: benshoff.duckdns.org
  • Scheme: http
  • Forward Hostname: jellyfin
  • Forward Port: 8096
  • Websockets: ON

Do not use:

  • 8097
  • the ZimaOS IP
  • localhost

Also confirm the SSL certificate domain is exactly benshoff.duckdns.org (no .com, no extra characters).

After saving, open https://benshoff.duckdns.org (no port).
If it still doesn’t load Jellyfin, the only thing left to check is that Jellyfin and NPM are on the same Docker network.

I think I tried to many times and it locked me out.

CommandError: Saving debug log to /tmp/letsencrypt-log/letsencrypt.log
An unexpected error occurred:
too many certificates (5) already issued for this exact set of identifiers in the last 168h0m0s, retry after 2025-12-25 12:40:19 UTC: see Rate Limits - Let's Encrypt
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /tmp/letsencrypt-log/letsencrypt.log or re-run Certbot with -v for more details.

at /app/lib/utils.js:16:13
at ChildProcess.exithandler (node:child_process:430:5)
at ChildProcess.emit (node:events:518:28)
at maybeClose (node:internal/child_process:1104:16)
at ChildProcess._handle.onexit (node:internal/child_process:304:5)

Yes, that’s exactly what happened. You’ve hit a Let’s Encrypt rate limit. Nothing is broken.

Plain explanation:

  • Let’s Encrypt only allows 5 certificates per domain every 7 days
  • You’ve reached that limit
  • The error message tells you exactly when it unlocks again

Key line:

retry after 2025-12-25 12:40:19 UTC

What to do now (simple)

  • Stop trying to issue new certs until that time
  • Do not reinstall anything
  • Do not delete containers

What you can do meanwhile (optional)

  • In Nginx Proxy Manager, use the Default NPM certificate temporarily
    (this will load the site with a browser warning, but it proves routing works)
  • Or just wait, that’s the cleanest option

Important reassurance

This is very common. It happens to almost everyone the first time setting this up.
Once the timer resets, issue one new cert and it will succeed immediately.

You didn’t lock yourself out permanently, it’s just a temporary cooldown.

I will just wait. lol. Enjoy the holidays. I am now off work till next Tuesday. A break from the tech mayhem. lol

1 Like

Hi

So its after the holidays and I have gone crazy with the screenshots. I want to get this all done and fixed. So I can stop bugging you guys, and stop having these issues. I am gonna just upload a link to a folder, since I am limited to uploads of picture files here.

This will probably get this pulled down for a few to verify the link.
Everything is on Bridge, except DuckDns. If I put it on Bridge. it errors out. Its also says Penguinsjellyfin. But everywhere else it says jellyfin. But I cant find a way to fix that. I recreated the ssl on Nginx, but it says its good in the message but red on the site. Just things I noticed. Thank you for your help as always. I hope we get it this time.

Thanks for the screenshots and the folder, that helps a lot. Let’s reset this mentally, not the system, and go step by step in the correct order.

Step 1 – DuckDNS (already done)
DuckDNS is working. Leave it alone.
It does not need to be on bridge and is not part of the routing path. No changes needed here.

Step 2 – Jellyfin container name (this matters)
Docker is very strict with names.
In your screenshots, Jellyfin appears as Penguinsjellyfin, but elsewhere it’s referenced as jellyfin.

Nginx Proxy Manager can only talk to the exact container name.

You must choose one:

  • Either update NPM to forward to Penguinsjellyfin
  • Or rename the Jellyfin container to jellyfin and use that everywhere

If the names don’t match exactly, it will never route correctly.

Step 3 – Nginx Proxy Manager routing
Once the name matches, set the proxy host like this:

  • Domain: benshoff.duckdns.org
  • Scheme: http
  • Forward Hostname: (exact Jellyfin container name)
  • Forward Port: 8096
  • Websockets: ON

Do not use:

  • ZimaOS IP
  • localhost
  • port 8097

Step 4 – Test routing before SSL
Before touching SSL again, test:

https://benshoff.duckdns.org

No port.

If Jellyfin loads, routing is fixed.

Step 5 – SSL (last step)
You previously hit the Let’s Encrypt rate limit, so SSL may still show red even if issued.
Do not keep reissuing certs until the cooldown has fully passed.

Once routing is confirmed and the cooldown is over, issue one certificate for:

benshoff.duckdns.org

That’s it. One step at a time, in this order.
Nothing here requires a reset or reinstall, this is just name matching + timing.