diff --git a/docker/Dockerfile b/docker/Dockerfile index 2219aba..ed44f2a 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -14,8 +14,9 @@ ARG BUILD_UID=1000 ARG BUILD_GID=1000 ENV LC_ALL=C.UTF-8 COPY docker/dev-common.bash / -RUN /dev-common.bash -CMD [ "/bin/bash", "--login" ] +RUN --mount=type=cache,id=var-cache-apt,target=/var/cache/apt,sharing=locked \ + /dev-common.bash +CMD [ "/bin/bash", "--login" ] # "dev" is a full development environment, suitable for shelling into or # using with the VS Code container plugin. @@ -24,7 +25,8 @@ ARG BUILDARCH ARG TARGETARCH LABEL maintainer="slamb@slamb.org" COPY docker/dev.bash / -RUN /dev.bash +RUN --mount=type=cache,id=var-cache-apt,target=/var/cache/apt,sharing=locked \ + /dev.bash USER moonfire-nvr:moonfire-nvr WORKDIR /var/lib/moonfire-nvr @@ -38,12 +40,18 @@ RUN --mount=type=tmpfs,target=/var/lib/moonfire-nvr/src/ui/node_modules \ # Build the Rust components. Note that dev.sh set up an environment variable # in .buildrc that similarly changes the target dir path. +# +# The "mode" argument to cache mounts doesn't seem to work reliably (as of +# Docker version 20.10.5, build 55c4c88, using a docker-container builder), +# thus the chmod command. FROM --platform=$BUILDPLATFORM dev AS build-server LABEL maintainer="slamb@slamb.org" -RUN --mount=type=cache,id=target,target=/var/lib/moonfire-nvr/target,sharing=locked,mode=1777 \ +RUN --mount=type=cache,id=target,target=/var/lib/moonfire-nvr/target,sharing=locked,mode=777 \ + --mount=type=cache,id=cargo-registry,target=/var/lib/moonfire-nvr/.cargo/registry,sharing=locked,mode=777 \ --mount=type=bind,source=server,target=/var/lib/moonfire-nvr/src/server,readonly \ bash -c 'set -o xtrace && \ source ~/.buildrc && \ + sudo chmod 777 /var/lib/moonfire-nvr/{.cargo/registry,target} && \ cd src/server && \ cargo test && \ cargo build --release && \ @@ -53,7 +61,8 @@ RUN --mount=type=cache,id=target,target=/var/lib/moonfire-nvr/target,sharing=loc FROM --platform=$TARGETPLATFORM ubuntu:20.04 AS deploy LABEL maintainer="slamb@slamb.org" ENV LC_ALL=C.UTF-8 -RUN export DEBIAN_FRONTEND=noninteractive && \ +RUN --mount=type=cache,id=var-cache-apt,target=/var/cache/apt,sharing=locked \ + export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ apt-get install --assume-yes --no-install-recommends \ ffmpeg \ @@ -64,7 +73,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ sqlite3 \ tzdata \ vim-nox && \ - apt-get clean && \ rm -rf /var/lib/apt/lists/* && \ ln -s moonfire-nvr /usr/local/bin/nvr COPY --from=build-server /usr/local/bin/moonfire-nvr /usr/local/bin/moonfire-nvr diff --git a/docker/dev-common.bash b/docker/dev-common.bash index 8b2d660..d45cc93 100755 --- a/docker/dev-common.bash +++ b/docker/dev-common.bash @@ -11,6 +11,11 @@ set -o xtrace export DEBIAN_FRONTEND=noninteractive +# This file cleans apt caches after every invocation. Instead, we use a +# buildkit cachemount to avoid putting them in the image while still allowing +# some reuse. +rm /etc/apt/apt.conf.d/docker-clean + packages=() # Install all packages necessary for building (and some for testing/debugging). @@ -27,8 +32,6 @@ packages+=( ) apt-get update apt-get install --assume-yes --no-install-recommends "${packages[@]}" -apt-get clean -rm -rf /var/lib/apt/lists/* # Create the user. On the dev environment, allow sudo. groupadd \ diff --git a/guide/build.md b/guide/build.md index 37b9860..ef8d5c5 100644 --- a/guide/build.md +++ b/guide/build.md @@ -35,7 +35,8 @@ which you can use from its shell via `docker run` or via something like Visual Studio Code's Docker plugin. ``` -$ docker buildx build --load --tag=moonfire-dev --target=dev +$ docker buildx build \ + --load --tag=moonfire-dev --target=dev -f docker/Dockerfile . ... $ docker run \ --rm --interactive=true --tty \ @@ -84,6 +85,15 @@ caveats: $ docker buildx build --load --platform=arm64/v8 ... ``` +On Linux hosts (as opposed to when using Docker Desktop on macOS/Windows), +you'll likely see errors like the ones below. The solution is to [install +emulators](https://github.com/tonistiigi/binfmt#installing-emulators). + +``` +Error while loading /usr/sbin/dpkg-split: No such file or directory +Error while loading /usr/sbin/dpkg-deb: No such file or directory +``` + ## Non-Docker setup You may prefer building without Docker on the host. Moonfire NVR should run