Should You Use Virtualenv in Docker?
Why use a virtualenv if your app runs inside of a Docker container already?
Docker is great at packaging OS-level dependencies together with your application. Virtualenv however, is great at making sure that you have a perfectly controlled environment for your Python application.
Sure, you could simply install your project’s dependencies inside of your Docker image without using virtualenv. Using a virtual environment with your dependency tooling of choice like pipenv, poetry or good old pip won’t hurt or slow you down.
What you get is the convenience of well-known tooling and additional control over your application’s Python dependencies.
Control Over Your Python Dependencies
When using virtualenv & co, you can make sure that a particular Python version is used for your project, and only a handful of well-defined Python dependencies are available to it.
You can completely eliminate bugs which relate to managing Python versions on the OS level, and unwanted Python package versions intruding on your application as a side effect of an OS upgrade.
By using a virtualenv, you make sure that there can be no clashes between existing Python packages installed through the OS package manager and ones which your project needs. This makes the Python environment of your application easier to control and keep clean.
If you stick to your usual tools, you can rely on workflows and processes which you know well from your development environment.
Going from virtualenv to no-virtualenv would introduce a difference between your development setup and the containerized setup. Apart from a slight rise in complexity by making sure that your Dockerfile handles virtual environment activation the right way, there is no downside.
You don’t lose any performance by using something like virtualenv inside of your Docker container, and you can rely on a well-tested setup.
While Docker provides an isolated environment for your Python application, you’re better off by using virtualenv (or your tool of choice) nevertheless.
It can help you to maintain control over your Python environment & dependencies. It also helps to keep the difference between your local development environment and the dockerized application small. It won’t slow your application down, and you’ll be less likely to run into weird bugs caused by OS-level changes down the line.