如何在 Docker 中 运行 flask_migrate
How to run flask_migrate in Docker
我有一个结构如下的项目:
proj
src
application
app.py
manage.py
migrations
Dockerfile
docker-compose.yaml
我的目标是 运行 在 docker-compose 期间从应用程序目录迁移以在数据库中创建表。
python manage.py db upgrade
Docker 文件
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
我该怎么做?
为这个任务使用第三个容器怎么样?据我所知,因为它只需要执行一次,所以将它添加到入口点可能不是最好的做法,除非你有一些检查来避免每次容器启动时 运行ning 它,即使它不会造成伤害,这是一个不必要的过程。
使用第三个容器将执行以下操作:
当您 运行 docker-compose up
时,它将根据您想要的顺序启动,然后 运行 命令退出。关于路径,您可以在实际应用程序容器和迁移任务容器之间创建共享命名卷。例如:
I have added a base
service to avoid duplication in the 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-it
或 wait-for
,如 the following answer 中所述
让我们试试 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
我会添加一个 bash 脚本,其中包含您想要在启动期间 运行 执行的命令,并将其用作映像中的默认入口点。通常最好将此脚本称为 entrypoint.sh
#!/usr/bin/env bash
python manage.py db upgrade
flask run --host=0.0.0.0
然后,在您的 Docker 文件中,将最后一行替换为以下内容
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
我有一个结构如下的项目:
proj
src
application
app.py
manage.py
migrations
Dockerfile
docker-compose.yaml
我的目标是 运行 在 docker-compose 期间从应用程序目录迁移以在数据库中创建表。
python manage.py db upgrade
Docker 文件
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
我该怎么做?
为这个任务使用第三个容器怎么样?据我所知,因为它只需要执行一次,所以将它添加到入口点可能不是最好的做法,除非你有一些检查来避免每次容器启动时 运行ning 它,即使它不会造成伤害,这是一个不必要的过程。
使用第三个容器将执行以下操作:
当您 运行 docker-compose up
时,它将根据您想要的顺序启动,然后 运行 命令退出。关于路径,您可以在实际应用程序容器和迁移任务容器之间创建共享命名卷。例如:
I have added a
base
service to avoid duplication in the 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-it
或wait-for
,如 the following answer 中所述
让我们试试 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
我会添加一个 bash 脚本,其中包含您想要在启动期间 运行 执行的命令,并将其用作映像中的默认入口点。通常最好将此脚本称为 entrypoint.sh
#!/usr/bin/env bash
python manage.py db upgrade
flask run --host=0.0.0.0
然后,在您的 Docker 文件中,将最后一行替换为以下内容
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