
简介这是一份以Ubuntu 22.04虚拟机为环境、通过Docker搭建ERPNext 14的图文操作指南面向运维人员、中小企业IT人员及需要快速落地开源ERP系统的开发者。ERPNext可覆盖财务、销售、采购、库存与项目管理等业务场景借助Docker能显著减少手动配置成本。资源以单个docx文档封装压缩包共1个文件大小321KB文档从系统准备开始完整记录了Git、Docker、Docker Compose的安装命令以及添加阿里云Docker源、验证GPG密钥、配置daemon.json镜像加速器等关键步骤并附有汉化开箱即用版的部署方式。针对镜像拉取失败、Docker服务状态异常等常见问题文档给出了重启Docker、查看状态等排错思路操作路径清晰适合按步骤跟做。已有628人学习下载对在虚拟机上快速体验ERPNext 14具备直接参考价值。1. 虚拟机里的 ERPNext 14Docker 三件套装完一条 compose 就能跑起来ERPNext 14 是一套开源 ERP 系统覆盖财务、销售、采购、库存、项目管理等模块底层依赖 Frappe 框架、MariaDB 数据库和 Redis 缓存。如果从源码手动编译安装光是依赖处理和站点初始化就能耗掉大半天换到 VMware 里的 Ubuntu 22.04.5 虚拟机用 Docker 部署半小时到一小时就能跑起来。这套流程的核心是三个工具Git 拉取安装文件Docker 提供容器运行时Docker Compose 编排多容器服务。三件套装好之后一条 compose 命令就能拉起整套 ERPNext 服务不需要关心 MariaDB、Redis、Gunicorn 之间的连接细节。对开发者来说这套部署方式最大的价值是快改配置、重启容器就能完成环境调整。对中小企业 IT 来说Docker 化部署意味着升级和迁移变成文件操作而不是重新编译。下面从虚拟机里的 Ubuntu 22.04 开始把 ERPNext 14 的完整部署过程拆开讲。2. Ubuntu 22.04 的 Git 与 Docker 三件套安装顺序、版本验证与用户组坑2.1 先装 Git一条命令加一次版本验证在 ERPNext 部署链路里Git 的第一个直接用途就是从 Gitee 仓库克隆erpnext_oob_docker项目。虽然 Git 和 Docker 没有强依赖关系但我仍然习惯先装 Git 并做一次版本验证这样后面的git clone不会因为环境缺工具而临时打断思路。安装 Gitsudo apt-get install git安装完成之后在终端执行版本检查git --version输出git version 2.34.1之类的内容就算装好了。Ubuntu 22.04 默认源里的 Git 版本是 2.34.x对拉取 ERPNext 相关仓库完全够用不需要为此折腾编译安装新版。git --version中间是两个短横线手打的时候别漏掉。安装 Git 之前建议先跑一次sudo apt update。跳过这步的话后续安装 Docker 依赖时偶尔会遇到软件包 404 或版本不匹配的提示重新拉一次索引就好了。2.2 Docker 安装的三段式更新、装依赖、加 GPG 密钥Docker 在 Ubuntu 上有两种装法apt install docker.io一条命令装完或者走 Docker 官方源。前者版本号偏旧和 Docker Compose 的兼容性不如官方源。ERPNext 部署场景我更推荐后者步骤多几步但后面省事。第一步更新系统软件包sudo apt update sudo apt upgrade sudo apt full-upgradefull-upgrade和upgrade的区别在于前者会在依赖变化时自动处理软件包的删除和安装比单独upgrade更彻底。虚拟机刚装完系统时跑这三条把基础库和内核升到当前状态后面装依赖会少很多麻烦。第二步安装 HTTPS 获取仓库所需的依赖包sudo apt install apt-transport-https ca-certificates curl software-properties-common这四个包的职责分别是apt-transport-https让 apt 支持 HTTPS 源ca-certificates提供 CA 证书校验curl用于下载 GPG 密钥software-properties-common提供add-apt-repository命令。后面添加 Docker 软件源和密钥一步都离不开它们。第三步添加 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.gpgcurl的-fsSL参数含义是-f失败时不输出 HTML 错误正文-s静默模式-S保留错误提示-L跟随重定向。gpg --dearmor把下载的 ASCII 格式密钥转成二进制放到/etc/apt/trusted.gpg.d/目录下apt 更新索引时会自动读取。验证一下密钥是否注册成功apt-key fingerprint 0EBFCD880EBFCD88执行后会显示 Docker 官方公钥的指纹信息看到完整的指纹串说明密钥已正确写入。这里有一点要说明apt-key在新版 apt 里被标记为弃用但 Ubuntu 22.04 上这条命令依然可用作为验证手段足够。2.3 添加软件源并安装 Docker 核心组件密钥验证通过后添加 Docker 稳定版软件源sudo add-apt-repository deb [archamd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable$(lsb_release -cs)是 shell 命令替换自动把 Ubuntu 22.04 的代号jammy填进源地址。手动写死jammy也行但用命令替换的好处是以后换系统版本不用改这一行。添完源再次更新sudo apt update然后安装 Docker 核心组件sudo apt install docker-ce docker-ce-cli containerd.iodocker-ce是 Docker 社区版守护进程docker-ce-cli是命令行工具containerd.io是容器运行时。这三个组件构成一个最小可运行的 Docker 环境。装完先重启服务并检查状态sudo systemctl restart docker sudo systemctl status docker docker --versionsystemctl status docker输出里看到active (running)就说明服务正常docker --version显示守护进程和客户端的版本号。2.4 用户组配置让 docker 命令不用每次加 sudo刚装完时不带 sudo 直接跑 docker 命令大概率会得到这样的报错docker: permission denied while trying to connect to the Docker daemon socket原因是/var/run/docker.sock这个 socket 文件默认属于 root 组当前用户不在 docker 组里就没有读写权限。解决方法是把当前用户加进 docker 组sudo usermod -aG docker 你的用户名 su - 你的用户名su -后面跟用户名作用是重新登录一次 shell。刚加的组权限对当前会话不会立即生效不重新登录的话即使usermod成功了docker 命令照样报权限错误。重新登录后执行docker images验证不报错就说明组配置生效了。这里把 Docker 服务的管理命令一并列出来后面排查会用到sudo systemctl status docker sudo systemctl start docker sudo systemctl enable docker sudo systemctl stop dockerenable设置开机自启status查看运行状态。部署 ERPNext 时建议保持 Docker 自启否则虚拟机重启后容器不会自动恢复。2.5 Docker Compose下载、赋权、软链接三步到位Docker Compose 的作用是把多个容器用一份 YAML 配置统一管理。ERPNext 14 的 OOB 版本里包含 Web 入口、后端应用、数据库、缓存等多个容器靠 Compose 一条命令全部拉起。下载 Compose 可执行文件sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose$(uname -s)输出 Linux$(uname -m)输出 x86_64拼起来就是 Linux x86_64 平台的二进制包。这个 URL 走 GitHub 的 latest release 重定向不用手动关心具体版本号。给下载的二进制加可执行权限sudo chmod x /usr/local/bin/docker-compose然后建立软链接sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose不建软链接的话多数用户敲docker-compose会提示命令找不到因为/usr/local/bin不一定在当前用户的 PATH 里。软链接到/usr/bin后任何用户都能直接执行。验证版本docker-compose --version输出docker-compose version 2.x的信息就说明安装成功。这里有个容易混淆的点新版 Docker 自带的docker compose子命令和独立安装的docker-compose命令是两回事后面避坑章节会专门讲。3. 配置 Docker 镜像加速daemon.json 的写入、重启顺序与失效切换3.1 先把现象说清楚拉取超时和 429 报错执行docker compose up -d的时候Compose 会从 Docker Hub 拉取 ERPNext 及依赖镜像。国内网络环境下直连 Docker Hub最常见两种故障一种是长时间卡在Waiting最终报net/http: TLS handshake timeout另一种是拉取到一半报429 Too Many Requests这是 Docker Hub 官方限流的表现。两种现象的原因都在网络链路本身。镜像加速器的本质是一个 registry mirror它启动时从 Docker Hub 同步镜像内容用户拉取时从加速器节点下载避开直连 Docker Hub 那条不稳定链路。加速器的配置入口是/etc/docker/daemon.jsonDocker 守护进程启动时读取这里的registry-mirrors字段。3.2 daemon.json 的配置结构和参数说明先创建配置文件并编辑touch /etc/docker/daemon.json chmod 777 -R /etc/docker/daemon.json vim /etc/docker/daemon.jsonchmod 777是为了编辑方便临时放开权限配置写完并确认无误后建议把权限收回到 644chmod 644 /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 ] }这一串地址里mirror.aliyuncs.com和mirror.baidubce.com属于云厂商官方镜像稳定性相对可靠docker.nju.edu.cn、docker.mirrors.ustc.edu.cn、docker.mirrors.sjtug.sjtu.edu.cn是高校运营的镜像站速度和稳定性随学校网络状况波动其余的社区镜像源多数由个人或小团队维护优点是覆盖不同网络出口缺点是可能随时停止服务。配置多个地址不是简单叠数量而是让 Docker 在某个源失败时按顺序切换下一个。3.3 重启顺序restart 和 daemon-reload 各干什么配置文件落盘后要重启 Docker 让它读取。实际操作时常用的顺序是systemctl restart docker systemctl daemon-reload systemctl restart docker systemctl daemon-reloadsystemctl daemon-reload让 systemd 重新加载 Docker 服务的 unit 文件systemctl restart docker才真正重启进程。上面这一组命令执行完配置基本就生效了。之后再次修改 daemon.json 时更简洁的做法是systemctl daemon-reload systemctl restart docker顺序不是玄学。第一次配置镜像加速时用两轮组合命令是为了确保系统级配置和进程级配置都同步到位之后每次改动配置一条 reload 加一条 restart 就够不用每次都跑四遍。重启后一定要验证配置是否被读进来docker info在输出里找到Registry Mirrors段能看到刚才写入的地址列表就说明配置生效了。如果这一项是空的要么是 daemon.json 路径不对要么是 JSON 格式有语法错误。JSON 对格式极其敏感多一个逗号或少一个引号都会让整个文件失效改完可以用 vim 打开看一遍结构。3.4 镜像加速器的失效切换和持续维护镜像加速器列表不是一劳永逸的。社区源说停就停高校源在寒暑假有时会调整策略这些你都可能遇到。一个务实的习惯是每隔一段时间检查一次docker info里的 Registry Mirrors 段某个地址总是超时就及时删掉不要留一堆死地址增大切换开销。另外注意daemon.json 是 Docker 守护进程级别的全局配置。如果之前为了别的用途配置过>cp /etc/docker/daemon.json /etc/docker/daemon.json.bak改挂了把备份恢复回去即可这是配置文件操作的后悔药。4. 用 docker compose 部署 ERPNext 14clone 项目、启动容器与浏览器验证4.1 erpnext_oob_docker 项目汉化开箱即用版解决了什么手动部署 ERPNext 14 的痛苦在于它不是单一应用而是一整套 Frappe 生态MariaDB 存数据、Redis 做缓存、Gunicorn 跑 Python 后端、Nginx 做 Web 入口还有后台 Worker 进程处理任务队列。手动一个个装光配置连接关系就能消耗大半天。erpnext_oob_docker项目把整套环境打包成一份开箱即用的 Compose 编排oob就是 out-of-box 的意思项目里已经处理了数据库初始化、站点创建、汉化补丁这些事情我们要做的只是把项目拉下来然后启动。先克隆项目并切换到工作目录git clone https://gitee.com/yuzelin/erpnext_oob_docker cd erpnext_oob_dockerGitee 是国内代码托管平台这个地址直接拉取即可克隆下来默认分支对应 ERPNext 14。克隆完成后先看一下目录结构ls -la一般能看到pwd.yml、env文件和若干配置目录。pwd.yml就是 Compose 主配置容器服务和端口映射都在里面。4.2 compose 启动命令参数解析和首次初始化启动命令是docker compose --project-name erpnext_oob -f pwd.yml up -d逐个看参数含义。--project-name erpnext_oob是项目名Compose 会以它为前缀命名容器同时作为 Docker 网络名称的基础。固定项目名之后后续所有 Compose 相关命令都能精确定位到这套服务。-f pwd.yml指定 Compose 配置文件。默认情况下 Compose 找docker-compose.yml或compose.yml这个项目的主文件名是pwd.yml必须用-f显式指定否则会报找不到配置文件。up -d创建并启动所有容器-d后台运行。加上-d后终端不会被日志刷屏适合在 SSH 会话里执行。想实时看日志可以去掉-d但那样窗口会被日志持续占用不方便做其他操作。首次执行时Compose 会逐层拉取镜像。输出里看到连续的Pull complete说明镜像正在从加速器下载。这个过程视网络情况持续几分钟到十几分钟耐心等它完成期间不要 CtrlC 中断。中断后再次执行同一命令Compose 会从断点继续已拉取的层不会重复下载。4.3 数据库初始化等待和容器状态检查镜像拉取完成后Compose 会依次启动所有容器。ERPNext 首次启动明显比普通容器慢因为在创建站点时要初始化 MariaDB 数据库结构、写入初始数据、编译静态资源。这段时间浏览器访问会看到空白页或 502这是正常的。用 Compose 查看当前状态docker compose --project-name erpnext_oob ps所有服务的STATUS列从starting变成Up并且出现了运行时间说明容器稳定运行。如果某个服务一直显示Restarting说明它启动失败了需要看日志定位docker compose --project-name erpnext_oob logs -f --tail 100--tail 100只显示每个容器最近 100 行日志-f持续跟踪。数据库容器的日志里出现ready for connections后端容器日志里出现监听地址基本上就可以确认初始化完成了。想直接验证数据库是否就绪可以进入数据库容器执行查询docker compose --project-name erpnext_oob exec db mysql -u root -p输入密码后能进入 MySQL 命令行就说明数据库容器工作正常。这个排查手段在后续运维中非常实用。4.4 浏览器验证输入地址确认 ERP 登录页初始化完成后在虚拟机内打开 Firefox访问http://localhost/80这个地址本质上走的是 HTTP 默认端口 80OOB 项目把 ERPNext 的 Web 入口映射到宿主机 80 端口访问时地址末尾的路径会由前端路由兜底处理重定向到根路径后就能看到登录页面。如果浏览器最终正常显示 ERPNext 登录页说明部署成功。如果虚拟机是无桌面的服务器版可以在宿主机浏览器访问虚拟机的网卡 IPhttp://192.168.x.x/80具体 IP 用ip addr查看前提是 VMware 网络模式允许宿主机访问虚拟机下一章会讲这个坑。登录 ERPNext 后看到包含采购、销售、库存、会计等模块的仪表盘说明 ERPNext 14 已经可以正式使用了。默认管理员账号和密码在 OOB 项目的 README 里登录后第一件事是改掉默认密码。提示从宿主机访问时输入虚拟机 IP 而不是 localhost。两个系统各自的 localhost 是不同概念。5. ERPNext 14 部署避坑清单五个高频问题的现象、原因与解决5.1 宿主机和虚拟机的 localhost 不互通现象在宿主机浏览器输入http://localhost/80始终打不开 ERPNext 页面但在虚拟机里用 Firefox 就能打开。原因localhost指向当前操作系统的回环地址。宿主机浏览器里的 localhost 指宿主机自己而 ERPNext 跑在虚拟机内部两边的 localhost 各自独立。解决部署验证阶段直接在虚拟机内访问http://localhost/80。需要从宿主机访问时把地址换成虚拟机的 IP比如http://192.168.80.130/80。前提是 VMware 虚拟机的网络模式不能是仅主机模式NAT 和桥接都可以让宿主机通过 IP 访问虚拟机的服务。5.2 80 端口被系统服务占用现象执行docker compose up -d时提示端口绑定失败报bind: address already in use。原因Ubuntu 服务器版默认可能装了 Apache 或 Nginx这两个服务默认监听 80 端口。Docker 容器要把宿主机 80 端口映射给 Nginx 容器时发现端口已被占用。解决先查占用 80 端口的进程sudo netstat -tlnp | grep :80如果是 Apache 占用停掉并禁止开机自启sudo systemctl stop apache2 sudo systemctl disable apache2是 Nginx 就同样停掉对应服务。停掉冲突服务后重新执行docker compose up -d端口绑定就能正常完成。生产环境如果 80 端口必须要留给其他 Web 服务考虑修改pwd.yml里的端口映射比如映射到 8080。5.3 镜像加速器配置后拉取仍然超时现象daemon.json 里配置了多个镜像加速器docker pull还是超时或者报failed to resolve reference。原因列表里有一部分源已经失效或限流Docker 按顺序尝试时会在失效源上浪费较长时间还有一些源只支持 Docker Hub 官方仓库的镜像对第三方仓库里的镜像拉取不到。解决先执行docker info确认 Registry Mirrors 段确实读到了配置。读到了仍然超时的话把明显失效的源从列表里删掉优先保留阿里云、百度云、DaoCloud 这几个相对稳定的源再重启 Docker。另外如果项目用到的镜像托管在第三方仓库而不是 Docker Hub加速器完全不生效这种场景要单独配置仓库地址的登录认证或直接拉取。5.4 首次启动页面长期 502现象容器全部启动成功、状态显示 Up但浏览器访问长时间显示 502 Bad Gateway等十几分钟依然如此。原因ERPNext 站点初始化包含创建数据库、安装应用、编译静态资源等步骤耗时较长。虚拟机的 CPU 和磁盘性能本来就不如物理机初始化时间会被进一步拉长。期间的 502 是因为 Web 入口已经启动但后端进程还没有监听端口。解决不要急着重启容器。用docker compose logs -f观察后端日志看到数据库迁移完成或站点创建成功的日志后再访问。如果日志里出现报错信息优先排查数据库连接配置和pwd.yml中的环境变量是否正确。等待时间过长的场景可以把虚拟机的 CPU 从 2 核调到 4 核、内存从 4GB 调到 8GB 再重新部署初始化速度会有明显提升。5.5 docker-compose 和 docker compose 命令不一致现象按教程输入docker compose --project-name erpnext_oob -f pwd.yml up -d系统提示docker: compose is not a docker command。原因Docker 的 Compose 能力有两种形态新一代 Docker 把它集成成docker compose子命令独立二进制安装的是docker-compose命令。Ubuntu 22.04 上用 curl 方式安装得到的通常是后者。解决先确认本机支持哪种方式docker-compose --version如果这条命令有输出后续所有操作统一用docker-compose替代docker composedocker-compose --project-name erpnext_oob -f pwd.yml up -d两种形态的--project-name和-f参数行为基本相同只要 project-name 一致管理的是同一组容器。关键点是命令别混用全流程里只选一种写法。6. 部署完成后的验证与维护容器状态、数据备份与日常检查6.1 验证 ERPNext 是否真正就绪的三种方式部署成功后第一步是确认容器状态docker compose --project-name erpnext_oob ps所有服务都 Up 还不够因为 Up 只代表进程活着不代表应用可用。更可靠的验证是看后端日志docker compose --project-name erpnext_oob logs --tail 50 backend日志末尾出现Listening at: http://0.0.0.0:8000之类的信息说明后端进程在正常监听。最后在浏览器打开登录页输入默认管理员账号正常进入主界面整个链路才算是真正走通。6.2 数据备份和容器重启的习惯OOB 版默认把数据写在 Docker 容器里容器删除后数据跟着消失。测试环境无所谓要往生产上靠就必须建立备份习惯。最常见的做法是用 ERPNext 自带的备份命令docker compose --project-name erpnext_oob exec backend bench --site all backup这条命令在容器内部生成站点数据库和文件的备份然后把备份目录拷贝到宿主机docker cp erpnext_oob_backend_1:/home/frappe/frappe-bench/sites/backups ./erpnext_backupserpnext_oob_backend_1是容器名不同环境的实际容器名可能不同用docker compose ps确认。数据备份是 ERP 部署里优先级最高的事没有之一。6.3 从开箱版迁移到标准版的思路OOB 版做的是汉化和初始化免配置。后续想切到官方标准镜像或者用bench升级 ERPNext 版本有一条清晰的迁移路径先用bench --site all backup完整备份再在标准镜像环境里恢复站点目录和数据库备份。站点目录里的site_config.json记录了数据库连接和加密密钥等信息迁移时整个目录一起拷不要只搬数据库文件。升级前一定要确认 ERPNext 版本之间有没有明确的迁移路径。ERPNext 14 对应 Frappe 14跨大版本升级前先把备份做好否则数据库结构迁移报错时想回滚都没有后悔药。从那以后我每次部署 ERPNext 都强制走一遍完整流程三件套装好、镜像加速配好、容器启动、登录页验证、备份导出一份做完这五步才敢说部署真正完成。这套流程本身也是一种测试——备份能正常导出说明数据库和文件系统都健康生产环境才敢放心交出去。希望帮到你。本文还有配套的精品资源点击获取