How to use Docker to build a Skype Bot controlling Jenkins!
“Besides black art, there is only automation and mechanization.” — Federico García Lorca
At my workplace, we use Jenkins for continuous integration and Skype for communication. Now, imagine being asked at least six times a day to run a build, another six times to check its status, another six to deploy, and yet another six to verify the deployment. And of course, four more times to explain why the platform is down!
This happens because some managers are too afraid to let non-technical staff touch Jenkins, and some non-technical people are too lazy to learn how to use it themselves.
I was getting frustrated with these repetitive tasks, so I decided to build a bot to handle them for me!
Now, every request is sent directly to the bot as a command. It performs the action automatically and listens for any status changes in the Jenkins job. If it detects a transition, it sends a notification.
The bot is simply a Python script running in the background as a daemon, using Skype4Py and the Jenkins API module. The logic is basic but easily extendable.
Things weren’t as simple as they seemed, so I’ll explain step by step how I built a functional bot.
Running Skype in a Docker Container
First, I couldn’t run two instances of Skype on the same machine, and I didn’t have another Windows machine available. However, I did have access to the server where Jenkins was installed.
The problem? The server had no GUI, and no installable version of Skype.
The solution? Docker!
I used the python:2.7.10 image as a base for my Dockerfile and added instructions to install Skype, inspired by jess/skype.
FROM python:2.7.10
MAINTAINER Youssef El Jaoujat <eljoujat@gmail.com>
# Tell debconf to run in non-interactive mode
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -f install --fix-missing
# Setup multiarch because Skype is 32-bit only
RUN dpkg --add-architecture i386 && \
apt-get update && apt-get install -y curl --no-install-recommends
# Install Skype
RUN curl -o /usr/src/skype.deb http://download.skype.com/linux/skype-debian_4.3.0.37-1_i386.deb
RUN dpkg -i /usr/src/skype.deb || true
RUN apt-get -fy install --fix-missing
RUN rm -rf /var/lib/apt/lists/* # Purge temp data
# Start Skype
ENTRYPOINT ["skype"]
To build the Docker image, run:
docker build -t eljoujat/skype .
Now, to test the container:
docker run -it -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY --device /dev/snd eljoujat/skype
If you get an error related to X11 protocols, run:
xhost +
Installing Python Modules
We need two Python modules: Skype4Py
and jenkinsapi
. To install them inside the container, update the Dockerfile:
## Install Python modules
RUN apt-get install -y python-pip && \
pip install Skype4Py && \
pip install jenkinsapi
Mounting the Script into the Container
A best practice with Docker is to decouple applications into multiple containers.
For simplicity, I mapped my local script directory inside the container using the -v
option:
docker run -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /media/eljaoujat/Linux/job/labs/docker/skype:/scripts -e DISPLAY=unix$DISPLAY --device /dev/snd eljoujat/skype:V1.1
Persisting Skype Login
When running the image, Skype launches, but I have to manually accept the Terms of Use and log in each time.
Since there’s no argument to auto-login, I used Docker’s commit
command to create an image with my logged-in session.
After logging in with the “Remember Me” option enabled, I ran:
docker commit <container_id> eljoujat/skype:v1.1
To get the container ID, run:
docker ps
Accessing the Running Container
To debug inside the running container, I used nsenter
:
docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter
Then, to enter the container:
PID=$(docker inspect --format <container_id>)
sudo nsenter --target $PID --mount --uts --ipc --net --pid
Inside, I could verify that my Python script was present and working.
Running the Bot on Container Startup
To automate script execution, I used supervisor, a process control system. Here’s the config file:
[supervisord]
nodaemon=false
[include]
files = /etc/supervisor/conf.d/*.conf
[program:skype]
command=python /scripts/buildchatbot.py
autostart=true
autorestart=true
startretries=20
stderr_logfile=/opt/skypebot.err.log
stdout_logfile=/opt/skypebot.out.log
Final Dockerfile
FROM python:2.7.10
MAINTAINER Youssef El Jaoujat <eljoujat@gmail.com>
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -f install --fix-missing
RUN dpkg --add-architecture i386 && \
apt-get update && apt-get install -y curl supervisor --no-install-recommends
# Install Skype
RUN curl -o /usr/src/skype.deb http://download.skype.com/linux/skype-debian_4.3.0.37-1_i386.deb
RUN dpkg -i /usr/src/skype.deb || true
RUN apt-get -fy install --fix-missing
RUN rm -rf /var/lib/apt/lists/*
# Install Python modules
RUN apt-get install -y python-pip && \
pip install Skype4Py jenkinsapi
# Add Supervisor config
ADD supervisor.conf /etc/supervisor.conf
CMD [ "sh", "-c", "supervisord -c /etc/supervisor.conf && skype" ]
Running the Final Version
docker build -t eljoujat/skype:V1.2 .
docker run -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /media/eljaoujat/Linux/job/labs/docker/skype:/scripts -e DISPLAY=unix$DISPLAY --device /dev/snd eljoujat/skype:V1.2
- To test : just send a messgae to the jenkins Bot telling him to run a job .
“I believe that there is always an other way to do it, and i hope that you let me know .”