用 systemd 托管 ASP.NET Core:开机自启与日志

Words: 949Read Time: 3 minLast edited: 2026-8-4
服务器因为机房维护重启过一次,我的博客就这么挂了整整一天,还是朋友提醒我才发现。原因很丢人:ASP.NET Core 应用是用 nohup dotnet MyBlog.dll & 这种土办法挂在后台的,机器一重启进程就没了。痛定思痛,我把应用交给 systemd 托管,顺手把日志问题也解决了。这篇记录配置过程和踩过的坑。

土办法的三大痛点

刚买服务器那会儿图省事,启动命令是 nohup dotnet MyBlog.dll > app.log 2>&1 &,敲完回车就不管了。用了几个月,问题陆续暴露:
  • 机器重启后进程不会自己起来,得靠人肉记住,而我显然记不住
  • 程序异常退出就是真死了,没有任何自动拉起机制
  • 日志全堆在一个文件里,越滚越大,既不好按时间过滤也不好按级别过滤
systemd 是现在主流发行版的标配(Ubuntu 16.04 之后、CentOS 7 之后都是),把 .NET 进程交给它管,开机自启、崩溃重启、日志收集全部自带,还不用装任何额外软件。

编写 service 单元文件

/etc/systemd/system/ 目录下新建 myblog.service,内容如下:
几个关键点:
  • WorkingDirectory:工作目录,这是最容易漏也最容易出事的一项,下文细说
  • ExecStart:启动命令,dotnet 建议写绝对路径,可以用 which dotnet
  • Restart=always 配合 RestartSec=5:进程不管怎么退出,5 秒后自动拉起
  • Environment:环境变量写在这里,比改 .bashrc 干净,也不会污染登录 shell
  • User:不要用 root 跑,给个低权限用户,出事时损失可控

常用管理命令

文件写好后,一套组合拳:
查日志用 journalctl,所有打到标准输出的内容(Console 输出、默认的 ILogger)都会收进去:
journalctl -u myblog -f 是我现在用得最多的命令:出问题时开一个窗口挂着,请求一来日志实时滚动,比以前翻 nohup 的大文件舒服太多。

踩过的坑

第一个坑:漏了 WorkingDirectory。 第一次写 unit 文件时我没写这一行,启动直接报找不到 appsettings.json。原因:.NET 读相对路径的配置文件是相对"当前工作目录",而不是 dll 所在目录。systemd 默认工作目录是根目录 /,配置文件当然找不到。静态文件、上传目录同理,只要代码里用了相对路径,这一项就必须写对。
第二个坑:环境变量没设 Production。 默认环境是 Development,异常页面会带出详细堆栈甚至敏感信息,日志也啰嗦。ASPNETCORE_ENVIRONMENT=Production 一定别漏。
第三个坑:权限。 我一开始用 root 跑,后来改成 www-data 时忘了给目录授权,启动报权限错误。chown -R www-data:www-data /var/www/myblog 一把解决。
折腾完回头看,systemd 那点配置成本根本不算啥:现在服务器随便重启,博客几十秒内自己爬起来,日志也有了正经去处。早就该这么干了。
Loading...
© 2024 - 2026 ihuadz
中文