diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..69f2cc3 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,26 @@ +name: Tests +on: + pull_request: + push: + +jobs: + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + ARCH: + - amd64 + # https://github.com/pi-hole/docker-pi-hole/issues/587#issuecomment-617180631 + #- armel + - armhf + - arm64 + env: + ARCH: ${{matrix.ARCH}} + steps: + - name: Checkout Repo + uses: actions/checkout@v2 + - name: Run Circle Test + run: | + echo "Building ${ARCH}" + ./circle-test.sh \ No newline at end of file diff --git a/Dockerfile.template b/Dockerfile similarity index 62% rename from Dockerfile.template rename to Dockerfile index cce6af4..9fff81c 100644 --- a/Dockerfile.template +++ b/Dockerfile @@ -1,7 +1,11 @@ -FROM {{ pihole.base }} +ARG PIHOLE_BASE +FROM $PIHOLE_BASE -ENV ARCH {{ pihole.arch }} -ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/{{ pihole.s6_version }}/s6-overlay-{{ pihole.s6arch }}.tar.gz +ARG PIHOLE_ARCH +ENV PIHOLE_ARCH "${PIHOLE_ARCH}" +ARG S6_ARCH +ARG S6_VERSION +ENV S6OVERLAY_RELEASE "https://github.com/just-containers/s6-overlay/releases/download/${S6_VERSION}/s6-overlay-${S6_ARCH}.tar.gz" COPY install.sh /usr/local/bin/install.sh COPY VERSION /etc/docker-pi-hole-version @@ -16,8 +20,10 @@ ADD s6/debian-root / COPY s6/service /usr/local/bin/service # php config start passes special ENVs into -ENV PHP_ENV_CONFIG '{{ pihole.php_env_config }}' -ENV PHP_ERROR_LOG '{{ pihole.php_error_log }}' +ARG PHP_ENV_CONFIG +ENV PHP_ENV_CONFIG "${PHP_ENV_CONFIG}" +ARG PHP_ERROR_LOG +ENV PHP_ERROR_LOG "${PHP_ERROR_LOG}" COPY ./start.sh / COPY ./bash_functions.sh / @@ -37,11 +43,14 @@ ENV ServerIP 0.0.0.0 ENV FTL_CMD no-daemon ENV DNSMASQ_USER root -ENV VERSION {{ pihole.version }} +ARG PIHOLE_VERSION +ENV VERSION "${PIHOLE_VERSION}" ENV PATH /opt/pihole:${PATH} -LABEL image="{{ pihole.name }}:{{ pihole.version }}_{{ pihole.arch }}" -LABEL maintainer="{{ pihole.maintainer }}" +ARG NAME +LABEL image="${NAME}:${PIHOLE_VERSION}_${PIHOLE_ARCH}" +ARG MAINTAINER +LABEL maintainer="${MAINTAINER}" LABEL url="https://www.github.com/pi-hole/docker-pi-hole" HEALTHCHECK CMD dig +norecurse +retry=0 @127.0.0.1 pi.hole || exit 1 diff --git a/Dockerfile.py b/Dockerfile.py index 0aa1e1b..7fc1363 100755 --- a/Dockerfile.py +++ b/Dockerfile.py @@ -2,12 +2,11 @@ """ Dockerfile.py - generates and build dockerfiles Usage: - Dockerfile.py [--hub_tag=] [--arch= ...] [-v] [-t] [--no-build | --no-generate] [--no-cache] + Dockerfile.py [--hub_tag=] [--arch= ...] [-v] [-t] [--no-build] [--no-cache] Options: --no-build Skip building the docker images --no-cache Build without using any cache data - --no-generate Skip generating Dockerfiles from template --hub_tag= What the Docker Hub Image should be tagged as [default: None] --arch= What Architecture(s) to build [default: amd64 armel armhf arm64] -v Print docker's command output [default: False] @@ -17,81 +16,18 @@ Examples: """ -from jinja2 import Environment, FileSystemLoader from docopt import docopt import os import subprocess -import sys THIS_DIR = os.path.dirname(os.path.abspath(__file__)) -base_vars = { - 'name': 'pihole/pihole', - 'maintainer' : 'adam@diginc.us', - 's6_version' : 'v1.22.1.0', -} - -os_base_vars = { - 'php_env_config': '/etc/lighttpd/conf-enabled/15-fastcgi-php.conf', - 'php_error_log': '/var/log/lighttpd/error.log' -} - __version__ = None dot = os.path.abspath('.') with open('{}/VERSION'.format(dot), 'r') as v: raw_version = v.read().strip() __version__ = raw_version.replace('release/', 'release-') -images = { - __version__: [ - { - 'base': 'pihole/debian-base:latest', - 'arch': 'amd64', - 's6arch': 'amd64', - }, - { - 'base': 'multiarch/debian-debootstrap:armel-stretch-slim', - 'arch': 'armel', - 's6arch': 'arm', - }, - { - 'base': 'multiarch/debian-debootstrap:armhf-stretch-slim', - 'arch': 'armhf', - 's6arch' : 'arm', - }, - { - 'base': 'multiarch/debian-debootstrap:arm64-stretch-slim', - 'arch': 'arm64', - 's6arch' : 'aarch64', - } - ] -} - -def generate_dockerfiles(args): - if args['--no-generate']: - print(" ::: Skipping Dockerfile generation") - return - - for version, archs in images.items(): - for image in archs: - if image['arch'] not in args['--arch']: - continue - s6arch = image['s6arch'] if image['s6arch'] else image['arch'] - merged_data = dict( - list({ 'version': version }.items()) + - list(base_vars.items()) + - list(os_base_vars.items()) + - list(image.items()) + - list({ 's6arch': s6arch }.items()) - ) - j2_env = Environment(loader=FileSystemLoader(THIS_DIR), - trim_blocks=True) - template = j2_env.get_template('Dockerfile.template') - - dockerfile = 'Dockerfile_{}'.format(image['arch']) - with open(dockerfile, 'w') as f: - f.write(template.render(pihole=merged_data)) - def build_dockerfiles(args): if args['--no-build']: @@ -104,7 +40,9 @@ def build_dockerfiles(args): def run_and_stream_command_output(command, args): print("Running", command) - build_result = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + build_env = os.environ.copy() + build_env['PIHOLE_VERSION'] = __version__ + build_result = subprocess.Popen(command.split(), env=build_env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True) if args['-v']: while build_result.poll() is None: @@ -117,19 +55,17 @@ def run_and_stream_command_output(command, args): def build(docker_repo, arch, args): - dockerfile = 'Dockerfile_{}'.format(arch) - repo_tag = '{}:{}_{}'.format(docker_repo, __version__, arch) - cached_image = '{}/{}'.format('pihole', repo_tag) + repo_tag = '{}:{}-{}'.format(docker_repo, __version__, arch) print(" ::: Building {}".format(repo_tag)) - time='' + time = '' if args['-t']: - time='time ' + time = 'time ' no_cache = '' if args['--no-cache']: no_cache = '--no-cache' - build_command = '{time}docker build {no_cache} --pull --cache-from="{cache},{create_tag}" -f {dockerfile} -t {create_tag} .'\ - .format(time=time, no_cache=no_cache, cache=cached_image, dockerfile=dockerfile, create_tag=repo_tag) - print(" ::: Building {} into {}".format(dockerfile, repo_tag)) + build_command = '{time}docker-compose -f build.yml build {no_cache} --pull {arch}'\ + .format(time=time, no_cache=no_cache, arch=arch) + print(" ::: Building {} into {}".format(arch, repo_tag)) run_and_stream_command_output(build_command, args) if args['-v']: print(build_command, '\n') @@ -145,5 +81,4 @@ if __name__ == '__main__': if args['-v']: print(args) - generate_dockerfiles(args) build_dockerfiles(args) diff --git a/Dockerfile.sh b/Dockerfile.sh index e48a64f..3338491 100755 --- a/Dockerfile.sh +++ b/Dockerfile.sh @@ -3,6 +3,8 @@ set -eux ./Dockerfile.py -v --arch="${ARCH}" --hub_tag="${ARCH_IMAGE}" +docker images + # TODO: Add junitxml output and have circleci consume it # 2 parallel max b/c race condition with docker fixture (I think?) py.test -vv -n 2 -k "${ARCH}" ./test/ diff --git a/Dockerfile_amd64 b/Dockerfile_amd64 deleted file mode 100644 index 121adde..0000000 --- a/Dockerfile_amd64 +++ /dev/null @@ -1,49 +0,0 @@ -FROM pihole/debian-base:latest - -ENV ARCH amd64 -ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz - -COPY install.sh /usr/local/bin/install.sh -COPY VERSION /etc/docker-pi-hole-version -ENV PIHOLE_INSTALL /root/ph_install.sh - -RUN bash -ex install.sh 2>&1 && \ - rm -rf /var/cache/apt/archives /var/lib/apt/lists/* - -ENTRYPOINT [ "/s6-init" ] - -ADD s6/debian-root / -COPY s6/service /usr/local/bin/service - -# php config start passes special ENVs into -ENV PHP_ENV_CONFIG '/etc/lighttpd/conf-enabled/15-fastcgi-php.conf' -ENV PHP_ERROR_LOG '/var/log/lighttpd/error.log' -COPY ./start.sh / -COPY ./bash_functions.sh / - -# IPv6 disable flag for networks/devices that do not support it -ENV IPv6 True - -EXPOSE 53 53/udp -EXPOSE 67/udp -EXPOSE 80 -EXPOSE 443 - -ENV S6_LOGGING 0 -ENV S6_KEEP_ENV 1 -ENV S6_BEHAVIOUR_IF_STAGE2_FAILS 2 - -ENV ServerIP 0.0.0.0 -ENV FTL_CMD no-daemon -ENV DNSMASQ_USER root - -ENV VERSION v5.0 -ENV PATH /opt/pihole:${PATH} - -LABEL image="pihole/pihole:v5.0_amd64" -LABEL maintainer="adam@diginc.us" -LABEL url="https://www.github.com/pi-hole/docker-pi-hole" - -HEALTHCHECK CMD dig +norecurse +retry=0 @127.0.0.1 pi.hole || exit 1 - -SHELL ["/bin/bash", "-c"] \ No newline at end of file diff --git a/Dockerfile_arm64 b/Dockerfile_arm64 deleted file mode 100644 index c3f6ad4..0000000 --- a/Dockerfile_arm64 +++ /dev/null @@ -1,49 +0,0 @@ -FROM multiarch/debian-debootstrap:arm64-stretch-slim - -ENV ARCH arm64 -ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-aarch64.tar.gz - -COPY install.sh /usr/local/bin/install.sh -COPY VERSION /etc/docker-pi-hole-version -ENV PIHOLE_INSTALL /root/ph_install.sh - -RUN bash -ex install.sh 2>&1 && \ - rm -rf /var/cache/apt/archives /var/lib/apt/lists/* - -ENTRYPOINT [ "/s6-init" ] - -ADD s6/debian-root / -COPY s6/service /usr/local/bin/service - -# php config start passes special ENVs into -ENV PHP_ENV_CONFIG '/etc/lighttpd/conf-enabled/15-fastcgi-php.conf' -ENV PHP_ERROR_LOG '/var/log/lighttpd/error.log' -COPY ./start.sh / -COPY ./bash_functions.sh / - -# IPv6 disable flag for networks/devices that do not support it -ENV IPv6 True - -EXPOSE 53 53/udp -EXPOSE 67/udp -EXPOSE 80 -EXPOSE 443 - -ENV S6_LOGGING 0 -ENV S6_KEEP_ENV 1 -ENV S6_BEHAVIOUR_IF_STAGE2_FAILS 2 - -ENV ServerIP 0.0.0.0 -ENV FTL_CMD no-daemon -ENV DNSMASQ_USER root - -ENV VERSION v5.0 -ENV PATH /opt/pihole:${PATH} - -LABEL image="pihole/pihole:v5.0_arm64" -LABEL maintainer="adam@diginc.us" -LABEL url="https://www.github.com/pi-hole/docker-pi-hole" - -HEALTHCHECK CMD dig +norecurse +retry=0 @127.0.0.1 pi.hole || exit 1 - -SHELL ["/bin/bash", "-c"] \ No newline at end of file diff --git a/Dockerfile_armel b/Dockerfile_armel deleted file mode 100644 index dc35b3a..0000000 --- a/Dockerfile_armel +++ /dev/null @@ -1,49 +0,0 @@ -FROM multiarch/debian-debootstrap:armel-stretch-slim - -ENV ARCH armel -ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-arm.tar.gz - -COPY install.sh /usr/local/bin/install.sh -COPY VERSION /etc/docker-pi-hole-version -ENV PIHOLE_INSTALL /root/ph_install.sh - -RUN bash -ex install.sh 2>&1 && \ - rm -rf /var/cache/apt/archives /var/lib/apt/lists/* - -ENTRYPOINT [ "/s6-init" ] - -ADD s6/debian-root / -COPY s6/service /usr/local/bin/service - -# php config start passes special ENVs into -ENV PHP_ENV_CONFIG '/etc/lighttpd/conf-enabled/15-fastcgi-php.conf' -ENV PHP_ERROR_LOG '/var/log/lighttpd/error.log' -COPY ./start.sh / -COPY ./bash_functions.sh / - -# IPv6 disable flag for networks/devices that do not support it -ENV IPv6 True - -EXPOSE 53 53/udp -EXPOSE 67/udp -EXPOSE 80 -EXPOSE 443 - -ENV S6_LOGGING 0 -ENV S6_KEEP_ENV 1 -ENV S6_BEHAVIOUR_IF_STAGE2_FAILS 2 - -ENV ServerIP 0.0.0.0 -ENV FTL_CMD no-daemon -ENV DNSMASQ_USER root - -ENV VERSION v5.0 -ENV PATH /opt/pihole:${PATH} - -LABEL image="pihole/pihole:v5.0_armel" -LABEL maintainer="adam@diginc.us" -LABEL url="https://www.github.com/pi-hole/docker-pi-hole" - -HEALTHCHECK CMD dig +norecurse +retry=0 @127.0.0.1 pi.hole || exit 1 - -SHELL ["/bin/bash", "-c"] \ No newline at end of file diff --git a/Dockerfile_armhf b/Dockerfile_armhf deleted file mode 100644 index 1862462..0000000 --- a/Dockerfile_armhf +++ /dev/null @@ -1,49 +0,0 @@ -FROM multiarch/debian-debootstrap:armhf-stretch-slim - -ENV ARCH armhf -ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-arm.tar.gz - -COPY install.sh /usr/local/bin/install.sh -COPY VERSION /etc/docker-pi-hole-version -ENV PIHOLE_INSTALL /root/ph_install.sh - -RUN bash -ex install.sh 2>&1 && \ - rm -rf /var/cache/apt/archives /var/lib/apt/lists/* - -ENTRYPOINT [ "/s6-init" ] - -ADD s6/debian-root / -COPY s6/service /usr/local/bin/service - -# php config start passes special ENVs into -ENV PHP_ENV_CONFIG '/etc/lighttpd/conf-enabled/15-fastcgi-php.conf' -ENV PHP_ERROR_LOG '/var/log/lighttpd/error.log' -COPY ./start.sh / -COPY ./bash_functions.sh / - -# IPv6 disable flag for networks/devices that do not support it -ENV IPv6 True - -EXPOSE 53 53/udp -EXPOSE 67/udp -EXPOSE 80 -EXPOSE 443 - -ENV S6_LOGGING 0 -ENV S6_KEEP_ENV 1 -ENV S6_BEHAVIOUR_IF_STAGE2_FAILS 2 - -ENV ServerIP 0.0.0.0 -ENV FTL_CMD no-daemon -ENV DNSMASQ_USER root - -ENV VERSION v5.0 -ENV PATH /opt/pihole:${PATH} - -LABEL image="pihole/pihole:v5.0_armhf" -LABEL maintainer="adam@diginc.us" -LABEL url="https://www.github.com/pi-hole/docker-pi-hole" - -HEALTHCHECK CMD dig +norecurse +retry=0 @127.0.0.1 pi.hole || exit 1 - -SHELL ["/bin/bash", "-c"] \ No newline at end of file diff --git a/Dockerfile_build b/Dockerfile_build index 550a050..5327d8d 100644 --- a/Dockerfile_build +++ b/Dockerfile_build @@ -1,12 +1,16 @@ -FROM docker:latest +FROM python:buster + +# Only works for docker CLIENT (bind mounted socket) +COPY --from=docker:18.09.3 /usr/local/bin/docker /usr/local/bin/ # Based on https://github.com/Ilhicas/alpine-pipenv ARG packages -RUN apk --update add python3 python3-dev curl gcc make \ - musl-dev libffi-dev openssl-dev ${packages} \ - && rm -rf /var/cache/apk/* \ +RUN apt-get update && \ + apt-get install -y python3-dev curl gcc make \ + libffi-dev libssl-dev ${packages} \ && pip3 install -U pip pipenv - +RUN curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && \ + chmod +x /usr/local/bin/docker-compose # -v "$(pwd):/$(pwd)" -w "$(pwd)" to prevent nested docker path confusion COPY ./Dockerfile.sh /usr/local/bin/ @@ -14,7 +18,7 @@ COPY Pipfile* /root/ WORKDIR /root RUN pipenv install --system \ - && sed -i 's|/bin/sh|/bin/bash|g' /usr/lib/python3.8/site-packages/testinfra/backend/docker.py + && sed -i 's|/bin/sh|/bin/bash|g' /usr/local/lib/python3.8/site-packages/testinfra/backend/docker.py RUN echo "set -ex && Dockerfile.sh && \$@" > /usr/local/bin/entrypoint.sh diff --git a/Pipfile.lock b/Pipfile.lock index d6cfad0..80ca574 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -324,13 +324,16 @@ "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", @@ -347,7 +350,9 @@ "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", - "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", + "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be" ], "index": "pypi", "version": "==1.1.1" @@ -363,10 +368,10 @@ }, "packaging": { "hashes": [ - "sha256:aec3fdbb8bc9e4bb65f0634b9f551ced63983a529d6a8931817d52fdd0816ddb", - "sha256:fe1d8331dfa7cc0a883b49d75fc76380b2ab2734b220fbb87d774e4fd4b851f8" + "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", + "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" ], - "version": "==20.0" + "version": "==20.4" }, "pathlib2": { "hashes": [ diff --git a/README.md b/README.md index c756752..1751c4a 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,8 @@ If you're using a Red Hat based distribution with an SELinux Enforcing policy ad Volumes are recommended for persisting data across container re-creations for updating images. The IP lookup variables may not work for everyone, please review their values and hard code IP and IPv6 if necessary. +You can customize where to store persistent data by setting the `PIHOLE_BASE` environment variable when invoking `docker_run.sh` (e.g. `PIHOLE_BASE=/opt/pihole-storage ./docker_run.sh`). If `PIHOLE_BASE` is not set, files are stored in your current directory when you invoke the script. + Port 443 is to provide a sinkhole for ads that use SSL. If only port 80 is used, then blocked HTTPS queries will fail to connect to port 443 and may cause long loading times. Rejecting 443 on your firewall can also serve this same purpose. Ubuntu firewall example: `sudo ufw reject https` **Automatic Ad List Updates** - since the 3.0+ release, `cron` is baked into the container and will grab the newest versions of your lists and flush your logs. **Set your TZ** environment variable to make sure the midnight log rotation syncs up with your timezone's midnight. @@ -95,25 +97,28 @@ There are other environment variables if you want to customize various things in | Docker Environment Var. | Description | | ----------------------- | ----------- | +| `ADMIN_EMAIL: `
*Optional Default: ''* | Set an administrative contact address for the Block Page | `TZ: `
**Recommended** *Default: UTC* | Set your [timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) to make sure logs rotate at local midnight instead of at UTC midnight. | `WEBPASSWORD: `
**Recommended** *Default: random* | http://pi.hole/admin password. Run `docker logs pihole \| grep random` to find your random pass. | `DNS1: `
*Optional* *Default: 8.8.8.8* | Primary upstream DNS provider, default is google DNS | `DNS2: `
*Optional* *Default: 8.8.4.4* | Secondary upstream DNS provider, default is google DNS, `no` if only one DNS should used -| `DNSSEC: `
*Optional* *Default: false* | Enable DNSSEC support -| `DNS_BOGUS_PRIV: `
*Optional* *Default: true* | Enable forwarding of reverse lookups for private ranges -| `DNS_FQDN_REQUIRED: `
*Optional* *Default: true* | Never forward non-FQDNs -| `CONDITIONAL_FORWARDING: `
*Optional* *Default: False* | Enable DNS conditional forwarding for device name resolution +| `DNSSEC: <"true"\|"false">`
*Optional* *Default: "false"* | Enable DNSSEC support +| `DNS_BOGUS_PRIV: <"true"\|"false">`
*Optional* *Default: "true"* | Enable forwarding of reverse lookups for private ranges +| `DNS_FQDN_REQUIRED: <"true"\|"false">`
*Optional* *Default: true* | Never forward non-FQDNs +| `CONDITIONAL_FORWARDING: <"true"\|"false">`
*Optional* *Default: "false"* | Enable DNS conditional forwarding for device name resolution | `CONDITIONAL_FORWARDING_IP: `
*Optional* | If conditional forwarding is enabled, set the IP of the local network router | `CONDITIONAL_FORWARDING_DOMAIN: `
*Optional* | If conditional forwarding is enabled, set the domain of the local network router | `CONDITIONAL_FORWARDING_REVERSE: `
*Optional* | If conditional forwarding is enabled, set the reverse DNS of the local network router (e.g. `0.168.192.in-addr.arpa`) | `ServerIP: `
**Recommended** | **--net=host mode requires** Set to your server's LAN IP, used by web block modes and lighttpd bind address | `ServerIPv6: `
*Required if using IPv6* | **If you have a v6 network** set to your server's LAN IPv6 to block IPv6 ads fully | `VIRTUAL_HOST: `
*Optional* *Default: $ServerIP* | What your web server 'virtual host' is, accessing admin through this Hostname/IP allows you to make changes to the whitelist / blacklists in addition to the default 'http://pi.hole/admin/' address -| `IPv6: `
*Optional* *Default: True* | For unraid compatibility, strips out all the IPv6 configuration from DNS/Web services when false. +| `IPv6: <"true"\|"false">`
*Optional* *Default: "true"* | For unraid compatibility, strips out all the IPv6 configuration from DNS/Web services when false. | `INTERFACE: `
*Advanced/Optional* | The default works fine with our basic example docker run commands. If you're trying to use DHCP with `--net host` mode then you may have to customize this or DNSMASQ_LISTENING. | `DNSMASQ_LISTENING: `
*Advanced/Optional* | `local` listens on all local subnets, `all` permits listening on internet origin subnets in addition to local. | `WEB_PORT: `
*Advanced/Optional* | **This will break the 'webpage blocked' functionality of Pi-hole** however it may help advanced setups like those running synology or `--net=host` docker argument. This guide explains how to restore webpage blocked functionality using a linux router DNAT rule: [Alternative Synology installation method](https://discourse.pi-hole.net/t/alternative-synology-installation-method/5454?u=diginc) | `DNSMASQ_USER: `
*Experimental Default: root* | Allows running FTLDNS as non-root. +| `TEMPERATUREUNIT`:
*Optional Default: c* | Set preferred temperature unit to `c`: Celsius, `k`: Kelvin, or `f` Fahrenheit units. +| `WEBUIBOXEDLAYOUT: `
*Optional Default: boxed* | Use boxed layout (helpful when working on large screens) To use these env vars in docker run format style them like: `-e DNS1=1.1.1.1` @@ -175,7 +180,7 @@ The primary docker tags / versions are explained in the following table. [Click | tag | architecture | description | Dockerfile | | --- | ------------ | ----------- | ---------- | -| `latest` | auto detect | x86, arm, or arm64 container, docker auto detects your architecture. | [Dockerfile](https://github.com/pi-hole/docker-pi-hole/blob/master/Dockerfile_amd64) | +| `latest` | auto detect | x86, arm, or arm64 container, docker auto detects your architecture. | [Dockerfile](https://github.com/pi-hole/docker-pi-hole/blob/master/Dockerfile) | | `v4.0.0-1` | auto detect | Versioned tags, if you want to pin against a specific version, use one of these | | | `v4.0.0-1_` | based on tag | Specific architectures tags | | | `dev` | auto detect | like latest tag, but for the development branch (pushed occasionally) | | diff --git a/bash_functions.sh b/bash_functions.sh index b1d00ff..32a0d32 100644 --- a/bash_functions.sh +++ b/bash_functions.sh @@ -23,7 +23,7 @@ prepare_configs() { # Also similar to preflights for FTL https://github.com/pi-hole/pi-hole/blob/master/advanced/Templates/pihole-FTL.service chown pihole:root /etc/lighttpd chown pihole:pihole "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" "/var/log/pihole" "${regexFile}" - chmod 644 "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" + chmod 644 "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" # not sure why pihole:pihole user/group write perms are not enough for web to write...dirty fix: chmod 777 "${regexFile}" touch /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /var/log/pihole.log @@ -35,27 +35,11 @@ prepare_configs() { # Update version numbers pihole updatechecker # Re-write all of the setupVars to ensure required ones are present (like QUERY_LOGGING) - + # If the setup variable file exists, if [[ -e "${setupVars}" ]]; then - # update the variables in the file - local USERWEBPASSWORD="${WEBPASSWORD}" - . "${setupVars}" - # Stash and pop the user password to avoid setting the password to the hashed setupVar variable - WEBPASSWORD="${USERWEBPASSWORD}" - # Clean up old before re-writing the required setupVars - sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/QUERY_LOGGING/d;/INSTALL_WEB_SERVER/d;/INSTALL_WEB_INTERFACE/d;/LIGHTTPD_ENABLED/d;' "${setupVars}" + cp -f "${setupVars}" "${setupVars}.update.bak" fi - # echo the information to the user - { - echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}" - echo "IPV4_ADDRESS=${IPV4_ADDRESS}" - echo "IPV6_ADDRESS=${IPV6_ADDRESS}" - echo "QUERY_LOGGING=${QUERY_LOGGING}" - echo "INSTALL_WEB_SERVER=${INSTALL_WEB_SERVER}" - echo "INSTALL_WEB_INTERFACE=${INSTALL_WEB_INTERFACE}" - echo "LIGHTTPD_ENABLED=${LIGHTTPD_ENABLED}" - }>> "${setupVars}" } validate_env() { @@ -98,7 +82,7 @@ setup_dnsmasq_dns() { setupDNS1="${setupDNS1/PIHOLE_DNS_1=/}" setupDNS2="${setupDNS2/PIHOLE_DNS_2=/}" if [[ -n "$DNS1" && -n "$setupDNS1" ]] || \ - [[ -n "$DNS2" && -n "$setupDNS2" ]] ; then + [[ -n "$DNS2" && -n "$setupDNS2" ]] ; then echo "Docker DNS variables not used" fi echo "Existing DNS servers used (${setupDNS1:-unset} & ${setupDNS2:-unset})" @@ -149,9 +133,9 @@ setup_dnsmasq() { local dns2="$2" local interface="$3" local dnsmasq_listening_behaviour="$4" - # Coordinates + # Coordinates setup_dnsmasq_config_if_missing - setup_dnsmasq_dns "$dns1" "$dns2" + setup_dnsmasq_dns "$dns1" "$dns2" setup_dnsmasq_interface "$interface" setup_dnsmasq_listening_behaviour "$dnsmasq_listening_behaviour" setup_dnsmasq_user "${DNSMASQ_USER}" @@ -212,7 +196,7 @@ setup_dnsmasq_hostnames() { setup_lighttpd_bind() { local serverip="$1" # if using '--net=host' only bind lighttpd on $ServerIP and localhost - if grep -q "docker" /proc/net/dev ; then #docker (docker0 by default) should only be present on the host system + if grep -q "docker" /proc/net/dev && [[ $serverip != 0.0.0.0 ]]; then #docker (docker0 by default) should only be present on the host system if ! grep -q "server.bind" /etc/lighttpd/lighttpd.conf ; then # if the declaration is already there, don't add it again sed -i -E "s/server\.port\s+\=\s+([0-9]+)/server.bind\t\t = \"${serverip}\"\nserver.port\t\t = \1\n"\$SERVER"\[\"socket\"\] == \"127\.0\.0\.1:\1\" \{\}/" /etc/lighttpd/lighttpd.conf fi @@ -244,7 +228,7 @@ setup_web_port() { # Quietly exit early for empty or default if [[ -z "${1}" || "${1}" == '80' ]] ; then return ; fi - if ! echo $1 | grep -q '^[0-9][0-9]*$' ; then + if ! echo $1 | grep -q '^[0-9][0-9]*$' ; then echo "$warning - $1 is not an integer" return fi @@ -320,9 +304,8 @@ test_configs() { echo "::: All config checks passed, cleared for startup ..." } - setup_blocklists() { - local blocklists="$1" + local blocklists="$1" # Exit/return early without setting up adlists with defaults for any of the following conditions: # 1. skip_setup_blocklists env is set exit_string="(exiting ${FUNCNAME[0]} early)" @@ -360,3 +343,32 @@ setup_var_exists() { fi } +setup_temp_unit() { + local UNIT="$1" + # check if var is empty + if [[ "$UNIT" != "" ]] ; then + # check if we have valid units + if [[ "$UNIT" == "c" || "$UNIT" == "k" || $UNIT == "f" ]] ; then + pihole -a -${UNIT} + fi + fi +} + +setup_ui_layout() { + local LO=$1 + # check if var is empty + if [[ "$LO" != "" ]] ; then + # check if we have valid types boxed | traditional + if [[ "$LO" == "traditional" || "$LO" == "boxed" ]] ; then + change_setting "WEBUIBOXEDLAYOUT" "$WEBUIBOXEDLAYOUT" + fi + fi +} + +setup_admin_email() { + local EMAIL=$1 + # check if var is empty + if [[ "$EMAIL" != "" ]] ; then + pihole -a -e "$EMAIL" + fi +} diff --git a/build.yml b/build.yml new file mode 100644 index 0000000..ab78653 --- /dev/null +++ b/build.yml @@ -0,0 +1,57 @@ +# Docker Compose build file: docker-compose -f build.yml build +version: "3.7" + +x-common-args: &common-args + PIHOLE_VERSION: ${PIHOLE_VERSION} + NAME: pihole/pihole + MAINTAINER: adam@diginc.us + S6_VERSION: v1.22.1.0 + PHP_ENV_CONFIG: /etc/lighttpd/conf-enabled/15-fastcgi-php.conf + PHP_ERROR_LOG: /var/log/lighttpd/error.log + + +services: + amd64: + image: pihole:${PIHOLE_VERSION}-amd64 + build: + context: . + cache_from: + - pihole/pihole:${PIHOLE_VERSION}-amd64 + args: + <<: *common-args + PIHOLE_BASE: pihole/debian-base:latest + PIHOLE_ARCH: amd64 + S6_ARCH: amd64 + armel: + image: pihole:${PIHOLE_VERSION}-armel + build: + context: . + cache_from: + - pihole/pihole:${PIHOLE_VERSION}-armel + args: + <<: *common-args + PIHOLE_BASE: multiarch/debian-debootstrap:armel-stretch-slim + PIHOLE_ARCH: armel + S6_ARCH: arm + armhf: + image: pihole:${PIHOLE_VERSION}-armhf + build: + context: . + cache_from: + - pihole/pihole:${PIHOLE_VERSION}-armhf + args: + <<: *common-args + PIHOLE_BASE: multiarch/debian-debootstrap:armhf-stretch-slim + PIHOLE_ARCH: arm + S6_ARCH: arm + arm64: + image: pihole:${PIHOLE_VERSION}-arm64 + build: + context: . + cache_from: + - pihole/pihole:${PIHOLE_VERSION}-arm64 + args: + <<: *common-args + PIHOLE_BASE: multiarch/debian-debootstrap:arm64-stretch-slim + PIHOLE_ARCH: arm64 + S6_ARCH: aarch64 \ No newline at end of file diff --git a/circle-test.sh b/circle-test.sh index e0a8b93..38ff736 100755 --- a/circle-test.sh +++ b/circle-test.sh @@ -22,8 +22,6 @@ docker run --rm \ --env-file /tmp/env \ $enter image_pipenv -docker images - test -z "${CIRCLE_PROJECT_REPONAME}" && exit 0 # The rest is circle-ci only echo $DOCKERHUB_PASS | docker login --username=$DOCKERHUB_USER --password-stdin diff --git a/docker_run.sh b/docker_run.sh index 7ac9e4f..cc0cd6e 100755 --- a/docker_run.sh +++ b/docker_run.sh @@ -2,6 +2,9 @@ # https://github.com/pi-hole/docker-pi-hole/blob/master/README.md +PIHOLE_BASE="${PIHOLE_BASE:-$(pwd)}" +[[ -d "$PIHOLE_BASE" ]] || mkdir -p "$PIHOLE_BASE" || { echo "Couldn't create storage directory: $PIHOLE_BASE"; exit 1; } + # Note: ServerIP should be replaced with your external ip. docker run -d \ --name pihole \ @@ -9,8 +12,9 @@ docker run -d \ -p 80:80 \ -p 443:443 \ -e TZ="America/Chicago" \ - -v "$(pwd)/etc-pihole/:/etc/pihole/" \ - -v "$(pwd)/etc-dnsmasq.d/:/etc/dnsmasq.d/" \ + -v "${PIHOLE_BASE}/etc-pihole/:/etc/pihole/" \ + -v "${PIHOLE_BASE}/etc-dnsmasq.d/:/etc/dnsmasq.d/" \ + --dns=127.0.0.1 --dns=1.1.1.1 \ --restart=unless-stopped \ --hostname pi.hole \ -e VIRTUAL_HOST="pi.hole" \ diff --git a/start.sh b/start.sh index 6f8f7d8..16b8c79 100755 --- a/start.sh +++ b/start.sh @@ -5,7 +5,7 @@ export ServerIP export ServerIPv6 export PYTEST export PHP_ENV_CONFIG -export PHP_ERROR_LOG +export PHP_ERROR_LOG export HOSTNAME export WEBLOGDIR export DNS1 @@ -21,12 +21,18 @@ export CONDITIONAL_FORWARDING export CONDITIONAL_FORWARDING_IP export CONDITIONAL_FORWARDING_DOMAIN export CONDITIONAL_FORWARDING_REVERSE +export TEMPERATUREUNIT +export ADMIN_EMAIL +export WEBUIBOXEDLAYOUT export adlistFile='/etc/pihole/adlists.list' # The below functions are all contained in bash_functions.sh . /bash_functions.sh +# Ensure we have all functions available to update our configurations +. /opt/pihole/webpage.sh + # PH_TEST prevents the install from actually running (someone should rename that) PH_TEST=true . $PIHOLE_INSTALL @@ -44,6 +50,12 @@ load_web_password_secret generate_password validate_env || exit 1 prepare_configs +change_setting "PIHOLE_INTERFACE" "$PIHOLE_INTERFACE" +change_setting "IPV4_ADDRESS" "$IPV4_ADDRESS" +change_setting "QUERY_LOGGING" "$QUERY_LOGGING" +change_setting "INSTALL_WEB_SERVER" "$INSTALL_WEB_SERVER" +change_setting "INSTALL_WEB_INTERFACE" "$INSTALL_WEB_INTERFACE" +change_setting "LIGHTTPD_ENABLED" "$LIGHTTPD_ENABLED" change_setting "IPV4_ADDRESS" "$ServerIP" change_setting "IPV6_ADDRESS" "$ServerIPv6" change_setting "DNS_BOGUS_PRIV" "$DNS_BOGUS_PRIV" @@ -55,6 +67,9 @@ change_setting "CONDITIONAL_FORWARDING_DOMAIN" "$CONDITIONAL_FORWARDING_DOMAIN" change_setting "CONDITIONAL_FORWARDING_REVERSE" "$CONDITIONAL_FORWARDING_REVERSE" setup_web_port "$WEB_PORT" setup_web_password "$WEBPASSWORD" +setup_temp_unit "$TEMPERATUREUNIT" +setup_ui_layout "$WEBUIBOXEDLAYOUT" +setup_admin_email "$ADMIN_EMAIL" setup_dnsmasq "$DNS1" "$DNS2" "$INTERFACE" "$DNSMASQ_LISTENING_BEHAVIOUR" setup_php_env setup_dnsmasq_hostnames "$ServerIP" "$ServerIPv6" "$HOSTNAME" diff --git a/test/conftest.py b/test/conftest.py index 12cdb99..161fd3b 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -81,7 +81,7 @@ def version(): @pytest.fixture() def tag(version, arch): - return '{}_{}'.format(version, arch) + return '{}-{}'.format(version, arch) @pytest.fixture def webserver(tag):