Mira la lección en vídeo
Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.
Desbloquear Plan PlusDeclarar volúmenes en Compose
Docker Compose permite definir volúmenes de manera declarativa utilizando la sección top-level volumes
en el archivo compose.yaml
. Esta aproximación simplifica significativamente la gestión de datos persistentes en aplicaciones multi-contenedor, eliminando la necesidad de crear volúmenes manualmente antes de ejecutar los servicios.
Sección top-level volumes
La declaración de volúmenes en Compose se realiza al mismo nivel que services
, creando un inventario centralizado de todos los volúmenes que utilizarán los contenedores:
services:
web:
image: nginx:1.27
volumes:
- static_files:/usr/share/nginx/html
database:
image: mysql:8.4
volumes:
- mysql_data:/var/lib/mysql
volumes:
static_files:
mysql_data:
Esta estructura declarativa permite a Docker Compose gestionar automáticamente el ciclo de vida de los volúmenes, creándolos si no existen y manteniéndolos disponibles para todos los servicios que los necesiten.
Configuración de volúmenes nombrados
Los volúmenes pueden incluir configuración específica utilizando el formato extendido. El driver por defecto es local
, pero podemos especificarlo explícitamente junto con opciones adicionales:
volumes:
mysql_data:
driver: local
driver_opts:
type: none
o: bind
device: /opt/mysql-data
postgres_data:
driver: local
labels:
com.example.description: "Database volume for PostgreSQL"
com.example.department: "backend"
Las etiquetas proporcionan metadatos útiles para organizar y documentar volúmenes en entornos empresariales, facilitando su identificación y gestión.
Volúmenes externos
Docker Compose puede referenciar volúmenes externos que ya existen en el sistema, evitando que se creen automáticamente durante el despliegue:
services:
app:
image: node:24-alpine
volumes:
- shared_storage:/app/uploads
volumes:
shared_storage:
external: true
Esta funcionalidad es especialmente útil cuando múltiples stacks de Compose necesitan compartir datos, o cuando los volúmenes son gestionados externamente por herramientas de administración.
Para volúmenes externos con nombres diferentes al especificado en Compose:
volumes:
app_data:
external: true
name: production-app-data
Ejemplo práctico con base de datos
Un caso típico combina volúmenes internos y configuración específica para servicios de base de datos:
services:
web:
image: nginx:1.27
ports:
- "80:80"
volumes:
- web_content:/usr/share/nginx/html
depends_on:
- database
database:
image: postgresql:17-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: developer
POSTGRES_PASSWORD: secret123
volumes:
- postgres_data:/var/lib/postgresql/data
- postgres_backups:/backups
volumes:
web_content:
driver: local
postgres_data:
driver: local
labels:
com.myapp.service: "database"
com.myapp.environment: "development"
postgres_backups:
driver: local
driver_opts:
type: none
o: bind
device: /opt/backups/postgres
Esta configuración crea volúmenes dedicados para datos de PostgreSQL y backups, con el directorio de backups mapeado a una ubicación específica del host mediante bind mount configurado como volumen nombrado.
Nomenclatura y namespacing
Docker Compose aplica prefijos automáticos a los nombres de volúmenes basados en el nombre del proyecto. Por defecto, utiliza el nombre del directorio que contiene el archivo compose.yaml
:
# Archivo en directorio 'myapp'
volumes:
database_data: # Se crea como 'myapp_database_data'
Para controlar el nombre del proyecto y, por tanto, el prefijo:
docker compose -p production up -d
# Los volúmenes tendrán prefijo 'production_'
Esta estrategia de naming evita conflictos entre diferentes proyectos y facilita la identificación de recursos en sistemas con múltiples aplicaciones containerizadas.
Montajes y permisos
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Los montajes de volúmenes en Docker Compose admiten diferentes tipos y configuraciones que determinan cómo se comportan los datos y qué permisos tienen los contenedores sobre ellos. La sintaxis extendida proporciona control granular sobre estos aspectos, permitiendo configuraciones específicas para cada caso de uso.
Sintaxis de montaje extendida
Docker Compose ofrece dos formas de declarar montajes: la sintaxis corta (volumen:ruta
) y la sintaxis extendida que proporciona mayor control. La sintaxis extendida utiliza el formato de objeto con propiedades específicas:
services:
database:
image: mysql:8.4
volumes:
- type: volume
source: mysql_data
target: /var/lib/mysql
read_only: false
- type: bind
source: ./config
target: /etc/mysql/conf.d
read_only: true
volumes:
mysql_data:
Las propiedades principales son type
(volume o bind), source
(nombre del volumen o ruta del host), target
(ruta dentro del contenedor) y read_only
para controlar permisos de escritura.
Tipos de montaje: volume vs bind
Los montajes de tipo volume utilizan volúmenes gestionados por Docker, proporcionando mejor portabilidad y rendimiento. Son ideales para datos que deben persistir pero no requieren acceso directo desde el host:
services:
postgres:
image: postgresql:17-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: dbuser
POSTGRES_PASSWORD: dbpass123
volumes:
- type: volume
source: postgres_data
target: /var/lib/postgresql/data
volume:
nocopy: false
- type: volume
source: postgres_logs
target: /var/log/postgresql
volumes:
postgres_data:
postgres_logs:
Los montajes de tipo bind mapean directorios específicos del host al contenedor, útiles para desarrollo y configuraciones que necesitan editarse externamente:
services:
web:
image: nginx:1.27
volumes:
- type: bind
source: ./html
target: /usr/share/nginx/html
read_only: true
- type: bind
source: ./nginx.conf
target: /etc/nginx/nginx.conf
read_only: true
ports:
- "8080:80"
Permisos de solo lectura
La opción read_only
previene modificaciones accidentales y mejora la seguridad, especialmente útil para archivos de configuración y recursos estáticos:
services:
app:
image: node:24-alpine
volumes:
# Código fuente en solo lectura
- type: bind
source: ./src
target: /app/src
read_only: true
# Directorio de escritura para logs
- type: volume
source: app_logs
target: /app/logs
read_only: false
# Configuración protegida
- type: bind
source: ./config/app.json
target: /app/config.json
read_only: true
volumes:
app_logs:
Gestión de permisos de usuario
Los permisos de archivos en volúmenes pueden requerir ajustes cuando los contenedores ejecutan procesos con usuarios específicos. PostgreSQL, por ejemplo, requiere que el directorio de datos pertenezca al usuario postgres
:
services:
postgres:
image: postgresql:17-alpine
user: "999:999" # UID:GID del usuario postgres
environment:
POSTGRES_DB: empresa
POSTGRES_USER: admin
POSTGRES_PASSWORD: secure456
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- type: volume
source: postgres_data
target: /var/lib/postgresql/data
volume:
nocopy: false
postgres_backup:
image: postgresql:17-alpine
depends_on:
- postgres
volumes:
- type: volume
source: postgres_data
target: /var/lib/postgresql/data
read_only: true
- type: bind
source: ./backups
target: /backups
command: >
sh -c "pg_dump -h postgres -U admin -d empresa > /backups/backup-$$(date +%Y%m%d).sql"
volumes:
postgres_data:
Configuración avanzada de volúmenes
Las opciones específicas de volúmenes permiten control adicional sobre el comportamiento del montaje. La opción nocopy
determina si el contenido inicial del contenedor se copia al volumen:
services:
mysql:
image: mysql:8.4
environment:
MYSQL_ROOT_PASSWORD: rootpass123
MYSQL_DATABASE: production
MYSQL_USER: appuser
MYSQL_PASSWORD: apppass456
volumes:
- type: volume
source: mysql_data
target: /var/lib/mysql
volume:
nocopy: true # No copiar datos iniciales
- type: bind
source: ./mysql-config
target: /etc/mysql/conf.d
read_only: true
bind:
propagation: rprivate
volumes:
mysql_data:
driver: local
driver_opts:
type: none
o: bind
device: /opt/mysql-data
Ejemplo integral con múltiples servicios
Un stack completo que combina diferentes tipos de montajes y permisos para una aplicación web con base de datos:
services:
nginx:
image: nginx:1.27-alpine
ports:
- "80:80"
- "443:443"
volumes:
- type: bind
source: ./nginx/nginx.conf
target: /etc/nginx/nginx.conf
read_only: true
- type: volume
source: static_content
target: /usr/share/nginx/html
read_only: true
- type: bind
source: ./ssl
target: /etc/ssl/certs
read_only: true
app:
image: node:24-alpine
user: "1000:1000"
working_dir: /app
environment:
NODE_ENV: production
DB_HOST: database
volumes:
- type: bind
source: ./app
target: /app
read_only: true
- type: volume
source: app_uploads
target: /app/uploads
- type: volume
source: static_content
target: /app/public
depends_on:
- database
database:
image: mysql:8.4
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: webapp
MYSQL_USER: webuser
MYSQL_PASSWORD: web456
volumes:
- type: volume
source: mysql_data
target: /var/lib/mysql
- type: bind
source: ./mysql/custom.cnf
target: /etc/mysql/conf.d/custom.cnf
read_only: true
volumes:
mysql_data:
driver: local
app_uploads:
driver: local
static_content:
driver: local
Esta configuración establece permisos diferenciados: archivos de configuración en solo lectura, volúmenes de datos con permisos de escritura, y separación clara entre contenido estático y dinámico para optimizar rendimiento y seguridad.
Aprendizajes de esta lección de Docker
- Comprender cómo declarar volúmenes en un archivo compose.yaml usando la sección top-level volumes.
- Diferenciar entre volúmenes nombrados, externos y sus configuraciones específicas.
- Aplicar la sintaxis extendida para montajes de volúmenes y bind mounts con control de permisos.
- Gestionar permisos de usuario y opciones avanzadas como nocopy para volúmenes.
- Configurar un stack completo con múltiples servicios y volúmenes optimizados para seguridad y rendimiento.
Completa este curso de Docker y certifícate
Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs