Creating ageless Windows CLIs with Docker and Wine

A while ago I spent some hours writing a mockup for a legacy Windows CLI. This CLI was part of the overall system to be overhauled and we wanted a dead simple Docker-based test setup. On the other hand, we wanted a test setup as close to the production system as possible. The other day a friend of mine asked: Shouldn’t it be possible to run the CLI inside a Docker container with Wine?

Wine (originally an acronym for "Wine Is Not an Emulator") is a compatibility layer capable of running Windows applications on several POSIX-compliant operating systems, such as Linux, macOS, & BSD.

Apparently, we were not the first to try this approach:

We ran a few promising experiments with several ready-made Dockerfiles available on the web.

The Dockerfile

Back at the drawing table we more or less followed How to Install Wine on Ubuntu 18.04 LTS and came up with a rather simple Dockerfile one-liner of our own:

FROM ubuntu:18.10

ENV WINEDEBUG -all

RUN apt-get update && apt-get install -y --no-install-recommends wine wine64

Tip: To suppress the Wine debug messages consider setting the environment variable WINEDEBUG=-all

This valuable flag is discussed in Cannot disable fixme message or How to permanently disable WINE debugger

A first Wine Experiment

With the Dockerfile prepared let’s build the wine-experiment image…

$ docker build --rm -t wine-experiment .
…
Processing triggers for wine (3.0.3-2) ...
Removing intermediate container d808ffb68959
 ---> 76343a265984
Successfully built 76343a265984
Successfully tagged wine-experiment:latest

and do a test-run:

$ docker run --rm -it  wine-experiment wine64-stable ipconfig                                                                                                   
wine: created the configuration directory '/root/.wine'
Could not load wine-gecko. HTML rendering will be disabled.
Could not load wine-gecko. HTML rendering will be disabled.
wine: configuration in '/root/.wine' has been updated.
Ethernet adapter lo

    Connection-specific DNS suffix. . :
    IPv4 address. . . . . . . . . . . : 127.0.0.1
    Default gateway . . . . . . . . . :
…

Ethernet adapter eth0

    Connection-specific DNS suffix. . : home
    IPv4 address. . . . . . . . . . . : 172.17.0.3
    Default gateway . . . . . . . . . : 172.17.0.1    

Nice.

Running the Windows CLI inside Docker

We mount our Windows tool demo-app.exe and all its dependencies into the container with -v $PWD:/demo. Since the executable isn’t on the path we also change the working directory via the option -w /demo/bin.

$ docker run -v $PWD/wine:/root/.wine -v $PWD:/demo -w /demo/bin wine-experiment demo-app
      /`·.¸
     /¸...¸`:·
 ¸.·´  ¸   `·.¸.·´)
: © );      ¸  {
 `·.¸ `·  ¸.·´\`·¸)
     `\\´´.·´

Tip: To avoid the generation of the wine metadata in .wine we additionally mount the configuration directory via -v $PWD/wine:/root/.wine into the container.

Seems Wine can extend the life of Windows CLIs…


Thanks for the Fish goes to ASCII Art Archive


Photo by Nicole De Khors from Burst

Show Comments