-
Testing Docker images with Autotest
For awhile now, I’ve had a docker image which blindly gets rebuilt via dockerhub every time the upstream image changes. As the docker image I’m building just pulls bits and pieces from other sources, I didn’t really have anything to unit test as part of the CI process. Since it was working fine at the time, I just left it.
Fast-forward a few years and sure enough, one of the things I bundle into the image shipped a broken version. The docker build still succeeded, but the final image didn’t work as expected. Rather than let that happen again, I thought I should find a testing solution.
Docker’s Autotest looked like a good fit. It can run tests on new commits, PRs and crucially on upstream image changes. However, I was a bit confused how I could use it without bloating my image with tests embedded inside. Turns out it’s really simple using a multi-stage build.
Suppose we have the following trivial docker image, where we simploy add a dummy
example-appto the alpine image.FROM alpine:latest COPY app/ /app WORKDIR /app RUN ln -s /app/example-app /usr/local/bin/example-appWe can turn it into a multi-stage image with a testing layer.
# Create release layer and label it FROM alpine:latest as release COPY app/ /app WORKDIR /app RUN ln -s /app/example-app /usr/local/bin/example-app # Create testing layer FROM alpine:latest as test COPY --from=release / / COPY test/ /test WORKDIR /test ENTRYPOINT ["/bin/sh", "-c"] CMD ["./tests.sh"] # Output release as the final image FROM releaseFirst we build the regular image and label it
release. We then build a testing layer using release as a base and add in our tests. Here we just copy in a directory containing a bash script of arbitrary tests. The only requirement is that it exits with a0when tests pass, or anything else when they fail.Finally we call
FROM releaseto ensure that on a regular build, we only build the app without the testing layer.For Autotest to work, we need to create a
docker-compose.test.ymlfile with asutservice.version: "3.8" services: sut: build: context: . target: "test"We set the target to
testso that it builds and runs the test layer from our image. We can test it locally (with a deliberate test failure):$ docker-compose -f docker-compose.test.yml up sut ... sut_1 | Executing tests... sut_1 | OK - example-app should run fine sut_1 | FAIL - example-app should run fine sut_1 | PASSED: 1 FAILED: 1 docker-autotest-example_sut_1 exited with code 1Now that it works locally we just need to enable Autotest in the Dockerhub settings.
Full example repository: Autotest-example.
-
Monitoring home internet speeds with Smokeping and Speed Test
I’ve been monitoring my home internet’s uptime using Smokeping docker container for awhile now. But after finally switching from ADSL to a 100Mbps connection I thought it would be a good time to start also monitoring internet speeds.
Turns out there is an existing plugin, smokeping-speedtest for Smokeping which does the job.
For easy setup, I created a docker image to combine the plugin and it’s dependencies and with linuxserver’s docker-smokeping image as a base.
For configuration, I just followed the instructions and added the follwing to the
Probesfile.+ speedtest binary = /usr/local/bin/speedtest-cli timeout = 300 step = 3600 offset = random pings = 3 ++ speedtest-download measurement = download ++ speedtest-upload measurement = uploadI also added a new section to my
Targetsfile to perform speed tests against a local ISP.+ SpeedTest menu = Speed Tests title = Speed Tests ++ download menu = Download title = Download probe = speedtest-download server = 2173 measurement = download host = internode.on.net ++ upload menu = Upload title = Upload probe = speedtest-upload server = 2173 measurement = upload host = internode.on.netThe complete Dockerfile is on github and the image on Docker Hub.
-
Moving from Heroku to Dokku
With Heroku's recent changes to their plan offerings, my hosting costs were suddenly about to increase form $0 a month to $42. To run an app 24 hrs a day, you need to be on the hobby tier ($7/month). Not really happy with that, I decided to look elsewhere.
I had previously explored Amazon's elastic beanstalk PaaS, but this time around I wanted to try hosting my own PaaS. Dokku bills itself as being a "Docker powered mini-Heroku in around 200 lines of Bash". After reading good things about it, I decided to give it a shot on a Digitial Ocean dropet.