2025-01-05
温故知新
00

目录

快速参考
支持的标签和相应的Dockerfile链接
快速参考(续)
什么是 PostgreSQL?
如何使用 Postgres
启动 postgres 实例
...或者通过psql
...通过docker-compose⁠或docker stack deploy⁠
如何扩展此图像
环境变量
POSTGRES_PASSWORD
POSTGRES_USER
POSTGRES_DB
POSTGRESINITDBARGS
POSTGRESINITDBWALDIR
POSTGRESHOSTAUTH_METHOD
PGDATA
Docker 秘密
初始化脚本
数据库配置
附加扩展
任意--user注释

注意: 此镜像的描述长度超过了 Hub 长度限制 25000,因此已被删减。完整描述可在https://github.com/docker-library/docs/tree/master/postgres/README.md ⁠找到。

另请参阅docker/hub-feedback#238 ⁠docker/roadmap#475 ⁠

快速参考

支持的标签和相应的Dockerfile链接

快速参考(续)

什么是 PostgreSQL?

PostgreSQL,通常简称为“Postgres”,是一种对象关系数据库管理系统 (ORDBMS),重点是可扩展性和标准合规性。作为数据库服务器,它的主要功能是安全地存储数据并支持最佳实践,然后根据其他软件应用程序的请求检索数据,无论是在同一台计算机上还是在网络(包括互联网)上的另一台计算机上运行的软件应用程序。它可以处理从小型单机应用程序到具有许多并发用户的大型面向互联网的应用程序的各种工作负载。最新版本还提供数据库本身的复制,以提高安全性和可扩展性。

PostgreSQL 实现了 SQL:2011 标准的大部分内容,符合 ACID 规范并支持事务(包括大多数 DDL 语句),使用多版本并发控制 (MVCC) 避免锁定问题,提供对脏读的免疫力和完全可序列化性;使用其他数据库中没有的多种索引方法处理复杂的 SQL 查询;具有可更新的视图和物化视图、触发器、外键;支持函数和存储过程以及其他可扩展性,并具有大量由第三方编写的扩展。除了可以与主要的专有和开源数据库一起使用之外,PostgreSQL 还通过其广泛的标准 SQL 支持和可用的迁移工具支持从这些数据库迁移。如果使用了专有扩展,则可以通过一些内置和第三方开源兼容性扩展(例如 Oracle)模拟许多扩展。

标识

如何使用 Postgres

启动 postgres 实例

console
$ docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres

默认postgres用户和数据库在入口点创建initdb

...或者通过psql

console
$ docker run -it --rm --network some-network postgres psql -h some-postgres -U postgres psql (14.3) Type "help" for help. postgres=# SELECT 1; ?column? ---------- 1 (1 row)

...通过docker-composedocker stack deploy

例如:docker-compose.yml``postgres

yaml
# Use postgres/example user/password credentials version: '3.9' services: db: image: postgres restart: always # set shared memory limit when using docker-compose shm_size: 128mb # or set shared memory limit when deploy via swarm stack #volumes: # - type: tmpfs # target: /dev/shm # tmpfs: # size: 134217728 # 128*2^20 bytes = 128Mb environment: POSTGRES_PASSWORD: example adminer: image: adminer restart: always ports: - 8080:8080

在 PWD 中尝试

运行docker stack deploy -c stack.yml postgres(或docker-compose -f stack.yml up),等待其完全初始化,然后访问http://swarm-ip:8080http://localhost:8080、 或http://host-ip:8080(根据情况)。

如何扩展此图像

扩展图像的方法有很多种postgres。我们不会尝试支持所有可能的用例,这里仅介绍一些我们认为有用的方法。

环境变量

PostgreSQL 镜像使用了几个容易被忽略的环境变量。唯一需要的变量是POSTGRES_PASSWORD,其余的都是可选的。

警告:仅当您使用空的数据目录启动容器时,Docker 特定变量才会产生效果;任何预先存在的数据库在容器启动时都将保持不变。

POSTGRES_PASSWORD

此环境变量是您使用 PostgreSQL 映像所必需的。它不能为空或未定义。此环境变量设置 PostgreSQL 的超级用户密码。默认超级用户由POSTGRES_USER环境变量定义。

注意 1: PostgreSQL 镜像在本地设置trust身份验证,因此您可能会注意到从(同一容器内)连接时不需要密码localhost。但是,如果从不同的主机/容器连接,则需要密码。

注意 2: 此变量定义 PostgreSQL 实例中的超级用户密码,由脚本在初始容器启动期间设置。它对客户端在运行时可能使用的环境变量initdb没有影响,如 https://www.postgresql.org/docs/14/libpq-envars.html中所述 。如果使用,将指定为单独的环境变量。PGPASSWORD psql PGPASSWORD

POSTGRES_USER

此可选环境变量与 一起使用,用于POSTGRES_PASSWORD设置用户及其密码。此变量将创建具有超级用户权限的指定用户和同名数据库。如果未指定,则将postgres使用 的默认用户。

请注意,如果指定了此参数,PostgreSQL 仍将The files belonging to this database system will be owned by user "postgres"在初始化期间显示。这指的是守护进程以之运行的 Linux 系统用户(来自/etc/passwd图像中)postgres,因此与该选项无关。有关更多详细信息,请参阅标题为“任意注释”POSTGRES_USER的部分。--user

POSTGRES_DB

此可选环境变量可用于为首次启动镜像时创建的默认数据库定义不同的名称。如果未指定,则将POSTGRES_USER使用的值。

POSTGRES_INITDB_ARGS

此可选环境变量可用于将参数发送到postgres initdb。该值是一个空格分隔的参数字符串,正如postgres initdb预期的那样。这对于添加数据页校验和等功能很有用:-e POSTGRES_INITDB_ARGS="--data-checksums"

POSTGRES_INITDB_WALDIR

此可选环境变量可用于定义 Postgres 事务日志的另一个位置。默认情况下,事务日志存储在主 Postgres 数据文件夹 ( PGDATA) 的子目录中。有时可能需要将事务日志存储在不同的目录中,该目录可能由具有不同性能或可靠性特征的存储支持。

注意: 在 PostgreSQL 9.x 上,此变量是POSTGRES_INITDB_XLOGDIR(反映了PostgreSQL 10+ 中标志名称的更改--xlogdir``--waldir)。

POSTGRES_HOST_AUTH_METHOD

此可选变量可用于控制数据库、用户和地址的连接auth-method。如果未指定,则使用密码验证(在 14 以上版本中;在较早版本中)。在未初始化的数据库中,这将通过以下近似行填充:host all all all scram-sha-256 md5 pg_hba.conf

console
echo "host all all all $POSTGRES_HOST_AUTH_METHOD" >> pg_hba.conf

有关可能的值及其含义的更多信息,pg_hba.conf请参阅 PostgreSQL文档

注 1: 不建议使用trust,因为它允许任何人无需密码即可连接,即使设置了密码(如 via POSTGRES_PASSWORD)。有关更多信息,请参阅 PostgreSQL 文档中的_信任身份验证_⁠

注2: 如果设置POSTGRES_HOST_AUTH_METHODtrust,则POSTGRES_PASSWORD不是必需的。

注 3: 如果将其设置为备用值(例如scram-sha-256),则可能需要额外的POSTGRES_INITDB_ARGS数据库才能正确初始化(例如POSTGRES_INITDB_ARGS=--auth-host=scram-sha-256)。

PGDATA

重要提示: 将数据卷安装在/var/lib/postgresql/data而不是/var/lib/postgresql,因为在后者路径上安装时,在重新创建容器时不会保留数据库数据。构建映像的 Dockerfile 声明了一个卷/var/lib/postgresql/data,如果该路径上没有安装数据卷,则容器运行时将自动创建一个匿名卷⁠,该卷不会在容器重新创建时重复使用。数据将写入匿名卷,而不是您想要的数据卷,并且在删除并重新创建容器时不会保留。

此可选变量可用于为数据库文件定义另一个位置(如子目录)。默认值为/var/lib/postgresql/data。如果您使用的数据卷是文件系统挂载点(如 GCE 持久磁盘),或无法由用户更改所有权的远程文件夹postgres(如某些 NFS 挂载),或包含文件夹/文件(例如lost+found),则 Postgresinitdb要求在挂载点内创建一个子目录来包含数据。

例如:

console
$ docker run -d \ --name some-postgres \ -e POSTGRES_PASSWORD=mysecretpassword \ -e PGDATA=/var/lib/postgresql/data/pgdata \ -v /custom/mount:/var/lib/postgresql/data \ postgres

这是一个非 Docker 特有的环境变量。由于该变量由postgres服务器二进制文件使用(请参阅PostgreSQL 文档⁠),因此入口点脚本会将其考虑在内。

Docker 秘密

作为通过环境变量传递敏感信息的替代方法,_FILE可以将其附加到之前列出的某些环境变量中,从而使初始化脚本从容器中存在的文件中加载这些变量的值。具体而言,这可用于从存储在/run/secrets/<secret_name>文件中的 Docker 机密中加载密码。例如:

console
$ docker run --name some-postgres -e POSTGRES_PASSWORD_FILE=/run/secrets/postgres-passwd -d postgres

目前,仅支持POSTGRES_INITDB_ARGSPOSTGRES_PASSWORDPOSTGRES_USERPOSTGRES_DB

初始化脚本

如果您想在从此映像派生的映像中进行其他初始化,请在(必要时创建目录)下添加一个或多个*.sql*.sql.gz*.sh脚本。在入口点调用创建默认用户和数据库后,它将运行任何文件、运行任何可执行脚本并获取在该目录中找到的任何不可执行脚本,以在启动服务之前进行进一步初始化。/docker-entrypoint-initdb.d``initdb``postgres``*.sql``*.sh``*.sh

警告/docker-entrypoint-initdb.d:仅当您使用空数据目录启动容器时,脚本才会运行;容器启动时,任何预先存在的数据库都不会受到影响。一个常见问题是,如果您的某个/docker-entrypoint-initdb.d脚本失败(这将导致入口点脚本退出),并且您的编排器使用已初始化的数据目录重新启动容器,它将不会继续执行您的脚本。

例如,要添加其他用户和数据库,请将以下内容添加到/docker-entrypoint-initdb.d/init-user-db.sh

bash
#!/bin/bash set -e psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL CREATE USER docker; CREATE DATABASE docker; GRANT ALL PRIVILEGES ON DATABASE docker TO docker; EOSQL

这些初始化文件将按照当前语言环境定义的排序名称顺序执行,默认为en_US.utf8。所有*.sql文件都将由 执行POSTGRES_USER,默认为postgres超级用户。建议使用标志以 身份执行脚本psql内运行的任何命令。由于容器内建立的 Unix 套接字连接存在身份验证,因此此用户无需密码即可连接。*.sh``POSTGRES_USER``--username "$POSTGRES_USER"``trust

此外,从docker-library/postgres#253开始,这些初始化脚本以用户身份运行(或以使用标志postgres指定的“半任意用户”身份运行;有关更多详细信息,请参阅标题为“任意说明”的部分)。此外,从docker-library/postgres#440开始,为这些初始化脚本启动的临时守护程序仅在 Unix 套接字上侦听,因此任何使用都应删除主机名部分(例如,请参阅docker-library/postgres#474 (comment) )。--user docker run --user psql

数据库配置

有许多方法可以设置 PostgreSQL 服务器配置。有关可配置内容的信息,请参阅您正在运行的 PostgreSQL 特定版本的PostgreSQL文档。以下是一些设置配置的选项:

  • 使用自定义配置文件。创建一个配置文件并将其放入容器中。如果您需要配置文件的起始位置,则可以使用 PostgreSQL 提供的示例,该示例在容器中可用/usr/share/postgresql/postgresql.conf.sample/usr/local/share/postgresql/postgresql.conf.sample在 Alpine 变体中)。

    • 重要提示: 您必须进行设置listen_addresses = '*',以便其他容器能够访问 postgres。
    console
    $ # get the default config $ docker run -i --rm postgres cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf $ # customize the config $ # run postgres with custom config $ docker run -d --name some-postgres -v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf -e POSTGRES_PASSWORD=mysecretpassword postgres -c 'config_file=/etc/postgresql/postgresql.conf'
  • 直接在运行行上设置选项。入口点脚本的制作目的是将传递给 docker 命令的任何选项都传递给服务器postgres守护进程。从PostgreSQL 文档⁠ 中,.conf我们看到可以通过设置文件中可用的任何选项-c

    console
    $ docker run -d --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword postgres -c shared_buffers=256MB -c max_connections=200

区域设置自定义

您可以使用简单的方法扩展基于 Debian 的图像以Dockerfile设置不同的语言环境。以下示例将默认语言环境设置为de_DE.utf8

dockerfile
FROM postgres:14.3 RUN localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8 ENV LANG de_DE.utf8

由于数据库初始化仅发生在容器启动时,这使我们能够在创建语言之前设置语言。

还值得注意的是,从 Postgres 15 开始的基于 Alpine 的变体支持 ICU 语言环境⁠。以前基于 alpine 的 Postgres 版本不_支持_语言环境;有关更多详细信息,请参阅 musl 文档中的“字符集和语言环境”。

您可以使用在基于 Alpine 的图像中设置区域设置POSTGRES_INITDB_ARGS来设置不同的区域设置。以下示例将新初始化的数据库的默认区域设置设置为de_DE.utf8

console
$ docker run -d -e LANG=de_DE.utf8 -e POSTGRES_INITDB_ARGS="--locale-provider=icu --icu-locale=de-DE" -e POSTGRES_PASSWORD=mysecretpassword postgres:15-alpine

附加扩展

当使用默认(基于 Debian)变体时,安装其他扩展(例如 PostGIS)应该与安装相关包一样简单(请参阅 github.com/postgis/docker-postgis了解 具体示例)。

当使用 Alpine 变体时,任何未在postgres-contrib中列出的 postgres 扩展都需要在您自己的映像中进行编译(再次参阅 github.com/postgis/docker-postgis 了解具体示例)。

任意--user注释

docker-library/postgres#253开始 --user,此镜像支持通过on以 (大多数情况下) 任意用户身份运行docker run。从docker-library/postgres#1018开始,Alpine 变体也是如此。

需要注意的主要警告是,postgres并不关心它以什么 UID 运行(只要的所有者/var/lib/postgresql/data匹配),但initdb_确实_关心(并且需要用户存在于/etc/passwd):

console
$ docker run -it --rm --user www-data -e POSTGRES_PASSWORD=mysecretpassword postgres The files belonging to this database system will be owned by user "www-data". ... ... **Note:** the description for this image is longer than the Hub length limit of 25000, so has been trimmed. The full description can be found at [https://github.com/docker-library/docs/tree/master/postgres/README.md](https://github.com/docker-library/docs/tree/master/postgres/README.md). See also [docker/hub-feedback#238](https://github.com/docker/hub-feedback/issues/238) and [docker/roadmap#475](https://github.com/docker/roadmap/issues/475).
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:DingDangDog

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!