运行 使用 Docker/Docker 撰写的 Postgres 迁移

Run Postgres migration with Docker/Docker compose

我对这整个主题都很陌生,如果这些问题很愚蠢,请原谅。我想 运行 在 Docker 容器中进行单元测试,如下所示:

我目前正在努力 运行迁移。我创建服务图像 FROM 我的产品图像和 RUN npm install --only=dev。我的 docker-compose.yml 看起来像这样:

version: "3.7"
services:
    db:
        image: postgres
        environment: 
            POSTGRES_PASSWORD: test_pw
            POSTGRES_USER: test_user
            POSTGRES_DB: test_db

        ports:
            - '5432:5432'

    web:
        image: docker_tests
        environment:
            DATABASE_URL: postgres://test_user:test_pw@db:5432/test_db?ssl=false
            DATABASE_SSL: "false"
            DATABASE_PW: test_pw
            DATABASE_USER: test_user
            DATABASE_NAME: test_db
            DATABASE_HOST: db
        depends_on: 
            - db
        ports:
            - '1337:1337'

还有我的Docker文件:

FROM docker_service
ENV NODE_ENV TEST
WORKDIR /usr/src/app
RUN npm install --only=dev
RUN ["./node_modules/.bin/node-pg-migrate", "up"]
EXPOSE 1337
CMD ["npm", "run", "test"]

当运行合成时,两个容器都启动,我什至得到

No migrations to run!
Migration complete!

但是,如果我 运行 测试,则没有可用的表格。迁移未应用于我的 Postgres 容器,并且在迁移后添加 RUN ["printenv"] 时,原因很清楚:必要的 DATABASE_URL 不存在。我用谷歌搜索发现 docker-compose.yml 中指定的环境变量仅在 运行 时可用,在构建时不可用。但是,当我将 ENV DATABASE_URL ... 添加到我的 Docker 文件时,当然它无法连接到数据库,因为 Postgres 容器尚未启动。

我该如何解决这个问题?一种可能的解决方案是在两个容器启动后立即在 Web 中 运行 ./node_modules/.bin/node-pg-migrate up,但是 Docker 只能有一个 CMD,对吗?我用它来 运行 我的单元测试。

TL;DR:如何在 运行 之前使用来自 Docker 服务容器的 node-pg-migrate 在 Docker Postgres 容器中进行迁移宁单元测试?

非常感谢!

我无法对此进行测试,但我的想法是:

  • 在与 Dockerfile 相同的文件夹中有一个 docker-entrypoint.sh 脚本
#!/usr/bin/env bash

./node_modules/.bin/node-pg-migrate up
exec "$@"
  • 更改 Dockerfile 以使用该脚本
FROM docker_service
ENV NODE_ENV TEST
WORKDIR /usr/src/app
RUN npm install --only=dev

COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh && \
    ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat

ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 1337
CMD ["npm", "run", "test"]

这样,每次创建容器时都会执行 docker-entrypoint.sh 脚本,之后会执行 npm run test 因为 exec "$@". Every DB image has this kind of setup and I advise you to take a look at the PostgreSQL Dockerfile and entrypoint script.


您可能需要 wait-for-it to make sure the DB has started, before executing migration scripts. depends_on 之类的东西来帮助您启动订单,但不会等待服务 健康

资源Control startup and shutdown order in Compose