Compare commits
215 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc8e746546 | ||
|
|
96647b1269 | ||
|
|
41b1d04100 | ||
|
|
625defbf11 | ||
|
|
f8d37693ed | ||
|
|
65a1ac7f1e | ||
|
|
999f02b598 | ||
|
|
cb0fffa26f | ||
|
|
b5c7ab0522 | ||
|
|
22ea5e77b4 | ||
|
|
7cbb8d1434 | ||
|
|
b7e813cadc | ||
|
|
797a9213e4 | ||
|
|
c56385ad49 | ||
|
|
5cc28d769a | ||
|
|
20e8ce208c | ||
|
|
119999be71 | ||
|
|
4dc3c7e2dc | ||
|
|
5ee2cc947c | ||
|
|
1c063a6619 | ||
|
|
df63b3ee12 | ||
|
|
3c135774d3 | ||
|
|
c8d7abed1b | ||
|
|
a257be134d | ||
|
|
7b06920cd0 | ||
|
|
1f49971046 | ||
|
|
a4296416b0 | ||
|
|
65ecba6705 | ||
|
|
80d5b9dbc1 | ||
|
|
6e15abd002 | ||
|
|
5b1e992d66 | ||
|
|
805c5ccdb7 | ||
|
|
73f05e6d35 | ||
|
|
187c1d3f29 | ||
|
|
ae16d39016 | ||
|
|
e7ae12a94c | ||
|
|
e7f5433d98 | ||
|
|
c7d775a82a | ||
|
|
468470b7b5 | ||
|
|
0e7ab463fa | ||
|
|
520669a6b9 | ||
|
|
478b98c503 | ||
|
|
4bd9def800 | ||
|
|
20e8843a97 | ||
|
|
8fd2a02d52 | ||
|
|
9a680e95ac | ||
|
|
43aa8f45d8 | ||
|
|
ec8f441df3 | ||
|
|
c17cd37eca | ||
|
|
e56b5eda00 | ||
|
|
bb3885a15b | ||
|
|
e14b742649 | ||
|
|
f770df9504 | ||
|
|
89a556f858 | ||
|
|
bd925db871 | ||
|
|
10f948fca0 | ||
|
|
70acf54c2c | ||
|
|
1b96d7e760 | ||
|
|
3afc1d43ff | ||
|
|
6364640d4f | ||
|
|
1a30cb7e7b | ||
|
|
3171feef4c | ||
|
|
cd6f2790bd | ||
|
|
3877a171da | ||
|
|
ad6b4be403 | ||
|
|
041ef30d42 | ||
|
|
d45bccf9b4 | ||
|
|
3a4cf40473 | ||
|
|
002c8349d2 | ||
|
|
4ff219b5b8 | ||
|
|
60bd77f586 | ||
|
|
3bf7992e52 | ||
|
|
6eabd15cd1 | ||
|
|
af1816b7e5 | ||
|
|
8e2889ba56 | ||
|
|
d12a876f8f | ||
|
|
a050918a5f | ||
|
|
e10a200d70 | ||
|
|
17b3781dd4 | ||
|
|
9948388656 | ||
|
|
aaad7c8981 | ||
|
|
225332b977 | ||
|
|
a51261ae16 | ||
|
|
6813831883 | ||
|
|
3295474f79 | ||
|
|
45a196d9c4 | ||
|
|
76d6a67d48 | ||
|
|
fed2f7f4d3 | ||
|
|
024571b123 | ||
|
|
b08ce657fc | ||
|
|
84b03e0a17 | ||
|
|
bc54868f80 | ||
|
|
cf8cc9a4d0 | ||
|
|
d8fdd4bacc | ||
|
|
9bb4a2daf5 | ||
|
|
d4c42b8c13 | ||
|
|
89b6b2a75e | ||
|
|
156679c925 | ||
|
|
c0ba5ad7ca | ||
|
|
bcbb509842 | ||
|
|
0ecc0c4e67 | ||
|
|
d57159e9ea | ||
|
|
9d5cc46f30 | ||
|
|
1c598d3078 | ||
|
|
d83a950a23 | ||
|
|
11ce14d732 | ||
|
|
300b2e6901 | ||
|
|
53f766876e | ||
|
|
cdcc882d28 | ||
|
|
f5e83456dd | ||
|
|
d5db4f4621 | ||
|
|
492b6f6402 | ||
|
|
b140aeb79d | ||
|
|
4f93823711 | ||
|
|
1f176da47d | ||
|
|
45f491ff7b | ||
|
|
a9b41c7099 | ||
|
|
94f76397fd | ||
|
|
795560f1af | ||
|
|
c42509541d | ||
|
|
91a483614b | ||
|
|
e430d5a5e5 | ||
|
|
91481efe48 | ||
|
|
c9165850c3 | ||
|
|
9b7e3998d6 | ||
|
|
39a8802c74 | ||
|
|
b517ecfe6c | ||
|
|
7664a1252f | ||
|
|
47a7419d13 | ||
|
|
75fc2771d1 | ||
|
|
26733330d5 | ||
|
|
4ab2a96552 | ||
|
|
62ddf72d15 | ||
|
|
16127f48fc | ||
|
|
22ab253efd | ||
|
|
fd4678de68 | ||
|
|
9427357489 | ||
|
|
ad727ec17b | ||
|
|
b0fac9576e | ||
|
|
ed9568c5ac | ||
|
|
e52572d034 | ||
|
|
a68629b2cf | ||
|
|
7758a3962c | ||
|
|
2cf778f423 | ||
|
|
feee2a2356 | ||
|
|
84eef29f6d | ||
|
|
d30f024db1 | ||
|
|
ec9f513beb | ||
|
|
8a88a67403 | ||
|
|
cb3a6e1ac8 | ||
|
|
e58aa2e69e | ||
|
|
3c96d9e556 | ||
|
|
cd71628992 | ||
|
|
efb03982e5 | ||
|
|
0614f4275d | ||
|
|
813c725636 | ||
|
|
0eefb76fca | ||
|
|
33c8b1dd18 | ||
|
|
22c9e81803 | ||
|
|
9d49414fe6 | ||
|
|
3bcdd27cb9 | ||
|
|
c4dc16685a | ||
|
|
c4986cfeff | ||
|
|
130f50c769 | ||
|
|
b33ea3b77f | ||
|
|
e5a56222a3 | ||
|
|
615af98eab | ||
|
|
b12f91983e | ||
|
|
9ed6bf153c | ||
|
|
af616f6afc | ||
|
|
9318064061 | ||
|
|
d9fa9b1016 | ||
|
|
d47442ee6e | ||
|
|
ea0a3221de | ||
|
|
7c6c48e133 | ||
|
|
988e17be7a | ||
|
|
aab0b3f3cb | ||
|
|
6ff1d21f7b | ||
|
|
563fcbc97b | ||
|
|
00a8764689 | ||
|
|
f17dfd0c03 | ||
|
|
eb7b0a1fd7 | ||
|
|
e484f79e85 | ||
|
|
fd4e123ca2 | ||
|
|
50fee7d832 | ||
|
|
800972856e | ||
|
|
5b85323494 | ||
|
|
ecc898af31 | ||
|
|
c4dfd83c27 | ||
|
|
94c90d9b91 | ||
|
|
bcfcc85ef3 | ||
|
|
45c25dce2f | ||
|
|
83ef38c8f7 | ||
|
|
b778a1dd4d | ||
|
|
92a65df3bb | ||
|
|
ac6e1cdc5a | ||
|
|
8886784b2e | ||
|
|
dded3945f5 | ||
|
|
376af2195d | ||
|
|
fe34280393 | ||
|
|
65f720deeb | ||
|
|
7c85ac8d32 | ||
|
|
95dae59418 | ||
|
|
825248fb86 | ||
|
|
fda63c8f82 | ||
|
|
e18d0618d9 | ||
|
|
be87bcb6a3 | ||
|
|
d8c72ab175 | ||
|
|
8cfa95f371 | ||
|
|
43982b6c90 | ||
|
|
ad884868db | ||
|
|
30b878f3da | ||
|
|
b372f0101d | ||
|
|
8326771570 | ||
|
|
70988c2f10 |
52
.github/ISSUE_TEMPLATE.md
vendored
Normal file
52
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<!-- Provide a general summary of the issue in the Title above -->
|
||||
<!-- Note: these are comments that don't show up in the actual issue, no need to delete them as you fill out the template -->
|
||||
|
||||
This is a... <!-- To choose ONE, put an [x] in the box that applies -->
|
||||
|
||||
- [ ] Request for a new or modified feature
|
||||
- [ ] Issue trying to run the docker image
|
||||
- [ ] Issue trying to build / test / develop the docker image
|
||||
|
||||
## Description
|
||||
<!-- Provide a more detailed introduction to the issue or feature -->
|
||||
|
||||
## Expected Behavior
|
||||
<!-- Tell us what should happen -->
|
||||
|
||||
## Actual Behavior
|
||||
<!-- Tell us what happens instead -->
|
||||
|
||||
## Possible Fix
|
||||
<!-- Not obligatory, but suggest a fix or reason for the bug -->
|
||||
|
||||
## Steps to Reproduce and debugging done
|
||||
<!-- Reproduce this bug. Include code to reproduce, if relevant -->
|
||||
e.g. your docker run command, pages to visit, CLI commands you ran
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
## Debug steps I have tried
|
||||
<!-- Please attempt these debug steps to see if it helps you resolve or understand your own issue -->
|
||||
|
||||
- [ ] I have tried destroying my container instance, pulling the newest image version, and re-creating a new container
|
||||
- [ ] I have tried running the nearly stock `docker run` example in the readme (removing any customizations I added)
|
||||
- [ ] I have tried running without my volume data mounts to eliminate volumes as the cause
|
||||
- [ ] I have searched this repository for existing issues and pull requests that look similar <!-- Add links below! -->
|
||||
|
||||
<!-- Note: If volumes are your issue, I strongly recommend just starting with fresh volume data -->
|
||||
|
||||
<!-- Add any other debugging steps you've taken that maybe relevant information -->
|
||||
|
||||
## Context and extra information
|
||||
<!-- How has this bug affected you? What were you trying to accomplish? -->
|
||||
<!-- Got any other relevant links to similar issues? -->
|
||||
|
||||
## Your Environment
|
||||
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||
* Docker Host Operating System and OS Version:
|
||||
* Docker Version:
|
||||
* Hardware architecture: <!-- ARMv7, x86 -->
|
||||
|
||||
|
||||
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<!--- Provide a general summary of your changes in the Title above -->
|
||||
|
||||
## Description
|
||||
<!--- Describe your changes in detail -->
|
||||
|
||||
## Motivation and Context
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
## How Has This Been Tested?
|
||||
<!--- Please describe in detail how you tested your changes. -->
|
||||
<!--- Include details of your testing environment, tests ran to see how -->
|
||||
<!--- your change affects other areas of the code, etc. -->
|
||||
|
||||
## Types of changes
|
||||
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
|
||||
## Checklist:
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
- [ ] My code follows the code style of this project.
|
||||
- [ ] My change requires a change to the documentation.
|
||||
- [ ] I have updated the documentation accordingly.
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,6 +2,9 @@
|
||||
*.pyc
|
||||
.cache
|
||||
__pycache__
|
||||
.tox
|
||||
.eggs
|
||||
UNKNOWN.egg-info
|
||||
|
||||
# WIP/test stuff
|
||||
doco.yml
|
||||
|
||||
16
.travis.yml
16
.travis.yml
@@ -2,13 +2,23 @@ sudo: required
|
||||
services:
|
||||
- docker
|
||||
language: python
|
||||
env:
|
||||
global:
|
||||
- QEMU_VER=v2.9.1
|
||||
matrix:
|
||||
- ARCH=amd64
|
||||
- ARCH=armhf
|
||||
- ARCH=aarch64
|
||||
python:
|
||||
- "2.7"
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
|
||||
script:
|
||||
script:
|
||||
# prepare qemu
|
||||
- docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
# generate and build dockerfile
|
||||
- ./Dockerfile.py --arch=${ARCH} -v
|
||||
- docker images
|
||||
# run docker build & tests
|
||||
- py.test -vv test/
|
||||
# 2 parallel max b/c race condition with docker fixture (I think?)
|
||||
- py.test -vv -n 2 -k "${ARCH}" ./test/
|
||||
|
||||
10
CONTRIBUTING.md
Normal file
10
CONTRIBUTING.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Pull Request Guidelines
|
||||
|
||||
Please review the following before opening a pull request (PR) to help your PR go smoothly:
|
||||
|
||||
* Code changes go to the `dev` branch first
|
||||
* To ensure proper testing and quality control, target any code change pull requests against `dev` branch.
|
||||
|
||||
* Make sure the tests pass
|
||||
* Take a look at [TESTING.md](TESTING.md) to see how to run tests locally so you do not have to push all your code to a PR and have travis-ci run it.
|
||||
* Your tests will probably run faster locally and you get a faster feedback loop.
|
||||
128
Dockerfile.py
Executable file
128
Dockerfile.py
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
""" Dockerfile.py - generates and build dockerfiles
|
||||
|
||||
Usage:
|
||||
Dockerfile.py [--arch=<arch> ...] [--skip=<arch> ...] [-v] [--no-build | --no-generate] [--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
|
||||
--arch=<arch> What Architecture(s) to build [default: amd64 armel armhf aarch64]
|
||||
--skip=<arch> What Architectures(s) to skip [default: None]
|
||||
-v Print docker's command output [default: False]
|
||||
|
||||
Examples:
|
||||
"""
|
||||
|
||||
from docopt import docopt
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from docopt import docopt
|
||||
import os
|
||||
import testinfra
|
||||
|
||||
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
base_vars = {
|
||||
'name': 'pihole/pihole',
|
||||
'maintainer' : 'adam@diginc.us',
|
||||
's6_version' : 'v1.21.4.0',
|
||||
}
|
||||
|
||||
os_base_vars = {
|
||||
'php_env_config': '/etc/lighttpd/conf-enabled/15-fastcgi-php.conf',
|
||||
'php_error_log': '/var/log/lighttpd/error.log'
|
||||
}
|
||||
|
||||
images = {
|
||||
'v4.0': [
|
||||
{
|
||||
'base': 'debian:stretch',
|
||||
'arch': 'amd64'
|
||||
},
|
||||
{
|
||||
'base': 'multiarch/debian-debootstrap:armel-stretch-slim',
|
||||
'arch': 'armel'
|
||||
},
|
||||
{
|
||||
'base': 'multiarch/debian-debootstrap:armhf-stretch-slim',
|
||||
'arch': 'armhf'
|
||||
},
|
||||
{
|
||||
'base': 'multiarch/debian-debootstrap:arm64-stretch-slim',
|
||||
'arch': 'aarch64'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
def generate_dockerfiles(args):
|
||||
if args['--no-generate']:
|
||||
print " ::: Skipping Dockerfile generation"
|
||||
return
|
||||
|
||||
for version, archs in images.iteritems():
|
||||
for image in archs:
|
||||
if image['arch'] not in args['--arch'] or image['arch'] in args['--skip']:
|
||||
return
|
||||
s6arch = image['arch']
|
||||
if image['arch'] == 'armel':
|
||||
s6arch = 'arm'
|
||||
merged_data = dict(
|
||||
{ 'version': version }.items() +
|
||||
base_vars.items() +
|
||||
os_base_vars.items() +
|
||||
image.items() +
|
||||
{ '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']:
|
||||
print " ::: Skipping Dockerfile building"
|
||||
return
|
||||
|
||||
for arch in args['--arch']:
|
||||
# TODO: include from external .py that can be shared with Dockerfile.py / Tests / deploy scripts '''
|
||||
build('pihole', 'v4.0', arch, args)
|
||||
|
||||
|
||||
def build(docker_repo, version, arch, args):
|
||||
run_local = testinfra.get_backend(
|
||||
"local://"
|
||||
).get_module("Command").run
|
||||
|
||||
dockerfile = 'Dockerfile_{}'.format(arch)
|
||||
repo_tag = '{}:{}_{}'.format(docker_repo, version, arch)
|
||||
cached_image = '{}/{}'.format('pihole', repo_tag)
|
||||
no_cache = ''
|
||||
if args['--no-cache']:
|
||||
no_cache = '--no-cache'
|
||||
build_command = 'docker build {no_cache} --pull --cache-from="{cache},{create_tag}" -f {dockerfile} -t {create_tag} .'\
|
||||
.format(no_cache=no_cache, cache=cached_image, dockerfile=dockerfile, create_tag=repo_tag)
|
||||
print " ::: Building {} into {}".format(dockerfile, repo_tag)
|
||||
if args['-v']:
|
||||
print build_command, '\n'
|
||||
build_result = run_local(build_command)
|
||||
if args['-v']:
|
||||
print build_result.stdout
|
||||
print build_result.stderr
|
||||
if build_result.rc != 0:
|
||||
print " ::: Building {} encountered an error".format(dockerfile)
|
||||
print build_result.stderr
|
||||
assert build_result.rc == 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = docopt(__doc__, version='Dockerfile 1.0')
|
||||
# print args
|
||||
|
||||
generate_dockerfiles(args)
|
||||
build_dockerfiles(args)
|
||||
@@ -1,61 +1,22 @@
|
||||
FROM {{ pihole.base }}
|
||||
|
||||
LABEL image="{{ pihole.name }}:{{ pihole.os }}_{{ pihole.arch }}"
|
||||
LABEL maintainer="{{ pihole.maintainer }}"
|
||||
LABEL url="https://www.github.com/diginc/docker-pi-hole"
|
||||
|
||||
ENV TAG {{ pihole.os }}
|
||||
ENV ARCH {{ pihole.arch }}
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
|
||||
COPY install.sh /usr/local/bin/docker-install.sh
|
||||
ENV setupVars /etc/pihole/setupVars.conf
|
||||
ENV PIHOLE_INSTALL /tmp/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/{{ pihole.s6_version }}/s6-overlay-{{ pihole.arch }}.tar.gz
|
||||
ENV PIHOLE_INSTALL /root/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/{{ pihole.s6_version }}/s6-overlay-{{ pihole.s6arch }}.tar.gz
|
||||
|
||||
{% if pihole.os == 'alpine' %}
|
||||
RUN apk upgrade --update && \
|
||||
apk add bind-tools wget curl bash libcap && \
|
||||
{% else %}
|
||||
RUN apt-get update && \
|
||||
apt-get install -y wget curl net-tools cron && \
|
||||
{% endif %}
|
||||
curl -L -s $S6OVERLAY_RELEASE \
|
||||
| tar xvzf - -C / && \
|
||||
docker-install.sh && \
|
||||
{% if pihole.os == 'alpine' %}
|
||||
rm -rf /var/cache/apk/*
|
||||
{% else %}
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
|
||||
{% endif %}
|
||||
apt-get install -y curl procps && \
|
||||
curl -L -s $S6OVERLAY_RELEASE | tar xvzf - -C / && \
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/* && \
|
||||
mv /init /s6-init
|
||||
|
||||
ENTRYPOINT [ "/init" ]
|
||||
RUN apt-get update && bash -ex docker-install.sh 2>&1
|
||||
|
||||
ADD s6/{{ pihole.os }}-root /
|
||||
ENTRYPOINT [ "/s6-init" ]
|
||||
|
||||
ADD s6/debian-root /
|
||||
COPY s6/service /usr/local/bin/service
|
||||
|
||||
{% if pihole.os == 'alpine' %}
|
||||
# Things installer did and fix alpine+nginx differences
|
||||
ENV WEBLOGDIR /var/log/nginx
|
||||
ENV PHP_CONFIG '/etc/php5/php-fpm.conf'
|
||||
RUN mkdir -p /etc/pihole/ && \
|
||||
mkdir -p /var/www/html/pihole && \
|
||||
mkdir -p /var/www/html/admin/ && \
|
||||
chown nginx:nginx /var/www/html && \
|
||||
touch ${WEBLOGDIR}/access.log ${WEBLOGDIR}/error.log && \
|
||||
chown -R nginx:nginx ${WEBLOGDIR} && \
|
||||
sed -i 's|^user\s*=.*$|user = nginx|' $PHP_CONFIG && \
|
||||
sed -i '/^;pid/ s|^;||' $PHP_CONFIG && \
|
||||
chmod 775 /var/www/html && \
|
||||
touch /var/log/pihole.log && \
|
||||
chmod 644 /var/log/pihole.log && \
|
||||
chown dnsmasq:root /var/log/pihole.log && \
|
||||
sed -i "s/@INT@/eth0/" /etc/dnsmasq.d/01-pihole.conf && \
|
||||
setcap CAP_NET_BIND_SERVICE=+eip `which dnsmasq` && \
|
||||
cp -f /usr/bin/list.sh /opt/pihole/list.sh && \
|
||||
echo 'Done!'
|
||||
{% endif %}
|
||||
|
||||
# php config start passes special ENVs into
|
||||
ENV PHP_ENV_CONFIG '{{ pihole.php_env_config }}'
|
||||
ENV PHP_ERROR_LOG '{{ pihole.php_error_log }}'
|
||||
@@ -63,16 +24,26 @@ COPY ./start.sh /
|
||||
COPY ./bash_functions.sh /
|
||||
|
||||
# IPv6 disable flag for networks/devices that do not support it
|
||||
{% if pihole.os == 'debian' %}
|
||||
# not fully supported in debian yet
|
||||
{% endif %}
|
||||
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 FTL_CMD no-daemon
|
||||
|
||||
ENV VERSION {{ pihole.version }}
|
||||
ENV ARCH {{ pihole.arch }}
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
|
||||
LABEL image="{{ pihole.name }}:{{ pihole.version }}_{{ pihole.arch }}"
|
||||
LABEL maintainer="{{ pihole.maintainer }}"
|
||||
LABEL url="https://www.github.com/pi-hole/docker-pi-hole"
|
||||
|
||||
HEALTHCHECK CMD dig @127.0.0.1 pi.hole || exit 1
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
import os
|
||||
|
||||
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
base_vars = {
|
||||
'name': 'diginc/pi-hole',
|
||||
'maintainer' : 'adam@diginc.us',
|
||||
's6_version' : 'v1.20.0.0',
|
||||
}
|
||||
|
||||
os_base_vars = {
|
||||
'debian': {
|
||||
'php_env_config': '/etc/lighttpd/conf-enabled/15-fastcgi-php.conf',
|
||||
'php_error_log': '/var/log/lighttpd/error.log'
|
||||
},
|
||||
'alpine': {
|
||||
'php_env_config': '/etc/php5/fpm.d/envs.conf',
|
||||
'php_error_log': '/var/log/nginx/error.log'
|
||||
}
|
||||
}
|
||||
|
||||
images = {
|
||||
'debian': [
|
||||
{
|
||||
'base': 'debian:jessie',
|
||||
'arch': 'amd64'
|
||||
},
|
||||
{
|
||||
'base': 'multiarch/debian-debootstrap:armhf-jessie-slim',
|
||||
'arch': 'armhf'
|
||||
},
|
||||
{
|
||||
'base': 'multiarch/debian-debootstrap:arm64-jessie-slim',
|
||||
'arch': 'aarch64'
|
||||
}
|
||||
],
|
||||
'alpine': [
|
||||
{
|
||||
'base': 'alpine:edge',
|
||||
'arch': 'amd64'
|
||||
},
|
||||
{
|
||||
'base': 'multiarch/alpine:armhf-edge',
|
||||
'arch': 'armhf'
|
||||
},
|
||||
{
|
||||
'base': 'multiarch/alpine:aarch64-edge',
|
||||
'arch': 'aarch64'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
def generate_dockerfiles():
|
||||
for os, archs in images.iteritems():
|
||||
for image in archs:
|
||||
merged_data = dict(
|
||||
{ 'os': os }.items() +
|
||||
base_vars.items() +
|
||||
os_base_vars[os].items() +
|
||||
image.items()
|
||||
)
|
||||
j2_env = Environment(loader=FileSystemLoader(THIS_DIR),
|
||||
trim_blocks=True)
|
||||
template = j2_env.get_template('Dockerfile.template')
|
||||
|
||||
dockerfile = 'Dockerfile_{}_{}'.format(os, image['arch'])
|
||||
with open(dockerfile, 'w') as f:
|
||||
f.write(template.render(pihole=merged_data))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
generate_dockerfiles()
|
||||
@@ -1,31 +1,22 @@
|
||||
FROM multiarch/debian-debootstrap:arm64-jessie-slim
|
||||
|
||||
LABEL image="diginc/pi-hole:debian_aarch64"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/diginc/docker-pi-hole"
|
||||
|
||||
ENV TAG debian
|
||||
ENV ARCH aarch64
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
FROM multiarch/debian-debootstrap:arm64-stretch-slim
|
||||
|
||||
COPY install.sh /usr/local/bin/docker-install.sh
|
||||
ENV setupVars /etc/pihole/setupVars.conf
|
||||
ENV PIHOLE_INSTALL /tmp/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.20.0.0/s6-overlay-aarch64.tar.gz
|
||||
ENV PIHOLE_INSTALL /root/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.21.4.0/s6-overlay-aarch64.tar.gz
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y wget curl net-tools cron && \
|
||||
curl -L -s $S6OVERLAY_RELEASE \
|
||||
| tar xvzf - -C / && \
|
||||
docker-install.sh && \
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
|
||||
apt-get install -y curl procps && \
|
||||
curl -L -s $S6OVERLAY_RELEASE | tar xvzf - -C / && \
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/* && \
|
||||
mv /init /s6-init
|
||||
|
||||
ENTRYPOINT [ "/init" ]
|
||||
RUN apt-get update && bash -ex docker-install.sh 2>&1
|
||||
|
||||
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'
|
||||
@@ -33,14 +24,26 @@ COPY ./start.sh /
|
||||
COPY ./bash_functions.sh /
|
||||
|
||||
# IPv6 disable flag for networks/devices that do not support it
|
||||
# not fully supported in debian yet
|
||||
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 FTL_CMD no-daemon
|
||||
|
||||
ENV VERSION v4.0
|
||||
ENV ARCH aarch64
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
|
||||
LABEL image="pihole/pihole:v4.0_aarch64"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/pi-hole/docker-pi-hole"
|
||||
|
||||
HEALTHCHECK CMD dig @127.0.0.1 pi.hole || exit 1
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
@@ -1,64 +0,0 @@
|
||||
FROM multiarch/alpine:aarch64-edge
|
||||
|
||||
LABEL image="diginc/pi-hole:alpine_aarch64"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/diginc/docker-pi-hole"
|
||||
|
||||
ENV TAG alpine
|
||||
ENV ARCH aarch64
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
|
||||
COPY install.sh /usr/local/bin/docker-install.sh
|
||||
ENV setupVars /etc/pihole/setupVars.conf
|
||||
ENV PIHOLE_INSTALL /tmp/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.20.0.0/s6-overlay-aarch64.tar.gz
|
||||
|
||||
RUN apk upgrade --update && \
|
||||
apk add bind-tools wget curl bash libcap && \
|
||||
curl -L -s $S6OVERLAY_RELEASE \
|
||||
| tar xvzf - -C / && \
|
||||
docker-install.sh && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
ENTRYPOINT [ "/init" ]
|
||||
|
||||
ADD s6/alpine-root /
|
||||
COPY s6/service /usr/local/bin/service
|
||||
|
||||
# Things installer did and fix alpine+nginx differences
|
||||
ENV WEBLOGDIR /var/log/nginx
|
||||
ENV PHP_CONFIG '/etc/php5/php-fpm.conf'
|
||||
RUN mkdir -p /etc/pihole/ && \
|
||||
mkdir -p /var/www/html/pihole && \
|
||||
mkdir -p /var/www/html/admin/ && \
|
||||
chown nginx:nginx /var/www/html && \
|
||||
touch ${WEBLOGDIR}/access.log ${WEBLOGDIR}/error.log && \
|
||||
chown -R nginx:nginx ${WEBLOGDIR} && \
|
||||
sed -i 's|^user\s*=.*$|user = nginx|' $PHP_CONFIG && \
|
||||
sed -i '/^;pid/ s|^;||' $PHP_CONFIG && \
|
||||
chmod 775 /var/www/html && \
|
||||
touch /var/log/pihole.log && \
|
||||
chmod 644 /var/log/pihole.log && \
|
||||
chown dnsmasq:root /var/log/pihole.log && \
|
||||
sed -i "s/@INT@/eth0/" /etc/dnsmasq.d/01-pihole.conf && \
|
||||
setcap CAP_NET_BIND_SERVICE=+eip `which dnsmasq` && \
|
||||
cp -f /usr/bin/list.sh /opt/pihole/list.sh && \
|
||||
echo 'Done!'
|
||||
|
||||
# php config start passes special ENVs into
|
||||
ENV PHP_ENV_CONFIG '/etc/php5/fpm.d/envs.conf'
|
||||
ENV PHP_ERROR_LOG '/var/log/nginx/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 80
|
||||
|
||||
ENV S6_LOGGING 0
|
||||
ENV S6_KEEP_ENV 1
|
||||
ENV S6_BEHAVIOUR_IF_STAGE2_FAILS 2
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
@@ -1,64 +0,0 @@
|
||||
FROM alpine:edge
|
||||
|
||||
LABEL image="diginc/pi-hole:alpine_amd64"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/diginc/docker-pi-hole"
|
||||
|
||||
ENV TAG alpine
|
||||
ENV ARCH amd64
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
|
||||
COPY install.sh /usr/local/bin/docker-install.sh
|
||||
ENV setupVars /etc/pihole/setupVars.conf
|
||||
ENV PIHOLE_INSTALL /tmp/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.20.0.0/s6-overlay-amd64.tar.gz
|
||||
|
||||
RUN apk upgrade --update && \
|
||||
apk add bind-tools wget curl bash libcap && \
|
||||
curl -L -s $S6OVERLAY_RELEASE \
|
||||
| tar xvzf - -C / && \
|
||||
docker-install.sh && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
ENTRYPOINT [ "/init" ]
|
||||
|
||||
ADD s6/alpine-root /
|
||||
COPY s6/service /usr/local/bin/service
|
||||
|
||||
# Things installer did and fix alpine+nginx differences
|
||||
ENV WEBLOGDIR /var/log/nginx
|
||||
ENV PHP_CONFIG '/etc/php5/php-fpm.conf'
|
||||
RUN mkdir -p /etc/pihole/ && \
|
||||
mkdir -p /var/www/html/pihole && \
|
||||
mkdir -p /var/www/html/admin/ && \
|
||||
chown nginx:nginx /var/www/html && \
|
||||
touch ${WEBLOGDIR}/access.log ${WEBLOGDIR}/error.log && \
|
||||
chown -R nginx:nginx ${WEBLOGDIR} && \
|
||||
sed -i 's|^user\s*=.*$|user = nginx|' $PHP_CONFIG && \
|
||||
sed -i '/^;pid/ s|^;||' $PHP_CONFIG && \
|
||||
chmod 775 /var/www/html && \
|
||||
touch /var/log/pihole.log && \
|
||||
chmod 644 /var/log/pihole.log && \
|
||||
chown dnsmasq:root /var/log/pihole.log && \
|
||||
sed -i "s/@INT@/eth0/" /etc/dnsmasq.d/01-pihole.conf && \
|
||||
setcap CAP_NET_BIND_SERVICE=+eip `which dnsmasq` && \
|
||||
cp -f /usr/bin/list.sh /opt/pihole/list.sh && \
|
||||
echo 'Done!'
|
||||
|
||||
# php config start passes special ENVs into
|
||||
ENV PHP_ENV_CONFIG '/etc/php5/fpm.d/envs.conf'
|
||||
ENV PHP_ERROR_LOG '/var/log/nginx/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 80
|
||||
|
||||
ENV S6_LOGGING 0
|
||||
ENV S6_KEEP_ENV 1
|
||||
ENV S6_BEHAVIOUR_IF_STAGE2_FAILS 2
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
@@ -1,64 +0,0 @@
|
||||
FROM multiarch/alpine:armhf-edge
|
||||
|
||||
LABEL image="diginc/pi-hole:alpine_armhf"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/diginc/docker-pi-hole"
|
||||
|
||||
ENV TAG alpine
|
||||
ENV ARCH armhf
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
|
||||
COPY install.sh /usr/local/bin/docker-install.sh
|
||||
ENV setupVars /etc/pihole/setupVars.conf
|
||||
ENV PIHOLE_INSTALL /tmp/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.20.0.0/s6-overlay-armhf.tar.gz
|
||||
|
||||
RUN apk upgrade --update && \
|
||||
apk add bind-tools wget curl bash libcap && \
|
||||
curl -L -s $S6OVERLAY_RELEASE \
|
||||
| tar xvzf - -C / && \
|
||||
docker-install.sh && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
ENTRYPOINT [ "/init" ]
|
||||
|
||||
ADD s6/alpine-root /
|
||||
COPY s6/service /usr/local/bin/service
|
||||
|
||||
# Things installer did and fix alpine+nginx differences
|
||||
ENV WEBLOGDIR /var/log/nginx
|
||||
ENV PHP_CONFIG '/etc/php5/php-fpm.conf'
|
||||
RUN mkdir -p /etc/pihole/ && \
|
||||
mkdir -p /var/www/html/pihole && \
|
||||
mkdir -p /var/www/html/admin/ && \
|
||||
chown nginx:nginx /var/www/html && \
|
||||
touch ${WEBLOGDIR}/access.log ${WEBLOGDIR}/error.log && \
|
||||
chown -R nginx:nginx ${WEBLOGDIR} && \
|
||||
sed -i 's|^user\s*=.*$|user = nginx|' $PHP_CONFIG && \
|
||||
sed -i '/^;pid/ s|^;||' $PHP_CONFIG && \
|
||||
chmod 775 /var/www/html && \
|
||||
touch /var/log/pihole.log && \
|
||||
chmod 644 /var/log/pihole.log && \
|
||||
chown dnsmasq:root /var/log/pihole.log && \
|
||||
sed -i "s/@INT@/eth0/" /etc/dnsmasq.d/01-pihole.conf && \
|
||||
setcap CAP_NET_BIND_SERVICE=+eip `which dnsmasq` && \
|
||||
cp -f /usr/bin/list.sh /opt/pihole/list.sh && \
|
||||
echo 'Done!'
|
||||
|
||||
# php config start passes special ENVs into
|
||||
ENV PHP_ENV_CONFIG '/etc/php5/fpm.d/envs.conf'
|
||||
ENV PHP_ERROR_LOG '/var/log/nginx/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 80
|
||||
|
||||
ENV S6_LOGGING 0
|
||||
ENV S6_KEEP_ENV 1
|
||||
ENV S6_BEHAVIOUR_IF_STAGE2_FAILS 2
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
@@ -1,31 +1,22 @@
|
||||
FROM debian:jessie
|
||||
|
||||
LABEL image="diginc/pi-hole:debian_amd64"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/diginc/docker-pi-hole"
|
||||
|
||||
ENV TAG debian
|
||||
ENV ARCH amd64
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
FROM debian:stretch
|
||||
|
||||
COPY install.sh /usr/local/bin/docker-install.sh
|
||||
ENV setupVars /etc/pihole/setupVars.conf
|
||||
ENV PIHOLE_INSTALL /tmp/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.20.0.0/s6-overlay-amd64.tar.gz
|
||||
ENV PIHOLE_INSTALL /root/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.21.4.0/s6-overlay-amd64.tar.gz
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y wget curl net-tools cron && \
|
||||
curl -L -s $S6OVERLAY_RELEASE \
|
||||
| tar xvzf - -C / && \
|
||||
docker-install.sh && \
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
|
||||
apt-get install -y curl procps && \
|
||||
curl -L -s $S6OVERLAY_RELEASE | tar xvzf - -C / && \
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/* && \
|
||||
mv /init /s6-init
|
||||
|
||||
ENTRYPOINT [ "/init" ]
|
||||
RUN apt-get update && bash -ex docker-install.sh 2>&1
|
||||
|
||||
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'
|
||||
@@ -33,14 +24,26 @@ COPY ./start.sh /
|
||||
COPY ./bash_functions.sh /
|
||||
|
||||
# IPv6 disable flag for networks/devices that do not support it
|
||||
# not fully supported in debian yet
|
||||
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 FTL_CMD no-daemon
|
||||
|
||||
ENV VERSION v4.0
|
||||
ENV ARCH amd64
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
|
||||
LABEL image="pihole/pihole:v4.0_amd64"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/pi-hole/docker-pi-hole"
|
||||
|
||||
HEALTHCHECK CMD dig @127.0.0.1 pi.hole || exit 1
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
49
Dockerfile_armel
Normal file
49
Dockerfile_armel
Normal file
@@ -0,0 +1,49 @@
|
||||
FROM multiarch/debian-debootstrap:armel-stretch-slim
|
||||
|
||||
COPY install.sh /usr/local/bin/docker-install.sh
|
||||
ENV PIHOLE_INSTALL /root/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.21.4.0/s6-overlay-arm.tar.gz
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y curl procps && \
|
||||
curl -L -s $S6OVERLAY_RELEASE | tar xvzf - -C / && \
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/* && \
|
||||
mv /init /s6-init
|
||||
|
||||
RUN apt-get update && bash -ex docker-install.sh 2>&1
|
||||
|
||||
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 FTL_CMD no-daemon
|
||||
|
||||
ENV VERSION v4.0
|
||||
ENV ARCH armel
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
|
||||
LABEL image="pihole/pihole:v4.0_armel"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/pi-hole/docker-pi-hole"
|
||||
|
||||
HEALTHCHECK CMD dig @127.0.0.1 pi.hole || exit 1
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
@@ -1,31 +1,22 @@
|
||||
FROM multiarch/debian-debootstrap:armhf-jessie-slim
|
||||
|
||||
LABEL image="diginc/pi-hole:debian_armhf"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/diginc/docker-pi-hole"
|
||||
|
||||
ENV TAG debian
|
||||
ENV ARCH armhf
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
FROM multiarch/debian-debootstrap:armhf-stretch-slim
|
||||
|
||||
COPY install.sh /usr/local/bin/docker-install.sh
|
||||
ENV setupVars /etc/pihole/setupVars.conf
|
||||
ENV PIHOLE_INSTALL /tmp/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.20.0.0/s6-overlay-armhf.tar.gz
|
||||
ENV PIHOLE_INSTALL /root/ph_install.sh
|
||||
ENV S6OVERLAY_RELEASE https://github.com/just-containers/s6-overlay/releases/download/v1.21.4.0/s6-overlay-armhf.tar.gz
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y wget curl net-tools cron && \
|
||||
curl -L -s $S6OVERLAY_RELEASE \
|
||||
| tar xvzf - -C / && \
|
||||
docker-install.sh && \
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
|
||||
apt-get install -y curl procps && \
|
||||
curl -L -s $S6OVERLAY_RELEASE | tar xvzf - -C / && \
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/* && \
|
||||
mv /init /s6-init
|
||||
|
||||
ENTRYPOINT [ "/init" ]
|
||||
RUN apt-get update && bash -ex docker-install.sh 2>&1
|
||||
|
||||
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'
|
||||
@@ -33,14 +24,26 @@ COPY ./start.sh /
|
||||
COPY ./bash_functions.sh /
|
||||
|
||||
# IPv6 disable flag for networks/devices that do not support it
|
||||
# not fully supported in debian yet
|
||||
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 FTL_CMD no-daemon
|
||||
|
||||
ENV VERSION v4.0
|
||||
ENV ARCH armhf
|
||||
ENV PATH /opt/pihole:${PATH}
|
||||
|
||||
LABEL image="pihole/pihole:v4.0_armhf"
|
||||
LABEL maintainer="adam@diginc.us"
|
||||
LABEL url="https://www.github.com/pi-hole/docker-pi-hole"
|
||||
|
||||
HEALTHCHECK CMD dig @127.0.0.1 pi.hole || exit 1
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
136
README.md
136
README.md
@@ -1,40 +1,59 @@
|
||||
A [Docker](https://www.docker.com/what-docker) project to make lightweight x86 and ARM container with [pi-hole](https://pi-hole.net) functionality. Why? Originally designed to be a quick, easy, and portable way to run x86 Pi-Hole, it now has an arm specific tag too.
|
||||
<p align="center">
|
||||
<a href="https://pi-hole.net"><img src="https://pi-hole.github.io/graphics/Vortex/Vortex_with_text.png" width="150" height="255" alt="Pi-hole"></a><br/>
|
||||
</p>
|
||||
<!-- Delete above HTML and insert markdown for dockerhub :  -->
|
||||
|
||||
1) Install docker for your [x86-64 system](https://www.docker.com/community-edition) or [ARMv6l/ARMv7 system](https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/) using those links.
|
||||
2) Use the appropriate tag (x86 can use default tag, ARM users need to use the `arm` tag) in the below `docker run` command
|
||||
## Overview
|
||||
|
||||
#### Renamed from `diginc/pi-hole` to `pihole/pihole`
|
||||
|
||||
A [Docker](https://www.docker.com/what-docker) project to make a lightweight x86 and ARM container with [Pi-hole](https://pi-hole.net) functionality.
|
||||
|
||||
1) Install docker for your [x86-64 system](https://www.docker.com/community-edition) or [ARMv7 system](https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/) using those links.
|
||||
2) Use the appropriate tag (x86 can use default tag, ARM users need to use images from [pihole/pihole:v4.0_armhf](https://store.docker.com/community/images/pihole/pihole/tags)) in the below `docker run` command
|
||||
3) Enjoy!
|
||||
|
||||
[](https://travis-ci.org/diginc/docker-pi-hole) [](https://store.docker.com/community/images/diginc/pi-hole) [](https://store.docker.com/community/images/diginc/pi-hole)
|
||||
[](https://travis-ci.org/pi-hole/docker-pi-hole) [](https://store.docker.com/community/images/pihole/pihole) [](https://store.docker.com/community/images/pihole/pihole)
|
||||
|
||||
[](https://gitter.im/diginc/docker-pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://gitter.im/pihole/docker-pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
## Running Pi-Hole Docker
|
||||
## Running Pi-hole Docker
|
||||
|
||||
[DockerCloud](https://store.docker.com/community/images/diginc/pi-hole) automatically builds the latest docker-pi-hole changes into images which can easily be pulled and ran with a simple `docker run` command. Changes and updates under development or testing can be found on the [dev tags](#development)
|
||||
[DockerCloud](https://store.docker.com/community/images/pihole/pihole) automatically builds the latest docker-pi-hole changes into images which can easily be pulled and ran with a simple `docker run` command. Changes and updates under development or testing can be found in the [dev tags](#development) section.
|
||||
|
||||
One crucial thing to know before starting is this container needs port 53 and port 80, 2 very popular ports that may conflict with existing applications. If you have no other services or dockers using port 53/80 (if you do, keep reading below for a reverse proxy example), the minimum arguments required to run this container are in the script [docker_run.sh](https://github.com/diginc/docker-pi-hole/blob/master/docker_run.sh) or summarized here:
|
||||
One crucial thing to know before starting is this container needs port 53 and port 80, two very popular ports that may conflict with existing applications. If you have no other services or docker containers using port 53/80 (if you do, keep reading below for a reverse proxy example), the minimum arguments required to run this container are in the script [docker_run.sh](https://github.com/pi-hole/docker-pi-hole/blob/master/docker_run.sh) or summarized here:
|
||||
|
||||
```
|
||||
IP_LOOKUP="$(ip route get 8.8.8.8 | awk '{ print $NF; exit }')" # May not work for VPN / tun0
|
||||
IPv6_LOOKUP="$(ip -6 route get 2001:4860:4860::8888 | awk '{ print $10; exit }')" # May not work for VPN / tun0
|
||||
IPv6_LOOKUP="$(ip -6 route get 2001:4860:4860::8888 | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')" # May not work for VPN / tun0
|
||||
IP="${IP:-$IP_LOOKUP}" # use $IP, if set, otherwise IP_LOOKUP
|
||||
IPv6="${IPv6:-$IPv6_LOOKUP}" # use $IPv6, if set, otherwise IP_LOOKUP
|
||||
DOCKER_CONFIGS="$(pwd)" # Default of directory you run this from, update to where ever.
|
||||
|
||||
echo "### Make sure your IPs are correct, hard code ServerIP ENV VARs if necessary\nIP: ${IP}\nIPv6: ${IPv6}"
|
||||
docker run -d \
|
||||
--name pihole \
|
||||
-p 53:53/tcp -p 53:53/udp -p 80:80 \
|
||||
-p 53:53/tcp -p 53:53/udp \
|
||||
-p 67:67/udp \
|
||||
-p 80:80 \
|
||||
-p 443:443 \
|
||||
-v "${DOCKER_CONFIGS}/pihole/:/etc/pihole/" \
|
||||
-v "${DOCKER_CONFIGS}/dnsmasq.d/:/etc/dnsmasq.d/" \
|
||||
-e ServerIP="${IP}" \
|
||||
-e ServerIPv6="${IPv6}" \
|
||||
--restart=always \
|
||||
diginc/pi-hole:alpine
|
||||
--restart=unless-stopped \
|
||||
--cap-add=NET_ADMIN \
|
||||
pihole/pihole:latest
|
||||
|
||||
echo -n "Your password for https://${IP}/admin/ is "
|
||||
docker logs pihole 2> /dev/null | grep 'password:'
|
||||
```
|
||||
|
||||
**This is just an example and might need changing.** Volumes are stored in the directory $DOCKER_CONFIGS and aren't required but are recommended for persisting data across docker re-creations for updating images. As mentioned on line 2, the auto IP_LOOKUP variable may not work for VPN tunnel interfaces.
|
||||
**This is just an example and might need changing.** Volumes are stored in the directory `$DOCKER_CONFIGS` and are recommended for persisting data across docker re-creations for updating images. As mentioned on line 2, the auto `IP_LOOKUP` variable may not work for VPN tunnel interfaces.
|
||||
|
||||
**Automatic Ad List Updates** - since 3.0+ release cron is baked into the container and will grab the newest versions of your lists and flush your logs. **Set TZ** environment variable to make sure the midnight log rotation syncs up with your timezone's midnight.
|
||||
Two recently added ports to the `docker run` and `docker-compose` examples are port 67 and 443. Port 67 is for users who wish to have Pi-hole run a DHCP server. 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.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@@ -44,113 +63,108 @@ There are other environment variables if you want to customize various things in
|
||||
| ----------------------- | ----------- |
|
||||
| `-e ServerIP=<Host's IP>`<br/> **Required** | Set to your server's external IP to block ads fully
|
||||
| `-e ServerIPv6=<Host's IPv6>`<br/> *Required if using IPv6* | **If you have a v6 network** set to your server's external IPv6 to block IPv6 ads fully
|
||||
| `-e TZ=<Timezone>`<br/> **Recommended** *Default: UTC* | Set your [timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) to make sure logs rotate ad midnight instead of your offset for London
|
||||
| `-e WEBPASSWORD=<Admin password>`<br/> **Recommended** *Default: random* | http://pi.hole/admin password. Run `docker logs pihole | grep random` to find your random pass.
|
||||
| `-e TZ=<Timezone>`<br/> **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.
|
||||
| `-e WEBPASSWORD=<Admin password>`<br/> **Recommended** *Default: random* | http://pi.hole/admin password. Run `docker logs pihole \| grep random` to find your random pass.
|
||||
| `-e DNS1=<IP>`<br/> *Optional* *Default: 8.8.8.8* | Primary upstream DNS provider, default is google DNS
|
||||
| `-e DNS2=<IP>`<br/> *Optional* *Default: 8.8.4.4* | Secondary upstream DNS provider, default is google DNS
|
||||
| `-e DNS2=<IP>`<br/> *Optional* *Default: 8.8.4.4* | Secondary upstream DNS provider, default is google DNS, `no` if only one DNS should used
|
||||
| `-e VIRTUAL_HOST=<Custom Hostname>`<br/> *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
|
||||
| `-e IPv6=<True\|False>`<br/> *Optional* *Default: True* | For unraid compatibility, strips out all the IPv6 configuration from DNS/Web services when false.
|
||||
| `-e INTERFACE=<NIC>`<br/> *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.
|
||||
| `-e DNSMASQ_LISTENING=<local\|all\|NIC>`<br/> *Advanced/Optional* | `local` listens on all local subnets, `all` permits listening on internet origin subnets in addition to local.
|
||||
| `-e WEB_PORT=<PORT>`<br/> *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: [Alternagtive Synology installation method](https://discourse.pi-hole.net/t/alternative-synology-installation-method/5454?u=diginc)
|
||||
|
||||
Here is a rundown of the other arguments passed into the example `docker run`
|
||||
Here is a rundown of the other arguments passed into the example `docker run`:
|
||||
|
||||
| Docker Arguments | Description |
|
||||
| ---------------- | ----------- |
|
||||
| `-p 80:80`<br/>`-p 53:53/tcp -p 53:53/udp`<br/> **Recommended** | Ports to expose, the bare minimum ports required for pi-holes HTTP and DNS services
|
||||
| `--restart=always`<br/> **Recommended** | Automatically (re)start your pihole on boot or in the event of a crash
|
||||
| `-v /dir/for/pihole:/etc/pihole`<br/> **Recommended** | Volumes for your pihole configs help persist changes across docker image updates
|
||||
| `-p 80:80`<br/>`-p 53:53/tcp -p 53:53/udp`<br/> **Recommended** | Ports to expose, the bare minimum ports required for Pi-holes HTTP and DNS services
|
||||
| `--restart=unless-stopped`<br/> **Recommended** | Automatically (re)start your Pi-hole on boot or in the event of a crash
|
||||
| `-v /dir/for/pihole:/etc/pihole`<br/> **Recommended** | Volumes for your Pi-hole configs help persist changes across docker image updates
|
||||
| `-v /dir/for/dnsmasq.d:/etc/dnsmasq.d`<br/> **Recommended** | Volumes for your dnsmasq configs help persist changes across docker image updates
|
||||
| `--net=host`<br/> *Optional* | Alternative to `-p <port>:<port>` arguments (Cannot be used at same time as -p) if you don't run any other web application
|
||||
| `--cap-add=NET_ADMIN`<br/> *Optional* | If you want to attempt DHCP (not fully tested or supported) I'd suggest this with --net=host
|
||||
| `--cap-add=NET_ADMIN`<br/> *Optional* | If you're forwarding port 67 you will also needs this for DHCP to work. (DHCP Reportedly works, I have not used however)
|
||||
|
||||
If you're a fan of [docker-compose](https://docs.docker.com/compose/install/) I have [example docker-compose.yml files](https://github.com/diginc/docker-pi-hole/blob/master/doco-example.yml) in github which I think are a nicer way to represent such long run commands.
|
||||
If you're a fan of [docker-compose](https://docs.docker.com/compose/install/) I have [example docker-compose.yml files](https://github.com/pi-hole/docker-pi-hole/blob/master/doco-example.yml) in github which I think are a nicer way to represent such long run commands.
|
||||
|
||||
## Tips and Tricks
|
||||
|
||||
* A good way to test things are working right is by loading this page: [http://pi.hole/admin/](http://pi.hole/admin/)
|
||||
* [How do I set or reset the Web interface Password?](https://discourse.pi-hole.net/t/how-do-i-set-or-reset-the-web-interface-password/1328)
|
||||
* `docker exec pihole_container_name pihole -a -p supersecurepassword`
|
||||
* `docker exec -it pihole_container_name pihole -a -p` - then enter your password into the prompt
|
||||
* Port conflicts? Stop your server's existing DNS / Web services.
|
||||
* Ubuntu users especially may need to shutoff dnsmasq on your docker server so it can run in the container on port 53
|
||||
* Ubuntu users especially may need to shut off dns on your docker server so it can run in the container on port 53
|
||||
* 17.04 and later should disable dnsmasq.
|
||||
* 17.10 should disable systemd-resolved service. See this page: [How to disable systemd-resolved in Ubuntu](https://askubuntu.com/questions/907246/how-to-disable-systemd-resolved-in-ubuntu)
|
||||
* Don't forget to stop your services from auto-starting again after you reboot
|
||||
* Port 80 is highly recommended because if you have another site/service using port 80 by default then the ads may not transform into blank ads correctly. To make sure docker-pi-hole plays nicely with an existing webserver you run you'll probably need a reverse proxy webserver config if you don't have one already. Pi-Hole has to be the default web app on said proxy e.g. if you goto your host by IP instead of domain then pi-hole is served out instead of any other sites hosted by the proxy. This is the '[default_server](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen)' in nginx or ['_default_' virtual host](https://httpd.apache.org/docs/2.4/vhosts/examples.html#default) in Apache and is taken advantage of so any undefined ad domain can be directed to your webserver and get a 'blocked' response instead of ads.
|
||||
* You can still map other ports to pi-hole port 80 using docker's port forwarding like this `-p 8080:80`, but again the ads won't render propertly. Changing the inner port 80 shouldn't be required unless you run docker host networking mode.
|
||||
* [Here is an example of running with jwilder/proxy](https://github.com/diginc/docker-pi-hole/blob/master/jwilder-proxy-example-doco.yml) (an nginx auto-configuring docker reverse proxy for docker) on my port 80 with pihole on another port. Pi-hole needs to be `DEFAULT_HOST` env in jwilder/proxy and you need to set the matching `VIRTUAL_HOST` for the pihole's container. Please read jwilder/proxy readme for more info if you have trouble. I tested this basic example which is based off what I run.
|
||||
* Port 80 is highly recommended because if you have another site/service using port 80 by default then the ads may not transform into blank ads correctly. To make sure docker-pi-hole plays nicely with an existing webserver you run you'll probably need a reverse proxy webserver config if you don't have one already. Pi-hole must be the default web app on the proxy e.g. if you go to your host by IP instead of domain then Pi-hole is served out instead of any other sites hosted by the proxy. This is the '[default_server](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen)' in nginx or ['_default_' virtual host](https://httpd.apache.org/docs/2.4/vhosts/examples.html#default) in Apache and is taken advantage of so any undefined ad domain can be directed to your webserver and get a 'blocked' response instead of ads.
|
||||
* You can still map other ports to Pi-hole port 80 using docker's port forwarding like this `-p 8080:80`, but again the ads won't render properly. Changing the inner port 80 shouldn't be required unless you run docker host networking mode.
|
||||
* [Here is an example of running with jwilder/proxy](https://github.com/pi-hole/docker-pi-hole/blob/master/jwilder-proxy-example-doco.yml) (an nginx auto-configuring docker reverse proxy for docker) on my port 80 with Pi-hole on another port. Pi-hole needs to be `DEFAULT_HOST` env in jwilder/proxy and you need to set the matching `VIRTUAL_HOST` for the Pi-hole's container. Please read jwilder/proxy readme for more info if you have trouble. I tested this basic example which is based off what I run.
|
||||
|
||||
## Docker tags and versioning
|
||||
|
||||
The primary docker tags / versions are explained in the following table. [Click here to see the full list of tags](https://store.docker.com/community/images/diginc/pi-hole/tags), I also try to tag with the specific version of Pi-Hole Core for version pinning purposes, the web version that comes with the core releases should be in the [GitHub Release notes](https://github.com/diginc/docker-pi-hole/releases).
|
||||
The primary docker tags / versions are explained in the following table. [Click here to see the full list of x86 tags](https://store.docker.com/community/images/pihole/pihole/tags) ([arm tags are here](https://store.docker.com/community/images/pihole/pihole/tags)), I also try to tag with the specific version of Pi-hole Core for version archival purposes, the web version that comes with the core releases should be in the [GitHub Release notes](https://github.com/pi-hole/docker-pi-hole/releases).
|
||||
|
||||
| tag | architecture | description | Dockerfile |
|
||||
| --- | ------------ | ----------- | ---------- |
|
||||
| `alpine` / `latest` | x86 | Alpine x86 image, small size container running nginx and dnsmasq | [Dockerfile](https://github.com/diginc/docker-pi-hole/blob/master/alpine.docker) |
|
||||
| `debian` | x86 | Debian x86 image, container running lighttpd and dnsmasq | [Dockerfile](https://github.com/diginc/docker-pi-hole/blob/master/debian.docker) |
|
||||
| `arm` | ARM | Debian ARM image, container running lighttpd and dnsmasq built for ARM | [Dockerfile](https://github.com/diginc/docker-pi-hole/blob/master/debian-armhf.docker) |
|
||||
| `latest` / `v4.0` | x86 | Debian x86 image, container running lighttpd and dnsmasq | [Dockerfile](https://github.com/pi-hole/docker-pi-hole/blob/master/Dockerfile_amd64) |
|
||||
|
||||
### `diginc/pi-hole:alpine` [](https://microbadger.com/images/diginc/pi-hole "Get your own image badge on microbadger.com") [](https://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com") [](https://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com")
|
||||
### `pihole/pihole:latest` [](https://microbadger.com/images/pihole/pihole "Get your own image badge on microbadger.com") [](https://microbadger.com/images/pihole/pihole "Get your own version badge on microbadger.com") [](https://microbadger.com/images/pihole/pihole "Get your own version badge on microbadger.com")
|
||||
|
||||
Alpine is also the default, aka `latest` tag. If you don't specify a tag you will get this version. This is only an x86 version and will not work on Raspberry Pi's ARM architecture. Use this if you like a small image.
|
||||
This version of the docker aims to be as close to a standard Pi-hole installation by using the recommended base OS and the exact configs and scripts (minimally modified to get them working). This enables fast updating when an update comes from Pi-hole.
|
||||
|
||||
### `diginc/pi-hole:debian` [](https://microbadger.com/images/diginc/pi-hole "Get your own image badge on microbadger.com") [](https://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com")
|
||||
### `pihole/pihole:v4.0_armhf` [](https://microbadger.com/images/pihole/pihole "Get your own image badge on microbadger.com")
|
||||
Latest version of ARMv7-compatible pihole image
|
||||
|
||||
This version of the docker aims to be as close to a standard pi-hole installation by using the same base OS and the exact configs and scripts (minimally modified to get them working). This serves as a stable baseline for merging and testing upstream repository pi-hole changes. Use this if you don't care about image size and want as stable of a product as possible.
|
||||
https://hub.docker.com/r/pihole/pihole/tags/
|
||||
|
||||
### `diginc/pi-hole:arm` [](https://microbadger.com/images/diginc/pi-hole "Get your own image badge on microbadger.com") [](https://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com")
|
||||
### `pihole/pihole:v4.0_aarch64` [](https://microbadger.com/images/pihole/pihole "Get your own image badge on microbadger.com")
|
||||
Latest version of ARM64-compatible pihole image
|
||||
|
||||
Same as the debian image, but cross compiled for ARM architecture hardware through [resin.io's awesome Qemu wrapper](https://resin.io/blog/building-arm-containers-on-any-x86-machine-even-dockerhub/).
|
||||
|
||||
Alpine doesn't have an arm cross compilable image at this time.
|
||||
https://hub.docker.com/r/pihole/pihole/tags/
|
||||
|
||||
## Upgrading, Persistence, and Customizations
|
||||
|
||||
The standard pi-hole customization abilities apply to this docker, but with docker twists such as using docker volume mounts to map host stored file configurations over the container defaults. Volumes are also important to persist the configuration in case you have removed the pi-hole container which is a typical docker upgrade pattern.
|
||||
The standard Pi-hole customization abilities apply to this docker, but with docker twists such as using docker volume mounts to map host stored file configurations over the container defaults. Volumes are also important to persist the configuration in case you have removed the Pi-hole container which is a typical docker upgrade pattern.
|
||||
|
||||
### Upgrading
|
||||
|
||||
**If you try to use pihole's built in updater it is not guaranteed to work**; it almost assuredly won't work for alpine but debian may. The preferred 'docker way' to upgrade is:
|
||||
`pihole -up` is disabled. Upgrade the docker way instead, please. Long-living docker containers are not the docker way since they aim to be portable and reproducible, why not re-create them often! Just to prove you can.
|
||||
|
||||
1. Download the latest version of the image: `docker pull diginc/pi-hole`
|
||||
1. Download the latest version of the image: `docker pull pihole/pihole`
|
||||
2. Throw away your container: `docker rm -f pihole`
|
||||
* **Warning** When removing your pihole container you may be stuck without DNS until step 3 - **docker pull** before you **docker rm -f** to avoid DNS inturruption **OR** always have a fallback DNS server configured in DHCP to avoid this problem all together.
|
||||
* If you care about your data (logs/customizations), make sure you have it volume mapped or it will be deleted in this step
|
||||
3. Start your container with the newer base image: `docker run <args> diginc/pi-hole` (`<args>` being your preferred run volumes and env vars)
|
||||
* **Warning** When removing your pihole container you may be stuck without DNS until step 3; **docker pull** before **docker rm -f** to avoid DNS inturruption **OR** always have a fallback DNS server configured in DHCP to avoid this problem altogether.
|
||||
* If you care about your data (logs/customizations), make sure you have it volume-mapped or it will be deleted in this step.
|
||||
3. Start your container with the newer base image: `docker run <args> pihole/pihole` (`<args>` being your preferred run volumes and env vars)
|
||||
|
||||
Why is this style of upgrading good? A couple reasons: Everyone is starting from the same base image which has been tested to know it works. No worrying about upgrading from A to B, B to C, or A to C is required when rolling out updates, it reducing complexity, and simply allows a 'fresh start' every time while preserving customizations with volumes. Basically I'm encouraging [phoenix servers](https://www.google.com/?q=phoenix+servers) principles for your containers.
|
||||
|
||||
|
||||
### Pihole features
|
||||
### Pi-hole features
|
||||
|
||||
Here are some relevant wiki pages from [pi-hole's documentation](https://github.com/pi-hole/pi-hole/blob/master/README.md#get-help-or-connect-with-us-on-the-web). The web interface or command line tools can be used to implement changes to pihole.
|
||||
Here are some relevant wiki pages from [Pi-hole's documentation](https://github.com/pi-hole/pi-hole/blob/master/README.md#get-help-or-connect-with-us-on-the-web). The web interface or command line tools can be used to implement changes to pihole.
|
||||
|
||||
We install all pihole utilities so the the built in [pihole commands](https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738) will work via `docker exec <container> <command>` like so:
|
||||
|
||||
* `docker exec pihole_container_name pihole updateGravity`
|
||||
* `docker exec pihole_container_name pihole -w spclient.wg.spotify.com
|
||||
* `docker exec pihole_container_name pihole -wild example.com
|
||||
* `docker exec pihole_container_name pihole -w spclient.wg.spotify.com`
|
||||
* `docker exec pihole_container_name pihole -wild example.com`
|
||||
|
||||
### Customizations
|
||||
|
||||
The webserver and DNS service inside the container can be customized if necessary. Any configuration files you volume mount into `/etc/dnsmasq.d/` will be loaded by dnsmasq when the container starts or restarts or if you need to modify the pi-hole config it is located at `/etc/dnsmasq.d/01-pihole.conf`. The docker start scripts runs a config test prior to starting so it will tell you about any errors in the docker log.
|
||||
The webserver and DNS service inside the container can be customized if necessary. Any configuration files you volume mount into `/etc/dnsmasq.d/` will be loaded by dnsmasq when the container starts or restarts or if you need to modify the Pi-hole config it is located at `/etc/dnsmasq.d/01-pihole.conf`. The docker start scripts runs a config test prior to starting so it will tell you about any errors in the docker log.
|
||||
|
||||
Similarly for the webserver you can customize configs in /etc/nginx (*:alpine* tag) and /etc/lighttpd (*:debian* tag).
|
||||
Similarly for the webserver you can customize configs in /etc/lighttpd
|
||||
|
||||
### Systemd init script
|
||||
|
||||
As long as your docker system service auto starts on boot and you run your container with `--restart=always` your container should always start on boot and restart on crashes. If you prefer to have your docker container run as a systemd service instead add the file [pihole.service](https://raw.githubusercontent.com/diginc/docker-pi-hole/master/pihole.service) to "/etc/systemd/system"; customize whatever your container name is and remove `--restart=always` from your docker run. Then after you have initially created the docker container using the docker run command above, you can control it with "systemctl start pihole" or "systemctl stop pihole" (instead of `docker start`/`docker stop`). You can also enable it to auto-start on boot with "systemctl enable pihole" (as opposed to `--restart=always` and making sure docker service auto-starts on boot).
|
||||
As long as your docker system service auto starts on boot and you run your container with `--restart=unless-stopped` your container should always start on boot and restart on crashes. If you prefer to have your docker container run as a systemd service instead, add the file [pihole.service](https://raw.githubusercontent.com/pi-hole/docker-pi-hole/master/pihole.service) to "/etc/systemd/system"; customize whatever your container name is and remove `--restart=unless-stopped` from your docker run. Then after you have initially created the docker container using the docker run command above, you can control it with "systemctl start pihole" or "systemctl stop pihole" (instead of `docker start`/`docker stop`). You can also enable it to auto-start on boot with "systemctl enable pihole" (as opposed to `--restart=unless-stopped` and making sure docker service auto-starts on boot).
|
||||
|
||||
NOTE: After initial run you may need to manually stop the docker container with "docker stop pihole" before the systemctl can start controlling the container.
|
||||
|
||||
## Development
|
||||
|
||||
[](https://travis-ci.org/diginc/docker-pi-hole) If you plan on making a contribution please pull request to the dev branch. I also build tags of the dev branch for bug fix testing after merges have been made:
|
||||
|
||||
| tag | architecture | description | Dockerfile |
|
||||
| --- | ------------ | ----------- | ---------- |
|
||||
| `alpine_dev` | x86 | Alpine x86 image, small size container running nginx and dnsmasq | [Dockerfile](https://github.com/diginc/docker-pi-hole/blob/dev/alpine.docker) |
|
||||
| `debian_dev` | x86 | Debian x86 image, container running lighttpd and dnsmasq | [Dockerfile](https://github.com/diginc/docker-pi-hole/blob/dev/debian.docker) |
|
||||
| `arm_dev` | ARM | Debian ARM image, container running lighttpd and dnsmasq built for ARM | [Dockerfile](https://github.com/diginc/docker-pi-hole/blob/dev/debian-armhf.docker) |
|
||||
Development image tags coming soon
|
||||
|
||||
# User Feedback
|
||||
|
||||
Please report issues on the [GitHub project](https://github.com/diginc/docker-pi-hole) when you suspect something docker related. Pi-Hole questions are best answered on their [user forums](https://github.com/pi-hole/pi-hole/blob/master/README.md#get-help-or-connect-with-us-on-the-web). Ping me (@diginc) on there if it's a docker and you're not sure if it's docker related.
|
||||
Please report issues on the [GitHub project](https://github.com/pi-hole/docker-pi-hole) when you suspect something docker related. Pi-hole questions are best answered on our [user forums](https://github.com/pi-hole/pi-hole/blob/master/README.md#get-help-or-connect-with-us-on-the-web). Ping me (@diginc) on the forums if it's a docker container and you're not sure if it's docker related.
|
||||
|
||||
21
TESTING.md
Normal file
21
TESTING.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Prerequisites
|
||||
|
||||
Make sure you have docker, python, and pip. I won't cover how to install those here, please search the internet for that info if you need it.
|
||||
|
||||
# Running tests locally
|
||||
|
||||
Travis-ci auto runs tests during pull requests (PR) but it only has 2 cores and if you have more/faster cpus your PC's local tests will be faster and you'll have quicker feedback loops than continually pushing to have your PR run travis-ci
|
||||
|
||||
After you have the prereqs, to get the required pip packages run: `pip install -r requirements.txt`
|
||||
|
||||
To run the Dockerfile templating, image build, and tests all in one command just run: `tox`
|
||||
|
||||
# Local image names
|
||||
|
||||
Docker images built by `tox` or `python Dockerfile.py` are named the same but stripped of the `pihole/` docker repository namespace.
|
||||
|
||||
e.g. `pi-hole:debian_amd64` or `pi-hole-multiarch:debian_aarch64`
|
||||
|
||||
You can run the multiarch images on an amd64 development system if you [enable binfmt-support as described in the multiarch image docs](https://hub.docker.com/r/multiarch/multiarch/debian-debootstrap/)
|
||||
|
||||
`docker run --rm --privileged multiarch/qemu-user-static:register --reset`
|
||||
@@ -1,12 +1,51 @@
|
||||
#!/bin/bash
|
||||
. /opt/pihole/webpage.sh
|
||||
setupVars="$setupVars"
|
||||
ServerIP="$ServerIP"
|
||||
ServerIPv6="$ServerIPv6"
|
||||
IPv6="$IPv6"
|
||||
|
||||
prepare_setup_vars() {
|
||||
prepare_configs() {
|
||||
# Done in /start.sh, don't do twice
|
||||
PH_TEST=true . $PIHOLE_INSTALL
|
||||
distro_check
|
||||
installConfigs
|
||||
touch "$setupVars"
|
||||
set +e
|
||||
mkdir -p /var/run/pihole /var/log/pihole
|
||||
# Re-apply perms from basic-install over any volume mounts that may be present (or not)
|
||||
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"
|
||||
# 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
|
||||
chown pihole:pihole /var/run/pihole /var/log/pihole
|
||||
test -f /var/run/pihole/FTL.sock && rm /var/run/pihole/FTL.sock
|
||||
chown pihole:pihole /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /etc/pihole /etc/pihole/dhcp.leases /var/log/pihole.log
|
||||
chmod 0644 /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /var/log/pihole.log
|
||||
set -e
|
||||
# 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;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;/INSTALL_WEB_SERVER/d;/INSTALL_WEB_INTERFACE/d;/LIGHTTPD_ENABLED/d;' "${setupVars}"
|
||||
fi
|
||||
# echo the information to the user
|
||||
{
|
||||
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
|
||||
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
|
||||
echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
|
||||
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
|
||||
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
|
||||
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() {
|
||||
@@ -15,14 +54,10 @@ validate_env() {
|
||||
exit 1
|
||||
fi;
|
||||
|
||||
# Debian
|
||||
nc_error='Name or service not known'
|
||||
if [[ "$TAG" == 'alpine' ]] ; then
|
||||
nc_error='bad address'
|
||||
fi;
|
||||
|
||||
# Required ServerIP is a valid IP
|
||||
if nc -w1 -z "$ServerIP" 53 2>&1 | grep -q "$nc_error" ; then
|
||||
# nc won't throw any text based errors when it times out connecting to a valid IP, otherwise it complains about the DNS name being garbage
|
||||
# if nc doesn't behave as we expect on a valid IP the routing table should be able to look it up and return a 0 retcode
|
||||
if [[ "$(nc -4 -w1 -z "$ServerIP" 53 2>&1)" != "" ]] || ! ip route get "$ServerIP" > /dev/null ; then
|
||||
echo "ERROR: ServerIP Environment variable ($ServerIP) doesn't appear to be a valid IPv4 address"
|
||||
exit 1
|
||||
fi
|
||||
@@ -30,11 +65,11 @@ validate_env() {
|
||||
# Optional IPv6 is a valid address
|
||||
if [[ -n "$ServerIPv6" ]] ; then
|
||||
if [[ "$ServerIPv6" == 'kernel' ]] ; then
|
||||
echo "WARNING: You passed in IPv6 with a value of 'kernel', this maybe beacuse you do not have IPv6 enabled on your network"
|
||||
echo "ERROR: You passed in IPv6 with a value of 'kernel', this maybe beacuse you do not have IPv6 enabled on your network"
|
||||
unset ServerIPv6
|
||||
return
|
||||
exit 1
|
||||
fi
|
||||
if nc -w 1 -z "$ServerIPv6" 53 2>&1 | grep -q "$nc_error" || ! ip route get "$ServerIPv6" ; then
|
||||
if [[ "$(nc -6 -w1 -z "$ServerIPv6" 53 2>&1)" != "" ]] || ! ip route get "$ServerIPv6" > /dev/null ; then
|
||||
echo "ERROR: ServerIPv6 Environment variable ($ServerIPv6) doesn't appear to be a valid IPv6 address"
|
||||
echo " TIP: If your server is not IPv6 enabled just remove '-e ServerIPv6' from your docker container"
|
||||
exit 1
|
||||
@@ -48,22 +83,41 @@ setup_dnsmasq_dns() {
|
||||
local DNS2="${2:-8.8.4.4}"
|
||||
local dnsType='default'
|
||||
if [ "$DNS1" != '8.8.8.8' ] || [ "$DNS2" != '8.8.4.4' ] ; then
|
||||
dnsType='custom'
|
||||
dnsType='custom'
|
||||
fi;
|
||||
|
||||
if [ ! -f /.piholeFirstBoot ] ; then
|
||||
local setupDNS1="$(grep 'PIHOLE_DNS_1' ${setupVars})"
|
||||
local setupDNS2="$(grep 'PIHOLE_DNS_2' ${setupVars})"
|
||||
if [[ -n "$DNS1" && -n "$setupDNS1" ]] || \
|
||||
[[ -n "$DNS2" && -n "$setupDNS2" ]] ; then
|
||||
echo "Docker DNS variables not used"
|
||||
fi
|
||||
echo "Existing DNS servers used"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Using $dnsType DNS servers: $DNS1 & $DNS2"
|
||||
[ -n "$DNS1" ] && change_setting "PIHOLE_DNS_1" "${DNS1}"
|
||||
[ -n "$DNS2" ] && change_setting "PIHOLE_DNS_2" "${DNS2}"
|
||||
if [[ -n "$DNS1" && -z "$setupDNS1" ]] ; then
|
||||
change_setting "PIHOLE_DNS_1" "${DNS1}"
|
||||
fi
|
||||
if [[ -n "$DNS2" && -z "$setupDNS2" ]] ; then
|
||||
if [ "$DNS2" = "no" ] ; then
|
||||
delete_setting "PIHOLE_DNS_2"
|
||||
else
|
||||
change_setting "PIHOLE_DNS_2" "${DNS2}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
setup_dnsmasq_interface() {
|
||||
local INTERFACE="${1:-eth0}"
|
||||
local interface="${1:-eth0}"
|
||||
local interfaceType='default'
|
||||
if [ "$INTERFACE" != 'eth0' ] ; then
|
||||
if [ "$interface" != 'eth0' ] ; then
|
||||
interfaceType='custom'
|
||||
fi;
|
||||
echo "DNSMasq binding to $interfaceType interface: $INTERFACE"
|
||||
[ -n "$INTERFACE" ] && change_setting "PIHOLE_INTERFACE" "${INTERFACE}"
|
||||
echo "DNSMasq binding to $interfaceType interface: $interface"
|
||||
[ -n "$interface" ] && change_setting "PIHOLE_INTERFACE" "${interface}"
|
||||
}
|
||||
|
||||
setup_dnsmasq_config_if_missing() {
|
||||
@@ -74,10 +128,13 @@ setup_dnsmasq_config_if_missing() {
|
||||
}
|
||||
|
||||
setup_dnsmasq() {
|
||||
local dns1="$1"
|
||||
local dns2="$2"
|
||||
local interface="$3"
|
||||
# Coordinates
|
||||
setup_dnsmasq_config_if_missing
|
||||
setup_dnsmasq_dns "$DNS1" "$DNS2"
|
||||
setup_dnsmasq_interface "$INTERFACE"
|
||||
setup_dnsmasq_dns "$dns1" "$dns2"
|
||||
setup_dnsmasq_interface "$interface"
|
||||
ProcessDNSSettings
|
||||
}
|
||||
|
||||
@@ -119,24 +176,16 @@ setup_dnsmasq_hostnames() {
|
||||
}
|
||||
|
||||
setup_lighttpd_bind() {
|
||||
if [[ "$TAG" == 'debian' ]] ; then
|
||||
# if using '--net=host' only bind lighttpd on $ServerIP
|
||||
if grep -q "docker" /proc/net/dev ; 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+80/server.bind\t\t = \"${ServerIP}\"\nserver.port\t\t = 80/" /etc/lighttpd/lighttpd.conf
|
||||
fi
|
||||
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 "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
|
||||
fi
|
||||
}
|
||||
|
||||
setup_php_env() {
|
||||
case $TAG in
|
||||
"debian") setup_php_env_debian ;;
|
||||
"alpine") setup_php_env_alpine ;;
|
||||
esac
|
||||
}
|
||||
|
||||
setup_php_env_debian() {
|
||||
if [ -z "$VIRTUAL_HOST" ] ; then
|
||||
VIRTUAL_HOST="$ServerIP"
|
||||
fi;
|
||||
@@ -156,103 +205,113 @@ setup_php_env_debian() {
|
||||
grep -E '(VIRTUAL_HOST|ServerIP|PHP_ERROR_LOG)' "$PHP_ENV_CONFIG"
|
||||
}
|
||||
|
||||
setup_php_env_alpine() {
|
||||
# Intentionally tabs, required by HEREDOC de-indentation (<<-)
|
||||
cat <<-EOF > "$PHP_ENV_CONFIG"
|
||||
[www]
|
||||
env[PATH] = ${PATH}
|
||||
env[PHP_ERROR_LOG] = ${PHP_ERROR_LOG}
|
||||
env[ServerIP] = ${ServerIP}
|
||||
EOF
|
||||
setup_web_port() {
|
||||
local warning="WARNING: Custom WEB_PORT not used"
|
||||
# Quietly exit early for empty or default
|
||||
if [[ -z "${1}" || "${1}" == '80' ]] ; then return ; fi
|
||||
|
||||
if [ -z "$VIRTUAL_HOST" ] ; then
|
||||
VIRTUAL_HOST="$ServerIP"
|
||||
fi;
|
||||
echo "env[VIRTUAL_HOST] = ${VIRTUAL_HOST}" >> "$PHP_ENV_CONFIG";
|
||||
if ! echo $1 | grep -q '^[0-9][0-9]*$' ; then
|
||||
echo "$warning - $1 is not an integer"
|
||||
return
|
||||
fi
|
||||
|
||||
local -i web_port="$1"
|
||||
if (( $web_port < 1 || $web_port > 65535 )); then
|
||||
echo "$warning - $web_port is not within valid port range of 1-65535"
|
||||
return
|
||||
fi
|
||||
echo "Custom WEB_PORT set to $web_port"
|
||||
echo "INFO: Without proper router DNAT forwarding to $ServerIP:$web_port, you may not get any blocked websites on ads"
|
||||
|
||||
# Update lighttpd's port
|
||||
sed -i '/server.port\s*=\s*80\s*$/ s/80/'$WEB_PORT'/g' /etc/lighttpd/lighttpd.conf
|
||||
# Update any default port 80 references in the HTML
|
||||
grep -Prl '://127\.0\.0\.1/' /var/www/html/ | xargs -r sed -i "s|/127\.0\.0\.1/|/127.0.0.1:${WEB_PORT}/|g"
|
||||
grep -Prl '://pi\.hole/' /var/www/html/ | xargs -r sed -i "s|/pi\.hole/|/pi\.hole:${WEB_PORT}/|g"
|
||||
|
||||
echo "Added ENV to php:"
|
||||
cat "$PHP_ENV_CONFIG"
|
||||
}
|
||||
|
||||
setup_web_password() {
|
||||
if [ -z "${WEBPASSWORD+x}" ] ; then
|
||||
if [ -z "${WEBPASSWORD+x}" ] ; then
|
||||
# Not set at all, give the user a random pass
|
||||
WEBPASSWORD=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
|
||||
echo "Assigning random password: $WEBPASSWORD"
|
||||
fi;
|
||||
# Turn bash debug on while setting up password (to print it)
|
||||
set -x
|
||||
if [[ "$WEBPASSWORD" == "" ]] ; then
|
||||
echo "" | pihole -a -p
|
||||
echo "" | pihole -a -p
|
||||
else
|
||||
pihole -a -p "$WEBPASSWORD" "$WEBPASSWORD"
|
||||
fi
|
||||
{ set +x; } 2>/dev/null
|
||||
pihole -a -p "$WEBPASSWORD" "$WEBPASSWORD"
|
||||
fi
|
||||
if [ "${PH_VERBOSE:-0}" -gt 0 ] ; then
|
||||
# Turn bash debug back off after print password setup
|
||||
# (subshell to null hides printing output)
|
||||
{ set +x; } 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
setup_ipv4_ipv6() {
|
||||
local ip_versions="IPv4 and IPv6"
|
||||
if [ "$IPv6" != "True" ] ; then
|
||||
ip_versions="IPv4"
|
||||
case $TAG in
|
||||
"debian") sed -i '/use-ipv6.pl/ d' /etc/lighttpd/lighttpd.conf ;;
|
||||
"alpine") sed -i '/listen \[::\]:80/ d' /etc/nginx/nginx.conf ;;
|
||||
esac
|
||||
sed -i '/use-ipv6.pl/ d' /etc/lighttpd/lighttpd.conf
|
||||
fi;
|
||||
echo "Using $ip_versions"
|
||||
}
|
||||
|
||||
test_configs() {
|
||||
case $TAG in
|
||||
"debian") test_configs_debian ;;
|
||||
"alpine") test_configs_alpine ;;
|
||||
esac
|
||||
}
|
||||
|
||||
test_configs_debian() {
|
||||
set -e
|
||||
echo -n '::: Testing DNSmasq config: '
|
||||
dnsmasq --test -7 /etc/dnsmasq.d
|
||||
echo -n '::: Testing pihole-FTL DNS: '
|
||||
pihole-FTL test || exit 1
|
||||
echo -n '::: Testing lighttpd config: '
|
||||
lighttpd -t -f /etc/lighttpd/lighttpd.conf
|
||||
lighttpd -t -f /etc/lighttpd/lighttpd.conf || exit 1
|
||||
set +e
|
||||
echo "::: All config checks passed, starting ..."
|
||||
echo "::: All config checks passed, cleared for startup ..."
|
||||
}
|
||||
|
||||
test_configs_alpine() {
|
||||
set -e
|
||||
echo -n '::: Testing DNSmasq config: '
|
||||
dnsmasq --test -7 /etc/dnsmasq.d
|
||||
echo -n '::: Testing PHP-FPM config: '
|
||||
php-fpm5 -t
|
||||
echo -n '::: Testing NGINX config: '
|
||||
nginx -t
|
||||
set +e
|
||||
echo "::: All config checks passed, starting ..."
|
||||
}
|
||||
|
||||
test_framework_stubbing() {
|
||||
if [ -n "$PYTEST" ] ; then
|
||||
echo ":::::: Tests are being ran - stub out ad list fetching and add a fake ad block"
|
||||
sed -i 's/^gravity_spinup$/#gravity_spinup # DISABLED FOR PYTEST/g' "$(which gravity.sh)"
|
||||
echo 'testblock.pi-hole.local' >> /etc/pihole/blacklist.txt
|
||||
fi
|
||||
}
|
||||
|
||||
docker_main() {
|
||||
echo -n '::: Starting up DNS and Webserver ...'
|
||||
service dnsmasq restart # Just get DNS up. The webserver is down!!!
|
||||
|
||||
TAG="$1"
|
||||
case $TAG in # Setup webserver
|
||||
"alpine")
|
||||
php-fpm5
|
||||
nginx
|
||||
;;
|
||||
"debian")
|
||||
service lighttpd start
|
||||
;;
|
||||
esac
|
||||
|
||||
gravity.sh # Finally lets update and be awesome.
|
||||
tail -F "${WEBLOGDIR}"/*.log /var/log/pihole.log
|
||||
|
||||
setup_blocklists() {
|
||||
local blocklists="$1"
|
||||
# Exit/return early without setting up adlists with defaults for any of the following conditions:
|
||||
# 1. NO_SETUP env is set
|
||||
exit_string="(exiting ${FUNCNAME[0]} early)"
|
||||
|
||||
if [ -n "${NO_SETUP}" ]; then
|
||||
echo "::: NO_SETUP requested ($exit_string)"
|
||||
return
|
||||
fi
|
||||
|
||||
# 2. The adlist file exists already (restarted container or volume mounted list)
|
||||
if [ -f "${adlistFile}" ]; then
|
||||
echo "::: Preexisting ad list ${adlistFile} detected ($exit_string)"
|
||||
cat "${adlistFile}"
|
||||
return
|
||||
fi
|
||||
|
||||
# 3. If we're running tests, use a small list of fake tests to speed everything up
|
||||
if [ -n "$PYTEST" ]; then
|
||||
echo ":::::: Tests are being ran - stub out ad list fetching and add a fake ad block ${exit_string}"
|
||||
sed -i 's/^gravity_spinup$/#gravity_spinup # DISABLED FOR PYTEST/g' "$(which gravity.sh)"
|
||||
echo '123.123.123.123 testblock.pi-hole.local' > "/var/www/html/fake.list"
|
||||
echo 'file:///var/www/html/fake.list' > "${adlistFile}"
|
||||
echo 'http://localhost/fake.list' >> "${adlistFile}"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "::: ${FUNCNAME[0]} now setting default blocklists up: "
|
||||
echo "::: TIP: Use a docker volume for ${adlistFile} if you want to customize for first boot"
|
||||
> "${adlistFile}"
|
||||
# Just copied outa the choices for now
|
||||
# https://github.com/pi-hole/pi-hole/blob/FTLDNS/automated%20install/basic-install.sh#L1014
|
||||
echo "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" >> "${adlistFile}"
|
||||
echo "https://mirror1.malwaredomains.com/files/justdomains" >> "${adlistFile}"
|
||||
echo "http://sysctl.org/cameleon/hosts" >> "${adlistFile}"
|
||||
echo "https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist" >> "${adlistFile}"
|
||||
echo "https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt" >> "${adlistFile}"
|
||||
echo "https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt" >> "${adlistFile}"
|
||||
echo "https://hosts-file.net/ad_servers.txt" >> "${adlistFile}"
|
||||
|
||||
echo "::: Blocklists (${adlistFile}) now set to:"
|
||||
cat "${adlistFile}"
|
||||
}
|
||||
|
||||
57
deploy_docker.sh
Executable file
57
deploy_docker.sh
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/bin/bash -ex
|
||||
# Script for manually pushing the docker arm images for diginc only
|
||||
# (no one else has docker repo permissions)
|
||||
if [ ! -f ~/.docker/config.json ] ; then
|
||||
echo "Error: You should setup your docker push authorization first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
parse_git_branch() {
|
||||
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
|
||||
}
|
||||
|
||||
namespace='pihole'
|
||||
localimg='pihole'
|
||||
remoteimg="$namespace/$localimg"
|
||||
branch="$(parse_git_branch)"
|
||||
version="${version:-unset}"
|
||||
dry="${dry}"
|
||||
latest="${latest:-false}" # true as shell env var to deploy latest
|
||||
|
||||
if [[ -n "$dry" ]]; then dry='echo '; fi
|
||||
|
||||
if [[ "$version" == 'unset' ]]; then
|
||||
if [[ "$branch" == "master" ]]; then
|
||||
echo "Version number var is unset and master branch needs a version...pass in \$version variable!"
|
||||
exit 1
|
||||
elif [[ "$branch" = "release/"* ]]; then
|
||||
version="$(echo $branch | grep -Po 'v[\d\.-]*')"
|
||||
echo "Version number is being taken from this release branch $version"
|
||||
else
|
||||
version="$branch"
|
||||
remoteimg="${namespace}/${localimg}-dev"
|
||||
echo "Using the branch ($branch) for deployed image version since not passed in"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "# DEPLOYING:"
|
||||
echo "version: $version"
|
||||
echo "branch: $branch"
|
||||
[[ -n "$dry" ]] && echo "DRY RUN: $dry"
|
||||
echo "Example tagging: docker tag $localimg:$tag $remoteimg:${version}_amd64"
|
||||
|
||||
$dry ./Dockerfile.py --arch=amd64 --arch=armhf --arch=aarch64
|
||||
|
||||
# ARMv6/armel doesn't have a FTL binary for v4.0 pi-hole
|
||||
# for tag in debian_armhf debian_aarch64 debian_armel; do
|
||||
for tag in amd64 armhf aarch64; do
|
||||
# Verison specific tags for ongoing history
|
||||
$dry docker tag $localimg:v4.0_$tag $remoteimg:${version}_${tag}
|
||||
$dry docker push pihole/pihole:${version}_${tag}
|
||||
# Floating latest tags (Conditionalize these to master?)
|
||||
if [[ "$tag" == 'amd64' ]] && [[ "$branch" == 'master' || "$latest" == 'true' ]] ; then
|
||||
# Latest tag should become a manifest for multiple architectures, not just amd64!
|
||||
$dry docker tag pihole:v4.0_amd64 pihole/pihole:latest
|
||||
$dry docker push pihole/pihole:latest
|
||||
fi;
|
||||
done
|
||||
@@ -1 +1 @@
|
||||
doco-alpine.yml
|
||||
doco-example.yml
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
docker build -f alpine.docker -t diginc/pi-hole:alpine .
|
||||
docker tag diginc/pi-hole:alpine diginc/pi-hole:latest
|
||||
docker build -f debian.docker -t diginc/pi-hole:debian .
|
||||
|
||||
IP_LOOKUP="$(ip route get 8.8.8.8 | awk '{ print $NF; exit }')" # May not work for VPN / tun0
|
||||
IP="${IP:-$IP_LOOKUP}" # use $IP, if set, otherwise IP_LOOKUP
|
||||
|
||||
# Alternative ports to not conflict with my real instance
|
||||
# shellcheck disable=SC2068
|
||||
docker run -it --rm --cap-add=NET_ADMIN \
|
||||
-p 5053:53/tcp \
|
||||
-p 5053:53/udp \
|
||||
-p 5080:80 \
|
||||
-e ServerIP="$IP" \
|
||||
-e VIRTUAL_HOST='pihole.diginc.lan:5080' \
|
||||
$@ \
|
||||
diginc/pi-hole:"${image:-alpine}"
|
||||
@@ -1,21 +1,30 @@
|
||||
#!/bin/bash
|
||||
IP_LOOKUP="$(ip route get 8.8.8.8 | awk '{ print $NF; exit }')" # May not work for VPN / tun0
|
||||
IPv6_LOOKUP="$(ip -6 route get 2001:4860:4860::8888 | awk '{ print $10; exit }')" # May not work for VPN / tun0
|
||||
# Lookups may not work for VPN / tun0
|
||||
IP_LOOKUP="$(ip route get 8.8.8.8 | awk '{ print $NF; exit }')"
|
||||
IPv6_LOOKUP="$(ip -6 route get 2001:4860:4860::8888 | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')"
|
||||
|
||||
# Just hard code these to your docker server's LAN IP if lookups aren't working
|
||||
IP="${IP:-$IP_LOOKUP}" # use $IP, if set, otherwise IP_LOOKUP
|
||||
IPv6="${IPv6:-$IPv6_LOOKUP}" # use $IPv6, if set, otherwise IP_LOOKUP
|
||||
DOCKER_CONFIGS="$(pwd)" # Default of directory you run this from, update to where ever.
|
||||
|
||||
echo "IP: ${IP} - IPv6: ${IPv6}"
|
||||
# Default of directory you run this from, update to where ever.
|
||||
DOCKER_CONFIGS="$(pwd)"
|
||||
|
||||
echo "### Make sure your IPs are correct, hard code ServerIP ENV VARs if necessary\nIP: ${IP}\nIPv6: ${IPv6}"
|
||||
|
||||
# Default ports + daemonized docker container
|
||||
docker run -d \
|
||||
--name pihole \
|
||||
-p 53:53/tcp -p 53:53/udp -p 80:80 \
|
||||
-p 53:53/tcp -p 53:53/udp \
|
||||
-p 67:67/udp \
|
||||
-p 80:80 \
|
||||
-p 443:443 \
|
||||
-v "${DOCKER_CONFIGS}/pihole/:/etc/pihole/" \
|
||||
-v "${DOCKER_CONFIGS}/dnsmasq.d/:/etc/dnsmasq.d/" \
|
||||
-e ServerIP="${IP:-$(ip route get 8.8.8.8 | awk '{ print $NF; exit }')}" \
|
||||
-e ServerIPv6="${IPv6:-$(ip -6 route get 2001:4860:4860::8888 | awk '{ print $10; exit }')}" \
|
||||
--restart=always \
|
||||
diginc/pi-hole:alpine
|
||||
-e ServerIP="${IP}" \
|
||||
-e ServerIPv6="${IPv6}" \
|
||||
--restart=unless-stopped \
|
||||
pihole/pihole:latest
|
||||
|
||||
echo -n "Your password for https://${IP}/admin/ is "
|
||||
docker logs pihole 2> /dev/null | grep 'password:'
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
version: "3"
|
||||
services:
|
||||
pihole:
|
||||
image: diginc/pi-hole:alpine
|
||||
environment:
|
||||
# enter your docker host IP here
|
||||
ServerIP:
|
||||
# IPv6 Address if your network supports it
|
||||
#ServerIPv6: 192.168.1.55
|
||||
volumes:
|
||||
- "./pihole/:/etc/pihole/"
|
||||
- "./dnsmasq.d/:/etc/dnsmasq.d/"
|
||||
ports:
|
||||
- "53:53/tcp"
|
||||
- "53:53/udp"
|
||||
- "80:80/tcp"
|
||||
restart: always
|
||||
@@ -1,11 +1,13 @@
|
||||
version: "3"
|
||||
services:
|
||||
pihole:
|
||||
image: diginc/pi-hole:alpine
|
||||
image: pihole/pihole:latest
|
||||
ports:
|
||||
- "53:53/tcp"
|
||||
- "53:53/udp"
|
||||
- "67:67/udp"
|
||||
- "80:80/tcp"
|
||||
- "443:443/tcp"
|
||||
environment:
|
||||
# enter your docker host IP here
|
||||
ServerIP:
|
||||
|
||||
123
install.sh
123
install.sh
@@ -1,88 +1,85 @@
|
||||
#!/bin/bash -ex
|
||||
mkdir -p /etc/pihole/
|
||||
export CORE_TAG='v3.1.4'
|
||||
export WEB_TAG='v3.1'
|
||||
export FTL_TAG='v2.11.1'
|
||||
mkdir -p /var/run/pihole
|
||||
# Production tags with valid web footers
|
||||
export CORE_TAG='v4.0'
|
||||
export WEB_TAG='v4.0'
|
||||
# Only use for pre-production / testing
|
||||
export USE_CUSTOM_BRANCHES=false
|
||||
|
||||
if [[ $USE_CUSTOM_BRANCHES == true ]] ; then
|
||||
CORE_TAG='development'
|
||||
fi
|
||||
|
||||
# Make pihole scripts fail searching for `systemctl`,
|
||||
# which fails pretty miserably in docker compared to `service`
|
||||
# For more info see docker/docker issue #7459
|
||||
mv "$(which systemctl)" /bin/no_systemctl && \
|
||||
which systemctl && mv "$(which systemctl)" /bin/no_systemctl
|
||||
# debconf-apt-progress seems to hang so get rid of it too
|
||||
mv "$(which debconf-apt-progress)" /bin/no_debconf-apt-progress
|
||||
which debconf-apt-progress && mv "$(which debconf-apt-progress)" /bin/no_debconf-apt-progress
|
||||
|
||||
# Get the install functions
|
||||
wget -O "$PIHOLE_INSTALL" https://raw.githubusercontent.com/pi-hole/pi-hole/${CORE_TAG}/automated%20install/basic-install.sh
|
||||
if [[ "$TAG" == 'alpine' ]] ; then
|
||||
sed -i '/OS distribution not supported/ i\ echo "Hi Alpine"' "$PIHOLE_INSTALL"
|
||||
sed -i '/OS distribution not supported/,+1d' "$PIHOLE_INSTALL"
|
||||
sed -i 's#nologin pihole#nologin pihole 2>/dev/null || adduser -S -s /sbin/nologin pihole#g' "$PIHOLE_INSTALL"
|
||||
# shellcheck disable=SC2016
|
||||
sed -i '/usermod -a -G/ s#$# 2> /dev/null || addgroup pihole ${LIGHTTPD_GROUP}#g' "$PIHOLE_INSTALL"
|
||||
sed -i 's/www-data/nginx/g' "$PIHOLE_INSTALL"
|
||||
sed -i '/LIGHTTPD_CFG/d' "${PIHOLE_INSTALL}"
|
||||
sed -i '/etc\/cron.d\//d' "${PIHOLE_INSTALL}"
|
||||
# For new FTL install lines
|
||||
sed -i 's/sha1sum --status --quiet/sha1sum -s/g' "${PIHOLE_INSTALL}"
|
||||
sed -i 's/install -T/install /g' "${PIHOLE_INSTALL}"
|
||||
# shellcheck disable=SC2016
|
||||
sed -i '/FTLinstall/ s/${binary}/pihole-FTL-musl-linux-x86_64/g' "${PIHOLE_INSTALL}"
|
||||
LIGHTTPD_USER="nginx" # shellcheck disable=SC2034
|
||||
LIGHTTPD_GROUP="nginx" # shellcheck disable=SC2034
|
||||
LIGHTTPD_CFG="lighttpd.conf.debian" # shellcheck disable=SC2034
|
||||
DNSMASQ_USER="dnsmasq" # shellcheck disable=SC2034
|
||||
fi
|
||||
curl https://raw.githubusercontent.com/pi-hole/pi-hole/${CORE_TAG}/automated%20install/basic-install.sh > "$PIHOLE_INSTALL"
|
||||
PH_TEST=true . "${PIHOLE_INSTALL}"
|
||||
|
||||
# Run only what we need from installer
|
||||
# Preseed variables to assist with using --unattended install
|
||||
{
|
||||
echo "PIHOLE_INTERFACE=eth0"
|
||||
echo "IPV4_ADDRESS=0.0.0.0"
|
||||
echo "IPV6_ADDRESS=0:0:0:0:0:0"
|
||||
echo "PIHOLE_DNS_1=8.8.8.8"
|
||||
echo "PIHOLE_DNS_2=8.8.4.4"
|
||||
echo "QUERY_LOGGING=true"
|
||||
echo "INSTALL_WEB_SERVER=true"
|
||||
echo "INSTALL_WEB_INTERFACE=true"
|
||||
echo "LIGHTTPD_ENABLED=true"
|
||||
}>> "${setupVars}"
|
||||
source $setupVars
|
||||
|
||||
export USER=pihole
|
||||
if [[ "$TAG" == 'debian' ]] ; then
|
||||
distro_check
|
||||
install_dependent_packages INSTALLER_DEPS[@]
|
||||
install_dependent_packages PIHOLE_DEPS[@]
|
||||
install_dependent_packages PIHOLE_WEB_DEPS[@]
|
||||
sed -i "/sleep 2/ d" /etc/init.d/dnsmasq # SLOW
|
||||
# IPv6 support for nc openbsd better than traditional
|
||||
apt-get install -y --force-yes netcat-openbsd
|
||||
elif [[ "$TAG" == 'alpine' ]] ; then
|
||||
apk add \
|
||||
dnsmasq \
|
||||
nginx \
|
||||
ca-certificates \
|
||||
php5-fpm php5-json php5-openssl php5-zip php5-sockets libxml2 \
|
||||
bc bash curl perl sudo git
|
||||
# S6 service like to be blocking/foreground
|
||||
sed -i 's|^;daemonize = yes|daemonize = no|' /etc/php5/php-fpm.conf
|
||||
fi
|
||||
distro_check
|
||||
|
||||
# fix permission denied to resolvconf post-inst /etc/resolv.conf moby/moby issue #1297
|
||||
apt-get -y install debconf-utils && echo resolvconf resolvconf/linkify-resolvconf boolean false | debconf-set-selections
|
||||
|
||||
# Tried this - unattended causes starting services during a build, should probably PR a flag to shut that off and switch to that
|
||||
#bash -ex "./${PIHOLE_INSTALL}" --unattended
|
||||
install_dependent_packages INSTALLER_DEPS[@]
|
||||
install_dependent_packages PIHOLE_DEPS[@]
|
||||
install_dependent_packages PIHOLE_WEB_DEPS[@]
|
||||
# IPv6 support for nc openbsd better than traditional
|
||||
apt-get install -y --force-yes netcat-openbsd
|
||||
|
||||
piholeGitUrl="${piholeGitUrl}"
|
||||
webInterfaceGitUrl="${webInterfaceGitUrl}"
|
||||
webInterfaceDir="${webInterfaceDir}"
|
||||
git clone "${piholeGitUrl}" "${PI_HOLE_LOCAL_REPO}"
|
||||
pushd "${PI_HOLE_LOCAL_REPO}"; git reset --hard "${CORE_TAG}"; popd;
|
||||
git clone "${webInterfaceGitUrl}" "${webInterfaceDir}"
|
||||
pushd "${webInterfaceDir}"; git reset --hard "${WEB_TAG}"; popd;
|
||||
|
||||
export PIHOLE_INTERFACE=eth0
|
||||
export IPV4_ADDRESS=0.0.0.0
|
||||
export IPV6_ADDRESS=0:0:0:0:0:0
|
||||
export PIHOLE_DNS_1=8.8.8.8
|
||||
export PIHOLE_DNS_2=8.8.4.4
|
||||
export QUERY_LOGGING=true
|
||||
tmpLog="/tmp/pihole-install.log"
|
||||
installLogLoc="${installLogLoc}"
|
||||
installPihole 2>&1 | tee "${tmpLog}"
|
||||
mv "${tmpLog}" /
|
||||
|
||||
tmpLog="${tmpLog}"
|
||||
instalLogLoc="${instalLogLoc}"
|
||||
installPihole | tee "${tmpLog}"
|
||||
sed -i 's/readonly //g' /opt/pihole/webpage.sh
|
||||
if [[ "$TAG" == 'alpine' ]] ; then
|
||||
cp /etc/.pihole/advanced/pihole.cron /etc/crontabs/pihole
|
||||
|
||||
# Fix hostname bug on block page
|
||||
sed -i "s/\$_SERVER\['SERVER_NAME'\]/\$_SERVER\['HTTP_HOST'\]/" /var/www/html/pihole/index.php
|
||||
if [[ $USE_CUSTOM_BRANCHES == true ]] ; then
|
||||
ln -s /bin/true /usr/local/bin/service
|
||||
echo "$CORE_TAG" | tee /etc/pihole/ftlbranch
|
||||
echo y | bash -x pihole checkout core $CORE_TAG
|
||||
echo y | bash -x pihole checkout web $CORE_TAG
|
||||
unlink /usr/local/bin/service
|
||||
else
|
||||
# Reset to our tags so version numbers get detected correctly
|
||||
pushd "${PI_HOLE_LOCAL_REPO}"; git reset --hard "${CORE_TAG}"; popd;
|
||||
pushd "${webInterfaceDir}"; git reset --hard "${WEB_TAG}"; popd;
|
||||
fi
|
||||
|
||||
|
||||
mv "${tmpLog}" "${instalLogLoc}"
|
||||
sed -i 's/readonly //g' /opt/pihole/webpage.sh
|
||||
|
||||
sed -i $'s/helpFunc() {/unsupportedFunc() {\\\n echo "Function not supported in Docker images"\\\n exit 0\\\n}\\\n\\\nhelpFunc() {/g' /usr/local/bin/pihole
|
||||
# Replace references to `updatePiholeFunc` with new `unsupportedFunc`
|
||||
sed -i $'s/updatePiholeFunc;;/unsupportedFunc;;/g' /usr/local/bin/pihole
|
||||
|
||||
touch /.piholeFirstBoot
|
||||
|
||||
# Fix dnsmasq in docker
|
||||
grep -q '^user=root' || echo -e '\nuser=root' >> /etc/dnsmasq.conf
|
||||
|
||||
@@ -9,11 +9,13 @@ applist:
|
||||
restart: always
|
||||
|
||||
pihole:
|
||||
image: diginc/pi-hole:alpine
|
||||
image: pihole/pihole:latest
|
||||
ports:
|
||||
- '53:53/tcp'
|
||||
- '53:53/udp'
|
||||
- "67:67/udp"
|
||||
- '8053:80/tcp'
|
||||
- "443:443/tcp"
|
||||
volumes:
|
||||
- '/var/log/pihole.log:/var/log/pihole.log'
|
||||
#net: host
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
supportedTags='^(alpine|debian)$'
|
||||
if ! (echo "$1" | grep -Pq "$supportedTags") ; then
|
||||
echo "$1 is not a supported tag"; exit 1;
|
||||
fi
|
||||
|
||||
unlink docker-compose.yml
|
||||
unlink Dockerfile
|
||||
|
||||
ln -s "doco-${1}.yml" docker-compose.yml
|
||||
ln -s "${1}.docker" Dockerfile
|
||||
@@ -1,6 +1,7 @@
|
||||
docker-compose
|
||||
jinja2
|
||||
pytest
|
||||
pytest-cov
|
||||
pytest-xdist
|
||||
testinfra==1.5.1
|
||||
jinja2
|
||||
tox
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
# Early DNS Startup for the gravity list process to use
|
||||
dnsmasq -7 /etc/dnsmasq.d
|
||||
|
||||
/start.sh
|
||||
gravity.sh
|
||||
|
||||
# Done with DNS, let s6 services start up properly configured dns now
|
||||
killall -9 dnsmasq
|
||||
@@ -1 +0,0 @@
|
||||
/etc/resolv.conf false doesntexist,0:1000 0664 0664
|
||||
@@ -1,45 +0,0 @@
|
||||
worker_processes 1;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
server {
|
||||
# PHP SERVER_NAME is empty unless set, which can bug out ipv6less setups
|
||||
server_name dockerpi.hole;
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
root /var/www/html;
|
||||
index pihole/index.php index.php;
|
||||
error_page 404 =200 /pihole/index.php;
|
||||
|
||||
location ~ .php$ {
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
location /*.js {
|
||||
index pihole/index.js
|
||||
error_page 404 =200 /pihole/index.js;
|
||||
}
|
||||
|
||||
location ~ ^/admin/ {
|
||||
add_header X-Pi-hole "The Pi-hole Web interface is working!";
|
||||
}
|
||||
|
||||
location / {
|
||||
add_header X-Pi-hole "A black hole for Internet advertisements." always;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
s6-echo "Starting crond"
|
||||
|
||||
exec -c
|
||||
fdmove -c 2 1 /usr/sbin/crond -f -L /var/log/cron -l 0 -c /etc/crontabs
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
kill -9 $(pgrep dnsmasq)
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-echo "Starting dnsmasq"
|
||||
|
||||
s6-setuidgid root dnsmasq -7 /etc/dnsmasq.d --no-daemon
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-svwait -u -t 5000 /var/run/s6/services/php-fpm
|
||||
s6-echo "Starting nginx"
|
||||
|
||||
nginx -g "daemon off;"
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-echo "Starting php-fpm"
|
||||
|
||||
php-fpm5 -d daemonize=no
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-echo "Starting pihole-FTL"
|
||||
pihole-FTL no-daemon
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/usr/bin/with-contenv sh
|
||||
|
||||
#
|
||||
# This script will determine the network IP of the container.
|
||||
#
|
||||
# Return format should be a single IP address.
|
||||
#
|
||||
|
||||
# Default to using the value of the $HOSTNAME ENV variable.
|
||||
getent hosts ${1:-$HOSTNAME} | awk '{print $1}'
|
||||
@@ -1,235 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Pi-hole: A black hole for Internet advertisements
|
||||
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
||||
# Network-wide ad blocking via your own hardware.
|
||||
#
|
||||
# Whitelists and blacklists domains
|
||||
#
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
|
||||
|
||||
#globals
|
||||
basename=pihole
|
||||
piholeDir=/etc/${basename}
|
||||
whitelist=${piholeDir}/whitelist.txt
|
||||
blacklist=${piholeDir}/blacklist.txt
|
||||
readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf"
|
||||
reload=false
|
||||
addmode=true
|
||||
verbose=true
|
||||
|
||||
domList=()
|
||||
domToRemoveList=()
|
||||
|
||||
listMain=""
|
||||
listAlt=""
|
||||
|
||||
helpFunc() {
|
||||
|
||||
if [[ ${listMain} == ${whitelist} ]]; then
|
||||
letter="w"
|
||||
word="white"
|
||||
else
|
||||
letter="b"
|
||||
word="black"
|
||||
fi
|
||||
|
||||
cat << EOM
|
||||
::: Immediately ${word}lists one or more domains in the hosts file
|
||||
:::
|
||||
::: Usage: pihole -${letter} domain1 [domain2 ...]
|
||||
:::
|
||||
::: Options:
|
||||
::: -d, --delmode Remove domains from the ${word}list
|
||||
::: -nr, --noreload Update ${word}list without refreshing dnsmasq
|
||||
::: -q, --quiet Output is less verbose
|
||||
::: -h, --help Show this help dialog
|
||||
::: -l, --list Display your ${word}listed domains
|
||||
EOM
|
||||
if [[ "${letter}" == "b" ]]; then
|
||||
echo "::: -wild, --wildcard Add wildcard entry (only blacklist)"
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
EscapeRegexp() {
|
||||
# This way we may safely insert an arbitrary
|
||||
# string in our regular expressions
|
||||
# Also remove leading "." if present
|
||||
echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
|
||||
}
|
||||
|
||||
HandleOther(){
|
||||
# First, convert everything to lowercase
|
||||
domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
|
||||
|
||||
#check validity of domain
|
||||
validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/')
|
||||
if [ -z "${validDomain}" ]; then
|
||||
echo "::: $1 is not a valid argument or domain name"
|
||||
else
|
||||
domList=("${domList[@]}" ${validDomain})
|
||||
fi
|
||||
}
|
||||
|
||||
PoplistFile() {
|
||||
#check whitelist file exists, and if not, create it
|
||||
if [[ ! -f ${whitelist} ]]; then
|
||||
touch ${whitelist}
|
||||
fi
|
||||
for dom in "${domList[@]}"; do
|
||||
# Logic : If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other
|
||||
if ${addmode}; then
|
||||
AddDomain "${dom}" "${listMain}"
|
||||
RemoveDomain "${dom}" "${listAlt}"
|
||||
if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then
|
||||
RemoveDomain "${dom}" "${wildcardlist}"
|
||||
fi
|
||||
else
|
||||
RemoveDomain "${dom}" "${listMain}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
AddDomain() {
|
||||
list="$2"
|
||||
domain=$(EscapeRegexp "$1")
|
||||
|
||||
if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
|
||||
|
||||
bool=true
|
||||
#Is the domain in the list we want to add it to?
|
||||
grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
|
||||
|
||||
if [[ "${bool}" == false ]]; then
|
||||
#domain not found in the whitelist file, add it!
|
||||
if [[ "${verbose}" == true ]]; then
|
||||
echo "::: Adding $1 to $list..."
|
||||
fi
|
||||
reload=true
|
||||
# Add it to the list we want to add it to
|
||||
echo "$1" >> "${list}"
|
||||
else
|
||||
if [[ "${verbose}" == true ]]; then
|
||||
echo "::: ${1} already exists in ${list}, no need to add!"
|
||||
fi
|
||||
fi
|
||||
|
||||
elif [[ "${list}" == "${wildcardlist}" ]]; then
|
||||
|
||||
source "${piholeDir}/setupVars.conf"
|
||||
#Remove the /* from the end of the IPv4addr.
|
||||
IPV4_ADDRESS=${IPV4_ADDRESS%/*}
|
||||
IPV6_ADDRESS=${IPV6_ADDRESS}
|
||||
|
||||
bool=true
|
||||
#Is the domain in the list?
|
||||
grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
|
||||
|
||||
if [[ "${bool}" == false ]]; then
|
||||
if [[ "${verbose}" == true ]]; then
|
||||
echo "::: Adding $1 to wildcard blacklist..."
|
||||
fi
|
||||
reload=true
|
||||
echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}"
|
||||
if [[ ${#IPV6_ADDRESS} > 0 ]] ; then
|
||||
echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}"
|
||||
fi
|
||||
else
|
||||
if [[ "${verbose}" == true ]]; then
|
||||
echo "::: ${1} already exists in wildcard blacklist, no need to add!"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
RemoveDomain() {
|
||||
list="$2"
|
||||
domain=$(EscapeRegexp "$1")
|
||||
|
||||
if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
|
||||
|
||||
bool=true
|
||||
#Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
|
||||
grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
|
||||
if [[ "${bool}" == true ]]; then
|
||||
# Remove it from the other one
|
||||
echo "::: Removing $1 from $list..."
|
||||
# Busybox sed compatible case-insensitive domain removal
|
||||
sed -i "$(grep -in "^${domain}$" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list}
|
||||
reload=true
|
||||
else
|
||||
if [[ "${verbose}" == true ]]; then
|
||||
echo "::: ${1} does not exist in ${list}, no need to remove!"
|
||||
fi
|
||||
fi
|
||||
|
||||
elif [[ "${list}" == "${wildcardlist}" ]]; then
|
||||
|
||||
bool=true
|
||||
#Is it in the list?
|
||||
grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
|
||||
if [[ "${bool}" == true ]]; then
|
||||
# Remove it from the other one
|
||||
echo "::: Removing $1 from $list..."
|
||||
# Busybox sed compatible case-insensitive domain removal
|
||||
sed -i "$(grep -in "/${domain}/" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list}
|
||||
reload=true
|
||||
else
|
||||
if [[ "${verbose}" == true ]]; then
|
||||
echo "::: ${1} does not exist in ${list}, no need to remove!"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
Reload() {
|
||||
# Reload hosts file
|
||||
pihole -g -sd
|
||||
}
|
||||
|
||||
Displaylist() {
|
||||
if [[ ${listMain} == ${whitelist} ]]; then
|
||||
string="gravity resistant domains"
|
||||
else
|
||||
string="domains caught in the sinkhole"
|
||||
fi
|
||||
verbose=false
|
||||
echo -e " Displaying $string \n"
|
||||
count=1
|
||||
while IFS= read -r RD; do
|
||||
echo "${count}: ${RD}"
|
||||
count=$((count+1))
|
||||
done < "${listMain}"
|
||||
exit 0;
|
||||
}
|
||||
|
||||
for var in "$@"; do
|
||||
case "${var}" in
|
||||
"-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";;
|
||||
"-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";;
|
||||
"-wild" | "wildcard" ) listMain="${wildcardlist}";;
|
||||
"-nr"| "--noreload" ) reload=false;;
|
||||
"-d" | "--delmode" ) addmode=false;;
|
||||
"-f" | "--force" ) force=true;;
|
||||
"-q" | "--quiet" ) verbose=false;;
|
||||
"-h" | "--help" ) helpFunc;;
|
||||
"-l" | "--list" ) Displaylist;;
|
||||
* ) HandleOther "${var}";;
|
||||
esac
|
||||
done
|
||||
|
||||
shift
|
||||
|
||||
if [[ $# = 0 ]]; then
|
||||
helpFunc
|
||||
fi
|
||||
|
||||
PoplistFile
|
||||
|
||||
if ${reload}; then
|
||||
Reload
|
||||
fi
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/usr/bin/execlineb -S0
|
||||
|
||||
if { s6-test $# -eq 2 }
|
||||
|
||||
backtick -in FILENAME {
|
||||
pipeline { s6-echo "${1}" }
|
||||
tr "a-z" "A-Z"
|
||||
}
|
||||
import -u FILENAME
|
||||
|
||||
redirfd -w 1 /var/run/s6/container_environment/${FILENAME}
|
||||
s6-echo -n -- ${2}
|
||||
@@ -1,10 +1,16 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
set -e
|
||||
|
||||
# Early DNS Startup for the gravity list process to use
|
||||
dnsmasq -7 /etc/dnsmasq.d
|
||||
bashCmd='bash -e'
|
||||
if [ "${PH_VERBOSE:-0}" -gt 0 ] ; then
|
||||
set -x ;
|
||||
bashCmd='bash -e -x'
|
||||
fi
|
||||
|
||||
/start.sh
|
||||
# used to start dnsmasq here for gravity to use...now that conflicts port 53
|
||||
|
||||
$bashCmd /start.sh
|
||||
gravity.sh
|
||||
|
||||
# Done with DNS, let s6 services start up properly configured dns now
|
||||
killall -9 dnsmasq
|
||||
# Kill dnsmasq because s6 won't like it if it's running when s6 services start
|
||||
kill -9 $(pgrep pihole-FTL) || true
|
||||
|
||||
4
s6/debian-root/etc/services.d/cron/finish
Normal file
4
s6/debian-root/etc/services.d/cron/finish
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-echo "Stopping cron"
|
||||
killall -9 cron
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
kill -9 $(pgrep dnsmasq)
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-echo "Starting dnsmasq"
|
||||
|
||||
s6-setuidgid root dnsmasq -7 /etc/dnsmasq.d --no-daemon
|
||||
4
s6/debian-root/etc/services.d/lighttpd/finish
Normal file
4
s6/debian-root/etc/services.d/lighttpd/finish
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-echo "Stopping lighttpd"
|
||||
killall -9 lighttpd
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-echo "Starting lighttpd"
|
||||
|
||||
lighttpd -D -f /etc/lighttpd/lighttpd.conf
|
||||
|
||||
4
s6/debian-root/etc/services.d/pihole-FTL/finish
Normal file
4
s6/debian-root/etc/services.d/pihole-FTL/finish
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-echo "Stopping pihole-FTL"
|
||||
kill -9 $(pgrep pihole-FTL)
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
s6-echo "Starting pihole-FTL"
|
||||
pihole-FTL no-daemon
|
||||
s6-echo "Starting pihole-FTL ($FTL_CMD)"
|
||||
s6-setuidgid root pihole-FTL $FTL_CMD
|
||||
|
||||
|
||||
15
s6/timeout
Executable file
15
s6/timeout
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
# A shim to make busybox timeout take in debian style args
|
||||
# v1 only need support for this style: `timeout 1 getent hosts github.com`
|
||||
|
||||
# Busybox args:
|
||||
# Usage: timeout [-t SECS] [-s SIG] PROG ARGS
|
||||
# Debian args:
|
||||
# Usage: timeout [OPTION] DURATION COMMAND [ARG]...
|
||||
# or: timeout [OPTION]
|
||||
|
||||
TIMEOUT=/usr/bin/timeout
|
||||
SECS="${1}"
|
||||
ARGS="${@:2}"
|
||||
|
||||
$TIMEOUT -t $SECS $ARGS
|
||||
6
setup.py
Normal file
6
setup.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
setup_requires=['pytest-runner'],
|
||||
tests_require=['pytest'],
|
||||
)
|
||||
38
start.sh
38
start.sh
@@ -12,22 +12,44 @@ export DNS1
|
||||
export DNS2
|
||||
export INTERFACE
|
||||
export IPv6
|
||||
export WEB_PORT
|
||||
export PLAINWEBPASSWORD="$WEBPASSWORD"
|
||||
|
||||
export adlistFile='/etc/pihole/adlists.list'
|
||||
|
||||
# The below functions are all contained in bash_functions.sh
|
||||
. /bash_functions.sh
|
||||
|
||||
echo " ::: Starting docker specific setup for docker diginc/pi-hole"
|
||||
# Some of the bash_functions use variables these core pi-hole/web scripts
|
||||
. /opt/pihole/webpage.sh
|
||||
# PH_TEST prevents the install from actually running (someone should rename that)
|
||||
PH_TEST=true . $PIHOLE_INSTALL
|
||||
|
||||
echo " ::: Starting docker specific setup for docker pihole/pihole"
|
||||
validate_env || exit 1
|
||||
prepare_setup_vars
|
||||
prepare_configs
|
||||
change_setting "IPV4_ADDRESS" "$ServerIP"
|
||||
change_setting "IPV6_ADDRESS" "$ServerIPv6"
|
||||
setup_web_password "$WEBPASSWORD"
|
||||
setup_dnsmasq "$DNS1" "$DNS2"
|
||||
setup_web_port "$WEB_PORT"
|
||||
setup_web_password "$PLAINWEBPASSWORD"
|
||||
setup_dnsmasq "$DNS1" "$DNS2" "$INTERFACE"
|
||||
setup_php_env
|
||||
setup_dnsmasq_hostnames "$ServerIP" "$ServerIPv6" "$HOSTNAME"
|
||||
setup_ipv4_ipv6
|
||||
setup_lighttpd_bind "$ServerIP" "$TAG"
|
||||
setup_lighttpd_bind "$ServerIP"
|
||||
setup_blocklists
|
||||
test_configs
|
||||
test_framework_stubbing
|
||||
echo "::: Docker start setup complete - beginning s6 services"
|
||||
|
||||
# s6's init takes care of running services now, no more main start services function
|
||||
[ -f /.piholeFirstBoot ] && rm /.piholeFirstBoot
|
||||
|
||||
echo " ::: Docker start setup complete"
|
||||
|
||||
echo """
|
||||
:: ::: ::: ::: ::: ::: ::: ::: ::: :::
|
||||
:: Image moved / deprecation notice
|
||||
:: OLD IMAGE : diginc/pi-hole
|
||||
:: NEW IMAGE : pihole/pihole
|
||||
:: In order to get the latest updates
|
||||
:: please update your image references
|
||||
:: ::: ::: ::: ::: ::: ::: ::: ::: :::
|
||||
"""
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import pytest
|
||||
import testinfra
|
||||
|
||||
WEB_SERVER = { 'alpine_amd64': 'nginx', 'debian_amd64': 'lighttpd' }
|
||||
|
||||
check_output = testinfra.get_backend(
|
||||
"local://"
|
||||
).get_module("Command").check_output
|
||||
|
||||
def DockerGeneric(request, args, image, cmd):
|
||||
def DockerGeneric(request, args, image, cmd, entrypoint=''):
|
||||
assert 'docker' in check_output('id'), "Are you in the docker group?"
|
||||
if 'pi-hole' in image:
|
||||
args += " --dns 127.0.0.1 -v /dev/null:/etc/.pihole/adlists.default -e PYTEST=\"True\""
|
||||
docker_run = "docker run -d {} {} {}".format(args, image, cmd)
|
||||
if 'pihole' in image:
|
||||
args += " --dns 127.0.0.1 -v /dev/null:/etc/pihole/adlists.default -e PYTEST=\"True\""
|
||||
docker_run = "docker run -d {args} {entry} {image} {cmd}".format(args=args, entry=entrypoint, image=image, cmd=cmd)
|
||||
print docker_run
|
||||
docker_id = check_output(docker_run)
|
||||
|
||||
@@ -39,62 +37,83 @@ def DockerGeneric(request, args, image, cmd):
|
||||
docker_container.run = funcType(run_bash, docker_container, testinfra.backend.docker.DockerBackend)
|
||||
return docker_container
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def Docker(request, args, image, cmd):
|
||||
def Docker(request, args, image, cmd, entrypoint):
|
||||
''' One-off Docker container run '''
|
||||
return DockerGeneric(request, args, image, cmd)
|
||||
return DockerGeneric(request, args, image, cmd, entrypoint)
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def DockerPersist(request, persist_args, persist_image, persist_cmd, Dig):
|
||||
''' Persistent Docker container for multiple tests '''
|
||||
''' Persistent Docker container for multiple tests, instead of stopping container after one test '''
|
||||
''' Uses DUP'd module scoped fixtures because smaller scoped fixtures won't mix with module scope '''
|
||||
persistent_container = DockerGeneric(request, persist_args, persist_image, persist_cmd)
|
||||
''' attach a dig conatiner for lookups '''
|
||||
persistent_container.dig = Dig(persistent_container.id)
|
||||
return persistent_container
|
||||
|
||||
@pytest.fixture
|
||||
def entrypoint():
|
||||
return ''
|
||||
|
||||
@pytest.fixture()
|
||||
def args(request):
|
||||
return '-e ServerIP="127.0.0.1" -e ServerIPv6="::1"'
|
||||
|
||||
@pytest.fixture(params=['amd64', 'armhf', 'aarch64'])
|
||||
@pytest.fixture(params=['amd64', 'armel', 'armhf', 'aarch64'])
|
||||
def arch(request):
|
||||
return request.param
|
||||
|
||||
@pytest.fixture(params=['debian', 'alpine'])
|
||||
def os(request):
|
||||
return request.param
|
||||
@pytest.fixture()
|
||||
def version(request):
|
||||
''' TODO: include from external .py that can be shared with Dockerfile.py / Tests / deploy scripts '''
|
||||
return 'v4.0'
|
||||
|
||||
@pytest.fixture()
|
||||
def tag(request, os, arch):
|
||||
return '{}_{}'.format(os, arch)
|
||||
def tag(request, version, arch):
|
||||
return '{}_{}'.format(version, arch)
|
||||
|
||||
@pytest.fixture
|
||||
def webserver(request, tag):
|
||||
return WEB_SERVER[tag]
|
||||
''' TODO: this is obvious without alpine+nginx as the alternative, remove fixture, hard code lighttpd in tests? '''
|
||||
return 'lighttpd'
|
||||
|
||||
@pytest.fixture()
|
||||
def image(request, tag):
|
||||
return 'pi-hole:{}'.format(tag)
|
||||
image = 'pihole'
|
||||
return '{}:{}'.format(image, tag)
|
||||
|
||||
@pytest.fixture()
|
||||
def cmd(request):
|
||||
return 'tail -f /dev/null'
|
||||
|
||||
@pytest.fixture(scope='module', params=['amd64'])
|
||||
def persist_arch(request):
|
||||
'''amd64 only, dnsmasq/pihole-FTL(?untested?) will not start under qemu-user-static :('''
|
||||
return request.param
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def persist_version(request):
|
||||
''' TODO: include from external .py that can be shared with Dockerfile.py / Tests / deploy scripts '''
|
||||
return 'v4.0'
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def persist_args(request):
|
||||
return '-e ServerIP="127.0.0.1" -e ServerIPv6="::1"'
|
||||
|
||||
@pytest.fixture(scope='module', params=['alpine_amd64', 'debian_amd64'])
|
||||
def persist_tag(request):
|
||||
return request.param
|
||||
@pytest.fixture(scope='module')
|
||||
def persist_tag(request, persist_version, persist_arch):
|
||||
return '{}_{}'.format(persist_version, persist_arch)
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def persist_webserver(request, persist_tag):
|
||||
return WEB_SERVER[persist_tag]
|
||||
''' TODO: this is obvious without alpine+nginx as the alternative, remove fixture, hard code lighttpd in tests? '''
|
||||
return 'lighttpd'
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def persist_image(request, persist_tag):
|
||||
return 'pi-hole:{}'.format(persist_tag)
|
||||
image = 'pihole'
|
||||
return '{}:{}'.format(image, persist_tag)
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def persist_cmd(request):
|
||||
@@ -138,7 +157,6 @@ Persistent Docker container for testing service post start.sh
|
||||
@pytest.fixture
|
||||
def RunningPiHole(DockerPersist, Slow, persist_webserver):
|
||||
''' Persist a fully started docker-pi-hole to help speed up subsequent tests '''
|
||||
Slow(lambda: DockerPersist.run('pgrep dnsmasq').rc == 0)
|
||||
Slow(lambda: DockerPersist.run('pgrep {}'.format(persist_webserver) ).rc == 0)
|
||||
Slow(lambda: DockerPersist.run('pgrep pihole-FTL').rc == 0)
|
||||
Slow(lambda: DockerPersist.run('pgrep lighttpd').rc == 0)
|
||||
return DockerPersist
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
''' This file starts with 000 to make it run first '''
|
||||
import pytest
|
||||
import testinfra
|
||||
import DockerfileGeneration
|
||||
|
||||
run_local = testinfra.get_backend(
|
||||
"local://"
|
||||
).get_module("Command").run
|
||||
|
||||
|
||||
def test_generate_dockerfiles():
|
||||
DockerfileGeneration.generate_dockerfiles()
|
||||
|
||||
@pytest.mark.parametrize('arch', [ 'amd64', 'armhf', 'aarch64' ])
|
||||
@pytest.mark.parametrize('os', [ 'debian', 'alpine' ])
|
||||
def test_build_pihole_image(os, arch):
|
||||
''' Build the entire matrix of OS+Architecture '''
|
||||
dockerfile = 'Dockerfile_{}_{}'.format(os, arch)
|
||||
image_tag = '{}:{}_{}'.format('pi-hole', os, arch)
|
||||
build_cmd = run_local('docker build --pull -f {} -t {} .'.format(dockerfile, image_tag))
|
||||
if build_cmd.rc != 0:
|
||||
print build_cmd.stdout
|
||||
print build_cmd.stderr
|
||||
assert build_cmd.rc == 0
|
||||
@@ -9,33 +9,99 @@ DEFAULTARGS = '-e ServerIP="127.0.0.1" '
|
||||
(DEFAULTARGS + '-e "IPv6=False"', False, 'IPv4'),
|
||||
(DEFAULTARGS + '-e "IPv6=foobar"', False, 'IPv4'),
|
||||
])
|
||||
def test_IPv6_not_True_removes_ipv6(Docker, os, args, expected_ipv6, expected_stdout):
|
||||
def test_IPv6_not_True_removes_ipv6(Docker, args, expected_ipv6, expected_stdout):
|
||||
''' When a user overrides IPv6=True they only get IPv4 listening webservers '''
|
||||
IPV6_LINE = { 'alpine': 'listen [::]:80 default_server',
|
||||
'debian': 'use-ipv6.pl' }
|
||||
WEB_CONFIG = { 'alpine': '/etc/nginx/nginx.conf',
|
||||
'debian': '/etc/lighttpd/lighttpd.conf' }
|
||||
IPV6_LINE = 'use-ipv6.pl'
|
||||
WEB_CONFIG = '/etc/lighttpd/lighttpd.conf'
|
||||
|
||||
function = Docker.run('. /bash_functions.sh ; setup_ipv4_ipv6')
|
||||
assert "Using {}".format(expected_stdout) in function.stdout
|
||||
config = Docker.run('cat {}'.format( WEB_CONFIG[os])).stdout
|
||||
assert (IPV6_LINE[os] in config) == expected_ipv6
|
||||
config = Docker.run('cat {}'.format(WEB_CONFIG)).stdout
|
||||
assert (IPV6_LINE in config) == expected_ipv6
|
||||
|
||||
@pytest.mark.parametrize('args, expected_stdout, dns1, dns2', [
|
||||
('-e ServerIP="1.2.3.4"', 'default DNS', '8.8.8.8', '8.8.4.4' ),
|
||||
('-e ServerIP="1.2.3.4" -e DNS1="1.2.3.4"', 'custom DNS', '1.2.3.4', '8.8.4.4' ),
|
||||
('-e ServerIP="1.2.3.4" -e DNS2="1.2.3.4"', 'custom DNS', '8.8.8.8', '1.2.3.4' ),
|
||||
('-e ServerIP="1.2.3.4" -e DNS1="1.2.3.4" -e DNS2="2.2.3.4"', 'custom DNS', '1.2.3.4', '2.2.3.4' ),
|
||||
@pytest.mark.parametrize('args', [DEFAULTARGS + '-e "WEB_PORT=999"'])
|
||||
def test_overrides_default_WEB_PORT(Docker, args):
|
||||
''' When a --net=host user sets WEB_PORT to avoid synology's 80 default IPv4 and or IPv6 ports are updated'''
|
||||
CONFIG_LINE = 'server.port\s*=\s*999'
|
||||
WEB_CONFIG = '/etc/lighttpd/lighttpd.conf'
|
||||
|
||||
function = Docker.run('. /bash_functions.sh ; eval `grep setup_web_port /start.sh`')
|
||||
assert "Custom WEB_PORT set to 999" in function.stdout
|
||||
assert "INFO: Without proper router DNAT forwarding to 127.0.0.1:999, you may not get any blocked websites on ads" in function.stdout
|
||||
config = Docker.run('cat {}'.format(WEB_CONFIG)).stdout
|
||||
assert re.search(CONFIG_LINE, config) != None
|
||||
# grep fails to find any of the old address w/o port
|
||||
assert Docker.run('grep -rq "://127.0.0.1/" /var/www/html/').rc == 1
|
||||
assert Docker.run('grep -rq "://pi.hole/" /var/www/html/').rc == 1
|
||||
# Find at least one instance of our changes
|
||||
# upstream repos determines how many and I don't want to keep updating this test
|
||||
assert int(Docker.run('grep -rl "://127.0.0.1:999/" /var/www/html/ | wc -l').stdout) >= 1
|
||||
assert int(Docker.run('grep -rl "://pi.hole:999/" /var/www/html/ | wc -l').stdout) >= 1
|
||||
|
||||
@pytest.mark.parametrize('args,expected_error', [
|
||||
(DEFAULTARGS + '-e WEB_PORT="LXXX"', 'WARNING: Custom WEB_PORT not used - LXXX is not an integer'),
|
||||
(DEFAULTARGS + '-e WEB_PORT="1,000"', 'WARNING: Custom WEB_PORT not used - 1,000 is not an integer'),
|
||||
(DEFAULTARGS + '-e WEB_PORT="99999"', 'WARNING: Custom WEB_PORT not used - 99999 is not within valid port range of 1-65535'),
|
||||
])
|
||||
def test_DNS_Envs_override_defaults(Docker, args, expected_stdout, dns1, dns2):
|
||||
''' When DNS environment vars are passed in, they override default dns servers '''
|
||||
def test_bad_input_to_WEB_PORT(Docker, args, expected_error):
|
||||
function = Docker.run('. /bash_functions.sh ; eval `grep setup_web_port /start.sh`')
|
||||
assert expected_error in function.stdout
|
||||
|
||||
|
||||
# DNS Environment Variable behavior in combinations of modified pihole LTE settings
|
||||
@pytest.mark.parametrize('args, expected_stdout, dns1, dns2', [
|
||||
('-e ServerIP="1.2.3.4"', 'default DNS', '8.8.8.8', '8.8.4.4' ),
|
||||
('-e ServerIP="1.2.3.4" -e DNS1="1.2.3.4"', 'custom DNS', '1.2.3.4', '8.8.4.4' ),
|
||||
('-e ServerIP="1.2.3.4" -e DNS2="1.2.3.4"', 'custom DNS', '8.8.8.8', '1.2.3.4' ),
|
||||
('-e ServerIP="1.2.3.4" -e DNS1="1.2.3.4" -e DNS2="2.2.3.4"', 'custom DNS', '1.2.3.4', '2.2.3.4' ),
|
||||
('-e ServerIP="1.2.3.4" -e DNS1="1.2.3.4" -e DNS2="no"', 'custom DNS', '1.2.3.4', None ),
|
||||
('-e ServerIP="1.2.3.4" -e DNS2="no"', 'custom DNS', '8.8.8.8', None ),
|
||||
])
|
||||
def test_override_default_servers_with_DNS_EnvVars(Docker, args, expected_stdout, dns1, dns2):
|
||||
''' on first boot when DNS vars are NOT set explain default google DNS settings are used
|
||||
or when DNS vars are set override the pihole DNS settings '''
|
||||
assert Docker.run('test -f /.piholeFirstBoot').rc == 0
|
||||
function = Docker.run('. /bash_functions.sh ; eval `grep setup_dnsmasq /start.sh`')
|
||||
assert expected_stdout in function.stdout
|
||||
|
||||
docker_dns_servers = Docker.run('grep "^server=" /etc/dnsmasq.d/01-pihole.conf').stdout
|
||||
expected_servers = 'server={}\nserver={}\n'.format(dns1, dns2)
|
||||
expected_servers = 'server={}\n'.format(dns1) if dns2 == None else 'server={}\nserver={}\n'.format(dns1, dns2)
|
||||
assert expected_servers == docker_dns_servers
|
||||
|
||||
@pytest.mark.parametrize('args, dns1, dns2, expected_stdout', [
|
||||
('-e ServerIP="1.2.3.4"', '9.9.9.1', '9.9.9.2',
|
||||
'Existing DNS servers used'),
|
||||
('-e ServerIP="1.2.3.4" -e DNS1="1.2.3.4"', '9.9.9.1', '9.9.9.2',
|
||||
'Docker DNS variables not used\nExisting DNS servers used'),
|
||||
('-e ServerIP="1.2.3.4" -e DNS2="1.2.3.4"', '8.8.8.8', '1.2.3.4',
|
||||
'Docker DNS variables not used\nExisting DNS servers used'),
|
||||
('-e ServerIP="1.2.3.4" -e DNS1="1.2.3.4" -e DNS2="2.2.3.4"', '1.2.3.4', '2.2.3.4',
|
||||
'Docker DNS variables not used\nExisting DNS servers used'),
|
||||
])
|
||||
def test_DNS_Envs_are_secondary_to_setupvars(Docker, args, expected_stdout, dns1, dns2):
|
||||
''' on second boot when DNS vars are set just use pihole DNS settings
|
||||
or when DNS vars and FORCE_DNS var are set override the pihole DNS settings '''
|
||||
# Given we are not booting for the first time
|
||||
assert Docker.run('rm /.piholeFirstBoot').rc == 0
|
||||
|
||||
# and a user already has custom pihole dns variables in setup vars
|
||||
setupVars = '/etc/pihole/setupVars.conf'
|
||||
Docker.run('sed -i "/^PIHOLE_DNS_1/ c\PIHOLE_DNS_1={}" {}'.format(dns1, setupVars))
|
||||
Docker.run('sed -i "/^PIHOLE_DNS_2/ c\PIHOLE_DNS_2={}" {}'.format(dns2, setupVars))
|
||||
|
||||
# When we run setup dnsmasq during startup of the container
|
||||
function = Docker.run('. /bash_functions.sh ; eval `grep setup_dnsmasq /start.sh`')
|
||||
assert expected_stdout in function.stdout
|
||||
|
||||
expected_servers = 'server={}\nserver={}\n'.format(dns1, dns2)
|
||||
servers = Docker.run('grep "^server=" /etc/dnsmasq.d/01-pihole.conf').stdout
|
||||
searchDns1 = servers.split('\n')[0]
|
||||
searchDns2 = servers.split('\n')[1]
|
||||
|
||||
# Then the servers are still what the user had customized if forced dnsmasq is not set
|
||||
assert 'server={}'.format(dns1) == searchDns1
|
||||
assert 'server={}'.format(dns2) == searchDns2
|
||||
|
||||
@pytest.mark.parametrize('args, expected_stdout, expected_config_line', [
|
||||
('-e ServerIP="1.2.3.4"', 'binding to default interface: eth0', 'interface=eth0' ),
|
||||
('-e ServerIP="1.2.3.4" -e INTERFACE="eth0"', 'binding to default interface: eth0', 'interface=eth0' ),
|
||||
@@ -54,11 +120,11 @@ expected_debian_lines = [
|
||||
'"ServerIP" => "127.0.0.1"',
|
||||
'"PHP_ERROR_LOG" => "/var/log/lighttpd/error.log"'
|
||||
]
|
||||
@pytest.mark.parametrize('os,expected_lines,repeat_function', [
|
||||
('debian', expected_debian_lines, 1),
|
||||
('debian', expected_debian_lines, 2)
|
||||
@pytest.mark.parametrize('expected_lines,repeat_function', [
|
||||
(expected_debian_lines, 1),
|
||||
(expected_debian_lines, 2)
|
||||
])
|
||||
def test_debian_setup_php_env(Docker, os, expected_lines, repeat_function):
|
||||
def test_debian_setup_php_env(Docker, expected_lines, repeat_function):
|
||||
''' confirm all expected output is there and nothing else '''
|
||||
stdout = ''
|
||||
for i in range(repeat_function):
|
||||
@@ -66,7 +132,9 @@ def test_debian_setup_php_env(Docker, os, expected_lines, repeat_function):
|
||||
for expected_line in expected_lines:
|
||||
search_config_cmd = "grep -c '{}' /etc/lighttpd/conf-enabled/15-fastcgi-php.conf".format(expected_line)
|
||||
search_config_count = Docker.run(search_config_cmd)
|
||||
assert search_config_count.stdout.rstrip('\n') == '1'
|
||||
found_lines = int(search_config_count.stdout.rstrip('\n'))
|
||||
if found_lines > 1:
|
||||
assert False, "Found line {} times (more than once): {}".format(expected_line)
|
||||
|
||||
@pytest.mark.parametrize('args,secure,setupVarsHash', [
|
||||
('-e ServerIP=1.2.3.4 -e WEBPASSWORD=login', True, 'WEBPASSWORD=6060d59351e8c2f48140f01b2c3f3b61652f396c53a5300ae239ebfbe7d5ff08'),
|
||||
|
||||
@@ -8,17 +8,18 @@ def start_cmd():
|
||||
@pytest.fixture
|
||||
def RunningPiHole(DockerPersist, Slow, persist_webserver, persist_tag, start_cmd):
|
||||
''' Override the RunningPiHole to run and check for success of a
|
||||
dnsmasq start based `pihole` script command '''
|
||||
pihole-FTL start based `pihole` script command '''
|
||||
#print DockerPersist.run('ps -ef').stdout
|
||||
Slow(lambda: DockerPersist.run('pgrep dnsmasq').rc == 0)
|
||||
assert DockerPersist.dig.run('ping -c 1 test_pihole').rc == 0
|
||||
Slow(lambda: DockerPersist.run('pgrep pihole-FTL').rc == 0)
|
||||
Slow(lambda: DockerPersist.run('pgrep {}'.format(persist_webserver)).rc == 0)
|
||||
oldpid = DockerPersist.run('pidof dnsmasq')
|
||||
oldpid = DockerPersist.run('pidof pihole-FTL')
|
||||
cmd = DockerPersist.run('pihole {}'.format(start_cmd))
|
||||
Slow(lambda: DockerPersist.run('pgrep dnsmasq').rc == 0)
|
||||
newpid = DockerPersist.run('pidof dnsmasq')
|
||||
Slow(lambda: DockerPersist.run('pgrep pihole-FTL').rc == 0)
|
||||
newpid = DockerPersist.run('pidof pihole-FTL')
|
||||
for pid in [oldpid, newpid]:
|
||||
assert pid != ''
|
||||
# ensure a new pid for dnsmasq appeared due to service restart
|
||||
# ensure a new pid for pihole-FTL appeared due to service restart
|
||||
assert oldpid != newpid
|
||||
assert cmd.rc == 0
|
||||
# Save out cmd result to check different stdout of start/enable/disable
|
||||
@@ -30,15 +31,17 @@ def test_pihole_start_cmd(RunningPiHole, start_cmd, persist_tag):
|
||||
''' the start_cmd tests are all built into the RunningPiHole fixture in this file '''
|
||||
assert RunningPiHole.cmd.stdout == START_DNS_STDOUT[persist_tag]
|
||||
|
||||
@pytest.mark.parametrize('start_cmd,hostname,expected_ip, expected_message', [
|
||||
('enable', 'pi.hole', '127.0.0.1', 'enabled'),
|
||||
('disable 0', 'pi.hole', '127.0.0.1', 'disabled'),
|
||||
@pytest.mark.parametrize('start_cmd,hostname,expected_ip, expected_messages', [
|
||||
('enable', 'pi.hole', '127.0.0.1', ['Enabling blocking','Pi-hole Enabled']),
|
||||
('disable', 'pi.hole', '127.0.0.1', ['Disabling blocking','Pi-hole Disabled']),
|
||||
])
|
||||
def test_pihole_start_cmd(RunningPiHole, Dig, persist_tag, start_cmd, hostname, expected_ip, expected_message):
|
||||
def test_pihole_start_cmd(RunningPiHole, Dig, persist_tag, start_cmd, hostname, expected_ip, expected_messages):
|
||||
''' the start_cmd tests are all built into the RunningPiHole fixture in this file '''
|
||||
dig_cmd = "dig +time=1 +noall +answer {} @test_pihole | awk '{{ print $5 }}'".format(hostname)
|
||||
lookup = RunningPiHole.dig.run(dig_cmd).stdout.rstrip('\n')
|
||||
assert lookup == expected_ip
|
||||
dig_cmd = "dig +time=1 +noall +answer {} @test_pihole".format(hostname)
|
||||
lookup = RunningPiHole.dig.run(dig_cmd)
|
||||
assert lookup.rc == 0
|
||||
lookup_ip = lookup.stdout.split()[4]
|
||||
assert lookup_ip == expected_ip
|
||||
|
||||
stdout = "::: Blocking has been {}!\n".format(expected_message)
|
||||
assert stdout in RunningPiHole.cmd.stdout
|
||||
for part_of_output in expected_messages:
|
||||
assert part_of_output in RunningPiHole.cmd.stdout
|
||||
|
||||
@@ -2,17 +2,10 @@ import pytest
|
||||
import time
|
||||
''' conftest.py provides the defaults through fixtures '''
|
||||
''' Note, testinfra builtins don't seem fully compatible with
|
||||
docker containers (esp. alpine) stripped down nature '''
|
||||
|
||||
def test_pihole_default_run_command(Docker, tag):
|
||||
expected_proc = '/sbin/tini -- /start.sh'
|
||||
pgrep = 'pgrep -f "{}" | wc -l || echo 0'.format(expected_proc)
|
||||
find_proc = Docker.run(pgrep).stdout
|
||||
if int(find_proc) < 1:
|
||||
print Docker.run('ps -ef')
|
||||
print "{} : {}".format(pgrep, find_proc)
|
||||
assert False, '{}: Couldn\'t find proc {}'.format(tag, expected_proc)
|
||||
docker containers (esp. musl based OSs) stripped down nature '''
|
||||
|
||||
# If the test runs /start.sh, do not let s6 run it too! Kill entrypoint to avoid race condition/duplicated execution
|
||||
@pytest.mark.parametrize('entrypoint,cmd', [('--entrypoint=tail','-f /dev/null')])
|
||||
@pytest.mark.parametrize('args', [ '' ])
|
||||
def test_ServerIP_missing_triggers_start_error(Docker):
|
||||
''' When args to docker are empty start.sh exits saying ServerIP is required '''
|
||||
@@ -21,10 +14,12 @@ def test_ServerIP_missing_triggers_start_error(Docker):
|
||||
assert start.rc == 1
|
||||
assert error_msg in start.stdout
|
||||
|
||||
# If the test runs /start.sh, do not let s6 run it too! Kill entrypoint to avoid race condition/duplicated execution
|
||||
@pytest.mark.parametrize('entrypoint,cmd', [('--entrypoint=tail','-f /dev/null')])
|
||||
@pytest.mark.parametrize('args,error_msg,expect_rc', [
|
||||
('-e ServerIP="1.2.3.z"', "ServerIP Environment variable (1.2.3.z) doesn't appear to be a valid IPv4 address",1),
|
||||
('-e ServerIP="1.2.3.4" -e ServerIPv6="1234:1234:1234:ZZZZ"', "Environment variable (1234:1234:1234:ZZZZ) doesn't appear to be a valid IPv6 address",1),
|
||||
('-e ServerIP="1.2.3.4" -e ServerIPv6="kernel"', "WARNING: You passed in IPv6 with a value of 'kernel'",0),
|
||||
('-e ServerIP="1.2.3.4" -e ServerIPv6="kernel"', "ERROR: You passed in IPv6 with a value of 'kernel'",1),
|
||||
])
|
||||
def test_ServerIP_invalid_IPs_triggers_exit_error(Docker, error_msg, expect_rc):
|
||||
''' When args to docker are empty start.sh exits saying ServerIP is required '''
|
||||
@@ -48,24 +43,38 @@ def test_indecies_are_present(RunningPiHole):
|
||||
File('/var/www/html/pihole/index.html').exists
|
||||
File('/var/www/html/pihole/index.js').exists
|
||||
|
||||
def validate_curl(http_rc, expected_http_code, page_contents):
|
||||
if int(http_rc.rc) != 0 or int(http_rc.stdout) != expected_http_code:
|
||||
print 'CURL return code: {}'.format(http_rc.rc)
|
||||
print 'CURL stdout: {}'.format(http_rc.stdout)
|
||||
print 'CURL stderr:{}'.format(http_rc.stderr)
|
||||
print 'CURL file:\n{}\n'.format(page_contents.encode('ascii'))
|
||||
|
||||
@pytest.mark.parametrize('addr', [ 'testblock.pi-hole.local' ])
|
||||
@pytest.mark.parametrize('url', [ '/', '/index.html', '/any.html' ] )
|
||||
def test_html_index_requests_load_as_expected(RunningPiHole, Slow, addr, url):
|
||||
command = 'curl -s -o /tmp/curled_file -w "%{{http_code}}" http://{}{}'.format(addr, url)
|
||||
http_rc = RunningPiHole.run(command)
|
||||
assert http_rc.rc == 0
|
||||
assert int(http_rc.stdout) == 200
|
||||
page_contents = RunningPiHole.run('cat /tmp/curled_file ').stdout
|
||||
assert 'blocked' in page_contents
|
||||
expected_http_code = 200
|
||||
|
||||
validate_curl(http_rc, expected_http_code, page_contents)
|
||||
assert http_rc.rc == 0
|
||||
assert int(http_rc.stdout) == expected_http_code
|
||||
assert 'testblock.pi-hole.local' in page_contents
|
||||
|
||||
@pytest.mark.parametrize('addr', [ 'testblock.pi-hole.local' ])
|
||||
@pytest.mark.parametrize('url', [ '/index.js', '/any.js'] )
|
||||
def test_javascript_requests_load_as_expected(RunningPiHole, addr, url):
|
||||
command = 'curl -s -o /tmp/curled_file -w "%{{http_code}}" http://{}{}'.format(addr, url)
|
||||
http_rc = RunningPiHole.run(command)
|
||||
page_contents = RunningPiHole.run('cat /tmp/curled_file ').stdout
|
||||
expected_http_code = 200
|
||||
|
||||
validate_curl(http_rc, expected_http_code, page_contents)
|
||||
assert http_rc.rc == 0
|
||||
assert int(http_rc.stdout) == 200
|
||||
assert RunningPiHole.run('md5sum /tmp/curled_file /var/www/html/pihole/index.js').rc == 0
|
||||
assert int(http_rc.stdout) == expected_http_code
|
||||
assert 'var x = "Pi-hole: A black hole for Internet advertisements."' in page_contents
|
||||
|
||||
# IPv6 checks aren't passing CORS, removed :(
|
||||
@pytest.mark.parametrize('addr', [ 'localhost' ] )
|
||||
@@ -73,9 +82,12 @@ def test_javascript_requests_load_as_expected(RunningPiHole, addr, url):
|
||||
def test_admin_requests_load_as_expected(RunningPiHole, addr, url):
|
||||
command = 'curl -s -o /tmp/curled_file -w "%{{http_code}}" http://{}{}'.format(addr, url)
|
||||
http_rc = RunningPiHole.run(command)
|
||||
assert http_rc.rc == 0
|
||||
assert int(http_rc.stdout) == 200
|
||||
assert RunningPiHole.run('wc -l /tmp/curled_file ') > 10
|
||||
assert RunningPiHole.run('grep -q "Content-Security-Policy" /tmp/curled_file ').rc == 0
|
||||
assert RunningPiHole.run('grep -q "scripts/pi-hole/js/footer.js" /tmp/curled_file ').rc == 0
|
||||
page_contents = RunningPiHole.run('cat /tmp/curled_file ').stdout
|
||||
expected_http_code = 200
|
||||
|
||||
validate_curl(http_rc, expected_http_code, page_contents)
|
||||
assert http_rc.rc == 0
|
||||
assert int(http_rc.stdout) == expected_http_code
|
||||
for html_text in ['dns_queries_today', 'Content-Security-Policy', 'scripts/pi-hole/js/footer.js']:
|
||||
assert html_text in page_contents
|
||||
|
||||
|
||||
13
tox.ini
Normal file
13
tox.ini
Normal file
@@ -0,0 +1,13 @@
|
||||
[tox]
|
||||
envlist = py27
|
||||
|
||||
[testenv]
|
||||
whitelist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
# 2 parallel max b/c race condition with docker fixture (I think?)
|
||||
commands = docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
./Dockerfile.py -v --arch amd64
|
||||
pytest -vv -n 2 -k amd64 ./test/
|
||||
./Dockerfile.py -v --arch armhf --arch aarch64
|
||||
pytest -vv -n 2 -k armhf ./test/
|
||||
pytest -vv -n 2 -k aarch64 ./test/
|
||||
106
traefik-docker-compose-example.md
Normal file
106
traefik-docker-compose-example.md
Normal file
@@ -0,0 +1,106 @@
|
||||
Please note the following about this [traefik](https://traefik.io/) example for pihole.
|
||||
|
||||
- Still requires standard pi-hole setup steps, make sure you've gone through the [README](https://github.com/pihole/docker-pi-hole/blob/master/README.md) and understand how to setup pihole without traefik first
|
||||
- Update these things before using:
|
||||
- set instances of `homedomain.lan` below to your home domain (typically set in your router)
|
||||
- set your pihole ENV WEBPASSWORD if you don't want a random admin pass
|
||||
- This works for me, Your mileage may vary!
|
||||
- For support, do your best to figure out traefik issues on your own:
|
||||
- by looking at logs and traefik web interface on port 8080
|
||||
- also by searching the web and searching their forums/docker issues for similar question/problems
|
||||
- Port 8053 is mapped directly to pihole to serve as a back door without going through traefik
|
||||
- There is some delay after starting your container before traefik forwards the HTTP traffic correctly, give it a minute
|
||||
|
||||
```
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
#
|
||||
traefik:
|
||||
container_name: traefik
|
||||
domainname: homedomain.lan
|
||||
|
||||
image: traefik
|
||||
restart: unless-stopped
|
||||
# Note I opt to whitelist certain apps for exposure to traefik instead of auto discovery
|
||||
# use `--docker.exposedbydefault=true` if you don't want to have to do this
|
||||
command: "--web --docker --docker.domain=homedomain.lan --docker.exposedbydefault=false --logLevel=DEBUG"
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /dev/null:/traefik.toml
|
||||
networks:
|
||||
- default
|
||||
- discovery
|
||||
dns:
|
||||
- 192.168.1.50
|
||||
- 192.168.1.1
|
||||
|
||||
pihole:
|
||||
container_name: pihole
|
||||
domainname: homedomain.lan
|
||||
|
||||
image: pihole/pihole:latest
|
||||
ports:
|
||||
- '0.0.0.0:53:53/tcp'
|
||||
- '0.0.0.0:53:53/udp'
|
||||
- '0.0.0.0:67:67/udp'
|
||||
- '0.0.0.0:8053:80/tcp'
|
||||
volumes:
|
||||
# run `touch ./pihole.log` first unless you like errors
|
||||
# - ./pihole.log:/var/log/pihole.log
|
||||
- ./etc-pihole/:/etc/pihole/
|
||||
- ./etc-dnsmasqd/:/etc/dnsmasq.d/
|
||||
environment:
|
||||
ServerIP: 192.168.1.50
|
||||
PROXY_LOCATION: pihole
|
||||
VIRTUAL_HOST: pihole.homedomain.lan
|
||||
VIRTUAL_PORT: 80
|
||||
TZ: 'America/Chicago'
|
||||
# WEBPASSWORD:
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
# required when using --docker.exposedbydefault=false
|
||||
- "traefik.enable=true"
|
||||
# https://www.techjunktrunk.com/docker/2017/11/03/traefik-default-server-catch-all/
|
||||
- "traefik.frontend.rule=HostRegexp:pihole.homedomain.lan,{catchall:.*}"
|
||||
- "traefik.frontend.priority=1"
|
||||
- "traefik.backend=pihole"
|
||||
- "traefik.port=80"
|
||||
|
||||
networks:
|
||||
# Discovery is manually created to avoid forcing any order of docker-compose stack creation (`docker network create discovery`)
|
||||
# allows other compose files to be seen by proxy
|
||||
# Not required if you aren't using multiple docker-compose files...
|
||||
discovery:
|
||||
external: true
|
||||
```
|
||||
|
||||
After running `docker-compose up -d` you should see this if you look at logs on traefik `docker-compose logs -f traefik`
|
||||
|
||||
```
|
||||
traefik | time="2018-03-07T18:57:41Z" level=debug msg="Provider event received {Status:health_status: healthy ID:33567e94e02c5adba3d47fa44c391e94fdea359fb05eecb196c95de288ffb861 From:pihole/pihole:latest Type:container Action:health_status: healthy Actor:{ID:33567e94
|
||||
e02c5adba3d47fa44c391e94fdea359fb05eecb196c95de288ffb861 Attributes:map[com.docker.compose.project:traefik image:pihole/pihole:latest traefik.frontend.priority:1 com.docker.compose.container-number:1 com.docker.compose.service:pihole com.docker.compose.version:1.19.0 name:pihole traefik.enable:true url:https://www.github.com/pihole/docker-pi-hole com.docker.compose.oneoff:False maintainer:adam@diginc.us traefik.backend:pihole traefik.frontend.rule:HostRegexp:pihole.homedomain.lan,{catchall:.*} traefik.port:80 com.docker.compose.config-
|
||||
hash:7551c3f4bd11766292c7dad81473ef21da91cae8666d1b04a42d1daab53fba0f]} Scope:local Time:1520449061 TimeNano:1520449061934970670}"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Filtering disabled container /traefik"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Could not load traefik.frontend.whitelistSourceRange labels"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Could not load traefik.frontend.entryPoints labels"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Could not load traefik.frontend.auth.basic labels"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Validation of load balancer method for backend backend-pihole failed: invalid load-balancing method ''. Using default method wrr."
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Configuration received from provider docker: {"backends":{"backend-pihole":{"servers":{"server-pihole":{"url":"http://172.18.0.2:80","weight":0}},"loadBalancer":{"method":"wrr"}}},"frontends":{"frontend-HostRegexp
|
||||
-pihole-homedomain-lan-catchall-0":{"entryPoints":["http"],"backend":"backend-pihole","routes":{"route-frontend-HostRegexp-pihole-homedomain-lan-catchall-0":{"rule":"HostRegexp:pihole.homedomain.lan,{catchall:.*}"}},"passHostHeader":true,"priority":1,"basicAuth":[]}}}"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Creating frontend frontend-HostRegexp-pihole-homedomain-lan-catchall-0"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Wiring frontend frontend-HostRegexp-pihole-homedomain-lan-catchall-0 to entryPoint http"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Creating route route-frontend-HostRegexp-pihole-homedomain-lan-catchall-0 HostRegexp:pihole.homedomain.lan,{catchall:.*}"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Creating backend backend-pihole"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Creating load-balancer wrr"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=debug msg="Creating server server-pihole at http://172.18.0.2:80 with weight 0"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=info msg="Server configuration reloaded on :80"
|
||||
traefik | time="2018-03-07T18:57:42Z" level=info msg="Server configuration reloaded on :8080"
|
||||
```
|
||||
|
||||
Also your port 8080 should list the Route/Rule for pihole and backend-pihole container.
|
||||
|
||||
Reference in New Issue
Block a user