systemd 单元配置实战:常驻服务、定时任务,以及跑在容器里的命令

一个后台程序要一直跑着,挂了自动拉起来;另一个程序要每 10 分钟跑一次,跑完就退出。这两件事在 Linux 上都归 systemd 管,前者写成 .service,后者要 .service + .timer 一对。 本文把这两种单元的每个字段拆开讲清楚,说明为什么定时任务用 timer 比 crontab 更合适,以及命令实际跑在 Docker 容器里时最容易踩的那个坑。 一、先分清楚 service 和 timer 很多人第一次配 timer 时会困惑:「定时任务为什么要写两个文件?」 因为这是两件事: .service 回答「这个程序该怎么跑」——跑什么命令、用哪个用户、挂了要不要重启、超时多久算失败 .timer 回答「什么时候去启动它」——每 10 分钟、每天凌晨 3 点、开机 5 分钟后 .service 是名词,.timer 是闹钟。闹钟响了就去按一下那个 service 的启动按钮,至于按下去之后发生什么,是 service 自己的事。 所以常驻型的程序只要一个 .service(它自己不停,不需要闹钟),周期型的要一对,而且两个文件必须同名:myapp-sync.service 配 myapp-sync.timer——timer 靠文件名找到对应的 service,改错一个字母就是「闹钟响了但没有任何反应」。 两种文件都放在 /etc/systemd/system/。 二、常驻型:Type=simple + Restart=always 先看一个真实的例子。一个 Python 写的后台 worker,从队列里领任务、执行、再领下一个,永远不退出: [Unit] Description=myapp 后台 worker After=network-online.target docker.service Wants=network-online.target [Service] Type=simple Environment=TZ=Asia/Shanghai WorkingDirectory=/var/www/myapp ExecStart=/var/www/myapp/.venv/bin/python -m worker Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target 逐段拆开。 ...

September 2, 2026 · 5 min · 翼橙

SSH 隧道详解:本地转发、远程转发与动态转发

数据库端口不想对公网开,但本地又要用图形工具连;内网的服务想临时给外面看一眼;出差时想让所有流量走回自己的服务器——这几件事都不用装额外软件,SSH 自带的端口转发就能做。 本文讲清楚三种转发方式的区别、参数怎么记、以及那些一看就懂但一用就错的地方。 一、先理解一件事:转发的是「连接」,不是「端口」 很多教程一上来就给命令,看完照抄能跑,但换个场景就不会改了。原因是没想清楚数据往哪边流。 SSH 转发的本质是:在一台机器上开个监听端口,谁连上来,就把这条连接通过已建立的 SSH 加密通道,转到另一端去替他连目标地址。 所以每次写命令,只需要回答三个问题: 在哪台机器上监听?(决定用 -L 还是 -R) 监听哪个端口? 连接最终要送到哪个地址、哪个端口?——从哪一端的视角看? 第三个问题是所有困惑的来源,后面会反复强调。 二、本地转发 -L:把远端的服务搬到本地 这是最常用的一种。典型场景:数据库只监听 127.0.0.1,不对公网开放,但你要用本地的图形工具连它。 ssh -L 13306:127.0.0.1:3306 root@db-server 参数怎么读 -L 13306:127.0.0.1:3306 └─┬─┘ └────┬────┘ └┬─┘ │ │ └─ 目标端口 │ └─ 目标地址(★ 从 db-server 的视角看 ★) └─ 在你本机监听的端口 中间那个地址是站在服务器上看的,这是最容易搞错的地方。127.0.0.1 在这里指的不是你的电脑,而是 db-server 自己。 数据怎么走 你的电脑 db-server mysql -h 127.0.0.1 -P 13306 │ └─→ 本机 13306(ssh 在监听) │ │ ═══ SSH 加密隧道(走 22 端口)═══ │ └─→ 127.0.0.1:3306(MySQL) 关键在于:MySQL 看到的连接来自它自己的 127.0.0.1,因为最后一跳是 db-server 内部发起的。所以数据库完全不用对外开放端口,防火墙只需要放行 22。 ...

September 2, 2026 · 3 min · 翼橙

update-alternatives 使用笔记:多版本共存的软链接管理器

在 Linux 系统中,update-alternatives 是一种用于管理命令软链接的工具,适合管理多个版本共存的程序,例如不同版本的 PHP、Java、GCC、Python 等。通过它可以灵活控制哪个版本被调用、切换默认版本、统一管理系统路径下的可执行程序。 一、基本原理 Linux 中大多数命令其实都是 /usr/bin/xxx 的可执行文件,这些文件很多是软链接: ls -l /usr/bin/php # 可能指向 -> /etc/alternatives/php # 再指向 -> /usr/bin/php8.2 update-alternatives 就是负责管理 /etc/alternatives/ 中的这些链接,并允许你注册多个候选路径、设置优先级、手动切换或自动切换。 二、常用参数 参数 说明 --install 添加一个新候选版本 --remove 移除某个候选路径 --config 手动选择当前使用哪个版本 --set 直接设置当前使用路径 --display / --query 查看当前配置状态 --auto 恢复为优先级自动选择模式 –install 的四个位置参数 update-alternatives --install 是添加“候选版本”的关键命令,它的完整语法格式如下: sudo update-alternatives --install <链接路径> <名字> <实际可执行路径> <优先级> 参数位置 含义 示例值 说明 链接路径 创建的统一入口点 /usr/bin/php 这是用户最终执行命令时调用的路径 名字 系统识别用的名称 php 是“组名”,管理同类版本的别名 实际路径 程序的真实可执行文件路径 /usr/bin/php7.4 要加入的某个版本路径 优先级 一个整数 74 数值越大,优先级越高,自动模式下会选择它 实例 你系统中已经安装了 PHP 7.4 和 PHP 8.2,可以这样添加: ...

July 23, 2025 · 2 min · 翼橙

从零搭建邮件服务器接收验证码

本文适用于:需要自建域名邮箱来注册平台账号、接收验证码的场景。全程命令行, 不用写 Python 脚本也能收码。 只讲收信。 对外发信要额外处理 rDNS、DKIM、DMARC 和 IP 信誉, 自建服务器发出去的信大概率进垃圾箱,那是另一件事。 一、背景说明 很多平台注册账号时会要求填写邮箱地址并接收验证码。为了批量注册或控制邮箱来源,一些用户希望自建域名邮箱系统,从而: 自己控制域名和邮箱地址 本地接收邮件,免费无限用 配合脚本自动抽取验证码 二、工作环境准备 1. 需要的条件 项目 说明 一台 VPS Ubuntu 20.04+,25 端口必须能入站。多数云厂商默认封 25,要向主机商申请解封 一个可配置 DNS 的域名 如 mail.example.com 2. 安装必要软件 apt update apt install postfix dovecot-core dovecot-imapd -y postfix = SMTP 邮件服务器,用于接收邮件 dovecot = IMAP 邮箱读取服务器,允许脚本/网页读邮件 三、配置 DNS 记录 到域名控制面板(如 Cloudflare、阿里云、Namecheap)添加以下 DNS 记录: 类型 主机记录 值 A mail VPS IP MX @ mail.example.com (10) TXT @ v=spf1 mx ~all 说明:MX 是接收邮件的域名服务器,SPF 是为了防止邮件被伪造,非必但建议配置 ...

May 27, 2025 · 2 min · 翼橙