【问题标题】:Using docker-compose to create tables in postgresql database使用 docker-compose 在 postgresql 数据库中创建表
【发布时间】:2015-10-23 18:28:40
【问题描述】:

我正在使用 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

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

【问题讨论】:

    标签: postgresql docker docker-compose


    【解决方案1】:

    Dockerfile 中的 COPY 方法对我不起作用。但我设法通过将以下内容添加到docker-compose.yml 来运行我的init.sql 文件:

        volumes:
            - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    

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

    【讨论】:

      【解决方案2】:

      我不想输入 psql 才能输入

      您可以简单地使用容器内置的 init 机制:

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

      这可以确保在 DB 服务器正确启动后执行您的 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 阶段初始化数据库对您至关重要,我建议仍然使用内置的 init 方法,通过从您的 dockerfile 调用 /docker-entrypoint.sh 然后清理在/docker-entrypoint-initdb.d/ 目录。

      【讨论】:

      • 这不适用于最新版本的 postgres 图像 :(
      【解决方案3】:

      我将创建表作为构建过程的一部分。在新目录./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
      

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

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

      postgres:
          build: ./database/
          ...
      

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

      【讨论】:

      • 感谢您的帮助。我在构建 docker-compose.yml 时遇到了这个错误。 bin/sh: 1: /fixtures/setup.sh: Permission denied Service 'postgres' failed to build: The command '/bin/sh -c /fixtures/setup.sh' returned a non-zero code: 126
      • 好的,你也可以在脚本顶部添加set -x,这样它就会打印出每一步,你可以找出它失败的地方。
      • 我添加了RUN chmod +x /fixtures/setup.sh 解决了这个问题。我现在得到No PostgreSQL clusters exist; see "man pg_createcluster" ... (warning). psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"? Service 'postgres' failed to build: The command '/bin/sh -c /fixtures/setup.sh' returned a non-zero code: 2
      • 好的,我认为您遇到了我在答案底部的“注释”中描述的情况
      • 您解决过这个集群问题吗?
      猜你喜欢
      • 2021-03-13
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      • 2017-12-09
      • 1970-01-01
      • 2015-11-08
      • 1970-01-01
      • 2020-06-05
      相关资源
      最近更新 更多