Skip to content

ivylikethevine/saffron

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

68 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Saffron

GitHub repo size GitHub last commit GitHub Repo stars GitHub forks GitHub License

(S)erver (A)s a (F)ile (F)older (R)unning (O)n (N)etwork

...the second half is a backcronym

Saffron is GPL-3.0 open sourced on github

Saffron is a docker compose deployment of a homelab via (almost entirely) static files

Why Saffron?

I built saffron because I wanted a way to utilize docker compose on a homelab server with easy SVM, configurability, and simple setup.

Read this project's README's as a wiki here, served via docsify.

Features

  • Media libraries for TV, movies, music, ebooks, & audiobooks. (+ subtitles!)
  • Easy migration from any existing docker or docker compose deployment.
  • Full torrenting suite with VPN integration.
  • Automated backup to cloud storage.
  • Smart home automation & integration.
  • Network speedtests + hardware monitoring.
  • Minecraft server hosting.
  • PXE environment for OS booting on other nodes.
  • Zero DNS or networking configuration outside of docker.
  • Easily configurable volume mounting via common.yaml and docker extends
Features (Under Development)
  1. Automatic traefik routing of containers using docker integration.
  2. Avahi mdns/nss-mdns discovery.
  3. Git submodules/subtrees for additional services.
  4. SSL certs

To deploy

Requires: git, docker, docker compose

Tested on: Linux Mint, Ubuntu, and Debian

# Grab saffron (either http or ssh)
git clone https://github.com/ivylikethevine/saffron.git # http, works with no SSH key
git clone git@github.com:ivylikethevine/saffron.git # ssh
cd saffron/resources

# Make directories with correct permssions, create common.yaml, & start dockge
./install-saffron.sh
Easy installation of git & docker
sudo apt install -y git # required to install saffron
sudo apt install -y curl # required to install docker via script
sudo apt install -y avahi-daemon # optional, but highly recommended for easy configuration

# Install docker from the easy install script
curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh ./get-docker.sh

# Allow docker to run without sudo
sudo usermod -aG docker $USER && newgrp docker
# And verify
docker run hello-world

Then visit http://localhost:5001 or http://<hostname>.local:5001 to start and stop individual stacks via the Dockge interface. Dockge is a Web UI to manage & control docker containers. As opposed to portainer, the user maintains direct and full control of the compose yaml files.

To Update
docker stop $(docker ps -a -q) # Important to stop before updates! (remove the $ if using fish shell)
cd /home/$USER/saffron
git pull
docker compose up -d dockge # Then visit dockge to start/stop containers

To Remove

cd /home/$USER/saffron/resources
./remove-saffron.sh

Important Paths

  1. /containers/ - stores individual generated configs, db files, etc.
    • This is not a perfect separation, since some containers will use config for "data" (such as torrent clients using it as a default download location)
  2. /home/$USER/saffron/stacks - all stacks & services' compose files
  3. $DATA_DIR - where bulk files are stored (configured during setup) See common.yaml for more infromation.

v0.35 List of Stacks & Services (35+ Apps, 40+ Containers)

** Names are lowercased per dockge stack naming requirements

  • 🚧 avahi - Allows docker containers to access mdns on LAN.

  • βœ… crafty - Easily deploy/manage minecraft servers.

  • βœ… dokemon - Web UI to manage docker containers/view logs/etc.

  • βœ… dockge - Web UI to manage docker compose files (integral to saffron).

    • WebUI Dashboard

      dockge ui screenshot x64 Version Arm64 Version
  • βœ… docsify - Web UI to view this repo's README.md's as a wiki reflecting local edits. See the public instance or visit http://hostname.local:5001 (if the container is running).

  • βœ… dozzle - Web UI to live docker container logs.

  • βœ… duplicati - Automated backup to AWS/Backblaze/etc.

  • βœ… esphome - Easily create & mange esp32-based IoT devices, such as temp. sensors.

  • βœ… handbrake - Web UI for transcoding video/audio files.

  • βœ… heimdall - Easy to use home page.

  • βœ… homeassistant - Smart home automation.

  • βœ… it-tools - Helpful tool for various tasks (generating UUIDs, hashes, etc.).

  • βœ… mariadb - Basic database (mostly used as template for adding to services that require a DB).

  • 🟒 media-clients - Various media streaming services.

    • βœ… jellyfin - TV/movie streaming.

    • βœ… jellyseerr - TV/movie requests.

    • βœ… kavita - Ebook reader.

    • βœ… navidrome - Music streaming service.

    • βœ… audiobookshelf - Audiobook streaming.

  • βœ… netboot - PXE boot system.

  • βœ… netdata - Hardware usage/monitoring (incl. containers).

  • βœ… octoprint - 3D printer automation/monitoring

  • βœ… plex - Fully featured media player/environment with many smart tv integrations.

  • 🟒 servarr - Media library systems.

    • βœ… sonarr - TV library manager.

    • βœ… radarr - Movie library manager.

    • βœ… lidarr - Music library manager.

    • βœ… readarr - Ebook library manager.

    • βœ… bazarr - Subtitle management/requests for sonarr/radarr.

  • βœ… speedtest-tracker - Internet speed monitoring.

  • 🚧 tdarr - Additional Web UI for transcoding video/audio files, with ability to use distributed compute nodes.

  • βœ… thelounge - IRC client.

  • 🟒 torrent - Full torrenting suite with a preconfigured .env.public.

    • βœ… qbittorrentvpn - Torrent client that runs only on VPN connection.

    • βœ… prowlarr - Search aggregator.

    • βœ… flaresolverr - Search proxy (required for some search engines & reduces error rates in general).

  • 🚧 traefik - Reverse proxy with easy docker integration.

  • βœ… uptime-kuma - Nice health checking tool with simple UI (same dev as Dockge!).

  • βœ… ustreamer - Easily deployable IP camera.

  • βœ… utils - Simple dockerfile-based compose with basic utils for debugging.

  • βœ… vscode-server - VSCode running with a Web UI (for editing saffron config files, etc.).

  • βœ… watchtower - Automatically update & restart docker containers.

  • βœ… windows - Automatic install/configuration with web VNC & native RDP for Windows XP -> Windows 11

Services under consideration

  • Adguard - for whole home ad blocking.
  • Ansible Semaphore - for easier host updating/management.
  • Mail Server - for notifications.
  • Cloudflare - for access outside of home network.
  • Nextcloud - for general homelab "cloud".

If a service isn't on here yet, feel free to add it! Most of these are very simple applications of the excellent linuxserver docker images. See creating a saffron-styled compose for more detail on the format of compose.yaml. There are also the official docker hub images.

I've also made stacks using Lissy93's well maintained portainer template repo, although this is slightly different than working from raw compose files.

Compatible with

  • obico - 3D print failure detection notification/stopping

    • To install: cd /home/$USER/saffron/stacks && git clone -b release https://github.com/TheSpaghettiDetective/obico-server.git && cd obico-server && docker compose up -d
  • For other projects that use a docker compose file from locally build Dockerfiles, clone the repo into /home/$USER/saffron/stacks, then add stacks/repoName/ to the .gitignore file. An alternative is to use either the p- or dev- prefix in the stack name to be ignored by git. See editing .gitignore for more information.

Configuration

common.yaml (new in v0.25)

By using a set of base "services"** inside of saffron/stacks/common.yaml, we can limit the length of each docker compose file & allow for easy re-use of shared docker configurations, mainly:

  1. Consistent PUID/PGID & UMASK - all extended services have shared environment variables.
  2. Consistent mount locations (such as media libraries) - library locations only have to be defined once.
  3. Consistent localtime - not very important, but nice to have.

On install, saffron copies it's local stacks/common.yaml.public file to stacks/compose.yaml, setting /data in all extended containers to the value of $DATA_DIR used during setup. This can be changed by using vscode-server and editing files in the saffron directory. common.yaml is set to be ignored by git to prevent committing personal directory paths.

** : These aren't full services since they have no images defined. As such, they can't run alone.

Env Files

This project has 2 types of .env files:

  1. .env - this type is natively loaded by dockge, allowing for Web UI editing + templating for paths. This is the place that VPN credentials, etc. should be stored since they will not be committed.
    • if stacks throw errors about undefined variables, make sure to define those variables in the .env for that stack.
    • these files are ignored by git, so they can locally hold some credentials (such as VPN logins) + personal folder routing
  2. .env.public - this holds basic preconfigurations for each container to work and should be changed with caution. They are not available in the Dockge Web UI.

Docker Volumes

When editing the DATA_DIR(s), it is often best to have the last part of the host volume match the container volume, such as:

  • /data/television/:/local/library/television -> Intuitive
  • /data/TV/:/local/library/television -> Often confusing (at least for me!)

Migration Tools

  • composerize - to turn docker run... into docker compose yaml (though dockge does have an implementation of this in the UI)
  • decomposerize - inverse of above
  • autocompose - to turn running containers into docker compose yaml
Internal Routing

For configuring docker containers that talk to each other, you can replace localhost with the container_name of the service to network, as long as both are inside of the same compose.yaml. For example, connecting prowlarr & sonarr, you can use prowlarr:9696 and sonarr:8989. If the containers are not in the same stack, this will require a bridge connection. An example of a bridge is included in servarr and torrent. To connect to servarr from torrent, qbittorrentvpn must use the servarr_bridge network.

Creating a Saffron-Styled compose from Scratch

Saffron is designed to be extensible. It is more an amalgamation of my experience than a specific software suite. As such, here is a compilation of my advice when creating new docker compose files for use with saffron or similar deployments.

  1. Only edit in one mode at a time - Implemented in this repository is a vscode server, which allows for editing of files that dockge does not display in the UI (such as .env.public, .gitignore, and the dockge compose.yaml). Using dockge to edit some files & vscode to edit others can often result in mismatches and confusion. For any operation, pick one tool and use that until you can fully transition to the other tool.
  2. Keep secrets in .env and double check your commits! An alternative option is docker secrets, but same rules apply. Make sure your commits never contain private keys, etc.
  3. Consistent naming - In the homelab space, some of the more advanced features of docker are not as useful and often lead to confusion. Here is an example format for a compose file, with explanations. Also, here is the compose documentation.
  • It is often easiest to name the stack after the main service in the compose file. image

stacks/vscode-server/compose.yaml

version: '3.8'
services:
  vscode-server:
    # "vscode-server" is the name of our service.
    image: linuxserver/code-server
    # Typically, the service name would be derived from the image name (the part after the "/"). Here, it is different to be easier for human readability since "code-server" is quite vague.
    container_name: vscode-server
    # Usually easiest to keep as exact duplicate of service name.
    restart: on-failure
    # Always remember to define a restart policy.
    ports:
      - 8445:8443
      # The port assignments in saffron are designed to avoid conflicts. host:container is the format, and it is easiest to change host mapping by itself, and not to mess with default port mappings. Some containers require environment variables to change the internal port, so its best to avoid.
    extends:
      file: ../common.yaml
      service: base-settings
      # base-settings: PUID, PGID, UMASK & localtime
      # media-access: base-settings + volume mounting $DATA_DIR(s)
    volumes:
      - /containers/vscode-server/config:/config
      # Again, usually easiest to follow /containers/container_name/folder:/folder for consistency & clarity.
networks: {}