使用 docker-compose 在 postgresql 数据库中创建表

Using docker-compose to create tables in postgresql database

我正在使用 docker-compose 来部署多容器 python Flask Web 应用程序。我很难理解如何在构建期间在 postgresql 数据库中创建表,因此我不必使用 psql 手动添加它们。

我的 docker-compose.yml 文件是:

web:
  restart: always
  build: ./web
  expose:
    - "8000"
  links:
    - postgres:postgres
  volumes:
    - /usr/src/flask-app/static
  env_file: .env
  command: /usr/local/bin/gunicorn -w 2 -b :8000 app:app

nginx:
  restart: always
  build: ./nginx/
  ports:
    - "80:80"
  volumes:
    - /www/static
  volumes_from:
    - web
  links:
    - web:web

data:
  restart: always
  image: postgres:latest
  volumes:
    - /var/lib/postgresql
  command: "true"

postgres:
  restart: always
  image: postgres:latest
  volumes_from:
    - data
  ports:
    - "5432:5432"

我不想为了输入而必须输入 psql:

CREATE DATABASE my_database;
CREATE USER this_user WITH PASSWORD 'password';
GRANT ALL PRIVILEGES ON DATABASE "my_database" to this_user;
\i create_tables.sql

我希望得到有关如何创建表格的指导。

我会在构建过程中创建 tables。在新目录 ./database/

中新建 Dockerfile
FROM postgres:latest
COPY . /fixtures
WORKDIR /fixtures
RUN /fixtures/setup.sh

./database/setup.sh 看起来像这样:

#!/bin/bash
set -e

/etc/init.d/postgresql start
psql -f create_fixtures.sql    
/etc/init.d/postgresql stop

将您的创建用户、创建数据库、创建 table sql(以及任何其他夹具数据)放入 ./database/ 目录中的 create_fixtures.sql 文件中。

最后您的 postgres 服务将更改为使用 build:

postgres:
    build: ./database/
    ...

注意:有时您需要 sleep 5(或者更好的脚本来轮询并等待 postgresql 启动)在 /etc/init.d/postgresql start 行之后。根据我的经验,init 脚本或 psql 客户端会为您处理这个问题,但我知道 mysql 不是这种情况,所以我想我会把它叫出来。

I dont want to have to enter psql in order to type in

你可以简单地使用容器内置的初始化机制:

COPY init.sql /docker-entrypoint-initdb.d/10-init.sql

这确保您的 sql 在数据库服务器正确启动后执行。

看看他们的入口点 script。它会做一些准备工作以正确启动 psql 并查看 /docker-entrypoint-initdb.d/ 目录中以 .sh.sql.sql.gz.

结尾的文件

10- in filename 是因为文件是按ASCII顺序处理的。例如,您可以将其他初始化文件命名为 20-create-tables.sql30-seed-tables.sql.gz,并确保它们按照您需要的顺序进行处理。

另请注意,调用命令does not 指定数据库。如果您要迁移到 docker-compose 并且您现有的 .sql 文件也没有指定 DB,请记住这一点。

您的文件将在容器的第一次启动时处理,而不是 build 阶段。由于 Docker Compose 停止图像然后恢复它们,因此几乎没有区别,但是如果在 build 阶段初始化数据库对您来说至关重要,我建议仍然通过调用 [=21 使用内置初始化方法=] 从你的 docker 文件,然后在 /docker-entrypoint-initdb.d/ 目录清理。

Dockerfile 中的 COPY 方法对我不起作用。但是我通过将以下内容添加到 docker-compose.yml:

来 运行 我的 init.sql 文件
    volumes:
        - ./init.sql:/docker-entrypoint-initdb.d/init.sql

init.sql 与我的 docker-compose.yml 在同一目录中。 我从 this gist. Check this 文章中选择了解决方案以获取更多信息。