├── .gitignore ├── twine ├── requirements.in ├── Dockerfile ├── requirements.txt └── Makefile ├── flake8 ├── requirements.in ├── requirements.txt ├── Dockerfile ├── README.md └── Makefile ├── Makefile ├── cleancss ├── README.md └── Dockerfile ├── uniscribe ├── Dockerfile └── README.md ├── python-lxml ├── Dockerfile └── README.md ├── python-pillow ├── Dockerfile └── README.md ├── travis ├── Dockerfile └── README.md ├── jekyll ├── Dockerfile └── README.md ├── dependencies.yml ├── loris-dev ├── Dockerfile └── README.md ├── heritrix ├── README.md └── Dockerfile ├── README.md ├── .travis.yml ├── LICENSE ├── dockerfiles.fish └── travis_run.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .docker 3 | -------------------------------------------------------------------------------- /twine/requirements.in: -------------------------------------------------------------------------------- 1 | twine==1.9.1 2 | -------------------------------------------------------------------------------- /flake8/requirements.in: -------------------------------------------------------------------------------- 1 | flake8==3.4.1 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include flake8/Makefile 2 | include twine/Makefile 3 | -------------------------------------------------------------------------------- /cleancss/README.md: -------------------------------------------------------------------------------- 1 | # cleancss 2 | 3 | This Docker image is a thin wrapper around . 4 | -------------------------------------------------------------------------------- /flake8/requirements.txt: -------------------------------------------------------------------------------- 1 | ## The following requirements were added by pip freeze: 2 | flake8==3.4.1 3 | mccabe==0.6.1 4 | pycodestyle==2.3.1 5 | pyflakes==1.5.0 6 | -------------------------------------------------------------------------------- /uniscribe/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | LABEL maintainer "Alex Chan " 4 | 5 | RUN apk update 6 | RUN apk add ruby 7 | RUN gem install --no-document uniscribe 8 | 9 | ENTRYPOINT ["/usr/bin/uniscribe"] 10 | -------------------------------------------------------------------------------- /cleancss/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | LABEL maintainer "Alex Chan " 4 | 5 | RUN apk update 6 | RUN apk add nodejs-npm 7 | RUN npm install -g clean-css-cli 8 | RUN which cleancss 9 | 10 | ENTRYPOINT ["/usr/bin/cleancss"] 11 | -------------------------------------------------------------------------------- /twine/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3-alpine 2 | 3 | LABEL maintainer "Alex Chan " 4 | LABEL description "A Python 3-based image for running Twine" 5 | 6 | COPY requirements.txt / 7 | RUN pip3 install -r /requirements.txt 8 | 9 | ENTRYPOINT ["twine"] 10 | -------------------------------------------------------------------------------- /flake8/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3-alpine 2 | 3 | LABEL maintainer "Alex Chan " 4 | LABEL description "A Python 3-based image for running flake8" 5 | 6 | COPY requirements.txt / 7 | RUN pip3 install -r /requirements.txt 8 | 9 | ENTRYPOINT ["flake8"] 10 | -------------------------------------------------------------------------------- /python-lxml/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | LABEL maintainer "Alex Chan alex@alexwlchan.net" 4 | LABEL description "A Docker image containing Python 3, lxml and its dependencies" 5 | 6 | RUN apk update 7 | RUN apk add build-base libxml2-dev libxslt-dev python3 python3-dev 8 | RUN pip3 install lxml 9 | -------------------------------------------------------------------------------- /python-lxml/README.md: -------------------------------------------------------------------------------- 1 | # python-lxml 2 | 3 | The Docker image in this directory has the [lxml library][lxml] and its immediate dependencies. 4 | 5 | I don't use this image directly, but I copy/paste the commands into a larger Docker image that has lxml as a dependency. 6 | 7 | [lxml]: https://pypi.org/project/lxml/ 8 | -------------------------------------------------------------------------------- /python-pillow/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | LABEL maintainer "Alex Chan alex@alexwlchan.net" 4 | LABEL description "A Docker image containing Pillow and its minimal dependencies" 5 | 6 | RUN apk update 7 | RUN apk add python py-pip 8 | 9 | RUN apk add build-base jpeg-dev python-dev zlib-dev 10 | 11 | RUN pip install Pillow 12 | -------------------------------------------------------------------------------- /python-pillow/README.md: -------------------------------------------------------------------------------- 1 | # python-pillow 2 | 3 | The Docker image in this directory has the [Pillow library][pillow] and its immediate dependencies. 4 | 5 | I wouldn't use this image directly, but I often copy/paste the commands into a larger Docker image that has Pillow as a dependency. 6 | 7 | [pillow]: https://pypi.org/project/Pillow/ 8 | -------------------------------------------------------------------------------- /travis/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | LABEL maintainer "Alex Chan " 4 | LABEL description "A Docker image that wraps the travis-ci command-line tool" 5 | 6 | RUN apk update 7 | RUN apk add git ruby ruby-dev 8 | RUN apk add build-base libffi-dev ruby-irb ruby-rdoc && \ 9 | gem install travis && \ 10 | apk del build-base libffi-dev 11 | 12 | VOLUME /repo 13 | WORKDIR /repo 14 | 15 | ENTRYPOINT ["/usr/bin/travis"] 16 | -------------------------------------------------------------------------------- /jekyll/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | LABEL maintainer "Alex Chan " 4 | LABEL description "A Docker image for Jekyll, the static site generator" 5 | 6 | # Some links that were useful in getting 'gem install' to work: 7 | # 8 | # - https://jekyllrb.com/docs/installation/ 9 | # - https://github.com/ffi/ffi/issues/485 10 | # 11 | RUN apk update 12 | RUN apk add build-base libffi-dev ruby ruby-dev ruby-irb ruby-rdoc 13 | 14 | RUN gem install bundler jekyll 15 | 16 | ENTRYPOINT ["/usr/bin/jekyll"] 17 | -------------------------------------------------------------------------------- /flake8/README.md: -------------------------------------------------------------------------------- 1 | # flake8 2 | 3 | This is a Docker image for running the [flake8](https://pypi.org/project/flake8/) linting tool. 4 | 5 | The entrypoint of the image is flake8 itself: 6 | 7 | $ docker run greengloves/flake8 --version 8 | 3.4.1 (mccabe: 0.6.1, pycodestyle: 2.3.1, pyflakes: 1.5.0) 9 | 10 | To run it over your own files, map your code into a volume in the container, and set that volume as the working directory. For example: 11 | 12 | $ docker run --volume $(pwd):/src --workdir /src greengloves/flake8 13 | -------------------------------------------------------------------------------- /dependencies.yml: -------------------------------------------------------------------------------- 1 | collectors: 2 | 3 | - type: python-pip 4 | path: flake8/requirements.in 5 | actors: 6 | - type: python-pip 7 | dependencies: ".*" 8 | versions: "Y.Y.Y" 9 | settings: 10 | pip_freeze_target: flake8/requirements.txt 11 | 12 | - type: python-pip 13 | path: twine/requirements.in 14 | actors: 15 | - type: python-pip 16 | dependencies: ".*" 17 | versions: "Y.Y.Y" 18 | settings: 19 | pip_freeze_target: twine/requirements.txt 20 | -------------------------------------------------------------------------------- /loris-dev/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | 3 | LABEL maintainer "Alex Chan " 4 | LABEL description "A Docker image for doing local Loris development" 5 | 6 | RUN apt-get update 7 | 8 | RUN apt-get install -y python python-pip python-setuptools python-dev \ 9 | uwsgi-plugin-python libjpeg-turbo8-dev libfreetype6-dev zlib1g-dev \ 10 | liblcms2-dev liblcms2-utils libtiff5-dev libwebp-dev libffi-dev libssl-dev 11 | 12 | COPY requirements.txt . 13 | COPY requirements_test.txt . 14 | 15 | RUN pip install -r requirements_test.txt 16 | 17 | VOLUME /repo 18 | WORKDIR /repo 19 | -------------------------------------------------------------------------------- /heritrix/README.md: -------------------------------------------------------------------------------- 1 | # heritrix 2 | 3 | This is a Docker image for running the [Heritrix web crawler][ia]. 4 | 5 | I was testing this for something (I don't remember what now), and it was more convenient to install it in Docker than try to run it locally. 6 | 7 | ## Usage 8 | 9 | ```console 10 | $ docker build -t heritrix . 11 | $ mkdir jobs 12 | $ docker run -d -p 8443:8443 -v $(pwd)/jobs:/usr/heritrix-3.2.0/jobs heritrix 13 | ``` 14 | 15 | To access the web interface, go to in your browser. 16 | Username/password is `heritrix`/`heritrix`. 17 | 18 | [ia]: https://webarchive.jira.com/wiki/display/Heritrix/Heritrix 19 | -------------------------------------------------------------------------------- /loris-dev/README.md: -------------------------------------------------------------------------------- 1 | # loris-dev 2 | 3 | This is the Docker image I use for doing local development work on the [Loris image server][loris]. 4 | My daily work environment is macOS, and Kakadu and OpenJPEG are particularly slow there – so I find it faster to run them in a Linux container. 5 | 6 | For example, to run all the Loris tests: 7 | 8 | ```console 9 | $ cd /path/to/loris-repo 10 | $ docker build -f /path/to/dockerfiles/loris-dev/Dockerfile -t loris-dev . 11 | $ docker run -v $(pwd):/repo loris-dev coverage run --module py.test --verbose tests/*.py && coverage report 12 | ``` 13 | 14 | [loris]: https://github.com/loris-imageserver/loris 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dockerfiles 2 | 3 | This repo contains some of my useful Dockerfiles. 4 | 5 | Some of them produce images that I run directly (for example, *flake8* or *travis*) to avoid having to install dependencies locally. 6 | These are pushed to Docker Hub and can be accessed through `docker pull`. 7 | 8 | Others serve as building blocks for bigger projects. 9 | For example, I have some Dockerfiles for Python libraries with non-trivial dependencies. 10 | When I need one of those dependencies in a project, I'll copy the relevant parts from the Dockerfile in this repo, rather than rederiving it from scratch. 11 | 12 | ## License 13 | 14 | MIT. 15 | -------------------------------------------------------------------------------- /twine/requirements.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile 3 | # To update, run: 4 | # 5 | # pip-compile --output-file requirements.txt requirements.in 6 | # 7 | certifi==2017.7.27.1 # via requests 8 | chardet==3.0.4 # via requests 9 | idna==2.6 # via requests 10 | pkginfo==1.4.1 # via twine 11 | requests-toolbelt==0.8.0 # via twine 12 | requests==2.18.4 # via requests-toolbelt, twine 13 | tqdm==4.19.4 # via twine 14 | twine==1.9.1 15 | urllib3==1.22 # via requests 16 | 17 | # The following packages are considered to be unsafe in a requirements file: 18 | # setuptools # via twine 19 | -------------------------------------------------------------------------------- /jekyll/README.md: -------------------------------------------------------------------------------- 1 | # jekyll 2 | 3 | The Docker image in this directory has `jekyll` as its entrypoint -- you can use this anywhere you'd run `jekyll`, but without the hassle of installing Ruby. 4 | 5 | I'm not a Ruby developer, but I used to use Jekyll on OS X. 6 | I was just using the version of Ruby that came installed with OS X, so when it shifted under my feet with new versions of OS X, I found that Jekyll was broken and I was stuck. 7 | With Docker, no more! 8 | 9 | In practice, I don't use this Dockerfile directly -- instead, I use it as a starting point to get me to Jekyll, and then build on it from there. 10 | It's short enough that I can copy/paste what it contains into a new Dockerfile. 11 | See for an example. 12 | -------------------------------------------------------------------------------- /uniscribe/README.md: -------------------------------------------------------------------------------- 1 | # uniscribe 2 | 3 | This Docker image is a thin wrapper around . 4 | It gives you a way to break down Unicode strings. 5 | For example: 6 | 7 | ```console 8 | $ uniscribe "Hello world" 9 | 10 | 0048 ├─ H ├─ LATIN CAPITAL LETTER H 11 | 0065 ├─ e ├─ LATIN SMALL LETTER E 12 | 006C ├─ l ├─ LATIN SMALL LETTER L 13 | 006C ├─ l ├─ LATIN SMALL LETTER L 14 | 006F ├─ o ├─ LATIN SMALL LETTER O 15 | 0020 ├─ ] [ ├─ SPACE 16 | 0077 ├─ w ├─ LATIN SMALL LETTER W 17 | 006F ├─ o ├─ LATIN SMALL LETTER O 18 | 0072 ├─ r ├─ LATIN SMALL LETTER R 19 | 006C ├─ l ├─ LATIN SMALL LETTER L 20 | 0064 ├─ d ├─ LATIN SMALL LETTER D 21 | 22 | ``` 23 | 24 | h/t [@glasnt](https://twitter.com/glasnt/status/878119485697269760) for telling me about this utility. -------------------------------------------------------------------------------- /twine/Makefile: -------------------------------------------------------------------------------- 1 | export ROOT = $(shell git rev-parse --show-toplevel) 2 | export TWINE = $(ROOT)/twine 3 | export TWINE_IMAGE = greengloves/twine 4 | export TWINE_VERSION = $(shell cat $(TWINE)/requirements.in | tr '=' ' ' | awk '{print $$2}') 5 | 6 | 7 | $(TWINE)/requirements.txt: $(TWINE)/requirements.in 8 | docker run --volume $(TWINE):/src micktwomey/pip-tools 9 | 10 | $(ROOT)/.docker/twine: $(TWINE)/Dockerfile $(TWINE)/requirements.txt 11 | docker build --tag $(TWINE_IMAGE) $(TWINE) 12 | mkdir -p $(ROOT)/.docker && touch $(ROOT)/.docker/twine 13 | 14 | twine-build: $(ROOT)/.docker/twine 15 | 16 | twine-version: 17 | @echo $(TWINE_VERSION) 18 | 19 | twine-publish: twine-build 20 | docker push $(TWINE_IMAGE):latest 21 | docker tag $(TWINE_IMAGE):latest $(TWINE_IMAGE):$(TWINE_VERSION) 22 | docker push $(TWINE_IMAGE):$(TWINE_VERSION) 23 | 24 | 25 | .PHONY: twine-build twine-publish twine-version 26 | -------------------------------------------------------------------------------- /flake8/Makefile: -------------------------------------------------------------------------------- 1 | export ROOT = $(shell git rev-parse --show-toplevel) 2 | export FLAKE8 = $(ROOT)/flake8 3 | export FLAKE8_IMAGE = greengloves/flake8 4 | export FLAKE8_VERSION = $(shell cat $(FLAKE8)/requirements.in | tr '=' ' ' | awk '{print $$2}') 5 | 6 | 7 | $(FLAKE8)/requirements.txt: $(FLAKE8)/requirements.in 8 | docker run --volume $(FLAKE8):/src micktwomey/pip-tools 9 | 10 | $(ROOT)/.docker/flake8: $(FLAKE8)/Dockerfile $(FLAKE8)/requirements.txt 11 | docker build --tag $(FLAKE8_IMAGE) $(FLAKE8) 12 | mkdir -p $(ROOT)/.docker && touch $(ROOT)/.docker/flake8 13 | 14 | flake8-build: $(ROOT)/.docker/flake8 15 | 16 | flake8-version: 17 | @echo $(FLAKE8_VERSION) 18 | 19 | flake8-publish: flake8-build 20 | docker push $(FLAKE8_IMAGE):latest 21 | docker tag $(FLAKE8_IMAGE):latest $(FLAKE8_IMAGE):$(FLAKE8_VERSION) 22 | docker push $(FLAKE8_IMAGE):$(FLAKE8_VERSION) 23 | 24 | 25 | .PHONY: flake8-build flake8-publish flake8-version 26 | -------------------------------------------------------------------------------- /heritrix/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | LABEL maintainer "Alex Chan alex@alexwlchan.net" 4 | LABEL description "A Docker image for running the Heritrix web crawler" 5 | 6 | RUN apk update 7 | 8 | # Java 7 instead of Java 8 because Heritrix has issues running under Java 7: 9 | # https://kris-sigur.blogspot.co.uk/2014/10/heritrix-java-8-and-sunsecuritytoolskey.html 10 | RUN apk add bash openjdk7-jre 11 | 12 | RUN wget -O /tmp/heritrix.tar.gz http://builds.archive.org/maven2/org/archive/heritrix/heritrix/3.2.0/heritrix-3.2.0-dist.tar.gz 13 | RUN tar -C /usr -xvf /tmp/heritrix.tar.gz 14 | 15 | RUN keytool -keystore /usr/heritrix-3.2.0/adhoc.keystore -storepass password -keypass password -alias adhoc -genkey -keyalg RSA -dname "CN=Heritrix Ad-Hoc HTTPS Certificate" -validity 3650 16 | 17 | EXPOSE 8443 18 | 19 | COPY run.sh /run.sh 20 | 21 | CMD ["/usr/heritrix-3.2.0/bin/heritrix", "--web-admin", "heritrix:heritrix", "--web-bind-hosts", "$(hostname -i)", "tail", "-f", "/usr/heritrix-3.2.0/heritrix_out.log"] 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | sudo: required 3 | 4 | python: 3.6 5 | 6 | services: 7 | - docker 8 | 9 | branches: 10 | only: 11 | - master 12 | 13 | install: 14 | - pip install daiquiri requests 15 | 16 | script: 17 | - ./travis_run.py 18 | 19 | env: 20 | global: 21 | - DOCKER_USERNAME=greengloves 22 | - secure: l+gWE278p8u+nWHY/8GARVD24DyR+Mkb3QVH2AjAEDCbbxELQb4hm26ZGxqYQIRjAehUaZrSxzTQVg1Rs7Ir66FDJH/B12k0BbwrPCPWvnItnrLvqkSo1gzHMtKM2HByaq9G6KqF0V1yNzknxAyips+oT5oiREMm4vMoMUh2olhF0XLkigAU4Nhe2jXxJ4aVDKJDqoJmv7o3+NDA9yu0Gt2XpnrJSRHhMpKyPee/YxPmbAD0S5QUovX4rE3VELbQVPxkGhEzAD4WttpyGI/ppZXiuEubmegq/SOaOneJudKLFTqDAbpQyjI0QwVuYWXDBxL8LtR9teljLPnVttdeR5mwmG93kJbpaAF1dMRZCuv/E4z9b0Ugfvb/DWpuzQus9hF94Ud8xc8SWAhWUfUtXc+EPMBBXpcFFKiQQJ0W3GO/pEP5wIeTjzeq7nUJbvbMtAsKlvyKJCogkGrq49/cbo0RQaCCwV637SNA//KdXnooWpjDC0/kx5YmL85hGVNXYAJ65qFw6Xry3TuNVb27O/AY6kHAt4BPQXnqiR1mm28BlMFyOeeErTAmClacvIUfz+A8KyRSxyh/4ltgKeW1iGMRM6TomM+bIKik5HJM6TTusuPDH0wHlaVX8+H0InVI/M/Tl1Cq1vvpyVw1tyJovJ0P8hCrilcj7uz7PeEmtqM= 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Alex Chan 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /travis/README.md: -------------------------------------------------------------------------------- 1 | # travis 2 | 3 | The Docker image in this directory wraps the [Travis CI CLI client][travis]. 4 | This saves me from dealing with `gem install` and keeping a compatible version of Ruby installed. 5 | 6 | [travis]: https://github.com/travis-ci/travis.rb#installation 7 | 8 | ## Usage 9 | 10 | You always need to share the `.travis` directory in your user folder with the container -- this is where Travis tracks the logged in user. 11 | 12 | You need to authenticate with GitHub when you first set up the CLI client. 13 | Like so: 14 | 15 | ```console 16 | $ docker run --volume ~/.travis:/root/.travis alexwlchan/travis login --github-token= 17 | ``` 18 | 19 | where `` is a personal access token generated [on GitHub][tokens] with access to your public repos. 20 | 21 | After that, I use the following command to run the container (bound to a shell alias): 22 | 23 | ```console 24 | $ docker run --volume $(git rev-parse --show-toplevel):/repo --volume ~/.travis:/root/.travis alexwlchan/travis 25 | ``` 26 | 27 | The `git` command is returning the path to the root of the current repository -- I've never had a scenario where I used the Travis CLI and wasn't in a Git repo. 28 | 29 | [tokens]: https://github.com/settings/tokens 30 | -------------------------------------------------------------------------------- /dockerfiles.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | # This is a script that I dot in as part of my fish shellconfig. It allows 3 | # me to use some of my Docker images within my native shell, by building 4 | # images on-demand and then passing through arguments. 5 | 6 | function dockerfiles-clean 7 | rm -rf ~/.dockerfiles 8 | end 9 | 10 | function build --description "Build and record a Docker image from dockerfiles" 11 | set name $argv[1] 12 | test -f ~/.dockerfiles/$name 13 | if [ $status != 0 ] 14 | docker build --tag alexwlchan/$name --file ~/repos/dockerfiles/$name/Dockerfile ~/repos/dockerfiles/$name 15 | mkdir -p ~/.dockerfiles 16 | touch ~/.dockerfiles/$name 17 | end 18 | end 19 | 20 | 21 | 22 | function travis 23 | build travis 24 | git rev-parse --show-toplevel >/dev/null 2>&1 25 | mkdir -p ~/.travis 26 | if [ $status = 0 ] 27 | docker run \ 28 | --volume ~/.travis:/root/.travis \ 29 | --volume (git rev-parse --show-toplevel):/repo \ 30 | alexwlchan/travis $argv 31 | else 32 | docker run \ 33 | --volume ~/.travis:/root/.travis \ 34 | alexwlchan/travis $argv 35 | end 36 | end 37 | 38 | 39 | function uniscribe 40 | build uniscribe 41 | docker run alexwlchan/uniscribe $argv 42 | end 43 | -------------------------------------------------------------------------------- /travis_run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- encoding: utf-8 3 | 4 | import logging 5 | import os 6 | import subprocess 7 | 8 | import daiquiri 9 | import requests 10 | 11 | daiquiri.setup(level=logging.INFO) 12 | logger = daiquiri.getLogger() 13 | 14 | publish_tasks = [] 15 | for root, _, filenames in os.walk('.'): 16 | for f in filenames: 17 | if f != 'Makefile': 18 | continue 19 | path = os.path.join(root, f) 20 | with open(path, 'r', encoding='utf-8') as f: 21 | for line in f: 22 | if line != line.lstrip(): 23 | continue 24 | task = line.split(':')[0] 25 | if not task.endswith('-publish'): 26 | continue 27 | publish_tasks.append(task) 28 | 29 | logger.info('*** Logging in to Docker Hub') 30 | subprocess.check_call([ 31 | 'docker', 'login', 32 | '--username', os.environ['DOCKER_USERNAME'], 33 | '--password', os.environ['DOCKER_PASSWORD'] 34 | ]) 35 | 36 | # For each publish task, get the most recent version from Docker Hub 37 | for p in publish_tasks: 38 | name = p.rsplit('-', 1)[0] 39 | logger.info('*** Starting checks for %s', name) 40 | resp = requests.get( 41 | f'https://registry.hub.docker.com/v2/repositories/greengloves/{name}/tags/' 42 | ) 43 | resp.raise_for_status() 44 | 45 | subprocess.check_call(['make', f'{name}-build']) 46 | 47 | if os.environ.get('TRAVIS_EVENT_TYPE') == 'pull_request': 48 | logger.info('This is a Travis PR, skipping publish steps') 49 | else: 50 | versioned_images = [ 51 | img 52 | for img in resp.json()['results'] 53 | if img['name'] != 'latest' 54 | ] 55 | try: 56 | latest_image = max(versioned_images, key=lambda img: img['last_updated']) 57 | latest_version = latest_image['name'].strip() 58 | except ValueError: 59 | latest_version = '' 60 | logger.info('Docker Hub = %s', latest_version) 61 | 62 | local_version = subprocess.check_output(['make', f'{name}-version']).decode('ascii').strip() 63 | logger.info('Local build = %s', local_version) 64 | 65 | if latest_version == local_version: 66 | logger.info('Versions match, nothing to do!') 67 | else: 68 | logger.warning('Versions differ, rebuilding!') 69 | subprocess.check_call(['make', f'{name}-publish']) 70 | 71 | logger.info('*** Finished checks for %s', name) 72 | --------------------------------------------------------------------------------