postgresql - docker compose:postgresql 创建数据库,用户通过并授予权限
问题描述
我有以下 docker-compose 文件:
version: '3'
services:
web:
build:
context: ./django_httpd_mod_wsgi
ports:
- "8000:80"
db:
build:
context: ./postgresql
volumes:
- db-data:/var/lib/postgres/data
volumes:
db-data:
我正在使用 archlinux 构建 psotgresql 映像:
以下是我的 postgresql Dockerfile:
FROM archlinux/base
RUN yes | pacman -S postgresql
RUN mkdir /run/postgresql/
RUN chown -R postgres:postgres /run/postgresql/
USER postgres
RUN initdb -D /var/lib/postgres/data
RUN psql -c 'CREATE DATABASE btgapp;'
RUN psql -c "CREATE USER simha WITH PASSWORD 'krishna';"
RUN psql -c 'GRANT ALL PRIVILEGES ON DATABASE btgapp TO simha;'
CMD ["/usr/bin/postgres","-D","/var/lib/postgres/data"]
当我尝试这样做时:
docker-compose up
我得到错误:
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/run/postgresql/.s.PGSQL.5432"?
ERROR: Service 'db' failed to build: The command '/bin/sh -c psql -c 'CREATE DATABASE dbname;'' returned a non-zero code: 2
我知道我必须psql -c CREATE DATABSE "dbname"
在启动 postgresql 服务器后运行/usr/bin/postgres -D /var/lib/postgres/data
但我无法在 Dockerfile 中启动多个命令。那么如何做到这一点。
选项是启动脚本。但是很难看到 postgres 作为单个进程运行。
解决方案
根据评论,我将尝试在这里回答。
我相信您应该使用 postgres 11-alpine 图像。我将尝试在这里解释原因。
官方 docker 镜像有很多好处,你应该在开始自己之前考虑这些好处。
- 升级路径很简单- 当包含在镜像中的应用程序的新版本发布时,官方 docker 镜像在大多数情况下会随之更新。通常,更改会尊重映像已建立的配置约定。例如环境变量、启动细节。这样用户就可以简单地更改堆栈中的标签,并进行升级。当然可能会有重大变化 - 总是检查这个。
- 庞大的用户群——当像 postgres 这样的图像被下载超过 1000 万次(2019 年)时,这不仅意味着它很受欢迎,而且本质上就像是对图像已经过彻底测试的保证。任何基本的错误都已被清除,您将可以轻松地使用图像。
- 针对尺寸和性能进行了优化- 您可以确定已经关注了很多细节,最大限度地减少了图像的尺寸并最大限度地提高了性能。许多项目在几个不同的 linux 发行版上发布他们的应用程序。像 postgres - 他们发布
debian
和alpine
基于图像。alpine
图像较小,而图像稍大debian
,但如果您需要安装额外的软件包,则可以访问庞大的 debian 软件包存储库。 - 易于配置- 官方图像的维护者通常非常了解他们的用户群的用例。他们试图让我们作为开发人员和管理员的生活更轻松(上帝保佑他们)。官方图像通常在他们的 docker hub 登陆页面上有一些非常好的文档,或者一个 github repo 的链接,其中
README.md
将涵盖常见的用例。我发现这些说明从上到下都值得一读。
我了解您希望保持图像较小,但您知道什么 - postgres 项目已经涵盖了您的用例。
最新的 alpine postgres 标记的图像11-alpine
具有28 MB的压缩空间和70 MB的解压缩空间。虽然archlinux/base
您要开始使用的映像具有 153MB 的压缩基本占用空间和445MB的解压缩大小。那是在你介绍 postgres 本身之前。
除此之外,您希望在启动时创建的数据库和用户 - 可以单独在官方 postgres 图像的环境变量中处理。像这样:
docker run -d --name some-postgres \
-e POSTGRES_PASSWORD=mysecretpassword \
-e POSTGRES_USER=simha \
-e POSTGRES_DB=btgapp \
postgres:11-alpine
如果这不包括数据库所需的初始化,那么您可以将.sql
脚本(和.sh
脚本)复制到映像中的特殊位置 - 它们将在启动时执行。为此,您可以像这样扩展他们的图像:
init-user-db.sh
#!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER simha;
CREATE DATABASE btgapp;
GRANT ALL PRIVILEGES ON DATABASE btgapp TO simha;
EOSQL
然后Dockerfile
像这样:
Dockerfile
FROM postgres:11-alpine
COPY ./init-user-db.sh /docker-entrypoint-initdb.d/init-user-db.sh
(这取自docker hub 上的 postgres 描述)
最后 - 我建议您不要优先考虑图像所基于的发行版的可用性和可维护性。Docker 使我们能够在容器中运行应用程序,而无需真正关心容器内的发行版是什么。反正都是linux。归根结底,我希望您像我一样想要一个稳定的 postgres 数据库容器。这就是我从官方 postgres 图像中得到的。
我希望我能帮助您评估您对此的选择。
推荐阅读
- ios - URLSession 委托不适用于 swift 4.2
- javascript - 如何在 Javascript 中将骆驼大小写为蛇大小写?
- bash - 每年对数百万个项目进行排序的 Bash 脚本太慢了
- python-3.x - 如何从另一个文件访问在另一个类的一个文件中创建的对象?
- python - For While 循环继续运行
- c# - 一个类的字段/属性与它自己的类型相同吗?
- c# - 使用泛型类型参数与使用其类型约束?
- ocr - pytesseract | image_to_string 和 image_to_boxes 之间的区别
- python - pandas:如何列出每个组的用户总数和组中的所有用户?
- javascript - 意外命中令牌错误异常?