-
1.1. Key Principles
1.2. Storage Solutions
-
2.1. Volume Management
2.2. Named Volumes
2.3. Volume Commands
-
3.1. Basic Usage
3.2. Development Workflow
-
Immutable Infrastructure
- Containers should never be changed, only re-deployed
- Ensures consistency and reproducibility
- Simplifies rollback and version control
-
Separation of Concerns
- Application binaries should be separate from data
- Unique data should not be mixed with application code
- Enables independent lifecycle management
Docker provides two main solutions for persistent data:
Solution | Description |
---|---|
Data Volumes | Special location outside container UFS (unique file system) |
Bind Mounts | Direct mapping between container path and host path |
Docker Storage Types Comparison
Feature | Volumes | Bind Mounts |
---|---|---|
Storage Location | Managed by Docker (/var/lib/docker/volumes/ ) |
Anywhere on host filesystem |
Content Population | New volume has contents of container image | Empty directory in the host |
Management | Docker CLI commands and APIs | Host filesystem commands |
Permissions | Can be modified by Docker container processes | Can be modified by both host and container processes |
Portability | High (easily movable between containers) | Low (dependent on host filesystem structure) |
Performance | Optimized for container storage | Depends on host filesystem |
OS Support | Works the same on all platforms | May have issues with file paths between OS |
Initialization | Can be pre-populated with container content | Empty by default unless files exist at mount point |
Sharing | Can be easily shared between containers | Must be manually shared via host filesystem |
Backup | Can be backed up using Docker commands | Must be backed up using host filesystem tools |
Best Used For | - Production database storage - Application data persistence - Container data sharing - Docker-managed backups |
- Local development - Source code mounting - Configuration files - Build artifacts |
Example Command | docker run -v mysql-data:/var/lib/mysql mysql |
docker run -v /home/user/code:/app node |
Access from Host | Requires Docker commands to access | Direct access through host filesystem |
Creation in Dockerfile | Can be declared with VOLUME instruction | Cannot be declared in Dockerfile |
Runtime Overhead | Minimal | Slightly higher due to filesystem translation |
Behavior on Container Deletion | - Volume persists - Must be explicitly deleted using docker volume rm - Data remains until volume is manually removed - Can be reused by new containers |
- Mount point remains on host - All data remains in host filesystem - No cleanup needed - Files remain accessible on host |
Cleanup Command | docker volume rm <volume_name> or docker volume prune |
Normal filesystem commands (rm, del, etc.) |
- Volumes persist after container removal
- Require manual deletion
- Managed through dedicated volume commands
- Can be shared between containers
Command | Description |
---|---|
docker volume ls |
Lists all volumes |
docker volume inspect <volume-name> |
Shows volume details |
docker volume prune |
Removes unused volumes |
- Check official image repositories on GitHub:
Example VOLUME declarations:
Image | Volume Location |
---|---|
MySQL | VOLUME /var/lib/mysql |
PostgreSQL | VOLUME /var/lib/postgresql/data |
MongoDB | VOLUME /data/db |
Note: The VOLUME instruction creates a mount point and marks it for external storage
VOLUME /var/lib/mysql
- Creates new volume location when container starts
- Files in this location outlive the container
- Requires manual cleanup
Command | Description |
---|---|
docker container run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=True -v mysql-db:/var/lib/mysql mysql |
Creates container with named volume |
docker container run -d --name mysql3 -e MYSQL_ALLOW_EMPTY_PASSWORD=True -v mysql-db:/var/lib/mysql mysql |
Reuses existing named volume |
docker container run -d --name postgres -e POSTGRES_PASSWORD=mysecretpassword -v postgres-db:/var/lib/postgresql/data postgres |
Creates container with named volume |
docker container run -d --name postgres2 -e POSTGRES_PASSWORD=mysecretpassword -v postgres-db:/var/lib/postgresql/data postgres:15.4 |
Reuses volume with specific version |
docker container run -d --name postgres3 -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_DB=myapp -v postgres-db:/var/lib/postgresql/data postgres |
Creates container with custom database name |
Command | Description |
---|---|
docker volume create |
Creates a volume |
docker volume ls |
Lists volumes |
docker volume inspect |
Displays volume information |
docker volume rm |
Removes volume |
- Maps host file/directory to container file/directory
- Cannot be used in Dockerfile
- Must be specified at container runtime
- Changes in host reflect immediately in container
- Ideal for local development
- Enables real-time code changes
- Supports rapid testing and debugging
Command | Description |
---|---|
docker container run -d --name nginx -p 80:80 -v $(pwd):/usr/share/nginx/html nginx |
Maps current directory to nginx html directory |
docker run -p 80:4000 -v $(pwd):/site bretfisher/jekyll-serve |
Maps current directory for Jekyll development |
Command | Description |
---|---|
docker container exec -it nginx bash |
Access container shell for debugging |
docker container run -d --name nginx2 -p 8080:80 nginx |
Run secondary container for testing |
Best Practices:
- Use named volumes for production data persistence
- Use bind mounts for development environments
- Always backup important data volumes
- Use volume drivers for cloud storage when needed
-
Authentication Options:
- Set password:
POSTGRES_PASSWORD=mypasswd
- Disable password:
POSTGRES_HOST_AUTH_METHOD=trust
- Set password:
-
Supported Image Versions:
- Old version:
postgres:15.1
- New version:
postgres:15.2
- Old version:
Note: Authentication changes were made in Docker Hub image, not in PostgreSQL itself.