0
0
DockerHow-ToBeginner · 4 min read

How to Use Volumes in Docker Compose for Data Persistence

In docker-compose.yml, use the volumes key to define storage that persists data outside containers. You can mount host directories or named volumes inside containers by specifying paths under services and volumes sections.
📐

Syntax

The volumes section in docker-compose.yml defines named volumes or host paths. Under each service, you specify volumes to mount these into container paths.

  • Named volume: A volume managed by Docker, declared under volumes: at root.
  • Host path: A directory on your machine, mounted directly into the container.
  • Container path: The location inside the container where the volume is mounted.
yaml
version: '3.8'
services:
  service_name:
    image: example-image
    volumes:
      - volume_name:/container/path
      - ./host/path:/container/path
volumes:
  volume_name: {}
💻

Example

This example shows a web service using a named volume to persist database files and a host directory to serve static files. The named volume keeps data safe even if the container is removed.

yaml
version: '3.8'
services:
  web:
    image: nginx:alpine
    volumes:
      - static_content:/usr/share/nginx/html
      - ./config/nginx.conf:/etc/nginx/nginx.conf:ro
  db:
    image: postgres:15
    volumes:
      - db_data:/var/lib/postgresql/data
volumes:
  static_content: {}
  db_data: {}
Output
docker-compose up -d # Containers start with volumes mounted # Data in db_data persists across container restarts # Static files served from host ./config directory
⚠️

Common Pitfalls

  • Forgetting to declare named volumes: Named volumes must be listed under the volumes: root key or Docker will create anonymous volumes.
  • Incorrect host path: Relative paths are relative to the docker-compose.yml location; wrong paths cause errors or empty mounts.
  • Permission issues: Host directory permissions can block container access; ensure proper read/write rights.
  • Using latest tag: Avoid using latest for images to prevent unexpected changes affecting volumes.
yaml
version: '3.8'
services:
  app:
    image: alpine
    volumes:
      - missing_volume:/data
volumes:
  # missing_volume is not declared here, Docker creates anonymous volume instead

# Correct way:
volumes:
  missing_volume: {}
📊

Quick Reference

Remember these tips when using volumes in Docker Compose:

  • Define named volumes under volumes: at root.
  • Mount volumes under each service with service_name:volumes:.
  • Use host_path:container_path for host directory mounts.
  • Use volume_name:container_path for named volumes.
  • Use :ro suffix for read-only mounts.

Key Takeaways

Define volumes under the root volumes: key to create named volumes.
Mount volumes inside services using volumes: with volume_name:container_path or host_path:container_path syntax.
Use named volumes to persist data beyond container life and host paths to share files with the host system.
Check paths and permissions carefully to avoid mount errors or access issues.
Add :ro to mounts to make them read-only inside containers.