Note: I'm cross posting this from my blog to dip my toe into dev.to
More and more developers are finding out that the Windows Subsystem for Linux (WSL) is pretty great. Being able to transparently use a ton of established *nix tooling on Windows can make your machine a kind of best-of-both hybrid as both a user and a developer.
Updates to WSL have included adding support for background tasks when all your Linux console windows are closed, where previously the WSL processes had to be running under a live shell. However, you still needed to start those services yourself because Linux sessions could only be initiated explicitly. There was no start-up config to launch services like Postgresql or RabbitMQ and the like.
After several restarts after which I neglected to start up these services manually, I wanted a solution that would get Postgres running in the background in the WSL layer automatically when I started up my machine.
Here’s how you can start WSL background services on Windows login:
First you’ll need a startup script. I called mine start_postgresql.sh
and put it in ~/.local/bin/
. All mine does is start the Postgres service, but you can start as many other services or do as many other start-up time actions as you want.
mkdir -p ~/.local/bin/
echo "service postgresql start" >> ~/.local/bin/start_postgresql.sh
chmod +x ~/.local/bin/start_postgresql.sh
Of course, running service requires sudo
privledges. But, since we need to run this at start-up without interaction and I don’t want to enable password-less sudo
what do we do?
It turns out you can enable password-less sudo
for specific commands without enabling the security faults of allowing your user to sudo
just anything without any safety check. Open visudo to edit your sudo
config:
sudo visudo
And then add this line to enable sudo
run only this script.
calvin ALL=(root) NOPASSWD: /home/calvin/.local/bin/start_postgresql.sh
Great! Of course, your name probably isn’t “calvin” like mine. Change that to your own username.
All that’s left to do is get Windows to run this script in the WSL layer when you login. We can use the Task Scheduler to do this, so open the start menu and type “Task Scheduler” to find the application and run it.
Now, click “Task Scheduler Library” on the left and then “Create Task…” on the right to create a new task you can configure to run your script with these steps:
- Name the task anything you want, like “Start Postgres”
- Under the “Triggers” tab, click “New…” to add a new trigger for this task
- In the “Begin the task” dropdown select “At log on”
- Select “Any user”
- Under the “Actions” tab, click “New…” to add a new action for this task
- Pick “Start a program” for the action type and then enter
C:\Windows\System32\bash.exe
as the program to run - Finally, as the last and most important step, at “Add arguments (optional)” set this argument string to run the command with:
-c "sudo ~/.local/bin/start_postgresql.sh"
That’s all you need. When you log into Windows next this task will be triggered and run your custom script as root and start Postgres and any other services you decide to spin up.
Hopefully this will make developing on Windows with Linux tooling even easier than WSL already does!
Top comments (20)
This will not necessarily work when you are runnning multiple WSL distros in parallel. You can resolve this by changing the command line in the task schedulder. In the following example I assume you want to run postgresql in Debian, which is not your primary/default WSL distro:
Instead of 'C:\Windows\System32\bash.exe' write 'wsl'
Instead of '-c "sudo ~./local/bin/start_postgresql.sh"' write '-d debian -e sudo /home/calvin/.local/bin/start_postgresql.sh".
(Yes, I had trouble with the ~ shortcut for the home directory, no idea why.)
if the command is sudo, anything after that is already run as root, so the ~ would mean /root and not /home/calvin
So, I started with your suggestion, but quickly realized most services are already scripts in /etc/init.d, and you usually manage these things with users. For example, for docker, I created a
/etc/sudoers.d/docker.sudoers
file, with the following:I think I'm also going to see if I can get a feature request endoresed for a
[autostart]
config section for the/etc/wsl.conf
file where you could just list services to autostart like so:It's nice to bring Unix tooling into Windows, but, as a Linux and Mac user, I'm curious as to what Windows brings to the table. My brief experiences with Windows post-XP were mostly frustrating. The UI for managing the machine is confusing and crude, downloading updates is slow and either slows down the machine or locks it down until finished.
I dunno, man. I'm not trying to sell you on Windows. I'm trying to help out people who already decided to use it. :-)
There are some of us that are forced to use Windows because of our employers, IT and the MS Apps that they require. This is easier than trying to get Linux working in a MS environment and using Open Source apps and WINE to satisfy the requirements.
if u are a full stack dev, or freelance solutions provider, its nice to have adobe products at your fingertips without rebooting while in programming mode
I would like to give my 20 cents and suggest to use just one single script (/home/youruser/autoexec.sh) to call ALL services wanted thru Task Scheduller.
And not just for postgres.
But man... you save the day!!
Thanks a lot!!!!!
I'm afraid it didn't work for me...
I need to run the same command:
service postgresql start
and it just isn't started (it runs fine as root/sudo). File permissions for the script are good wrxwrxwrx. I do believe shell starts and the script is being run.I have Windows build 17692. I must be missing something...
Great post, I appreciate it!
I'll keep trying. Cheers.
UPDATE: IT IS WORKING!!!!!!!!!!!
Yay!!!
I had been rebooting the windows machine by "restart"... This morning when I booted it from shutdown state, the Postgres server was running. And this is from the script and task scheduler you explained.
Thanks again.
it worked for me, thanks!
However, I am curious why not put 'sudo' in bash script, but put it in the task scheduler's command. If you put it in the bash script, you could avoid typing sudo when you used it from the console.
I would not do what is suggested here.
What you have done is allowed passwordless execution of a user-editable shell script haven't you?
If I wanted to execute arbitrary code under sudo I would simply edit that shell script and then use the permission to execute that shell script as a sudo user.
You need to make sure that whatever script you are allowing anyone to call without providing the SUDO password (as the sudo user) is uneditable.
Otherwise there is NO advantage to trying to avoid allowing passwordless SUDO.
I'm not a nix guru, so I don't have a working solution for others to read here, but the specific advice given here isn't great, I'd suggest looking for a different script that is owned by the sudoers that cannot be edited by a non-sudo'er to allow passwordless sudo'ers to execute to achieve the same functionality.
I was also late to realize that Apache and MySQL was not started automatically in WSL land.
Although this method shows an awkward flash of bash window during startup. But hey, at least it works. Thx for the tip!
I just start the postgresql server in the script and add that script to
~/.bashrc
I've tried very hard to make it work with Redis but it didn't work!
I used this official Redis article to install Redis redislabs.com/blog/redis-on-window...
Any help?