Homelab Setup

2023-09-28

    After using my trusty old laptop for nearly 5 to 6 years, I noticed it had started making fan noises, even right after a fresh boot-up. Rather than retiring it or letting it gather dust, I decided to give it a new life by transforming it into a personal homelab server. Leveraging the power of Cloudflare Zero Trust and a collection of Docker containers, I embarked on a journey to create a versatile homelab environment.

    Within this homelab, I’ve set up a range of essential services that make daily life more enjoyable and efficient. These include a media player for movies, a music and audiobook player, a book reader, server monitoring tool, webpage monitoring capabilities, and a nice looking homepage accessible from virtually any device. What makes these services truly exceptional is their ability to accommodate multiple users, allowing family and friends to join in on the experience from anywhere.

    To make your homelab setup as smooth as possible, I’ve provided all the Docker Compose files you’ll need for each of these services. With them, you’ll be up and running in no time, ready to unlock the full potential of your homelab server. So, let’s dive in and see how each services with respective docker-compose stack looks like.


Homepage#

Homelab bookmarks tab, access all the self hosted services and more from this page. Allows fancy graphics and stuff too but I’ve gone only text based with minimal bookmarks.yml file configuration.

version: "3.3"
services:
  homepage:
    image: ghcr.io/benphelps/homepage:latest
    container_name: homepage
    ports:
      - 8921:3000
    volumes:
      - ./config:/app/config # Make sure your local config directory exists
      - /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations
    restart: unless-stopped

$ cat bookmarks.yaml

---

- Monitoring:
    - Portainer:
        - abbr: Pr
          href: https://portainer.pawanchhetri.com.np/
    - Grafana:
        - abbr: gf
          href: https://grafana.pawanchhetri.com.np/
    - Uptime-kuma:
        - abbr: Up
          href: https://uptimekuma.pawanchhetri.com.np/
    - SSH:
       - abbr: sh
         href: https://ssh.pawanchhetri.com.np/

- Media:
   - Music:
       - abbr: Mu
         href: https://music.pawanchhetri.com.np
   - Jellyfin:
       - abbr: Jf
         href: https://jellyfin.pawanchhetri.com.np
   - Audiobook:
       - abbr: AS
         href: https://audiobook.pawanchhetri.com.np

- Reading:
    - Blog:
       - abbr: Bl
         href: https://pawanchhetri.com.np/
    - Books:
        - abbr: KV
          href: https://books.pawanchhetri.com.np

- Social:
    - Reddit:
        - abbr: RE
          href: https://reddit.com/
    - YouTube:
        - abbr: YT
          href: https://youtube.com/
    - LinkendIn:
        - abbr: LN
          href: https://www.linkedin.com/
    - Github:
        - abbr: GH
          href: https://github.com/Pawan-666/
    - Feedly:
        - abbr: rss
          href: https://feedly.com/


Grafana Prometheus Nodeexporter Cadvisor#

For server and docker containers monitoring I’ve used Grafana. Helps to monitor the server CPU,Memory,Network status.

version: '3.3'
services:
``    node-exporter:
      # ports localhost:9100/metrics
        network_mode: host
        pid: host
        volumes:
            - '/:/host:ro,rslave'
        image: 'quay.io/prometheus/node-exporter:latest'

    prometheus:
        container_name: prometheus
        ports:
            - '9091:9090' #modify 9091 to your setup needs
        volumes:
            - './Configs/Prometheus/prometheus.yml:/etc/prometheus/prometheus.yml' #modify the path for your install location
        image: prom/prometheus

    cadvisor:
      image: gcr.io/cadvisor/cadvisor
      container_name: cadvisor
      ports:
        - 8080:8080
      volumes:
        - /:/rootfs:ro
        - /var/run:/var/run:rw
        - /sys:/sys:ro
        - /var/lib/docker:/var/lib/docker:ro

    grafana:            # admin/admin default username/password
        container_name: grafana
        ports:
            - '3457:3000' #modify 3457 to your setup needs
        image: grafana/grafana

$ cat prometheus.yml

global:
  scrape_interval: 5s
  external_labels:
    monitor: 'node'
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['192.168.1.68:9090'] ## IP Address of the localhost. Match the port to your container port
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['192.168.1.68:9100'] ## IP Address of the localhost

  - job_name: 'docker-metrics'
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.1.68:9323']

  - job_name: 'cAvisor'
    static_configs:
      - targets: ['192.168.1.68:8080']


Portainer#

I prefer and use terminal to deploy containers but portainer does provide nice gui to deploy docker stuffs with nice visualizations, bells and whistles.

version: "3.7"

services:
  portainer:
    image: portainer/portainer-ce:2.11.0-alpine # Replace 2.11.0 with the latest version.
    command: -H unix:///var/run/docker.sock
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /volume1/docker/config/Portainer:/data
    ports:
      - 9443:9443
    healthcheck:
      test: ['CMD', 'wget', '--spider', 'localhost:9000']
      interval: 15s # Amount of time after it starts checking for readiness



Uptime-kuma#

Fantastic to monitor websites(up or not), latency and ssl cert expiry date, You can even share the status page with clients.

version: '3'
services:
  uptime-kuma:
    image: louislam/uptime-kuma:1.23.2
    container_name: uptime-kuma
    restart: always
    ports:
      - "3001:3001"
    volumes:
      - ./data:/app/data


Jellyfin#

Your netflix at home. Also has plugin for subtitle download.

version: '3.3'
services:
    jellyfin:
        volumes:
            - './config:/config'
            - './cache:/cache'
            - '/home/pawan/Storage/movies/:/media'
        ports:
            - '8096:8096'
        container_name: jellyfin
        restart: unless-stopped
        image: jellyfin/jellyfin


Qbittorrent#

This is a basic requirement to add movies and series to your jellyfin server. I don’t use it and don’t recommend it either !.

---
version: "2.1"
services:
  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - WEBUI_PORT=8081
    volumes:
      - ./config:/config
      - /home/pawan/Storage/movies/torrent:/downloads

    ports:
      - 8081:8081
      - 6881:6881
      - 6881:6881/udp
    restart: unless-stopped


Nice music player, especially great for those who prefer listening music with full albums like I do. It has android clients too.

version: "3"
services:
  navidrome:
    image: deluan/navidrome:latest
    # user: 1000:1000 # should be owner of volumes
    ports:
      - "4533:4533"
    restart: unless-stopped
    environment:
      # Optional: put your config options customization here. Examples:
      ND_SCANSCHEDULE: 1h
      ND_LOGLEVEL: info  
      ND_SESSIONTIMEOUT: 24h
      ND_BASEURL: ""
    volumes:
      - "./data:/data"
      - "/home/pawan/Music/:/music:ro"


Audiobookshelf#

Same as the music player above but for audiobooks and podcasts.

version: "3.7"
services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:latest
    container_name: audiobookshelf
    ports:
      - 13378:80
    volumes:
      - /home/pawan/Storage/movies/AudioBooks:/audiobooks
      - /home/pawan/Storage/movies/podcast:/podcasts
      - ./config/:/config
      - ./metadata/:/metadata


Kavita#

An online book reader. I don’t like reading softcopy books tho. Ctrl+c/v code snippets from technical books is useful at times and it helps to have a softcopy even if you have a hardcopy for this purpose only.

version: '3.9'
services:
    kavita:
        image: kizaing/kavita:latest
        volumes:
            - /home/pawan/Storage/Bokks/Books:/manga
            - ./data:/kavita/config
        ports:
            - "5000:5000"
        restart: unless-stopped


Setup requirements and best practices#

  • Machine with a GNU/linux os
    • You can run a linux vm with bridge networking set up
  • Setting up static ip on your server for ip persistence
  • Knowledge of how docker containers work and how to deploy them using docker-compose
  • A domain name
  • Setting domains in Cloudflare
  • Using cloudflare zero trust to map subdomains to the docker containers
  • Desire to learn and troubleshoot, part of the process
  • Setting strong passwords for each service
  • Monitoring your server so that it doesn’t burn!

I've also set up Cloudflare Access to ssh into my machine from the browser itself. A directory is set for each docker-compose stack. Helps to keep configuration easy and clean as they should.



Surf the subreddit selfhosted for more awesomeness.