How to get pipenv running in docker?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
pipenv works fine in Docker, but the cleanest container pattern is different from the usual local-development pattern. In most Docker images you do not want pipenv shell; you want pipenv to install locked dependencies into the container's system Python during the image build.
The Practical Docker Pattern
Inside a container, the container itself is already an isolated environment. Because of that, pipenv install --system --deploy is usually the right choice.
This does four important things:
- installs
pipenv, - copies
PipfileandPipfile.lockbefore the rest of the source for layer caching, - installs exactly the locked dependencies,
- and runs the app with the container's Python instead of launching a nested virtual environment.
Why --system Is Usually Better in Docker
Without --system, pipenv creates a virtual environment inside the container. That is not inherently wrong, but it adds an extra environment layer inside something that is already isolated by Docker.
Using --system keeps the image simpler:
- fewer moving pieces,
- easier
CMDlines, - and less confusion about where packages were installed.
If you truly want a project-local virtual environment inside the image, you can do it, but it is a specialized choice rather than the default best practice.
Build Caching Matters
A slow Docker build is often caused by copying the whole application too early. If you copy the entire source tree before dependency installation, any code change invalidates the dependency layer.
This order is better:
With that layout, application code changes do not force a full dependency reinstall unless the lock file changed.
Development vs Production Images
For local development in Docker, you may want development dependencies too:
For production, keep it stricter and smaller:
The --deploy flag causes the build to fail if the lock file is missing or out of sync. That is valuable in CI because it prevents "works on my machine" dependency drift.
A Small Example Project
Suppose your Pipfile defines Flask:
A minimal app can then be:
Build and run it:
At that point, pipenv is only part of the build workflow. The running container just executes Python normally.
Multi-Stage Builds Are Optional but Useful
If your project compiles native dependencies, a multi-stage build can reduce final image size by separating the build environment from the runtime environment. The idea is to install dependencies in one stage and copy the results into a smaller runtime image.
That is not mandatory for every project, but it becomes attractive when the base image would otherwise carry build tools you do not need at runtime.
Common Pitfalls
The most common mistake is trying to run pipenv shell inside Docker. That opens an interactive shell, which is not how container startup is normally managed.
Another mistake is omitting Pipfile.lock from the image build. Without the lock file, you lose reproducibility and may install different dependency versions between builds.
Developers also often skip --system and then wonder why the container cannot find packages when CMD ["python", "app.py"] runs. The packages may be inside a virtual environment that the process never activated.
Finally, if the image rebuilds dependencies on every code change, check the COPY order. Docker layer caching only helps when the dependency files are copied separately.
Summary
- In Docker, the usual
pipenvpattern ispipenv install --system --deploy. - Copy
PipfileandPipfile.lockbefore application code to preserve layer caching. - Use
--ignore-pipfilein production builds when you want the lock file to be the source of truth. - Do not rely on
pipenv shellas the container startup model. - Treat
pipenvas a build-time dependency manager and let the container run plain Python.
Related reading
- How to get the IP address of the docker host from inside a docker container
- How to get the list of dependent child images in Docker?
- How to get the status of a particular pod or container kubectl get pods using jsonpath
- How to handle database migrations with Kubernetes and Skaffold
- How to get real-time resource usage of a pod in k8s?
- How to get running pod status via Rest API
- How to get POSTed JSON in Flask?
- How to get precision, recall and f-measure from confusion matrix in Python

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.