将RSS抓取应用放进Docker容器,本质是把运行脚本所需的解释器、第三方库和配置全部打包成不可变镜像,从而屏蔽不同主机之间的差异。下面以Python编写的RSS抓取程序为例,梳理从代码到可运行容器的完整路径。

一、准备RSS抓取脚本
我们先写一个简单的RSS抓取脚本,它使用feedparser库读取订阅源,并把标题和链接写入本地JSON文件。这个脚本不依赖外部服务,方便后续容器化测试。
在真实项目中,你可能会加入去重、异常处理和多种输出格式。但容器化的核心不在于脚本多复杂,而在于让脚本在任何地方都以相同方式运行。因此保持脚本对环境的假设越少越好,比如不要硬编码绝对路径,而是通过环境变量获取输出目录。
import os
import json
import feedparser
RSS_URL = os.getenv('RSS_URL', 'https://ipipp.com/feed.xml')
OUT_DIR = os.getenv('OUT_DIR', '/data')
def fetch():
feed = feedparser.parse(RSS_URL)
items = []
for entry in feed.entries:
items.append({'title': entry.title, 'link': entry.link})
if not os.path.exists(OUT_DIR):
os.makedirs(OUT_DIR)
with open(os.path.join(OUT_DIR, 'news.json'), 'w', encoding='utf-8') as f:
json.dump(items, f, ensure_ascii=False, indent=2)
if __name__ == '__main__':
fetch()
二、编写Dockerfile
Dockerfile决定了镜像里有什么。我们采用多阶段构建,第一阶段安装依赖并生成虚拟环境,第二阶段只复制必要文件,从而显著减小最终镜像体积。基础镜像选用slim版本,既保留包管理工具,又避免完整桌面环境带来的冗余。
需要注意,在容器里应当用非root用户运行脚本,提升安全性。同时用ENV指令设置默认环境变量,让容器在未指定参数时也能正常工作。下面的例子展示了完整步骤,其中pip安装部分锁定了feedparser版本,防止上游变更破坏构建。
FROM python:3.11-slim AS builder WORKDIR /app RUN pip install --no-cache-dir feedparser==6.0.10 FROM python:3.11-slim WORKDIR /app COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY rss_fetch.py . ENV RSS_URL=https://ipipp.com/feed.xml ENV OUT_DIR=/data RUN useradd -m appuser && mkdir /data && chown appuser:appuser /data USER appuser CMD ["python", "rss_fetch.py"]
三、配置定时抓取
很多RSS应用需要周期运行而非常驻进程。我们可以在容器启动时用shell循环配合sleep实现简易定时,也可以借助宿主机的cron直接重新创建容器。前者逻辑内聚,后者更容易集中管理。
如果选择在镜像内定时,可以把CMD换成包装脚本。下方代码展示了一个每半小时执行一次的入口脚本,它通过环境变量INTERVAL控制间隔,避免修改镜像就能调整频率。使用exec形式确保信号能正确传递给Python进程,方便容器优雅停止。
#!/bin/sh
INTERVAL=${INTERVAL:-1800}
while true; do
python /app/rss_fetch.py
sleep $INTERVAL
done
四、使用docker compose编排
当抓取源变多或需要同时挂载存储、设置网络时,命令行参数会显得杂乱。docker compose用声明式文件描述服务,便于版本控制和团队复用。我们在compose中挂载本地目录到/data,保证抓取结果落盘。
下面的配置定义了一个rss服务,构建上下文为当前目录,并限制容器重启策略为失败时重试。通过environment覆盖默认源地址,展示如何在不改代码情况下切换目标。这种结构让你在另一台机器只需执行docker compose up即可恢复整套采集任务。
version: '3.8'
services:
rss:
build: .
environment:
- RSS_URL=https://ipipp.com/tech/feed.xml
- OUT_DIR=/data
- INTERVAL=900
volumes:
- ./output:/data
restart: on-failure
五、构建与运行验证
完成上述文件后,在含Docker环境的主机执行构建命令,观察分层缓存是否命中以加快后续变更。构建成功后运行容器,检查输出目录是否生成news.json,并确认文件内容包含预期字段。
若抓取为空,优先排查容器日志与网络策略,因为部分环境禁止容器访问外网。可以在compose里临时添加network_mode为host做对比测试。整个流程跑通后,镜像可推送到私有仓库,供其他节点拉取,实现真正的一次构建到处运行。
docker build -t rss-fetcher:local . docker run --rm -v "$PWD/output:/data" rss-fetcher:local cat output/news.json