Files
2023-09-22 08:40:00 +08:00

376 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 简介
针对 [PostgreSQL](https://www.postgresql.org) 应用的 Docker 镜像,用于提供 PostgreSQL 服务。
详细信息可参照:[PostgreSQL10手册](http://www.postgres.cn/docs/10/)及[PostgreSQL12手册](http://www.postgres.cn/docs/12/)
<img src="img/postgresql-logo.png" alt="postgresql-logo" style="zoom: 33%;" />
**版本信息:**
- 13
**镜像信息:**
* 镜像地址:
- 阿里云: registry.cn-shenzhen.aliyuncs.com/colovu/postgresql:13
- Colovu Registry: docker.colovu.com/colovu/postgresql:13
- 依赖镜像:colovu/debian:12
> 后续相关命令行默认使用 Aliyun ACR 镜像服务器做说明
## TL;DR
Docker 快速启动命令:
```shell
# 从 Registry 服务器下载镜像并启动
$ docker run -d -e ALLOW_ANONYMOUS=yes --name postgres docker.colovu.com/colovu/postgresql:13
```
- `registry.cn-shenzhen.aliyuncs.com/colovu/postgresql:<TAG>`:镜像名称及版本标签 TAG;标签不指定时默认使用最新版本
Docker-Compose 快速启动命令:
```shell
# 从 Gitee 下载 Compose 文件
$ curl -sSL -o https://gitee.com/colovu/docker-postgres/raw/master/docker-compose.yml
# 从 Github 下载 Compose 文件
$ curl -sSL -o https://raw.githubusercontent.com/colovu/docker-postgres/master/docker-compose.yml
# 创建并启动容器
$ docker-compose up -d
```
---
## 默认对外声明
### 端口
- 5432PostgreSQL 业务客户端访问端口
### 数据卷
镜像默认提供以下数据卷定义:
```shell
/srv/postgresql/conf # 配置文件
/srv/postgresql/data # 数据文件,主要存放应用数据
/srv/postgresql/cert # 证书文件存放目录
/srv/postgresql/log # 日志输出
/var/run/postgresql # 系统运行时文件,如 PID 文件
```
如果需要持久化存储相应数据,需要**在宿主机建立本地目录**,并在使用镜像初始化容器时进行映射。宿主机相关的目录中如果不存在对应应用`postgresql`的子目录或相应数据文件,则容器会在初始化时创建相应目录及文件。
举例:
- 使用宿主机`/host/dir/to/conf`存储配置文件
- 使用宿主机`/host/dir/to/data`存储数据文件
- 使用宿主机`/host/dir/to/log`存储日志文件
创建以上相应的宿主机目录后,容器启动命令中对应的数据卷映射参数类似如下:
```shell
-v /host/dir/to/conf:/srv/postgresql/conf -v /host/dir/to/data:/srv/postgresql/data -v /host/dir/to/log:/srv/postgresql/log
```
使用 Docker Compose 时配置文件类似如下:
```yaml
services:
postgresql:
...
volumes:
- /host/dir/to/conf:/srv/postgresql/conf
- /host/dir/to/data:/srv/postgresql/data
- /host/dir/to/log:/srv/postgresql/log
...
```
> 注意:应用需要使用的子目录会自动创建。
## 使用说明
### 启动容器
#### 通过默认方式启动
```shell
$ docker run --name some-postgres -e PG_PASSWORD=mysecretpassword -d -p 5432:5432 registry.cn-shenzhen.aliyuncs.com/colovu/postgresql:13
```
- 由容器执行默认的`entry.sh`脚本,并生成默认的用户及数据文件
- `some-postgres`:容器名;命名后,可以直接使用该名字进行操作
- `mysecretpassword`:数据库密码
#### 通过`docker-compose`方式启动
docker-cpmpose.yml 参考:
```yaml
# 使用 postgres/example 作为用户名/密码
version: '3.8'
services:
db:
image: registry.cn-shenzhen.aliyuncs.com/colovu/postgresql:13
restart: always
environment:
PG_PASSWORD: example
```
## 镜像扩展使用
有多种方式可以扩展使用`postgresql`镜像;这里仅列举部分,在实际使用时,不一定需要全部使用。
### 环境变量
PostgreSQL镜像定义了许多环境变量,但并不是所有都必须使用的;如果需要定制化启动镜像,可以选择需要的环境变量进行设置。
> 注意:部分环境变量仅在初始化时起作用。针对已经存在数据目录的情况,环境变量会被跳过。
### 自动变量替换
针对应用配置文件中的配置项,支持由环境变量名自动替换生成,该类环境变量需要使用统一前缀,定义规则为:`PG_CFG_*=<val>`
- `PG_CFG_`:环境变量自动替换标识,具备该前缀的环境变量会被自动处理并更新至配置文件
- `*`:配置文件中对应的配置项名,大小写需要符合实际参数名要求;特殊字符需要符合`特殊字符替换规则`
- `<val>`:配置项对应值
**特殊字符替换规则**
因为 Shell 变量只能以字母、数字和下划线组成,针对'xml'、'ini'等配置文件中使用的'.'、'-'等特殊字符,需要进行重定义及转换。预定义如下:
+ `_` ==> `_` : 应用配置属性中的`_`(下划线),与环境变量相同
+ `__` ==> `.` : 应用配置属性中的`.`(半角点),在环境变量中由`__`(双下划线)表示
+ `___` ==> `-` : 应用配置属性中的`-`(中划线),在环境变量中由`___`(三下划线)表示
例如:
```shell
# 容器启动时的环境变量(大小写无关)
PG_CFG_MIN_WAL_SIZE=100MB
PG_CFG_max_wal_size="400MB"
# 容器启动后,应用配置文件中对应配置项生效,且设置为相应值:
min_wal_size = '100MB'
max_wal_size = '400MB'
```
### 常规配置参数
常规配置参数用来配置容器基本属性,一般情况下需要设置,主要包括:
- `PG_USERNAME`:默认值:**postgres**。设置用户名,可针对不同应用设置不同用户名
- `PG_PASSWORD`:默认值:**无**。设置用户密码,生产环境中不应当为空
- `PG_DATABASE`:默认值:**postgres**。设置用户默认使用的数据库
- `PG_POSTGRES_PASSWORD`:默认值:**无**。设置超级用户密码,未设置时,默认密码同`PG_PASSWORD`
### 常规可选参数
如果没有必要,可选配置参数可以不用定义,直接使用对应的默认值,主要包括:
- `ENV_DEBUG`:默认值:**false**。设置是否输出容器调试信息。可选值:false、no、true、yes
- `ALLOW_ANONYMOUS`:默认值:**no**。设置是否允许匿名链接。可选值:false、no、true、yes
- `TZ`:默认值:**Asia/Shanghai**。设置默认时区
- `PG_USER_IP4_RANGE`:默认值:**0.0.0.0/0**。设置允许访问的 IPv4 地址范围
- `PG_USER_IP6_RANGE`:默认值:**::0/0**。设置允许访问的 IPv6 地址范围
- `PG_INITSCRIPTS_USERNAME`:默认值:**`PG_USERNAME`**。设置数据库SQL初始化使用的用户名
- `PG_INITSCRIPTS_PASSWORD`:默认值:**`PG_PASSWORD`**。设置数据库SQL初始化时的用户密码
### 集群配置参数
配置服务为集群工作模式时,通过以下参数进行配置:
- `PG_REPLICATION_MODE`:默认值:**primary**。设置当前容器中服务的工作模式。可选值:primary、standby
**Primary(Master)配置:**
- `PG_SYNCHRONOUS_REPLICAS_NUM`:默认值:**0**。设置备机的数量,从备机列表中选取
- `PG_SYNCHRONOUS_REPLICAS_METHOD`:默认值:**无**。设置备机选择模式。可选值:无、FIRST、ANY
- `PG_SYNCHRONOUS_REPLICAS_NAMES`:默认值:**无**。设置备机列表
- `PG_CFG_MAX_WAL_SENDERS`:默认值:**10**。
- `PG_CFG_WAL_LEVEL`:默认值:**logical**。
- `PG_CFG_WAL_LOG_HINTS`:默认值:**on**。
**Standby(Slave)配置:**
- `PG_REPLICATION_APP_NAME`:默认值:**cvcluster**。设置本机应用默认名称
- `PG_REPLICATION_HOST`:默认值:**无**。设置 Master 服务地址
- `PG_REPLICATION_PORT`:默认值:**5432**。设置 Master 服务端口
- `PG_REPLICATION_USER`:默认值:**无**。设置访问 Master 的用户名
- `PG_REPLICATION_PASSWORD`:默认值:**无**。设置访问 Master 用户的密码
- `PG_REPLICATION_CONNECT_TIMEOUT`:默认值:**10**。设置连接超时时间
默认,配置允许从备机备份,参考[官方说明](http://www.postgres.cn/docs/9.4/app-pgbasebackup.html)
- `PG_CFG_FULL_PAGE_WRITES`:默认值:**on**。
- `PG_CFG_HOT_STANDBY`:默认值:**on**。
- `PG_CFG_MAX_WAL_SENDERS`:默认值:**16**。
### TLS配置参数
配置服务使用 TLS 加密时,可通过`PG_CFG_SSL_*`相关参数进行配置,容器启动时会自动替换`postgresql.conf`中对应配置项。
TLS 加密使用的相关秘钥文件,默认存放在容器的`/srv/postgresql/cert`目录中,需提前进行映射。
- `PG_CFG_SSL`:默认值:**off**。设置是否使用 SSL 加密。可选值:off / on
### LDAP认证配置参数
配置服务使用 LDAP 进行用户认证时,通过以下参数进行配置:
- `PG_ENABLE_LDAP`:默认值:**no**。设置是否使用 LDAP 认证。可选值:yes / no
以 URL 方式配置认证地址:
- `PG_LDAP_URL`:默认值:**无**。设置 LDAP 连接地址,如果配置该参数,则后续单独的配置信息不用配置
或,以单独参数方式配置认证地址:
- `PG_LDAP_PREFIX`:默认值:**无**。设置前缀
- `PG_LDAP_SUFFIX`:默认值:**无**。设置后缀
- `PG_LDAP_SERVER`:默认值:**无**。设置 LDAP 服务器访问 IP
- `PG_LDAP_PORT`:默认值:**无**。设置 LDAP 服务器访问端口
- `PG_LDAP_SCHEME`:默认值:**无**。
- `PG_LDAP_TLS`:默认值:**无**。设置 LDAP 服务器使用启用 TLS
- `PG_LDAP_BASE_DN`:默认值:**无**。设置搜索的基 DN
- `PG_LDAP_BIND_DN`:默认值:**无**。设置绑定用户的 DN
- `PG_LDAP_BIND_PASSWORD`:默认值:**无**。设置绑定用户的密码
- `PG_LDAP_SEARCH_ATTR`:默认值:**无**。设置搜索参数
- `PG_LDAP_SEARCH_FILTER`:默认值:**无**。设置搜索过滤器
### 初始化脚本
如果需要在使用当前镜像时,增加一些附加的初始化操作,可以将相应的`*.sql``*.sql.gz``*.sh`脚本文件放置在配置文件目录的`initdb.d`子目录中(使用数据卷映射方式时,可先创建相应的目录)。容器在初始化时,会执行所有在`initdb.d`目录下的`*.sql`及可执行`*.sh`脚本,并`source`所有不可执行的`*.sh`脚本,执行完成后,启动`postgres`服务。
> 注意:
>
> - 在`initdb.d`目录下的脚本,仅在数据库存储目录为空时才会执行。如果部分脚本执行失败(会导致容器退出),则可能数据库目录已经存在;此时,重新启动容器,则不会继续执行`initdb.d`目录下的初始化脚本。
### 数据库配置
有多种方式可以配置 PostgreSQL 服务器。详细信息可参考相关[docs](https://www.postgresql.org/docs/current/static/runtime-config.html)文档。部分常用配置项如下:
- 使用自定义的配置文件。可将容器内的模板配置文件 `/usr/local/postgresql/share/postgresql.conf.sample`导出后修改,并重新映射以启动容器。
```shell
$ # 获取配置文件模板,存储为当前目录的my-postgres.conf
$ docker run -i --rm registry.cn-shenzhen.aliyuncs.com/colovu/postgresql:13 cat /usr/local/postgresql/share/postgresql.conf.sample > my-postgres.conf
$ # 个性化修改配置信息,至少增加`listen_addresses='*'`以确保其他容器可以访问
$ echo "listen_addresses='*'" >> my-postgres.conf
$ # 使用定制后的配置文件启动容器
$ docker run -d --name some-postgres -v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf -e POSTGRES_PASSWORD=mysecretpassword registry.cn-shenzhen.aliyuncs.com/colovu/postgresql:13 -c 'config_file=/etc/postgresql/postgresql.conf'
```
- 在命令行中设置相应参数。`entry.sh`基本会将所有的启动时传递给 Docker 的配置参数传递给 Postgres 服务进程。从官方 [docs](https://www.postgresql.org/docs/current/static/app-postgres.html)文档可以看出,所有在 `.conf`文件中的配置项都可以使用`-c`进行设置。
```shell
$ docker run -d --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword registry.cn-shenzhen.aliyuncs.com/colovu/postgresql:13 -c 'shared_buffers=256MB' -c 'max_connections=200'
```
> 注意:配置文件至少修改`listen_addresses='*'`以确保其他容器可以访问
### 扩展功能模块
使用默认的镜像时,安装扩展功能模块比较简单,可以参考文档 [github.com/postgis/docker-postgis](https://github.com/postgis/docker-postgis/blob/4eb614133d6aa87bfc5c952d24b7eb1f499e5c7c/12-3.0/Dockerfile) 。
使用基于Alpine的镜像时,没有在 [postgres-contrib](https://www.postgresql.org/docs/10/static/contrib.html) 列明的模块需要自己在镜像中编译,参见文档 [github.com/postgis/docker-postgis](https://github.com/postgis/docker-postgis/blob/4eb614133d6aa87bfc5c952d24b7eb1f499e5c7c/12-3.0/alpine/Dockerfile) 。
## 使用预警
如果不存在数据库,容器启动时,会花费一定时间创建默认的数据库,在创建期间,容器不接受访问链接。如果使用`docker-compose`方式同时启动多个容器时,可能会产生问题。
容器默认的`/dev/shm` 大小为`64MB`。如果在容器运行过程中共享内存不足,可能会遇到错误``。针对这种情况,可以通过在启动容器时传递类似参数 [--shm-size=256MB ](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources) 进行调整。
在 Swarm 模式中使用`overlay`网络模式时,针对长时间运行的IDLE链接,可能会遇到`IPVS connection timeouts`错误,可以参照以下信息解决: ["IPVS connection timeout issue" in the Docker Success Center](https://success.docker.com/article/ipvs-connection-timeout-issue) 。
## 如何存储数据
**重要**:针对运行在 Docker 容器中的应用,有几种不同的数据存储方式。如:
- 让 Docker 本身管理存储的数据(在容器内)。这是一种简单,也是默认的存储方式。这种方式存在的问题是:在宿主机上很难使用工具对存储的数据定位及处理。
- 在宿主机上创建数据存储目录(在容器外)。使用这种方式,可以比较容易的在宿主机上使用工具对数据文件进行分析及处理。这种方式存在的问题是:使用镜像的用户需要保证相关目录的存在和权限的正确性。
详细说明,可参考 Docker 的相关文档或讨论区。简单举例使用方式:
1. 在宿主机上合适位置创建数据存储目录,如:`/absolute/host/datadir`.
2. 启动容器:
```shell
$ docker run --name <instance-name> -v /absolute/host/datadir:/container/volume/dir -d image-name:tag
```
其中,`-v /absolute/host/datadir:/container/volume/dir`参数部分,会将宿主机的`/absolute/host/datadir`目录挂载为容器中的`/var/lib/postgresql/data`目录。
## 安全
### 用户及密码
PostgreSQL 镜像默认禁用了无密码访问功能,在实际生产环境中建议使用用户名及密码控制访问;如果为了测试需要,可以使用以下环境变量启用无密码访问功能:
```shell
ALLOW_ANONYMOUS=yes
```
通过配置环境变量`PG_PASSWORD`,可以启用基于密码的用户认证功能。命令行使用参考:
```shell
$ docker run -d -e PG_USERNAME=postgres -e PG_PASSWORD=colovu registry.cn-shenzhen.aliyuncs.com/colovu/postgresql:13
```
使用 Docker-Compose 时,`docker-compose.yml`应包含类似如下配置:
```yaml
services:
postgres:
...
environment:
- PG_USERNAME=postgres
- PG_PASSWORD=colovu
...
```
### 容器安全
本容器默认使用`non-root`运行应用,以加强容器的安全性。在使用`non-root`用户运行容器时,相关的资源访问会受限;应用仅能操作镜像创建时指定的路径及数据。使用`non-root`方式的容器,更适合在生产环境中使用。
如果需要赋予容器内应用访问外部设备的权限,可以使用以下两种方式:
- 启动参数增加`--privileged=true`选项
- 针对特定权限需要使用`--cap-add`单独增加特定赋权,如:ALL、NET_ADMIN、NET_RAW
如果需要切换为`root`方式运行应用,可以在启动命令中增加`-u root`以指定运行的用户。
## 注意事项
- 容器中应用的启动参数不能配置为后台运行,如果应用使用后台方式运行,则容器的启动命令会在运行后自动退出,从而导致容器退出
## 更新记录
- 2023/8/17: 变更应用版本为 v13.12
- 2023/8/17: 变更应用版本为 v13.11
- 2021/1/1 (1.0): 初始版本
## 参考
- [官方介绍](http://www.postgresql.org/docs/9.5/interactive/app-initdb.html)
- [官方中文手册](http://www.postgres.cn/v2/document)
----
本文原始来源 [Endial Fang](https://github.com/colovu) @ [Github.com](https://github.com)