运行 使用 Docker/Docker 撰写的 Postgres 迁移
Run Postgres migration with Docker/Docker compose
我对这整个主题都很陌生,如果这些问题很愚蠢,请原谅。我想 运行 在 Docker 容器中进行单元测试,如下所示:
- 启动一个没有 tables/data
的 Postgres 容器
- 运行 数据库迁移(我正在使用 node-pg-migrate)创建所有表
- 用测试数据填充数据库
- 用我的服务启动一个 Node 容器
- 运行单元测试
- 删除数据库
- 关闭down/delete所有容器(除非有错误)
我目前正在努力 运行迁移。我创建服务图像 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
之类的东西来帮助您启动订单,但不会等待服务 健康 。
我对这整个主题都很陌生,如果这些问题很愚蠢,请原谅。我想 运行 在 Docker 容器中进行单元测试,如下所示:
- 启动一个没有 tables/data 的 Postgres 容器
- 运行 数据库迁移(我正在使用 node-pg-migrate)创建所有表
- 用测试数据填充数据库
- 用我的服务启动一个 Node 容器
- 运行单元测试
- 删除数据库
- 关闭down/delete所有容器(除非有错误)
我目前正在努力 运行迁移。我创建服务图像 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
之类的东西来帮助您启动订单,但不会等待服务 健康 。