简介:面向需要在 Ubuntu 22.04 虚拟机中快速搭建 ERP 系统的运维与开发人员,这份基于 Docker 的 ERPNext 14 部署指南,将 Git、Docker、Docker Compose 的安装配置、镜像加速处理与容器启动等关键步骤整合为一份可对照操作的 Word 文档。包体仅含 1 个 docx 文件,大小 321KB,以图文步骤方式呈现,特别针对 Docker Hub 拉取失败问题提供了 daemon.json 多镜像源配置,并采用汉化开箱即用版镜像,降低上手门槛。文档从系统准备、依赖安装、用户组设置到浏览器访问后台均有明确命令与验证方式,读者可以据此在 VMware 中完成从空白系统到 ERPNext 可访问的全流程,同时理解 Docker 容器化带来的快速部署、弹性扩展与社区支持优势。已有 629 人浏览学习,适合初次接触 ERP 部署的技术人员按步骤实操,也适合企业内快速验证 ERPNext 功能场景。
1. 虚拟机安装 Ubuntu 22.04 部署 ERPNext 14:为什么我选择 Docker 而不是裸机安装
虚拟机安装 Ubuntu 22.04,再用 Docker 把 ERPNext 14 跑起来,这不是一条绕远路。某开发者第一次在物理机上装 ERPNext 时,光是 Python 依赖冲突就折腾了一个周末——系统自带的 Python 3.10 和 ERPNext 要求的 Node 版本互相打架,最后只能重装系统。后来换成 Docker 部署,整个流程压缩到一顿饭的时间。ERPNext 14 是一套开源的企业资源规划系统,覆盖财务、销售、采购、库存、项目管理等模块,适合从初创团队到中型组织的业务管理。对正在做毕设或课设的同学来说,这套方案的价值在于:你不需要从源码编译,不需要手动配置数据库和 Redis,只需要在 Ubuntu 22.04 上装好 Git、Docker、Docker Compose,再拉取一个开箱即用的仓库,系统就能自动完成容器编排和数据库初始化。
这篇方案适合两类人:一类是课程设计需要交付 ERP 系统展示的学生,另一类是公司内部要快速搭一套 ERP 测试环境的技术人员。读完你会得到完整的安装命令、镜像加速配置、常见故障排查清单,以及答辩时能讲清楚的设计思路。
2. 环境准备与总体设计:虚拟机、Ubuntu 22.04 与 Docker 的协作架构
2.1 为什么用 VMware 方案:虚拟化环境的分层设计
在 VMware 中创建虚拟机时,我一般会分配 4 核 CPU、8GB 内存和 60GB 磁盘。ERPNext 由前端(Web 界面)、后端(Frappe 框架)、数据库(MariaDB)、搜索(Redis)、队列(Worker)等多个组件组成,Docker 容器会共享宿主机的内存,所以 8GB 是起步配置。磁盘至少要 60GB,因为镜像拉取后大约占用 15~20GB,加上系统本身和日志,预留一倍空间才不会在运行几个月后出现磁盘写满的问题。
网络模式选择 NAT 即可,虚拟机通过宿主机访问外网,宿主机通过浏览器访问虚拟机 IP。这样的设计把 ERPNext 的 Web 服务端口(默认 80)映射到虚拟机 IP 上,宿主机的 Firefox 或 Chrome 直接访问http://虚拟机IP就能看到登录页。部署完成后如果要在其他电脑访问,需要将 VMware 网络模式改为桥接,让虚拟机获得局域网独立 IP。这个差异我在验收章节会细说。
2.2 安装流程的模块划分:五步递进
整个安装过程可以拆成五个模块,每个模块都有明确的验收点:
模块一:系统更新——保证 apt 软件源索引和已安装软件处于最新状态,避免依赖版本不兼容,对应命令是sudo apt update、sudo apt upgrade、sudo apt full-upgrade。
模块二:基础工具安装——Git 用于拉取 ERPNext 的部署仓库,Docker 负责容器运行,Docker Compose 负责多容器编排。验收命令分别是git --version、docker --version、docker-compose --version。
模块三:镜像源配置——由于网络环境的原因,直接从 Docker Hub 拉取 ERPNext 镜像可能失败或极慢,通过配置/etc/docker/daemon.json让 Docker 从镜像加速器拉取。
模块四:仓库克隆与容器编排——从 Gitee 克隆erpnext_oob_docker仓库,目录里包含pwd.yml编排文件。
模块五:启动验证——docker compose up -d拉起全部容器,然后通过浏览器访问http://localhost/80,进入 ERPNext 14 登录界面。
整体设计思路是把环境准备和业务部署解耦:系统层面的配置(Git、Docker)只做一次,ERPNext 的业务组件全部封装在容器里,前后端、数据库、缓存互不影响,任何一个容器崩溃都不会拖垮整个系统。
2.3 Docker 安装过程中的关键命令拆解
安装 Docker 的完整命令序列如下:
# Step1 更新系统软件包 sudo apt update sudo apt upgrade sudo apt full-upgrade # Step2 安装依赖包(用于通过 HTTPS 获取仓库) sudo apt install apt-transport-https ca-certificates curl software-properties-common # Step3 添加 Docker 官方 GPG 密钥 sudo -i curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-ce.gpg # Step4 验证公钥指纹 sudo apt-key fingerprint 0EBFCD88 # Step5 添加 Docker 阿里稳定版软件源 sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" # Step6 再次更新软件包 sudo apt update # Step7 安装默认最新版 sudo apt install docker-ce docker-ce-cli containerd.io这里有一个典型的翻车点:sudo -i切换到 root 后,后面的curl -fsSL会把 GPG 密钥文件写到 root 用户的环境变量和 sudo 信任路径下,如果没切换而直接用sudo curl,部分系统会提示/etc/apt/trusted.gpg.d/docker-ce.gpg权限不足。解决方法是先执行sudo -i再执行后续命令,或者把curl和gpg --dearmor放到同一个sudo -i会话中。
0EBFCD88是 Docker 官方公钥指纹,执行sudo apt-key fingerprint 0EBFCD88后系统会显示公钥信息,这一步的意义是确认即将安装的软件包确实来自 Docker 官方而非被篡改的源。实际部署中如果指纹不一致,可能是镜像站返回了错误的密钥文件,需要检查网络代理或换用其他镜像站。
2.4 Docker 用户组配置与 systemctl 管理
# 将当前用户加入 docker 用户组(无需每次 sudo) sudo usermod -aG docker $(whoami) su - $(whoami) # 刷新 shell 状态,使用户组生效 # 验证 Docker 是否安装成功 docker images # 查看 Docker 服务状态 sudo systemctl status docker # 启动 / 停止 / 设置开机自启 sudo systemctl start docker sudo systemctl stop docker sudo systemctl enable docker # 重启并检查状态 sudo systemctl restart docker sudo systemctl status docker # 查看 Docker 版本 docker --versionusermod -aG docker把当前用户加入 docker 组,之后运行docker命令不需要再加sudo。这一步在实际操作中经常被忽略——如果不执行,后面的docker compose up -d会反复提示权限不足,最后只能切到 root 执行,日志和文件权限就会混乱。su - $(whoami)的作用是重新加载登录环境,让用户组变更立即生效。
systemctl enable docker确保了虚拟机重启后 Docker 服务自动拉起。ERPNext 容器设置了 restart 策略(可以在 pwd.yml 中看到),Docker 服务启动后会自动恢复之前运行的容器。这意味着做完这套配置后,虚拟机意外重启也不会导致 ERPNext 失联。
3. Docker Compose 安装与镜像加速配置:解决拉取失败的关键细节
3.1 Docker Compose 的二进制安装与软链接
Docker Compose 的作用是把 ERPNext 的多个容器(web、worker、db、redis、socketio)组合成一个整体,通过一个 YAML 文件统一管理。安装命令如下:
# 下载 Docker Compose 可执行文件到 /usr/local/bin sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 赋予可执行权限 sudo chmod +x /usr/local/bin/docker-compose # 创建软链接,使得任意目录下都可直接执行 sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose # 验证版本 docker-compose --version用curl -L的原因是需要跟随 GitHub Releases 页面的重定向,$(uname -s)会自动替换为 Linux,$(uname -m)自动替换为 x86_64 或 aarch64。在 Ubuntu 22.04 虚拟机中通常是 x86_64,所以实际下载的是docker-compose-linux-x86_64。
/usr/local/bin是用户安装的可执行文件目录,/usr/bin是系统命令目录,ln -s创建软链接后,系统在任意路径下都能找到docker-compose。如果跳过软链接这一步,执行docker-compose --version会提示command not found。
3.2 daemon.json 镜像加速器配置:绕过 Docker Hub 拉取限制
部署 ERPNext 时最容易卡住的是拉取镜像环节——Docker Hub 访问不稳定,docker compose up -d会反复重试。解决方法是编辑 Docker 配置文件,加入多个加速器地址:
# 切换到 root 用户后执行 touch /etc/docker/daemon.json chmod 777 -R /etc/docker/daemon.json vim /etc/docker/daemon.json{ "registry-mirrors": [ "https://docker.registry.cyou", "https://docker-cf.registry.cyou", "https://dockercf.jsdelivr.fyi", "https://docker.jsdelivr.fyi", "https://dockertest.jsdelivr.fyi", "https://mirror.aliyuncs.com", "https://dockerproxy.com", "https://mirror.baidubce.com", "https://docker.m.daocloud.io", "https://docker.nju.edu.cn", "https://docker.mirrors.sjtug.sjtu.edu.cn", "https://docker.mirrors.ustc.edu.cn", "https://mirror.iscas.ac.cn", "https://docker.rainbond.cc" ] }配置完成后执行:
systemctl restart docker systemctl daemon-reload systemctl restart docker systemctl daemon-reload这里有一个容易被忽略的顺序:先restart docker让 Docker 重新读取配置,再daemon-reload通知 systemd 重新加载服务配置。实测中如果把顺序反过来,偶尔会出现 Docker 已经启动但加速器未生效的情况。配置多个加速器的意义在于容错——第一个加速器失效时,Docker 会自动尝试下一个,不用重新配置。
选加速器地址时优先选择教育网节点(如docker.nju.edu.cn、docker.mirrors.ustc.edu.cn),这些节点在校园网络环境下延迟较低。如果部署环境是公司内网,建议把加速器地址替换为内网 Harbor 仓库地址,格式同样是https://registry.yourdomain.com。
3.3 配置完加速器后如何验证生效
配置加速器后,判断是否生效的方法是执行docker info,查看输出中的Registry Mirrors字段:
docker info | grep -A 10 "Registry Mirrors"正常输出会列出刚配置的所有加速器地址。如果该字段为空,说明 daemon.json 没有被正确加载,检查文件权限和 JSON 格式是否合法:
cat /etc/docker/daemon.json python3 -m json.tool /etc/docker/daemon.jsonjson.tool会用 Python 解析 JSON,如果格式错误会直接报错并指出行列位置。我经历过一次踩坑:把注释写进了 JSON 文件导致解析失败,Docker 直接拒绝启动,systemctl status docker显示JSON parse error。这提醒我们 daemon.json 是严格的 JSON 格式,不允许包含//或#注释。
4. 仓库克隆与容器编排:erpnext_oob_docker 的落地实战
4.1 克隆项目仓库并检查目录结构
git clone https://gitee.com/yuzelin/erpnext_oob_docker && cd erpnext_oob_docker ls -la在终端执行ls -la后,能看到仓库下的pwd.yml文件和若干脚本。这个仓库是一个汉化开箱即用版 ERPNext 编排仓库,核心价值在于已经把 ERPNext 14 的镜像版本、数据库初始化脚本、环境变量都配置好了,不需要手工写 Dockerfile。pwd.yml是 Docker Compose 的编排文件,名称取值pwd可以理解为 project working directory,表示以当前目录为工作目录。
通读pwd.yml可以发现容器服务的组成:
| 服务名称 | 容器职责 | 端口映射 |
|---|---|---|
| web | ERPNext 前端与后端 | 80:80 |
| worker | 后台任务(发送邮件、文档转换等) | 无 |
| redis_cache | Redis 缓存 | 无 |
| redis_queue | Redis 队列 | 无 |
| db | MariaDB 数据库 | 无 |
| socketio | WebSocket 实时通知 | 无 |
这里有一个值得在答辩时讲的设计点:数据库和 Redis 容器没有暴露端口到宿主机,只在容器内部网络互通。这样做提升了安全性——外部无法直接连接数据库,只能通过 ERPNext 的 Web 接口操作。如果要做数据处理或备份,可以进入容器内部执行命令,也可以临时把端口映射出来。
4.2 执行容器编排并观察日志输出
docker compose --project-name erpnext_oob -f pwd.yml up -d拆开这条命令的每个参数:
--project-name erpnext_oob:给这次编排命名为erpnext_oob,生成的容器名称会带有该前缀,避免与系统中其他 Compose 项目重名-f pwd.yml:指定编排文件,默认会找docker-compose.yml,这里显式指定up -d:创建并启动容器,-d表示后台运行,终端不会持续输出日志
执行后系统的反应是开始拉取镜像。因为已经配置了加速器,正常情况下 3~5 分钟可以完成下载。如果之前没有配置加速器,会看到pull access denied或连续多次retrying,这时候还不能继续走下一步,必须先解决镜像拉取问题。
4.3 查看容器状态与初始化判断
docker ps docker ps -adocker ps显示运行中的容器,如果看到六个容器全部是 Up 状态,说明编排成功。docker ps -a会连已退出的容器一起显示,用来排查启动失败的情况——如果某个容器状态是Exited (1)或Restarting,需要查看日志定位原因:
docker compose -f pwd.yml logs -f web docker logs erpnext_oob_web_1查看web容器日志时,重点观察是否出现Listening on: 0.0.0.0:80或类似的输出,这表示 ERPNext Web 服务已经就绪。首次启动时初始化过程较长(创建数据库、执行迁移),一般需要 2~5 分钟,期间访问网页可能会提示 502 或连接拒绝,这是正常现象,等待日志输出完毕再刷新。
4.4 浏览器访问与汉化验证
# 在 Ubuntu 虚拟机的火狐浏览器中打开 http://localhost/80这里有一个容易误解的地方:localhost后斜杠加 80 是本教程仓库地址的固定写法的写法问题,实际浏览器地址栏建议直接输入http://localhost或http://127.0.0.1,端口 80 是默认值可以省略。如果你是从宿主机浏览器访问虚拟机,则要输入http://虚拟机IP,例如http://192.168.157.131。
首次访问会看到 ERPNext 的设置向导,需要创建管理员账号、设置站点名称、选择语言。汉化版默认已经内置了中文语言包,只需在设置向导中将系统语言切换为简体中文。ERPNext 14 的首页仪表盘会出现销售、采购、库存、会计等模块的快捷入口,至此部署完成。
5. 避坑清单:四个最容易翻车的环节
5.1 现象:Docker 命令提示permission denied while trying to connect to the Docker daemon socket
原因:当前用户不在 docker 用户组中,Linux 要求 socket 文件权限匹配才能通信。具体排查方法是ls -l /var/run/docker.sock,如果权限显示srw-rw---- root docker,而当前用户不在 docker 组,就会拒绝连接。
解决:按上文执行sudo usermod -aG docker $(whoami)和su - $(whoami)后重新执行docker images。注意su -和su的区别,必须带-才能重新加载环境变量,否则用户组变更不会生效。
5.2 现象:docker compose up -d卡在 Pulling 阶段,进度条长时间不动或反复重试
原因:Docker Hub 访问直连失败,或者镜像加速器配置没有被 Docker 加载。真实案例中,某同学配置了加速器但忘记重启 Docker,导致加速器没有生效。
解决:检查/etc/docker/daemon.json的 JSON 格式,使用python3 -m json.tool校验;执行docker info | grep "Registry Mirrors"确认加速器已加载;重启 Docker 服务后再执行docker compose -f pwd.yml up -d。如果仍失败,换用加速器列表中的其他节点。
5.3 现象:ERPNext 页面提示 502 Bad Gateway 或无法连接
原因:Web 容器启动失败,或数据库容器没有完成初始化。常见于首次启动时资源不足(内存低于 6GB),或数据库容器初始化未完成时前端就已开始接管请求。
解决:docker ps -a查看容器状态,docker logs erpnext_oob_db_1和docker logs erpnext_oob_web_1分别查看日志。如果 db 容器还在初始化(日志中有Initializing database字样),耐心等待 2~5 分钟。如果 web 容器报端口被占用,执行sudo lsof -i :80找出占用进程并停止。
5.4 现象:宿主机浏览器无法访问虚拟机的 ERPNext
原因:VMware 网络模式为 NAT,宿主机访问虚拟机需要正确的 IP 地址。很多人输入了错误的 IP,或防火墙阻止了 80 端口。
解决:在虚拟机内执行ip addr show | grep "inet 192"获取实际 IP(通常是192.168.xxx.xxx),宿主机浏览器输入http://192.168.xxx.xxx。注意localhost只在虚拟机内部浏览器有效。如果仍无法访问,检查 Ubuntu 防火墙sudo ufw status,如果为 active 则执行sudo ufw allow 80/tcp。
6. 验收与答辩:怎么证明这套系统真的部署成功了
6.1 部署验收清单
部署完成后,不要急着关终端,按下面的清单逐项确认。
| 验收项 | 操作与预期结果 |
|---|---|
| Docker 服务健康 | docker images能列出镜像;docker ps显示全部容器 Up |
| 容器完整性 | docker ps中至少有 web、worker、redis_cache、redis_queue、db、socketio 六个容器 |
| 服务可访问性 | 虚拟机内 Firefox 访问http://localhost,出现 ERPNext 设置向导或登录页 |
| 数据持久化验证 | docker compose -f pwd.yml down再docker compose -f pwd.yml up -d,重新访问后系统数据仍在 |
| 汉化完整性 | 登录后系统语言可选择简体中文,仪表盘各模块显示正常 |
6.2 答辩时的高分技巧:讲清楚三个设计决策
答辩时不要只说自己敲了哪些命令,要强调设计层面的考量。第一个设计决策是为什么选择 Docker 部署而不是裸机安装:ERPNext 依赖 Python 3.10、Node.js 14、MariaDB 10.6、Redis 等多种组件,裸机安装需要手动处理环境变量冲突和依赖版本不兼容,Docker 通过容器隔离消除了环境差异,提升了可移植性。
第二个设计决策是镜像加速器配置的意义:避免因为网络问题导致部署中断,切换到国内镜像节点后拉取时间从几十分钟缩短到几分钟。
第三个设计决策是容器端口映射策略——只暴露 web 服务的 80 端口,数据库和 Redis 不暴露端口,减少了攻击面。回答“如果业务增长怎么办”时可以讲:修改 pwd.yml 添加更多 worker 容器副本,执行docker compose -f pwd.yml up -d --scale worker=2即可实现水平扩展。
6.3 一个容易被追问的深挖点:数据备份与恢复
答辩时导师可能会追问数据可靠性。可以回答 MariaDB 容器使用命名卷存储数据库文件,默认路径由 Docker 管理。备份操作是:
docker exec erpnext_oob_db_1 mysqldump -u root -p --all-databases > erpnext_backup.sql恢复则使用:
cat erpnext_backup.sql | docker exec -i erpnext_oob_db_1 mysql -u root -p实际操作时需要注意数据库 root 密码定义在 pwd.yml 的环境变量中,备份前查看一下MYSQL_ROOT_PASSWORD的取值。如果你在答辩中主动演示了备份恢复,整个部署的完整度会明显加分。
从那以后我每次部署完一个环境,都会强制要求自己把命令行日志整个回放一遍——从git --version开始,到docker compose up -d结束,确认每一步都有输出、没有隐藏错误。这是装过几台机器后养成的习惯,也算是对翻车经历的交待。希望这套步骤和排查清单能帮到你,把 ERPNext 14 顺利跑起来。
本文还有配套的精品资源,点击获取