Gitlab-runner with docker executor: Unable to import Python module

I want to run pylint over the source code of a Python project.

When I activate the virtualenv with pipenv and run pylint with pylint --rcfile=.pylintrc -f colorized <src-dir> I’ve no warning and errors and the expected rating of 10.

When I run pylint as part of a GitLab CI job locally with gitlab-runner and Docker executor I get several errors of the type <src-dir>/<src-file>.py:8:0: E0401: Unable to import '<Python-module>' (import-error). The modules are modules from the Python project’s dependencies, here PyModbus. <REPO> is the name of the GitLab project and is the same as the Python package name.

Running with gitlab-runner 12.3.0 (a8a019e0)
  on docker-auto-scale fa6cab46
Using Docker executor with image python:3.6 ...
Pulling docker image python:3.6 ...
Using docker image sha256:a08c6226131aeb7682d83f350e0ff5cf2b99c6418f00de58e4d6ad3d5c1c1492 for python:3.6 ...
Running on runner-fa6cab46-project-14530831-concurrent-0 via runner-fa6cab46-srm-1570033946-96949821...
Fetching changes with git depth set to 50...
Initialized empty Git repository in /builds/<COMPANY>/<REPO>/.git/
Created fresh repository.
From https://gitlab.com/<COMPANY>/<REPO>
 * [new branch]      ci_setup   -> origin/ci_setup
Checking out d1c4957c as ci_setup...

Skipping Git submodules setup
$ pip install .
Processing /builds/<COMPANY>/<REPO>
Building wheels for collected packages: <REPO>
  Building wheel for <REPO> (setup.py): started
  Building wheel for <REPO> (setup.py): finished with status 'done'
  Created wheel for <REPO>: filename=<REPO>-0.0.1-cp36-none-any.whl size=4574 sha256=5b146f0a4520af1f2d7db62f259be31df56878b321570e96cc84adce1443e6b1
  Stored in directory: /tmp/pip-ephem-wheel-cache-4951t1ry/wheels/fd/db/bc/f1af74461c2e1209948cdf611648c68b6e7b4756cf37ba598a
Successfully built <REPO>
Installing collected packages: <REPO>
Successfully installed <REPO>-0.0.1
$ pip install pylint==2.4.2
Collecting pylint==2.4.2
  Downloading https://files.pythonhosted.org/packages/ef/ed/1cb8e7b85a31807aa0bff8b3e60935370bed7e141df8b530aac6352bddff/pylint-2.4.2-py3-none-any.whl (302kB)
Collecting astroid<2.4,>=2.3.0 (from pylint==2.4.2)
  Downloading https://files.pythonhosted.org/packages/13/e1/74a63c85c501c29c52da5be604c025e368f4dd77daf1fa13c878a33e5a36/astroid-2.3.1-py3-none-any.whl (205kB)
Collecting mccabe<0.7,>=0.6 (from pylint==2.4.2)
  Downloading https://files.pythonhosted.org/packages/87/89/479dc97e18549e21354893e4ee4ef36db1d237534982482c3681ee6e7b57/mccabe-0.6.1-py2.py3-none-any.whl
Collecting isort<5,>=4.2.5 (from pylint==2.4.2)
  Downloading https://files.pythonhosted.org/packages/e5/b0/c121fd1fa3419ea9bfd55c7f9c4fedfec5143208d8c7ad3ce3db6c623c21/isort-4.3.21-py2.py3-none-any.whl (42kB)
Collecting typed-ast<1.5,>=1.4.0; implementation_name == "cpython" and python_version < "3.8" (from astroid<2.4,>=2.3.0->pylint==2.4.2)
  Downloading https://files.pythonhosted.org/packages/31/d3/9d1802c161626d0278bafb1ffb32f76b9d01e123881bbf9d91e8ccf28e18/typed_ast-1.4.0-cp36-cp36m-manylinux1_x86_64.whl (736kB)
Collecting wrapt==1.11.* (from astroid<2.4,>=2.3.0->pylint==2.4.2)
  Downloading https://files.pythonhosted.org/packages/23/84/323c2415280bc4fc880ac5050dddfb3c8062c2552b34c2e512eb4aa68f79/wrapt-1.11.2.tar.gz
Collecting lazy-object-proxy==1.4.* (from astroid<2.4,>=2.3.0->pylint==2.4.2)
  Downloading https://files.pythonhosted.org/packages/0e/26/534a6d32572a9dbca11619321535c0a7ab34688545d9d67c2c204b9e3a3d/lazy_object_proxy-1.4.2-cp36-cp36m-manylinux1_x86_64.whl (49kB)
Collecting six==1.12 (from astroid<2.4,>=2.3.0->pylint==2.4.2)
  Downloading https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl
Building wheels for collected packages: wrapt
  Building wheel for wrapt (setup.py): started
  Building wheel for wrapt (setup.py): finished with status 'done'
  Created wheel for wrapt: filename=wrapt-1.11.2-cp36-cp36m-linux_x86_64.whl size=75246 sha256=fa33c48ac860e97bd201c96e5c1ca07696f55dd9b7d9f999ed820bb2f496030a
  Stored in directory: /root/.cache/pip/wheels/d7/de/2e/efa132238792efb6459a96e85916ef8597fcb3d2ae51590dfd
Successfully built wrapt
Installing collected packages: typed-ast, wrapt, lazy-object-proxy, six, astroid, mccabe, isort, pylint
Successfully installed astroid-2.3.1 isort-4.3.21 lazy-object-proxy-1.4.2 mccabe-0.6.1 pylint-2.4.2 six-1.12.0 typed-ast-1.4.0 wrapt-1.11.2
$ pylint --rcfile=.pylintrc -f colorized <REPO-SRC-DIR>
************* Module <REPO>.<MODULE>
<REPO>/<MODULE>.py:8:0: E0401: Unable to import 'pymodbus.client.sync' (import-error)
<REPO>/<MODULE>.py:10:0: E0401: Unable to import 'pymodbus.bit_read_message' (import-error)
<REPO>/<MODULE>.py:11:0: E0401: Unable to import 'pymodbus.register_read_message' (import-error)

-----------------------------------
Your code has been rated at 8.53/10

ERROR: Job failed: exit code 1

My .gitlab-ci.yml looks like this:

image: python:3.6

before_script:
  - pip install .

stages:
  - Static Analysis

pylint:
  stage: Static Analysis
  script:
    - pip install pylint==2.4.2
    - pylint --rcfile=.pylintrc -f colorized <src-dir>

And I am using pipenv (Pipfile + Pipfile.lock) for dependency management. The only official GitLab docs I was able to find is Test and deploy a Python application with GitLab CI/CD. But it is kind of outdated cause it uses pip instead of pipenv for dependency management.

How can I fix this issue?