'Canonical way to checksum downloads in a Dockerfile?
I'm creating a Dockerfile that downloads, builds, installs node.js from source. I'd like to checksum the download before building it, and stop or exit the Dockerfile if the checksum fails:
# officially supported ubuntu
FROM ubuntu:12.04
# SETUP
RUN cd /tmp
RUN apt-get update -y
RUN apt-get install wget build-essential automake -y
RUN wget http://nodejs.org/dist/latest/node-v0.10.26.tar.gz
RUN wget http://nodejs.org/dist/latest/SHASUMS256.txt
# RUN checksum: exit on fail, continue on success
??? how ???
# INSTALL
RUN tar -xvf node-v0.10.26.tar.gz && cd node-v0.10.26
RUN ./configure && make && make install
# CLEANUP
apt-get autoremove --purge wget build-essential automake -y
Has the Docker community settled on a 'best practices' way of doing this?
Solution 1:[1]
If any of the RUN
commands return a non-zero code, the build will fail.
FROM fedora
RUN false
In the Dockerfile above, I'm just doing a quick test by running false
. false
is a linux utility that just sets a non-zero return code, handy for testing. As you can see, when I build that Dockerfile, it complains and fails out.
$ docker build .
Uploading context 12.29 kB
Uploading context
Step 0 : FROM fedora
---> 58394af37342
Step 1 : RUN false
---> Running in a5b9a4b37e25
2014/04/22 09:41:19 The command [/bin/sh -c false] returned a non-zero code: 1
Now that we know this, if we have the file and checksums in the image (which you appear to have via wget
), we can test that they match up. Here is a quick and dirty version of this below, in which I generate a file and calculate its checksum before verifying it. In your example, you would obviously not be doing that, I just do it to show you how this works.
FROM fedora
# Create the text file
RUN echo ThisIsATest > echo.txt
# Calculate the checksum
RUN sha1sum echo.txt > sha1sums.txt
# Validate the checksum (this should pass)
RUN sha1sum -c sha1sums.txt
# Alter the text
RUN echo ThisShouldFail > echo.txt
# Validate the checksum (this should now fail)
RUN sha1sum -c sha1sums.txt
And if we run this...
$ docker build -no-cache .
Warning: '-no-cache' is deprecated, it will be removed soon. See usage.
Uploading context 12.8 kB
Uploading context
Step 0 : FROM fedora
---> 58394af37342
Step 1 : RUN echo ThisIsATest > echo.txt
---> Running in cd158d4e6d91
---> 4088b1b4945f
Step 2 : RUN sha1sum echo.txt > sha1sums.txt
---> Running in 5d028d901d94
---> c97b1d31a720
Step 3 : RUN sha1sum -c sha1sums.txt
---> Running in 44d119897164
echo.txt: OK
---> ca01d590cadd
Step 4 : RUN echo ThisShouldFail > echo.txt
---> Running in 87b575ac4052
---> 36bb5d8cf6d1
Step 5 : RUN sha1sum -c sha1sums.txt
---> Running in e20b7ac0c924
echo.txt: FAILED
WARNING: 1 computed checksum did NOT match
2014/04/22 10:29:07 The command [/bin/sh -c sha1sum -c sha1sums.txt] returned a non-zero code: 1
Solution 2:[2]
1- Download your file and put it where you need it, then run:
sha256sum /path/to/file
Output:
255d...334 /path/to/file
2- copy the output and put it in your Dockerfile like this: (be careful about spaces between brackets)
RUN [ "255d...334 /path/to/file" = "$(sha256sum /usr/local/bin/confd)" ]
As @Todd mentioned, if the command responds non-zero the build will fail. you can use sha1sum or sha512sum aswell.
Solution 3:[3]
I have set the checksum as a variable
ARG CHECKSUMKUBECTL="51f5679a0cb11a65f25c3479bbfdfd21c4d0acd8814d3cbaf5aaeea7682178a3820c3555b17ea6ee24470ac67ebfd0f78cc98513e5b526436494350be64bda69"
The following throws an exit code when they do not match, and an Ok if they match.
RUN echo "${CHECKSUMKUBECTL} $BIN_DIR/kubectl" | sha512sum --check
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | NicoKowe |
Solution 3 | Zephaniah Grunschlag |