我正在做一个应用,需要在docker容器启动时预填充knex数据库模式(* 仅当数据库为空 *)。
如果我手动执行它:容器中的yarn knex --knexfile config/knexfile.js migrate:latest
-它可以工作,但我需要在docker容器启动时这样做。
Dockerfile.dev
FROM node:18.15.0-alpine3.17
# Create app directory
WORKDIR /opt/app
COPY package*.json yarn*.lock ./
RUN yarn
COPY . .
ENTRYPOINT [ "node", "server.js" ]
docker-compose-dev.yml
backend:
container_name: backend-dev
build:
context: ./backend
dockerfile: Dockerfile.dev
restart: unless-stopped
env_file: ./backend/.env.dev
command: bash -c "yarn knex --knexfile ./config/knexfile.js migrate:latest" && "node server.js"
ports:
- "3000:3000"
networks:
- network
depends_on:
- db
没有错误或异常,但在DB容器内没有从迁移创建的关系。
我很乐意接受意见。
先谢谢你!
1条答案
按热度按时间piah890a1#
现在什么都没有发生,因为你在Dockerfile中使用
ENTRYPOINT
,并在Compose设置中单独设置了command:
。当你同时设置了入口点和命令时,命令会作为附加参数传递给入口点,所以你会看到bash
,-c
和另外三个参数作为Node应用程序的参数。我在这里要做的第一件事是在Dockerfile中将
ENTRYPOINT
更改为CMD
。这将使Composecommand:
覆盖生效。其中有一个语法问题(两个命令需要在相同的引号字符串中;sh -c
只接受一个参数),但是如果您修复了这个问题,那么迁移应该可以工作。但我实际上是将其实现为一个 * 入口点 Package 器脚本 *。如果
CMD
是要运行的实际命令,并且它作为参数传递给ENTRYPOINT
,那么您可以将ENTRYPOINT
用于第一次设置的脚本,然后运行作为参数传递给它的命令。例如:请确保此文件作为可执行文件签入到源代码控制中,如果您使用的是Windows系统,请确保它具有Unix(仅限LF)行结尾。您现有的
COPY
命令将把它复制到映像中,因此您所需要做的就是运行它并且您不需要覆盖
docker-compose.yml
文件中的command:
。在问题中,你添加了一个限制条件“只有当数据库为空时”。我在这里展示的设置将无条件地运行数据库迁移。然而,入口点脚本只是一个shell脚本,你可以在那里编写任何你需要的逻辑。此外,由于它只是一个shell脚本,如果你在开发和调试过程中需要
./entrypoint.sh echo hello
,你可以在本地运行它。