Series of posts about my homelab

81 posts latest post 2026-10-06
Publishing rhythm
Oct 2026 | 1 posts

I heard about SearXNG on a couple podcasts and saw it trending on GitHub several times before I finally decided to stand it up. I used it transparently when trying out khoj, a self-hosted AI LLM agent playground kind of a thing, but I’ve also been messing around with Open-WebUI to have a self-hosted ChatGPT-like experience. I don’t know if SearchXNG used to be harder to set up, but it was pretty simple with a Docker Compose up and a couple configuration options given my personal homelab setup. Using it feels very nice.

services:
  redis:
    container_name: redis
    image: docker.io/valkey/valkey:8-alpine
    command: valkey-server --save 30 1 --loglevel warning
    restart: unless-stopped
    volumes:
      - ./data/redis:/data
    logging:
      driver: "json-file"
      options:
        max-size: "1m"
        max-file: "1"

  searxng:
    container_name: searxng
    image: docker.io/searxng/searxng:latest
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - ./data/searxng:/etc/searxng:rw
    env_file: .env
    environment:
      # - SEARXNG_BASE_URL=https://${SEARXNG_HOSTNAME:-localhost}/
      - UWSGI_WORKERS=${SEARXNG_UWSGI_WORKERS:-4}
      - UWSGI_THREADS=${SEARXNG_UWSGI_THREADS:-4}
    logging:
      driver: "json-file"
      options:
        max-size: "1m"
        max-file: "1"

I love the self-hosted aspect. I love not seeing any ads on my search results. I did a few searches where I know what results to expect and it did okay. It is good right now at filtering out garbage in my results.

SearXNG

So I look forward to tweaking it and using it as a search backend with open web UI. Next on my list is having enough resources to run Ollama and a stable diffusion generator at the same time and have image generation working through open web UI.

It’s easy to configure push notifications through Gotify from Grafana by setting up a generic Webhook Alerting Contact Point…

The parameters are:

  • HTTP Method: POST
  • URL: http:///message
  • Authentication is done with an app token generated from Gotify, and you put it in Authorization Header: Credentials in the Grafana configuration

See image

💭 audiobookshelf

Audiobookshelf looks like a solid competitor for booksonic. I've liked the simple subsonic api driven nature of booksoni

1 min

I’m building a few FastAPI apps to throw in docker and run on my homelab… I wanted to add healthchecks and here’s a simple way to do it

Make sure to install curl in the dockerfile (near the top for effeciency)

# Install curl with minimal dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

Then I recommend making compose files even for single image deployments

services:
  app:
    build: .
    volumes:
      - type: bind
        source: .
        target: /app
    environment:
      - PYTHONPATH=/app
      - DOCKER_ENV=true
      - UV_VIRTUALENV=/opt/app-env
    user: "1000:1000"
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

Then finally you’ll need a /health endpoint


@app.get("/health", response_class=HTMLResponse)
async def health_check():
    """
    A health check endpoint that returns a status message.
    """
    return "<html><body><h1>Service is healthy</h1></body></html>"

I use LSIO Jelyfin container for the easy addon they provide for AMD GPUs but I couldn’t get trickplay to work with HWE…

There was almost NOTHING on the internet about the error, and all the threads were about BSD systems…

Thankfully someone posted on the formum here but the only answer was to literally upgrade stuff in the container…

Someday maybe I’ll build off of LSIO to add this, but until then I shell’d in and homelab’d the hell out of it

THIS IS INSIDE THE CONTAINER - I use Portianer to make it easy


apt update && apt install -y curl gpg

mkdir -p /etc/apt/keyrings

curl -fsSL https://repo.radeon.com/rocm/rocm.gpg.key | gpg --dearmor -o /etc/apt/keyrings/rocm.gpg

cat <<EOF | tee /etc/apt/sources.list.d/rocm.sources

Types: deb

URIs: https://repo.radeon.com/rocm/apt/latest

Suites: ubuntu

Components: main

Architectures: amd64

Signed-By: /etc/apt/keyrings/rocm.gpg

EOF

apt update && apt install -y rocm-opencl-runtime

hostnamectl is apparently a linux utility for easily changing your hostname in a variety of ways


❯ hostnamectl --help
hostnamectl [OPTIONS...] COMMAND ...

Query or change system hostname.

Commands:
  status                 Show current hostname settings
  hostname [NAME]        Get/set system hostname
  icon-name [NAME]       Get/set icon name for host
  chassis [NAME]         Get/set chassis type for host
  deployment [NAME]      Get/set deployment environment for host
  location [NAME]        Get/set location for host

Options:
  -h --help              Show this help
     --version           Show package version
     --no-ask-password   Do not prompt for password
  -H --host=[USER@]HOST  Operate on remote host
  -M --machine=CONTAINER Operate on local container
     --transient         Only set transient hostname
     --static            Only set static hostname
     --pretty            Only set pretty hostname
     --json=pretty|short|off
                         Generate JSON output

See the hostnamectl(1) man page for details.

I learned there’s transient and static hostnames, so that’s cool…

The thing I needed was hostnamectl --static hostname babyblue-aurora

pretty sweet tool

I rebooted by server and DNS broke randomly. I have no idea if it was from a kernel update or what but that’s the issue with Ubuntu I guess…

After much toil and none of the other options working for me (sorry to not have those documented here) this is what got me the vic from this SO Post

sudo mkdir /etc/systemd/resolved.conf.d/ sudo $EDITOR /etc/systemd/resolved.conf.d/dns_servers.conf

Most folks probably are good with google (8.8.8.8) and cloudflare (1.1.1.1)

[Resolve]
DNS=8.8.8.8 1.1.1.1

But I decided to use tailscale

[Resolve]
DNS=100.100.100.100

Then restart systemd-resolved

sudo systemctl restart systemd-resolved

enabling DHCP WAN port (dhclient <iface>)- running the bootstrap script - sh /usr/local/sbin/opnsense-bootstrap

Recovering OPNSense

I woke up to faulty internet and after some troubleshooting it turns out the root zfs dataset that OPNSense boots from got corrupted… PRO-TIP - Auto backup your OPNSense config to Google Drive, git, or nextcloud… But if you won’t then at least back up your OPNSense config somewhere everytime you update it. It’s too much to recount every issue, so here’s a bullet list what worked. On a fresh drive install OPNSense Plug in the old drive through a USB enclosure - now I’m not sure what would happen if you plugged it in along with the new drive and then booted up. Because both drives will have a zfs pool and the boot dataset is automounted at. My old pool was so it didn’t automount Because the old was corrupted I did this to mount it RO: -d is the zfs flag to import the pool by disk id, -N it to not mount any of the datasets (we need to change mountpoints) and the imports the pool with a new name Change the mountpoints for all the datasets to somewhere like Depending on the mount point you…

Add from url??

ADD http://example.com/cars.csv /tmp/cars.csv

Unpack automatically!? (.tar, .tar.gz, .tgz, .bz2, .tbz2, .txz, .zip)

ADD myapp.tar.gz /opt/myapp/