running - Usando Docker-Compose, cómo ejecutar múltiples comandos
docker compose mysql (11)
Ejecuto cosas previas al inicio como migraciones en un contenedor efímero separado, así (nota, el archivo de composición debe ser del tipo versión ''2''):
db:
image: postgres
web:
image: app
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
depends_on:
- migration
migration:
build: .
image: app
command: python manage.py migrate
volumes:
- .:/code
links:
- db
depends_on:
- db
Esto ayuda a mantener las cosas limpias y separadas. Dos cosas a tener en cuenta:
-
Debe asegurarse de la secuencia de inicio correcta (usando depende_en)
-
desea evitar múltiples compilaciones, lo cual se logra etiquetándolo la primera vez usando compilación e imagen; puede referirse a la imagen en otros contenedores y luego
Quiero hacer algo como esto donde puedo ejecutar múltiples comandos en orden.
db:
image: postgres
web:
build: .
command: python manage.py migrate
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
Esto funciona para mi:
#!/bin/bash
python manage.py migrate
exec "$@"
docker-compose intenta desreferenciar las variables antes de ejecutar el comando, por lo que si desea que bash maneje las variables, deberá escapar de los signos de dólar al duplicarlas ...
version: ''3.1''
services:
db:
image: postgres
web:
build: .
command:
- /bin/bash
- -c
- |
python manage.py migrate
python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
... de lo contrario obtendrá un error:
Formato de interpolación no válido para la opción "comando" en el servicio "web":
Lo descubrí, usa
bash -c
.
Ejemplo:
command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
Mismo ejemplo en multilíneas:
command: >
bash -c "python manage.py migrate
&& python manage.py runserver 0.0.0.0:8000"
O:
command: bash -c "
python manage.py migrate
&& python manage.py runserver 0.0.0.0:8000
"
Me encontré con esto mientras trataba de configurar mi contenedor jenkins para construir contenedores docker como el usuario jenkins.
Necesitaba tocar el archivo docker.sock en el Dockerfile cuando lo vinculo más adelante en el archivo docker-compose. A menos que lo haya tocado primero, todavía no existe. Esto funcionó para mí.
Dockerfile:
USER root RUN apt-get update && / apt-get -y install apt-transport-https / ca-certificates / curl / software-properties-common && / curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && / add-apt-repository / "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") / $(lsb_release -cs) / stable" && / apt-get update && / apt-get -y install docker-ce RUN groupmod -g 492 docker && / usermod -aG docker jenkins && / touch /var/run/docker.sock && / chmod 777 /var/run/docker.sock USER Jenkins
docker-compose.yml:
version: ''3.3'' services: jenkins_pipeline: build: . ports: - "8083:8083" - "50083:50080" volumes: - /root/pipeline/jenkins/mount_point_home:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock
Otra idea:
Si, como en este caso, crea el contenedor, simplemente coloque un script de inicio y ejecútelo con el comando. O monte el script de inicio como volumen.
Puede usar el punto de entrada aquí. El punto de entrada en la ventana acoplable se ejecuta antes del comando, mientras que el comando es el comando predeterminado que se debe ejecutar cuando se inicia el contenedor. Por lo tanto, la mayoría de las aplicaciones generalmente llevan el procedimiento de configuración en el archivo de punto de entrada y en el último permiten que se ejecute el comando.
hacer un archivo de script de shell puede ser como
docker-entrypoint.sh
(el nombre no importa) con los siguientes contenidos.
command:
- /bin/bash
- -c
- |
var=$$(echo ''foo'')
echo $$var # prints foo
en el archivo docker-compose.yml utilícelo con el punto de
entrypoint: /docker-entrypoint.sh
y registre el comando como
command: python manage.py runserver 0.0.0.0:8000
PS: no olvide copiar
docker-entrypoint.sh
junto con su código .
Recomiendo usar
sh
en lugar de
bash
porque está más disponible en la mayoría de las imágenes basadas en Unix (alpina, etc.).
Aquí hay un ejemplo de
docker-compose.yml
:
version: ''3''
services:
app:
build:
context: .
command: >
sh -c "python manage.py wait_for_db &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000"
Esto llamará a los siguientes comandos en orden:
-
python manage.py wait_for_db
- espera a que la base de datos esté lista -
python manage.py migrate
: ejecuta cualquier migración -
python manage.py runserver 0.0.0.0:8000
- iniciar mi servidor de desarrollo
Si necesita ejecutar más de un proceso de daemon, hay una sugerencia en la documentación de Docker para usar Supervisord en un modo separado para que todos los sub-daemons salgan al stdout.
De otra pregunta de SO, descubrí que puede redirigir los procesos secundarios a la salida estándar. ¡De esa manera puedes ver toda la salida!
Use una herramienta como esperar o dockerize . Estos son pequeños scripts de envoltura que puede incluir en la imagen de su aplicación. O escriba su propio script de contenedor para ejecutar comandos más específicos de la aplicación. de acuerdo con: https://docs.docker.com/compose/startup-order/
intente usar ";" para separar los comandos si está en la versión dos, por ejemplo
command: "sleep 20; echo ''a''"
* ACTUALIZACIÓN *
Pensé que la mejor manera de ejecutar algunos comandos es escribir un Dockerfile personalizado que haga todo lo que quiera antes de que el CMD oficial se ejecute desde la imagen.
docker-compose.yaml:
version: ''3''
# Can be used as an alternative to VBox/Vagrant
services:
mongo:
container_name: mongo
image: mongo
build:
context: .
dockerfile: deploy/local/Dockerfile.mongo
ports:
- "27017:27017"
volumes:
- ../.data/mongodb:/data/db
Dockerfile.mongo:
FROM mongo:3.2.12
RUN mkdir -p /fixtures
COPY ./fixtures /fixtures
RUN (mongod --fork --syslog && /
mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && /
mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && /
mongoimport --db wcm-local --collection content --file /fixtures/content.json && /
mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && /
mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && /
mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && /
mongoimport --db wcm-local --collection videos --file /fixtures/videos.json)
Esta es probablemente la forma más limpia de hacerlo.
* VIEJA FORMA *
Creé un script de shell con mis comandos.
En este caso, quería comenzar
mongod
y ejecutar
mongoimport
pero llamar a
mongod
te impide ejecutar el resto.
docker-compose.yaml :
version: ''3''
services:
mongo:
container_name: mongo
image: mongo:3.2.12
ports:
- "27017:27017"
volumes:
- ./fixtures:/fixtures
- ./deploy:/deploy
- ../.data/mongodb:/data/db
command: sh /deploy/local/start_mongod.sh
start_mongod.sh :
mongod --fork --syslog && /
mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && /
mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && /
mongoimport --db wcm-local --collection content --file /fixtures/content.json && /
mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && /
mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && /
mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && /
mongoimport --db wcm-local --collection videos --file /fixtures/videos.json && /
pkill -f mongod && /
sleep 2 && /
mongod
Entonces esto bifurca a mongo, monogimporta y luego mata al mongo bifurcado que se separa, y lo inicia de nuevo sin separarse. No estoy seguro de si hay una manera de adjuntar a un proceso bifurcado, pero esto funciona.
NOTA: Si desea cargar estrictamente algunos datos de db iniciales, esta es la forma de hacerlo:
mongo_import.sh
USER root
RUN apt-get update && /
apt-get -y install apt-transport-https /
ca-certificates /
curl /
software-properties-common && /
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release;
echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && /
add-apt-repository /
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") /
$(lsb_release -cs) /
stable" && /
apt-get update && /
apt-get -y install docker-ce
RUN groupmod -g 492 docker && /
usermod -aG docker jenkins && /
touch /var/run/docker.sock && /
chmod 777 /var/run/docker.sock
USER Jenkins
Los archivos mongo_fixtures / *. json se crearon mediante el comando mongoexport.
docker-compose.yaml
version: ''3.3''
services:
jenkins_pipeline:
build: .
ports:
- "8083:8083"
- "50083:50080"
volumes:
- /root/pipeline/jenkins/mount_point_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock