如何将核心开源 ERP 系统平滑迁移至 Ubuntu 生产环境?避开这 10 个权限与数据卷大坑
Odoo / Dolibarr / ERPNext 等开源 ERP 迁移至 Ubuntu Docker 生产环境实战指南。权限隔离、数据卷持久化、数据库选型、备份恢复 10 大坑全解析。
「我们公司用 Odoo 跑了 5 年,原来部署在 Windows Server 上。最近想迁到 Ubuntu + Docker,没想到部署完员工登录看不到自己的数据、附件全丢、定时任务不执行……」
这是开源 ERP 系统迁移最常见的灾难现场。Odoo / ERPNext / Dolibarr 这些 ERP 部署看似简单,生产环境配置不当 = 数据丢、性能崩、备份失效。这篇把 10 个最常踩的坑讲透。
一、迁移前必做的 5 件事
1. 完整盘点
- 数据库类型 + 版本(PostgreSQL? MySQL? MariaDB? 版本?)
- 文件存储路径(附件、报表、自定义模块)
- 定时任务 / cron
- 第三方集成(短信网关、邮件、支付)
- 自定义代码 / 插件
2. 备份完整数据
# 数据库
pg_dump -Fc -d production_db -f backup_$(date +%Y%m%d).dump
# 文件目录
tar -czf files_$(date +%Y%m%d).tar.gz /var/lib/odoo/
# 配置
cp /etc/odoo/odoo.conf ./odoo.conf.bak
3. 准备测试环境
- 测试环境完整跑通迁移流程
- 不要直接在生产环境试
4. 用户培训 + 业务暂停窗口
- 通知所有用户停业 X 小时
- 关键流程暂停(订单、发票)
5. 回滚预案
- 万一失败如何回到旧环境
- 数据库快照保留至少 30 天
二、10 个最常见的坑
🚨 坑 1:Docker volume 权限不对
症状:容器启动后无法写入文件,附件上传失败
原因:容器内用户 ID(如 odoo 是 101)和宿主机目录 owner 不一致
解法:
# 宿主机
sudo chown -R 101:101 /opt/odoo/data
sudo chmod -R 755 /opt/odoo/data
# 或在 docker-compose 里指定 user
services:
odoo:
user: "101:101"
🚨 坑 2:数据库连接名 / 端口错误
症状:容器启动报错 connection refused 或 unknown host
原因:迁移后服务名变了(如 localhost → postgres 容器名)
解法:
# odoo.conf
db_host = postgres # 不是 localhost
db_port = 5432
db_user = odoo
db_password = ...
🚨 坑 3:数据库字符集不一致
症状:迁移完中文乱码、特殊字符丢失
原因:旧库是 LATIN1,新库用了 UTF8
解法:
-- 创建新库时必须指定
CREATE DATABASE odoo_production
WITH ENCODING 'UTF8'
LC_COLLATE 'en_US.utf8'
LC_CTYPE 'en_US.utf8'
TEMPLATE template0;
恢复时:
pg_restore -d odoo_production --no-owner --no-privileges backup.dump
🚨 坑 4:文件路径硬编码
症状:导出的报表 / 模板找不到
原因:模块里写死了 C:\odoo\addons\... 或 /var/lib/odoo/
解法:
# 全局搜索硬编码路径
grep -r "C:\\\\" /path/to/addons/
grep -r "/var/lib/odoo" /path/to/addons/
# 替换为环境变量或相对路径
🚨 坑 5:cron 任务时区不对
症状:每天 9 点的报表 5 点就发了 / 17 点才发
原因:Docker 默认 UTC,宿主机是 UTC+8
解法:
services:
odoo:
environment:
- TZ=Asia/Shanghai
volumes:
- /etc/localtime:/etc/localtime:ro
数据库也要:
services:
postgres:
environment:
- PGTZ=Asia/Shanghai
- TZ=Asia/Shanghai
🚨 坑 6:附件 / Filestore 没迁移
症状:登录后所有上传的图片、合同、二维码都丢了
原因:Odoo 默认把附件存在 data_dir/filestore/,不在数据库里
解法:
# 必须同时迁移:
# 1. 数据库
# 2. /var/lib/odoo/filestore/<dbname>/
# 3. /var/lib/odoo/sessions/
rsync -avz old-server:/var/lib/odoo/ /opt/odoo/data/
🚨 坑 7:自定义模块依赖缺失
症状:升级后某些功能消失 / 报错 module not found
原因:自定义模块用了系统 Python 包,Docker 镜像没装
解法:
# 自定义 Dockerfile
FROM odoo:17
USER root
RUN pip3 install --no-cache-dir \
requests \
openpyxl \
qrcode \
your-custom-deps
USER odoo
🚨 坑 8:内存限制太小导致 worker 崩
症状:长报表 / 大批量导出时 worker 自动重启
原因:Odoo 默认 limit_memory_soft / hard 太低
解法:
# odoo.conf
workers = 4
limit_memory_soft = 2147483648 # 2GB
limit_memory_hard = 2684354560 # 2.5GB
limit_time_cpu = 600
limit_time_real = 1200
🚨 坑 9:反代缺 X-Forwarded-Proto
症状:登录页 HTTPS,登录后变 HTTP、各种功能失效
原因:Nginx 反代没传协议头
解法:
location / {
proxy_pass http://odoo:8069;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https; # ⭐ 关键
}
Odoo 配置:
proxy_mode = True
🚨 坑 10:备份脚本备的是空目录
症状:迁移 3 个月后磁盘满了想恢复,发现备份只有 0 字节
原因:备份脚本备的是 /opt/data 但容器把数据写到了 /var/lib/odoo
解法:备份脚本必须从容器内部或正确的挂载点执行:
#!/bin/bash
# backup.sh
BACKUP_DIR="/opt/backups/odoo"
DATE=$(date +%Y%m%d_%H%M%S)
# 数据库
docker exec postgres pg_dump -Fc -U odoo production > $BACKUP_DIR/db_$DATE.dump
# 附件
docker run --rm -v odoo_data:/data -v $BACKUP_DIR:/backup alpine \
tar -czf /backup/files_$DATE.tar.gz -C /data .
# 验证大小
find $BACKUP_DIR -name "*_$DATE.*" -size 0 && echo "⚠️ 备份为空文件!"
三、标准 docker-compose.yml(生产级)
version: "3.8"
services:
postgres:
image: postgres:16
environment:
POSTGRES_DB: postgres
POSTGRES_USER: odoo
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
TZ: Asia/Shanghai
PGTZ: Asia/Shanghai
volumes:
- postgres-data:/var/lib/postgresql/data
secrets:
- db_password
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U odoo"]
interval: 10s
odoo:
image: odoo:17
depends_on:
postgres:
condition: service_healthy
ports:
- "8069:8069"
environment:
HOST: postgres
USER: odoo
PASSWORD_FILE: /run/secrets/db_password
TZ: Asia/Shanghai
volumes:
- odoo-data:/var/lib/odoo
- ./addons:/mnt/extra-addons
- ./config/odoo.conf:/etc/odoo/odoo.conf:ro
secrets:
- db_password
restart: unless-stopped
user: "101:101"
deploy:
resources:
limits:
memory: 4G
nginx:
image: nginx:1.25-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- odoo
restart: unless-stopped
volumes:
postgres-data:
odoo-data:
secrets:
db_password:
file: ./secrets/db_password.txt
四、迁移完成检查清单
- [ ] 所有用户能登录
- [ ] 历史数据完整(订单数、客户数对得上)
- [ ] 附件 / 图片可见
- [ ] 报表能生成 PDF
- [ ] 邮件能发送
- [ ] 定时任务执行
- [ ] 备份脚本测试恢复成功
- [ ] HTTPS 证书有效
- [ ] 监控告警接通
- [ ] 性能测试通过(10 并发 / 1 分钟)
五、性能调优
PostgreSQL 调优
shared_buffers = 4GB # 内存 25%
effective_cache_size = 12GB # 内存 75%
maintenance_work_mem = 1GB
work_mem = 64MB
max_connections = 200
random_page_cost = 1.1 # SSD
Odoo 调优
workers = (CPU 核数 × 2 + 1)
max_cron_threads = 2
limit_memory_hard = 内存 / workers
写在最后
迁移开源 ERP 不是 docker-compose up 就完事。我们整理了一份《标准 ERP 系统生产环境一键式 Docker-Compose 部署脚本(带安全加固)》:
- 支持 Odoo / ERPNext / Dolibarr / iDempiere
- 含 SSL / 反代 / 备份 / 监控完整方案
- 含数据迁移迁移脚本(旧库 → 新库)
- 含 10 大坑预防机制
📥 扫码加助手免费获取 → 联系销售取脚本 →
或了解我们的 企业 IT 运维方案,含 ERP 部署 / 迁移 / 维保一站式服务。
下载《如何将核心开源 ERP 系统平滑迁移至 Ubuntu 生产环境?避开这 10 个权限与数据卷大坑》PDF 完整版
留下邮箱,立刻获取本文 PDF + 后续企业 AI / 软件采购干货
- ✓ 含全部图表、检查清单、参考链接
- ✓ 可用于内部分享 / 招投标资料引用
- ✓ 后续更新自动推送 · 不发垃圾邮件
