DockerHub 仓库中的原生 PostgreSQL 镜像操作说明(一)原文翻译

news/2024/7/9 20:43:52 标签: postgresql, 数据库, docker

原生的 PostgreSQL 镜像的制作还是比较合理的,推荐大家深入研究这个镜像的使用操作,能熟悉构建脚本最好不过。
原文链接:https://hub.docker.com/_/postgres

如何使用这个镜像

启动一个 postgres 实例

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

入口点(entrypoint)会使用 initdb 命令创建默认的 postgres 用户和数据库

postgres 数据库是供用户、实用工具程序和第三方应用程序使用的默认数据库

postgresql.org/docs

… 或者通过psql

$ 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.com/engine/reference/commandline/stack_deploy/">docker stack deploydocker-compose

例子用于 postgresstack.yml

# Use postgres/example user/password credentials
version: '3.1'

services:

  db:
    image: postgres
    restart: always
    environment:
      POSTGRES_PASSWORD: example

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-30Sx9bu8-1677600497745)(null)]

运行docker stack deploy -c stack.yml postgres(或 docker-compose -f stack.yml up 等待它初始化完成,然后访问 http://swarm-ip:8080, http://localhost:8080, 或 http://host-ip:8080(视情况而定)

如何扩展这个镜像

有许多方法可以扩展postgres镜像。在不尝试支持每种可能的用例的情况下,以下是我们发现有用的一些方法。

环境变量

PostgreSQL 镜像使用了几个环境变量,这些变量很容易被忽略。唯一必需的变量是POSTGRES_PASSWORD,其余变量是可选的。
警告:仅当你使用一个空的数据目录启动容器时,这些 Docker 特定的变量才会生效;任何现有的数据库都将在容器启动时保持不变。

POSTGRES_PASSWORD

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

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

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

POSTGRES_USER

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

注意,如果指定了该参数,PostgreSQL 仍然会显示属于该数据库系统的文件将在初始化过程中由用户“postgres”所有。这是指 postgres 守护进程以 Linux 系统用户(来自镜像中的/etc/passwd)运行的,因此与这个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)。如果未指定,则使用scram-sha-256密码身份验证(这是在 14+ 版本中;而早期版本中则使用MD5)。在未初始化的数据库上,这将通过以下近似行填充 pg_hba.conf:

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

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

注意1:不建议使用trust,因为它允许任何人在没有密码的情况下连接,即使设置了密码(例如通过POSTGRES_PASSWORD)。有关详细信息,请参阅 PostgreSQL 文档中的 Trust 身份认证。

注意2:如果将POSTGRES_HOST_AUTH_METHOD设置为trust,则不需要POSTGRES_PASSWORD

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

PGDATA

该可选变量可用于定义另一个位置(例如一个子目录)来存储数据库文件。默认情况下为/var/lib/postgresql/data。如果你使用的数据卷是文件系统挂载点(例如 GCE 持久磁盘)或无法修改所有权(chowned)为postgres用户的远程文件夹(例如某些 NFS 挂载),则 Postgres 的 initdb 建议创建一个子目录来包含数据。

例如:

$ 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 文档),因此入口点(entrypoint)脚本会对它加以重视。

Docker 私密信息

作为传递敏感信息的替代方法,可以在一些先前列出的环境变量后添加_FILE,从容器中存在的文件中加载这些变量的值,从而使初始化脚本从文件中读取密码。特别地,这可用于从存储在/run/secrets/<secret_name>文件中的 Docker 私密消息中加载密码。例如:

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

目前,这仅适用于POSTGRES_INITDB_ARGSPOSTGRES_PASSWORDPOSTGRES_USER、和POSTGRES_DB

初始化脚本

如果你想要在派生自此镜像的镜像中进行额外的初始化,请在 /docker-entrypoint-initdb.d 目录下添加一个或多个 *.sql*.sql.gz*.sh 脚本(如果必要,创建该目录)。在 entrypoint 调用 initdb 创建默认的 postgres 用户和数据库之后,它将运行任何 *.sql 文件、运行任何可执行的 *.sh 脚本,并在该目录中 source 任何非可执行的 *.sh 脚本以在启动服务之前进行进一步的初始化。

警告:仅在使用空数据目录启动容器时,/docker-entrypoint-initdb.d 中的脚本才会被运行;任何现存的数据库都将在容器启动时保持不变。一个常见的问题是,如果你的 /docker-entrypoint-initdb.d 中的脚本失败(这将导致 entrypoint 脚本退出),并且你的编排器使用已初始化的数据目录重新启动容器,它将不会继续运行您的脚本。

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

#!/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 超级用户。建议在 *.sh 脚本中运行的任何 psql 命令都使用 --username "$POSTGRES_USER" 标志以 POSTGRES_USER 身份执行。由于容器内 Unix 套接字连接的 trust 身份验证存在,该用户将能够连接而无需密码。

此外,截至 docker-library/postgres#253,这些初始化脚本是以 postgres 用户的身份运行的(或使用 --user 标志指定给 docker run 的“半随意用户”;有关更多详细信息,请参见“任意 --user 注意事项”一节)。另外,自 docker-library/postgres#440 起,为这些初始化脚本启动的临时守护程序仅在 Unix 套接字上侦听,因此任何 psql 的使用都应该删除主机名(hostname)部分(请参见 docker-library/postgres#474(注释)的示例)。

数据库配置

有很多设置 PostgreSQL 服务器配置的方法。有关可配置项的信息,请查看你正在运行的 PostgreSQL 版本的PostgreSQL文档。以下是几种设置配置的选项:

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

    • 重要提示:你必须设置listen_addresses = '*',以便其他容器可以访问 postgres。
    $ # 获取默认配置
    $ docker run -i --rm postgres cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf
    
    $ # 自定义这个配置(即:my-postgres.conf)
    
    $ # 使用自定义配置运行 postgres
    $ 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来设置。

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

语言环境定制

你可以使用一个简单的Dockerfile扩展基于 Debian 的镜像,以设置不同的语言环境。以下示例将默认语言环境设置为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 文档中的“字符集和语言环境”。

你可以使用POSTGRES_INITDB_ARGS在基于 alpine 的镜像中设置语言环境,来设置一个不同的语言环境。下面的例子将一个新初始化的数据库的默认区域设置为de_DE.utf8

$ 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开始,该镜像支持通过 docker run 上的 --user 以(大多数)任意用户身份运行。从docker-library/postgres#1018开始,这也适用于Alpine变体。

要注意的主要注意事项是 postgres 不关心它作为什么 UID 运行(只要 /var/lib/postgresql/data 的所有者匹配即可),但是 initdb 确实关心(并需要用户存在于 /etc/passwd 中):

$ docker run -it --rm --user www-data -e POSTGRES_PASSWORD=mysecretpassword postgres
这个数据库系统的文件将属于用户“www-data”。
...

$ docker run -it --rm --user 1000:1000 -e POSTGRES_PASSWORD=mysecretpassword postgres
initdb: could not look up effective user ID 1000: user does not exist

解决此问题的三种最简单方法:

  1. 允许镜像使用 nss_wrapper 库来“伪造”/etc/passwd内容(有关详细信息,请参见docker-library/postgres#448)

  2. 从宿主机上以只读方式绑定挂载/etc/passwd如果你需要的 UID 是宿主机上的有效用户):

    $ docker run -it --rm --user "$(id -u):$(id -g)" -v /etc/passwd:/etc/passwd:ro -e POSTGRES_PASSWORD=mysecretpassword postgres
    这个数据库系统的文件将属于用户“jsmith”。
    ...
    
  3. 与最终运行分开,单独先初始化目标目录(在两者中间插入一个chown操作):

    $ docker volume create pgdata
    $ docker run -it --rm -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=mysecretpassword postgres
    属于该数据库系统的文件将由用户“postgres”拥有。
    ...
    (如果 PostgreSQL 成功初始化并等待连接,那么可以停止它)
    $ docker run -it --rm -v pgdata:/var/lib/postgresql/data bash chown -R 1000:1000 /var/lib/postgresql/data
    $ docker run -it --rm --user 1000:1000 -v pgdata:/var/lib/postgresql/data postgres
    LOG:  database system was shut down at 2017-01-20 00:03:23 UTC
    LOG:  MultiXact member wraparound protections are now enabled
    LOG:  autovacuum launcher started
    LOG:  database system is ready to accept connections
    

注意事项

如果在容器启动postgres时没有数据库,那么postgres将为你创建此默认数据库。虽然这是postgres的预期行为,但这意味着在此期间它将不接受传入连接。当使用自动化工具(如:docker-compose)同时启动多个容器时,这可能会引起问题。

还请注意,容器的默认/dev/shm大小为 64MB。如果共享内存用尽,您将遇到ERROR:could not resize shared memory segment ...: No space left on device的错误。你需要向docker run传递--shm-size=256MB之类的参数,或者在docker-compose中指定。

数据存储位置

重要提示:有多种方法可以存储应用程序在 Docker 容器中运行时使用的数据。我们鼓励postgres镜像的用户熟悉可用的选项,包括:

  • 让 Docker 使用自己的内部卷管理将数据库文件写入宿主机系统上的磁盘,以管理数据库数据的存储。这是默认的方式,对用户而言易于使用而且相当透明。缺点是,对于直接运行在宿主机系统上的工具和应用程序(即容器外部),文件可能难以定位。
  • 在宿主机系统(容器外部)上创建一个数据目录,并将其挂载到容器内部可见的目录。这将在宿主机系统上的一个已知位置放置数据库文件,并使宿主机系统上的工具和应用程序很容易访问这些文件。缺点是用户需要确保目录存在,并且在宿主机系统上正确设置了目录权限和其他安全机制。

Docker文档是理解不同存储选项和变化的一个很好的起点,有许多博客和论坛帖子讨论并给出了这方面的建议。在这里我们将简单地展示上述后一个选项的基本过程:

  1. 在宿主机系统上适当的卷上创建一个数据目录,例如:/my/own/datadir

  2. 以以下方式启动你的postgres容器:

    $ docker run --name some-postgres -v /my/own/datadir:/var/lib/postgresql/data -e POSTGRES_PASSWORD=mysecretpassword -d postgres:tag
    

该命令的-v /my/own/datadir:/var/lib/postgresql/data部分将底层宿主机系统中的/my/own/datadir目录挂载为容器中的/var/lib/postgresql/data,默认情况下 PostgreSQL 将在这里写入它的数据文件。


http://www.niftyadmin.cn/n/110007.html

相关文章

「TCG 规范解读」基础设施架构和协议 (4)

可信计算组织&#xff08;Ttrusted Computing Group,TCG&#xff09;是一个非盈利的工业标准组织&#xff0c;它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立&#xff0c;并采纳了由可信计算平台联盟&#xff08;the Trusted Computing Platform Alli…

SpringCloud(微服务)学习篇(一)

SpringCloud(微服务)学习篇(一) 1 nacos的下载和配置 1.1 进入官网 nacos官网 1.2 点击nacos➡点击最新稳定版本 1.3 往下翻并点击nacos-server-2.2.0.zip,此时就已经开始下载了 1.4 把下载好的压缩包解压到没有中文路径的目录里面 1.5 修改application.properties文件 1.…

【R+VIC模型】融合实践技术应用及未来气候变化模型预测

在气候变化问题日益严重的今天&#xff0c;水文模型在防洪规划&#xff0c;未来预测等方面发挥着不可替代的重要作用。目前&#xff0c;无论是工程实践或是科学研究中都存在很多著名的水文模型如SWAT/HSPF/HEC-HMS等。虽然&#xff0c;这些软件有各自的优点&#xff1b;但是&am…

CHAPTER 1 Linux 集群

集群1 集群介绍2 集群分类1. 高可用性集群&#xff08;High Availability Cluster&#xff09;HA2. 负载均衡集群&#xff08;Load Balance Cluster&#xff09;LB3. 高性能集群&#xff08;High Performance Computing Cluster&#xff09;HPC3 HA集群逻辑架构1. 信息层/基础架…

化繁为简高效部署 华为云发布部署服务CodeArts Deploy

​随着互联网、数字化的发展&#xff0c;公司机构与各类企业往往需要进行大量频繁的软件部署&#xff0c;部署设备类型多样&#xff0c;如&#xff1a;本地机器、云上裸金属服务器、云上虚拟机与容器等。面对多种部署模式、分布式复杂运行环境&#xff0c;如何用最短时间、高质…

vue模板语法和数据绑定和el、data的两种

vue模板语法有两大类&#xff1a; 1.插值语法&#xff1a; 功能&#xff1a;用于解拆标签体内容 写法&#xff1a;{{xxx}}&#xff0c;xxx是js表达式&#xff0c;且可以直接读取到data中的所有属性 2.指令语法&#xff1a; 功能&#xff1a;用于解拆标签&#xff08;包括&…

操作系统发展历程

手工操作阶段(此阶段无操作系统) 用户在计算机上算题的所有工作都要人工干预。该阶段有两个突出缺点&#xff1a; 用户独占全机&#xff0c;虽然不会出现因资源已被其他用户占用而等待的现象&#xff0c;但资源利用率低。 CPU等待手工操作&#xff0c;CPU的利用不充分 唯一的…

4.文件管理

文章目录1、初识文件管理1.1、回顾1.2、文件的属性1.3、无结构文件/有结构文件1.4、文件之间应该怎样组织起来&#xff1f;1.5、操作系统应该向上提供哪些功能&#xff1f;1.6、从上往下看&#xff0c;文件应如何存放在外存&#xff1f;1.7、其他需要由操作系统实现的文件管理功…