Introduction #
By setting poetry config virtualenvs.in-project true
, Poetry creates a .venv
directory within the project to isolate the environment.
$ tree -L 1 -a
.
├── app/
├── dockerfiles/
├── .dockerignore
├── .gitlab-ci.yml
├── poetry.lock
├── pyproject.toml
├── README.md
└── .venv/
In GitLab CI/CD, caching this .venv
directory can avoid reinstalling external libraries (pip) every time, thus speeding up the process.
.venv
in different jobs (different directories) is not always guaranteed to work correctly.
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93367
1. Creating the Dockerfile #
Since we don’t want to create a virtual environment inside the image, we only make Poetry commands available without running poetry install
.
FROM python:3.12
ENV PYTHONUNBUFFERED=1
ENV PATH="/root/.local/bin:$PATH"
RUN curl -sSL https://install.python-poetry.org | python3 -
RUN poetry config virtualenvs.in-project true
POETRY_VIRTUALENVS_IN_PROJECT
environment variable. docs
2. Creating the .gitlab-ci.yml
#
Save the created image as $CI_REGISTRY_IMAGE/ci/python312:latest
in GitLab’s container registry and use it in GitLab CI/CD.
By preparing a dedicated job prepare_cache
to run poetry install
, subsequent jobs can use the cached .venv
.
.venv
for testing multiple Python versions, you can change prefix: ci-python312
to separate them. For dynamic usage per branch, refer to the docs.
.python_cache:
image: $CI_REGISTRY_IMAGE/ci/python312:latest
cache:
key:
files:
- poetry.lock
prefix: ci-python312 # Want to change the scope of the cache -> https://docs.gitlab.com/ee/ci/caching/#common-use-cases-for-caches
policy: pull
paths:
- .venv
# - mypy_cache # Uncomment if you use mypy
prepare_cache:
extends: .python_cache
stage: cache
cache:
policy: pull-push
script:
- poetry install -v
small_test:
extends: .python_cache
stage: test
script:
- poetry run python -m pytest
needs:
- prepare_cache
3. Execution Results #
Two jobs will be executed.
prepare_cache
Since .venv
is cached and saved, subsequent runs of poetry install -v
will be skipped due to “Already installed”, speeding up the process.
small_test
Since .venv
is restored from the cache, poetry run
can be executed without running poetry install
.
Conclusion #
The code and pipeline execution results are provided below for reference.