# Understanding Docker Volumes: Persisting Data Beyond Containers

`A practical guide to storing application data using Docker Volumes.`

### Introduction

Containers are designed to be temporary and disposable. This raised an important question:

> What happens to application data when a container is removed?

To understand this concept, I built a simple Flask application that stores a visitor counter in a file. I then tested what happens with and without Docker Volumes.

In this article, I'll explain how Docker Volumes help preserve data even when containers are deleted and recreated.

### The Problem

Example:

![](https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/1c3ca111-093c-4ac2-9c05-039d8e36365c.png align="center")

If the container is removed:

```shell
docker rm -f mycontainer
```

the data disappears as well.

For applications such as:

*   Databases
    
*   Log storage
    
*   User uploads
    
*   Application configuration
    

This behaviour is not desirable.

### What is a Docker Volume?

A Docker Volume is a storage mechanism managed by Docker.

Rather than storing data inside the container, data is stored separately on the host.

![](https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/5102f542-b7c0-45b6-9081-95c0a7c1884e.png align="center")

Because the volume exists independently of the container, the data remains available even after the container is removed.

### Project Architecture

![](https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/2e47ef6f-2a42-47e2-bbab-fb3934309c34.png align="center")

The application stores a simple visit counter inside a file located in a Docker Volume.

### Project Structure

![](https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/88e22c9a-36bf-4d4e-acd9-d2dc6aa487e4.png align="center")

### Step 1: Create the Flask Application

Create [`app.py`](http://app.py).

```shell
from flask import Flask
import os

app = Flask(__name__)

COUNTER_FILE = "/data/counter.txt"

@app.route('/')
def home():

    if not os.path.exists(COUNTER_FILE):
        with open(COUNTER_FILE, "w") as f:
            f.write("0")

    with open(COUNTER_FILE, "r") as f:
        count = int(f.read())

    count += 1

    with open(COUNTER_FILE, "w") as f:
        f.write(str(count))

    return f"""
    <h1>CloudOps Chronicle</h1>
    <h2>Docker Volume Demo</h2>
    <h3>Visits: {count}</h3>
    """

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
```

Each time the page is accessed, the counter value increases and is written to a file.

### Step 2: Create requirements.txt

```shell
flask
```

### Step 3: Create the Dockerfile

```shell
FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

RUN mkdir /data

EXPOSE 5000

CMD ["python", "app.py"]
```

Build the image:

```shell
docker build -t flask-volume:v1 .
```

Testing Without a Volume

```shell
docker run -d \
--name flask-volume-test \
-p 5000:5000 \
flask-volume:v1
```

Access the application:

```shell
curl http://localhost:5000
```

Example:

```shell
Visits: 1
Visits: 2
Visits: 3
```

Now remove the container:

```shell
docker rm -f flask-volume-test
```

Start it again:

```shell
docker run -d \
--name flask-volume-test \
-p 5000:5000 \
flask-volume:v1
```

The counter starts again from:

`Visits: 1`

The data was lost.

### Creating a Docker Volume

Create a volume:

```shell
docker volume create visit-data
```

Verify:

```shell
docker volume ls
```

### Running With a Volume

Start the container again, this time mounting the volume.

```shell
docker run -d \
--name flask-volume-test \
-p 5000:5000 \
-v visit-data:/data \
flask-volume:v1
```

The `-v` option maps the Docker Volume to the `/data` directory inside the container.

### Verify Data Persistence

Access the application several times:

![](https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/d4727dd7-113a-4fee-b9a7-c35a48ee6480.png align="center")

Now remove the container:

```shell
docker rm -f flask-volume-test
```

Create it again:

```shell
docker run -d \
--name flask-volume-test \
-p 5000:5000 \
-v visit-data:/data \
flask-volume:v1
```

Access the application:

![](https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/9522ee34-dc31-4de4-b9f3-49e267c7c435.png align="center")

The counter continues from the previous value.

Success!

The data survived because it was stored inside the Docker Volume rather than inside the container.

### Inspecting the Volume

List volumes:

```shell
docker volume ls
```

Inspect the volume:

```shell
docker volume inspect visit-data
```

This shows where Docker stores the volume data on the host system.

### Conclusion

Docker containers are designed to be temporary, but application data should not be.

Docker Volumes provide a simple and effective way to persist data beyond the lifecycle of a container.

Happy Learning!
