From 292a6b961c336bf9a16655054c0399f2a05e2c29 Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Sat, 16 Mar 2024 01:56:35 +0000 Subject: [PATCH] Update Dockerfile to use a nifty buildkit feature allowing us to either pull FTL from the web, or use a locally built copy. Add a build script for ease of local building (separate from the build-and-test script). Update Readme with build instructions Signed-off-by: Adam Warner --- README.md | 26 ++++++++++++---- build.sh | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/Dockerfile | 45 +++++++++++++++++---------- 3 files changed, 132 insertions(+), 22 deletions(-) create mode 100755 build.sh diff --git a/README.md b/README.md index 5c12981..199ea78 100644 --- a/README.md +++ b/README.md @@ -205,17 +205,31 @@ Why is this style of upgrading good? A couple reasons: Everyone is starting fro To reconfigure Pi-hole you'll either need to use an existing container environment variables or if there is no a variable for what you need, use the web UI or CLI commands. -### Building an image with alternative component branches +### Building the image locally Occasionally you may need to try an alternative branch of one of the components (`core`,`web`,`ftl`). On bare metal you would run, for example, `pihole checkout core custombranchname`, however in Docker world we have disabled this command as it can cause unpredictable results. -The preferred method is to clone this repository and rebuild the image with the custom branch name passed in as an arg, e.g `docker buildx build src/. --tag pihole_custom --build-arg CORE_BRANCH=custombranchname --no-cache`, and then redeploy your stack with this new image (In this case you should have a local image named `pihole_custom`, but you can call it whatever you want) +The preferred method is to clone this repository and build the image locally with `./build.sh` -Valid args are: +#### Usage: +``` +./build.sh [-l] [-f ] [-c ] [-w ] [-t ] [use_cache] +``` -- `CORE_BRANCH` -- `WEB_BRANCH` -- `FTL_BRANCH` +#### Options: + +- `-f ` / `--ftlbranch `: Specify FTL branch (cannot be used in conjunction with `-l`) +- `-c ` / `--corebranch `: Specify Core branch +- `-w ` / `--webbranch `: Specify Web branch +- `-t ` / `--tag `: Specify Docker image tag (default: `pihole`) +- `-l` / `--local`: Use locally built FTL binary (requires `src/pihole-FTL` file) +- `use_cache`: Enable caching (by default `--no-cache` is used) + +If no options are specified, the following command will be executed: + +``` +docker buildx build src/. --tag pihole --no-cache +``` ### Pi-hole features diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..fd8f076 --- /dev/null +++ b/build.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Usage function +usage() { + echo "Usage: $0 [-l] [-f ] [-c ] [-w ] [-t ] [use_cache]" + echo "Options:" + echo " -f, --ftlbranch Specify FTL branch (cannot be used in conjunction with -l)" + echo " -c, --corebranch Specify Core branch" + echo " -w, --webbranch Specify Web branch" + echo " -t, --tag Specify Docker image tag (default: pihole)" + echo " -l, --local Use locally built FTL binary (requires src/pihole-FTL file)" + echo " use_cache Enable caching (by default --no-cache is used)" + echo "" + echo "If no options are specified, the following command will be executed:" + echo " docker buildx build src/. --tag pihole --no-cache" + exit 1 +} + +# Set default values +DOCKER_BUILD_CMD="docker buildx build src/. --tag pihole --no-cache" +FTL_FLAG=false + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + key="$1" + + case $key in + -l | --local) + if [ ! -f "src/pihole-FTL" ]; then + echo "File 'src/pihole-FTL' not found. Exiting." + exit 1 + fi + if [ "$FTL_FLAG" = true ]; then + echo "Error: Both -l and -f cannot be used together." + usage + fi + FTL_FLAG=true + DOCKER_BUILD_CMD+=" --build-arg FTL_SOURCE=local" + shift + ;; + -f | --ftlbranch) + if [ "$FTL_FLAG" = true ]; then + echo "Error: Both -l and -f cannot be used together." + usage + fi + FTL_FLAG=true + FTL_BRANCH="$2" + DOCKER_BUILD_CMD+=" --build-arg FTL_BRANCH=$FTL_BRANCH" + shift + shift + ;; + -c | --corebranch) + CORE_BRANCH="$2" + DOCKER_BUILD_CMD+=" --build-arg CORE_BRANCH=$CORE_BRANCH" + shift + shift + ;; + -w | --webbranch) + WEB_BRANCH="$2" + DOCKER_BUILD_CMD+=" --build-arg WEB_BRANCH=$WEB_BRANCH" + shift + shift + ;; + -t | --tag) + TAG="$2" + DOCKER_BUILD_CMD=${DOCKER_BUILD_CMD/pihole/$TAG} + shift + shift + ;; + use_cache) + DOCKER_BUILD_CMD=${DOCKER_BUILD_CMD/--no-cache/} + shift + ;; + *) + echo "Unknown option: $1" + usage + ;; + esac +done + +# Execute the docker build command +echo "Executing command: $DOCKER_BUILD_CMD" +eval $DOCKER_BUILD_CMD diff --git a/src/Dockerfile b/src/Dockerfile index 8fe0a5d..e4ced6b 100644 --- a/src/Dockerfile +++ b/src/Dockerfile @@ -1,6 +1,7 @@ # syntax=docker/dockerfile:1 -ARG alpine_version="3.19" -FROM alpine:${alpine_version} +ARG FTL_SOURCE=remote +ARG alpine_version="3.19" +FROM alpine:${alpine_version} as base # https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope ARG TARGETPLATFORM @@ -43,20 +44,7 @@ ADD --chmod=0755 https://raw.githubusercontent.com/pi-hole/PADD/${PADD_BRANCH}/p # download a the main repos from github RUN git clone --depth 1 --single-branch --branch ${WEB_BRANCH} https://github.com/pi-hole/web.git /var/www/html/admin && \ - git clone --depth 1 --single-branch --branch ${CORE_BRANCH} https://github.com/pi-hole/pi-hole.git /etc/.pihole ;\ - # Download the latest version of pihole-FTL for alpine: - if [ "$TARGETPLATFORM" = "linux/amd64" ]; then FTLARCH=amd64; \ - elif [ "$TARGETPLATFORM" = "linux/386" ]; then FTLARCH=386; \ - elif [ "$TARGETPLATFORM" = "linux/arm/v6" ]; then FTLARCH=armv6; \ - elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then FTLARCH=armv7; \ - # Note for the future, "linux/arm6/v8" is not a valid value for TARGETPLATFORM, despite the CI platform name being that. - elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then FTLARCH=arm64; \ - elif [ "$TARGETPLATFORM" = "linux/riscv64" ]; then FTLARCH=riscv64; \ - else FTLARCH=amd64; fi \ - && echo "Arch: ${TARGETPLATFORM}, FTLARCH: ${FTLARCH}" \ - && curl -sSL "https://ftl.pi-hole.net/${FTL_BRANCH}/pihole-FTL-${FTLARCH}" -o /usr/bin/pihole-FTL \ - && chmod +x /usr/bin/pihole-FTL \ - && readelf -h /usr/bin/pihole-FTL || cat /usr/bin/pihole-FTL + git clone --depth 1 --single-branch --branch ${CORE_BRANCH} https://github.com/pi-hole/pi-hole.git /etc/.pihole RUN cd /etc/.pihole && \ install -Dm755 -d /opt/pihole && \ @@ -77,6 +65,31 @@ RUN cd /etc/.pihole && \ COPY --chmod=0755 bash_functions.sh /usr/bin/bash_functions.sh COPY --chmod=0755 start.sh /usr/bin/start.sh +## Buildkit can do some fancy stuff and we can use it to either download FTL from ftl.pi-hole.net or use a local copy + +FROM base as remote-ftl-install +# Default stage if FTL_SOURCE is not explicitly set to "local" +# Download the latest version of pihole-FTL for the correct architecture +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then FTLARCH=amd64; \ + elif [ "$TARGETPLATFORM" = "linux/386" ]; then FTLARCH=386; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v6" ]; then FTLARCH=armv6; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then FTLARCH=armv7; \ + # Note for the future, "linux/arm6/v8" is not a valid value for TARGETPLATFORM, despite the CI platform name being that. + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then FTLARCH=arm64; \ + elif [ "$TARGETPLATFORM" = "linux/riscv64" ]; then FTLARCH=riscv64; \ + else FTLARCH=amd64; fi \ + && echo "Arch: ${TARGETPLATFORM}, FTLARCH: ${FTLARCH}" \ + && curl -sSL "https://ftl.pi-hole.net/${FTL_BRANCH}/pihole-FTL-${FTLARCH}" -o /usr/bin/pihole-FTL \ + && chmod +x /usr/bin/pihole-FTL \ + && readelf -h /usr/bin/pihole-FTL || cat /usr/bin/pihole-FTL + +FROM base as local-ftl-install +# pihole-FTL must be built from source and copied to the build directory first! +COPY --chmod=0755 pihole-FTL /usr/bin/pihole-FTL + +# Use the appropriate FTL Install stage based on the FTL_SOURCE build-arg +FROM ${FTL_SOURCE}-ftl-install as final + HEALTHCHECK CMD dig +short +norecurse +retry=0 @127.0.0.1 pi.hole || exit 1 ENTRYPOINT ["/sbin/tini", "--", "start.sh"]