Installation guide for setting up Home Assistant, AdGuard Home, Pi-hole, Nginx Proxy Manager, and Portainer as Docker containers in an Ubuntu LXC container on a Proxmox VE server. The setup includes a reverse proxy using Nginx Proxy Manager and a Cloudflare Tunnel for secure external access. Portainer will be added to manage all Docker containers. This guide assumes you’re starting from scratch and includes specific commands and configurations.


Step 1: Prepare the Ubuntu LXC Container

  1. Access Proxmox VE:
  • Log in to your Proxmox web interface (e.g., https://proxmox-ip:8006).
  • Ensure an Ubuntu LXC container (or VM) is set up. If not, create one:
    • Select “Create CT” in Proxmox.
    • Choose Ubuntu (e.g., 22.04 LTS or 24.04 LTS) template.
    • Allocate resources (e.g., 2 CPU cores, 4GB RAM, 20GB storage).
    • Enable Docker-compatible features: Enable “Nesting” and “FUSE” in the container options.
  1. Access the Ubuntu Container:
  • SSH into the container: ssh user@container-ip (replace user and container-ip with your credentials/IP).
  • Alternatively, use the Proxmox console.
  1. Update and Install Docker:
  • Update the package list: sudo apt update && sudo apt upgrade -y.
  • Install Docker and Docker Compose:
    bash sudo apt install docker.io docker-compose -y sudo systemctl enable docker sudo systemctl start docker
  • Add your user to the Docker group: sudo usermod -aG docker $USER, then log out and back in.
  1. Create a Project Directory:
  • Create a directory for all Docker configurations:
    bash mkdir ~/homelab && cd ~/homelab

Step 2: Set Up Docker Compose with All Services

  1. Create the Docker Compose File:
  • Create a docker-compose.yml file: nano docker-compose.yml.
  • Add the following configuration, which includes Home Assistant, AdGuard Home, Pi-hole, Nginx Proxy Manager, and Portainer. Replace Your/Timezone (e.g., America/New_York) and your_pihole_password with your desired values.

version: ‘3.8’
services:
homeassistant:
image: ghcr.io/home-assistant/home-assistant:stable
container_name: homeassistant
restart: unless-stopped
ports:
– “8123:8123” # Internal port for Home Assistant
volumes:
– ./homeassistant:/config
environment:
– TZ=Your/Timezone

adguard:
image: adguard/adguardhome:latest
container_name: adguard
restart: unless-stopped
ports:
– “1053:53/tcp” # Avoid port 53 conflict with Pi-hole
– “1053:53/udp”
– “3000:3000” # Web UI (internal)
volumes:
– ./adguard/workdir:/opt/adguardhome/work
– ./adguard/confdir:/opt/adguardhome/conf

pihole:
image: pihole/pihole:latest
container_name: pihole
restart: unless-stopped
ports:
– “53:53/tcp” # DNS port
– “53:53/udp”
– “8080:80/tcp” # Web UI (avoid conflict with NPM)
environment:
– TZ=Your/Timezone
– WEBPASSWORD=your_pihole_password
volumes:
– ./pihole/etc-pihole:/etc/pihole
– ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d

npm:
image: jc21/nginx-proxy-manager:latest
container_name: npm
restart: unless-stopped
ports:
– “80:80” # HTTP
– “443:443” # HTTPS
– “81:81” # NPM admin UI
volumes:
– ./npm/data:/data
– ./npm/letsencrypt:/etc/letsencrypt

portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped
ports:
– “9000:9000” # Portainer Web UI (internal)
volumes:
– /var/run/docker.sock:/var/run/docker.sock
– ./portainer/data:/data
environment:
– TZ=Your/Timezone

  1. Notes on Configuration:
  • Port Conflicts: Pi-hole uses port 53 for DNS, so AdGuard uses port 1053 to avoid conflicts. Pi-hole’s web UI is moved to 8080 to avoid clashing with Nginx Proxy Manager’s port 80.
  • Volumes: Persistent data is stored in ~/homelab/<service> directories (e.g., ./homeassistant).
  • Portainer: Maps to port 9000 for its web UI and connects to Docker via /var/run/docker.sock.
  1. Start the Containers:
  • Run: docker compose up -d.
  • Verify containers are running: docker ps. You should see five containers: homeassistant, adguard, pihole, npm, and portainer.
  1. Test Local Access:
  • Home Assistant: http://container-ip:8123
  • AdGuard Home: http://container-ip:3000
  • Pi-hole: http://container-ip:8080/admin
  • Nginx Proxy Manager: http://container-ip:81 (default login: admin@example.com, password: changeme)
  • Portainer: http://container-ip:9000 (set up admin user on first login)

Step 3: Configure Nginx Proxy Manager (Reverse Proxy)

  1. Access Nginx Proxy Manager:
  • Open http://container-ip:81 in a browser.
  • Log in with default credentials (update the password immediately).
  1. Add Proxy Hosts:
  • In NPM, go to “Hosts” → “Proxy Hosts” → “Add Proxy Host”.
  • Configure each service:
    • Home Assistant:
    • Domain: ha.yourdomain.com
    • Scheme: http
    • Forward Host: homeassistant
    • Forward Port: 8123
    • Enable “Block Common Exploits” and “Websockets Support”.
    • AdGuard Home:
    • Domain: adguard.yourdomain.com
    • Scheme: http
    • Forward Host: adguard
    • Forward Port: 3000
    • Pi-hole:
    • Domain: pi.yourdomain.com
    • Scheme: http
    • Forward Host: pihole
    • Forward Port: 80
    • Portainer:
    • Domain: portainer.yourdomain.com
    • Scheme: http
    • Forward Host: portainer
    • Forward Port: 9000
  • For each, request an SSL certificate via NPM’s “SSL” tab (select “Request a new certificate” with Let’s Encrypt, enable “Force SSL”).
  1. Update Docker Compose for External Access:
  • Edit docker-compose.yml to remove conflicting ports (only NPM needs 80/443 exposed externally). Update the ports section:
    yaml services: homeassistant: ports: [] # Remove 8123 adguard: ports: - "1053:53/tcp" - "1053:53/udp" # Remove 3000 pihole: ports: - "53:53/tcp" - "53:53/udp" # Remove 8080 npm: ports: - "80:80" - "443:443" - "81:81" portainer: ports: [] # Remove 9000
  • Apply changes: docker compose down && docker compose up -d.

Step 4: Set Up Cloudflare Tunnel

  1. Install cloudflared:
  • In the Ubuntu container, install the Cloudflare daemon:
    bash wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb sudo dpkg -i cloudflared-linux-amd64.deb
  1. Authenticate with Cloudflare:
  • Run: cloudflared tunnel login.
  • A browser window opens; log in to Cloudflare and authorize the tunnel.
  1. Create a Tunnel:
  • Create a tunnel: cloudflared tunnel create homelab-tunnel.
  • Note the tunnel UUID and credentials file path (e.g., /root/.cloudflared/<tunnel-uuid>.json).
  1. Configure the Tunnel:
  • Create a configuration file: nano ~/.cloudflared/config.yml.
  • Add:

    tunnel: homelab-tunnel
    credentials-file: /root/.cloudflared/.json
    ingress:
  • hostname: ha.yourdomain.com
    service: http://npm:80
  • hostname: adguard.yourdomain.com
    service: http://npm:80
  • hostname: pi.yourdomain.com
    service: http://npm:80
  • hostname: portainer.yourdomain.com
    service: http://npm:80
  • service: http_status:404
  • Replace <tunnel-uuid> with your actual tunnel UUID.
  1. Route DNS in Cloudflare:
  • For each subdomain, create a CNAME record in the Cloudflare dashboard pointing to <tunnel-uuid>.cfargotunnel.com. Example:
    • ha.yourdomain.com<tunnel-uuid>.cfargotunnel.com
    • Repeat for adguard, pi, and portainer.
  • Alternatively, use: cloudflared tunnel route dns homelab-tunnel ha.yourdomain.com (repeat for each subdomain).
  1. Run the Tunnel:
  • Start the tunnel: cloudflared tunnel run homelab-tunnel.
  • For persistence, set up as a systemd service:
    bash sudo cloudflared service install sudo systemctl enable cloudflared sudo systemctl start cloudflared

Step 5: Configure Portainer for Docker Management

  1. Access Portainer:
  • Initially, access Portainer at http://container-ip:9000.
  • After reverse proxy setup, use https://portainer.yourdomain.com.
  • On first login, create an admin user and password.
  1. Manage Containers:
  • In Portainer, go to “Environments” and ensure the local Docker environment is connected (it uses /var/run/docker.sock).
  • Navigate to “Containers” to view and manage all Docker containers (Home Assistant, AdGuard, Pi-hole, NPM).
  • Use Portainer to start/stop containers, view logs, or update images (e.g., docker pull equivalent).
  1. Optional: Stack Management:
  • In Portainer, go to “Stacks” → “Add Stack”.
  • Copy the docker-compose.yml content into the web editor to manage the entire setup as a stack.
  • This allows you to update all services via Portainer’s UI instead of the command line.

Step 6: Post-Setup Configuration

  1. DNS Configuration:
  • Pi-hole: Access https://pi.yourdomain.com/admin. Set as your router’s primary DNS for network-wide ad blocking.
  • AdGuard Home: Access https://adguard.yourdomain.com. Use as a secondary DNS (port 1053) or configure Pi-hole to forward to AdGuard.
  • To avoid conflicts, consider running only one DNS service or configuring them in tandem (e.g., Pi-hole as primary, AdGuard as upstream).
  1. Security:
  • Update all service passwords (Home Assistant, Pi-hole, AdGuard, Portainer, NPM).
  • In Proxmox, restrict firewall rules to allow only ports 80, 443, and 81 inbound.
  • Enable 2FA in Cloudflare for added security.
  1. Backups:
  • Back up Docker volumes (~/homelab/<service>) to Proxmox storage or an external location.
  • Use Portainer’s “Volumes” section to inspect and manage data.
  1. Testing:
  • Verify external access:
    • Home Assistant: https://ha.yourdomain.com
    • AdGuard: https://adguard.yourdomain.com
    • Pi-hole: https://pi.yourdomain.com/admin
    • Portainer: https://portainer.yourdomain.com
  • Check logs if issues arise: docker compose logs -f <service-name> or use Portainer’s log viewer.

Step 7: Troubleshooting Tips

  • Port Conflicts: Ensure no services bind to the same ports (e.g., only NPM uses 80/443 externally).
  • Cloudflare Tunnel Issues: Verify CNAME records and tunnel status (cloudflared tunnel info homelab-tunnel).
  • Docker Issues: Use Portainer’s “Containers” view or docker ps -a to check container status.
  • Logs: Access detailed logs via Portainer or docker logs <container-name>.

Total Containers

This setup includes five Docker containers:

  1. Home Assistant
  2. AdGuard Home
  3. Pi-hole
  4. Nginx Proxy Manager
  5. Portainer

Additional Notes

  • Refer to official documentation for specific service configurations:
  • Home Assistant: https://www.home-assistant.io
  • Pi-hole: https://pi-hole.net
  • AdGuard Home: https://adguard.com/adguard-home
  • Portainer: https://docs.portainer.io
  • Nginx Proxy Manager: https://nginxproxymanager.com
  • Ensure your domain is correctly set up in Cloudflare before configuring the tunnel.
  • Test each service locally before enabling the reverse proxy and Cloudflare Tunnel.
  • Regularly update containers via Portainer or docker compose pull && docker compose up -d.

This guide provides a complete setup with Portainer for easy management, accessible securely via Cloudflare Tunnel. Let me know if you need specific tweaks or further clarification!

https://grok.com/share/c2hhcmQtMw%3D%3D_d07e38a3-c7ad-42d8-8479-c49583c6b66a