Skip to content

Instantly share code, notes, and snippets.

@arpieb
Created February 16, 2023 20:42
Show Gist options
  • Save arpieb/edb6ea64611baaaaec0a26213e0f1e14 to your computer and use it in GitHub Desktop.
Save arpieb/edb6ea64611baaaaec0a26213e0f1e14 to your computer and use it in GitHub Desktop.
Set up a Wine environment in a Docker container with Python 3.8 installed
################
# Attempt to run Windows scripts in a Docker container (for K8s deployment)
# Inspiration/material from:
# https://betterprogramming.pub/how-to-run-any-windows-cli-app-in-a-linux-docker-container-318cd49bdd25
################
FROM ubuntu:22.04
# Core system packages
RUN apt -y update
RUN apt -y install wget
# Install Wine stack (https://wiki.winehq.org/Main_Page)
# NOTE these repos are platform-version specific
ENV WINEDEBUG=fixme-all
RUN dpkg --add-architecture i386 && \
mkdir -pm755 /etc/apt/keyrings && \
wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key && \
wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources && \
apt update && \
apt -y install --install-recommends winehq-stable winbind cabextract
# Install "dummy" X Server
RUN apt install -y xvfb
ENV DEBIAN_FRONTEND=noninteractive
ENV DISPLAY :1
# Install Mono framework
RUN wget -P /mono https://dl.winehq.org/wine/wine-mono/7.4.0/wine-mono-7.4.0-x86.msi && \
wineboot -u && msiexec /i /mono/wine-mono-7.4.0-x86.msi && \
rm -rf /mono/wine-mono-7.4.0-x86.msi
# Install Python
RUN wget https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe && \
xvfb-run wine64 python-3.8.10-amd64.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 SimpleInstall=1 /nogui && \
rm -f python-3.8.10-amd64.exe
@arpieb
Copy link
Author

arpieb commented Feb 16, 2023

I know you're asking - WTF and WHY???

There are sometimes use cases where a Python script needs to access Windows system components to analyze Windows-native files using Windows core DLLs, but you want to be able to containerize it.

Here's yer card...

@richardnm-2
Copy link

richardnm-2 commented Feb 5, 2024

Glad to know that I`m not the only one trying something like this... :D

I just came across your script after a few days fiddling around, with no success.

Yours seems very promising, but I still get an error after running it:

2024-02-05 23:46:41 (6.91 MB/s) - 'python-3.8.10-amd64.exe' saved [28296784/28296784]

004c:err:ole:StdMarshalImpl_MarshalInterface Failed to create ifstub, hr 0x80004002
004c:err:ole:CoMarshalInterface Failed to marshal the interface {6d5140c1-7436-11ce-8034-00aa006009fa}, hr 0x80004002
004c:err:ole:apartment_get_local_server_stream Failed: 0x80004002
The command '/bin/sh -c wget https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe &&      xvfb-run wine64 python-3.8.10-amd64.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 SimpleInstall=1 /nogui &&      rm -f python-3.8.10-amd64.exe' returned a non-zero code: 243

I separated the running commands, to try to pinpoint the exact point of failure, an seems to be at the installation of python

# Install Python
RUN  wget https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe
RUN xvfb-run wine64 python-3.8.10-amd64.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 SimpleInstall=1 /nogui
RUN rm -f python-3.8.10-amd64.exe

004c:err:ole:StdMarshalImpl_MarshalInterface Failed to create ifstub, hr 0x80004002
004c:err:ole:CoMarshalInterface Failed to marshal the interface {6d5140c1-7436-11ce-8034-00aa006009fa}, hr 0x80004002
004c:err:ole:apartment_get_local_server_stream Failed: 0x80004002
The command '/bin/sh -c xvfb-run wine64 python-3.8.10-amd64.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 SimpleInstall=1 /nogui' returned a non-zero code: 243

I was wondering if you ran into similar issues and could help me to try to make this work.

Appreciate your time and effort already!

Running on W10 22H2 (OS Build 22621.3007), WSL 2, Ubuntu 22.04.3 LTS, Docker version 24.0.5, build 24.0.5-0ubuntu1~22.04.1

@arpieb
Copy link
Author

arpieb commented Feb 6, 2024

You are truly a masochist - Wine in Ubuntu container under WSL on Win10! And here I thought I was nuts trying to get this to run on macOS (and tested under K8s on RHEL). ;)

I don't have a Win10 box at my disposal, but will take a run at this on Win11 and see where that gets me.

In the meantime, have you tried any different versions of the Python installer? I was using the 3.8 tree as my requirement wouldn't run on anything newer at the time, maybe a different version would play nicely on Win10 WSL?

@arpieb
Copy link
Author

arpieb commented Feb 6, 2024

Yeah, was getting the same errors on Win11 + WSL2. Did some digging, and it appears that pyinstaller sussed this out prior to my attempts, unsure why their solution never came up in search results:

https://github.com/cdrx/docker-pyinstaller

I just picked the Dockerfile for the env I wanted to build for, commented out the pyinstaller-specific commands after the wine, python, and MSVC redist installs, and ran it. For Dockerfile-py3-win64:

rbates@lusca:~/tmp$ docker run -it --rm 2293bd09d1ecf899a4eb2aa82fae44d11c35b05c563d2fcfad12187b4165bc99
root@fc1393e9ab15:/# python
python      python2     python2.7   python3     python3.5   python3.5m  python3m
root@fc1393e9ab15:/# python3 -m platform
Linux-5.15.133.1-microsoft-standard-WSL2-x86_64-with-Ubuntu-16.04-xenial
root@fc1393e9ab15:/# wine python -m platform
0048:err:explorer:initialize_display_settings Failed to query current display settings for L"\\\\.\\DISPLAY1".
0098:err:ntoskrnl:ZwLoadDriver failed to create driver L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\wineusb": c0000142
Windows-7-6.1.7601-SP1
root@fc1393e9ab15:/# wine python --version
0044:err:explorer:initialize_display_settings Failed to query current display settings for L"\\\\.\\DISPLAY1".
0098:err:ntoskrnl:ZwLoadDriver failed to create driver L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\wineusb": c0000142
Python 3.7.5
root@fc1393e9ab15:/# exit

If the display errors are irritating, could prob leverage the dummy display setup from my Dockerfile, but it didn't appear to affect Python execution.

@arpieb
Copy link
Author

arpieb commented Feb 6, 2024

Also ran across this interesting project leveraging embedded Python builds:

https://github.com/pleiszenburg/wenv

ymmv, but another option.

@richardnm-2
Copy link

Thank you so much, I really appreciate your time and effort on this. Without this guidance, I would still probably have nothing.

This wenv project I did not find during the search, but tried it today and works really well, probably the easiest and cleanest way to have a Windows python interpreter running in Linux.
Unfortunately, as you said, as I'm a masochist, the project I'm currently working on failed as the package requires a path to run the Windows python interpreter. Might get it working changing the config, but the documentation states that

*"wenv will create a special kind of environment __underneath__ the Unix Python virtual environment"*

Maybe tweaking the paths in config I can access the actual path for the interpreter an get it working. Homework, I guess.

The docker-pyinstaller repo I did find during my search, but then it kept hanging at one of the .msi downloads, and as it looked far more complicated and cumbersome than yours, I was really trying to make your script work. After not getting anywhere with the errors I was getting, I chose to confirm with you if this would work, especially as I had doubts on the setup I have as well.

After your example getting this docker-pyinstaller a spin, I gave it a go, changing the wget to retry a couple of times before failing and trying again, and it worked!!

I guess I'll finish setting my project on top of this python install in the container, and eventually get back to the wenv package, just because it looks very good for these use cases.

Again, at least a week of deep frustration avoided, thank you!

@arpieb
Copy link
Author

arpieb commented Feb 8, 2024

Glad you got some traction and I was able to help in some way! My use case was a Python-based script that used pywin32 to load and analyze Windows-only executables, and I was experimenting to see if I could get that to run in an existing k8s cluster on RHEL hosts. I had limited success before the spike was abandoned.

Good luck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment