
Windows上直接用Docker跑Apache Doris是我本地做数据分析实验时摸索出的方案。Doris这个MPP分析型数据库查大宽表确实快但官方常规部署方式一直以Linux为主对只用Windows当开发机的程序员来说第一步就容易被劝退。后来我换了思路Windows装Docker Desktop把Doris拆成FE和BE两个容器跑从环境准备到建表导入数据半小时内能全部搞定。这篇就把整个流程、端口规划、常见坑一起记录下来适合想快速体验Doris、做小规模联调试验或者暂时不方便开Linux虚拟机的读者。1. 为什么Windows上跑Doris我首选Docker这条路1.1 先搞清楚Doris的部署形态Doris的架构一句话讲就是“一前一后”FE负责元数据、查询规划、任务调度和对外服务BE负责数据存储和查询计算。你在MySQL客户端里执行一条SQL实际上是连到FE的9030端口FE把SQL拆成查询计划分发给多个BE去执行最后再把结果汇总回来。所以手动部署Doris最少也要两个组件以前不少人直接在Linux物理机上各自解压FE、BE目录改配置、起服务、再去FE里注册BE步骤不少。这里想通之后Docker的优势就很明显了FE和BE各起一个容器环境、依赖、启动脚本都打在镜像里你只需要关心端口怎么映射、数据挂在哪里剩下的交给容器。Windows本机直接跑Doris会很别扭因为Doris的启动脚本是bash、依赖glibc运行环境和JDK就算你在Windows装了bash各种文件路径、权限、信号处理也会让你折腾到怀疑人生。尤其是第一次接触Doris的人与其自己啃编译产物和shell脚本不如直接用现成镜像把时间节省下来。1.2 Docker方案比本机直接跑好在哪Docker Desktop在Windows上默认走WSL2容器内核其实跑在轻量Linux虚拟机里Doris遇到的整套Linux习惯全都兼容。用Docker还有一个好处是“犯错成本低”配置写坏了把容器删掉重新跑一遍就是不会像本机安装那样弄得环境里到处是残留文件。对技术人员来说能快速重来比什么都重要。另一个实用点端口映射。Windows宿主机直接访问localhost:8030和localhost:9030就能打到容器里不需要记IP也不需要在Windows里装Doris的一堆依赖。Docker Hub上有官方镜像apache/doris版本跟着官网走小版本升级只需改一下tag重来一次部署。后面我会用docker compose做编排因为FE和BE两个容器同时管理compose比两条docker run命令清晰得多日志、网络、依赖关系都统一处理。2. 环境准备Docker Desktop、WSL2和虚拟化一个都不能少2.1 安装前先检查两个硬性条件Docker Desktop能正常启动前提是Windows的虚拟化功能开着。很多人在安装Docker Desktop时第一次启动就弹“virtualization support not detected”或“Docker Desktop failed to start because v...”这类错误十有八九是BIOS里的VT-xIntel或SVMAMD没开。检查方法是打开任务管理器切到“性能”页看“虚拟化”那项是不是“已启用”。如果是“已禁用”就需要进BIOS找Intel Virtualization Technology或AMD SVM Mode打开后保存重启。第二步是启用Windows功能。Win10/11家庭版用户也照样能用WSL2只需在“控制面板-程序和功能-启用或关闭Windows功能”里勾上“虚拟机平台”和“适用于Linux的Windows子系统”然后重启。如果你之前用过Hyper-V也保留启用状态。这一步做完再装Docker Desktop就顺利很多。2.2 Docker Desktop的安装与基本配置Docker Desktop的安装流程本身没什么好说的下载安装包后一路默认关键是在弹窗选择后端时要选“Use WSL 2 instead of Hyper-V”因为WSL2更容易和Windows协同资源占用也比老式Hyper-V方案轻。装完以后建议进入Settings在General里确认“Use the WSL 2 based engine”是勾选状态再进入Resources在WSL Integration里把你准备用的那个WSL发行版打开集成比如默认的Ubuntu。装好后打开Windows Terminal执行docker version确认客户端和服务端都能正常输出。如果这里能看到Server信息Docker环境就算夯实了。还要提一句Docker Desktop首次启动可能要等一两分钟右下角鲸鱼图标不转圈了才说明准备好。如果一直转圈多半是前面的虚拟化或WSL2组件没弄好。2.3 给WSL2分配内存和CPU别让Doris饿着很多人部署Doris时遇到容器进程反复被杀或启动失败问题往往不在Docker而在WSL2的默认内存限制太小。WSL2默认最多吃一半物理内存对笔记本来说经常不够FE和BE同时跑。此时Windows用户目录下的.wslconfig文件就成了关键配置。我一般这样写[wsl2] memory6GB processors4 swap8GB保存后在Windows Terminal里执行wsl --shutdown等几秒再打开Docker Desktop配置才会生效。如果你只有8GB或16GB内存建议给WSL2至少4GB如果跑Doris还要同时开IDEA、Chrome那16GB机器给6GB比较平衡。磁盘也不可忽视Docker镜像和容器数据都在WSL2的虚拟磁盘文件里C盘空间紧张的话可以在Docker Desktop的Settings里的Advanced选项中把Disk image location改到空间充裕的盘。3. 用docker compose一次性拉起Doris FE和BE3.1 端口规划这组端口分别干什么Doris不像MySQL那样只要一个3306FE和BE各自开着好几个服务端口。我第一次部署时就是因为少映射了某个端口BE注册不上去卡了很久。这里把常用端口表整理出来端口所在组件用途8030FEFE Web UI浏览器访问Doris管理界面9030FEMySQL协议端口客户端连接就在这里9010FEFE内部通信端口BE注册时也会用到8040BEBE Web UI查看BE节点状态9050BEBE心跳注册端口ADD BACKEND时填这个9060BEBE查询服务端口FE调度计算时使用8060BEbRPC端口导入和查询过程会用在Windows下docker compose文件里把容器端口映射到宿主机的相同端口用localhost访问是最直观的方式。如果某个端口被本机其他程序占用就会看到“port is already allocated”之类的启动失败日志。这时候两条命令解决netstat -ano | findstr :9030拿到占用进程的PID再taskkill /F /PID 12345把这个进程结束掉。如果被系统服务占用且无法结束也可以去修改Doris的FE配置里的query_port然后重启容器。3.2 编写docker-compose.yml我把FE和BE写在同一个compose文件里版本号以官方镜像仓库当前tag为准示例用的是2.1.7。文件如下version: 3.8 services: fe: image: apache/doris:2.1.7 container_name: doris-fe ports: - 8030:8030 - 9030:9030 - 9010:9010 volumes: - fe-meta:/opt/apache-doris/fe/doris-meta command: [fe] restart: unless-stopped be: image: apache/doris:2.1.7 container_name: doris-be ports: - 8040:8040 - 9050:9050 - 9060:9060 - 8060:8060 volumes: - be-storage:/opt/apache-doris/be/storage command: [be] restart: unless-stopped depends_on: - fe volumes: fe-meta: be-storage:有两点我要特别说明。第一数据目录建议用命名卷而非bind mount尤其FE的doris-meta对I/O延迟很敏感挂载Windows本地磁盘会让FE启动变慢权限问题也会更频繁命名卷实际存放在WSL2的ext4文件系统里性能比挂Windows盘高不少。第二depends_on只表示启动顺序FE从启动到完全ready需要一段初始化时间BE容器起来后可能连不上FE。我通常先起FE等看到FE日志里出现“Serving as a Frontend”之类的关键字后再观察BE日志最后统一注册BE。3.3 启动容器并注册BE节点在docker-compose.yml所在目录执行docker compose up -d docker compose logs -f fe第一次启动会拉镜像可能要等一阵。看到FE日志稳定输出后直接在宿主机另开一个终端用MySQL协议连到FE执行注册命令。如果Docker镜像里自带mysql客户端可以这样操作docker exec -it doris-fe mysql -uroot -P 9030 -h 127.0.0.1登录后执行ALTER SYSTEM ADD BACKEND be:9050; SHOW BACKENDS;注意这里我用的是compose服务名be而不是IP因为FE和BE在同一个compose网络里服务名可以直接解析。如果SHOW BACKENDS里那一行Alive显示true说明BE注册成功如果是false就去翻BE容器日志。常见原因是FE和BE镜像版本不一致、网络不通、或者BE还处于刚启动状态给它十几秒再来一次。另外有些版本的官方镜像没有内置mysql命令遇到这种情况就在宿主机上装个MySQL客户端工具连接同样能操作本地没有图形客户端的话DBeaver也能执行这些SQL。4. 首次验证建库建表与导入数据4.1 用MySQL客户端连接9030上面的docker exec方式已经验证了内部连通不过日常工作更推荐在宿主机用MySQL客户端直接连localhost。执行mysql -h127.0.0.1 -P9030 -uroot默认情况下root密码为空直接回车就能进。只要进来了就说明端口映射和FE的MySQL协议都正常。如果你更喜欢图形界面DBeaver里新建一个MySQL连接填127.0.0.1、端口9030、用户root也能连上。有些读者连进来会碰到“Host is not allowed to connect to this MySQL server”之类的提示这是新版Doris对root用户做了访问控制收紧。最简单的处理是先通过docker exec方式访问然后执行CREATE USER admin% IDENTIFIED BY 你的密码;再给权限之后用这个新用户连接。生产环境下更应该养成不用root做业务开发的好习惯。4.2 几MB的小数据量表到底要不要分桶这是很多新人问的问题答案很直接几MB的数据量完全没必要分太多桶设置1个分桶就够了。Doris设计大数据量和多节点场景下才需要把数据切成多个分桶做并行扫描本地实验、报表开发阶段数据量可能就几十万行几个GB都不到十几个桶只会让每个桶里文件碎片化导入和查询都要多开销运维上还没什么收益。建表时我会推荐这样写CREATE DATABASE demo; USE demo; CREATE TABLE test_event ( id INT NOT NULL, user_name VARCHAR(50), event_time DATETIME ) DUPLICATE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 1 PROPERTIES (replication_num 1);分桶键尽量选高基数的字段比如id避免选性别、状态这类枚举字段否则数据全部堆到一个桶里分桶就失去了意义。replication_num设成1是因为单BE集群无法做多副本设2反而会提示副本数不足等以后扩到3台BE再相应调整副本数。至于分区小表可以不做Range分区单分区单桶已经能满足绝大多数验证场景。4.3 实例从CSV导入几行数据完成验证建好表后先导入一点数据冒烟。最简单的方式是直接INSERTINSERT INTO test_event VALUES (1, zhangsan, 2025-01-01 10:00:00), (2, lisi, 2025-01-01 10:05:00), (3, wangwu, 2025-01-02 09:30:00); SELECT COUNT(*) FROM test_event;看到返回3就说明整条链路通了。如果手头有CSV文件想验证导入Doris推荐的是Stream Load通过HTTP协议提交。走的是FE的8030端口也就是Web UI那个端口curl --location-trusted -u root: -T data.csv \ -H label:test_label \ -H column_separator:, \ http://127.0.0.1:8030/api/demo/test_event/_stream_load第一次用Stream Load失败别慌大多是label重复、列格式或者文件分隔符没对上把-H参数逐项调整即可。导入成功后可以用SELECT确认条数。5. 部署后的常见问题与排查实录5.1 问题速查表Docker部署Doris踩坑概率最高的场景我汇总成一张表现象可能原因解决思路Docker Desktop启动失败报virtualization相关错误BIOS虚拟化未开或WSL2组件没启用打开BIOS的VT-x/SVM启用“虚拟机平台”和“适用于Linux的Windows子系统”容器起来了但8030端口打不开FE仍在初始化、端口被占用、Windows防火墙拦截等待并观察FE日志netstat查端口放行端口BE注册后Alive一直是falseFE和BE版本不一致、心跳端口不通、BE启动内存不足统一镜像tag检查9050端口连通检查BE日志BE容器反复退出日志出现OOMWSL2内存限制不够或容器无内存限制调整.wslconfig并wsl --shutdown观察Docker Desktop资源占用容器重启后数据“没了”启动时没挂载volume或误执行down -v用命名卷持久化FE元数据与BE存储删容器时保留卷从外部工具连9030失败root访问限制、客户端版本过老、端口未映射创建专用账号使用较新的MySQL客户端核对compose端口Presto/Trino连接Doris报missing相关错误连接器配置里catalog、FE地址不匹配或驱动版本过旧检查连接器配置中的FE HTTP地址和协议版本确认和Doris服务端接口版本匹配5.2 三个值得单独展开的坑第一个坑是Windows端口占用。Doris的8030、9030这些端口不算冷门尤其9030和MySQL默认端口附近很容易撞车。端口被占用后compose会直接报端口分配失败而不会告诉你具体是哪个进程占了。解决方案就是上面说的netstat加taskkill两步走。如果那个进程不能杀比如是公司安全软件那就修改fe.conf里的query_port并把compose映射改成新端口注意客户端连接时也要换端口。第二个坑是BE容器启动时的内存检查。Doris BE在启动时会对系统内存做检测容器里看到的“系统”其实是WSL2虚拟机的内存如果BE认为内存不足会直接退出而不会等待。我在Docker部署时给BE启动命令增加过--containerizedtrue参数不同Doris小版本参数名略有差异就是为了告诉BE你正在容器环境里运行内存检测逻辑要按容器资源来做。如果你的BE日志里频繁出现memory相关报错可以优先考虑这个参数和WSL2内存配额而不是一直调大JVM参数。第三个坑是数据持久化的“假安全”。有人以为docker compose restart不会丢数据就万事大吉实际上如果容器启动命令里没写volumedocker compose down会把容器连同里面的FE元数据、BE数据一起清掉。FE的元数据一旦损坏整个集群状态就乱了。所以从一开始就不要在容器内部留数据FE挂fe-metaBE挂be-storage这样才能docker compose up -d重启后还能看到之前的库表和数据。6. 在Windows上长期使用Doris的经验与选型建议6.1 开发机上要养成的三个好习惯第一把命令封装成Windows Terminal的片段或PowerShell函数。我自己的开发机里存了一个do-doris.ps1里面就是docker compose up -d、docker compose logs -f fe、docker exec -it doris-fe mysql四个常用指令每天省得敲长命令。第二定期备份FE元数据。开发环境里数据丢了能重新导入但FE里的账号权限、建表语句、表元数据信息丢了就非常麻烦我会在每天下班前执行一次docker cp把FE目录里的doris-meta拷到备份目录。备份文件很小但关键时刻能救命。第三控制数据规模。Windows开发机上跑的Doris适合做功能验证和小数据量实验我一般不会让它承接超过几十GB的导入任务。真要把Doris用在生产或准生产环境至少3台Linux服务器做FE高可用和BE多节点Windows容器方案只当作最方便的开发沙盘这一点要在心里划清楚。6.2 顺带聊聊Doris和ClickHouse怎么选部署完Doris之后很多人会拿它和ClickHouse对比。我的感受是单机小数据量实验阶段两者都够用ClickHouse部署更轻、压缩比更激进查询也很猛但Doris胜在MySQL协议和标准SQL的友好度现有数据人员上手门槛低点查、Join、UPDATE这类场景比ClickHouse舒服不少。如果团队后端大量用MySQL生态Doris的兼容性会节省很多适配成本。如果只是做日志流水那种超大批量、宽表聚合分析ClickHouse也是好选择。选型没有绝对谁强关键还是看你手里的业务场景对“标准SQL、实时写入、高并发点查”哪方面更敏感。我在实际部署中最大的体会是Windows加Docker加Doris这套组合最大的阻力不是Doris本身而是WSL2的资源分配和端口环境。很多报错看起来像Doris的问题翻日志才发现是WSL2内存不够或者Windows端口被占。所以遇到问题第一反应应该是docker compose logs -f fe和be把日志当唯一真相来源而不是在网上海量搜索同类报错。最后再说一个我后来一直在用的小技巧在Windows Terminal里给docker命令加上PowerShell函数快捷键或者直接把长命令保存为代码片段让Doris日常操作顺手很多。等你把整套流程熟悉了这个本地环境会比虚拟机方案更轻、更贴近实际集群的运行逻辑。