4.3Advanced networks and reverse proxy
The essentials in 30 seconds
- Segment by function: a frontend network (proxy to applications) and a backend network (applications to databases) — the database, confined to backend, stays directly unreachable even if the proxy is compromised.
- A single published port, everything else routed: the reverse proxy (frontend) is the only published one and routes by hostname — applications only expose internally and are reached by their names.
- Idir's reflex: adding a service = one routing entry, zero extra ports — proxy config mounted read-only.
Threaded mini-case — Idir tidies messy ports behind a frontend
Idir, junior DevOps in Algiers, manages two applications each publishing their own port: the URLs are unreadable and the database is reachable from the frontend network. He creates two networks (frontend and backend), only publishes the proxy's port, routes by hostnames and confines the database to backend. Third milestone of the thread: a single entry point, segmented services, zero messy ports.
Sequel of cases 4.1-4.2 — Idir's hardened services are now cleanly exposed.
1. Segmenting: one network per function
Beyond a single network, segment: frontend (proxy to applications) and backend (applications to databases). A service belongs to several networks if needed; a database is only on backend: even if the proxy is compromised, it stays directly unreachable.
Segmentation is concrete isolation: each network only sees what it must see. Idir places each service according to what it must reach — and nothing else.
2. The reverse proxy: one port for all
Traefik or Nginx as frontend: only its port 80/443 is published, it routes by hostname (each host to its service). Applications publish nothing any more: they expose internally and the proxy reaches them by names. One entry point, N services — adding an application is one routing entry.
Nginx (explicit config, perfect for learning) and Traefik (automatic discovery, ideal when services move) apply the same pattern: Idir starts simple with an explicit config.
3. Locally: clean names, future certificates
In development, declare hosts in the hosts file (each name to the local machine); in production, DNS + TLS encrypt traffic. Remember the pattern: only one published, everything else routed.
And the proxy config is mounted read-only: the container reads it without being able to rewrite it.
🔎 Concrete example — 🔎 Concrete example — Two apps behind Nginx
Idir's frontend: only the proxy publishes port 80.
services:
proxy:
image: nginx:1.27
ports: ["80:80"]
volumes: [./proxy.conf:/etc/nginx/conf.d/default.conf:ro]
networks: [frontal]
app1:
image: nginx:1.27
networks: [frontal]
app2:
image: nginx:1.27
networks: [frontal]
networks:
frontal:
backend:
Reading: only the proxy publishes port 80; applications are only visible through it.
Lesson: adding a third application = one routing entry, zero extra ports.
Section vocabulary
- Reverse proxy
- Frontend receiving requests and ROUTING them to the right services by hostname.
Simple example: Idir's proxy sends each host to its application.
What it is not: publishing each application port to the outside.
Reflex: several services, one port: set up a frontend.
- Segmentation
- Splitting into NETWORKS BY FUNCTION (frontend, backend) to isolate flows.
Simple example: Idir confines his database to backend, unreachable from the entry.
What it is not: a single network where everything sees everything.
Reflex: database: never on the frontend network.
- Host-based routing
- Each HOSTNAME is directed to its service (one host = one application).
Simple example: Each of Idir's applications has its name, routed by the proxy.
What it is not: a different tinkered port per application.
Reflex: new service: a routing entry, not a port.
- EXPOSE
- INTERNAL declaration of a port, without publishing to the outside.
Simple example: Idir's applications expose internally; only the proxy publishes.
What it is not: a port publication accessible from the machine.
Reflex: behind a proxy: expose, don't publish.
In practice — In practice — Setting up a frontend
- Create the frontend and backend networks.
- Run two unpublished applications on frontend.
- Run the published proxy with host-based routing.
- Test both hosts, then cut one backend: the other survives.
Ready-to-say script — justifying the frontend to the team (30 s)
“This is Idir: instead of one port per application, we only expose the proxy and it routes by names. Applications are no longer directly reachable, the database stays confined to its network, and the next application will only cost one routing line.”
Say when “one more port” is suggested again: show the current port list.
Copy-paste template — Nginx frontend + networks (Compose)
services:
proxy:
image: nginx:1.27
ports: ["80:80"]
volumes: [./proxy.conf:/etc/nginx/conf.d/default.conf:ro]
networks: [frontal]
app1:
image: nginx:1.27
networks: [frontal]
app2:
image: nginx:1.27
networks: [frontal]
networks:
frontal:
backend:
Second application
Like Idir: one more routing entry, no extra published port.
Frequently moving services
Switch to Traefik: automatic service discovery, same single-frontend pattern.
Database to protect
Database confined to backend, reached by name from applications: unreachable from the entry.
Local development
Names declared in the hosts file: the same frontend file serves locally then in production.
✓ Best practices
- Only one published: the proxy.
- Routes by explicit hostnames.
- Proxy config as read-only mount.
✗ Common pitfalls
- Publishing each application (messy ports).
- Database on the frontend network.
- Proxy config writable from the container.
Key takeaways
- Segment: frontend vs backend.
- One published proxy routes everything.
- Unpublished apps, reached by names.
- TLS in prod, hosts in dev.
48h challenge — apply tomorrow
Behind a single published proxy: expose 2 unpublished applications routed by hosts, database confined to backend, config read-only.
- I can segment into frontend and backend networks.
- I can publish only the proxy and route by hosts.
- I can confine the database and mount the config read-only.
Frequently asked questions
Traefik or Nginx?
Nginx: explicit config, perfect for learning. Traefik: automatic discovery via labels, ideal when services move. Both apply the same pattern: only one published, routing by hosts.
Do you need a proxy in dev?
From two applications on: yes, even a simple one. It is the same file that will serve in production, without messy ports.
Three web apps on one machine, a single port 80. What do you do?