python – Getting a Windows Docker Container running with .gitlab-ci.yml

python – Getting a Windows Docker Container running with .gitlab-ci.yml

Youre getting the linux version of the python container because GitLabs shared runners use linux. Due to how containers work, they share the kernel of the host machine, so a linux runner cant host a windows container – it simply doesnt have the kernel instructions to run it.

If you want to run a windows docker image, you will need to have a windows server with a supported version that youre self hosting. You will also need to ensure that the windows docker container youre using works properly.

All of this having been said – if youre trying to use python, just run it in Linux. It seems like there are vanishingly few reasons you would need python to be running specifically on windows for your CI/CD, but if you let us know what they are we may be able to help.

There is one other answer and that is Pywine. It emulates a windows inside of a linux for python.

It therfore is:

A docker runner than opens another docker runner that emulatates windows that can be used to solve this. Down below you will find my setup for this:

This is by far not the best setup but it works for me. As a docker image i am using tobix/pywine:3.9. If you find a better way please tell me. I would be very happy to improve the setup.

image: python:3.9

# Change pips cache directory to be inside the project directory since we can
# only cache local items.
variables:
  PIP_CACHE_DIR: $CI_PROJECT_DIR/.cache/pip
  
stages:
  - Static Code Analysis
  - test
  - deploy

cache:
  paths:
    - .cache/pip
    - venv/

before_script:
  - python3.9 -V  # Print out python version for debugging
  - python3.9 -m pip install virtualenv
  - virtualenv venv
  - source venv/bin/activate

Black Linter:
  when: always
  stage: Static Code Analysis
  tags:
    - pi
  script:
    - pip install black
    - black  --check --diff ./
  allow_failure: true

Flake Linter:
  when: always
  stage: Static Code Analysis
  tags:
    - pi
  script:
    - pip install flake8
    - flake8 --statistics
  allow_failure: true

Type-test:
  when: always
  image: tobix/pywine:3.9
  tags:
    - win-docker
  stage: Static Code Analysis
  before_script:
    - . /opt/mkuserwineprefix
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -v
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pip install --upgrade pip setuptools
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pip install wheel --no-warn-script-location
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pip install -Ur requirements/test.txt --no-warn-script-location
  script:
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m mypy . --warn-redundant-casts --warn-unused-ignores --show-column-numbers --pretty --install-types --non-interactive
  allow_failure: true

test:
  needs: []
  tags:
    - win-docker
  image: tobix/pywine:3.9
  before_script:
    - . /opt/mkuserwineprefix
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -v
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pip install --upgrade pip setuptools --no-warn-script-location
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pip install wheel --no-warn-script-location
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pip install -Ur requirements/test.txt --no-warn-script-location
  script:
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pytest test/ --junitxml=/report.xml --cov=./
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m coverage report
    - wine /opt/wineprefix/drive_c/Python39/Python.exe -m coverage xml
  artifacts:
    when: always
    reports:
      junit: report.xml
      cobertura: coverage.xml

pyinstall:
  stage: deploy
  image: tobix/pywine:3.9
  retry: 2
  tags:
    - win-docker
  before_script:
      - . /opt/mkuserwineprefix
      - wine /opt/wineprefix/drive_c/Python39/Python.exe -v
      - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pip install --upgrade pip setuptools pyinstaller
      - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pip install wheel --no-warn-script-location
      - wine /opt/wineprefix/drive_c/Python39/Python.exe -m pip install -Ur requirements/base.txt --no-warn-script-location

  script:
    - wine /opt/wineprefix/drive_c/Python39/Scripts/pyinstaller.exe main.spec --clean
  artifacts:
    paths:
      - dist/*.exe
  rules:
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Please note that everything I didnt need to run on windows runs in an normal docker container to be more efficient.

python – Getting a Windows Docker Container running with .gitlab-ci.yml

Leave a Reply

Your email address will not be published.