本地数据库客户端只能自己用?用 cpolar 安全访问 NAS 上的 PostgreSQL 管理台

发布时间:2026/9/28 18:08:59
本地数据库客户端只能自己用?用 cpolar 安全访问 NAS 上的 PostgreSQL 管理台 本地数据库客户端只能自己用用 cpolar 安全访问 NAS 上的 PostgreSQL 管理台图用 cpolar 安全访问 NAS 上的 PostgreSQL 管理台我以前最怕这种验收数据库跑在家里 NAS 或办公室小主机上本地客户端连得好好的同事一问“我能不能看一下表结构和几条测试数据”现场就开始尴尬。直接把 PostgreSQL 的5432端口映射出去肯定不合适。数据库端口不是演示页面公网裸露风险太高更别说很多测试库里还混着调试数据一不小心就把权限放大了。这篇换个更稳的做法在 NAS/Docker 上跑 PostgreSQL 测试库和 pgAdmin Web 管理台只给同事一个临时 HTTPS 入口进管理台用只读账号验收查询结果。验收结束后关掉 cpolar入口消失数据库端口一直不对公网开放。1 这次要做成什么这套方案的重点不是“远程连接数据库”而是“临时验收 Web 管理台”。最终链路长这样同事浏览器 ↓ HTTPS 临时地址 cpolar HTTP 隧道 ↓ NAS 上的 pgAdmin Web 管理台5050 ↓ Docker 内网 PostgreSQL 测试库5432划重点外部访问的是 pgAdmin 的 Web 页面不是 PostgreSQL 的5432端口。pgAdmin 再使用 Docker 内网地址连接 PostgreSQL。这篇里我会用 PostgreSQL 官方镜像和 pgAdmin 官方镜像做演示。pgAdmin 官方文档要求容器启动时设置PGADMIN_DEFAULT_EMAIL和PGADMIN_DEFAULT_PASSWORD容器默认监听80我们把它映射到 NAS 的5050端口方便本地浏览器访问。安全边界先说清楚不公网暴露 PostgreSQL5432。不给同事超级管理员账号。只使用脱敏测试库和只读数据库账号。cpolar 只用于临时验收验收结束立刻关闭隧道。生产环境走正式远程接入方案、堡垒机或统一网关不拿临时隧道当长期入口。2 环境准备NAS 上先有 Docker这篇默认你的 NAS、迷你主机或 Linux 服务器已经能运行 Docker 和 Docker Compose。群晖、威联通、Ubuntu 小主机都可以命令写法以标准 Docker Compose 为准。先在 NAS 上建一个单独目录别把测试库文件散落到系统目录里mkdir -p ~/pg-review-demo cd ~/pg-review-demo这里单独建目录有两个好处后面清理简单Compose 文件、初始化 SQL、数据卷都能按项目收口。临时验收结束后如果确定不用了整个目录也更容易归档。再确认 Docker Compose 可用docker version docker compose version如果docker compose version没有输出版本号先把 NAS 的 Docker 套件或 Docker Compose 插件补齐。这里别急着往下跑Compose 不通后面的服务编排会直接卡住。3 部署 PostgreSQL 测试库和 pgAdmin先写一份docker-compose.yml。这份配置包含两个服务postgres测试用 PostgreSQL 数据库容器内端口仍是5432但不映射到宿主机公网端口。pgadminWeb 管理台对宿主机开放5050后面 cpolar 只穿透这个端口。cat docker-compose.yml EOF services: postgres: image: postgres:16 container_name: pg-review-postgres environment: POSTGRES_DB: reviewdb POSTGRES_USER: app_admin POSTGRES_PASSWORD: AdminPass_ChangeMe_2026 volumes: - pgdata:/var/lib/postgresql/data - ./init:/docker-entrypoint-initdb.d:ro networks: - pg-review-net restart: unless-stopped pgadmin: image: dpage/pgadmin4:latest container_name: pg-review-pgadmin environment: PGADMIN_DEFAULT_EMAIL: adminexample.com PGADMIN_DEFAULT_PASSWORD: PgAdmin_ChangeMe_2026 PGADMIN_DISABLE_POSTFIX: 1 ports: - 5050:80 depends_on: - postgres networks: - pg-review-net restart: unless-stopped volumes: pgdata: networks: pg-review-net: driver: bridge EOF提醒一下示例密码是为了教程可复制。你自己跑的时候要改成更长的随机密码尤其是 pgAdmin 登录密码。同事验收只需要 pgAdmin 的登录入口不需要知道app_admin的密码。这里没有写5432:5432是故意的。PostgreSQL 只在 Docker 网络里被 pgAdmin 访问避免把数据库原始端口暴露到 NAS 宿主机和公网。4 初始化测试表并创建只读账号为了让验收不只是“能打开页面”我们准备一张脱敏订单表再创建一个只读账号review_reader。同事后面用这个账号在 pgAdmin 里跑查询能看到数据但不能改表。先创建初始化目录和 SQL 文件mkdir -p init cat init/01-review-demo.sql EOF CREATE SCHEMA IF NOT EXISTS review_app; CREATE TABLE IF NOT EXISTS review_app.orders ( id BIGSERIAL PRIMARY KEY, order_no TEXT NOT NULL UNIQUE, customer_name TEXT NOT NULL, amount NUMERIC(10, 2) NOT NULL, status TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); INSERT INTO review_app.orders (order_no, customer_name, amount, status, created_at) VALUES (T20260720001, 测试用户A, 128.50, PAID, 2026-07-20 10:20:0008), (T20260720002, 测试用户B, 68.00, PENDING, 2026-07-20 10:35:0008), (T20260720003, 测试用户C, 299.90, PAID, 2026-07-20 11:05:0008) ON CONFLICT (order_no) DO NOTHING; CREATE ROLE review_reader LOGIN PASSWORD ReaderPass_ChangeMe_2026 NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION; GRANT CONNECT ON DATABASE reviewdb TO review_reader; GRANT USAGE ON SCHEMA review_app TO review_reader; GRANT SELECT ON ALL TABLES IN SCHEMA review_app TO review_reader; ALTER DEFAULT PRIVILEGES IN SCHEMA review_app GRANT SELECT ON TABLES TO review_reader; EOFPostgreSQL 官方文档里CREATE ROLE可以明确指定LOGIN、NOSUPERUSER、NOCREATEDB、NOCREATEROLE这些权限属性。这里把危险权限全部关掉只保留登录和查询需要的权限。注意/docker-entrypoint-initdb.d里的 SQL 只会在数据库数据目录首次初始化时执行。如果你已经启动过一次 PostgreSQL再改初始化 SQL 不会自动重跑。测试阶段想重置环境可以执行docker compose down -v docker compose up -ddown -v会删除 Compose 创建的数据卷测试数据也会一起清掉。别在真实库上这么干这一步只适合当前这种临时演示库。5 启动服务本地先确认管理台能打开现在启动两个容器docker compose up -d看一下状态docker compose ps正常情况下能看到pg-review-postgres和pg-review-pgadmin都处于运行状态。如果 pgAdmin 还在启动中等十几秒再刷新页面它第一次初始化会比普通静态页面慢一点。在局域网电脑上打开http://NAS_IP:5050把NAS_IP换成你的 NAS 地址比如192.168.1.20。登录账号使用刚才配置里的adminexample.com PgAdmin_ChangeMe_2026图局域网先通过 pgAdmin :5050 验收数据库这一步应该看到 pgAdmin 的登录页和主界面。图里适合截两块浏览器地址栏里的:5050以及 pgAdmin 登录后的首页。这样读者能一眼看懂现在只是局域网访问还没对外开放。如果打不开先查三件事docker compose ps docker logs pg-review-pgadmin --tail80 curl -I http://127.0.0.1:5050curl能返回 HTTP 响应说明 pgAdmin 在 NAS 本机端口已经起来局域网电脑打不开多半是 NAS 防火墙、Docker 端口映射或访问地址填错。6 在 pgAdmin 里添加 PostgreSQL 服务器登录 pgAdmin 后需要手动把 Docker 内网里的 PostgreSQL 加进去。在左侧或首页找到添加服务器入口填写这些信息General / Name: review-postgres Connection / Host name/address: postgres Connection / Port: 5432 Connection / Maintenance database: reviewdb Connection / Username: review_reader Connection / Password: ReaderPass_ChangeMe_2026这里最容易填错的是 Host。不要填127.0.0.1也不要填 NAS 的局域网 IP。pgAdmin 和 PostgreSQL 在同一个 Docker Compose 网络里服务名postgres就是可解析的内网主机名。为什么这一步用review_reader而不是app_admin因为验收只需要看表结构和跑查询不需要建库、删表、改权限。把只读账号提前接好同事拿到 Web 页面后也只能做只读验证。连接成功后展开Servers → review-postgres → Databases → reviewdb → Schemas → review_app → Tables → orders在 Query Tool 里执行SELECT id, order_no, customer_name, amount, status, created_at FROM review_app.orders ORDER BY id;能看到 3 条测试订单说明数据库、权限和 Web 管理台链路都通了。再试一条写入语句验证只读限制UPDATE review_app.orders SET status CANCELLED WHERE order_no T20260720002;这条语句会被权限拒绝。这个报错是好事说明只读账号没有被放大权限。验收前建议自己先跑一遍别等同事打开页面才发现权限给多了或给少了。7 用 cpolar 开临时 HTTPS 入口给同事验收本地确认没问题后再让外网同事访问。这里用 cpolar 开 HTTP 隧道目标端口是 pgAdmin 的5050。Linux 环境可以使用官方一键安装脚本curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash安装完成后先确认本机管理端口能打开cpolar version curl -s http://127.0.0.1:9200 /dev/null echo cpolar web ui okcpolar 支持通过 Web UI 登录完成账号绑定也支持命令行手动写入 authtoken。纯命令行环境可以执行cpolar authtoken YOUR_CPOLAR_AUTH_TOKEN把YOUR_CPOLAR_AUTH_TOKEN换成你自己后台里的 token。这里不要把 token 发给同事也不要写进公开仓库。临时验收直接运行cpolar http 5050命令输出里会出现公网访问地址选择https://开头的地址发给同事。免费随机地址适合这种短时演示cpolar 已核对规则里免费套餐的随机公网地址会在 24 小时内变化所以不要把它写进长期文档。图cpolar HTTPS 临时入口交付同事验收这张图适合截 cpolar 输出的 HTTPS 地址以及同事浏览器打开 pgAdmin 登录页的状态。注意截图时遮住邮箱、token、真实公网地址里的敏感片段只保留能说明“HTTPS 临时入口已生成”的部分。发给同事时只给这几项pgAdmin 临时地址https://xxxx.cpolar.xxx pgAdmin 登录账号adminexample.com pgAdmin 登录密码PgAdmin_ChangeMe_2026 数据库连接名review-postgres 可验收查询SELECT * FROM review_app.orders ORDER BY id;更稳一点的做法是验收前把 pgAdmin 密码改成一次性的强密码验收后再改掉或直接关闭容器。别把自己长期使用的 pgAdmin 管理员密码拿出来共享。8 验收结束后怎么收口同事确认能登录、能看表、能跑只读查询后立刻关闭 cpolar 隧道。如果你是在前台运行cpolar http 5050在终端按CtrlC再确认外网地址打不开pgAdmin 页面就不会继续暴露在公网入口上。如果这套 PostgreSQL 和 pgAdmin 只是本次验收使用也可以停掉容器docker compose down如果连测试数据也不保留执行docker compose down -v再次提醒down -v会删除 PostgreSQL 数据卷。只要里面有任何需要留存的数据就不要加-v。这里还有几个收口动作我建议固定做删除或更换 pgAdmin 临时登录密码。确认没有在路由器、防火墙、NAS 控制台里额外开放5432。如果测试库来自生产数据验收前只保留脱敏字段手机号、邮箱、地址、真实姓名不要原样放进去。9 总结这次我们做成的不是“把 PostgreSQL 放到公网”而是把 NAS 上的 pgAdmin Web 管理台临时拿出来给同事验收。数据库仍然待在 Docker 内网里外部只通过 HTTPS 临时入口访问管理台再用只读账号查看测试表。关键步骤可以记成三件事PostgreSQL 不映射5432pgAdmin 映射到 NAS 的5050。数据库里提前创建review_reader只给CONNECT、USAGE和SELECT。cpolar 只穿透 pgAdmin 的 Web 端口验收结束马上关闭。安全边界也别省同事验收用脱敏测试库不给超级管理员不共享长期密码生产环境使用正式远程接入方案、堡垒机或统一网关。临时演示就用临时入口做完收口这样既能让协作顺畅也不会把数据库安全押在侥幸上。