Search code examples
checksumdocker

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

  • 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