Securely Exposing Raspberry Pi AI Services: Reverse Proxy, Let's Encrypt and DNS Automation
tutorialedgesecurity

Securely Exposing Raspberry Pi AI Services: Reverse Proxy, Let's Encrypt and DNS Automation

wwhata
2026-02-07 12:00:00
10 min read
Advertisement

Step-by-step runbook to expose Raspberry Pi 5 AI services securely: Traefik/Nginx, Let's Encrypt automation, dynamic DNS, NAT traversal, and firewall hardening.

Securely Exposing Raspberry Pi AI Services in 2026: A Practical Runbook

Hook: You built a powerful AI service on a Raspberry Pi 5 with the new AI HAT+ 2 or an LLM container, but now you need it reachable from the internet—securely, automatically, and reliably. Cloud costs and complex provider lock-in are unacceptable, and your router/NAT adds friction. This guide walks you through a production-ready approach: reverse proxy (Traefik or Nginx), Let's Encrypt SSL automation, dynamic DNS, and hardened firewall/NAT traversal patterns tuned for edge devices in 2026.

Executive summary (most important items first)

  • Run a containerized reverse proxy (Traefik recommended) on the Pi to manage TLS, routing, and service discovery.
  • Prefer DNS-01 ACME challenge (Cloudflare/DNS provider) when behind CGNAT or if you want wildcard certs; HTTP-01 is simpler with direct port 80/443.
  • Use dynamic DNS (DuckDNS, Cloudflare API, or custom) to keep your public name pointing to the Pi; alternatively use Cloudflare Tunnel/Tailscale to avoid exposing ports.
  • Harden the Pi with firewall rules (ufw or nftables), SSH rate-limits, and resource constraints for containers.
  • Test with Let's Encrypt staging, monitor cert expiration and proxy logs, and use automation for recovery (backups and alerts).

Why this matters in 2026

Edge AI and on-device LLMs are mainstream in 2026. The Raspberry Pi 5 plus AI HAT+ 2 is a cost-effective platform for hosting inference services, but exposing these services safely remains hard. ISPs increasingly use CGNAT, consumer routers have inconsistent feature sets, and teams want automation to avoid manual certificate churn. This runbook gives you repeatable steps—suitable for developers and ops teams—to operate secure, automated remote access without vendor lock-in or recurring cloud costs.

Prerequisites and decisions (quick checklist)

  • Raspberry Pi 5 with up-to-date 64-bit OS (2026: Raspberry Pi OS / Debian 12/13 or a lightweight distro you trust).
  • Docker and docker-compose or Podman + Compose-compatible stack.
  • Domain name (example: yourdomain.example) and control over DNS (Cloudflare, Route53, or DuckDNS for free dynamic names).
  • Router access (for port forward) or account for Cloudflare Tunnel / Tailscale / reverse SSH if behind CGNAT.
  • Basic familiarity with Linux networking and firewalling.

High-level architecture options

1) Standard: Router port-forwarding + Traefik + Let's Encrypt (HTTP-01)

  • Forward ports 80 and 443 to the Pi's IP.
  • Traefik runs on the Pi, uses HTTP-01 to get certs automatically.
  • Good for stable public IPs or when NAT allows port-forwarding.

2) Resilient: DNS-01 (Cloudflare) + Traefik for wildcard or when behind CGNAT

  • Use Cloudflare API or other DNS provider for ACME DNS challenge—no inbound ports required.
  • Best for wildcard certs (*.example.com) and CGNAT environments.

3) Zero-exposure: Cloudflare Tunnel / Tailscale / ngrok + Local proxy

  • No router config needed — the Pi creates an outbound tunnel to a cloud service or private network mesh.
  • Good for sensitive setups and when you prefer not to expose ports; you can combine with Traefik internally.

Traefik is lightweight, dynamically configures routes from Docker labels, and has native ACME support. Below is a docker-compose setup that works in most home/prosumer environments.

1) Prepare the Pi

  1. Update OS and install Docker + docker-compose (or docker-compose-plugin):
    sudo apt update && sudo apt upgrade -y
    curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh
    sudo usermod -aG docker $USER
    sudo apt install -y docker-compose
  2. Create a directory: /home/pi/traefik and subfolders acme (persist certs) and logs.

2) docker-compose.yml for Traefik (HTTP-01)

Use HTTP-01 when you can expose 80/443. Replace domain and email.

version: '3.8'
services:
  traefik:
    image: traefik:latest
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./traefik.toml:/etc/traefik/traefik.toml
      - ./acme:/acme
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
      - "traefik.enable=true"

3) traefik.toml minimal config (ACME + Docker provider)

[entryPoints]
  [entryPoints.web]
    address = ":80"
  [entryPoints.websecure]
    address = ":443"

[providers.docker]
  endpoint = "unix:///var/run/docker.sock"
  exposedByDefault = false

[certificatesResolvers.le.acme]
  email = "you@yourdomain.example"
  storage = "/acme/acme.json"
  [certificatesResolvers.le.acme.httpChallenge]
    entryPoint = "web"

Permissions: ensure acme.json is owned by UID 0 and mode 600 once created.

4) Example app service (AI) with Traefik labels

  ai-service:
    image: ghcr.io/example/textgen:latest
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ai.rule=Host(`ai.yourdomain.example`)"
      - "traefik.http.routers.ai.entrypoints=websecure"
      - "traefik.http.routers.ai.tls.certresolver=le"
    networks:
      - web

If your ISP uses CGNAT or you cannot forward ports reliably, use DNS-01 to prove domain ownership. Traefik supports Cloudflare via API token.

1) Create Cloudflare API token

  • Create a token limited to Zone:DNS:Edit for your zone(s).
  • Store it in the Pi as an environment variable or file and mount it to Traefik.

2) Traefik config snippet for Cloudflare DNS-01

[certificatesResolvers.le.acme]
  email = "you@yourdomain.example"
  storage = "/acme/acme.json"
  [certificatesResolvers.le.acme.dnsChallenge]
    provider = "cloudflare"
    delayBeforeCheck = 0

[providers.env]

Then set environment variable in docker-compose:

environment:
  - CF_API_TOKEN=xxxxxx
Mounting /run/secrets or environment variables are both valid. Always limit token scope.

Nginx alternative (when you don’t want Docker for the proxy)

Nginx remains a solid choice. Use certbot with --nginx installer or use DNS challenge with certbot-dns-cloudflare plugin. Nginx is slightly more manual than Traefik for dynamic routing, but offers mature configuration control.

Example: certbot DNS with Cloudflare

sudo apt install certbot python3-certbot-dns-cloudflare
# /etc/letsencrypt/cloudflare.ini contains api token
sudo certbot --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d "ai.yourdomain.example" --agree-tos --no-eff-email --email you@yourdomain.example

Dynamic DNS strategies

If your home IP changes, update a DNS record automatically. Options:

  • DuckDNS: free, simple. Use curl to update every 5 minutes via cron.
  • Cloudflare: use API to update A record—more control and recommended when using DNS-01.
  • Router-provided DDNS for some providers (less flexible).

Example DuckDNS update cron (simple)

# /usr/local/bin/update-duckdns.sh
DOMAIN="your-subdomain"
TOKEN="your-token"
curl -s "https://www.duckdns.org/update?domains=$DOMAIN&token=$TOKEN&ip=" >/dev/null

# cron entry (run every 5 minutes)
*/5 * * * * /usr/local/bin/update-duckdns.sh >/dev/null 2>&1

Example Cloudflare update script (robust)

#!/bin/bash
ZONE_ID="your_zone_id"
RECORD_NAME="ai.yourdomain.example"
API_TOKEN="xxxx"
IP=$(curl -s https://ipv4.icanhazip.com)
RECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$RECORD_NAME" \
  -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" | jq -r '.result[0].id')

curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
  -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" \
  --data "{\"type\":\"A\",\"name\":\"$RECORD_NAME\",\"content\":\"$IP\",\"ttl\":120}"

NAT traversal alternatives (when port-forwarding is impossible)

  • Cloudflare Tunnel (cloudflared) — runs outbound and maps a public hostname without opening ports.
  • Tailscale with Tailscale SSH/ACLs — join the Pi into a private mesh; use a proxy or SSH reverse port forwarding.
  • Reverse SSH tunnel or autossh — DIY, low-cost, requires another remote host with public IP.
  • Commercial tunnels (ngrok, pagekite) — fast but often paid for stable subdomains and enterprise features.
Tip: For production-like reliability, pair a tunnel (Cloudflare/Tailscale) for management with publicly verifiable DNS/TLS for client-facing endpoints.

Firewall and hardening (ufw and nftables examples)

Keep attack surface minimal. Allow only necessary ports and protect SSH.

Simple ufw policy

sudo apt install ufw
# reset to safe defaults
sudo ufw default deny incoming
sudo ufw default allow outgoing
# allow web
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# restrict SSH (change 22 to your port)
sudo ufw allow 22/tcp
# enable ufw
sudo ufw enable

SSH hardening (critical)

  • Disable password auth; use keys and ssh-agent.
  • Change default port or use port-knocking (security-through-obscurity is limited).
  • Use Fail2ban or nftables rate-limits for SSH brute-force protection.

nftables example rate-limit for SSH

sudo apt install nftables
sudo nft add table inet filter
sudo nft 'add chain inet filter input { type filter hook input priority 0; policy drop; }'
sudo nft 'add rule inet filter input ct state established,related accept'
sudo nft 'add rule inet filter input tcp dport 22 ct state new limit rate 4/minute accept'
sudo nft 'add rule inet filter input ip protocol icmp accept'
sudo nft 'add rule inet filter input iif lo accept'

Let's Encrypt operational tips

  • Always use the staging environment for initial tests: avoids hitting rate limits.
  • Back up acme.json or /etc/letsencrypt regularly—if you lose it, you must revalidate and may hit rate limits. See broader backup thinking in Beyond Backup.
  • Monitor cert expiry with a simple cron or Prometheus exporter; renewals can fail silently if DNS changes.
  • Use short, tracked change windows when modifying DNS provider API tokens or DNS records.

Resource management on Raspberry Pi

Raspberry Pi 5 is powerful, but multi-container AI workloads can exhaust memory or thermal limits. Best practices:

  • Use Docker resource limits (--memory) for heavy inference services.
  • Enable swap file with limits and use zram on 2026 kernels for better performance on low-RAM models.
  • Prefer smaller base images (alpine variants) where possible; cross-compile images for arm64 to match the Pi 5.
  • Monitor CPU, temp, and memory. Add a heatsink/fan for continuous inference loads. Field testing lessons from devices like the ByteCache edge appliance reinforce watching thermal and I/O behavior.

Observability and recovery

Include logging and alerting in your runbook:

  • Collect Traefik logs and access logs. Push to a central ELK/Promtail + Grafana or local logrotate.
  • Use uptime checks (external monitors) for your domain and notify on certificate failures or TLS mismatches. Investing in an edge-first developer experience approach makes these checks repeatable across a fleet.
  • Keep an offsite backup of important configs and the Traefik acme.json file.

Real-world examples & patterns

Case A — Home lab with public IPv4

  • Use HTTP-01 with Traefik, forward 80/443, run DuckDNS or Cloudflare dynamic updates, and enable ufw. Easy to set up; low latency.

Case B — ISP CGNAT / corporate NAT

  • DNS-01 with Cloudflare plus Traefik avoids inbound ports. Or run Cloudflare Tunnel (cloudflared) to publish a hostname and optionally use Cloudflare's edge certs.

Case C — Remote customers and fleet management

  • Use Tailscale or a VPN mesh for private connectivity; use internal Traefik for routing inside the mesh and expose services through a central gateway that handles public TLS and rate limits. Consider edge orchestration and container patterns from Edge Containers & Low-Latency Architectures when scaling multiple Pis.

Security checklist before going live

  1. Test that only required ports are open externally (nmap from remote host).
  2. Confirm TLS chain with SSL Labs or curl --tlsv1.3, verify HSTS if you need it.
  3. Rotate API tokens and use least privilege for DNS/Cloudflare tokens.
  4. Enable fail2ban and review logs for suspicious activity in first 72 hours.
  5. Document recovery steps: how to restore acme.json, recreate DNS records, and reissue certs using staging endpoint first.
  • Edge AI proliferation: expect more orchestration tools optimized for small clusters and ARM architectures; see Edge Containers.
  • Increased adoption of tunneling meshes (Tailscale, Nebula) for secure remote access—useful for fleets of Pis.
  • DNS-based CA challenges remain the most stable approach for wildcard and CGNAT scenarios; keep an eye on CA policy changes and rate limits.
  • Serverless/edge-hosted ingress may blur lines—if you need global scale, consider hybrid: local inference, clouded public gateway. Review tradeoffs in On-Prem vs Cloud analyses.

Troubleshooting quick reference

  • No cert issued: inspect Traefik logs, try staging ACME, verify DNS resolves and points to your public IP, and ensure ports 80/443 are reachable for HTTP-01.
  • Cert renewal failed: check acme.json permissions and API token if DNS-01 is used.
  • Service unreachable but proxy healthy: verify Docker network labels and service is healthy on internal port.
  • High load on Pi: throttle model concurrency, set container memory limits, or offload heavy workloads to an external GPU/accelerator.

Example minimal operational checklist

  1. Deploy Traefik with ACME (staging), add service, test routing.
  2. Switch ACME to production once validated.
  3. Enable monitoring and daily DNS update cron.
  4. Harden firewall, rotate tokens, back up acme.json weekly.

Final notes

Bringing AI services on a Raspberry Pi 5 to the public internet in 2026 is both inexpensive and secure when you apply automation and modern patterns. Traefik simplifies TLS automation and dynamic routing; DNS-01 protects you from NAT limitations; and tunnels offer secure management without exposing ports. The combination you choose depends on your environment constraints: ISP NAT, tolerance for cloud dependencies, and the expected traffic profile.

Actionable takeaways

  • Start with Traefik + ACME staging to validate the flow before switching to production.
  • Use DNS-01 when you cannot control inbound ports or want wildcard certificates.
  • Automate dynamic DNS updates and back up your ACME storage (Beyond Backup).
  • Harden network access with ufw/nftables and enforce SSH key access with rate limits.
  • Consider Cloudflare Tunnel or Tailscale when you must avoid opening router ports.

Call to action: Ready to deploy? Download the sample docker-compose and scripts from our GitHub repo, test against Let's Encrypt staging, and join our Discord for troubleshooting and performance tuning for Raspberry Pi 5 AI deployments.

Advertisement

Related Topics

#tutorial#edge#security
w

whata

Contributor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.

Advertisement
2026-01-24T04:34:32.030Z