Tengo un proyecto con la siguiente estructura:
proj src application app.py manage.py migrations Dockerfile docker-compose.yamlMi objetivo es ejecutar migraciones desde el directorio de la aplicación para crear tablas en la base de datos durante la composición de la ventana acoplable.
python manage.py db upgradeDockerfile
FROM python:3.7-alpine ADD requirements.txt /code/ WORKDIR /code RUN apk add --no-cache postgresql-dev gcc python3 musl-dev && \ pip3 install -r requirements.txt ADD . /code EXPOSE 5000 WORKDIR /code/src/application CMD ["flask", "run", "--host=0.0.0.0"]docker-compose.yaml
--- version: "3" services: web: links: - "db" build: . ports: - "5000:5000" volumes: - .:/code depends_on: - db env_file: - .env db: image: postgres:10 restart: always environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=app ports: - "5432:5432" expose: - 5432¿Cómo puedo hacer eso?
¿Qué hay de usar un tercer contenedor para esta tarea? Como debe ejecutarse solo una vez, hasta donde yo sé, agregarlo a un punto de entrada podría no ser lo mejor que se puede hacer, a menos que tenga algunos controles para evitar ejecutarlo cada vez que se inicia el contenedor, incluso si no dañará, es un proceso innecesario de hacer.
El uso de un tercer contenedor hará lo siguiente:
Cuando ejecute docker-compose up , se iniciará de acuerdo con el orden que desee, ejecutará el comando y luego saldrá. Con respecto a la ruta, puede crear un volumen con nombre compartido entre el contenedor de la aplicación real y el contenedor de la tarea de migración. Por ejemplo:
He agregado un servicio
basepara evitar la duplicación en el docker-compose
version: "3" services: base: build: . volumes: - .:/code env_file: - .env command: 'false' web: extends: service: base command: flask run --host=0.0.0.0 links: - "db" ports: - "5000:5000" depends_on: - db db: image: postgres:10 restart: always environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=app ports: - "5432:5432" expose: - 5432 migrations: extends: service: base command: python manage.py db upgrade depends_on: - dbOtras notas:
links porque docker-compose por defecto crea una red.expose también, el contenedor verá el puerto del otro siempre que estén en la misma red.wait-for-it o wait-for como se explica en la siguiente respuestaprobemos con docker-compose.yml
--- version: "3" services: web: links: - "db" build: . ports: - "5000:5000" volumes: - .:/code entrypoint: - python - manage.py - db - upgrade depends_on: - db env_file: - .env db: image: postgres:10 restart: always environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=app ports: - "5432:5432" expose: - 5432Agregaría un script bash que tenga los comandos que desea ejecutar durante el inicio y lo usaría como el punto de entrada predeterminado en su imagen. Por lo general, es una buena práctica llamar a este script entrypoint.sh
#!/usr/bin/env bash python manage.py db upgrade flask run --host=0.0.0.0Y luego, en su Dockerfile, reemplace la última línea con la siguiente
RUN chmod u+x ./entrypoint.sh ENTRYPOINT ["./entrypoint.sh"]Si desea ejecutar el comando de actualización solo en la redacción de Docker, en lugar de cambiar el punto de entrada predeterminado en la imagen, puede anularlo en el archivo de redacción de esta manera
web: links: - "db" build: . ports: - "5000:5000" volumes: - .:/code depends_on: - db entrypoint: /code/entrypoint.sh env_file: - .env