> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Two Containers Behind a Load Balancer

> Demonstrates running two backend containers behind an NGINX load balancer to observe request distribution and failover when one container stops.

This lab demonstrates running a small app in two backend containers behind an NGINX load balancer. You will:

* Start two app containers from the same image.
* Send multiple requests to the load balancer at `localhost:8080` and observe how requests are distributed.
* Stop one backend container while requests are being served and observe failover to the remaining container.

<Callout icon="lightbulb" color="#1CB2FE">
  This lab assumes an NGINX-based load balancer is already configured to proxy requests from `localhost:8080` to the two backend app containers. For a refresher, see [Introduction to NGINX](https://learn.kodekloud.com/user/courses/introduction-to-nginx).
</Callout>

## What you'll observe

* Requests to `localhost:8080` are proxied by NGINX to one of the two app containers.
* NGINX performs simple load distribution between the backends (round-robin or similar, depending on config).
* If one backend stops, NGINX continues to forward requests to the remaining healthy container, keeping the service available.

## Quick step-by-step

1. Launch two app containers (they both use the same image).
2. Confirm each container is running.
3. Send multiple `curl` requests to the load balancer and observe responses from each backend.
4. Stop one backend and continue sending requests to observe failover.

## Commands and examples

Start both containers:

```bash theme={null}
# Start two app containers (both use the same image)
docker run -d --name app1 photoapp:v1
docker run -d --name app2 photoapp:v1
# Example output: b7e2d1...
```

Send requests to the load balancer on port 8080:

```bash theme={null}
# Send requests to the load balancer
curl localhost:8080
curl localhost:8080
# Example response: Hello from app2
```

Simulate failover by stopping one backend while requests are ongoing:

```bash theme={null}
# Stop one backend container
docker stop app1

# Requests should continue and be routed to the remaining container
curl localhost:8080
# Example response: Hello from app2
```

## Commands reference

| Task                     |                                 Command | Notes / Example output                                                   |
| ------------------------ | --------------------------------------: | ------------------------------------------------------------------------ |
| Run first app container  | `docker run -d --name app1 photoapp:v1` | Starts `app1` in detached mode; sample container ID `a1f3c9...`          |
| Run second app container | `docker run -d --name app2 photoapp:v1` | Starts `app2`; sample container ID `b7e2d1...`                           |
| Query load balancer      |                   `curl localhost:8080` | Response shows which backend served the request, e.g., `Hello from app1` |
| Stop a backend           |                      `docker stop app1` | Takes `app1` offline; NGINX should then route requests to `app2`         |

<Callout icon="warning" color="#FF6B6B">
  Make sure container names (e.g., `app1`, `app2`) match the backend upstream configuration in your NGINX proxy, and that the load balancer is listening on `localhost:8080`. If NGINX isn’t configured correctly, requests will not be forwarded to your containers.
</Callout>

## Troubleshooting tips

* If `curl localhost:8080` returns a connection refused error, validate that NGINX is running and listening on port 8080:
  * `ss -ltnp | grep 8080` or `docker ps` (if NGINX is containerized).
* If responses always come from the same backend, inspect the NGINX upstream configuration to confirm the load-balancing method.
* Use `docker logs <container>` to see app-specific output if you don’t get the expected `Hello from ...` responses.

## Links and references

* [Introduction to NGINX](https://learn.kodekloud.com/user/courses/introduction-to-nginx)
* Docker documentation: [https://docs.docker.com/](https://docs.docker.com/)
* NGINX upstream module reference: [https://nginx.org/en/docs/http/ngx\_http\_upstream\_module.html](https://nginx.org/en/docs/http/ngx_http_upstream_module.html)

This exercise shows how NGINX maintains availability by routing traffic to the remaining healthy backend when one container is taken down.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/system-design-for-beginners/module/df166cca-6100-4b0c-af69-1c80618a63c1/lesson/cf5f79dd-4231-449a-ac1a-357d65d1c399" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/system-design-for-beginners/module/df166cca-6100-4b0c-af69-1c80618a63c1/lesson/8f843c54-252a-4195-a75a-acbbdc090246" />
</CardGroup>
