☰
Ubuntu 22.04 上用 Docker Compose 部署 ERPNext 14 完整避坑指南
2026/10/17 1:06:22 网站建设 项目流程

简介:面向需要在 VMware 虚拟机中快速搭建开源 ERP 系统的运维人员与开发者,这份资源以 Ubuntu 22.04.5 为运行环境,完整整理了基于 Docker 部署 ERPNext 14 的安装流程。内容覆盖 Git、Docker、Docker Compose 的安装与版本检查,阿里云软件源与 Docker GPG 密钥验证,并专门给出拉取镜像失败时的 daemon.json 镜像加速器配置;随后通过 erpnext_oob_docker 完成容器化部署,最后在浏览器中访问 localhost 验证系统。压缩包内只有 1 个 docx 文档,包体约 321KB,适合作为边操作边查阅的简明部署手册。该资源已有 629 人浏览学习,尤其适合希望绕过重复配置、快速获得可运行 ERPNext 14 环境的进阶初学者。

1. 为什么选择 Ubuntu 22.04 + Docker 部署 ERPNext 14

ERPNext 14 是我接触过的开源 ERP 里部署门槛比较微妙的一套系统。直接源码安装要处理 Python 环境、Node 环境、Redis、MariaDB、wkhtmltopdf 一堆依赖,版本稍微不对就能折腾一下午;而用 Docker 部署,整个系统被封装进容器,宿主机只要准备好 Docker 环境就行。我这次用的是 Ubuntu 22.04.5 虚拟机 + Docker + Docker Compose 的组合,从装系统到浏览器里跑通 ERPNext 14,大概花了一个多小时,中间大部分时间都耗在 Docker 镜像拉取上。

选 Ubuntu 22.04 而不是更老的 20.04,是因为 22.04 的 apt 源里自带较新的依赖包,而且和 Docker 官方仓库的兼容性更好;ERPNext 14 本身对容器化部署支持得很成熟,官方也推荐生产环境走 Docker 这条路。这套方案对新手最友好的一点在于:只要 Docker 环境建好,后面的一切都是docker compose up -d一条命令的事。如果你正卡在 ERPNext 安装上,或者想在虚拟机里快速搭一套能用的 ERP 环境做测试、学习、二次开发,这篇笔记能让你少走不少弯路。

2. 先搭地基:Git 安装与 Ubuntu 系统初始化

2.1 安装 Git:版本验证别写错参数

ERPNext 的 Docker 部署文件是从 Git 仓库克隆下来的,所以 Git 是第一项要装的东西。Ubuntu 22.04 的默认源里就有 Git,直接 apt 安装就行,不需要额外加 PPA。

sudo apt-get install git git --version

第二条命令注意是两个短横线,很多新手在文档里复制粘贴时会变成git –version(一个类似连接符的长横线),结果 shell 直接报错说找不到这个选项。装完能看到类似git version 2.34.1的输出,就说明 Git 可用了。我一般还会顺手配一下用户信息,虽然拉取公开仓库不需要,但后面如果自己提交代码或修改配置,没配会报错:

git config --global user.name "yourname" git config --global user.email "you@example.com"

2.2 系统更新:update、upgrade、full-upgrade 的区别要分清

在装 Docker 之前,先把系统软件包更新到最新状态。这一步很多人会省略,但 Ubuntu 22.04.5 如果长期没更新,apt 源索引可能是旧的,后面安装 Docker 时可能因为依赖版本不满足而失败。

sudo apt update sudo apt upgrade sudo apt full-upgrade

apt update只是刷新软件源索引,不实际升级任何包;apt upgrade升级已安装的软件包,但不处理依赖关系变化;apt full-upgrade是更激进的升级,会处理依赖冲突并可能移除旧包。我一般会三条连着跑,尤其是刚从 VMware 装完系统、还没改过源的情况下,这一步能避免后面一堆莫名其妙的问题。这里有个细节:如果虚拟机网络较慢,apt upgrade可能需要几分钟,别中途 Ctrl+C。

系统更新完,我习惯顺手reboot一次,让内核和系统服务都处于干净状态。别小看这次重启,很多装 Docker 后遇到的诡异问题(比如 containerd 起不来)其实是旧内核和新 Docker 组件不匹配导致的。

3. 安装 Docker:GPG 密钥、软件源、用户组一次配齐

3.1 添加依赖包与 GPG 密钥:为什么必须走 HTTPS

Docker 官方仓库要求系统支持通过 HTTPS 获取软件包,所以要先装四个依赖:apt-transport-https、ca-certificates、curl、software-properties-common。这几个包不只是为了让 apt 走 HTTPS,software-properties-common还提供了add-apt-repository命令,后面添加 Docker 软件源靠的就是它。

sudo apt install apt-transport-https ca-certificates curl software-properties-common

接着添加 Docker 的 GPG 密钥。这里我用的是阿里镜像站的密钥地址,比直接连 Docker 官方服务器快得多,尤其在虚拟机网络环境不理想的时候差别很明显:

sudo -i curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-ce.gpg

curl -fsSL中-f表示遇到 HTTP 错误就失败退出,-s静默模式,-S显示错误信息,-L跟随重定向;gpg --dearmor把下载的 ASCII 格式密钥转换成二进制格式,存到/etc/apt/trusted.gpg.d/目录下,apt 就会信任这个密钥签名的软件源。注意我用了sudo -i切换到 root 执行,避免权限问题。

验证密钥是否正确,用指纹命令:

sudo apt-key fingerprint 0EBFCD880

这里我用的是指纹的前缀,完整指纹是 0EBFCD88,输出里会显示 Docker 相关的公钥信息。如果这个命令查不到内容,说明密钥没有正确导入,后面添加软件源一定会报NO_PUBKEY错误。

3.2 添加阿里稳定版软件源并安装 Docker 核心组件

密钥验证通过后,添加 Docker 稳定版软件源。这里仍然走阿里镜像,地址里有$(lsb_release -cs)这个动态参数,Ubuntu 22.04 会自动替换成jammy:

sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io

add-apt-repository会把这一行写入/etc/apt/sources.list.d/下的新文件里。apt install docker-ce docker-ce-cli containerd.io装的是 Docker 的三个核心组件:docker-ce是 Docker 引擎本体,docker-ce-cli是命令行工具,containerd.io是容器运行时。这三者版本是绑定的,不要单独升级其中某一个,否则可能出现客户端和服务端版本不匹配。

装完后验证一下:

docker --version sudo systemctl status docker

docker --version能看到类似Docker version 24.0.7的输出。如果systemctl status显示active (running),说明 Docker 服务已经起来了。

3.3 用户组配置:不用每次敲 sudo

Docker 安装后,只有 root 用户和 docker 用户组成员才能直接运行 docker 命令。默认情况下普通用户执行docker images会报权限错误,所以要把当前用户加进 docker 组:

sudo usermod -aG docker 你的用户名 su - 你的用户名 docker images

usermod -aG中的-a表示追加,-G指定附加组,不会影响用户原来的组。加了组之后必须重新登录让组信息生效,su - 用户名就是切换并刷新 shell 状态的常见做法。如果直接在当前终端里跑docker images,大概率还会提示权限不足,这时候别怀疑自己操作错了,就是会话没刷新。

执行docker images应该能进入命令而不报错,此刻仓库是空的,所以输出里没有镜像列表是正常的。我一般会再跑一句docker run hello-world做完整验证,但考虑到这里后面要配置镜像加速,可以等配好再测。

3.4 Docker 服务管理命令与状态检查

装完 Docker,这几个日常管理命令最好先记住,后面部署 ERPNext 时会反复用到:

sudo systemctl start docker sudo systemctl stop docker sudo systemctl restart docker sudo systemctl enable docker sudo systemctl status docker

enable是设置开机自启,虚拟机重启后 Docker 能自动运行;restart是改完配置后重新加载服务的标准操作。我给这套环境做检查时,会先restart再status,确认服务没有因为配置修改而挂掉。状态输出里重点看两行:Active: active (running)和Loaded: loaded (/etc/systemd/system/docker.service; enabled),前者表示当前运行,后者表示开机自启已设置。

4. 配置 Docker 镜像加速:拉取 ERPNext 镜像的关键一步

4.1 daemon.json 的写法与常见错误

从 Docker Hub 拉镜像在国内网络环境下经常超时,尤其是 ERPNext 这种体积很大的镜像。我的做法是直接配置/etc/docker/daemon.json,给 Docker 守护进程加镜像加速器。这个文件默认不存在,需要手动创建:

sudo -i touch /etc/docker/daemon.json chmod 777 -R /etc/docker/daemon.json vim /etc/docker/daemon.json

chmod 777在这种系统配置文件上其实不太规范,但作为临时配置手段很管用,能排除文件权限导致的读取失败问题。写入 JSON 内容:

{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker.nju.edu.cn", "https://docker.mirrors.ustc.edu.cn", "https://mirror.iscas.ac.cn", "https://mirror.aliyuncs.com" ] }

这里我保留了几个当前可用性较好的镜像地址,实际使用中不同地区、不同运营商的连通性差异很大。加速器的原理是 Docker 在拉取镜像时会先请求镜像加速器,加速器缓存了热门镜像,如果本地网络直连 Docker Hub 慢,走加速器能快很多。注意registry-mirrors的值必须是数组,即使只填一个地址也要加方括号,这是最常见的格式错误。

保存后重启 Docker 加载配置:

systemctl restart docker systemctl daemon-reload systemctl restart docker

第一次restart是让 daemon 重新读取 JSON 配置,daemon-reload是让 systemd 重新加载 unit 文件,第二次restart是确保最终的配置生效。我习惯连跑两遍,因为只跑一次偶尔会遇到 daemon 没完全加载新配置的情况。

4.2 验证加速器是否生效

配置完加速器,用docker info查看:

docker info | grep -A 5 "Registry Mirrors"

如果输出里列出了你刚写入的那些地址,说明加速器已经生效。然后跑一个测试拉取:

docker pull hello-world

能在一两分钟内拉取成功,说明网络链路正常。这一步很关键,因为 ERPNext 的镜像体积有几百 MB,如果这里就不通,后面的docker compose up会卡在拉取阶段很久。

5. 部署 ERPNext 14:docker compose 一条命令拉起整套系统

5.1 安装 Docker Compose 并配置命令链接

ERPNext 的 Docker 部署用到的是独立二进制的docker-compose,不是 Docker 插件版的docker compose。新版 Docker 集成了 compose 插件,但这个开箱即用版仓库里用的是独立命令,两个都装也不冲突。我用的是从 GitHub 下载最新版的方式:

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

$(uname -s)和$(uname -m)动态获取系统类型和架构,在 Ubuntu 22.04 x86_64 虚拟机里会被替换成Linux和x86_64,拼出完整的下载文件名。chmod +x给二进制文件可执行权限,软链接则让docker-compose命令在 PATH 里能被找到。虽然/usr/local/bin一般已经在 PATH 里,但有些发行版或自定义环境会漏掉它,链到/usr/bin是最保险的办法。

验证版本:

docker-compose --version

能看到类似Docker Compose version v2.24.1的输出就说明装好了。注意如果下载很慢,可以手动在浏览器里下载对应文件再传到虚拟机,效果一样。

5.2 克隆部署仓库并启动服务

镜像加速配置好、Compose 也装好后,就可以开始部署 ERPNext 了。这个仓库是汉化开箱即用版,里面已经写好了完整的docker-compose配置,包含 ERPNext 14、数据库、Redis 等服务的编排:

git clone https://gitee.com/yuzelin/erpnext_oob_docker && cd erpnext_oob_docker docker compose --project-name erpnext_oob -f pwd.yml up -d

第一条命令从 Gitee 拉取仓库并进入目录,Gitee 在国内访问比 GitHub 稳定得多。第二条命令里--project-name erpnext_oob指定项目名,所有容器都会以这个前缀命名,方便管理;-f pwd.yml指定使用当前目录下的pwd.yml作为编排文件;up -d表示构建并后台启动所有服务。

这一步会拉取大量镜像,包括 ERPNext 14 主镜像、MariaDB、Redis 等,取决于网络情况可能需要 10 到 30 分钟。如果发现拉取卡住,先按 Ctrl+C 中断,再检查docker info里的加速器配置是否生效,或者换一组镜像地址。启动完成后用以下命令查看状态:

docker compose --project-name erpnext_oob ps docker ps

docker compose ps看的是这个项目内所有容器的状态,docker ps列出宿主机上所有运行中的容器。如果看到多个Up状态的容器,说明服务启动成功。我在这步踩过一次坑:因为事先没检查 80 端口是否被占用,容器启动后一直报端口冲突,重启了 Apache 才解决。

6. 避坑指南:ERPNext 14 Docker 部署的 5 个高频问题

6.1 现象:容器启动后 80 端口被占用

使用docker compose up -d时提示port is already allocated,或者浏览器访问时看到的是其他页面。原因通常是宿主机上已经跑了 Nginx、Apache 或者其他 Web 服务,占用了 80 端口。解决方法是先执行sudo lsof -i:80或sudo netstat -tlnp | grep 80找到占用进程,停掉它或者让出端口。我一般直接sudo systemctl stop apache2或sudo systemctl stop nginx,然后重启 ERPNext 容器。

6.2 现象:docker compose 命令执行时报 yaml 语法错误

提示yaml: line X: mapping values are not allowed in this context。多数情况是pwd.yml里的缩进格式被改了,或者文件是从 Windows 拷贝过来的,带上了\r换行符。解决方法是检查编排文件的缩进一致性,确保每层只空两格;如果是 Windows 来的文件,用sed -i 's/\r$//' pwd.yml清理掉回车符,再重新跑docker compose -f pwd.yml config查语法。

6.3 现象:镜像拉取永远超时

拉取frappe/erpnext镜像时长时间卡在pulling,最后报net/http: TLS handshake timeout。这是典型的 Docker Hub 直连失败现象。我之前就在这一步卡得最久,后来把镜像加速器配置重新写了一遍才算解决。解决方法在上面第 4 章已经讲过,这里补充一点:如果所有镜像加速器都失效,可以执行docker pull时加--platform linux/amd64参数强制指定架构,偶尔能绕过部分网络问题。

6.4 现象:浏览器提示无法连接 localhost

容器明明显示Up状态,但访问http://localhost却连不上。先确认宿主机防火墙是否放行了 80 端口,Ubuntu 默认ufw可能是开启状态。执行sudo ufw allow 80/tcp放行。另外还要确认容器映射端口是否正确,用docker ps查看PORTS列,正常应该显示0.0.0.0:80->80/tcp或类似的映射关系。这里有个文档坑:原文写的是http://localhost/80,实际浏览器访问只需要http://localhost就行。

6.5 现象:System Check 报错或初始化一直转圈

第一次访问 ERPNext 安装向导时,页面一直转圈或者报System Check failed。通常原因有两个:一是容器内存不足,ERPNext 14 要求至少 2GB 内存,虚拟机分配内存如果只有 1GB 就会出问题;二是 MariaDB 容器还没完全初始化。解决方法是检查虚拟机内存设置,给到 4GB 比较稳妥;数据库初始化慢的话就多等几分钟,执行docker logs -f 容器名看看数据库是否已经 ready。如果在安装向导里遇到Hosts is not set之类的报错,检查一下是否在 ERPNext 的站点配置里填对了域名。

7. 装完怎么验证跑通:从端口检查到业务数据入库

部署完成后,验证要按层次来,不能只看容器是不是Up状态就以为万事大吉。

第一步先确认所有容器都在运行。进入部署目录执行docker compose --project-name erpnext_oob ps,正常应该看到erpnext、mariadb、redis等容器全部处于Up状态,后台的restarting状态说明某个容器起不来,需要看日志。接着在浏览器里访问http://localhost,注意如果虚拟机上没有图形界面,就用宿主机浏览器访问虚拟机的 IP 地址,比如http://192.168.x.x。看到 ERPNext 的安装欢迎页就算网络通了。

安装向导里填管理员账号和密码时,密码强度要求比较高,建议直接带上大小写字母加数字和特殊符号,避免反复校验不通过。设置向导最后一步会创建数据库并初始化站点数据,这一步根据宿主机磁盘性能可能要等几分钟,中途别刷新页面。初始化完成后进入 ERPNext 后台,再走一遍实际业务验证:

验证项操作预期结果
站点连通访问http://localhost能进入登录页并登录
基础数据新建一个客户资料保存后列表能查到记录
功能模块建一张销售订单单据能正常保存、提交
容器稳定性执行docker compose ps所有容器连续运行无重启

走完这四个验证点,这套环境才算真正跑通。我习惯在验证通过后再做一次快照备份,这样后面如果改配置改崩了,能一键回到这个干净状态——这算是我被装崩好几次后换来的习惯。

从那以后我每次在新虚拟机部署 ERPNext 14,都强制自己走一遍“系统更新 → Git → Docker → 镜像加速 → compose 部署 → 建单验证”的完整流程,不会有跳过。装坏了大不了回滚快照,人生苦短,别浪费在反复重装环境上。希望这篇笔记能帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询