最近弄了好多东西,根本没有时间记录,所以用 AI(DeepSeek) 记录总结一次完整的 Firecrawl 容器化部署故障排查过程,详细记录从问题发现到解决的每一步。不得不说 DeepSeek 最新的 3.2 模型真的垃圾,写个记录总结都做不好,丢三落四的简直就是老人痴呆,没时间人工修正,凑合着看吧。顺便提一嘴,还是今年5月份的 Google Gemini 2.5 Pro 才是真强,是至今唯一让我感觉惊艳的模型,能力真的强太多了,很多时候我都不用说太多讲太明白,它就能 Get 到了,智商很高,现在的都是些降智的智障货色,要写一大堆提示,还做不好。
另外吐槽一下 Firecrawl 官方的部署说明(firecrawl/SELF_HOST.md at main · firecrawl/firecrawl),按照它的步骤操作根本不行,必须修改官方的 .env 和 docker-compose.yml 文件才能部署成功。
问题初现:服务无法访问
在部署 Firecrawl 项目后,发现 API 服务无法正常启动:
sudo docker compose logs api
关键错误信息:
Error: listen EADDRINUSE: address already in use 0.0.0.0:3002
api Node.js v22.20.0
✗ api 13.8s (1)
✗ Fatal error occurred
第一步:确认问题现象
1.1 检查服务状态
sudo docker compose ps
发现只有基础服务运行,API 服务反复重启。
1.2 查看详细日志
sudo docker compose logs api --tail=50
发现服务在启动过程中多次尝试绑定 3002 端口失败。
第二步:分析端口占用情况
2.1 检查宿主机端口占用
sudo lsof -i :3002
sudo netstat -tulpn | grep 3002
确认 3002 端口是否被其他进程占用。
2.2 检查 Docker 容器端口映射
sudo docker ps -a --format "table {{.Names}}\t{{.Ports}}"
查看所有容器的端口映射情况。
第三步:深入分析服务架构
3.1 分析 docker-compose.yml 结构
services:
api:
ports:
- "3002:3002" # 外部:内部端口映射
environment:
PORT: 3002 # 容器内部服务端口
playwright-service:
environment:
PORT: 3000 # 内部使用3000端口
extract-worker:
# 官方配置文件中根本就没有这个,健康检查默认使用3002端口
3.2 发现关键问题
通过分析发现多个服务存在端口冲突:
- api 服务:内部使用 3002 端口
- extract-worker:健康检查也使用 3002 端口
- playwright-service:使用 3000 端口(可能与宿主机其他服务冲突)
第四步:制定解决方案
4.1 端口重新规划方案
服务 原端口 新端口
------ ------ ------
api (内部) 3002 3004
api (外部映射) 3002:3002 3002:3004
playwright-service 3000 3001
extract-worker 3002 3003
4.2 修改配置文件
更新 .env 文件:
# 端口配置
PORT=3002 # 外部访问端口
INTERNAL_PORT=3004 # 新增API容器内部端口
HOST=0.0.0.0
# 服务配置
PLAYWRIGHT_MICROSERVICE_URL=http://playwright-service:3001/scrape
更新 docker-compose.yml:
services:
api:
environment:
PORT: ${INTERNAL_PORT:-3004} # 改为3004
WORKER_PORT: ${WORKER_PORT:-3005}
EXTRACT_WORKER_PORT: ${EXTRACT_WORKER_PORT:-3003} # 新增
ports:
- "${PORT:-3002}:${INTERNAL_PORT:-3004}" # 外部3002映射到内部3004
playwright-service:
environment:
PORT: 3001 # 改为3001避免冲突
ports:
- "3001:3001"
第五步:实施解决方案
5.1 停止现有服务
sudo docker compose down
5.2 清理环境
# 检查并释放可能被占用的端口
sudo lsof -i :3003
sudo lsof -i :3004
5.3 应用新配置
# 重新启动服务
sudo docker compose up -d
第六步:验证解决方案
6.1 检查服务状态
sudo docker compose ps
期望输出:所有服务状态为 "Up"
6.2 验证端口映射
sudo docker port firecrawl-api-1
确认端口正确映射:3004/tcp -> 0.0.0.0:3002
6.3 测试服务健康状态
# 测试playwright-service
curl http://localhost:3001/health
# 测试API服务
curl http://localhost:3002/
# 测试API功能
curl -X POST http://localhost:3002/v0/scrape \
-H "Content-Type: application/json" \
-d '{"urls": ["https://example.com"]}'
6.4 检查服务日志
sudo docker compose logs api --tail=20
sudo docker compose logs playwright-service --tail=10
确认无错误信息,服务正常启动。
第七步:配置不必需的环境变量
7.1 设置AI功能所需变量
# 编辑.env文件添加配置
echo 'OPENAI_API_KEY=your_actual_api_key_here' >> .env
echo 'MODEL_NAME=gpt-3.5-turbo' >> .env
echo 'MODEL_EMBEDDING_NAME=text-embedding-3-small' >> .env
7.2 重启服务应用配置
sudo docker compose down
sudo docker compose up -d
最终验证
完整功能测试
# 1. 检查所有服务状态
sudo docker compose ps
# 2. 测试各服务端点
curl -s http://localhost:3001/health | jq '.status'
curl -s http://localhost:3002/v0/ | jq '.'
# 3. 执行完整爬取测试
curl -X POST http://localhost:3002/v0/scrape \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TEST_API_KEY}" \
-d '{
"urls": ["https://httpbin.org/json"],
"formats": ["markdown"]
}' | jq '.'
排查总结
通过这次故障排查,总结出容器化部署的排查要点:
- 从现象到根源:从服务重启现象追溯到端口冲突根本原因
- 系统化分析:逐层分析宿主机、Docker、容器内部的端口使用情况
- 架构理解:深入理解微服务架构中各组件的交互关系
- 渐进式解决:小步修改、及时验证,确保每一步改动都有效
这次排查不仅解决了当前的端口冲突问题,更重要的是建立了一套完整的 Docker 容器故障排查方法论,为后续的运维工作奠定了坚实基础。
Comments NOTHING