Running Dify behind your corporate reverse proxy: what changes and why it matters
This section explains why publishing a self-hosted Dify through an existing corporate ingress, WAF or load balancer changes how the platform must be configured, and when that work is worth planning. If your platform team has to expose Dify through a standard ingress, a web application firewall or a shared TLS termination point, Dify will sit behind a layer you already operate, and several of its settings must agree with that layer. The bundled Nginx service in the Docker Compose stack is designed to be the front door for a default deployment. Once you place your own proxy in front of it, you own the request path from the browser to Dify, including header handling, body size limits and connection upgrades.
Dify is self-hosted in your infrastructure, so the reverse-proxy layer is yours to design, run and patch. The community edition runs anywhere Docker runs, according to the Dify deployment overview, and nothing in the platform requires a specific vendor ingress or load balancer. Teams usually need this setup for three reasons: corporate ingress standards that every internal application must follow, WAF inspection of prompts and uploads before they reach the application, and central TLS termination managed by a security team. Each reason adds decisions about which headers the proxy sets, which paths it forwards and who owns certificate renewal.
Before you change anything, confirm with your network and security teams which layer will set the forwarded client address and protocol, and which layer will enforce request size limits. Then check the Dify environment variable reference for the public URL settings, because the browser-facing hostname must match what the proxy presents. The rest of this page works through those settings in order, so you can test each one before the platform goes into service.
Which request paths cross your proxy and what each one needs
Console and published app pages are browser traffic. Users load HTML, scripts and static assets, sign in, and move between workspaces and apps. These requests are short and carry session cookies, so the proxy's main jobs are preserving the public hostname and scheme, passing cookies through unchanged, and making sure redirects point at the external address.
- Host and scheme: Forward the external Host header and X-Forwarded-Proto so Dify builds links and redirects with the public https address.
- Cookies: Pass Cookie and Set-Cookie headers through the edge without stripping, renaming or rewriting them.
- Redirects: If the proxy terminates TLS, a Location header that points at an internal http address sends users to the wrong place after sign-in.
- Caching: WAF or CDN caching rules should never store authenticated HTML pages.
- URL variables: Set the console, app and file URL variables in your environment file to the public address. The environment variable reference lists them.
Confirm the URL variables match the hostname users type, then sign in from a fresh browser session and open one published app to check redirects and assets.
Service API calls come from products, scripts and pipelines rather than browsers. They send an Authorization header with an API key, usually with JSON bodies, and they expect the same response whether the call enters through your edge or reaches Dify directly. Most failures here come from a WAF rule or rewrite that changes the path, headers or body before Dify sees them.
- Authorization header: Confirm your WAF and load balancer forward the Authorization header unchanged for API paths.
- Path handling: Do not rewrite or prefix API paths at the proxy. Clients and documentation expect the paths Dify publishes.
- Client IP: Dify logs and any rate limiting see the proxy address unless forwarded client headers are trusted. Trust forwarded headers only from proxies you operate, and set the trusted hop list at the edge.
- Timeouts: Workflows that run to completion before responding need read timeouts longer than the slowest expected run.
- Error pages: Custom error pages at the edge can hide JSON error bodies from API clients, so return API errors unchanged.
Test one service call from outside your network with a test key, then compare the status code and body with a call made from inside the network to find any edge changes.
Streamed responses send answer text in chunks over a connection that stays open while the model generates output. Each chunk must reach the user promptly, so anything that buffers, compresses or times out the response in the middle can make the answer appear frozen, arrive all at once or cut off. The Dify documentation on HTTPS with its bundled Nginx covers long proxy timeouts for streaming, and the same principle applies at your own edge.
- Buffering: Turn off response buffering for streamed paths, or the proxy will hold chunks until the buffer fills or the response ends.
- Read timeouts: Set idle and read timeouts longer than the pauses a model can take between tokens and any tool calls in the middle of a run.
- Compression: Gzip or Brotli filters can delay chunks. Exclude the streaming endpoints from compression.
- Protocol version: Use HTTP/1.1 or HTTP/2 consistently from the edge to Dify so chunked responses pass through intact.
- Retries: Edge retries on a dropped stream can repeat a generation and bill the model twice. Disable automatic retries for streaming routes.
Confirm streaming behavior on the exact Dify version you deploy, because the release notes on GitHub describe changes between minor versions. Then run a long answer through the proxy and watch whether text appears continuously.
File uploads send multipart request bodies that can be far larger than typical API calls. Upload size is limited at every hop the request crosses: the WAF, the load balancer, any Kubernetes ingress and Dify's own Nginx layer. A limit at any one hop rejects the upload with an error that often does not name the hop responsible, so the limits have to be set and checked together.
- Body size per hop: Set the maximum request body on the WAF, load balancer, ingress and bundled Nginx to the same value. The bundled Nginx limit is set through an environment variable, so confirm its name and default in
.env.examplefor your version. - Request buffering: Some proxies buffer the full upload to disk before forwarding. Confirm this does not add timeouts for large files.
- Upload timeouts: Slow uplinks need send timeouts that cover the time a large document takes to arrive.
- Multipart integrity: Content inspection rules can alter or block multipart bodies. Test with representative file types.
- File links: The file URL variable determines the links Dify hands back for stored files, so it must resolve through the proxy.
Upload a document close to your largest expected size through the external hostname and confirm it appears in the knowledge base or the file field without an error page.
WebSocket connections start as an HTTP request that asks to switch protocols, then stay open so the server can push messages both ways. A proxy that does not forward the upgrade request will leave the connection stuck in plain HTTP, and the collaboration feature will fail quietly or fall back in ways that are hard to see from the browser. Whether your deployed version uses WebSocket for a given feature is a question to confirm against its documentation and release notes.
- Upgrade headers: Forward the Upgrade and Connection headers for the WebSocket path, and send them to the upstream over HTTP/1.1.
- Idle timeouts: Long-lived connections are closed by default idle timeouts on many load balancers. Set them above your session length or add keepalive pings.
- Routing: Keep WebSocket paths on the same routing rules as the rest of the console so the browser reaches the expected backend.
- Affinity: If you run more than one web node, confirm whether the version needs session affinity for collaboration state.
- Health checks: Health probes should target a plain HTTP endpoint so a probe failure does not remove a node that is serving live sessions.
Open the collaboration feature in two browser sessions, make a change in one, and confirm it appears in the other. Repeat after a proxy restart to check reconnection.
Proxy configuration options and when each one fits
This table compares the main ways to place Dify behind a corporate proxy, load balancer or WAF, and what each choice means for TLS, client IP visibility, logs and upgrades. Read each row against your existing ingress standards, then confirm the chosen layout with the Dify version you plan to run.
| Decision | Option | Trade-off | When it fits |
|---|---|---|---|
| TLS termination | At the corporate proxy or load balancer | Certificates and renewals stay with your edge team, but the hop from proxy to Dify must be trusted and protected by your network controls | Your standard requires all public TLS to end at a shared edge |
| TLS termination | At the bundled Nginx | Keeps Dify's documented HTTPS setup in one place, but the edge must pass HTTPS through and certificates are managed on the Dify host | Dify is a dedicated tenant with its own certificate process |
| Bundled Nginx | Kept as the backend behind your proxy | Least change to the Compose layout and simpler upgrades, but two proxy layers must agree on headers, body limits and timeouts | You want to follow the vendor's default routing with minimal edits |
| Bundled Nginx | Replaced by your own ingress or gateway | Full control over routing and policy, but you must reproduce WebSocket, streaming and upload settings and recheck them on every upgrade | Your platform team already runs a standard ingress for all services |
| Forwarded headers | Trusted only from the known proxy address | Client IP and scheme in logs are accurate, and spoofed headers from clients are ignored; requires a stable proxy address | Logs and audit trails must show real client addresses |
| Forwarded headers | Trusted from any upstream hop | Simple to configure, but clients can forge addresses in logs and access decisions that depend on them | Rarely acceptable for regulated access logging |
| WAF placement | Inline before the load balancer | Inspects traffic before it reaches any Dify component, though WAF rules may need tuning for prompt-heavy and upload requests | Security policy requires one inspection point for all public apps |
| WAF placement | After the load balancer, in front of Dify | Sees traffic after TLS termination and routing, which can simplify rules for Dify paths, but depends on the balancer already enforcing the edge policy | Separate teams own the load balancer and application security rules |
| Public URL variables | Console, API and web app URLs set to the external HTTPS hostname | Redirects, generated links and embedded web apps break if these point at internal names or HTTP; confirm each variable in the environment reference | Any proxy layout, since mismatches surface after login or in embedded apps |
| Upgrades and logs | Custom proxy configuration kept outside the Dify files | Keeps vendor files untouched between releases, but you must recheck headers and limits against each upgrade note | You plan to pull new Compose versions regularly |
Setup sequence for a Dify ingress behind an existing proxy
This sequence moves a Dify instance from its default local addresses to one that a corporate proxy or load balancer serves correctly under the external hostname. Each step ends with a check the operator runs, so any failure traces back to a single change.
Fix the external hostname and scheme
The network or platform team decides the public hostname that users and API clients will use, and whether the edge serves it over HTTPS. Record the hostname, the certificate it will present, and the internal address the proxy forwards to in the change record. Ask the team to confirm that DNS and the certificate match this name before any Dify settings change. Check: a request to the public name reaches the proxy over the intended scheme with a certificate that validates in a browser.
Set the public URL variables to match
Update the URL variables in the Compose env file so every address Dify generates uses the external hostname and scheme. These cover the console, the web app, the service API and file URLs. Confirm each variable name and expected format in the environment variable reference for your release, because the list changes between versions. Restart the stack after editing. Check: load the console from the public hostname, open the browser developer tools, and confirm there are no requests to localhost, internal hostnames or plain http addresses.
Forward headers and the WebSocket upgrade
Configure the proxy to pass the original host, the scheme and the client address to the Dify edge, and to upgrade connections on the paths that carry collaboration traffic. Accept forwarded headers only from the proxy's own address range, so clients cannot spoof their origin. Confirm which header and trusted-proxy settings your Dify version supports with the vendor documentation and your proxy's documentation. Check: open the same app in two browser sessions, edit the workflow in one, and confirm the other session receives the change without a reconnect loop.
Set upload body limits on proxy and Dify
Set the maximum request body size on the corporate proxy or load balancer, then set the matching upload limits in the Dify environment. If the two values differ, the smaller one rejects files first, often with an error that does not name the layer responsible. Confirm the Dify limits for documents and uploads against the maximum file size your team needs. Check: upload a file just under the limit to a knowledge base and to a file input in a workflow, then one just over, and confirm the rejection comes from the expected layer.
Confirm streaming and long-running timeouts
Set the proxy's read and send timeouts long enough for streamed chat responses and long workflow runs, because an idle timeout cuts a stream mid-answer. Turn off response buffering for event-stream paths so tokens reach the browser as they are generated. If traffic passes through the bundled Nginx container, check its proxy timeout settings as well. Check: run a streamed chat response and a workflow that produces a long model output, and confirm both finish without truncation or a gateway timeout error.
Restart and check against the environment reference
Restart the Compose stack, then compare your env file with the current
.env.exampleand the environment variable reference for your target release, since new variables appear between versions. Record each changed setting and the reason for it. Before any upgrade, take a backup and read the upgrade guide for the target version on the releases page. Check: repeat the console load, file upload and streamed run from a clean browser session, and confirm the service logs show no errors related to URLs, headers or the proxy.
Trusting forwarded headers without letting clients spoof them
Forwarded headers decide what Dify believes about the client and the connection. Behind a load balancer or WAF, the client address and original scheme arrive in headers such as X-Forwarded-For and X-Forwarded-Proto rather than in the connection itself. Dify's logs, any rate limiting or access rules you add at the edge, the Secure flag on cookies and the scheme used in generated links all depend on those values. If the application accepts a header from any sender, a client can send its own X-Forwarded-For value and make audit logs show a different address, or send X-Forwarded-Proto: https over plain HTTP and cause the app to treat the connection as secure when it is not.
The control is to trust forwarded headers only from the proxy hops you operate. Your edge component should strip or overwrite inbound copies of the forwarding headers before adding its own, so the value Dify receives was written by infrastructure you control. Each hop in a chain needs the same rule, and a CDN or third-party WAF in front of your own proxy must be configured to send only its verified client address. Check which hosts your reverse proxy treats as trusted and make sure no path lets clients reach the Dify containers directly, since that bypasses the rewrite entirely.
Session integrity is the other half. The environment reference says SECRET_KEY signs session cookies and JWTs and encrypts OAuth credentials, and that changing it after deployment logs out all users. That makes the key a deliberate, stable secret to generate once and store in your secrets manager, not something to rotate casually during a proxy change. Confirm in your Dify version exactly which forwarded headers the API and web containers read, whether a trusted-proxy setting exists, and how the cookie Secure attribute is decided, using the Dify environment variables reference and your own test requests before you go live.
Security and operational risks at the proxy layer
A reverse proxy or load balancer in front of Dify changes how requests arrive, how they are filtered and how URLs resolve. Each risk below comes from one of those changes, and each has a check your team can run before go-live. Review them together with your proxy team, because the fix often sits in both the proxy and the Dify configuration.
Spoofed forwarded headers
Dify sees the client address and original scheme through headers such as X-Forwarded-For and X-Forwarded-Proto that your proxy sets. If the proxy passes through values supplied by the client, anyone can write their own address into those headers and affect logging, rate limits and access rules. Make the proxy overwrite these headers rather than append to them, and confirm which upstream addresses Dify's Nginx trusts for forwarded headers. Test with a request that carries a fake forwarded address.
WAF inspection of streams and uploads
Web application firewalls often buffer request and response bodies, apply size limits or time out idle connections. Dify's streaming chat responses and document uploads can fail silently when a WAF buffers them, closes them early or rejects large multipart bodies. Confirm with your security team which rules apply to the Dify hostname, and test a streamed answer and a large upload through the WAF before enabling enforcement.
Direct access that bypasses the proxy
If the Dify published port is reachable from the network, requests can skip the WAF, authentication layer and logging that the proxy provides. This is common when a Compose host has its ports open to a subnet. Restrict the Nginx port to the proxy's addresses at the host or network firewall, and verify from an unapproved host that the Dify port does not answer.
SSRF through outbound requests
Dify makes outbound requests when workflows call HTTP endpoints or fetch remote files, so a user who controls a URL could aim those calls at internal services. The SSRF_PROXY setting routes outbound requests through a proxy that blocks internal and private IP ranges. Confirm that this setting is active in your deployment, and do not let the reverse proxy's internal addresses become a reachable target through workflow tools.
Logouts when SECRET_KEY changes
SECRET_KEY signs session cookies and JWTs and encrypts OAuth credentials. Changing it after deployment logs out all users, and a proxy or load balancer rotation plan that reuses this value by accident can cause a sudden loss of sessions. Store the value in your secrets manager, schedule any rotation as a planned change with a user notice, and record which environments share the key.
Hostname and certificate changes
Moving Dify behind a new hostname or certificate changes the public URLs that Dify uses in links, callbacks and embedded pages. If those variables still point to the old hostname or to http, redirects, OAuth callbacks and web app links can break after cutover. Update every public URL variable to the external hostname, reload the stack, and check that sign-in, shared links and callbacks use the new address.
What teams ask before putting Dify behind a corporate proxy
How much effort does putting Dify behind a corporate reverse proxy take?
The effort is usually modest in code terms and heavier in coordination, because most of the work is agreeing on how the existing edge treats Dify's traffic. The main drivers are how many layers already sit in front of the service (a load balancer, a WAF, an ingress controller), whether those layers already pass forwarded headers correctly, how many public URL variables must match the external hostname, and whether Dify is served from Compose or from a platform the team already runs. Teams that also need streaming responses, collaboration over WebSockets and large file uploads should expect more test cycles, since each of those paths has its own limits to verify. Ask your team to map every hop between the user and the Dify web and API services before estimating any work.
How long does a reverse proxy integration for Dify typically run?
No general duration can be stated from the supplied facts, so treat any figure you hear with caution. Duration is driven by approval cycles for network and WAF changes, the number of certificate and DNS owners involved, whether a test environment already mirrors production routing, and how many rounds of upload, streaming and WebSocket testing are needed before sign-off. Organizations with a change-advisory process often spend more calendar time waiting for approvals than on configuration. Ask for a written schedule that lists each dependency and who owns it, and ask which steps can run in parallel. A fixed-scope agreement in writing gives both sides a defined list of deliverables to hold against those dates.
What does the client need to provide for a Dify proxy project?
The work needs input from several teams, and it goes faster when each one is named at the start. Typical contributors are:
- The network team, who controls load balancer listeners, routing rules, and the path between the edge and the Dify host.
- WAF owners, who must confirm that rules do not block long requests, WebSocket upgrades or large multipart uploads.
- Certificate and DNS owners, who issue the public certificate and control the hostname that Dify must advertise.
- Platform or application owners, who provide a test environment that matches the production edge closely enough to prove the behavior.
Confirm with each owner which change tickets they need and how long their approvals take, since these are your own internal facts rather than anything this page can state.
Can an internal platform team configure Dify behind a proxy without outside help?
A team with solid experience in reverse proxies, TLS and container networking can usually do this internally, and the Community edition is available for self-hosting with no license fee. The questions to answer honestly are whether the team has someone who understands how Dify's Nginx service, its API and its WebSocket path interact with the upstream edge, and whether they have a safe place to test header trust, upload limits and streaming before production. Self-hosted Community use is limited to a single workspace, and the Enterprise edition is custom priced and adds SSO and multiple workspaces, so confirm which edition the scope requires before deciding who builds it. An external partner is most useful when the team lacks that test environment or cannot spare the time for repeated verification.
What changes at each Dify upgrade when it runs behind a proxy?
Each upgrade needs a review of the proxy settings, not just a new image. Dify's Docker Compose documentation says to follow the upgrade guide for the target version on the GitHub Releases page, to take a backup before every upgrade, and to check .env.example for new variables after upgrading. Public URL variables and any header or body-size settings on your edge may need to change with a new release, so compare them against the release notes each time. Minor releases arrive roughly monthly, so plan a recurring review rather than treating this as a one-time task. Ask whether your support arrangement covers upgrade testing through the proxy path.
Which proxy settings should an engineer check first after go-live?
Start with the settings that fail silently. Confirm that forwarded headers are trusted only from your own edge, so that client IP and scheme are read correctly and spoofed headers from outside are dropped. Then verify that the public URL variables match the external hostname and use HTTPS where users connect. Next, test a long streamed response, a WebSocket session used for collaboration and a file upload near your configured limit, because each path has different timeouts and body limits at the load balancer or WAF. Finally, record the results and re-run the same checks after every upgrade. Exact variable names and defaults should be taken from the environment variable reference at the time of your deployment.
Does putting Dify behind a WAF change its security posture?
A WAF or edge gateway adds a useful control layer, but it does not replace the controls inside Dify, and it can create new risk if misconfigured. Trusting forwarded headers from the wrong source can let a client appear to come from an internal address, which matters because Dify's outbound request filtering and access logs depend on accurate client information. Also confirm that the edge does not expose internal services such as the admin paths or the plugin daemon. Security testing of the exposed application and its APIs is a separate piece of work that can be scoped alongside the proxy change, and the results should be reviewed by the team that owns the edge.
Keeping the proxy configuration aligned through Dify upgrades
Treat the proxy configuration as part of every Dify upgrade, because the releases page shows minor releases arriving roughly monthly, and each one can add variables that your ingress rules and URL settings never accounted for. The upgrade routine starts with a backup, as the Docker Compose upgrade guidance recommends for every upgrade, followed by a read of the target version's upgrade guide and a diff of .env.example against the file your team actually runs. Any new variable that touches public URLs, forwarded headers, upload limits or WebSocket paths goes onto the review list before anything is restarted.
A change log for ingress rules is the artifact that makes that review possible. Record each change to the corporate reverse proxy or load balancer with its owner, date, the Dify version it was tested against, the exact client_max_body_size-equivalent limit, timeouts, forwarded header rules and the public hostname variables. Confirm with your proxy vendor the exact directive names and defaults for your product. Keep the log in the same repository as the Compose env files so that an auditor or on-call engineer can see what changed between two releases without reconstructing it from memory.
Stage every upgrade behind a proxy that matches production: the same certificates chain, the same header rules, the same body limits and the same WAF policy. Run one upload of a document near your largest permitted size, one streamed chat response, and one login through your identity path, then compare the results with the previous version. Write the rollback plan before the upgrade window opens: the backup to restore, the previous image tags, the previous .env file and the proxy configuration revision to reapply. Confirm that a rollback has been rehearsed, since a proxy rule that works on the new version can still break an older client.
How DeployOpen scopes and delivers a Dify ingress integration
DeployOpen plans and implements self-hosted open-source platforms inside your own infrastructure, including Dify behind an existing ingress, WAF or load balancer. We start from the forwarded headers, WebSocket path, upload limits and public URL settings your edge already uses, then deliver a tested configuration your team can run and change.
How we scope
- Inventory the existing ingress, WAF and load balancer, including TLS termination and header rewriting rules
- Agree which public hostname, protocol and upload size Dify must accept, in writing before work starts
- Define the fixed scope, deliverables and timeline together with your network and security teams
How we build
- Configure trusted proxy and forwarded header handling so client addresses reach Dify logs correctly
- Route the WebSocket path used for collaboration and set body size limits at every hop in the chain
- Align the public URL variables with the external hostname and test each path from outside the network
How we hand over
- Document the proxy configuration, the URL variables, and the reasoning behind each header and limit
- Provide a verification checklist covering login, uploads, streaming responses and WebSocket connections
- Walk your operations team through upgrade checks, including reviewing new environment variables after each release
How we support
- Offer ongoing support, upgrades and continuous testing for the ingress layer as a retainer
- Re-test the edge configuration when your WAF rules, load balancer or Dify version changes
- Keep the written scope current so each change to the edge is planned, tested and recorded

