1
0
mirror of https://github.com/pi-hole/docker-pi-hole.git synced 2024-06-20 06:26:38 +02:00

Merge pull request #91 from diginc/master

update dev with latest master release code
This commit is contained in:
Adam Hill 2017-01-18 20:25:12 -06:00 committed by GitHub
commit 35a282b45d
24 changed files with 257 additions and 256 deletions

6
.gitmodules vendored
View File

@ -1,6 +0,0 @@
[submodule "pi-hole"]
path = pi-hole
url = https://github.com/pi-hole/pi-hole.git
[submodule "AdminLTE"]
path = AdminLTE
url = https://github.com/pi-hole/AdminLTE.git

View File

@ -7,4 +7,4 @@ python:
install:
- pip install -r requirements.txt
script: py.test -vv
script: py.test -vv test/

@ -1 +0,0 @@
Subproject commit 3e6955d4a01d78bb8c73a8f9fcec6d3be51bea4c

View File

@ -1 +0,0 @@
v1.4.4.2

View File

@ -4,7 +4,7 @@ A [Docker](https://www.docker.com/what-docker) project to make lightweight x86 a
* The current Raspbian install is simply `curl -sSL https://get.docker.com | sh` [[1]](https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/)
[![Build Status](https://travis-ci.org/diginc/docker-pi-hole.svg?branch=master)](https://travis-ci.org/diginc/docker-pi-hole) [![Docker Stars](https://img.shields.io/docker/stars/diginc/pi-hole.svg?maxAge=604800)](https://hub.docker.com/r/diginc/pi-hole/) [![Docker Pulls](https://img.shields.io/docker/pulls/diginc/pi-hole.svg?maxAge=604800)](https://hub.docker.com/r/diginc/pi-hole/)
[![Build Status](https://api.travis-ci.org/diginc/docker-pi-hole.svg?branch=master)](https://travis-ci.org/diginc/docker-pi-hole) [![Docker Stars](https://img.shields.io/docker/stars/diginc/pi-hole.svg?maxAge=604800)](https://hub.docker.com/r/diginc/pi-hole/) [![Docker Pulls](https://img.shields.io/docker/pulls/diginc/pi-hole.svg?maxAge=604800)](https://hub.docker.com/r/diginc/pi-hole/)
[![Join the chat at https://gitter.im/diginc/docker-pi-hole](https://badges.gitter.im/diginc/docker-pi-hole.svg)](https://gitter.im/diginc/docker-pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@ -16,12 +16,12 @@ One crucial thing to know before starting is the docker-pi-hole container needs
```
IMAGE='diginc/pi-hole'
NIC='eth0'
IP=$(ip addr show $NIC | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
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
docker run -p 53:53/tcp -p 53:53/udp -p 80:80 --cap-add=NET_ADMIN -e ServerIP="$IP" --name pihole -d $IMAGE
# Recommended auto ad list updates & log rotation:
wget -O- https://raw.githubusercontent.com/diginc/docker-pi-hole/master/docker-pi-hole.cron | sudo tee /etc/cron.d/docker-pi-hole.cron
wget -O- https://raw.githubusercontent.com/diginc/docker-pi-hole/master/docker-pi-hole.cron | sudo tee /etc/cron.d/docker-pi-hole
```
This is just an example and might need changing. For exmaple of you're running on a raspberry pi over wireless you'll probably want to change your NIC variable to `wlan0` and IMAGE to `diginc/pi-hole:arm`
@ -46,8 +46,8 @@ In addition to the required environment variable you saw above (`-e ServerIP="$I
* 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
* Don't forget to stop your services from auto-starting again after you reboot
* Port 80 is required 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 exising webserver you run you'll probably need a reverse proxy websever 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 pi-hole is served out instead of any other sites hosted by the proxy. This behavior is taken advantage of so any ad domain can be directed to your webserver and get blank html/images/videos instead of ads.
* [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 exmaple which is based off what I run.
* Port 80 is required 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 pi-hole is served out instead of any other sites hosted by the proxy. This behavior is taken advantage of so any ad domain can be directed to your webserver and get blank html/images/videos instead of ads.
* [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.
## Volume Mounts
Here are some useful volume mount options to persist your history of stats in the admin interface, or add custom whitelists/blacklists. **Create these files on the docker host first or you'll get errors**:
@ -68,15 +68,15 @@ The primary docker tags / versions are as follows. [Click here to see the full
| `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) |
### `diginc/pi-hole:alpine` [![](https://images.microbadger.com/badges/image/diginc/pi-hole:alpine.svg)](http://microbadger.com/images/diginc/pi-hole "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/version/diginc/pi-hole:alpine.svg)](http://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com") [![](https://images.microbadger.com/badges/version/diginc/pi-hole:latest.svg)](http://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com")
### `diginc/pi-hole:alpine` [![](https://images.microbadger.com/badges/image/diginc/pi-hole:alpine.svg)](https://microbadger.com/images/diginc/pi-hole "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/version/diginc/pi-hole:alpine.svg)](https://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com") [![](https://images.microbadger.com/badges/version/diginc/pi-hole:latest.svg)](https://microbadger.com/images/diginc/pi-hole "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.
### `diginc/pi-hole:debian` [![](https://images.microbadger.com/badges/image/diginc/pi-hole:debian.svg)](http://microbadger.com/images/diginc/pi-hole "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/version/diginc/pi-hole:debian.svg)](http://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com")
### `diginc/pi-hole:debian` [![](https://images.microbadger.com/badges/image/diginc/pi-hole:debian.svg)](https://microbadger.com/images/diginc/pi-hole "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/version/diginc/pi-hole:debian.svg)](https://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com")
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 nice baseline for merging and testing upstream repository pi-hole changes.
### `diginc/pi-hole:arm` [![](https://images.microbadger.com/badges/image/diginc/pi-hole:arm.svg)](http://microbadger.com/images/diginc/pi-hole "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/version/diginc/pi-hole:arm.svg)](http://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com")
### `diginc/pi-hole:arm` [![](https://images.microbadger.com/badges/image/diginc/pi-hole:arm.svg)](https://microbadger.com/images/diginc/pi-hole "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/version/diginc/pi-hole:arm.svg)](https://microbadger.com/images/diginc/pi-hole "Get your own version badge on microbadger.com")
As close to the debian image as possible, 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/).
@ -84,7 +84,7 @@ Alpine doesn't have an arm cross compileable image at this time.
## 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 incase you have remove 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
@ -124,7 +124,7 @@ Similarly for the webserver you can customize configs in /etc/nginx (*:alpine* t
## Development [![Build Status](https://travis-ci.org/diginc/docker-pi-hole.svg?branch=dev)](https://travis-ci.org/diginc/docker-pi-hole)
## Development [![Build Status](https://api.travis-ci.org/diginc/docker-pi-hole.svg?branch=dev)](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:

View File

@ -2,50 +2,29 @@ FROM alpine:edge
MAINTAINER adam@diginc.us <adam@diginc.us>
ENV IMAGE alpine
ENV PATH /opt/pihole:${PATH}
COPY install.sh /install.sh
COPY ./alpine/service /usr/local/bin/service
ENV setupVars /etc/pihole/setupVars.conf
ENV PIHOLE_INSTALL /tmp/ph_install.sh
ENV TINI_VERSION v0.13.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static /tini
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static.asc /tini.asc
# Tini and package requirements
RUN apk add --update gpgme && \
RUN apk add --update 'gnupg<2.1.17-r0' && \
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 0527A9B7 && \
gpg --verify /tini.asc && \
chmod +x /tini && \
apk add \
dnsmasq \
nginx \
ca-certificates \
php5-fpm php5-json php5-openssl libxml2 \
bc bash curl perl sudo git && \
apk add wget bash && \
/install.sh && \
rm -rf /var/cache/apk/*
# Customized from submodules
COPY ./pi-hole/gravity.sh /usr/local/bin/
COPY ./pi-hole/advanced/Scripts/* /usr/local/bin/
COPY ./pi-hole/pihole /usr/local/bin/
RUN sed -i 's|service dnsmasq restart|kill -9 $(pidof dnsmasq); dnsmasq -7 /etc/dnsmasq.d|g' \
/usr/local/bin/pihole \
/usr/local/bin/gravity.sh \
/usr/local/bin/list.sh
RUN sed -i 's|service dnsmasq start|dnsmasq -7 /etc/dnsmasq.d|g' \
/usr/local/bin/pihole \
/usr/local/bin/gravity.sh \
/usr/local/bin/list.sh
COPY ./alpine/nginx.conf /etc/nginx/nginx.conf
# Original upstream pihole code being used
COPY ./pi-hole/adlists.default /etc/pihole/
COPY ./pi-hole/adlists.default /etc/.pihole/
RUN mkdir -p /opt/ && ln -s /usr/local/bin /opt/pihole
COPY ./pi-hole/advanced/dnsmasq.conf.original /etc/dnsmasq.conf
COPY ./pi-hole/advanced/01-pihole.conf /etc/dnsmasq.d/
COPY ./pi-hole/advanced/index* /var/www/html/pihole/
COPY ./pi-hole/advanced/pihole.sudo /etc/sudoers.d/pihole
COPY ./AdminLTE /var/www/html/admin
COPY ./AdminLTE_version.txt /etc/
COPY ./pi-hole_version.txt /etc/
# Things installer did and fix alpine+nginx differences
ENV WEBLOGDIR /var/log/nginx
ENV PHP_CONFIG '/etc/php5/php-fpm.conf'
@ -61,16 +40,11 @@ RUN mkdir -p /etc/pihole/ && \
chmod 644 /var/log/pihole.log && \
chown dnsmasq:root /var/log/pihole.log && \
sed -i "s/@INT@/eth0/" /etc/dnsmasq.d/01-pihole.conf && \
sed -i 's|"cd /etc/.pihole/ && git describe --tags --abbrev=0"|"cat /etc/pi-hole_version.txt"|g' /var/www/html/admin/footer.php && \
sed -i 's|"git describe --tags --abbrev=0"|"cat /etc/AdminLTE_version.txt"|g' /var/www/html/admin/footer.php && \
sed -i 's|www-data|nginx|g' /etc/sudoers.d/pihole && \
/bin/true # placeholder
echo 'Done!'
# This chould be eliminated if all (upstream) files were +x in git
RUN chmod +x /usr/local/bin/*.sh
# Fix dnsmasq in docker
RUN grep -q '^user=root' || echo 'user=root' >> /etc/dnsmasq.conf
#sed -i 's|"cd /etc/.pihole/ && git describe --tags --abbrev=0"|"cat /etc/pi-hole_version.txt"|g' /var/www/html/admin/footer.php && \
#sed -i 's|"git describe --tags --abbrev=0"|"cat /etc/AdminLTE_version.txt"|g' /var/www/html/admin/footer.php && \
#sed -i 's|www-data|nginx|g' /etc/sudoers.d/pihole && \
# php config start passes special ENVs into
ENV PHP_ENV_CONFIG '/etc/php5/fpm.d/envs.conf'
@ -84,5 +58,6 @@ ENV IPv6 True
EXPOSE 53 53/udp
EXPOSE 80
SHELL ["/bin/bash", "-c"]
ENTRYPOINT ["/tini", "--"]
CMD [ "/start.sh" ]

View File

@ -15,18 +15,15 @@ http {
listen 80;
listen [::]:80;
root /var/www/html;
index index.php pihole/index.html;
error_page 404 =200 /pihole/index.html;
index pihole/index.php index.php;
error_page 404 =200 /pihole/index.php;
location ~ ^/admin/ {
add_header X-Pi-hole "The Pi-hole Web interface is working!";
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
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 {
@ -34,6 +31,10 @@ http {
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;
}

55
alpine/service Executable file
View File

@ -0,0 +1,55 @@
#!/bin/bash
# lazy cheap service script patch for alpine
dnsmasq_start() {
dnsmasq -7 /etc/dnsmasq.d
}
dnsmasq_stop() {
kill -9 $(pidof dnsmasq)
}
dnsmasq_restart() {
dnsmasq_stop; dnsmasq_start;
}
status() {
if pidof $service 2&>1 > /dev/null ; then
echo "$service running"
else
echo "$service not running"
fi;
}
nginx_start() {
nginx -t && \
nginx
}
nginx_stop() {
nginx -t && \
kill -9 $(pidof nginx)
}
nginx_restart() {
nginx_stop
nginx_start
}
dnsmasq_status() {
status
}
nginx_status() {
status
}
service="$1"
command="$2"
if [[ "$service" == 'lighttpd' ]] ; then
echo -e "Lighttpd replaced by nginx in diginc/pi-hole:alpine\nrunning service nginx $command instead";
service='nginx'
fi;
if [[ "$service" == 'dnsmasq' ]] || [[ "$service" == 'nginx' ]] ; then
${service}_${command} || echo "Unknown option $command"
else
echo "$service service wrapper not patched into alpine container"
exit 1
fi

View File

@ -1,3 +1,5 @@
. /opt/pihole/webpage.sh
validate_env() {
if [ -z "$ServerIP" ] ; then
echo "ERROR: To function correctly you must pass an environment variables of 'ServerIP' into the docker container with the IP of your docker host from which you are passing web (80) and dns (53) ports from"
@ -5,14 +7,8 @@ validate_env() {
fi;
}
setup_saved_variables() {
# /tmp/piholeIP is the current override of auto-lookup in gravity.sh
echo "$ServerIP" > /etc/pihole/piholeIP;
echo "IPv4_address=$ServerIP" > /etc/pihole/setupVars.conf;
echo "IPv6_address=$ServerIPv6" >> /etc/pihole/setupVars.conf;
}
setup_dnsmasq_dns() {
. /opt/pihole/webpage.sh
local DNS1="${1:-8.8.8.8}"
local DNS2="${2:-8.8.4.4}"
local dnsType='default'
@ -21,14 +17,15 @@ setup_dnsmasq_dns() {
fi;
echo "Using $dnsType DNS servers: $DNS1 & $DNS2"
sed -i "s/@DNS1@/$DNS1/" /etc/dnsmasq.d/01-pihole.conf && \
sed -i "s/@DNS2@/$DNS2/" /etc/dnsmasq.d/01-pihole.conf
[ -n "$DNS1" ] && change_setting "PIHOLE_DNS_1" "${DNS1}"
[ -n "$DNS2" ] && change_setting "PIHOLE_DNS_2" "${DNS2}"
ProcessDNSSettings
}
setup_dnsmasq_hostnames() {
# largely borrowed from automated install/basic-install.sh
local IPv4_address="${1}"
local IPv6_address="${2}"
local IPV4_ADDRESS="${1}"
local IPV6_ADDRESS="${2}"
local hostname="${3}"
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
@ -40,16 +37,16 @@ setup_dnsmasq_hostnames() {
fi
fi;
if [[ "${IPv4_address}" != "" ]]; then
tmp=${IPv4_address%/*}
sed -i "s/@IPv4@/$tmp/" ${dnsmasq_pihole_01_location}
if [[ "${IPV4_ADDRESS}" != "" ]]; then
tmp=${IPV4_ADDRESS%/*}
sed -i "s/@IPV4@/$tmp/" ${dnsmasq_pihole_01_location}
else
sed -i '/^address=\/pi.hole\/@IPv4@/d' ${dnsmasq_pihole_01_location}
sed -i '/^address=\/@HOSTNAME@\/@IPv4@/d' ${dnsmasq_pihole_01_location}
sed -i '/^address=\/pi.hole\/@IPV4@/d' ${dnsmasq_pihole_01_location}
sed -i '/^address=\/@HOSTNAME@\/@IPV4@/d' ${dnsmasq_pihole_01_location}
fi
if [[ "${IPv6_address}" != "" ]]; then
sed -i "s/@IPv6@/$IPv6_address/" ${dnsmasq_pihole_01_location}
if [[ "${IPV6_ADDRESS}" != "" ]]; then
sed -i "s/@IPv6@/$IPV6_ADDRESS/" ${dnsmasq_pihole_01_location}
else
sed -i '/^address=\/pi.hole\/@IPv6@/d' ${dnsmasq_pihole_01_location}
sed -i '/^address=\/@HOSTNAME@\/@IPv6@/d' ${dnsmasq_pihole_01_location}
@ -152,18 +149,21 @@ test_framework_stubbing() {
if [ -n "$PYTEST" ] ; then sed -i 's/^gravity_spinup$/#gravity_spinup # DISABLED FOR PYTEST/g' "$(which gravity.sh)"; fi;
}
main() {
docker_main() {
echo -n '::: Starting up DNS and Webserver ...'
service dnsmasq restart # Just get DNS up. The webserver is down!!!
IMAGE="$1"
case $IMAGE in
case $IMAGE in # Setup webserver
"alpine")
gravity.sh # dnsmasq start included
php-fpm
nginx
php-fpm
nginx
;;
"debian")
gravity.sh # dnsmasq start included
service lighttpd start
service lighttpd start
;;
esac
gravity.sh # Finally lets update and be awesome.
tail -F "${WEBLOGDIR}"/*.log /var/log/pihole.log
}

View File

@ -2,67 +2,26 @@ FROM jsurf/rpi-raspbian
MAINTAINER adam@diginc.us <adam@diginc.us>
RUN [ "cross-build-start" ]
ENV IMAGE debian
ENV PATH /opt/pihole:${PATH}
COPY install.sh /install.sh
ENV setupVars /etc/pihole/setupVars.conf
ENV PIHOLE_INSTALL /tmp/ph_install.sh
ENV TINI_VERSION v0.13.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-armhf /tini
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-armhf.asc /tini.asc
# Tini and package requirements
RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 0527A9B7 && \
gpg --verify /tini.asc && \
chmod +x /tini && \
apt-get -q update && \
apt-get install -y \
dnsmasq \
lighttpd \
php5-common php5-cgi php5 \
bc curl unzip wget sudo dnsutils && \
apt-get install -y wget net-tools && \
/install.sh && \
rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
# Original upstream pihole code being used
COPY ./pi-hole/gravity.sh /usr/local/bin/
COPY ./pi-hole/adlists.default /etc/pihole/
COPY ./pi-hole/adlists.default /etc/.pihole/
COPY ./pi-hole/pihole /usr/local/bin/
COPY ./pi-hole/advanced/Scripts/* /usr/local/bin/
RUN mkdir -p /opt/ && ln -s /usr/local/bin /opt/pihole
COPY ./pi-hole/advanced/lighttpd.conf.debian /etc/lighttpd/lighttpd.conf
COPY ./pi-hole/advanced/dnsmasq.conf.original /etc/dnsmasq.conf
COPY ./pi-hole/advanced/01-pihole.conf /etc/dnsmasq.d/
COPY ./pi-hole/advanced/index* /var/www/html/pihole/
RUN rm /var/www/html/index.lighttpd.html
COPY ./pi-hole/advanced/pihole.sudo /etc/sudoers.d/pihole
COPY ./AdminLTE /var/www/html/admin
COPY ./AdminLTE_version.txt /etc/
COPY ./pi-hole_version.txt /etc/
# Make pihole scripts fail searching for `systemctl`,
# which fails pretty miserably in docker compared to `service`
# For more info see docker/docker issue #7459
RUN mv `which systemctl` /bin/no_systemctl
ENV WEBLOGDIR /var/log/lighttpd
RUN mkdir -p /etc/pihole/ && \
mkdir -p /var/www/html/pihole && \
mkdir -p /var/www/html/admin/ && \
chown www-data:www-data /var/www/html && \
touch ${WEBLOGDIR}/access.log ${WEBLOGDIR}/error.log && \
chown -R www-data.www-data ${WEBLOGDIR} && \
chmod 775 /var/www/html && \
lighty-enable-mod fastcgi fastcgi-php || true && \
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 && \
sed -i 's|"cd /etc/.pihole/ && git describe --tags --abbrev=0"|"cat /etc/pi-hole_version.txt"|g' /var/www/html/admin/footer.php && \
sed -i 's|"git describe --tags --abbrev=0"|"cat /etc/AdminLTE_version.txt"|g' /var/www/html/admin/footer.php
# This chould be eliminated if all (upstream) files were +x in git
RUN chmod +x /usr/local/bin/*.sh
# Fix dnsmasq in docker
RUN grep -q '^user=root' || echo 'user=root' >> /etc/dnsmasq.conf
# 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'
@ -76,7 +35,7 @@ ENV IPv6 True
EXPOSE 53 53/udp
EXPOSE 80
# Tini doesn't work in ARM
SHELL ["/bin/bash", "-c"]
ENTRYPOINT ["/tini", "--"]
CMD [ "/start.sh" ]

View File

@ -2,66 +2,24 @@ FROM debian:jessie
MAINTAINER adam@diginc.us <adam@diginc.us>
ENV IMAGE debian
ENV PATH /opt/pihole:${PATH}
COPY install.sh /install.sh
ENV setupVars /etc/pihole/setupVars.conf
ENV PIHOLE_INSTALL /tmp/ph_install.sh
ENV TINI_VERSION v0.13.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini.asc /tini.asc
# Tini and package requirements
RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 0527A9B7 && \
gpg --verify /tini.asc && \
chmod +x /tini && \
apt-get -q update && \
apt-get install -y \
dnsmasq \
lighttpd \
php5-common php5-cgi php5 \
bc curl unzip wget sudo dnsutils && \
apt-get install -y wget net-tools && \
/install.sh && \
rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
# Original upstream pihole code being used
COPY ./pi-hole/gravity.sh /usr/local/bin/
COPY ./pi-hole/adlists.default /etc/pihole/
COPY ./pi-hole/adlists.default /etc/.pihole/
COPY ./pi-hole/pihole /usr/local/bin/
COPY ./pi-hole/advanced/Scripts/* /usr/local/bin/
RUN mkdir -p /opt/ && ln -s /usr/local/bin /opt/pihole
COPY ./pi-hole/advanced/lighttpd.conf.debian /etc/lighttpd/lighttpd.conf
COPY ./pi-hole/advanced/dnsmasq.conf.original /etc/dnsmasq.conf
COPY ./pi-hole/advanced/01-pihole.conf /etc/dnsmasq.d/
COPY ./pi-hole/advanced/index* /var/www/html/pihole/
RUN rm /var/www/html/index.lighttpd.html
COPY ./pi-hole/advanced/pihole.sudo /etc/sudoers.d/pihole
COPY ./AdminLTE /var/www/html/admin
COPY ./AdminLTE_version.txt /etc/
COPY ./pi-hole_version.txt /etc/
# Make pihole scripts fail searching for `systemctl`,
# which fails pretty miserably in docker compared to `service`
# For more info see docker/docker issue #7459
RUN mv `which systemctl` /bin/no_systemctl
ENV WEBLOGDIR /var/log/lighttpd
RUN mkdir -p /etc/pihole/ && \
mkdir -p /var/www/html/pihole && \
mkdir -p /var/www/html/admin/ && \
chown www-data:www-data /var/www/html && \
touch ${WEBLOGDIR}/access.log ${WEBLOGDIR}/error.log && \
chown -R www-data.www-data ${WEBLOGDIR} && \
chmod 775 /var/www/html && \
lighty-enable-mod fastcgi fastcgi-php || true && \
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 && \
sed -i 's|"cd /etc/.pihole/ && git describe --tags --abbrev=0"|"cat /etc/pi-hole_version.txt"|g' /var/www/html/admin/footer.php && \
sed -i 's|"git describe --tags --abbrev=0"|"cat /etc/AdminLTE_version.txt"|g' /var/www/html/admin/footer.php
# This chould be eliminated if all (upstream) files were +x in git
RUN chmod +x /usr/local/bin/*.sh
# Fix dnsmasq in docker
RUN grep -q '^user=root' || echo 'user=root' >> /etc/dnsmasq.conf
# 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'
@ -75,5 +33,6 @@ ENV IPv6 True
EXPOSE 53 53/udp
EXPOSE 80
SHELL ["/bin/bash", "-c"]
ENTRYPOINT ["/tini", "--"]
CMD [ "/start.sh" ]

View File

@ -8,7 +8,7 @@
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
#
# This file is under source-control of the Pi-hole installation and update
# scripts, any changes made to this file will be overwritten when the softare
# is updated or re-installed. Please make any changes to the appropriate crontab
@ -20,12 +20,12 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Pi-hole: Update the ad sources once a week on Sunday at 01:59
# Download any updates from the adlists
59 1 * * 7 root docker exec $DOCKER_NAME pihole updateGravity > /dev/null
59 1 * * 7 root PATH="$PATH:/usr/local/bin/" docker exec $DOCKER_NAME pihole updateGravity > /dev/null
# Update docker-pi-hole by pulling the latest docker image ane re-creating your container.
# pihole software update commands are unsupported in docker!
#30 2 * * 7 root docker exec $DOCKER_NAME pihole updatePihole > /dev/null
#30 2 * * 7 root PATH="$PATH:/usr/local/bin/" docker exec $DOCKER_NAME pihole updatePihole > /dev/null
# Pi-hole: Flush the log daily at 00:00 so it doesn't get out of control
# Stats will be viewable in the Web interface thanks to the cron job above
00 00 * * * root docker exec $DOCKER_NAME pihole flush > /dev/null
00 00 * * * root PATH="$PATH:/usr/local/bin/" docker exec $DOCKER_NAME pihole flush > /dev/null

View File

@ -3,7 +3,8 @@ 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=$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
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
@ -15,4 +16,3 @@ docker run -it --rm --cap-add=NET_ADMIN \
-e VIRTUAL_HOST='pihole.diginc.lan:5080' \
$@ \
diginc/pi-hole:"${image:-alpine}"

View File

@ -1,7 +1,7 @@
#!/bin/bash
IMAGE=${1:-'diginc/pi-hole:alpine'}
NIC=${2:-'eth0'}
IP=$(ip addr show "$NIC" | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
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
# Default ports + daemonized docker container
docker run -p 53:53/tcp -p 53:53/udp -p 80:80 \

60
install.sh Executable file
View File

@ -0,0 +1,60 @@
#!/bin/bash -x
mkdir -p /etc/pihole/
# 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 && \
# debconf-apt-progress seems to hang so get rid of it too
mv "$(which debconf-apt-progress)" /bin/no_debconf-apt-progress
# Get the install functions
wget -O "$PIHOLE_INSTALL" https://install.pi-hole.net
if [[ "$IMAGE" == '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}"
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
PH_TEST=true . "${PIHOLE_INSTALL}"
# Run only what we need from installer
export USER=pihole
if [[ "$IMAGE" == 'debian' ]] ; then
install_dependent_packages INSTALLER_DEPS[@]
install_dependent_packages PIHOLE_DEPS[@]
sed -i "/sleep 2/ d" /etc/init.d/dnsmasq # SLOW
elif [[ "$IMAGE" == 'alpine' ]] ; then
apk add \
dnsmasq \
nginx \
ca-certificates \
php5-fpm php5-json php5-openssl libxml2 \
bc bash curl perl sudo git
fi
git clone --depth 1 "${piholeGitUrl}" "${PI_HOLE_LOCAL_REPO}"
git clone --depth 1 "${webInterfaceGitUrl}" "${webInterfaceDir}"
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
installPihole | tee "${tmpLog}"
sed -i 's/readonly //g' /opt/pihole/webpage.sh
mv "${tmpLog}" "${instalLogLoc}"
# Fix dnsmasq in docker
grep -q '^user=root' || echo -e '\nuser=root' >> /etc/dnsmasq.conf
echo 'done'

@ -1 +0,0 @@
Subproject commit 69e3a45083bd311aecdbc3935986dac5ce64caa8

View File

@ -1 +0,0 @@
v2.9.5

View File

@ -1,5 +1,5 @@
docker-compose
pytest
pytest-xdist
pytest-cov
testinfra
pytest-xdist
testinfra==1.5.1

View File

@ -1,5 +1,4 @@
#!/bin/bash -e
. /bash_functions.sh
#!/bin/bash -ex
# Dockerfile variables
export IMAGE
export ServerIP
@ -9,16 +8,22 @@ export PHP_ENV_CONFIG
export PHP_ERROR_LOG
export HOSTNAME
export WEBLOGDIR
export DNS1
export DNS2
export IPv6
#export setupVars="${setupVars:-/etc/pihole/setupVars.conf}"
. /bash_functions.sh
echo " ::: Starting docker specific setup for docker diginc/pi-hole"
validate_env
setup_saved_variables
setup_php_env
change_setting "IPV4_ADDRESS" "$ServerIP"
change_setting "IPV6_ADDRESS" "$ServerIPv6"
setup_dnsmasq_dns "$DNS1" "$DNS2"
setup_php_env
setup_dnsmasq_hostnames "$ServerIP" "$ServerIPv6" "$HOSTNAME"
setup_ipv4_ipv6
test_configs
test_framework_stubbing
main "$IMAGE"
docker_main "$IMAGE"

View File

@ -10,7 +10,7 @@ check_output = testinfra.get_backend(
def DockerGeneric(request, args, image, cmd):
assert 'docker' in check_output('id'), "Are you in the docker group?"
if 'diginc/pi-hole' in image:
args += " -e PYTEST=\"True\""
args += " -v /dev/null:/etc/pihole/adlists.default -e PYTEST=\"True\""
docker_run = "docker run -d {} {} {}".format(args, image, cmd)
docker_id = check_output(docker_run)
@ -20,6 +20,21 @@ def DockerGeneric(request, args, image, cmd):
docker_container = testinfra.get_backend("docker://" + docker_id)
docker_container.id = docker_id
def run_bash(self, command, *args, **kwargs):
cmd = self.get_command(command, *args)
if self.user is not None:
out = self.run_local(
"docker exec -u %s %s /bin/bash -c %s",
self.user, self.name, cmd)
else:
out = self.run_local(
"docker exec %s /bin/bash -c %s", self.name, cmd)
out.command = self.encode(cmd)
return out
funcType = type(docker_container.run)
docker_container.run = funcType(run_bash, docker_container, testinfra.backend.docker.DockerBackend)
return docker_container
@pytest.fixture
@ -113,7 +128,7 @@ 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 {}'.format(persist_webserver) ).rc == 0)
Slow(lambda: DockerPersist.run('pgrep dnsmasq').rc == 0)
Slow(lambda: DockerPersist.run('pgrep {}'.format(persist_webserver) ).rc == 0)
return DockerPersist

View File

@ -14,9 +14,10 @@ def cmd(request):
])
def test_IPv6_not_True_removes_ipv6(Docker, tag, args, expected_ipv6, expected_stdout):
''' When a user overrides IPv6=True they only get IPv4 listening webservers '''
IPV6_LINE = { 'alpine': 'listen \[::\]:80', 'debian': 'use-ipv6.pl' }
WEB_CONFIG = { 'alpine': '/etc/nginx/nginx.conf', 'debian': '/etc/lighttpd/lighttpd.conf' }
IPV6_LINE = { 'alpine': 'listen \[::\]:80',
'debian': 'use-ipv6.pl' }
WEB_CONFIG = { 'alpine': '/etc/nginx/nginx.conf',
'debian': '/etc/lighttpd/lighttpd.conf' }
function = Docker.run('. /bash_functions.sh ; setup_ipv4_ipv6')
assert "Using {}".format(expected_stdout) in function.stdout
@ -38,7 +39,7 @@ def test_DNS_Envs_override_defaults(Docker, args, expected_stdout, dns1, dns2):
expected_servers = 'server={}\nserver={}\n'.format(dns1, dns2)
assert expected_servers == docker_dns_servers
expected_debian_lines = [
expected_debian_lines = [
'"VIRTUAL_HOST" => "192.168.100.2"',
'"ServerIP" => "192.168.100.2"',
'"PHP_ERROR_LOG" => "/var/log/lighttpd/error.log"'

View File

@ -1,22 +1,22 @@
import pytest
@pytest.fixture
def restart_cmd():
def start_cmd():
''' broken by default, required override '''
return None
RESTART_DNS_STDOUT = {
START_DNS_STDOUT = {
'alpine': '',
'debian': 'Restarting DNS forwarder and DHCP server: dnsmasq.\n'
}
@pytest.fixture
def RunningPiHole(DockerPersist, Slow, persist_webserver, persist_tag, restart_cmd):
def RunningPiHole(DockerPersist, Slow, persist_webserver, persist_tag, start_cmd):
''' Override the RunningPiHole to run and check for success of a
dnsmasq restart based `pihole` script command '''
Slow(lambda: DockerPersist.run('pgrep {}'.format(persist_webserver) ).rc == 0)
dnsmasq start based `pihole` script command '''
Slow(lambda: DockerPersist.run('pgrep dnsmasq').rc == 0)
Slow(lambda: DockerPersist.run('pgrep {}'.format(persist_webserver) ).rc == 0)
oldpid = DockerPersist.run('pidof dnsmasq')
cmd = DockerPersist.run('pihole {}'.format(restart_cmd))
cmd = DockerPersist.run('pihole {}'.format(start_cmd))
Slow(lambda: DockerPersist.run('pgrep dnsmasq').rc == 0)
newpid = DockerPersist.run('pidof dnsmasq')
for pid in [oldpid, newpid]:
@ -24,24 +24,24 @@ def RunningPiHole(DockerPersist, Slow, persist_webserver, persist_tag, restart_c
# ensure a new pid for dnsmasq appeared
assert oldpid != newpid
assert cmd.rc == 0
# Save out cmd result to check different stdout of restart/enable/disable
# Save out cmd result to check different stdout of start/enable/disable
DockerPersist.cmd = cmd
return DockerPersist
@pytest.mark.parametrize('restart_cmd', ['restart_cmd'])
def test_pihole_restart_cmd(RunningPiHole, restart_cmd, persist_tag):
''' the restart_cmd tests are all built into the RunningPiHole fixture in this file '''
assert RunningPiHole.cmd.stdout == RESTART_DNS_STDOUT[persist_tag]
@pytest.mark.parametrize('start_cmd', ['start_cmd'])
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('restart_cmd,hostname,expected_ip', [
@pytest.mark.parametrize('start_cmd,hostname,expected_ip', [
('enable', 'pi.hole', '192.168.100.2'),
('disable', 'pi.hole', '192.168.100.2'),
])
def test_pihole_restart_cmd(RunningPiHole, Dig, persist_tag, restart_cmd, hostname, expected_ip):
''' the restart_cmd tests are all built into the RunningPiHole fixture in this file '''
def test_pihole_start_cmd(RunningPiHole, Dig, persist_tag, start_cmd, hostname, expected_ip):
''' 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
stdout = "::: Blocking has been {}d!\n{}".format(restart_cmd, RESTART_DNS_STDOUT[persist_tag])
stdout = "::: Blocking has been {}d!\n{}".format(start_cmd, START_DNS_STDOUT[persist_tag])
assert RunningPiHole.cmd.stdout == stdout

View File

@ -4,7 +4,6 @@ import time
''' 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)
@ -38,12 +37,12 @@ def test_indecies_are_present(RunningPiHole):
File('/var/www/html/pihole/index.html').exists
File('/var/www/html/pihole/index.js').exists
@pytest.mark.parametrize('ip', [ '127.0.0.1', '[::]' ] )
@pytest.mark.parametrize('ip', [ 'localhost', '[::]' ])
@pytest.mark.parametrize('url', [ '/', '/index.html', '/any.html' ] )
def test_html_index_requests_load_as_expected(RunningPiHole, ip, url):
command = 'curl -s -o /tmp/curled_file -w "%{{http_code}}" http://{}{}'.format(ip, url)
http_rc = RunningPiHole.run(command)
assert RunningPiHole.run('md5sum /tmp/curled_file /var/www/html/pihole/index.html').rc == 0
assert RunningPiHole.run('grep -q "Access to the following site has been blocked" /tmp/curled_file ').rc == 0
assert int(http_rc.stdout) == 200
@pytest.mark.parametrize('ip', [ '127.0.0.1', '[::]' ] )
@ -54,7 +53,8 @@ def test_javascript_requests_load_as_expected(RunningPiHole, ip, url):
assert RunningPiHole.run('md5sum /tmp/curled_file /var/www/html/pihole/index.js').rc == 0
assert int(http_rc.stdout) == 200
@pytest.mark.parametrize('ip', [ '127.0.0.1', '[::]' ] )
# IPv6 checks aren't passing CORS, removed :(
@pytest.mark.parametrize('ip', [ 'localhost' ] )
@pytest.mark.parametrize('url', [ '/admin/', '/admin/index.php' ] )
def test_admin_requests_load_as_expected(RunningPiHole, ip, url):
command = 'curl -s -o /tmp/curled_file -w "%{{http_code}}" http://{}{}'.format(ip, url)
@ -62,5 +62,5 @@ def test_admin_requests_load_as_expected(RunningPiHole, ip, url):
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 "js/pihole/footer.js" /tmp/curled_file ').rc == 0
assert RunningPiHole.run('grep -q "scripts/pi-hole/js/footer.js" /tmp/curled_file ').rc == 0

View File

@ -1,19 +0,0 @@
#!/bin/bash -x
# Grab newest code and update version files
git submodule foreach git pull;
git submodule foreach git pull origin master;
pushd pi-hole ; git describe --tags --abbrev=0 > ../pi-hole_version.txt ; popd ;
pushd AdminLTE ; git describe --tags --abbrev=0 > ../AdminLTE_version.txt ; popd ;
# Copy latest crontab and modify to use docker exec commands
cron='./docker-pi-hole.cron'
cp -f pi-hole/advanced/pihole.cron ${cron};
sed -i '/Update the ad sources/ i\# Your container name goes here:\nDOCKER_NAME=pihole\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n' ${cron};
sed -i "s|/usr/local/bin/|docker exec \$DOCKER_NAME |g" ${cron};
sed -i '/docker exec/ s|$| > /dev/null|g' ${cron};
# docker-pi-hole users update their docker images, not git code
sed -i '/Update Pi-hole/ a\# pihole software update commands are unsupported in docker!' ${cron};
sed -i '/Update Pi-hole/ c\# Update docker-pi-hole by pulling the latest docker image ane re-creating your container.' ${cron};
sed -i '/pihole updateDashboard/ s/^/#/' ${cron};