Understanding Resin.io Dockerfile and persistent files


#1

Hello,
I still have a hard time understanding how resin.io works in detail for my devices. I still cannot understand how my device knows which script to start when it boots.

I use this script: resin-wifi-connect (which does not work for me:( on RPi3).
FROM resin/%%RESIN_MACHINE_NAME%%-debian

ENV INITSYSTEM on

RUN apt-get update \
    && apt-get install -y dnsmasq \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /usr/src/app/

WORKDIR /usr/src/app

RUN curl https://api.github.com/repos/resin-io/resin-wifi-connect/releases/latest -s \
    | grep -hoP 'browser_download_url": "\K.*%%RESIN_ARCH%%\.tar\.gz' \
    | xargs -n1 curl -Ls \
    | tar -xvz -C /usr/src/app/

COPY start .

CMD ["bash", "start"]

I understand that I push the cloned files to my resin repo and it gets built by some virtual emulator, so everything is faster. Then I use ethernet to provision my device. That means this built image gets downloaded on my rpi3 right?
Next step, my question is does that mean, CMD COPY apt-get update and all these commands are executed each time, when the device reboots? Or does the Rpi3 “know” he as already got a finished built and just has to execute CMD start. How can one check against /data volume persistent files? Do they get overwritten?

Thank you very much.


#2

Hey @rquant

I think the confusion is coming from the difference between build and runtime instructions in a Dockerfile, I’ll try to give you a quick run through of the differences and gotchas.

Build commands are commands that change the image that gets built when you do a git push resin master. Examples of this are ENV, RUN, COPY. These commands will work on the virtual filesystem of the image at build time, and any changes are saved in the image filesystem.

The build finishes, and the produced image is deployed to your device. When the image is present on your device, it will use docker to create a container from the image and run it. When docker runs a container it will look for a CMD entry, which is a runtime command (another example of a runtime command is ENTRYPOINT, but I’m not going to go into that). The arguments which are passed to the CMD command are the commands which are run when the contianer is started.

In the above example, a script named start is copied into the image (using COPY) and then this file is specified as the script that will be run, (via bash) in the CMD step.

So to answer your question, the device “knows” what to run when it starts your image due to the CMD step, and build steps (RUN, COPY, ENV) are ran exactly once, at build time.

Let me know if anything isn’t clear and I’ll be glad to get you up and running :slight_smile:

Cameron