Docker Compose:PostgreSQL 创建数据库、用户密码和授权权限。

6

我有以下的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构建PostgreSQL镜像:
以下是我的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

我明白在启动PostgreSQL服务器之后,我必须运行psql -c CREATE DATABASE "dbname"

但是我无法在Dockerfile中启动多个命令。那么该怎么办呢?

解决方案是启动一个脚本,但这样很难看到postgres作为单个进程运行。


你没有使用官方的Postgres镜像,有什么特别的原因吗?它支持这种启动行为。 - Andreas Lorenzen
我想尝试一下Arch Linux。因为我在所有的Web和Redis上都使用相同的操作系统,这也会节省空间。 - Santhosh
1个回答

18

基于评论,我将在此尝试回答。

我认为您应该选择postgres 11-alpine镜像,并在此尝试解释原因。

官方docker映像具有许多优点,在开始使用自己的映像之前,您应该始终考虑这些优点。

  1. 易于升级-当包装在映像中的应用程序的新版本发布时,官方docker映像通常会随之更新。并且通常更改遵循映像已经建立的配置约定,比如环境变量、启动特定项。因此,用户可以简单地更改其堆栈中的标签,并进行升级。当然可能会存在一些破坏性变化-请始终进行检查。
  2. 大量用户群体-当像postgres这样的映像被下载超过1000万次(2019年)时,这不仅意味着它很受欢迎,而且本质上是保证映像已经经过了彻底测试。任何基本错误都已经被排除,您将轻松处理该映像。
  3. 大小和性能优化-您可以确信,已经注意到了许多细节,最大限度地减小了映像的大小并最大化了性能。许多项目在几个不同的Linux发行版上发布其应用程序,比如postgres-他们发布debian和基于alpine的映像。 alpine映像更小,而debian略大,但如果您需要安装其他包,则可以访问广泛的debian软件包存储库。
  4. 易于配置-官方映像的维护者通常非常了解其用户群体的使用情况。并且他们试图使我们作为开发人员和管理员的生活更轻松(上帝保佑他们)。正式映像通常有一些非常好的文档显示在其docker hub着陆页面上,或者链接到一个github repo,其中README.md将涵盖常见的用例。我认为这些说明值得从头到尾好好阅读。

我知道您想要保持镜像的小巧精悍,但是Postgres项目已经考虑到了您的用例。

最新的alpine postgres映像标记为11-alpine,压缩后占用空间仅28 MB,解压后大小为70MB。而您想要开始使用的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镜像获得的。

我希望这有助于您评估您的选择。


1
非常感谢您的解释。我很愿意转向官方的Docker镜像。但是我也想了解如何使用Archlinux进行操作。只是为了学习。因此,如果我使用多个容器的Docker compose,则无法使用docker run命令来启动postgresql,因为它必须在web启动之前启动。我认为在我的postgresql Dockerfile中,我必须尝试使用ENTRYPOINT而不是CMD。另外,是否有关于postgres:11-alpine Dockerfile的文档?学习创建自己的Dockerfiles可以让我们更好地理解。 - Santhosh
1
为了更深入地了解Dockerfiles和Docker容器的工作原理,创建一些自己的镜像绝对是一个不错的项目。祝您愉快! - Andreas Lorenzen
谢谢。我习惯于使用Arch Linux仓库、AUR和安装软件包以及美观的维基页面。因此,我很高兴在Docker的帮助下可以继续使用我的Arch Linux。 - Santhosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接