← Back to Apache Course | Chapter 3: Modules | Lesson 3 of 5

mod_proxy

mod_proxy lets Apache forward requests on to another server -- typically an application server like Gunicorn, Node.js, or a backend on a different machine -- and hand the response back as if Apache had generated it itself.

Forward vs. Reverse Proxy

A forward proxy sits in front of clients, fetching the internet on their behalf (like a corporate proxy). A reverse proxy sits in front of servers, receiving requests from the public internet and forwarding them to a backend the public never talks to directly. mod_proxy is almost always used the second way with Apache, covered in full in the dedicated Reverse Proxy lesson later in this course.

Enabling the Right Sub-Modules

mod_proxy itself is the base module, but you also need a protocol-specific one: mod_proxy_http for HTTP/HTTPS backends, or mod_proxy_wstunnel for WebSocket connections. On Ubuntu: sudo a2enmod proxy proxy_http (add proxy_wstunnel too if needed).

ProxyPass and ProxyPassReverse

ProxyPass "/api/" "http://127.0.0.1:8000/" forwards any request under /api/ to that backend address. ProxyPassReverse does the matching job in the other direction: it rewrites Location/Set-Cookie headers coming back from the backend so they reference the public-facing URL instead of the internal one, which matters for redirects and cookies to work correctly.

A Typical Use Case

A very common pattern: run a Python (Gunicorn/uWSGI) or Node.js app listening only on 127.0.0.1:8000, not exposed to the internet at all, and let Apache on port 80/443 be the only thing the public actually reaches -- handling TLS, static files, and logging, then proxying dynamic requests through to the app.

Note: Always pair ProxyPass with ProxyPassReverse for the same path -- ProxyPass alone forwards the request fine, but leaves any redirect the backend sends pointing at the wrong (internal) address.

Example: Proxying /api/ to a local backend

apacheconf
ProxyPreserveHost On
ProxyPass "/api/" "http://127.0.0.1:8000/"
ProxyPassReverse "/api/" "http://127.0.0.1:8000/"
{# Flagged by hand after confirming a runner can't handle this example (a shell command / go.mod file stored as a TopicExample, a language feature the configured runner version doesn't support, or output that blows a runner's sandbox limit) -- see TopicExample.norun. Never render the run button for these, regardless of language, since it would just fail at execute_code (or worse, hang the Judge0 queue on a submission that can never finish cleanly). #}

⚠️ This example can't run in the browser editor. Try it in your own local environment instead.

{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Enabling mod_proxy but forgetting mod_proxy_http, so plain HTTP/HTTPS proxying doesn't actually work.
  2. Using ProxyPass without a matching ProxyPassReverse, breaking redirects or cookies coming back from the backend.
  3. Exposing the backend app server's port directly to the internet in addition to proxying it through Apache, defeating the point of putting Apache in front of it.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.