Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect behavior when running in a Docker container in WSL2 #157

Closed
AaronFriel opened this issue Dec 11, 2019 · 0 comments · Fixed by #164
Closed

Incorrect behavior when running in a Docker container in WSL2 #157

AaronFriel opened this issue Dec 11, 2019 · 0 comments · Fixed by #164

Comments

@AaronFriel
Copy link

AaronFriel commented Dec 11, 2019

Docker containers do not have access to the Windows environment, so the is-wsl check is not sufficient. The result is that a Docker container on WSL2 fails to run Create React App applications without additional configuration, see logs below.

I was unsure of whether I should make an issue here or in https://github.com/sindresorhus/is-wsl, here's the crux of it:

  • Is is-wsl supposed to detect if we're running a WSL1/2 kernel? If so, then it is behaving correctly and open should likely change.

  • Or, is is-wsl supposed to detect if we have access from a WSL1/WSL2 userland to Windows utilities, such as cmd.exe? If so, then is-wsl should likely change.

Either way, I have done a bit preliminary research and there are a few reliable ways of detecting if you're running in Docker and WSL2, although different container runtimes can do different things:

  1. cat /proc/1/cgroup | grep docker exits with status code 0 if running in Docker, because it runs the init process in various cgroups. (We could also check if it contains more than 1 cgroup, or if it contains cgroups that are not the root cgroup, but I'm less sure of the accuracy of those.)

  2. The file /.dockerenv is injected into Docker containers on WSL2 and absent otherwise, but a root user or a distro could theoretically create this file, so it's not reliable.

  3. WSL2 distributions do not set the HOSTNAME env var, but Docker on WSL2 does.

  4. Lastly, I think this may be the best way to detect if we can access Windows: cat /proc/mounts | awk '{print $3}' | grep drvfs detects whether or not we have a drvfs mount available to us. 🔔 🔔 🔔 this might be the winner.

In which case, I would be happy to make a PR with code like this:

const fs = require('fs');

const parseMountString = (mountString) => {
  const [device, mountPoint, fsType, flags, extra] = mountString.split(' ');

  return { device, mountPoint, fsType, flags, extra };
};

const canAccessWindows = fs
  .readFileSync('/proc/mounts')
  .toString()
  .split('\n')
  .map(parseMountString)
  .some(({ fsType }) => fsType === 'drvfs');

console.log(canAccessWindows);

See result of running this in a Docker container on WSL2 (left) and in a regular WSL2 distribution (right):

image

Logs showing the error on starting create-react-app application, and a potentially related issue:

> react-app-rewired start

ℹ 「wds」: Project is running at http://172.19.0.5/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /app/public
ℹ 「wds」: 404s will fallback to /index.html
Starting the development server...

events.js:174
      throw er; // Unhandled 'error' event
      ^

Error: spawn cmd.exe ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
    at onErrorNT (internal/child_process.js:415:16)
    at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
    at Process.ChildProcess._handle.onexit (internal/child_process.js:246:12)
    at onErrorNT (internal/child_process.js:415:16)
    at process._tickCallback (internal/process/next_tick.js:63:19)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant