A few months ago I worked on a Golang project, which was developed and built on a Linux environment only. Fortunately, it could be compiled on a Windows machine and just lacked some of the standard Linux build tools not given by a regular Git installation. However, it could be solved with a full Git SDK installation and with the help of pacman. I wasn't familiar with the SDK before and was curious if I could get some other tools running, which I use on Linux servers like tmux as a terminal multiplexer.
It turned out that tmux was installable, but didn't feel very comfortable, so I gave Windows Subsystem for Linux a try and started with a simple bat file like this to determine if a command like git is even executable.
@echo off
bash.exe -c "git %*"
In short: yes, it is.
A quick research revealed that this approach had been used quite a long time ago, so nothing new here. A bat file might either be sufficient or not at all and my knowledge of writing complex bat files is a bit limited. Besides that, I wasn't sure, how easy it will be to change environmental settings or to use configurational aspects.
Golang seems to be one of today's candidates for system programming and had been chosen for this project because of the mentioned points besides an access to low level API's and the native compilation -- well, I could improve my Go writing at the same time. The compilation part is certainly also a downside of using Golang for this kind of proxy generation, as a properly configured toolchain with C/C++ compilers next to Go's toolchain is required. We can make a trade in the times of containerization and choose docker as a requirement instead, but it should only be required during for the building process.
Okay, let me introduce the project codesk to you and what it can be used for:
- Common Linux packages can be preferred over pre-compiled Windows binaries.
Tools like curl, wget, ffmpeg can be directly used from Windows - Development software like git can be maintained on one system only, but used on both.
How is it done?
codesk.exe is a binary, that hosts a tarball containing some proxy Go code and a Dockerfile that creates a binary to communicate with the addressed target over WSL in a way that is described in the bat file from above. A tarball had been chosen to simplify the build process using docker's stdin build context feature, but this is more a detail. Please refer to the documentation on Github to see additional aspects, like configuration of environmental settings.
You might have to setup an X11 server if your workflow also includes binaries with UI, as unfortunately, there is none provided by default. At the time of writing, there are VcXsrv, X410, XMing and others available. Last, linking your $HOME directory makes things even more convenient
For example, use this command to create a proxy for git with codesk:
codesk.exe stick --target git # target can either be a fully qualified path to the executable or a name only, it just has to exist and must be locatable
What about Docker?
Docker is required only during the compilation process, so a binary can be created on any arbitrary host. It may still be valuable to think about a proper Docker setup on your host if you plan to move to WSL entirely:
- The docker desktop setup with Hyper-V offers a better overall experience compared to the one with virtualbox. For example, localhost network addressing becomes possible and it's always good when few things are different in a cross environment or in cooperation with different OS users. You may want to read how to preserve virtualbox if it can't be completely omitted.
In either case, volume mounting is supported, but WSL uses sub directories below /mnt by default. So it's recommended to harmonize this by changing the root property in /etc/wsl.conf to /, which eliminates any additional path translations. You can find details in this blog post. - Any Windows executable can be directly used inside of WSL and thus docker.exe, albeit restricted to the technical possibilities given by a regular command prompt or powershell execution, because it's unaware of the Subsystem. As long as TLS is not supported for localhost connections or Microsoft hasn't released a seamless docker client integration yet, it's best to stick with npiperelay.
It's one step closer to a unified environment and allows mounting /var/run/docker.sock into the container, which leads us to Dind on Windows with less security concerns.
The photograph for this article was taken by Rawpixel.
Become a backer or share this article with your colleagues and friends. Any kind of interaction is appreciated.