Skip to content

feat(config): add Local Gateway URL for reverse proxy and Docker#2486

Merged
lidel merged 6 commits into
ipfs:mainfrom
NiltonVolpato:fix/local-gateway-override
Jun 30, 2026
Merged

feat(config): add Local Gateway URL for reverse proxy and Docker#2486
lidel merged 6 commits into
ipfs:mainfrom
NiltonVolpato:fix/local-gateway-override

Conversation

@NiltonVolpato

@NiltonVolpato NiltonVolpato commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Problem

When running Kubo in Docker or behind a reverse proxy, the WebUI generates incorrect gateway URLs (e.g., http://127.0.0.1:8080) for:

  • File downloads
  • Preview links
  • IPLD Explore page

This happens because the WebUI reads the gateway address from Kubo's config, which typically contains Docker-internal addresses like /ip4/0.0.0.0/tcp/8080 that get converted to 127.0.0.1:8080.

Solution

Adds a new "Local Gateway URL" setting that allows users to override the gateway URL used by the WebUI.

Priority order for gateway URL:

  1. User-configured Local Gateway URL (new)
  2. Gateway address from Kubo config
  3. Public Gateway (fallback)

Changes

  • Added LocalGatewayForm component in Settings
  • Added ipfsLocalGateway localStorage key
  • Modified selectGatewayUrl to check local override first
  • Sync setting to kuboGateway format for IPLD Explore page compatibility

How to Use

  1. Go to SettingsLocal Gateway
  2. Enter your actual gateway URL (e.g., https://ipfs.example.com)
  3. Submit - downloads and previews will now use this URL

Leave empty to use the existing behavior (auto-detect from Kubo config).

Testing

  • All Settings e2e tests pass
  • Manually tested with Docker + reverse proxy setup
  • Backward compatible - no change when setting is empty

Adds a new 'Local Gateway URL' setting that allows users to override
the gateway address from Kubo config. This is useful when:
- Running Kubo in Docker
- Accessing WebUI through a reverse proxy
- Accessing from a different host than where Kubo runs

The setting takes priority over the Kubo config gateway address.
When empty, the behavior falls back to the existing logic.

Fixes ipfs#2458
Ensures URLs like 'https://example.com/' and 'https://example.com'
are handled the same way, avoiding double slashes when constructing
paths like /ipfs/CID.
The ipld-explorer-components (Explore page) uses localStorage key
'kuboGateway' with {host, port, protocol} format. This change syncs
our 'ipfsLocalGateway' setting to that format so the Explore page
also uses the correct gateway URL.

Fixes Explore page using 127.0.0.1:8080 instead of custom gateway.
…flakiness

The e2e test uses getByText('Addresses') which matches any element
containing 'address' (case-insensitive). Changed 'gateway address' to
'gateway URL' in the description to avoid matching this query.
@gammazero

Copy link
Copy Markdown

Triage: Will look at in conjunction with kubo v0.42.0

@GZGavinZhao

GZGavinZhao commented Apr 20, 2026

Copy link
Copy Markdown

I'd like to note that this fix is not just helpful for people using reverse proxy and Docker, but also anyone who doesn't set Addresses.Gateway to the default /ip4/127.0.0.1/tcp/8080. For example, I set my gateway port as 9090 because 8080 is used by some other application, and then WebUI refuses to "Explore" any CID because it tries to connect to http://127.0.0.1:8080/ipfs/<CID>.

The Local Gateway URL only reached download links, so previews,
thumbnails and IPNS links still used the public gateway behind a
reverse proxy. Make the override apply to every gateway link the
WebUI builds.

- config: when an override is set, use it as the reachable gateway
  too, so previews, thumbnails, Explore and IPNS links honor it
- ipns-manager: use the available gateway URL, which also fixes a
  broken link before the gateway check has run
- gateway/ipfs-provider: one shared helper builds the Explore (Helia)
  gateway config from the override, and clearing the override resets it
- local-gateway-form: check the URL loads before saving so a typo
  cannot silently break links; the check now keeps the port
- settings: show the description above the input like the other
  gateway fields, link the gateway address to its Kubo docs, and use
  `http://localhost:8080` in the example
- tests: unit coverage for the override selection and the Helia config
  helper, plus an e2e that sets a Local Gateway URL and confirms it on
  the Status page

Closes ipfs#2383
@lidel lidel force-pushed the fix/local-gateway-override branch from d734d65 to 83e21d5 Compare June 30, 2026 01:56

@lidel lidel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this, and for your patience while it sat.

I pushed a follow-up to your branch instead of sending you back for another round. It merges in latest main and:

  • extends the override to previews, thumbnails, the Explore page and IPNS links, which still pointed at the public gateway behind a reverse proxy because only the download path read it (this also closes #2383)
  • folds the duplicated kuboGateway sync into one helper, and resets it when the override is cleared
  • validates that the URL is reachable before saving, so a typo can't silently break links
  • moves the field description above the input to match the other gateway settings, with a couple of unit tests
  • adds e2e test to lock this down against regressions

If any of it doesn't match what you intended, let me know in a new issue / pr, but I'm going to merge so it is not missed in the next release :)

@lidel lidel merged commit 6a4acab into ipfs:main Jun 30, 2026
13 checks passed
@lidel lidel changed the title Add Local Gateway URL setting for reverse proxy and Docker support feat(config): add Local Gateway URL for reverse proxy and Docker Jun 30, 2026
lidel added a commit that referenced this pull request Jun 30, 2026
The share modal's local links flow through selectGatewayUrl, so the
Local Gateway URL override added in #2486 reaches them. Subdomain links
are offered only for domain gateways, since subdomain gateways cannot
resolve on a bare IP such as 127.0.0.1.

- files.js: add getLocalLinks, deriving both links from the gateway url
  (host, port, scheme); gate the subdomain link to domain hosts and to
  CIDs that fit a 63-char DNS label; share filename and base32 logic
  with getShareableLink
- actions.js: build the local links via getLocalLinks
- share-modal: clear the subdomain choice when the local link is
  unchecked, so it cannot silently reapply
- protocol.ts: type the share-link result as ShareLinks, not string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants