"sudo systemctl enable docker" not available: Automatically run Docker at boot on WSL2 (using a "sysvinit" / "init" command or a workaround)
Asked Answered
P

4

30

I am using Ubuntu on WSL2 (not on Docker Desktop).

According to How to fix docker ‘Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?’ on Ubuntu, I can automatically start the docker daemon at boot using

sudo systemctl enable docker

instead of just starting it again at every boot with

sudo systemctl start docker

with both commands avoiding "Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?".

When using any of the two, I get

Synchronizing state of docker.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable docker

and a test run shows, that docker is not yet running:

docker run hello-world 

docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?. See 'docker run --help'.

Some steps before, I also got a different message at this point:

System has not been booted with systemd as init system (PID 1). Can't operate.Failed to connect to bus: Host is down"

which brought me to Fixing "System has not been booted with systemd as init system" Error:

Reason: Your Linux system is not using systemd How to know which init system you are using? You may use this command to know the process name associated with PID 1 (the first process that runs on your system):

ps -p 1 -o comm=

It should show systemd or sysv (or something like that) in the output.

ps -p 1 -o comm= gave me init.

According to this and this table

enter image description here

Systemd command
    Sysvinit command

systemctl start service_name
    service service_name start

systemctl stop service_name
    service service_name stop

systemctl restart service_name
    service service_name restart

systemctl status service_name
    service service_name status

systemctl enable service_name
    chkconfig service_name on

systemctl disable service_name
    chkconfig service_name off

I can choose service docker start to run docker, which works. But I cannot find something like "systemd"'s sudo systemctl enable docker for "sysvinit". I would expect it to be like:

sudo service docker enable

But that "enable" is not available for "sysvinit" / "init".

While sudo service docker start works like sudo systemctl start docker, there is no such command that uses "enable". At the moment, I need to run sudo service docker start whenever I start WSL2.

The question:

What is the command that reaches sudo systemctl enable docker using sudo service docker ..., or if that does not exist, what is a workaround here to automatically start docker when opening Ubuntu on WSL2?

Persaud answered 20/1, 2021 at 16:54 Comment(0)
L
6

This answer requires the latest version of Windows and WSL at the time of this posting, and it now works under both Windows 10 and 11. Run wsl --version and confirm that you are on WSL 1.0.0 (not to be confused with WSL1) or later.

If you are on an older release of Windows or WSL, then wsl --version will likely just show the Help text. See this answer for information on how to upgrade.

If you cannot upgrade at this time, then please see my original answer for a workaround for Windows 10.


what is a workaround here to automatically start docker when opening Ubuntu on WSL2?

  • Option 1: Enable Systemd support in WSL2

    The latest release of WSL2 includes support for Systemd. You can read how to enable it in this Community Wiki answer or my original Ask Ubuntu answer.

    However, my personal recommendation is to consider whether you really need Systemd. It will add additional overhead and potentially other complications, and it isn't strictly necessary for Ubuntu to run (well) on WSL, as we've been doing for quite a few years without it. Option 2 may be a better (and faster) option for many services.

    If you do have Systemd enabled, then the commands in the original question should work for you:

    sudo systemctl enable docker
    sudo systemctl start docker
    

    Docker Engine should automatically start for you the next time you restart your WSL2 distribution. However, please see the bottom of this answer for an important note on keeping the services running.


  • Option 2: Add the necessary commands to the [boot] section in /etc/wsl.conf:

    [boot]
    command= service docker start
    

    To run multiple commands, separate them with a semicolon as in:

    [boot]
    command= service docker start; service cron start
    

Important Note: If you run a service (e.g. cron or docker) using either of these methods, please note that the WSL distribution will still auto-terminate when the last process that was started interactively completes. You can see more discussion (and a workaround using keychain) for this in my answer to the Ask Ubuntu question Is it possible to run a WSL app in the background?.

Lucifer answered 3/12, 2022 at 0:5 Comment(3)
"It will add additional overhead and potentially other complications" - I'm roughly intermediate level at Linux, and was curious what overhead it adds?Lovering
@J.ScottElblein Re:overhead -- Systemd automatically starts many services that you may not need. Before enabling Systemd on WSL2, I count 5 services running by default at startup. After enabling Systemd, that number goes up to 34. Some of these can be disabled, as they simply aren't needed (e.g. wpa-supplicant, which is used to configure wireless networks in Ubuntu), but that does require some additional effort. Also, while the Systemd support is getting better, it still continues to be a source of many issues (and fixes) in recent WSL2 releases.Lucifer
@J.ScottElblein Honestly, that's probably worth a question all-by-itself, but it might be tough to word it just the right way to avoid "opinion". Also, if you do, I'd recommend asking on [Ask Ubuntu](askubuntu.com) (assuming you are running Ubuntu) since the Mods there draw the "subjective" line a bit further than here ;-).Lucifer
L
59

Important note: Most users should read my updated answer first. This answer is a bit outdated, but I'm leaving it here in case it's beneficial to anyone running on an older WSL release.


Short answer to "what is a workaround here to automatically start docker when opening Ubuntu on WSL2?

  • Option 1: On Windows 11, add the necessary commands to the [boot] section in /etc/wsl.conf:

    [boot]
    command="service docker start"
    

    Note that under the latest Preview releases, there appears to be an issue that causes anything started via this boot.command to terminate when no services that were started via an actual command-line are still running. In other words, if you need Docker (or any other service) to continue to run after you exit your WSL2 session, you'll probably need to use Option 2 (or uninstall the Preview).

  • Option 2: On Windows 10, run the necessary commands in your user startup scripts (e.g. .profile). Do it with a check to see if the service is running first, like:

    wsl.exe -u root -e sh -c "service docker status || service docker start"
    

    This is a better alternative than my previous answer (option 3, below) since it doesn't require modification to sudoers. This takes advantage of the fact that the wsl.exe command can be run from inside WSL, using the -u root option to run the commands as root without a password.

    Note: If for some reason this command fails, your default WSL distribution may be different than you expect. Check the output of wsl.exe -l -v. You can change the default distro using wsl.exe --setdefault <distro_name> or adjust the commandline above to specify the distro with -d <distro_name>.

  • Option 3: (old answer, here for posterity): visudo or add rules to /etc/sudoers.d to allow your user to run the commands without a password:

    username ALL = (root) NOPASSWD: /usr/sbin/service docker *
    

    Then edit your .profile to add:

    sudo service docker status || sudo service docker start
    

More Details:

As you've discovered, WSL does not include any systemd support, nor really any direct support for starting a service on boot.

For starters, the WSL subsystem doesn't launch at Windows boot, but only when the user launches a login session anyway. So without any real "system start", the init.d or systemd startup doesn't make as much sense.

Further, users may have multiple WSL instances/distributions running, and if you are doing that (as I am), then you really don't want all services from all instances running on every boot (although, updated answer, Windows 11 does now give us this option).

For Docker, though, are you running Docker Desktop with WSL2 integration, or just installed directly into a WSL2 instance? For Docker Desktop, I ran across this in another question yesterday on how to start Docker Desktop daemon at Windows boot.

You can also have the WSL2 instance start via Windows Task Manager when the user logs in, and run the script via something like wsl -u root service docker start in the Task Manager.

Note that the same doesn't seem to work at Windows boot, however, (only login) because Windows seems to terminate any WSL instance that isn't tied to an active user after a few seconds (even if a service is running in the background). You can work around this with the PowerShell Invoke-WmiMethod, something like ...

powershell.exe Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList 'wsl', although I haven't tested this all that thoroughly.

Lucifer answered 20/1, 2021 at 17:26 Comment(9)
Worked for me adding sudo service docker status || sudo service docker start to my ~/.profile on my WSL2 Linux drive. Afterwards, sudo docker run hello-world runs. You are right, it seems logical that docker is not started automtically since you do not always need it ;). And as to your question, I run Docker installed directly into a WSL2 instance.Persaud
Option 1 worked perfectly. I'm on Windows 11 and have Docker installed directly onto my WSL2 Ubuntu instance. thanks @NotTheDro1dsMonopetalous
For some reason option 2 works intermittently for me. wsl.exe -u root -e sh -c "service docker status || service docker start" sometimes is working fine. Then I backup and restore wsl and everything is okay, except that line then gives sh: service: not found (x2). Oddly enough, after a ~week usage it started working again, idk why. Then I needed to transfer WSL (bkp/restore) again and it stopped working again. Win 10, WSL2. Tried troubleshooting but no luck.Esplanade
@ViníciusM If the service command isn't being found, then my first guess would be that the PATH isn't set correctly, of course. You can check (using the same process) with wsl.exe -u root -e sh -c 'echo $PATH'. Second guess - Have you at any point installed a Systemd script (Genie? Distrod? Etc.)? I'm wondering if it is getting activated sometimes. When Systemd is active, the service command uses systemctl internally. Note that once Systemd is activated, some parts of it change all instances -- So even if you run it in another WSL distribution, it could impact this one.Lucifer
@Lucifer PATH check outputs /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib: plus some windows folders; I can correctly call service in terminal on both my user and as root (after sudo su -). It's just from the wsl.exe call that it fails. And about the Systemd script: nope. Never installed anything. I run away scared from stuff that could cause "more unpredictable behaviour" and "troubleshooting" heheEsplanade
@ViníciusM Ah, sorry. I think I know what's going on here. When you "backup and restore", I assume you are doing this through --export/--import? And perhaps --unregister between? In that case, I think another distribution gets set as default (perhaps Docker?). If the problem that you mentioned is currently happening, check wsl -l -v to confirm the default distro.Lucifer
@Lucifer That was precisely it! wsl --setdefault Ubuntu fixed it! Maybe worth making a small footnote somewhere? I've made a quick edit suggest. =)Esplanade
For the Windows 10 solution, I redirected output to dev/null wsl.exe -u root -e sh -c "service docker status || service docker start" >/dev/null 2>&1. Another small note, the .profile file is opened from within a WSL terminal (not PowerShell, CMD, etc). For example, using nano ~/.profile.Moss
@Moss Just a heads-up, since your comment here pulled me to this answer -- My answer is a bit outdated, and I'll try to update it soon. On Windows 10, you can now use the same solution as on Windows 11. See this answer for how to upgrade to the latest WSL release that can do this on Windows 10.Lucifer
L
6

This answer requires the latest version of Windows and WSL at the time of this posting, and it now works under both Windows 10 and 11. Run wsl --version and confirm that you are on WSL 1.0.0 (not to be confused with WSL1) or later.

If you are on an older release of Windows or WSL, then wsl --version will likely just show the Help text. See this answer for information on how to upgrade.

If you cannot upgrade at this time, then please see my original answer for a workaround for Windows 10.


what is a workaround here to automatically start docker when opening Ubuntu on WSL2?

  • Option 1: Enable Systemd support in WSL2

    The latest release of WSL2 includes support for Systemd. You can read how to enable it in this Community Wiki answer or my original Ask Ubuntu answer.

    However, my personal recommendation is to consider whether you really need Systemd. It will add additional overhead and potentially other complications, and it isn't strictly necessary for Ubuntu to run (well) on WSL, as we've been doing for quite a few years without it. Option 2 may be a better (and faster) option for many services.

    If you do have Systemd enabled, then the commands in the original question should work for you:

    sudo systemctl enable docker
    sudo systemctl start docker
    

    Docker Engine should automatically start for you the next time you restart your WSL2 distribution. However, please see the bottom of this answer for an important note on keeping the services running.


  • Option 2: Add the necessary commands to the [boot] section in /etc/wsl.conf:

    [boot]
    command= service docker start
    

    To run multiple commands, separate them with a semicolon as in:

    [boot]
    command= service docker start; service cron start
    

Important Note: If you run a service (e.g. cron or docker) using either of these methods, please note that the WSL distribution will still auto-terminate when the last process that was started interactively completes. You can see more discussion (and a workaround using keychain) for this in my answer to the Ask Ubuntu question Is it possible to run a WSL app in the background?.

Lucifer answered 3/12, 2022 at 0:5 Comment(3)
"It will add additional overhead and potentially other complications" - I'm roughly intermediate level at Linux, and was curious what overhead it adds?Lovering
@J.ScottElblein Re:overhead -- Systemd automatically starts many services that you may not need. Before enabling Systemd on WSL2, I count 5 services running by default at startup. After enabling Systemd, that number goes up to 34. Some of these can be disabled, as they simply aren't needed (e.g. wpa-supplicant, which is used to configure wireless networks in Ubuntu), but that does require some additional effort. Also, while the Systemd support is getting better, it still continues to be a source of many issues (and fixes) in recent WSL2 releases.Lucifer
@J.ScottElblein Honestly, that's probably worth a question all-by-itself, but it might be tough to word it just the right way to avoid "opinion". Also, if you do, I'd recommend asking on [Ask Ubuntu](askubuntu.com) (assuming you are running Ubuntu) since the Mods there draw the "subjective" line a bit further than here ;-).Lucifer
G
4

In WSL2 Ubuntu

  1. Create or modify the /etc/wsl.conf file with sudo and add:
[boot]
systemd=true
  1. Enable the Docker daemon on boot:
systemctl enable docker
  1. Create a Docker group and add your user so it can run without sudo
sudo groupadd docker
sudo usermod -aG docker $USER
  1. Restart your WSL environment :
wsl --shutdown
Gabrielagabriele answered 2/11, 2023 at 21:13 Comment(1)
Great, we can use systemd now. Additional info in "Advanced settings configuration in WSL" learn.microsoft.com/en-us/windows/wsl/…Hinkley
T
0

This worked for WSL ubuntu:

Before:

service --status-all

[ - ] ssh

service ssh start

After:

service --status-all

[ + ] ssh

Tetrastichous answered 30/11, 2021 at 23:31 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Granulate

© 2022 - 2024 — McMap. All rights reserved.