Learn advanced Docker concepts including persistent data storage with volumes, application configuration with environment variables, container monitoring, and linking multiple containers using Docker networks.
By default, data inside a container is ephemeral (lost when the container is removed). Volumes provide a way to safely persist data.
docker run -d -v /app/data --name web1 nginx
docker volume create mydata
docker run -d -v mydata:/app/data --name web2 nginx
docker volume ls

Bind mounts attach a specific directory on your host machine to a directory inside the container.
mkdir myapp-data
docker run -d -v ${PWD}/myapp-data:/app/data --name web3 nginx
echo "From Host" > myapp-data/host-file.txt
docker exec web3 cat /app/data/host-file.txt

Environment variables allow us to pass configuration parameters into the container at runtime.
We built a custom Flask application that returns configuration data via a /config API endpoint.
app.py
import os
from flask import Flask
app = Flask(__name__)
db_host = os.environ.get('DATABASE_HOST', 'localhost')
debug_mode = os.environ.get('DEBUG', 'false').lower() == 'true'
api_key = os.environ.get('API_KEY')
@app.route('/config')
def config():
return {
'db_host': db_host,
'debug': debug_mode,
'has_api_key': bool(api_key)
}
if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port, debug=debug_mode)
Dockerfile
FROM python:3.9-slim
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
ENV PORT=5000
ENV DEBUG=false
EXPOSE 5000
CMD ["python", "app.py"]
docker build -t flask-env-app .
docker run -d --name flask-app -p 5000:5000 \
-e DATABASE_HOST="prod-db.example.com" \
-e DEBUG="true" \
-e API_KEY="secret-xyz" \
flask-env-app

We can verify that the environment variables were successfully passed into the running container.
docker exec flask-app printenv DATABASE_HOST
curl http://localhost:5000/config

Monitoring allows us to keep track of resource usage, running processes, and application logs.
docker stats --no-stream
docker top flask-app
docker logs flask-app

We can automate these checks using a bash script (monitor.sh):
monitor.sh
#!/bin/bash
echo "=== Docker Monitoring Dashboard ==="
echo "Time: $(date)"
echo "1. Running Containers:"
docker ps --format "table \t\t"
echo "2. Resource Usage:"
docker stats --no-stream --format "table \t\t"
echo "3. Recent Events:"
docker events --since '5m' --until '0s' | tail
echo "4. System Info:"
docker system df
Docker networks allow isolated containers to securely communicate with each other.
We created a custom bridge network and attached two Nginx containers to it.
docker network create my-network
docker run -d --name net-web1 --network my-network nginx
docker run -d --name net-web2 --network my-network nginx

Because they share a custom network, containers can communicate with each other using their container names as DNS addresses.
docker exec net-web1 curl -s http://net-web2

In a real-world scenario, we often have an application connected to a database and a cache layer, all residing on the same network.
docker network create myapp-network
docker run -d --name postgres --network myapp-network \
-e POSTGRES_PASSWORD=mysecretpassword \
-v postgres-data:/var/lib/postgresql/data postgres:15
docker run -d --name redis --network myapp-network \
-v redis-data:/data redis:7-alpine

docker ps
docker stats --no-stream postgres redis

docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
docker volume prune -f
docker network prune -f

| Command | Description |
|———|————-|
| docker volume create <name> | Create a named volume |
| docker run -v <volume>:/path | Mount named volume |
| docker run -v /host:/container | Mount local bind |
| Command | Description |
|———|————-|
| docker run -e VAR=value | Inject single variable |
| docker run --env-file .env | Inject multiple from file |
| Command | Description |
|———|————-|
| docker stats | Live resource usage |
| docker top <container> | process list inside container |
| docker logs -f <container> | Follow container logs |
| Command | Description |
|———|————-|
| docker network create <name> | Create custom network |
| docker run --network <name> | Run container on network |
| Previous | Home | Next |
|---|---|---|
| ← Lab 4 | Main README | Lab 6 → |