我的日常工作都离不开 Ruby on Rails,并用 PostgreSQL 作为关系型数据库服务。所以,我接下来要谈的是如何在 Windows Subsystem Linux(WSL)2 上自动启动 PostgreSQL 服务。
事情的由来
当初 Windows 11 在 Insider Preview 渠道发布时,我可是相当兴奋。我在自己的 Dell XPS 笔电上加入了该计划,并跑了一个星期。使用体验很不错,完全没有遇到那些通常跟着 Windows 不稳定版本一起打包送来的问题或低级 bug。因此,这篇文章是根据我在最新 Windows Preview build 22000.5 上设置的经验写成的。
背景
我参考了 GoRails 的教程,学习如何在 Windows 10 上安装 Ruby On Rails。该教程建议我们在 Windows 上安装 PostgreSQL,然后在 WSL 里使用它。我试过这个方法,但它无法开箱即用,我相信还需要进一步调整,而我至今还没搞清楚该怎么做。正因如此,我改为在 WSL 上安装 PostgreSQL,代价就是每次第一次启动 WSL 时,都得手动启动 Postgres 服务。
如何启动 Postgres 服务?
以下两种方法在我的 WSL 上都能成功启动 postgres 服务:
- sudo pg_ctlcluster 12 main start 或;
- sudo service postgresql start

问题所在
我以前用 Ubuntu 时,postgres 服务会在操作系统启动时自动启动。这大概要归功于 systemd 吧?
每次我忘了启动 postgres 服务,然后执行 Active Record 命令却返回错误时,我都被吓一跳:
PG::ConnectionBad: could not connect to server: No such file or directory
既然每次启动 WSL 终端时 postgres 服务对我来说都是必需的,我就在想怎样才能做到每次第一次打开终端时,服务都能自动启动。p/s:postgres 服务在 WSL 上并不会自动启动。
写一个简单的 Shell Script
每次我们启动终端时,操作系统都会执行 .bashrc* 文件,所以我们要修改这个文件,检查 postgres 服务是否正在运行。为什么要检查?因为终端可以被打开很多次,服务没必要重复启动多次,只需启动一次就好。所以,我们需要有某种机制来检查服务的状态。
*注:.bashrc 位于你的主目录,通常是在 /home/<username>/.bashrc
if ! pgrep -x "postgres" >/dev/null; then
sudo pg_ctlcluster 12 main start
echo "postgres service started using: sudo pg_ctlcluster 12 main start"
fi
这就是我完整的 .bashrc 文件的样子。
另一个问题
如果你在设置好 .bashrc 文件后马上启动终端,你会注意到系统会向你索取密码,因为启动服务需要你拥有超级用户权限。因此,我们接下来要把该命令列入白名单,让它不必输入密码。
我们会在 sudoers.d 中创建一个文件,因为不想直接去改动操作系统的文件。这样即使将来操作系统在升级时需要更新真正的 sudoers 文件,也不会引发任何问题。首先,我们需要创建一个文件,把文件名取为 skip_sudo_pg。
$ sudo visudo -f /etc/sudoers.d/skip_sudo_pg
然后,文件的内容如下:
%sudo ALL=(ALL) NOPASSWD:/usr/bin/pg_ctlcluster
搞定!现在你已经把 postgres 服务设置为在第一次运行终端时自动启动。这对我来说非常合理,因为我每次打开 WSL 终端时,都会用 Rails console 跑 Active Record 查询。

如果你是我,除了这个方法以外,你会怎样设置你的环境?跟我分享一下吧 ?。
参考资料
https://www.cyberciti.biz/faq/bash-check-if-process-is-running-or-notonlinuxunix/
https://superuser.com/questions/1343558/how-to-make-wsl-run-services-at-startup
https://www.digitalocean.com/community/tutorials/how-to-edit-the-sudoers-file

发表回复
要发表评论,您必须先登录。