ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OpenReplay 自托管 PostgreSQL 18 Docker 镜像构建与 Kubernetes 部署指南

OpenReplay 自托管 PostgreSQL 18 Docker 镜像构建与 Kubernetes 部署指南 可观测性开发工具前端后端【免费下载链接】openreplaySession replay, cobrowsing and product analytics you can self-host. Best for reproducing issues and iterating on your product.项目地址https://gitcode.com/gh_mirrors/op/openreplay点击查看免费下载OpenReplay 仓库在 scripts/dockerfiles/postgres/18 目录下维护了一套 Bitnami 风格的 PostgreSQL 容器镜像方案它基于 Chainguard Wolfi 基础镜像构建 PostgreSQL 18.6以非 root 用户UID 1001运行预置了pg_stat_statements、pg_trgm、pgcrypto、pgaudit等扩展并配套完整的 Makefile 构建/测试流水线与 Kubernetes 部署模板。本文将围绕该目录中的 README.md 与 DEPLOYMENT.md 展开结合 Dockerfile、entrypoint 脚本和测试脚本的源码实现讲解如何构建镜像、本地运行、配置环境变量、部署到 Kubernetes以及如何验证扩展与数据操作的正确性帮助你在自托管 OpenReplay 或任何需要 Bitnami 兼容 PostgreSQL 的环境中快速落地这套方案。镜像设计目标Bitnami 兼容 非 root 安全运行OpenReplay 的 PostgreSQL 容器镜像在设计上有两个核心约束一是与 Bitnami 风格的部署模式完全兼容目录结构、环境变量命名、挂载点约定二是默认以非 root 用户运行从而满足 Kubernetes 平台的安全审计要求。从 Dockerfile 可以看到镜像的完整构建链路FROM cgr.dev/chainguard/wolfi-base # Install PostgreSQL 18 with contrib extensions and locale support RUN apk add --no-cache \ postgresql-18 \ postgresql-18-contrib \ postgresql-18-client \ pgaudit-18 \ glibc-locale-en \ tini \ bash \ addgroup -g 1001 postgres || true \ adduser -u 1001 -G postgres -s /bin/bash -D postgres || true \ mkdir -p /opt/bitnami/postgresql/bin \ mkdir -p /opt/bitnami/postgresql/conf \ mkdir -p /opt/bitnami/postgresql/tmp \ mkdir -p /bitnami/postgresql/data \ ln -s /usr/bin/postgres /opt/bitnami/postgresql/bin/postgres \ ln -s /usr/bin/pg_ctl /opt/bitnami/postgresql/bin/pg_ctl \ ln -s /usr/bin/initdb /opt/bitnami/postgresql/bin/initdb \ ln -s /usr/bin/psql /opt/bitnami/postgresql/bin/psql \ ln -s /usr/bin/pg_isready /opt/bitnami/postgresql/bin/pg_isready \ chown -R 1001:1001 /opt/bitnami/postgresql \ chown -R 1001:1001 /bitnami/postgresql ENV LANGen_US.UTF-8 \ LANGUAGEen_US:en \ LC_ALLen_US.UTF-8 ENV BITNAMI_DEBUGfalse \ POSTGRESQL_PORT_NUMBER5432 \ POSTGRESQL_VOLUME_DIR/bitnami/postgresql \ PGDATA/bitnami/postgresql/data \ POSTGRES_USERpostgres \ POSTGRES_DBpostgres \ POSTGRESQL_ENABLE_LDAPno \ POSTGRESQL_ENABLE_TLSno \ POSTGRESQL_LOG_HOSTNAMEfalse \ POSTGRESQL_LOG_CONNECTIONSfalse \ POSTGRESQL_LOG_DISCONNECTIONSfalse \ POSTGRESQL_CLIENT_MIN_MESSAGESerror \ POSTGRESQL_SHARED_PRELOAD_LIBRARIESpgaudit,pg_stat_statements COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod x /usr/local/bin/docker-entrypoint.sh USER 1001 EXPOSE 5432 ENTRYPOINT [/sbin/tini, --, docker-entrypoint.sh] CMD [postgres]关键设计点基础镜像选用cgr.dev/chainguard/wolfi-baseWolfi 是一个面向容器的、以安全为核心的开源 Linux 发行版并通过apk安装postgresql-18、postgresql-18-contrib、postgresql-18-client与pgaudit-18其中 contrib 包保证了后续可通过CREATE EXTENSION使用全部标准 contrib 扩展。用户与权限显式创建 GID/UID 均为 1001 的postgres用户构建期即把/opt/bitnami/postgresql和/bitnami/postgresql的属主设为1001:1001最后通过USER 1001切换到非 root 运行。进程管理使用tini作为 init 进程ENTRYPOINT [/sbin/tini, --, docker-entrypoint.sh]确保信号转发与僵尸进程回收行为正确。Bitnami 路径兼容通过符号链接把/usr/bin下的postgres、pg_ctl、initdb、psql、pg_isready映射到/opt/bitnami/postgresql/bin/与 Bitnami 镜像的二进制布局保持一致。注意README 标题写的是 PostgreSQL 17但当前 18 目录对应的 Dockerfile 明确安装的是postgresql-18含pgaudit-18Makefile 默认version ? 18。仓库同时维护 17 目录作为 PostgreSQL 17 版本两者目录结构、entrypoint 与部署方式完全一致本文以 18 目录为准。目录结构与启动命令镜像的容器文件系统采用配置不落盘、数据单独持久化的 Bitnami 风格布局# Bitnami-compatible structure (container filesystem) /opt/bitnami/postgresql/ ├── bin/ # PostgreSQL binaries (symlinks) │ ├── postgres │ ├── pg_ctl │ ├── initdb │ └── psql ├── conf/ # Configuration files (not in volume) │ ├── postgresql.conf │ └── pg_hba.conf └── tmp/ # Runtime files └── postgresql.pid # Volume mount (persisted data only) /bitnami/postgresql/ └── data/ # PostgreSQL data directory (PGDATA)这套布局带来的直接收益是数据目录与配置文件分离。postgresql.conf与pg_hba.conf存放在容器的/opt/bitnami/postgresql/conf/不随数据卷持久化因此数据可以在容器重建、镜像升级时完整保留配置更新可以通过重新构建镜像完成不会污染已有数据数据卷挂载点固定为/bitnami/postgresql与 Bitnami 生态的其他工具链无缝对接。容器启动 PostgreSQL 的实际命令来自 docker-entrypoint.sh/opt/bitnami/postgresql/bin/postgres \ -D /bitnami/postgresql/data \ --config-file/opt/bitnami/postgresql/conf/postgresql.conf \ --external_pid_file/opt/bitnami/postgresql/tmp/postgresql.pid \ --hba_file/opt/bitnami/postgresql/conf/pg_hba.confentrypoint 脚本约定当容器命令为postgres即$1等于postgres时走完整的配置 启动流程否则把剩余参数直接透传执行exec $方便调试时覆盖容器入口命令。构建镜像make build 与参数覆盖项目通过 Makefile 统一封装镜像构建支持通过变量覆盖仓库名、镜像名与版本号# Build with default settings (local/postgresql:18) make build # Build with custom repo/name/version make build repomyrepo namepostgres version18 # Produces: myrepo/postgres:18Makefile 中定义的默认变量如下变量默认值说明builderpodman容器构建工具可覆盖为dockerrepolocal镜像仓库前缀namepostgresql镜像名version18版本标签image$(repo)/$(name):$(version)最终镜像全名实际执行的是$(builder) build -t $(image) .即在 18 目录内以仓库根目录下对应 Dockerfile 构建。如果你习惯使用 Docker 而非 Podman直接执行make build builderdocker本地运行make dev 与手动启动一键交互式运行make devdev目标会先执行构建然后以交互模式启动容器Makefilepodman run -it --rm --network host \ -e POSTGRES_PASSWORDpostgres123 \ -v postgresql-data:/bitnami/postgresql \ local/postgresql:18这里的关键点--network host让容器直接复用宿主机网络本地开发时可通过localhost:5432直接连接-v postgresql-data:/bitnami/postgresql挂载命名卷数据持久化到宿主机通过-e POSTGRES_PASSWORDpostgres123注入超级用户密码entrypoint 强制要求未设置会直接报错退出见下文初始化流程。手动启动脱离 Makefilepodman run -d --name postgres \ -p 5432:5432 \ -e POSTGRES_PASSWORDpostgres123 \ -v pgdata:/bitnami/postgresql \ local/postgresql:18连接验证podman exec -it postgres psql -U postgres -d postgres环境变量详解镜像通过环境变量完成全部运行时配置既支持 Bitnami 风格的POSTGRESQL_*命名也兼容经典的POSTGRES_*命名。完整变量清单如下默认值以 Dockerfile 为准环境变量默认值说明POSTGRES_USERpostgresPostgreSQL 超级用户名POSTGRES_PASSWORD无必填超级用户密码entrypoint 同时兼容POSTGRESQL_PASSWORD优先取POSTGRES_PASSWORDPOSTGRES_DBpostgres默认创建的数据库名若与postgres不同首次初始化时会自动CREATE DATABASEPOSTGRESQL_PORT_NUMBER5432PostgreSQL 监听端口POSTGRESQL_VOLUME_DIR/bitnami/postgresql数据卷挂载目录PGDATA/bitnami/postgresql/dataPostgreSQL 数据目录POSTGRESQL_SHARED_PRELOAD_LIBRARIESpgaudit,pg_stat_statementsshared_preload_libraries 列表entrypoint 会过滤掉其中的pgaudit见下文POSTGRESQL_ENABLE_LDAPno是否启用 LDAP 认证当前 entrypoint 预留的兼容开关POSTGRESQL_ENABLE_TLSno是否启用 TLS 加密连接POSTGRESQL_LOG_HOSTNAMEfalse是否记录客户端主机名POSTGRESQL_LOG_CONNECTIONSfalse是否记录连接日志POSTGRESQL_LOG_DISCONNECTIONSfalse是否记录断开日志POSTGRESQL_CLIENT_MIN_MESSAGESerror客户端消息最小级别BITNAMI_DEBUGfalseBitnami 兼容的调试开关需要特别说明的是POSTGRESQL_SHARED_PRELOAD_LIBRARIES的默认值与 README 略有出入README 写的是默认pg_stat_statements而实际 Dockerfile 的默认值是pgaudit,pg_stat_statements。entrypointdocker-entrypoint.sh在写入配置前会执行一次过滤把pgaudit从 preload 列表中剔除原因是pgaudit需要独立授权且并非所有部署都启用它FILTERED_PRELOAD_LIBRARIES$(echo ${POSTGRESQL_SHARED_PRELOAD_LIBRARIES} | sed s/pg_audit,\?//g | sed s/,pg_audit//g | sed s/,,/,/g | sed s/^,//;s/,$//)因此最终写入postgresql.conf的shared_preload_libraries实际为pg_stat_statements。如果你明确需要pg_stat_statements之外的其他 preload 库应通过覆盖该环境变量传入而不是依赖默认值。首次初始化流程entrypoint 做了什么docker-entrypoint.sh 在容器首次启动时执行了一套完整的引导逻辑理解它有助于排查初始化类问题准备数据目录若PGDATA不存在则创建并强制chmod 0700PostgreSQL 对数据目录的硬性权限要求。校验密码读取POSTGRES_PASSWORD或POSTGRESQL_PASSWORD两者都为空则输出ERROR: POSTGRES_PASSWORD or POSTGRESQL_PASSWORD must be set并退出exit 1这正是密码必填的强制来源。初始化数据库若${PGDATA}/PG_VERSION不存在则执行initdb -D ${PGDATA} -U ${POSTGRES_USER} --auth-localtrust --auth-hosttrust先用 trust 认证完成引导。写入 bootstrap 配置生成一份引导模式的postgresql.conflisten_addresses 仅本地 socket无网络监听和只含local all all trust的pg_hba.conf用pg_ctl临时拉起实例。设置密码并建库通过本地 socket 执行ALTER USER ... WITH PASSWORD并在POSTGRES_DB ! postgres时执行CREATE DATABASE。落盘标记停止临时实例touch ${PGDATA}/.initialized保证后续重启跳过初始化。写入正式配置覆盖写入listen_addresses *的正式postgresql.conf以及使用md5 密码认证的正式pg_hba.conflocal all all md5 host all all 127.0.0.1/32 md5 host all all ::1/128 md5 host all all 0.0.0.0/0 md5后台刷新 collation 版本正式启动后后台任务等待pg_isready就绪然后遍历所有非template0数据库执行ALTER DATABASE ... REFRESH COLLATION VERSION规避 glibc 升级导致的 collation 版本不一致问题docker-entrypoint.sh。这套先 trust 引导、后切换 md5 认证的两阶段流程保证了首次建库不需要预先知道密码而正式对外服务时所有连接都必须经过密码认证。Kubernetes 部署镜像专为 Kubernetes 场景设计仓库提供了完整的部署模板 kubernetes-example.yaml。核心是fsGroup 安全上下文 非 root 用户的组合securityContext: fsGroup: 1001 containers: - name: postgresql image: local/postgresql:18 securityContext: runAsUser: 1001 env: - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: postgresql key: postgresql-password volumeMounts: - name: data mountPath: /bitnami/postgresql权限模型如何工作容器以 UID 1001 运行Dockerfile 中USER 1001Pod 级securityContext.fsGroup: 1001让 Kubernetes 在挂载卷时把数据卷属组设为 1001entrypoint 启动时再把PGDATA权限收紧为0700PostgreSQL 硬性要求。挂载后的权限形态来自 DEPLOYMENT.md/bitnami/postgresql/ # drwxrwxr-x root:1001 /bitnami/postgresql/data/ # drwx------ 1001:root (after entrypoint fix)完整部署清单解读kubernetes-example.yaml 由四个资源组成Secret存放postgresql-password示例值changeme生产环境务必修改PersistentVolumeClaimpostgresql-data默认申请 10GiStatefulSet单副本postgresql容器完整注入全部环境变量并配置了资源限制limits: cpu 1 / memory 2Gi、liveness/readiness 探针与/dev/shm的 emptyDir 挂载ServiceClusterIP 类型5432 → tcp-postgresql。探针均使用pg_isready做进程级检查两者区别在于延迟与用途livenessProbe: exec: command: [/bin/sh, -c, exec pg_isready -U \postgres\ -d \dbnamepostgres\ -h 127.0.0.1 -p 5432] initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 readinessProbe: exec: command: [/bin/sh, -c, exec pg_isready -U \postgres\ -d \dbnamepostgres\ -h 127.0.0.1 -p 5432] initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5注意模板中的镜像名仍为local/postgresql:17实际部署 18 版本时应替换为你make build repoyour-registry namepostgresql version18产出的镜像。快速部署# 1. Update image in kubernetes-example.yaml image: your-registry/postgresql:18 # 2. Update password in Secret # 3. Deploy kubectl apply -f kubernetes-example.yaml # 4. Verify kubectl get pods kubectl logs postgresql-0 kubectl exec -it postgresql-0 -- psql -U postgres常见部署陷阱卷必须挂载在/bitnami/postgresql而不是/bitnami/postgresql/data数据卷应包含整个数据根目录entrypoint 会在其中创建data/子目录挂错位置会导致初始化失败或数据隔离。fsGroup 必须是 1001否则 Kubernetes 挂载卷的属组与容器用户1001不匹配entrypoint 的chmod 0700无法纠正属主问题会报权限错误。若出现FATAL: data directory has invalid permissions / DETAIL: Permissions should be urwx (0700)按序检查卷是否挂在/bitnami/postgresql、fsGroup 是否为 1001、容器是否以 1001 运行。可用扩展与启用方式镜像内置了完整的 contrib 扩展集README 与测试脚本重点覆盖四个扩展扩展用途启用 SQLpg_stat_statements查询性能跟踪preload 加载CREATE EXTENSION pg_stat_statements;pg_trgm模糊文本匹配与相似度搜索CREATE EXTENSION pg_trgm;pgcrypto加密函数哈希、加密、密码哈希CREATE EXTENSION pgcrypto;pgaudit审计日志独立包安装未 preloadCREATE EXTENSION pgaudit;启用方式README 中的标准示例CREATE EXTENSION pg_trgm; -- Fuzzy text search and similarity CREATE EXTENSION pgcrypto; -- Cryptographic functions (hashing, encryption) CREATE EXTENSION pg_stat_statements; -- Query performance tracking -- And many more from contrib packagepg_stat_statements之所以能直接工作是因为它已在镜像的shared_preload_libraries中预加载经 entrypoint 过滤pgaudit后写入配置无需重启实例即可建扩展。OpenReplay 的 docker-compose 部署scripts/docker-compose/docker-compose.yaml同样使用ghcr.io/openreplay/postgres:${POSTGRES_VERSION}镜像并挂载pgdata:/bitnami/postgresql与本镜像的设计一脉相承。测试套件make test 全流程验证仓库为镜像提供了三层自动化测试全部通过make test一键执行Makefile# Test with default settings make test # Test with custom version make test version18测试流程为构建镜像 → 以后台容器postgres-test启动-p 5432:5432 -e POSTGRES_PASSWORDpostgres123→ 等待 15 秒初始化 → 依次执行三个测试脚本 → 清理容器。1. 容器健康与连通性测试test_postgres.sh验证容器状态、pg_isready连接、SELECT version()版本输出、SHOW shared_preload_libraries预加载库以及最近 10 行容器日志最后打印连接信息。2. 数据库 CRUD 测试create_test_object.sh创建test_table含SERIAL主键与TIMESTAMP DEFAULT NOW()插入三条记录查询验证启用pg_stat_statements最后清理表。3. 扩展功能测试test_extensions.sh逐项验证扩展的真实可用性# pg_trgm: 相似度函数与模糊匹配 SELECT similarity(PostgreSQL, Postgres) as similarity_score; SELECT hello % hallo as is_similar; # pgcrypto: SHA256 摘要与 bcrypt 密码哈希 SELECT encode(digest(test, sha256), hex) as sha256_hash; SELECT length(crypt(mypassword, gen_salt(bf))) as bcrypt_length; # pgaudit: 配置与会话审计 CREATE EXTENSION IF NOT EXISTS pgaudit; SHOW pgaudit.log; SET pgaudit.log READ,WRITE; SELECT 1 as test_query;最后通过SELECT extname, extversion FROM pg_extension ORDER BY extname;列出全部已安装扩展。注意make test默认绑定5432宿主机端口若本机已有 PostgreSQL 占用该端口需先停止冲突服务或修改 Makefile 中的端口映射。Make 目标速查make help # Show all available targets make build # Build PostgreSQL image make test # Build and run full test suite make push # Build and push to registry make dev # Build and run interactively make clean # Remove test containers and images make kube # Build and push for Kubernetes其中push与kube都会先执行build再推送$(builder) push $(image)clean会停止并删除postgres-test容器并移除镜像。安全要点总结容器以非 root 用户UID 1001运行与 fsGroup 安全上下文完全兼容支持 KubernetessecurityContext约束runAsUser、fsGroup内置pgcrypto可用于密码哈希bcrypt与数据加密需求正式配置使用 md5 密码认证对外连接必须提供凭据密码强制通过环境变量注入entrypoint 校验推荐在 Kubernetes 中配合 Secret 使用。整套方案的关键文件索引镜像定义 Dockerfile、构建与测试入口 Makefile、运行时逻辑 docker-entrypoint.sh、Kubernetes 完整模板 kubernetes-example.yaml、部署细节 DEPLOYMENT.md以及三个测试脚本 test_postgres.sh、create_test_object.sh、test_extensions.sh。赞分享可观测性开发工具前端后端【免费下载链接】openreplaySession replay, cobrowsing and product analytics you can self-host. Best for reproducing issues and iterating on your product.项目地址https://gitcode.com/gh_mirrors/op/openreplay点击查看免费下载相关推荐OpenReplay 自托管 PostgreSQL 17 镜像解析Bitnami 兼容、非 root 运行与 Kubernetes 部署实战OpenReplay 自托管 PostgreSQL 17 镜像解析Bitnami 兼容、非 root 运行与 Kubernetes 部署实战 本指南围绕 Op可观测性开发工具前端后端如何自托管部署OpenReplayDocker Compose与Kubernetes等5种方式完整指南如何自托管部署OpenReplayDocker Compose与Kubernetes等5种方式完整指南 OpenReplay 是一款开源的 会话回放Sess可观测性开发工具前端后端Encore 自托管镜像构建指南使用 encore build docker 一键产出可部署的 Docker 镜像Encore 自托管镜像构建指南使用 encore build docker 一键产出可部署的 Docker 镜像 Encore 提供了从 CLI 直接构建后端开发工具云原生微服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表