Poetry creates the environment under its own cache directory, with a path like ~/.cache/pypoetry/virtualenvs/projectname-HASH-py3.12, where the hash is derived from the project path. Editors, Docker layer caching and CI cache steps all expect .venv next to the code, so the default causes a steady drip of confusion.
poetry config virtualenvs.in-project true makes Poetry create .venv in the project root instead. Set it per repository with poetry config --local virtualenvs.in-project true, which writes poetry.toml next to pyproject.toml so every contributor and CI job gets it.
Two related settings matter in CI. virtualenvs.create false tells Poetry to install into the active interpreter, which is what you want inside a container that is already isolated. poetry env info --path prints the resolved path in either case, and is the reliable way for a script to find the interpreter. Note that changing the setting does not move an existing environment; remove the old one with poetry env remove --all first.