Does virtualenv serve a purpose (in production) when using docker?
Virtualenv was created long before docker. Today, I lean towards docker instead of virtualenv for these reasons:
- Virtualenv still means people consuming your product need to download eggs. With docker, they get something which is "known to work". No strings attached.
- Docker can do much more than virtualenv (like create a clean environment when you have products that need different Python versions).
The main drawback for Docker was the poor Windows support. That changed with the version for Windows 10.
As for "how many apps per container", the usual policy is 1.
Yes. You should still use virtualenv. Also, you should be building wheels instead of eggs now. Finally, you should make sure that you keep your Docker image lean and efficient by building your wheels in a container with the full build tools and installing no build tools into your application container.
You should read this excellent article. https://glyph.twistedmatrix.com/2015/03/docker-deploy-double-dutch.html
The key take away is
It’s true that in many cases, perhaps even most, simply installing stuff into the system Python with Pip works fine; however, for more elaborate applications, you may end up wanting to invoke a tool provided by your base container that is implemented in Python, but which requires dependencies managed by the host. By putting things into a virtualenv regardless, we keep the things set up by the base image’s package system tidily separated from the things our application is building, which means that there should be no unforeseen interactions, regardless of how complex the application’s usage of Python might be.
Introducing virtualenv is very easy, so I'd say start without it on your docker container.
If the need arises, then maybe you can install it. Running "pip freeze > requirements.txt" will give you all your python packages. However, I doubt you'll ever need virtualenv inside a docker container as creating another container would be a more preferable alternative.
I would not recommend having more than one application in a single container. When you get to this point, your container is doing too much.
I use both because with that you can more easily use multi stage builds and simply move your dependencies you built in one stage into later images/layers. Example can be found here.