# 🔧 Optimize Web Performance: Deploy NGINX and Redis Cache Using Docker Compose 🌟

To set up a Nginx web application with a Redis cache using Docker Compose on an EC2 instance.

### Overview

In this task, we will set up a web application using the NGINX image with Redis caching. Redis is a fast, in-memory key-value store, commonly used to temporarily store frequently accessed data. This improves web app performance by reducing the load on the main database. We'll configure Redis for external access and troubleshoot any connectivity issues.

What is Redis Cache?

* Redis cache is an in-memory data store that temporarily holds data. It speeds up web apps by storing frequently accessed data, reducing the need to retrieve data from slower databases every time.
    

### How Redis Cache Works:

1. **Web App:** When a user requests data (e.g., a product list), the app first checks Redis for cached data.
    
2. **Cache Hit:** If Redis has the data, it's quickly returned.
    
3. **Cache Miss:** If Redis doesn’t have the data, the app retrieves it from the database, caches it in Redis for future requests, and returns it to the user.
    

### Why Use Redis Cache with a Web App?

* **Speed:** Fetching data from Redis (memory) is faster than querying a database (disk).
    
* **Efficiency:** Redis reduces the load on the database by caching repeated requests, making the application more scalable.
    

### Prerequisites

1. **Docker** and **Docker Compose** installed on your EC2 instance.
    
2. **Security group rules** allowing inbound traffic to your EC2 instance on port `6379` (for Redis).
    
3. **Basic knowledge** of Docker, Docker Compose, and Redis.
    

![What Is Redis Cache – NBKomputer](https://linuxiac.b-cdn.net/wp-content/uploads/2021/06/redis-how-it-works.png align="left")

### Steps

#### 1\. **Create the Docker Compose File**

Create a `docker-compose.yml` file with the following content:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725633673780/30ce06c8-5617-4527-b4f2-bf3e06c96ee4.png align="center")

* `web` (NGINX container): It serves a web application, and it's exposed on port `8080` on your docker host.
    
* `redis` (Redis container): This is your Redis cache service, exposed on port `6379` on your docker host.
    
* `depends_on`: The `web` service (NGINX) depends on Redis, so Docker Compose will ensure that **Redis starts before the web container.**
    

Run `docker-compose up` in the terminal.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725596738863/de9e2ea5-d425-4a0f-9690-347cb0692b58.png align="left")

Access [http://&lt;ec2 IP address&gt;:8080](http://localhost:8080) to see the Nginx web server running inside the container.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725597086244/c5d10a52-489c-498f-8af8-ea6b539a23a4.png align="left")

### Issue Encountered with Redis

While we were able to access the NGINX web server using `<EC2_PUBLIC_IP>:8080`, we could not access Redis on `<EC2_PUBLIC_IP>:6379` via a browser.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725632307693/f6408d5c-7f37-404a-bf96-d5abe80ece00.png align="center")

### Troubleshooting Steps

1. **Check Running Containers: <mark>docker ps</mark>**
    

To confirm if Redis and NGINX containers were running and had the correct port mappings.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725634123308/632c773f-a959-4512-abac-2b40d689848f.png align="center")

2. **Verify Port Mapping:**
    

* We reviewed the `docker-compose.yml` to ensure the Redis container was mapped correctly on port `6379`. The mapping was correct.
    

3. **EC2 Security Group Configuration:**
    

Checked the inbound rules of the EC2 instance's security group to ensure it allowed traffic on port `6379` from anywhere (`0.0.0.0/0`).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725634190149/1007186a-9fc9-47c0-b80a-dc929b71fa72.png align="center")

Inspect Redis Container Logs:

Command: <mark>docker-compose logs redis</mark>

The logs showed that Redis was bound to `127.0.0.1`, restricting external access.

**Test Redis Connectivity from EC2 Instance:**

From within the EC2 instance, test if Redis is accessible on port:

Command: <mark>telnet </mark> [<mark>localhost</mark>](http://localhost) <mark>6379</mark>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725634807012/1c895e44-2223-44c5-bee6-b32b3ca7550a.png align="left")

**Check Redis Configuration:**

* By default, Redis binds to `127.0.0.1`. To allow external access, we needed to configure Redis to bind to `0.0.0.0`.
    
* We confirmed this by checking the Redis configuration file.
    

### Fix: Creating a Custom Redis Configuration

1. **Create Redis Configuration File:**
    

Created a file named `redis.conf` in the EC2 instance's `/home/ubuntu` directory &lt;`create in your project directory or any other directory you prefer`\&gt;

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725635211696/cb45f7ab-c99b-4cc6-8057-557099435936.png align="left")

Command: <mark>sudo vi /home/ubuntu/redis.conf</mark>

2. Add the following configurations:
    

```plaintext
bind 0.0.0.0
protected-mode no
```

* `bind 0.0.0.0`: Allows Redis to accept connections from any network interface.
    
* `protected-mode no`: Disables protected mode to allow external connections.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725636000874/6f62ac95-2f1d-4219-8746-d36a72cff93d.png align="left")

3. Update `docker-compose.yml` to Use Custom Configuration:
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725635721024/d71d7308-8229-4c99-a35f-5b91b711e821.png align="center")

* **volumes**: Maps the local `redis.conf` to `/usr/local/etc/redis/redis.conf` inside the Redis container.
    
* **command**: Instructs Redis to start with the custom configuration.
    

### Restart Docker Compose

After updating the `docker-compose.yml` file, we restarted the Docker containers to apply the changes.

**Stop and Remove Existing Containers:**

Command: **<mark>docker-compose down</mark>**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725636197396/c74ff661-08f1-4d32-a6f7-40e4447046f6.png align="left")

**Start Containers in Detached Mode:**

Command: **<mark>docker-compose up -d</mark>**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725636260707/b399e040-bb54-4633-8d85-bbffabdde672.png align="left")

### Verify External Access to Redis

Now that Redis was configured to bind to all network interfaces, we verified external access:

1. **Test Connection to Redis:**
    
    * From the local machine, we tested Redis connectivity using the EC2 public IP
        

Command: **<mark>redis-cli -h &lt;EC2_PUBLIC_IP&gt; -p 6379</mark>**

Replace &lt;EC2\_PUBLIC\_IP&gt; with your actual EC2 public IP address

Once connected, you should see a prompt like this `44.211.216.152:6379>`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725636426745/d94a4338-8da6-447c-9a6c-5023fcdcb4d9.png align="center")

Redis commands to run:

* **Check for Keys**: `KEYS *` : This command lists all the keys currently stored in Redis. It's a way to check if there are any stored key-value pairs in Redis at the moment. Running `KEYS *` will display all keys, helping you see what data is cached.
    
* **Set a Key-Value Pair**: `SET mykey "Hello, Redis!"`: This command stores a key (`mykey`) with the value `"Hello, Redis!"` in Redis. It's an example of how Redis can cache data. The key-value pair is stored in memory and can be quickly retrieved later, demonstrating the cache functionality.
    
* **Retrieve a Key-Value Pair**: `GET mykey`: This command retrieves the value associated with the key `mykey`. In this case, it will return `"Hello, Redis!"`. This demonstrates how data can be fetched quickly from Redis once it has been cached, without having to query the main database.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725637186754/6b151780-9286-48b1-8608-b641c3e08521.png align="center")

### Conclusion

In this project, we successfully set up a web application with NGINX and Redis cache using Docker Compose. The system is designed to allow the web server to first check Redis for cached data before accessing the main database (not configured in this task). We resolved an issue where Redis wasn't externally accessible by configuring it to bind to all interfaces, making it reachable via the EC2 public IP. Finally, we verified Redis was functioning correctly by testing key-value operations.

This project demonstrates the basics of setting up a web and caching layer, ensuring proper configuration for external access and smooth operation.
