Proxmox to SearXNG with Traefik

Created: 2025-06-05 19:47:38 | Last updated: 2025-06-10 20:38:52 | Status: Public

1. Install Proxmox 8.4.1

  • Boot from Proxmox ISO
  • Accept defaults through installer
  • Set root password and network config
  • Access web UI at https://[IP]:8006

2. Create Debian 12 VM via Helper Scripts

# SSH to Proxmox host
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/vm/debian-vm.sh)"
  • Select defaults
  • Note VM ID and IP
  • Resize disk: VM → Hardware → Hard Disk → Resize
# Install parted if needed
sudo apt install parted

# Resize the partition
sudo parted /dev/sda resizepart 1 100%

# Resize the filesystem
sudo resize2fs /dev/sda1

# Verify
df -h

3. Install Portainer on Debian VM

SSH to Debian VM:

# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# Install Portainer
docker volume create portainer_data
docker run -d -p 9000:9000 --name portainer --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data portainer/portainer-ce:latest

Access: http://[VM-IP]:9000

4. Deploy SearXNG Stack in Portainer

Create new stack with this compose:

version: '3.8'
services:
  searxng:
    image: searxng/searxng:latest
    container_name: searxng
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      - SEARXNG_BASE_URL=http://[VM-IP]:8080
    volumes:
      - ./searxng:/etc/searxng

Test: http://[VM-IP]:8080

5. Router Port Forwarding

  • Forward ports 80 and 443 to Debian VM IP
  • Varies by router - typically under “Port Forwarding” or “Virtual Server”

6. CloudFlare DNS Setup

  • Add domain to CloudFlare
  • Create A record: *[Your-Public-IP]
  • Set proxy status to “DNS only” (gray cloud)

7. Deploy Traefik Stack

Replace SearXNG stack with this:

version: '3.8'
services:
  traefik:
    image: traefik:v3.0.4
    container_name: traefik
    restart: unless-stopped
    command:
      - --api.dashboard=true
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.letsencrypt.acme.tlschallenge=true
      - --certificatesresolvers.letsencrypt.acme.email=your@email.com
      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.yourdomain.com`)"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
      - "traefik.http.routers.dashboard.service=api@internal"
    networks:
      - traefik

  searxng:
    image: searxng/searxng:latest
    container_name: searxng
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.searxng.rule=Host(`search.yourdomain.com`)"
      - "traefik.http.routers.searxng.tls.certresolver=letsencrypt"
      - "traefik.http.services.searxng.loadbalancer.server.port=8080"
    networks:
      - traefik

networks:
  traefik:
    external: false

Replace yourdomain.com and your@email.com with actual values.

8. Verify

  • Access SearXNG: https://search.yourdomain.com
  • Access Traefik dashboard: https://traefik.yourdomain.com
  • Check SSL certificates are valid

Recovery Notes

  • Backup /var/lib/docker/volumes for container data
  • Export Portainer stacks from UI
  • Document custom configurations
  • Keep CloudFlare API keys secure