Si bien Docker es una herramienta útil para empaquetar y administrar aplicaciones, también presenta muchos desafíos únicos, como el manejo de datos almacenados. Por lo general, agrega volúmenes a los contenedores en el script de creación, pero ¿qué sucede si necesita crear otros nuevos?
Agregar un volumen a un contenedor Docker en ejecución
Desafortunadamente, no es tan simple como simplemente agregar un nuevo volumen. Los contenedores deben tener sus volúmenes configurados al inicio, lo que significa que para agregar un nuevo volumen, debe reiniciar el contenedor. Si bien existe una solución engañosa (más sobre eso a continuación), se recomienda encarecidamente que se reinicie el contenedor de todos modos.
Esto se debe a algunas razones. Reiniciar el contenedor es bastante fácil y la mayoría de las actualizaciones de código requieren reiniciar el servicio de todos modos. Tener un seguimiento de las actualizaciones en Git es otro factor importante, especialmente si está utilizando Docker Compose, y editar el script de inicio es mucho mejor que agregar manualmente el volumen a un contenedor en ejecución.
Si su servicio es lo suficientemente grande como para preocuparse por unos minutos (como máximo) de posible tiempo de inactividad programado para reiniciar el contenedor, probablemente debería ejecutar una implementación escalable con varias instancias que se pueden actualizar de forma independiente. Los sistemas modernos de escalado automático deben diseñarse para manejar eso, ya que las implementaciones de código ocurren con frecuencia.
Si desea agregar un volumen, deberá detener el contenedor en ejecución:
docker stop my_container
Cree un nuevo volumen si necesita:
docker volume create nginx-config
Y luego ejecútelo con un comando de inicio actualizado, agregando el --mount
marca para configurar el volumen de origen y el destino de destino.
docker run -d --name devtest --mount source=nginx-config,target=/etc/nginx nginx:latest
Si usa Docker Compose, puede automatizar y rastrear este proceso más fácilmente, ya que la configuración del volumen se maneja a través de un archivo de configuración. deberá agregar el volumen a docker-compose.yml
archivo:
version: "3.0" services: web: image: nginx:latest ports: - "80:80" volumes: - /docker/nginx-config/:/etc/nginx/
Luego, puede reiniciar los servicios de Docker Compose. Compose tiene un comando de "reinicio", pero en realidad es solo para actualizar el servicio en ejecución sin ningún cambio de configuración. Si desea actualizar las imágenes, deberá ejecutar docker-compose up
con --build
bandera:
docker-compose up -d --build
También puede ejecutar manualmente docker-compose down
de antemano para detener los servicios, pero no es necesario en la mayoría de los casos a menos que desee ejecutarlo con -v
marca para destruir los volúmenes existentes.
RELACIONADO: ¿Qué es Docker Compose y cómo se usa?
Clonación de un contenedor existente
En casi todos los casos, no debería depender del estado de ejecución actual de un contenedor. Todo lo que le interese, como los datos de la aplicación, debe almacenarse en un volumen para que pueda persistir en los reinicios y reconstrucciones del contenedor.
Este método probablemente no sea una buena idea para la mayoría de las personas, ya que requiere que crees una nueva imagen cada vez que quieras hacer esto, y aún requiere tiempo de inactividad. Pero, si necesita agregar un volumen a un contenedor en ejecución, puede usar docker commit
para crear una nueva imagen basada en ese contenedor y luego clonarla con el nuevo volumen.
Tome la ID del contenedor de docker ps
:
docker ps
Y luego, clonarlo con commit
:
docker commit f88f33c918d2 imagename
Luego, puede ejecutar la nueva imagen, reemplazando la imagen anterior con la clonada.
docker run -d --name devtest --mount source=nginx-config,target=/etc/nginx imagename
La solución Hacky
Los volúmenes de Docker son en realidad solo un engaño que el tiempo de ejecución de Docker utiliza para exponer los directorios del host a los contenedores, y todo depende de la configuración. Debido a esto, puede modificar esa configuración directamente y reiniciar todo el demonio Docker para que su sistema aplique esos cambios sin reiniciar en absoluto.
Por supuesto, esto es mucho más complicado que simplemente lidiar con el reinicio de un contenedor, por lo que si puede administrar un minuto de tiempo de inactividad, le recomendamos que lo haga en su lugar.
Deberá navegar hasta el directorio de almacenamiento de Docker:
cd /var/lib/docker/containers
Aquí habrá muchas carpetas que corresponden a los ID de contenedores de Docker, que puede encontrar con docker ps
. Abra el del contenedor que desea modificar.
El archivo de configuración es config.v2.json
, pero tiene un formato compacto y es difícil de editar. Puede instalar jq
para imprimir bastante JSON en la línea de comando y canalizar esto a un nuevo archivo para editarlo:
jq . config.v2.json > tmp.json
Deberá desplazarse hacia abajo para encontrar "MountPoints", que contiene la configuración para todos los volúmenes y montajes de enlace. Puede agregar uno nuevo aquí, que debe tener el siguiente formato:
"MountPoints": { "/home/container": { "Source": "/var/lib/pterodactyl/volumes/c7fb3a04-e540-48a7-9704-13987f52e933", "Destination": "/home/container", "RW": true, "Name": "", "Driver": "", "Type": "bind", "Propagation": "rprivate", "Spec": { "Type": "bind", "Source": "/var/lib/pterodactyl/volumes/c7fb3a04-e540-48a7-9704-13987f52e933", "Target": "/home/container" }, "SkipMountpointCreation": true } },
Luego, una vez que haya terminado, puede minimizar el JSON nuevamente en el archivo de configuración:
jq -c . tmp.json > config.v2.json
jq
es una poderosa utilidad, por lo que si desea automatizar este proceso por completo, puede hacerlo.
RELACIONADO: Cómo trabajar con JSON en la línea de comandos
Luego, simplemente reinicie el servicio Docker para aplicar los cambios:
sudo service docker restart