如何在Docker中运行flask_migrate

时间:2019-03-18 14:03:21

标签: python docker flask flask-migrate

我有一个结构如下的项目:

proj
  src
    application
      app.py
      manage.py
      migrations
  Dockerfile
  docker-compose.yaml

我的目标是在docker-compose期间从应用程序目录运行迁移以在数据库中创建表。

python manage.py db upgrade

Dockerfile

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

我该怎么做?

3 个答案:

答案 0 :(得分:1)

我将添加一个bash脚本,其中包含您要在启动期间运行的命令,并将其用作映像中的默认入口点。通常最好的做法是将此脚本称为entrypoint.sh

#!/usr/bin/env bash
python manage.py db upgrade
flask run --host=0.0.0.0

然后,在您的Dockerfile中,用以下内容替换最后一行

RUN chmod u+x ./entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]

如果您只想在Docker compose中运行upgrade命令,则无需更改映像中的默认入口点,而可以像这样在compose文件中覆盖它

  web:
    links:
      - "db"
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
    depends_on:
      - db
    entrypoint: /code/entrypoint.sh
    env_file:
      - .env

答案 1 :(得分:0)

使用第三个容器执行此任务怎么样?据我所知,它只需要执行一次,因此将它添加到入口点可能不是最好的事情,除非您进行一些检查以避免每次容器启动时都运行它,即使它不会造成伤害,不必要的过程。

使用第三个容器将执行以下操作:

运行docker-compose up时,它将按照您想要的顺序启动并运行命令,然后退出。关于路径,您可以在实际应用程序容器和迁移任务容器之间创建一个共享的命名卷。例如:

  

我添加了一个base服务,以避免在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:
      - db

其他说明:

    不需要
  • links,因为默认情况下docker-compose会创建网络。
  • 也不需要
  • expose,只要彼此位于同一网络中,容器就可以看到彼此的端口。
  • 您可能会遇到某种竞争状况,其中您的数据库实际上尚未准备好进行连接,而django应用程序尝试连接至该数据库。因此,为了解决此问题,您将需要使用the following answer
  • 中所述的wait-for-itwait-for

答案 2 :(得分:0)

让我们尝试使用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:
      - 5432