RPi-Distro / pi-gen

Tool used to create the official Raspberry Pi OS images
BSD 3-Clause "New" or "Revised" License
2.52k stars 1.59k forks source link

How to preload a docker image? #706

Closed half2me closed 6 months ago

half2me commented 10 months ago

I have successfully created a custom image and pre-installed docker by adding this inside the 00-run-chroot.sh file in my custom step:

#!/bin/bash
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh ./get-docker.sh

When I boot my raspberry pi, docker is installed and working as expected. For the next step, I'd like to do a docker pull of a few images that I want to have available for offline use already preloaded with the pi image. Unfortunately inside the script if I try to run any docker commands it fails with: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?. Is it possible to do it this way or shall I try to somehow copy over the docker image files to the filesystem manually?

reubenmiller commented 10 months ago

I'm not sure if you can pre-load images...I'm sure you could hack the filesystem, but that's not going be very fragile.

Instead you could add the images (as tarballs) to a known folder, and on device startup check the folder the folder and run the docker import <file> command. This would just involve setting up a one-shot systemd service to run the appropriate commands.

half2me commented 10 months ago

I'm not sure if you can pre-load images...I'm sure you could hack the filesystem, but that's not going be very fragile.

Instead you could add the images (as tarballs) to a known folder, and on device startup check the folder the folder and run the docker import <file> command. This would just involve setting up a one-shot systemd service to run the appropriate commands.

That's not a bad idea. I still think it would be super useful to run docker commands in the chroot. It would simplify the process. Instead of having to download the docker image, export it, move it to the raspberry pi's filesystem, make a script that docker loads it on startup, it would be a simple docker pull and done.

I'm even thinking of running my built pi image on qemu and running the docker commands there, I just need an easy way to automate this.

barneyman commented 7 months ago

I thought i'd pipe up with something I found at https://forums.docker.com/t/is-it-possible-to-import-a-docker-image-without-docker-load/136197 - in a nutshell - point the host's docker at where var/lib/docker will be, hup it, and do a pull (then revert it and hup it again) - be aware - if you're using your host's docker for something else it will go bang!

here's my stage-docker/00-install-and-pull/00-run.sh

#!/bin/bash -e

mkdir -p ${ROOTFS_DIR}/var/firstboot
# replaced below
#docker pull ghcr.io/barneyman/gpsd-chrony-ntp
#docker save ghcr.io/barneyman/gpsd-chrony-ntp | gzip > ${ROOTFS_DIR}/var/firstboot/1.tar.gz

cp files/docker-compose.yml ${ROOTFS_DIR}/var/firstboot/
cp files/docker-compose-app.service ${ROOTFS_DIR}/etc/systemd/system/
cp files/firstboot.sh ${ROOTFS_DIR}/var/firstboot/

# install docker
on_chroot << EOF
    # get the convenience script
    curl -fsSL https://get.docker.com -o get-docker.sh

    # and run it
    sh ./get-docker.sh

    # clean up
    rm ./get-docker.sh

    # add user
    usermod -aG docker ${FIRST_USER_NAME}

    # enable my one-shot service
    systemctl enable docker-compose-app

EOF

## point docker to my partition and pull

# preserve any existing config
if [ -e /etc/docker/daemon.json ]
then
        mv /etc/docker/daemon.json  /etc/docker/daemon.json.old
fi

# point to my 'future' var/lib/docker
cat > /etc/docker/daemon.json << EOF
{
  "data-root": "${ROOTFS_DIR}/var/lib/docker"
}
EOF

# restart docker
systemctl restart docker
# pull image(s)
docker pull ghcr.io/barneyman/gpsd-chrony-ntp
# kill my hacked config
rm /etc/docker/daemon.json
# and reinstate the old config
if [ -e /etc/docker/daemon.json.old ]
then
        mv /etc/docker/daemon.json.old  /etc/docker/daemon.json
fi
# and start the host docker again
systemctl restart docker

Now to see if i can get this running with https://github.com/usimd/pi-gen-action :)

half2me commented 6 months ago

@barneyman thanks, I'll give that a go. Recently I've been thinking if I can find a way to mount the raspberry pi image and run it with qemu, I can just do all the things i need to do like docker pull, as if I'm already on the device. That would make life much easier.

XECDesign commented 6 months ago

Closing since it's more of a question about setting up docker in a chroot environment rather than anything specific to pi-gen itself.

half2me commented 4 months ago

hey @barneyman I'm also using that Github Action. I'm giving it a go with your method, but I'm also trying to see if I can somehow make this work with docker in docker. If you want to collab on getting this to work, just drop me an email halftome[at]gmail. We might be able to help each other out

half2me commented 4 months ago

@barneyman I think your workaround might be the only way to get it done. I've even tried using skopeo which can copy docker images to and from various registries and formats. Even that doesn't have support for the overlay2 backend that docker uses, as it's some internal implementation.