• Home
  • About
    • FuzzyGrim

      Another computer enthusiast

    • Email
    • Matrix
    • Github
    • RSS
    • Learn More
  • Posts
    • All Posts
    • All Tags
  • Projects
  • Seasons

My self-hosting setup

22 Jan 2022 / 7 minutes

A few months ago, I started my journey in self-hosting with a media server on my laptop, and after playing with some other applications and being able to enjoy the control over my system and my data, I became even more interested. Also, as I started college, I have needed my laptop for it, so I decided to buy a dedicated machine for hosting and take this opportunity to learn more.

So, I am writing this to share my current setup after tinkering during my year-end break as a way to document what I did for myself and for others who may be interested. Also, with this, I will have a record of what I did during this moment in time to look back on in the future.

Hardware

My budget was around 300€, and I was looking for something small and quiet because I was going to place it in my bedroom, another plus was to have a low power consumption (0.27 €/kWh). My initial idea was to buy a Raspberry Pi, but after searching for it, I think they are quite expensive for what they offer. My next idea was a Intel NUC, and as I was looking for a good deal on Ebay, I found something even better in my opinion, a Fujitsu C720 for 65€ with the following specifications:

  • Intel Core i5-4570
  • 8GB RAM DDR3
  • 1TB HDD

I wanted an SSD for the OS, and since the PC didn’t seem to have space for another internal drive, I bought a 500GB external SSD from Samsung for 75€. The 1TB hard drive that came with the PC was going to be used for NextCloud and I already had a 1TB external hard drive for backups. Finally, I wanted another drive to store my media server, so I went with a 2TB WD Elements for 60€. This added up to a total price of 200€.

pc

Operating System

At first, I was thinking of using Debian or Ubuntu Server, however after reading different posts on r/homelab and r/selfhosted I was convinced to try Proxmox. My current setup, after learning how to use Proxmox and seeing multiple comparisons on VM vs LXC, is:

Proxmox

I basically have 4 LXC containers:

  • Resettable: A container that I don’t mind being restarted/downloaded, it currently hosts Libreddit, Invidious, LibreSpeed and Portainer.

  • Media Server: Here I am hosting Jellyfin, Radarr, Sonarr, Bazarr and Ombi and I have binded the 2TB external HDD.

  • VPN: Some services that needs to be run behind a VPN, they are currently only Transmission and Prowlarr, it has also binded the 2TB external HDD.

  • Storage: All the services whose data is stored on the 1TB hard disk and needs to be backed up to the 1TB external hard disk, I host most of my services here and some of them are: Vaultwarden, Nextcloud and Bookstack.

Services

I am running all my services as a Docker container with docker compose, which made it easier to maintain all the different services I was hosting. Each group of related services has its own docker-compose.yml with all the services you need, such as databases or auto-healing. You can find all my docker-compose files on Github.

I am currently hosting over 20 services, which are currently only meant to be used by myself and therefore are not faced to the public. Some of the services I want to highlight are shown below with their docker-compose file configuration.

Heimdall

A simple and beautiful dashboard, I use it mainly as a way to see all my current hosted services and as a shortcut to each of them.

You can see most of the services I am hosting with my Heimdall dashboard:

Heimdall

version: "2.1"
services:
  heimdall:
    image: lscr.io/linuxserver/heimdall
    container_name: heimdall
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - /data/heimdall:/config
    ports:
      - 49154:80
      - 49155:443
    restart: unless-stopped

Media Server

The main reason I wanted to start self-hosting, it can automatically download the necessary episodes as they are released.

Jellyfin

It is composed by a stack with Jellyfin, Sonnar, Radarr, Bazarr and Ombi and another stack with Prowlarr and Transmission because they are hosted in different LXC containers:

version: "3"
services:
  jellyfin:
    image: linuxserver/jellyfin
    container_name: jellyfin
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - ./jellyfin_config:/config
      - /data/media/tvshows:/data/tvshows
      - /data/media/movies:/data/movies
      - /data/media/anime:/data/anime
    devices:
      - "/dev/dri:/dev/dri"
    ports:
      - 8096:8096
    restart: unless-stopped

  sonarr:
    image: linuxserver/sonarr
    container_name: sonarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - ./sonarr_config:/config
      - /data/media/anime:/anime
      - /data/media/tvshows:/tvshows
      - /data/transmission/downloads/complete:/downloads/complete
    ports:
      - 8989:8989
    restart: unless-stopped

  radarr:
    image: linuxserver/radarr
    container_name: radarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - ./radarr_config:/config
      - /data/transmission/downloads/complete:/downloads/complete
      - /data/media/movies:/movies
    ports:
      - 7878:7878
    restart: unless-stopped

  ombi:
    image: linuxserver/ombi
    container_name: ombi
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - ./ombi_config:/config
    ports:
      - 3579:3579
    restart: unless-stopped
    depends_on:
      - radarr
      - sonarr
  bazarr:
    image: linuxserver/bazarr
    container_name: bazarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - ./bazarr_config:/config
      - /data/media/movies:/movies #optional
      - /data/media/tvshows:/tvshows #optional
      - /data/media/anim:/anime
    ports:
      - 6767:6767
    restart: unless-stopped
version: "2.1"
services:
  prowlarr:
    image: linuxserver/prowlarr:develop
    container_name: prowlarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - ./prowlarr:/config
    ports:
      - 9696:9696
    restart: unless-stopped

  transmission:
    image: linuxserver/transmission
    container_name: transmission
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - ./transmission:/config
      - /data/transmission/downloads:/downloads
    ports:
      - 9091:9091
      - 51413:51413
      - 51413:51413/udp
    restart: unless-stopped

Data analytics and monitoring

I don’t monitor a lot of data and I don’t look at it very often but I think it came out pretty good.

Grafana

Although the full configuration of the monitoring stack is beyond the scope of this post, the main docker-compose file is a stack with Grafana, Loki, Promtail and Prometheus. I install Netdata separately with this command: bash <(curl -Ss https://my-netdata.io/kickstart.sh).

version: "3"
networks:
  loki:
services:
  loki:
    image: grafana/loki:2.4.0
    volumes:
      - /data/loki:/etc/loki
    ports:
      - "3100:3100"
    restart: unless-stopped
    command: -config.file=/etc/loki/loki-config.yml
    networks:
      - loki

  promtail:
    image: grafana/promtail:2.4.0
    volumes:
      - /var/log:/var/log
      - /data/promtail:/etc/promtail
    # ports:
    #   - "1514:1514" # this is only needed if you are going to send syslogs
    restart: unless-stopped
    command: -config.file=/etc/promtail/promtail-config.yml
    networks:
      - loki

  grafana:
    image: grafana/grafana:latest
    user: "1000"
    volumes:
    - /data/grafana:/var/lib/grafana
    ports:
      - "3000:3000"
    restart: unless-stopped
    networks:
      - loki

  prometheus:
    container_name: prometheus      
    ports:
      - '9080:9090'
    volumes:
      - '/data/prometheus:/etc/prometheus'
    image: prom/prometheus
    restart: unless-stopped
    networks:
      - loki

Bookstack

An elegant wiki software, I use it for documentation and note-taking.

BookStack

version: "2"
services:
  bookstack:
    image: linuxserver/bookstack
    container_name: bookstack
    environment:
      - PUID=1000
      - PGID=1000
      - APP_URL=${URL}
      - DB_HOST=bookstack_db
      - DB_USER=bookstack
      - DB_PASS=${DB_PW}
      - DB_DATABASE=bookstackapp
    volumes:
      - /data/bookstack/config:/config
    ports:
      - 6875:80
    restart: unless-stopped
    depends_on:
      - bookstack_db
  bookstack_db:
    image: linuxserver/mariadb
    container_name: bookstack_db
    environment:
      - PUID=1000
      - PGID=1000
      - MYSQL_ROOT_PASSWORD=${DB_PW}
      - TZ=Europe/Madrid
      - MYSQL_DATABASE=bookstackapp
      - MYSQL_USER=bookstack
      - MYSQL_PASSWORD=${DB_PW}
    volumes:
      - /data/bookstack/database/config:/config
    restart: unless-stopped

Vaultwarden

It’s an unofficial server implementation of Bitwarden. It’s a fast, simple and cross-platform password manager.

version: '3'

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    environment:
      - WEBSOCKET_ENABLED=true  # Enable WebSocket notifications.
    volumes:
      - ./vw-data:/data
    ports:
      - 8086:80

Nextcloud

Probably the most popular self-hosted application, I’m using it for cloud storage, CalDAV, CardDAV, Kanban, Bookmarks and Notes. Although I’ve seen people complaining about the slowness of the software and the difficulty in configuring it, I haven’t had any problems with my hardware.

Nextcloud

version: "3.7"

services:
  nextcloud:
    image: linuxserver/nextcloud:latest
    container_name: nextcloud
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - /data/nextcloud/config:/config
      - /data/nextcloud:/data
    ports:
      - 9443:443
    restart: unless-stopped
    depends_on:
      - db

  db:
    image: linuxserver/mariadb:latest
    container_name: nextcloud_db
    environment:
      - PUID=1000
      - PGID=1000
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PW}
      - TZ=${TIMEZONE}
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PW}
    volumes:
      - /data/nextcloud/config_db:/config
    restart: unless-stopped

Duplicati

Duplicati is my go-to backup tool, I use it to back up to my 1TB external drive and MEGA.NZ as I currently don’t have much data to back up. I am thinking of using BlackBlaze B2 in the future once my data is big enough.

Duplicati

version: "2.1"
services:
  duplicati:
    image: lscr.io/linuxserver/duplicati
    container_name: duplicati
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
    volumes:
      - ./config:/config
      - /backup:/backups
      - /data:/source
    ports:
      - 8200:8200
    restart: unless-stopped

Watchtower

Watchtower is great for keeping your services up to date, although the default setting is to update them automatically, I prefer to simply receive a discord notification when an update is available.

version: "3"
services:
  watchtower:
    container_name: watchtower
    image: containrrr/watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      TZ: Europe/Madrid
      WATCHTOWER_SCHEDULE: 0 30 18 * * *
      WATCHTOWER_MONITOR_ONLY: "true"
      WATCHTOWER_CLEANUP: "true"
      WATCHTOWER_NO_STARTUP_MESSAGE: "true"
      WATCHTOWER_NOTIFICATIONS: "shoutrrr"
      WATCHTOWER_NOTIFICATION_URL: "discord://token@channel"

Caddy

Caddy is my choice for reverse-proxy, it is used to map a domain or subdomain to the corresponding port exposed in the docker container. It is simple to configure and also automatically obtains and renews TLS certificates for you.

version: '3'

services:
  caddy:
    image: caddy:2
    container_name: caddy
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./caddy:/usr/bin/caddy  # Your custom build of Caddy.
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy-config:/config
      - ./caddy-data:/data
    environment:
      - EMAIL=${email}
      - CLOUDFLARE_API_TOKEN=${cloudflare_token}
      - LOG_FILE=/data/access.log

You can see the rest of my docker-compose files on Github.

Conclusion

As you can see, my current setup is just a combination of multiple Docker services that I take care of, I am considering to learn Ansible for some automation in the future. However, the next rabbit hole will be home automation with Home Assistant.

That’s it my friends, if you made it this far, congratulations and thanks for reading. I wish you the best in your self-hosting adventures!



self-hosting
Toot RSS Kofi