# Running and Deploying Pi-Hole

> Octelium documentation. Canonical page: <https://octelium.com/docs/octelium/latest/management/guide/service/homelab/pihole>.

Octelium provides a L7 aware DNS mode where you can provide secure access to internal as well as public, including commercial, DNS servers with application-layer aware access control and visibility (read more about the DNS mode [here](https://octelium.com/docs/octelium/latest/management/core/service/dns.md)). For example, you can very easily deploy and serve a Pi-hole container (read more about managed containers [here](https://octelium.com/docs/octelium/latest/management/core/service/managed-containers.md)) as a *Service* as follows:

```yaml
kind: Service
metadata:
  name: pihole
spec:
  mode: DNS
  config:
    upstream:
      container:
        port: 53
        image: pihole/pihole:latest
        env:
        - name: FTLCONF_dns_listeningMode
          value: all
```

You can now apply the creation of the *Service* as follows (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview.md)):

```bash
octeliumctl apply /PATH/TO/SERVICE.YAML
```

Once connected to the *Cluster* via `octelium connect` (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect.md)), you can now test the DNS server `pihole`, for example, as follows:

```bash
dig @pihole google.com
```

It's noteworthy to point out that the *Cluster*'s [DNS Server](https://octelium.com/docs/octelium/latest/reference/components.md#dns-server) which resolves DNS queries for the all connected *Users* (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect.md#dns)) is itself a DNS *Service* with the name `dns.octelium`. This DNS server can additionally resolve queries outside the *Cluster* domain by proxying the requests to fallback servers that can be set via the *ClusterConfig* (read more [here](https://octelium.com/docs/octelium/latest/management/core/cluster-config.md#dns)). We can, for example, deploy a Pi-hole server as a typical Kubernetes service and serve it as a fallback server to control and secure DNS queries for all connected `octelium` clients as follow:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pihole
spec:
  selector:
    matchLabels:
      app: pihole
  template:
    metadata:
      labels:
        app: pihole
    spec:
      containers:
      - name: pihole
        image: pihole/pihole:latest
        ports:
        - containerPort: 53
          protocol: UDP
        env:
        - name: FTLCONF_dns_listeningMode
          value: all
---
apiVersion: v1
kind: Service
metadata:
  name: pihole
spec:
  selector:
    app: pihole
  ports:
    - name: dns
      port: 53
      targetPort: 53
      protocol: UDP
```

You can now apply the creation of the deployment and service via `kubectl apply` as follows:

```bash
kubectl apply -f PATH/TO/K8S_RESOURCES.YAML
```

Now we finally refer to the Kubernetes service as a fallback upstream as follows:

```yaml
kind: ClusterConfig
metadata:
  name: default
spec:
  dns:
    fallbackZone:
      servers:
      - dns://pihole.default.svc
```

And as always, you apply the changes via `octeliumctl apply`.

Octelium also provides OpenTelemetry-ready, application-layer L7 aware visibility and access logging in real time (see an example for DNS [here](https://octelium.com/docs/octelium/latest/management/core/service/dns.md#visibility)). You can read more about visibility [here](https://octelium.com/docs/octelium/latest/management/core/visibility.md)
