如何在Docker中运行flask_migrate?

34 浏览
0 Comments

如何在Docker中运行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

我该如何做到这一点?

admin 更改状态以发布 2023年5月21日
0
0 Comments

那么,使用一个第三个容器来完成这项任务如何?据我所知,它只需要执行一次,因此将其添加到入口点可能不是最好的选择,除非您有一些检查来避免在每次容器启动时运行它,即使它不会造成伤害,这也是一个不必要的过程。

使用第三个容器将会导致以下操作:

当您运行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应用程序会尝试连接它。所以,为了解决这个问题,你需要使用wait-for-itwait-for,如下面的回答所述
0
0 Comments

我会添加一个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中运行升级命令,而不是更改镜像中的默认入口点,则可以像这样在compose文件中覆盖它

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

0