https://github.com/kaczmar2/pihole-cloudflared-doh
Pi-hole v6 + cloudflared in Docker: A simple Docker Compose setup for Pi-hole v6 that uses cloudflared with Pi-hole to enable DNS-over-HTTPS queries to Cloudflare, Google, and other DoH providers.
https://github.com/kaczmar2/pihole-cloudflared-doh
cloudflared cloudflareddns dns-over-https docker docker-compose doh pihole pihole-configuration
Last synced: 21 days ago
JSON representation
Pi-hole v6 + cloudflared in Docker: A simple Docker Compose setup for Pi-hole v6 that uses cloudflared with Pi-hole to enable DNS-over-HTTPS queries to Cloudflare, Google, and other DoH providers.
- Host: GitHub
- URL: https://github.com/kaczmar2/pihole-cloudflared-doh
- Owner: kaczmar2
- License: mit
- Created: 2025-08-23T03:17:48.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-08-24T01:33:20.000Z (9 months ago)
- Last Synced: 2025-08-24T11:10:31.241Z (9 months ago)
- Topics: cloudflared, cloudflareddns, dns-over-https, docker, docker-compose, doh, pihole, pihole-configuration
- Homepage:
- Size: 16.6 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Pi-hole v6 + cloudflared (DoH) in Docker
## Summary
This is a **baseline setup of Pi-hole and cloudflared** using Docker. It
assumes that you already have a gateway/router with a
**separate DHCP and NTP server**. If you want Pi-hole to handle DHCP,
additional configuration is needed.
This setup uses Cloudflare's **cloudflared**, a tunneling daemon, to connect
Pi-hole to DNS-over-HTTPS (DoH) providers like
[1.1.1.1](https://one.one.one.one/) or [Quad9](https://quad9.net/), providing
enhanced privacy and security for DNS queries. It follows the official
[Pi-hole cloudeflared guide](https://docs.pi-hole.net/guides/dns/cloudflared/)
but adapts it for Pihole v6 and Docker Compose.
In this setup, **cloudflared does not have its own network interface**;
instead, it runs using **Pi-hole's network stack**
(`network_mode: service:pihole`). This means:
- **cloudflared is not exposed to the host network** but can still handle DNS-over-HTTPS queries.
- **Pi-hole forwards all upstream DNS queries** to `127.0.0.1#5335`, where cloudflared handles DoH lookups.
- **No additional networking configurations are needed** for cloudflared.
## Prerequisites
Before you begin, ensure you are running:
- A **Debian or Debian-based Linux distribution** (Ubuntu, Raspberry Pi OS, etc.)
- [**Docker** installed](https://docs.docker.com/engine/install/)
## Step 1: Create the Directory Structure for Bind Mounts
Before downloading the repository, set up the necessary directories for your
**bind mounts**.
Run the following commands:
```bash
mkdir -p ~/docker/pihole-cloudflared
sudo mkdir -p /srv/docker/pihole-cloudflared/pihole/etc-pihole
sudo mkdir -p /srv/docker/pihole-cloudflared/pihole/etc-dnsmasq.d
sudo chown -R $USER:$USER /srv/docker
chmod -R 755 /srv/docker
cd ~/docker/pihole-cloudflared
```
### What These Commands Do
- `mkdir -p ~/docker/pihole-cloudflared`: Creates a working directory in your home folder.
- `sudo mkdir -p /srv/docker/...`: Creates **bind mounts** for Pi-hole.
- `sudo chown -R $USER:$USER /srv/docker`: Ensures **your user owns the folders**.
- `chmod -R 755 /srv/docker`: Sets **read/write permissions** for better access.
## Step 2: Download the Repository
Download the latest version of this repository:
```bash
curl -L -o main.tar.gz https://github.com/kaczmar2/pihole-cloudflared-doh/archive/refs/heads/main.tar.gz
tar -xzf main.tar.gz --strip-components=1
```
The `--strip-components=1` flag ensures the contents are extracted directly into
`~/docker/pihole-cloudflared` instead of creating an extra subdirectory.
**Note**: This setup uses cloudflared as a DNS-over-HTTPS proxy, providing
enhanced privacy and security for DNS queries.
## Step 3: Configure the DoH Provider
By default, the `.env` file is configured to use **Cloudflare's DoH service**
(). If you want to use a different provider,
edit the `DOH_PRIMARY` variable in the `.env` file before starting the
containers. See the [DNS-over-HTTPS Providers table](#common-dns-over-https-providers)
at the bottom for other options.
## Step 3: Set the Pi-hole Admin Password
### Automated Setup
Use the automated setup script to configure your Pi-hole admin password:
```bash
./set-password.sh
```
This script will:
- Prompt you securely for a password
- Temporarily disable the password environment variable in docker-compose.yml
- Set the password in the Pi-hole container (writes to pihole.toml)
- Extract and save the password hash to your `.env` file
- Re-enable the password environment variable in docker-compose.yml
- Restart containers with the new configuration
- Create backups of your config files
Your Pi-hole admin interface will be ready with the password you set.
### Manual Setup
If you prefer the manual approach or need to troubleshoot:
Click to expand manual setup instructions
**Important**: For Pi-hole v6, environment variables override the TOML file.
You must temporarily comment out the password environment variable to allow
the TOML file to be updated.
1. Comment out `FTLCONF_webserver_api_pwhash` in `docker-compose.yml`:
```yaml
# FTLCONF_webserver_api_pwhash: ${WEBSERVER_PWHASH}
```
2. Restart containers to apply the change:
```bash
docker compose down && docker compose up -d
```
3. Set your password in the Pi-hole container:
```bash
docker exec -it pihole /bin/bash
pihole setpassword 'mypassword'
```
4. Get the hashed password from `pihole.toml`:
```bash
cat /etc/pihole/pihole.toml | grep -E "^[[:space:]]*pwhash[[:space:]]*="
exit
```
5. Copy the hash value and add it to your `.env` file (enclose in single quotes):
```bash
WEBSERVER_PWHASH='$BALLOON-SHA256$v=1$s=1024,t=32$pZCbBIUH/Ew2n144eLn3vw==$vgej+obQip4DvSmNlywD0LUHlsHcqgLdbQLvDscZs78='
```
6. Uncomment the `FTLCONF_webserver_api_pwhash` environment variable in `docker-compose.yml`:
```yaml
FTLCONF_webserver_api_pwhash: ${WEBSERVER_PWHASH}
```
7. Restart the containers:
```bash
docker compose down && docker compose up -d
```
## Step 4: Verify cloudflared Is Working
To confirm cloudflared is resolving queries correctly, run the following
commands **in the pihole container**:
Open a `bash` shell in the container:
```bash
docker exec -it pihole /bin/bash
```
Test that cloudflared is operational:
```bash
dig pi-hole.net @127.0.0.1 -p 5335
```
The first query may be quite slow, but subsequent queries should be fairly
quick.
## Step 5: Access the Pi-hole Web Interface
Once running, open your web browser and go to:
```bash
http:///admin/
```
Login using the password you set.
## Step 6: Secure Web Interface With SSL (Optional)
For enhanced security, see my other guides on **configuring SSL encryption**
for the Pi-hole web interface.
- [Pi-hole v6 + Docker: Automating Let's Encrypt SSL Renewal with Cloudflare DNS](https://gist.github.com/kaczmar2/027fd6f64f4e4e7ebbb0c75cb3409787#file-pihole-v6-docker-le-cf-md)
## Check Docker logs
This will show logs for both the `pihole` and `cloudflared` containers.
```bash
docker logs pihole
docker logs cloudflared-doh
```
## Notes
### Common DNS-over-HTTPS Providers
| Provider | DoH Endpoint |
|----------|-------------|
| [Cloudflare](https://one.one.one.one) | |
| [Quad9](https://quad9.net/service/service-addresses-and-features) | |
| [Google](https://developers.google.com/speed/public-dns/docs/doh) | |
| [OpenDNS](https://support.opendns.com/hc/en-us/articles/360038086532-Using-DNS-over-HTTPS-DoH-with-OpenDNS) | |
**Note**: To use a different DoH provider, update the `DOH_PRIMARY` variable
in your `.env` file with the desired endpoint from the table above.