A small Python Docker image based on Alpine Linux.
- 2.7 (Dockerfile)
- 2.7-onbuild (Dockerfile)
- 2.7-slim (Dockerfile)
- 3.4 (Dockerfile)
- 3.4-onbuild (Dockerfile)
- 3.4-slim (Dockerfile)
NOTE: onbuild
images install the requirements.txt
of your project from the get go. This allows you to cache your requirements right in the build. Make sure you are in the same directory of your requirements.txt
file.
The default docker python images are too big, much larger than they need to be. Hence I built this simple image based on docker-alpine, that has everything needed for the most common python projects - including python3-dev
(which is not common in most minimal alpine python packages).
REPOSITORY TAG SIZE
jfloff/alpine-python 2.7-slim 52.86 MB
python 2.7-slim 180.8 MB
jfloff/alpine-python 2.7-onbuild 204 MB
jfloff/alpine-python 2.7 204 MB
python 2.7 676.2 MB
jfloff/alpine-python 3.4-slim 63.93 MB
python 3.4-slim 193.9 MB
jfloff/alpine-python 3.4-onbuild 226.8 MB
jfloff/alpine-python 3.4 226.8 MB
python 3.4 681.5 MB
Perhaps this could be even more smaller, but I'm not an Alpine guru. Feel free to post a PR.
- Installs
build-base
andpython-dev
, allowing the use of more advanced packages such asgevent
- Installs
bash
allowing interaction with the container - Just like the main
python
docker image, it creates useful symlinks that are expected to exist, e.g.python3.4
>python
,pip2.7
>pip
, etc.) - Added
testing
andcommunity
repositories to Alpine's/etc/apk/repositories
file
This image runs python
command on docker run
. You can either specify your own command, e.g:
docker run --rm -ti jfloff/alpine-python python hello.py
You can also access bash
inside the container:
docker run --rm -ti jfloff/alpine-python bash
These images can be used to bake your dependencies into an image by extending the plain python images. To do so, create a custom Dockerfile
like this:
FROM jfloff/alpine-python:3.4-onbuild
# for a flask server
EXPOSE 5000
CMD python manage.py runserver
Don't forget to build that Dockerfile
:
docker build --rm=true -t jfloff/app .
docker run --rm -t jfloff/app
Personally, I build an extended Dockerfile
version (like shown above), and mount my specific application inside the container:
docker run --rm -v "$(pwd)":/home/app -w /home/app -p 5000:5000 -ti jfloff/app
These images are very small to download, and can install requirements at run-time via flags. The install only happens the first time the container is run, and dependencies can be baked in (see Creating Images).
These images can be run in multiple ways. With no arguments, it will run python
interactively:
docker run --rm -ti jfloff/alpine-python:2.7-slim
If you specify a command, they will run that:
docker run --rm -ti jfloff/alpine-python:2.7-slim python hello.py
Pip dependencies can be installed by the -p
switch, or a requirements.txt
file.
If the file is at /requirements.txt
it will be automatically read for dependencies. If not, use the -P
or -r
switch to specify a file.
# This runs interactive Python with 'simplejson' and 'requests' installed
docker run --rm -ti jfloff/alpine-python:2.7-slim -p simplejson -p requests
# Don't forget to add '--' after your dependencies to run a custom command:
docker run --rm -ti jfloff/alpine-python:2.7-slim -p simplejson -p requests -- python hello.py
# This accomplishes the same thing by mounting a requirements.txt in:
echo 'simplejson' > requirements.txt
echo 'requests' > requirements.txt
docker run --rm -ti \
-v requirements.txt:/requirements.txt \
jfloff/alpine-python:2.7-slim python hello.py
# This does too, but with the file somewhere else:
echo 'simplejson requests' > myapp/requirements.txt
docker run --rm -ti \
-v myapp:/usr/src/app \
jfloff/alpine-python:2.7-slim \
-r /usr/src/app/requirements.txt \
-- python /usr/src/app/hello.py
Alpine package dependencies can be installed by the -a
switch, or an apk-requirements.txt
file.
If the file is at /apk-requirements.txt
it will be automatically read for dependencies. If not, use the -A
switch to specify a file.
You can also try installing some Python modules via this method, but it is possible for Pip to interfere if it detects a version problem.
# Unknown why you'd need to do this, but you can!
docker run --rm -ti jfloff/alpine-python:2.7-slim -a openssl -- python hello.py
# This installs libxml2 module faster than via Pip, but then Pip reinstalls it because Ajenti's dependencies make it think it's the wrong version.
docker run --rm -ti jfloff/alpine-python:2.7-slim -a py-libxml2 -p ajenti
Build-time Alpine package dependencies (such as compile headers) can be installed by the -b
switch, or a build-requirements.txt
file. They will be removed after the dependencies are installed to save space.
If the file is at /build-requirements.txt
it will be automatically read for dependencies. If not, use the -B
switch to specify a file.
build-base
, linux-headers
and python-dev
are always build dependencies, you don't need to include them.
docker run --rm -ti jfloff/alpine-python:2.7-slim \
-p gevent \
-p libxml2 \
-b libxslt-dev \
-b libxml-dev \
-- python hello.py
Similar to the onbuild images, dependencies can be baked into a new image by using a custom Dockerfile
, e.g:
FROM jfloff/alpine-python:2.7-slim
RUN /entrypoint.sh \
-p ajenti-panel \
-p ajenti.plugin.dashboard \
-p ajenti.plugin.settings \
-p ajenti.plugin.plugins \
-b libxml2-dev \
-b libxslt-dev \
-b libffi-dev \
-b openssl-dev \
&& echo
CMD ["ajenti-panel"]
# you won't be able to add more dependencies later though-- see 'Debugging'
The /entrypoint.sh
script that manages dependencies in the slim images creates an empty file, /requirements.installed
, telling the script not to install any dependencies after the container's first run. Removing this file will allow the script to work again if it is needed.
You can also access bash
inside the container:
docker run --rm -ti jfloff/alpine-python:2.7-slim bash
The code in this repository, unless otherwise noted, is MIT licensed. See the LICENSE
file in this repository.