人在 B 地,库在 A 地:用 Docker 把数据库“打包带走”就好了
背景
我在开发一个前后端项目时,后端连接的是A地服务器上的 PostgreSQL 数据库。平时在 A 地开发没有问题,因为电脑和服务器在同一个网络里,可以直接连接数据库。
但是问题来了:我下周要带着这台电脑去B地开发,B地网络肯定访问不到我A地的内网数据库。也就是说,项目代码在电脑上,但数据库在A地的服务器上。一旦离开A地的网络,后端就无法正常启动,接口也无法调试。
最初的连接方式是:
我的电脑 -> A地网络 -> A地服务器 PostgreSQL
去B地后需要变成:
我的电脑 -> 本机 Docker PostgreSQL
这篇文章记录我是如何把A地数据库复制到本机 Docker 里,让自己在B地也能继续开发的。
最终方案
核心思路很简单:
- 在自己的电脑上安装 Docker Desktop。
- 用 Docker 在本机启动 PostgreSQL 和 Redis。
- 在离开 A 地之前,把A地服务器数据库导出一份备份。
- 把备份导入本机 Docker PostgreSQL。
- 把项目的
DATABASE_URL改成本地数据库地址。
这样即使到了B地,访问不到A地的数据库,也可以继续开发。
为什么用 Docker
导师提到可以本地安装 Docker。这里 Docker 的作用不是帮我们连接A地的数据库,而是让电脑本地跑一个数据库。
也就是说,Docker 解决的是:
B地连不上A地数据库,但我电脑本地可以自己跑一个数据库
相比直接在 Windows 上安装 PostgreSQL,用 Docker 有几个好处:
- 环境更干净,不容易污染系统。
- 数据库版本可控。
- 以后换电脑或重装环境更方便。
- PostgreSQL、Redis 等服务可以用一条命令启动。
安装 Docker Desktop
在 Windows 上安装 Docker Desktop 时,需要 WSL2 支持。
如果 Docker Desktop 提示 WSL 没安装,可以用管理员 PowerShell 执行:
wsl --install --no-distribution
wsl --update
wsl --set-default-version 2
如果提示需要重启电脑,就先重启。
安装完成后,检查 Docker 是否可用:
docker --version
docker compose version
wsl --list --verbose
正常情况下可以看到 Docker 版本,以及类似下面的 WSL 发行版:
docker-desktop Running 2
关于 C 盘和 D 盘
Docker Desktop 主程序可以装在 C 盘,这个问题不大。真正占空间的是 Docker 镜像、容器和数据库数据。
安装完成后,可以在 Docker Desktop 里设置数据目录:
Settings -> Resources -> Advanced -> Disk image location
建议改到:
D:\software\DockerData
这样以后下载的镜像、本地 PostgreSQL 数据等主要会占用 D 盘空间。
需要注意:WSL 系统组件本身属于 Windows 功能,通常还是会在 C 盘。这个体积一般不是主要问题,真正大的数据可以迁到 D 盘。
准备 Docker Compose 文件
我在项目根目录准备了一个本地开发用的 docker-compose.dev.yml:
services:
postgres:
image: postgres:16-alpine
container_name: codestory-postgres
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-devpass}
POSTGRES_DB: ${POSTGRES_DB:-codestory}
ports:
- '${POSTGRES_PORT:-55432}:5432'
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-codestory}']
interval: 5s
timeout: 5s
retries: 10
restart: unless-stopped
redis:
image: redis:7-alpine
container_name: codestory-redis-dev
ports:
- '${REDIS_PORT:-6379}:6379'
volumes:
- redis_dev_data:/data
restart: unless-stopped
volumes:
postgres_data:
redis_dev_data:
这里 PostgreSQL 暴露到本机的端口是 55432,不是 5432。原因是我电脑上本来就有一个 PostgreSQL 占用了 5432,所以 Docker 里的 PostgreSQL 改用 55432,避免端口冲突。
启动本地数据库
在项目根目录执行:
docker compose -f docker-compose.dev.yml up -d postgres redis
第一次执行时会下载镜像:
postgres:16-alpine
redis:7-alpine
下载完成后会启动两个容器:
codestory-postgres
codestory-redis-dev
可以用下面的命令查看运行状态:
docker ps
备份A地服务器数据库
离开 A 地之前,一定要在还能连接A地服务器数据库的时候导出备份。
备份命令:
docker run --rm -v "${PWD}:/backup" postgres:16-alpine pg_dump -Fc "postgresql://用户名:密码@A地服务器地址:5432/数据库名?schema=public" -f /backup/codestory-dev.dump
这里的数据库连接地址就是项目原来使用的 DATABASE_URL。
注意:DATABASE_URL 里通常包含数据库密码,不要截图发给别人,也不要提交到 Git。
备份成功后,项目根目录会出现:
codestory-dev.dump
建议在 .gitignore 里加入:
*.dump
*.backup
避免把数据库备份误提交。
导入到本地 Docker PostgreSQL
先把备份文件复制进 PostgreSQL 容器:
docker cp codestory-dev.dump codestory-postgres:/tmp/codestory-dev.dump
再执行恢复:
docker exec codestory-postgres pg_restore -U postgres -d codestory --clean --if-exists --no-owner /tmp/codestory-dev.dump
如果没有报错,一般就说明导入成功。
可以查看有哪些表:
docker exec codestory-postgres psql -U postgres -d codestory -c "\dt"
也可以查看关键表的数据量:
docker exec codestory-postgres psql -U postgres -d codestory -c "select 'users' as table_name, count(*) from users union all select 'courses', count(*) from courses union all select 'chapters', count(*) from chapters union all select 'lessons', count(*) from lessons union all select 'exercises', count(*) from exercises;"
修改项目数据库连接
导入完成后,把项目后端的 .env 改成本机 Docker 数据库:
DATABASE_URL=postgresql://postgres:devpass@localhost:55432/codestory?schema=public
REDIS_URL=redis://localhost:6379
注意端口是 55432。
如果你没有端口冲突,也可以使用 5432。但我这里因为本机已有 PostgreSQL,所以 Docker PostgreSQL 使用 55432。
验证 Prisma 能连接数据库
如果项目使用 Prisma,可以在后端目录执行:
npx prisma db pull --print
只要没有认证失败、连接失败之类的错误,就说明后端能连接到本地数据库。
也可以正常启动后端:
cd backend
pnpm run dev
用 Navicat 查看数据库
如果想用 Navicat、DBeaver、DataGrip 或 pgAdmin 查看本地 Docker 数据库,连接信息如下:
类型:PostgreSQL
主机:localhost
端口:55432
初始数据库:codestory
用户名:postgres
密码:devpass
SSL:关闭
连接成功后,就可以直接查看 users、courses、lessons、exercises 等表。
每次开发前要做什么
以后每次开发前,先确保 Docker Desktop 已经启动。
然后在项目根目录执行:
docker compose -f docker-compose.dev.yml up -d postgres redis
如果容器已经在运行,重复执行这条命令也没关系,它不会清空数据库,也不会重复创建数据。
可以用下面命令确认:
docker ps
如果能看到:
codestory-postgres
codestory-redis-dev
说明本地数据库已经在运行。
Navicat 没有关,不代表数据库一定在运行。Navicat 只是客户端,真正的数据库服务由 Docker 容器提供。
这套方案解决了什么
最后形成的开发方式是:
在 A 地:
电脑 -> A地服务器数据库
去B地:
电脑 -> 本机 Docker PostgreSQL
这样就算B地网络访问不到A地的服务器,也可以继续开发、调接口、看数据。
需要同步的内容分两类:
- 代码:用 Git 同步。
- 数据库结构:用 Prisma migration 或 SQL migration 同步。
- 开发数据:离开 A 地前导出一份备份,导入本机 Docker。
注意事项
不要直接把A地数据库端口暴露到公网。这样虽然能远程连数据库,但安全风险很高。
如果一定要在B地实时连接A地的服务器,应该使用:
- Tailscale
- ZeroTier
- WireGuard
- VPN
但对于日常开发来说,本地 Docker 数据库更稳定,也不依赖网络。
总结
这次问题的本质不是代码问题,而是开发环境依赖了A地的内网数据库。一旦离开这个网络,项目就失去了关键依赖。
Docker 的作用是把这个依赖本地化:
远程数据库依赖 -> 本机 Docker 数据库
最终我实现了:
- Docker Desktop 正常运行。
- 本地 PostgreSQL 和 Redis 正常启动。
- A地数据库成功备份并导入本机。
- 项目后端改为连接本地 Docker 数据库。
- Navicat 可以正常查看本地数据库。
这样去B地以后,只要启动 Docker,本机就有完整的开发数据库环境,可以继续开发。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)