[{"data":1,"prerenderedAt":39},["ShallowReactive",2],{"article-how-reverse-proxies-actually-work-and-why-every-self-hosted-server-needs-one-103d":3},{"type_of":4,"id":5,"title":6,"description":7,"readable_publish_date":8,"slug":9,"path":10,"url":11,"comments_count":12,"public_reactions_count":12,"collection_id":13,"published_timestamp":14,"language":15,"subforem_id":16,"positive_reactions_count":12,"cover_image":17,"social_image":18,"canonical_url":19,"created_at":14,"edited_at":20,"crossposted_at":13,"published_at":14,"last_comment_at":14,"reading_time_minutes":21,"tag_list":22,"tags":23,"body_html":28,"body_markdown":29,"user":30},"article",4180941,"How Reverse Proxies Actually Work (And Why Every Self-Hosted Server Needs One)","Imagine walking into a large office building. You don't know which department handles your request,...","Jul 19","how-reverse-proxies-actually-work-and-why-every-self-hosted-server-needs-one-103d","\u002Fashraful\u002Fhow-reverse-proxies-actually-work-and-why-every-self-hosted-server-needs-one-103d","https:\u002F\u002Fdev.to\u002Fashraful\u002Fhow-reverse-proxies-actually-work-and-why-every-self-hosted-server-needs-one-103d",0,null,"2026-07-19T16:51:42Z","en",1,"https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=1000,height=420,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1tukharxpy4o4dss7vau.png","https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=1200,height=627,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1tukharxpy4o4dss7vau.png","https:\u002F\u002Fblog.ashraful.dev\u002Farticle\u002Fhow-reverse-proxies-actually-work-and-why-every-self-hosted-server-needs-one-103d","2026-07-19T17:02:03Z",4,"webdev, nginx, linux, proxy",[24,25,26,27],"webdev","nginx","linux","proxy","\u003Cp>Imagine walking into a large office building. You don't know which department handles your request, so you first stop at the reception desk.\u003C\u002Fp>\n\n\u003Cp>The receptionist asks what you need, checks your request, and directs you to the correct department.\u003C\u002Fp>\n\n\u003Cp>A \u003Cstrong>reverse proxy\u003C\u002Fstrong> works exactly like that receptionist.\u003C\u002Fp>\n\n\u003Cp>Instead of exposing every application directly to the internet, all traffic first reaches the reverse proxy. The reverse proxy then decides where that request should go.\u003C\u002Fp>\n\n\u003Cp>If you're running a home server, VPS, or Kubernetes cluster, understanding reverse proxies is one of the most valuable networking concepts you can learn.\u003C\u002Fp>\n\n\u003Cp>Let's dive in.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"what-is-a-reverse-proxy\" href=\"#what-is-a-reverse-proxy\">\n  \u003C\u002Fa>\n  What Is a Reverse Proxy?\n\u003C\u002Fh1>\n\n\u003Cp>A reverse proxy is a server that sits \u003Cstrong>between clients and your backend applications\u003C\u002Fstrong>.\u003C\u002Fp>\n\n\u003Cp>Instead of users connecting directly to your services, they connect to the reverse proxy first.\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>Internet\n     │\n     ▼\n+--------------------+\n|   Reverse Proxy    |\n+--------------------+\n        │\n ┌──────┼─────────┐\n │      │         │\n ▼      ▼         ▼\nJellyfin Immich  Nextcloud\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>The client never talks directly to Jellyfin, Immich, or Nextcloud.\u003C\u002Fp>\n\n\u003Cp>Everything passes through the reverse proxy.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"reverse-proxy-vs-forward-proxy\" href=\"#reverse-proxy-vs-forward-proxy\">\n  \u003C\u002Fa>\n  Reverse Proxy vs Forward Proxy\n\u003C\u002Fh1>\n\n\u003Cp>People often confuse these two.\u003C\u002Fp>\n\n\u003Ch2>\n  \u003Ca name=\"forward-proxy\" href=\"#forward-proxy\">\n  \u003C\u002Fa>\n  Forward Proxy\n\u003C\u002Fh2>\n\n\u003Cp>A forward proxy works \u003Cstrong>for the client\u003C\u002Fstrong>.\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>You\n │\n ▼\nForward Proxy\n │\n ▼\nInternet\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>Examples:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Corporate networks\u003C\u002Fli>\n\u003Cli>School internet\u003C\u002Fli>\n\u003Cli>VPNs\u003C\u002Fli>\n\u003Cli>Anonymous browsing\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>The website sees the proxy—not you.\u003C\u002Fp>\n\n\u003Ch2>\n  \u003Ca name=\"reverse-proxy\" href=\"#reverse-proxy\">\n  \u003C\u002Fa>\n  Reverse Proxy\n\u003C\u002Fh2>\n\n\u003Cp>A reverse proxy works \u003Cstrong>for the server\u003C\u002Fstrong>.\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>Internet\n     │\n     ▼\nReverse Proxy\n     │\n     ▼\nYour Applications\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>Clients don't know which server actually handled the request.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"why-not-just-open-every-port\" href=\"#why-not-just-open-every-port\">\n  \u003C\u002Fa>\n  Why Not Just Open Every Port?\n\u003C\u002Fh1>\n\n\u003Cp>Suppose your server runs:\u003C\u002Fp>\n\n\u003Cdiv class=\"table-wrapper-paragraph\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Application\u003C\u002Fth>\n\u003Cth>Port\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Jellyfin\u003C\u002Ftd>\n\u003Ctd>8096\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Immich\u003C\u002Ftd>\n\u003Ctd>2283\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Nextcloud\u003C\u002Ftd>\n\u003Ctd>8080\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Grafana\u003C\u002Ftd>\n\u003Ctd>3000\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Portainer\u003C\u002Ftd>\n\u003Ctd>9443\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\u003C\u002Fdiv>\n\n\u003Cp>Without a reverse proxy, you'd access them like this:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>https:\u002F\u002Fexample.com:8096\nhttps:\u002F\u002Fexample.com:2283\nhttps:\u002F\u002Fexample.com:8080\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>That's messy.\u003C\u002Fp>\n\n\u003Cp>Instead, a reverse proxy lets you use:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>https:\u002F\u002Fmovies.example.com\nhttps:\u002F\u002Fphotos.example.com\nhttps:\u002F\u002Fcloud.example.com\nhttps:\u002F\u002Fgrafana.example.com\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>Much cleaner.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"how-a-reverse-proxy-routes-requests\" href=\"#how-a-reverse-proxy-routes-requests\">\n  \u003C\u002Fa>\n  How a Reverse Proxy Routes Requests\n\u003C\u002Fh1>\n\n\u003Cp>Imagine someone opens:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>https:\u002F\u002Fmovies.example.com\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>The request reaches your reverse proxy.\u003C\u002Fp>\n\n\u003Cp>The reverse proxy checks:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight http\">\u003Ccode>\u003Cspan class=\"err\">Host: movies.example.com\n\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>It finds a rule:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>movies.example.com\n      ↓\nhttp:\u002F\u002F192.168.1.20:8096\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>The request is forwarded to Jellyfin.\u003C\u002Fp>\n\n\u003Cp>If someone instead visits:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>https:\u002F\u002Fphotos.example.com\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>The proxy routes it to:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>http:\u002F\u002F192.168.1.20:2283\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>which is your Immich server.\u003C\u002Fp>\n\n\u003Cp>The client never notices this routing.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"a-real-example\" href=\"#a-real-example\">\n  \u003C\u002Fa>\n  A Real Example\n\u003C\u002Fh1>\n\n\u003Cp>Suppose your home server hosts four services.\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>192.168.10.10\n\n├── Jellyfin\n├── Immich\n├── Grafana\n└── Portainer\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>You install Nginx Proxy Manager.\u003C\u002Fp>\n\n\u003Cp>DNS records:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>movies.example.com\nphotos.example.com\ngrafana.example.com\nportainer.example.com\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>Routing table:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>movies.example.com\n    ↓\nlocalhost:8096\n\nphotos.example.com\n    ↓\nlocalhost:2283\n\ngrafana.example.com\n    ↓\nlocalhost:3000\n\nportainer.example.com\n    ↓\nlocalhost:9443\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>Everything is now accessible using simple URLs.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"https-becomes-easy\" href=\"#https-becomes-easy\">\n  \u003C\u002Fa>\n  HTTPS Becomes Easy\n\u003C\u002Fh1>\n\n\u003Cp>Without a reverse proxy, every application must:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Generate certificates\u003C\u002Fli>\n\u003Cli>Renew certificates\u003C\u002Fli>\n\u003Cli>Configure HTTPS\u003C\u002Fli>\n\u003Cli>Handle redirects\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>That's a lot of work.\u003C\u002Fp>\n\n\u003Cp>Instead:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>Internet\n    │ HTTPS\n    ▼\nReverse Proxy\n    │ HTTP\n    ▼\nApplications\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>The reverse proxy handles:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>SSL certificates\u003C\u002Fli>\n\u003Cli>Let's Encrypt\u003C\u002Fli>\n\u003Cli>Automatic renewal\u003C\u002Fli>\n\u003Cli>HTTPS redirects\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Your backend applications can remain on HTTP inside your trusted local network.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"security-benefits\" href=\"#security-benefits\">\n  \u003C\u002Fa>\n  Security Benefits\n\u003C\u002Fh1>\n\n\u003Cp>A reverse proxy isn't just about convenience.\u003C\u002Fp>\n\n\u003Cp>It adds another security layer.\u003C\u002Fp>\n\n\u003Cp>It can:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Hide internal IP addresses\u003C\u002Fli>\n\u003Cli>Block malicious requests\u003C\u002Fli>\n\u003Cli>Limit request rates\u003C\u002Fli>\n\u003Cli>Require authentication\u003C\u002Fli>\n\u003Cli>Restrict countries\u003C\u002Fli>\n\u003Cli>Filter bad bots\u003C\u002Fli>\n\u003Cli>Prevent direct access to services\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Your applications become much harder to attack.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"load-balancing\" href=\"#load-balancing\">\n  \u003C\u002Fa>\n  Load Balancing\n\u003C\u002Fh1>\n\n\u003Cp>Suppose one server isn't enough.\u003C\u002Fp>\n\n\u003Cp>Instead of one backend:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>App Server 1\nApp Server 2\nApp Server 3\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>The reverse proxy distributes traffic.\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>Client 1 → Server 1\n\nClient 2 → Server 2\n\nClient 3 → Server 3\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>Benefits:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Higher availability\u003C\u002Fli>\n\u003Cli>Better performance\u003C\u002Fli>\n\u003Cli>Fault tolerance\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Large websites rely heavily on this.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"caching\" href=\"#caching\">\n  \u003C\u002Fa>\n  Caching\n\u003C\u002Fh1>\n\n\u003Cp>Imagine your homepage receives thousands of requests.\u003C\u002Fp>\n\n\u003Cp>Instead of asking your application every time:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>User\n  │\n  ▼\nReverse Proxy\n  │\nCache Exists?\n  │\n Yes ─────► Return Cached Page\n  │\n No\n  ▼\nApplication\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>Static content like:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Images\u003C\u002Fli>\n\u003Cli>CSS\u003C\u002Fli>\n\u003Cli>JavaScript\u003C\u002Fli>\n\u003Cli>Fonts\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>can be served directly from the reverse proxy.\u003C\u002Fp>\n\n\u003Cp>This greatly reduces application load.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"compression\" href=\"#compression\">\n  \u003C\u002Fa>\n  Compression\n\u003C\u002Fh1>\n\n\u003Cp>Modern reverse proxies can compress responses.\u003C\u002Fp>\n\n\u003Cp>Instead of sending:\u003Cbr>\n\u003C\u002Fp>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight plaintext\">\u003Ccode>HTML\nCSS\nJavaScript\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Cp>uncompressed, they use:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Gzip\u003C\u002Fli>\n\u003Cli>Brotli\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Smaller responses mean:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Faster websites\u003C\u002Fli>\n\u003Cli>Lower bandwidth usage\u003C\u002Fli>\n\u003Cli>Better user experience\u003C\u002Fli>\n\u003C\u002Ful>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"websockets-and-streaming\" href=\"#websockets-and-streaming\">\n  \u003C\u002Fa>\n  WebSockets and Streaming\n\u003C\u002Fh1>\n\n\u003Cp>Applications like:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Jellyfin\u003C\u002Fli>\n\u003Cli>Home Assistant\u003C\u002Fli>\n\u003Cli>Immich\u003C\u002Fli>\n\u003Cli>VS Code Server\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>use persistent connections.\u003C\u002Fp>\n\n\u003Cp>Reverse proxies understand WebSockets and keep these connections alive while still handling routing and HTTPS.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"popular-reverse-proxy-software\" href=\"#popular-reverse-proxy-software\">\n  \u003C\u002Fa>\n  Popular Reverse Proxy Software\n\u003C\u002Fh1>\n\n\u003Cdiv class=\"table-wrapper-paragraph\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Software\u003C\u002Fth>\n\u003Cth>Best For\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Nginx\u003C\u002Ftd>\n\u003Ctd>High performance and flexibility\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Nginx Proxy Manager\u003C\u002Ftd>\n\u003Ctd>Easy web interface for beginners\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Traefik\u003C\u002Ftd>\n\u003Ctd>Docker and Kubernetes integration\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>HAProxy\u003C\u002Ftd>\n\u003Ctd>High-performance load balancing\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Caddy\u003C\u002Ftd>\n\u003Ctd>Automatic HTTPS with minimal configuration\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Envoy\u003C\u002Ftd>\n\u003Ctd>Large-scale microservices and cloud-native deployments\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\u003C\u002Fdiv>\n\n\u003Cp>Each has its strengths, but for many self-hosters, \u003Cstrong>Nginx Proxy Manager\u003C\u002Fstrong> provides an excellent balance of simplicity and features.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"common-mistakes\" href=\"#common-mistakes\">\n  \u003C\u002Fa>\n  Common Mistakes\n\u003C\u002Fh1>\n\n\u003Cp>Many beginners accidentally:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Expose application ports directly to the internet.\u003C\u002Fli>\n\u003Cli>Skip HTTPS entirely.\u003C\u002Fli>\n\u003Cli>Open unnecessary firewall ports.\u003C\u002Fli>\n\u003Cli>Forget to configure \u003Ccode>X-Forwarded-For\u003C\u002Fcode> and \u003Ccode>X-Forwarded-Proto\u003C\u002Fcode> headers.\u003C\u002Fli>\n\u003Cli>Leave administrative interfaces like Portainer publicly accessible without authentication.\u003C\u002Fli>\n\u003Cli>Mix internal and external DNS records in ways that create routing issues.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Taking time to configure your reverse proxy correctly can prevent these problems.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"when-do-you-need-a-reverse-proxy\" href=\"#when-do-you-need-a-reverse-proxy\">\n  \u003C\u002Fa>\n  When Do You Need a Reverse Proxy?\n\u003C\u002Fh1>\n\n\u003Cp>You probably need one if you:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Host more than one web application.\u003C\u002Fli>\n\u003Cli>Want friendly domain names instead of port numbers.\u003C\u002Fli>\n\u003Cli>Need HTTPS certificates.\u003C\u002Fli>\n\u003Cli>Run Docker containers.\u003C\u002Fli>\n\u003Cli>Self-host services at home.\u003C\u002Fli>\n\u003Cli>Want a central place to manage routing, security, and access control.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>For many self-hosted environments, a reverse proxy quickly becomes an essential part of the stack rather than an optional extra.\u003C\u002Fp>\n\n\n\u003Chr>\n\n\u003Ch1>\n  \u003Ca name=\"conclusion\" href=\"#conclusion\">\n  \u003C\u002Fa>\n  Conclusion\n\u003C\u002Fh1>\n\n\u003Cp>A reverse proxy is much more than a traffic router. It acts as the front door to your infrastructure, deciding where requests go, protecting your applications, managing HTTPS, balancing traffic, and improving performance through caching and compression.\u003C\u002Fp>\n\n\u003Cp>Whether you're running a single Raspberry Pi with a few services or a rack of servers in a data center, the underlying concept is the same:\u003C\u002Fp>\n\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Clients talk to the reverse proxy, and the reverse proxy talks to your applications.\u003C\u002Fstrong>\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\n\u003Cp>Once you understand this pattern, you'll notice it everywhere—from home labs and Docker setups to cloud platforms and some of the world's largest websites. It is one of the foundational building blocks of modern web infrastructure.\u003C\u002Fp>\n\n","Imagine walking into a large office building. You don't know which department handles your request, so you first stop at the reception desk.\n\nThe receptionist asks what you need, checks your request, and directs you to the correct department.\n\nA **reverse proxy** works exactly like that receptionist.\n\nInstead of exposing every application directly to the internet, all traffic first reaches the reverse proxy. The reverse proxy then decides where that request should go.\n\nIf you're running a home server, VPS, or Kubernetes cluster, understanding reverse proxies is one of the most valuable networking concepts you can learn.\n\nLet's dive in.\n\n---\n\n# What Is a Reverse Proxy?\n\nA reverse proxy is a server that sits **between clients and your backend applications**.\n\nInstead of users connecting directly to your services, they connect to the reverse proxy first.\n\n```text\nInternet\n     │\n     ▼\n+--------------------+\n|   Reverse Proxy    |\n+--------------------+\n        │\n ┌──────┼─────────┐\n │      │         │\n ▼      ▼         ▼\nJellyfin Immich  Nextcloud\n```\n\nThe client never talks directly to Jellyfin, Immich, or Nextcloud.\n\nEverything passes through the reverse proxy.\n\n---\n\n# Reverse Proxy vs Forward Proxy\n\nPeople often confuse these two.\n\n## Forward Proxy\n\nA forward proxy works **for the client**.\n\n```text\nYou\n │\n ▼\nForward Proxy\n │\n ▼\nInternet\n```\n\nExamples:\n\n- Corporate networks\n- School internet\n- VPNs\n- Anonymous browsing\n\nThe website sees the proxy—not you.\n\n## Reverse Proxy\n\nA reverse proxy works **for the server**.\n\n```text\nInternet\n     │\n     ▼\nReverse Proxy\n     │\n     ▼\nYour Applications\n```\n\nClients don't know which server actually handled the request.\n\n---\n\n# Why Not Just Open Every Port?\n\nSuppose your server runs:\n\n| Application | Port |\n|-------------|------|\n| Jellyfin | 8096 |\n| Immich | 2283 |\n| Nextcloud | 8080 |\n| Grafana | 3000 |\n| Portainer | 9443 |\n\nWithout a reverse proxy, you'd access them like this:\n\n```text\nhttps:\u002F\u002Fexample.com:8096\nhttps:\u002F\u002Fexample.com:2283\nhttps:\u002F\u002Fexample.com:8080\n```\n\nThat's messy.\n\nInstead, a reverse proxy lets you use:\n\n```text\nhttps:\u002F\u002Fmovies.example.com\nhttps:\u002F\u002Fphotos.example.com\nhttps:\u002F\u002Fcloud.example.com\nhttps:\u002F\u002Fgrafana.example.com\n```\n\nMuch cleaner.\n\n---\n\n# How a Reverse Proxy Routes Requests\n\nImagine someone opens:\n\n```text\nhttps:\u002F\u002Fmovies.example.com\n```\n\nThe request reaches your reverse proxy.\n\nThe reverse proxy checks:\n\n```http\nHost: movies.example.com\n```\n\nIt finds a rule:\n\n```text\nmovies.example.com\n      ↓\nhttp:\u002F\u002F192.168.1.20:8096\n```\n\nThe request is forwarded to Jellyfin.\n\nIf someone instead visits:\n\n```text\nhttps:\u002F\u002Fphotos.example.com\n```\n\nThe proxy routes it to:\n\n```text\nhttp:\u002F\u002F192.168.1.20:2283\n```\n\nwhich is your Immich server.\n\nThe client never notices this routing.\n\n---\n\n# A Real Example\n\nSuppose your home server hosts four services.\n\n```text\n192.168.10.10\n\n├── Jellyfin\n├── Immich\n├── Grafana\n└── Portainer\n```\n\nYou install Nginx Proxy Manager.\n\nDNS records:\n\n```text\nmovies.example.com\nphotos.example.com\ngrafana.example.com\nportainer.example.com\n```\n\nRouting table:\n\n```text\nmovies.example.com\n    ↓\nlocalhost:8096\n\nphotos.example.com\n    ↓\nlocalhost:2283\n\ngrafana.example.com\n    ↓\nlocalhost:3000\n\nportainer.example.com\n    ↓\nlocalhost:9443\n```\n\nEverything is now accessible using simple URLs.\n\n---\n\n# HTTPS Becomes Easy\n\nWithout a reverse proxy, every application must:\n\n- Generate certificates\n- Renew certificates\n- Configure HTTPS\n- Handle redirects\n\nThat's a lot of work.\n\nInstead:\n\n```text\nInternet\n    │ HTTPS\n    ▼\nReverse Proxy\n    │ HTTP\n    ▼\nApplications\n```\n\nThe reverse proxy handles:\n\n- SSL certificates\n- Let's Encrypt\n- Automatic renewal\n- HTTPS redirects\n\nYour backend applications can remain on HTTP inside your trusted local network.\n\n---\n\n# Security Benefits\n\nA reverse proxy isn't just about convenience.\n\nIt adds another security layer.\n\nIt can:\n\n- Hide internal IP addresses\n- Block malicious requests\n- Limit request rates\n- Require authentication\n- Restrict countries\n- Filter bad bots\n- Prevent direct access to services\n\nYour applications become much harder to attack.\n\n---\n\n# Load Balancing\n\nSuppose one server isn't enough.\n\nInstead of one backend:\n\n```text\nApp Server 1\nApp Server 2\nApp Server 3\n```\n\nThe reverse proxy distributes traffic.\n\n```text\nClient 1 → Server 1\n\nClient 2 → Server 2\n\nClient 3 → Server 3\n```\n\nBenefits:\n\n- Higher availability\n- Better performance\n- Fault tolerance\n\nLarge websites rely heavily on this.\n\n---\n\n# Caching\n\nImagine your homepage receives thousands of requests.\n\nInstead of asking your application every time:\n\n```text\nUser\n  │\n  ▼\nReverse Proxy\n  │\nCache Exists?\n  │\n Yes ─────► Return Cached Page\n  │\n No\n  ▼\nApplication\n```\n\nStatic content like:\n\n- Images\n- CSS\n- JavaScript\n- Fonts\n\ncan be served directly from the reverse proxy.\n\nThis greatly reduces application load.\n\n---\n\n# Compression\n\nModern reverse proxies can compress responses.\n\nInstead of sending:\n\n```text\nHTML\nCSS\nJavaScript\n```\n\nuncompressed, they use:\n\n- Gzip\n- Brotli\n\nSmaller responses mean:\n\n- Faster websites\n- Lower bandwidth usage\n- Better user experience\n\n---\n\n# WebSockets and Streaming\n\nApplications like:\n\n- Jellyfin\n- Home Assistant\n- Immich\n- VS Code Server\n\nuse persistent connections.\n\nReverse proxies understand WebSockets and keep these connections alive while still handling routing and HTTPS.\n\n---\n\n# Popular Reverse Proxy Software\n\n| Software | Best For |\n|-----------|----------|\n| Nginx | High performance and flexibility |\n| Nginx Proxy Manager | Easy web interface for beginners |\n| Traefik | Docker and Kubernetes integration |\n| HAProxy | High-performance load balancing |\n| Caddy | Automatic HTTPS with minimal configuration |\n| Envoy | Large-scale microservices and cloud-native deployments |\n\nEach has its strengths, but for many self-hosters, **Nginx Proxy Manager** provides an excellent balance of simplicity and features.\n\n---\n\n# Common Mistakes\n\nMany beginners accidentally:\n\n- Expose application ports directly to the internet.\n- Skip HTTPS entirely.\n- Open unnecessary firewall ports.\n- Forget to configure `X-Forwarded-For` and `X-Forwarded-Proto` headers.\n- Leave administrative interfaces like Portainer publicly accessible without authentication.\n- Mix internal and external DNS records in ways that create routing issues.\n\nTaking time to configure your reverse proxy correctly can prevent these problems.\n\n---\n\n# When Do You Need a Reverse Proxy?\n\nYou probably need one if you:\n\n- Host more than one web application.\n- Want friendly domain names instead of port numbers.\n- Need HTTPS certificates.\n- Run Docker containers.\n- Self-host services at home.\n- Want a central place to manage routing, security, and access control.\n\nFor many self-hosted environments, a reverse proxy quickly becomes an essential part of the stack rather than an optional extra.\n\n---\n\n# Conclusion\n\nA reverse proxy is much more than a traffic router. It acts as the front door to your infrastructure, deciding where requests go, protecting your applications, managing HTTPS, balancing traffic, and improving performance through caching and compression.\n\nWhether you're running a single Raspberry Pi with a few services or a rack of servers in a data center, the underlying concept is the same:\n\n> **Clients talk to the reverse proxy, and the reverse proxy talks to your applications.**\n\nOnce you understand this pattern, you'll notice it everywhere—from home labs and Docker setups to cloud platforms and some of the world's largest websites. It is one of the foundational building blocks of modern web infrastructure.",{"name":31,"username":32,"twitter_username":33,"github_username":34,"user_id":35,"website_url":36,"profile_image":37,"profile_image_90":38},"Mohamad Ashraful Islam","ashraful","_ashraful","iashraful",30490,"https:\u002F\u002Fashraful.dev","https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=640,height=640,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30490%2F9dc1ef64-0233-43b5-9127-79affd83cc43.jpg","https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=90,height=90,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30490%2F9dc1ef64-0233-43b5-9127-79affd83cc43.jpg",1784633123717]