使用 docker-compose 在 postgresql 数据库中创建表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33309121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using docker-compose to create tables in postgresql database
提问by blahblahblah
I am using docker-compose to deploy a multicontainer python Flask web application. I'm having difficulty understanding how to create tables in the postgresql database during the build so I don't have to add them manually with psql.
我正在使用 docker-compose 来部署多容器 python Flask Web 应用程序。我很难理解如何在构建期间在 postgresql 数据库中创建表,因此我不必使用 psql 手动添加它们。
My docker-compose.yml file is:
我的 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"
I dont want to have to enter psql in order to type in:
我不想必须输入 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
I would appreciate guidance on how to create the tables.
我很感激有关如何创建表格的指导。
回答by Daerdemandt
I dont want to have to enter psql in order to type in
我不想为了输入而必须输入 psql
You can simply use container's built-in init mechanism:
您可以简单地使用容器的内置初始化机制:
COPY init.sql /docker-entrypoint-initdb.d/10-init.sql
COPY init.sql /docker-entrypoint-initdb.d/10-init.sql
This makes sure that your sql is executed after DB server is properly booted up.
这确保在正确启动数据库服务器后执行您的 sql。
Take a look at their entrypoint script. It does some preparations to start psql correctly and looks into /docker-entrypoint-initdb.d/
directory for files ending in .sh
, .sql
and .sql.gz
.
看看他们的入口点脚本。它为正确启动 psql 做了一些准备工作,并在/docker-entrypoint-initdb.d/
目录中查找以.sh
,.sql
和结尾的文件.sql.gz
。
10-
in filename is because files are processed in ASCII order. You can name your other init files like 20-create-tables.sql
and 30-seed-tables.sql.gz
for example and be sure that they are processed in order you need.
10-
in filename 是因为文件是按 ASCII 顺序处理的。你能说出你的其他的init文件,如20-create-tables.sql
和30-seed-tables.sql.gz
例如,并确保他们在需要的顺序进行处理。
Also note that invoking command does notspecify the database. Keep that in mind if you are, say, migrating to docker-compose and your existing .sql
files don't specify DB either.
另请注意,调用命令不指定数据库。如果您要迁移到 docker-compose 并且您现有的.sql
文件也没有指定 DB ,请记住这一点。
Your files will be processed at container's first start instaed of build
stage though. Since Docker Compose stops images and then resumes them, there's almost no difference, but if it's crucial for you to init the DB at build
stage I suggest still using built-in init method by calling /docker-entrypoint.sh
from your dockerfile and then cleaning up at /docker-entrypoint-initdb.d/
directory.
不过,您的文件将在容器第一次启动时处理build
。由于 Docker Compose 停止图像然后恢复它们,几乎没有区别,但是如果您在build
阶段初始化数据库至关重要,我建议您仍然通过/docker-entrypoint.sh
从 dockerfile调用然后在/docker-entrypoint-initdb.d/
目录中进行清理来使用内置的 init 方法。
回答by Victor Di
it did not work for me with the COPY approach in Dockerfile. But I managed to run my init.sql file by adding:
它不适用于 Dockerfile 中的 COPY 方法。但是我设法通过添加以下内容来运行我的 init.sql 文件:
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
into my docker-compose.yml. init.sql was in the same catalog as my docker-compose.yml. I peeked the solution here: https://gist.github.com/vrulevskyi/307b08abddc9568cf8f9c1b429c1ab56
进入我的 docker-compose.yml。init.sql 与我的 docker-compose.yml 位于同一目录中。我在这里查看了解决方案:https: //gist.github.com/vrulevskyi/307b08abddc9568cf8f9c1b429c1ab56
回答by dnephin
I would create the tables as part of the build process. Create a new Dockerfile
in a new directory ./database/
我将创建表作为构建过程的一部分。Dockerfile
在新目录中新建一个./database/
FROM postgres:latest
COPY . /fixtures
WORKDIR /fixtures
RUN /fixtures/setup.sh
./database/setup.sh
would look something like this:
./database/setup.sh
看起来像这样:
#!/bin/bash
set -e
/etc/init.d/postgresql start
psql -f create_fixtures.sql
/etc/init.d/postgresql stop
Put your create user, create database, create table sql (and any other fixture data) into a create_fixtures.sql
file in the ./database/
directory.
将您的创建用户、创建数据库、创建表 sql(以及任何其他夹具数据)放入目录中的create_fixtures.sql
文件中./database/
。
and finally your postgres
service will change to use build
:
最后您的postgres
服务将改为使用build
:
postgres:
build: ./database/
...
Note: Sometimes you'll need a sleep 5
(or even better a script to poll and wait for postgresql to start) after the /etc/init.d/postgresql start
line. In my experience either the init script or the psql client handles this for you, but I know that's not the case with mysql, so I thought I'd call it out.
注意:有时sleep 5
在该/etc/init.d/postgresql start
行后面需要一个(或者更好的脚本来轮询并等待 postgresql 启动)。根据我的经验,init 脚本或 psql 客户端都会为您处理这个问题,但我知道 mysql 不是这种情况,所以我想我会说出来。