惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
Microsoft Azure Blog
Microsoft Azure Blog
The Register - Security
The Register - Security
Stack Overflow Blog
Stack Overflow Blog
博客园 - 三生石上(FineUI控件)
T
Threat Research - Cisco Blogs
S
SegmentFault 最新的问题
V2EX - 技术
V2EX - 技术
Hacker News: Ask HN
Hacker News: Ask HN
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Proofpoint News Feed
J
Java Code Geeks
Microsoft Security Blog
Microsoft Security Blog
M
MIT News - Artificial intelligence
AI
AI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
P
Proofpoint News Feed
Hacker News - Newest:
Hacker News - Newest: "LLM"
B
Blog
N
News and Events Feed by Topic
N
News | PayPal Newsroom
Google DeepMind News
Google DeepMind News
酷 壳 – CoolShell
酷 壳 – CoolShell
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
C
Cybersecurity and Infrastructure Security Agency CISA
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
U
Unit 42
腾讯CDC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Cloudflare Blog
H
Help Net Security
Recent Announcements
Recent Announcements
P
Privacy & Cybersecurity Law Blog
IT之家
IT之家
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Security Archives - TechRepublic
Security Archives - TechRepublic
L
LINUX DO - 热门话题
Martin Fowler
Martin Fowler
MongoDB | Blog
MongoDB | Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
H
Heimdal Security Blog
博客园 - 聂微东
S
Securelist
大猫的无限游戏
大猫的无限游戏
Cloudbric
Cloudbric
Cisco Talos Blog
Cisco Talos Blog

博客园 - Nihaorz

告别闪烁,拥抱流畅:在 Windows Terminal 中完美配置 Cygwin 环境 Nginx 透明代理 + 自动回源存储:访问即缓存,落盘即文件 创建 docker ipvlan,让 docke 容器获取独立ip 电犀牛 R68s iStoreOS 2.5G 网口速率优化 解决 openwrt ssh 命令行终端 home、end 键不可用问题 一键添加视频封面脚本 ffmpeg 转码参数 docker save 远程 ssh 主机直接 load,不产生本地文件 AutoHotKey 脚本 - win10 自动连接无线显示器 SSH 登录/退出实时监控脚本 OpenClaw 安装部署,配置 deepseek curl 断点续传下载 debian iso 镜像下载地址 linux 安装 zerotier,加入网络 基于 Fail2ban 的 SSH 入侵自动反制方案 ssh 配置密钥登录,关闭密码登录 memc - 基于 shell 的交互式清理内存脚本 基于 Fail2ban 的 OpenWRT SSH 入侵自动反制方案 Linux Screen 命令速查 linux 磁盘挂载示例
使用 ofelia 在 docker 容器中执行计划任务
Nihaorz · 2026-03-02 · via 博客园 - Nihaorz

我需要在执行某些计划任务,由于一些不可名状的原因,我不想在宿主机上写 cron,不然全天下都知道我在干什么了,那么我就脱裤子放个屁 —— 在 docker 容器内部悄咪咪的执行

具体场景是我启动了一个 nginx 的 docker 容器,我需要每2个小时执行一次授权检测,授权检测实际上就是在 nginx 容器内部执行一个检测脚本,脚本具体工作事项就不具体介绍了

原本这个事情直接在宿主虚拟机上搞定是最直接的,但是直接在宿主上跑一个计划任务那不是谁都知道了(就是防止一下甲方问东问西),那这里我们就需要用到 ofelia,让 ofelia 来帮我干这个活

摘抄一份 deepseek 查到的 ofelia 介绍

Ofelia 非常灵活,提供了四种不同的任务(Job)类型以适应不同场景:

job-exec:在 指定的、正在运行 的容器中执行命令。例如,定期在已有的 nginx 容器里执行日志清理脚本。

job-run:每次任务触发时,都会基于指定的镜像创建一个新容器来执行命令,执行完毕后销毁该容器。这对于运行一次性的、隔离性要求高的任务非常有用。

job-local:在 运行 Ofelia 本身的主机(或容器)上 直接执行命令。

job-service-run:用于 Docker Swarm 模式,在 Swarm 集群中创建一个一次性服务来执行任务。

下面上代码

docker-compose.yml

services:

  nginx:
    image: owasp/modsecurity-crs:nginx
    container_name: nginx
    hostname: nginx
    volumes:
      - ./server.conf:/etc/nginx/conf.d/server.conf
      - ./html:/usr/share/nginx/html
      - ./rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:/etc/modsecurity.d/owasp-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:ro
    environment:
      - TZ=Asia/Shanghai
      - BLOCKING_PARANOIA=2     # 阻断模式的严格等级
      - ANOMALY_INBOUND=4       # 入站异常分数阈值,低于 9 GetCapabilities 就会被拦截
      - ANOMALY_OUTBOUND=4      # 出站异常分数阈值
    ports:
      - "80:80" # modsecurity-nginx 内部由8080端口反向代理到80端口,我们自己的配置文件以80端口启动即可
    user: root
    restart: always

  ofelia:
    image: mcuadros/ofelia:0.3
    container_name: ofelia
    hostname: ofelia
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - TZ=Asia/Shanghai
    user: root
    restart: always

ofelia/config.ini

[job-exec "auth_check"]

# 每秒执行
# schedule = * * * * * *

# 每两个小时执行
schedule = 0 0 */2 * * *

container = nginx
command = sh /script/auth_check.sh

# 可选参数
user = root                    # 指定执行用户
no-overlap = true              # 防止任务重叠执行

script/auth_check.sh

#!/bin/bash

export PATH=$PATH:/usr/local/bin

DEADLINE="2026-03-03 00:00:00"
LOG_FILE="/var/log/auth_check.log"

if [ $(date +%s) -gt $(date -d "$DEADLINE" +%s) ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 授权已过期" >> $LOG_FILE
    touch /etc/nginx/auth_expired.lock 2>/dev/null
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 授权正常" >> $LOG_FILE
    rm /etc/nginx/auth_expired.lock -rf 2>/dev/null
fi

三个文件准备好后执行下面的启动命令(不在启动 compose 时挂载文件,使用 docker cp 则是为了不留痕迹, docker cp 完毕后记得删除 script 和 ofelia 两个目录,深藏功与名)

docker compose up -d
docker cp script nginx:/
docker cp ofelia ofelia:/etc

# ofelia 启动后没有配置文件,拷贝配置文件进去后停止2秒等待下一次重启
sleep 2
docker logs -f ofelia

# 删除 script 和 ofelia 深藏功与名
# rm script ofelia -rf

ofelia 的容器日志应该类似下面这样

open /etc/ofelia/config.ini: no such file or directory
open /etc/ofelia/config.ini: no such file or directory
2026-03-01T19:20:00.793+08:00  scheduler.go:44 ▶ NOTICE New job registered "auth_check" - "sh /script/auth_check.sh" - "0 0 */2 * * *"
2026-03-01T19:20:00.793+08:00  scheduler.go:55 ▶ DEBUG Starting scheduler with 1 jobs

说明任务已经注册成功了,等待下一次任务执行后再查看最新日志即可

针对我的这个任务查看是否执行成功则很简单,运行下面的 docker 命令验证即可

[root@host-10-1-146-42 srv]# docker exec -it nginx cat /var/log/auth_check.log
2026-03-01 20:00:00 - 授权正常

说到底上面这个流程近似于脱裤子放屁,要更隐蔽一点就不要直接使用 ofelia,from ofelia,自己 build 一个镜像,把配置文件换一个路径,把镜像换一个名字掩盖一下

如果还嫌不够彻底,那就自己用 go 或 c++ 写一个程序,硬编码要执行的计划任务