This post appeared originally in our sysadvent series and has been moved here following the discontinuation of the sysadvent microsite
The first time I successfully fired up a container I was pretty excited with the potential this tool had to make a lot of everyday tasks much easier. For example when I had a colleague ask for package xyz from EPEL/PPA made available from our internal mirrors, I could just fire up a clean CentOS/Ubuntu/Debian container and download the packages much faster. This seemed much better than having a CentOS7 virtual machine that I needed to fire up or browsing EPEL manually.
Then I realized it solved the issues of putting together a script you want to use locally but you need to install something from pip/npm/CPAN. I dislike having to add these things to my desktop, or having to setup parallel environments. Now one can put all this in a container and not have to worry about dirtying up your desktop install.
One of my first use cases was IPython3 (python 2.7 was the system default). Docker made this so much easier.
Create Local Docker Images
In order to create an image locally on your workstation you will need to make a “Dockerfile”. This file contains instructions telling docker how to assemble the image.
- Dockerfile for Python3 - literally called “Dockerfile”
FROM alpine:latest
RUN set -ex \
&& apk update \
&& apk add python3 libxml2 libxslt \
&& apk add --no-cache --virtual .build-deps \
gcc python3-dev musl-dev linux-headers libxml2-dev libxslt-dev \
&& pip3 install --upgrade pip \
&& pip3 install ipython requests ftfy zeep pytz docker-py mysql-connector==2.1.6 \
&& apk del .build-deps
CMD ["/usr/bin/ipython"]
-
FROM - Is the base image and version. In this case I am using the latest base image for alpine Linux.
-
You can specify a specific tag if you need to. To see valid alpine tags for example you would need to look at the project. In this case its at https://hub.docker.com/_/alpine/.
-
apk is the package manager in Alpine.
-
-
RUN - Run these commands in order. Adds the goodies you want to have in your image.
-
CMD - in this case when IPython starts it will run in the foreground. Any process you fire off in the container should always be in the foreground. If not the container will just exit when the command completes. See https://docs.docker.com/engine/reference/builder/#parser-directives for all the goodies.
That’s about all there is to it for this one. Now I can build the image locally.
Building the Image.
Your Dockerfile should be in its own directory
$ ls
Dockerfile README.md
Run docker build -t “image_name” .
- in this case I am going with local/ipython3
sudo docker build -t local/ipython3 .
After it builds successfully you should see the image available on your workstation.
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
local/ipython3 latest c2cdc435736b 50 seconds ago 115MB
Running your container.
There is quite a few command line options you can use when starting a container locally with the docker command. The ones I personally use most often are –rm, -v, -i, and -t
- –rm - This will remove the changes done to your local image while the container was running.
- -v will expose a local file-system in the container
- -i interactive.
- -t tty.
- -p expose port on docker host.
-p 80:80
would expose TCP 80 on the docker host to the container on the same port.-p 80:80/udp
would expose UDP. You can expose multiple ports in the same command. - -d daemon mode, no examples of this in this article but worth knowing about.
$ sudo docker run --rm -i -t -v $HOME/scripts:/scripts local/ipython
IPython 3.6.1 (default, May 2 2017, 15:16:41)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]:
And my exposed file-system on the host is available
In [1]: !ls /scripts/
mypythonscript.py
Make an alias:
alias ipython='sudo docker run --rm -i -t -v $HOME/scripts:/scripts local/ipython'
Ansible is another good example:
FROM alpine:latest
RUN apk update \
&& apk add alpine-sdk bash gcc git libffi-dev musl-dev perl python3 python3-dev sshpass openssh libressl-dev \
&& pip3 install --upgrade pip \
&& pip3 install ansible
Build the image.
With this setup one can choose to run either Ansible or ansible-playbook with an alias
alias ansible-playbook='sudo docker run --rm -i -t -v $HOME/projects/myansibleproject:/etc/ansible/ -v /home/$USER/.ssh:/root/.ssh local/ansible ansible-playbook'
alias ansible='sudo docker run --rm -i -t -v $HOME/projects/myansibleproject:/etc/ansible/ -v /home/$USER/.ssh:/root/.ssh local/ansible ansible'
I am exposing the local file-system where my Ansible repositories is located and my SSH key.
$ ansible-playbook --version
[sudo] password for $USER:
ansible-playbook 2.4.1.0
config file = /etc/ansible/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 3.6.1 (default, Oct 2 2017, 20:46:59) [GCC 6.3.0]
$ ansible --version
ansible 2.4.1.0
config file = /etc/ansible/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.1 (default, Oct 2 2017, 20:46:59) [GCC 6.3.0]
In this case I’m building latest but you can edit the docker file to run exactly. what. you. want. And its easily reproduced EXACTLY as you want anywhere docker is running. Three versions of Ansible is no problem. Each run is off a clean image. The container starts, runs the command and exits.
If you put all your docker-files in your own private repositories on GitHub its simple to get your tools back if your machines dies, or you need them in 2 places, share with with your buddies. Nifty
The irony of insecure security software
It can probably be understood from my previous blog post that if it was up to me, I’d avoid products like CrowdStrike - but every now and then I still have to install something like that. It’s not the idea of “security software” per se that I’m against, it’s the actual implementation of many of those products. This post lists up some properties that should be fulfilled for me to happy to install such a product.