Packaging Python scripts with Docker
In Part 1 of this post I covered the creation of the initial MyUsps notification script. There’s quite a few dependencies in the environment required for running this script. At a bare minimum you will need a functional Linux or Windows environment with the following dependencies
GeckoDriver Firefox v59 Selenium 3.11 (pip install selenium) Python3.6 imgurpython (pip install imgurpython ) Pushbullet Python Library (pip install pushbullet.py)
There’s some challenges getting all of these things to work well together. It’s also very difficult to keep all of these applications in sync and distribute a working installation script to allow users to clone your environment.
Enter Docker.
Using Docker images we can create a dockerfile that will package images with all the necessary components, and allow for easy distribution of working images. The dockerfile for this project looks like this –
FROM ubuntu:16.04 MAINTAINER Nick Shores #Install Python 3.6 RUN apt-get update RUN apt-get install -y software-properties-common vim RUN add-apt-repository ppa:jonathonf/python-3.6 RUN apt-get update #install curl RUN apt-get install curl wget RUN apt-get install -y build-essential python3.6 python3.6-dev python3-pip python3.6-venv RUN apt-get install -y git # update pip RUN python3.6 -m pip install pip --upgrade RUN python3.6 -m pip install wheel #Install Pushbullet library RUN pip install pushbullet.py #Install imgrurpython RUN pip install imgurpython #Install MyUsps Library RUN pip install myusps #Update Selenium to 3.6 RUN pip install selenium --upgrade #Clone myusps_notifications repo RUN git clone https://github.com/nshores/my_usps_notifications.git #Install Dependencies RUN apt-get install -y unzip openjdk-8-jre-headless xvfb libxi6 libgconf-2-4 #========= # Firefox #========= ARG FIREFOX_VERSION=latest RUN FIREFOX_DOWNLOAD_URL=$(if [ $FIREFOX_VERSION = "latest" ] || [ $FIREFOX_VERSION = "nightly-latest" ] || [ $FIREFOX_VERSION = "devedition-latest" ]; then echo "https://download.mozilla.org/?product=firefox-$FIREFOX_VERSION-ssl&os=linux64&lang=en-US"; else echo "https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-x86_64/en-US/firefox-$FIREFOX_VERSION.tar.bz2"; fi) \ && apt-get update -qqy \ && apt-get -qqy --no-install-recommends install firefox \ && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \ && wget --no-verbose -O /tmp/firefox.tar.bz2 $FIREFOX_DOWNLOAD_URL \ && apt-get -y purge firefox \ && rm -rf /opt/firefox \ && tar -C /opt -xjf /tmp/firefox.tar.bz2 \ && rm /tmp/firefox.tar.bz2 \ && mv /opt/firefox /opt/firefox-$FIREFOX_VERSION \ && ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox # Install geckodriver: RUN export BASE_URL=https://github.com/mozilla/geckodriver/releases/download \ && export VERSION=$(curl -sL \ https://api.github.com/repos/mozilla/geckodriver/releases/latest | \ grep tag_name | cut -d '"' -f 4) \ && curl -sL \ $BASE_URL/$VERSION/geckodriver-$VERSION-linux64.tar.gz | tar -xz \ && mv geckodriver /usr/local/bin/geckodriver # Install Chrome RUN curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list RUN apt-get -y update RUN apt-get -y install google-chrome-stable #Install Chrome Driver RUN CHROME_DRIVER_VERSION=$(curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE) && wget -N http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip -P ~/ RUN unzip ~/chromedriver_linux64.zip -d ~/ RUN rm ~/chromedriver_linux64.zip RUN mv -f ~/chromedriver /usr/local/bin/chromedriver RUN chown root:root /usr/local/bin/chromedriver RUN chmod 0755 /usr/local/bin/chromedriver #Start Main script which runs chromedriver and keeps container open #TODO - Create main start script and loop CMD [ "python3.6", "/my_usps_notifications/mail.py" ]
After you have this dockerfile created and stored in your github repo, you can connect your repository to Docker Hub . Docker Hub will create images by running the docker build command on your dockerfile, and will store the resulting images on their servers. The manual equivalent of this process is
sudo docker build .
In the context of this project, this allows me to distribute my python script as a whole package, that includes all the dependencies in one file, and makes it easier to run. To run my script, all we need to do is run
sudo docker pull nshores/my_usps_notifications
Then edit the included docker_run.sh file to start our docker container. Head over to the github repository page for this project if you’d like to grab a copy of this script and get further instructions on usage.
Future Improvements
I’m planning on improving this script and making it a provider agnostic notification agent. I plan to support scraping UPS and Fedex in the future. I’m also going to use the Google Vision API . to extract names from pictures of mail and store that in a database, then notify the person that they have mail via a slack private message. Something like this –
After that’s working I am also going to work on converting this script into a full fledged mail checking slack bot! Check back for updates!
Pingback: Checking your snail mail with Python/Docker and Slack. (Part 1) – Ops and Automation