430 lines
15 KiB
Markdown
430 lines
15 KiB
Markdown
# Homelab
|
|
|
|
I have a dedicated home server that I run a lot of services on. This repo has my monolithic `docker-compose.yml` plus info about what I run.
|
|
|
|
| | |
|
|
| --- | ------------------- |
|
|
| CPU | Intel i3-7100 |
|
|
| RAM | 32GB |
|
|
| SSD | 512GB |
|
|
| HDD | 3x10TB RAID-Z Array |
|
|
| OS | Debian |
|
|
|
|
## Services
|
|
|
|
These are all the services hosted, what they are for, and any clients I use with them, in alphabetical order.
|
|
|
|
### Media
|
|
|
|
- [AudioBookShelf](https://www.audiobookshelf.org/) - Audiobook, ebook, and podcast server
|
|
- The official mobile client works great
|
|
- [Immich](https://immich.app/) - Photo and video management
|
|
- Their official mobile apps are quite good
|
|
- [Jellyfin](https://jellyfin.org) - Media server for movies, TV shows, and music
|
|
- [Feishin](https://github.com/jeffvli/feishin) - Desktop music client (soon to be replaced by [audioling](https://github.com/audioling/audioling))
|
|
- [Finamp](https://github.com/jmshrv/finamp) - Mobile music client
|
|
- For other devices (desktop, mobile, Roku/Android TV) I use either the web app or the official Jellyfin client
|
|
|
|
### Utilities
|
|
|
|
- [Actual Budget](https://actualbudget.org/) - Excellent budgeting app. It can be automatically synced with your bank ([SimpleFIN Bridge](https://beta-bridge.simplefin.org/) for US banks, $15/year), but I have found that to be unstable
|
|
- There used to be an official app but it has been discontinued - I added the website to my phone's home screen and it works quite well
|
|
- [Baikal](https://sabre.io/baikal/) - Calendar/contacts
|
|
- [Backrest](https://github.com/garethgeorge/backrest) - UI to manage backups (sent to a Raspberry Pi 5 running [restic](https://restic.net/))
|
|
- [ConvertX](https://github.com/C4illin/ConvertX) - File conversion utility
|
|
- [Gitea](https://about.gitea.com/) - Git server - in the process of replacing my GitHub account
|
|
- [iOS Client](https://apps.apple.com/us/app/grocy-mobile/id1567803209)
|
|
- [Wallabag](https://wallabag.org/) - Bookmark tool for links, pictures, notes, etc.
|
|
- [IT Tools](https://github.com/CorentinTh/it-tools) - Collection of random useful development/IT utilities
|
|
- [Kiwix](https://kiwix.org/en/) - Offline wiki hosting - I have Wikipedia, the Arch Linux wiki, and several others downloaded
|
|
- [LubeLogger](https://lubelogger.com/) - Car mileage and service tracker
|
|
- [Maloja](https://github.com/krateng/maloja) - Self-hosted music listen tracker (last.fm replacement) - with [multi-scrobbler](https://github.com/FoxxMD/multi-scrobbler) for Jellyfin support
|
|
- [Memos](https://github.com/usememos/memos) - Super simple note/list/todo/memo app
|
|
- [Miniflux](https://miniflux.app/) - Minimalist RSS feed reader
|
|
- [NetNewsWire](https://netnewswire.com/) - Wonderful all-purpose iOS RSS client
|
|
- [Paperless-ngx](https://docs.paperless-ngx.com/) - Document management system for legal documents, IDs, bank statements, etc.
|
|
- [Swift Paperless](https://github.com/paulgessinger/swift-paperless) - iOS client
|
|
- [PicoShare](https://github.com/picocss/pico) - Super simple file sharing tool
|
|
- [Seafile](https://www.seafile.com/en/home/) - Cloud drive
|
|
- [Static Webserver](https://github.com/lipanski/docker-static-website) - Simple Docker container with BusyBox to serve my personal website ([azpsen.com](https://azpsen.com))
|
|
- [Stirling PDF](https://www.stirlingpdf.com/) - PDF tools for viewing, editing, converting, and everything else
|
|
- [Tandoor](https://tandoor.dev/) - Recipe management, so I always know which zucchine muffin recipe is the good one
|
|
- [Untare](https://github.com/phantomate/Untare) - Mobile client (discontinued but it still works for now)
|
|
- [Tinyhome](https://github.com/bderenzo/tinyhome) - Static new tab page set up with links to all my server stuff
|
|
- [Vaultwarden](https://github.com/dani-garcia/vaultwarden) - Password manager
|
|
- [Bitwarden clients](https://bitwarden.com/download/)
|
|
- [Wizarr](https://github.com/Wizarrrr/wizarr?tab=readme-ov-file) - Jellyfin user invite manager
|
|
- [Workout Tracker](https://github.com/jovandeginste/workout-tracker) - Used with [OpenTracks](https://github.com/OpenTracksApp/OpenTracks) to track my cycling
|
|
|
|
### Monitoring
|
|
|
|
- [Beszel](https://www.beszel.dev/) - System stats with pretty graphs
|
|
- [Dozzle](https://dozzle.dev/) - Docker logs all in one place
|
|
- [Glances](https://github.com/nicolargo/glances) - System monitor - I mostly have this for dashboard widgets but it can be useful by itself
|
|
- [Scrutiny](https://github.com/AnalogJ/scrutiny) - HDD SMART monitoring, so I know when to prepare for a drive failure
|
|
- [MySpeed](https://github.com/gnmyt/myspeed) - Runs scheduled internet speedtests and creates pretty graphs to keep my ISP honest
|
|
|
|
### Networking
|
|
|
|
- [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) - DNS filtering - I use this with [tailscale](https://tailscale.com/) to block ads on my phone
|
|
- [Cloudflared](https://github.com/cloudflare/cloudflared) - CloudFlare tunnel client for easy and secure external service access
|
|
- [Gluetun](https://github.com/qdm12/gluetun) - Docker VPN client and kill-switch. Very useful, allows for per-container VPN routing.
|
|
|
|
Note that I run tailscale as a system service, not in a container, so it is not listed here, but it is very useful for secure remote access - both for SSH and for services that don't need to be publicly visible.
|
|
|
|
In `docker-compose.yml`, services that I access through tailscale need the `dns: 100.111.0.126` section in order to access the internet (`100.111.0.126` is the tailscale IP of the server).
|
|
|
|
### Downloading
|
|
|
|
- [Bazarr](https://www.bazarr.media/) - Automated subtitle fetching (I also use the OpenSubtitles plugin within Jellyfin when needed, but this works hands-off most of the time)
|
|
- [Prowlarr](https://prowlarr.com/) - Torrent indexer that interfaces with the other \*arrs
|
|
- [qBittorrent](https://www.qbittorrent.org/) - The only torrent client I'll ever use
|
|
- [Radarr](https://radarr.video/) - Automated movie fetching
|
|
- [Sonarr](https://sonarr.tv/) - Automated TV show fetching
|
|
|
|
I use [LunaSea](https://www.lunasea.app/) as a mobile client for Radarr and Sonarr.
|
|
|
|
## Environment
|
|
|
|
This configuration uses `.env` files to separate secrets from public information and keep the main `docker-compose.yml` a little shorter. It is set up to look for these files in `/docker/env`, with each service having its own `<service>.env` file.
|
|
|
|
Below are the variables that need to be set in the `.env` file for each service. Empty variables should be replaced with your values.
|
|
|
|
> **A Note on Email**
|
|
>
|
|
> Several of these env files include SMTP settings, which are completely optional. Automated email sending is very useful for user signups, 2FA, account recovery, and notifications, but email is notoriously difficult to self-host. The solution I've found works very well and generally gets past spam filters.
|
|
>
|
|
> I use [SendGrid](https://sendgrid.com/en-us) with CloudFlare's [email routing](https://blog.cloudflare.com/introducing-email-routing/) for email. I have a catch-all rule in CloudFlare that forwards all emails to a dedicated Gmail address, and that address uses a `Send Mail As` address set up with SendGrid's SMTP for sending emails by hand.
|
|
>
|
|
> By default, emails sent this way will show a little `via sendgrid.net` notice. To remove this, [verify your domain](https://www.twilio.com/docs/sendgrid/ui/account-and-settings/how-to-set-up-domain-authentication) with SendGrid.
|
|
>
|
|
> Also, link tracking is enabled by default and should be disabled in SendGrid's tracking settings.
|
|
>
|
|
> **SMTP Settings:**
|
|
>
|
|
> - Host: `smtp.sendgrid.net`
|
|
> - Port: `587`
|
|
> - Security: `tls` (or equivalent, e.g. `starttls` for vaultwarden)
|
|
> - Username: `apikey`
|
|
> - Password: API Key generated in SendGrid
|
|
> - From: `<mailer-name>@<your-domain>` - For each custom sender (`mailer-name`), there needs to be a verified sender in SendGrid.
|
|
|
|
### Beszel
|
|
|
|
[Docs](https://www.beszel.dev/guide/environment-variables)
|
|
|
|
```env
|
|
# beszel.env
|
|
|
|
# Hub settings
|
|
BESZEL_HUB_APP_URL=
|
|
|
|
# Agent settings
|
|
BESZEL_AGENT_LISTEN=/beszel_socket/beszel.sock
|
|
BESZEL_AGENT_KEY=''
|
|
```
|
|
|
|
### Cloudflared
|
|
|
|
[Docs](https://github.com/cloudflare/cloudflared?tab=readme-ov-file)
|
|
|
|
```env
|
|
# cloudflared.env
|
|
|
|
# Available in the cloudflare zero-trust tunnel dashboard, under `install and run a connector`
|
|
TUNNEL_TOKEN=
|
|
```
|
|
|
|
### ConvertX
|
|
|
|
[Docs](https://github.com/C4illin/ConvertX#environment-variables)
|
|
|
|
```env
|
|
# convertx.env
|
|
|
|
JWT_SECRET=
|
|
HTTP_ALLOWED=true
|
|
```
|
|
|
|
### Gluetun
|
|
|
|
[Docs](https://github.com/qdm12/gluetun)
|
|
|
|
The values below are specific to Mullvad VPN ([gluetun docs](https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/mullvad.md)). Other providers need different values, refer to the corresponding gluetun documentation.
|
|
|
|
```env
|
|
# gluetun.env
|
|
|
|
VPN_SERVICE_PROVIDER=mullvad
|
|
VPN_TYPE=wireguard
|
|
WIREGUARD_PRIVATE_KEY=
|
|
WIREGUARD_ADDRESSESS=
|
|
SERVER_CITIES=
|
|
```
|
|
|
|
The values for `WIREGUARD_PRIVATE_KEY` and `WIREGUARD_ADDRESSES` should be available in the WireGuard configuration file generated by Mullvad. `SERVER_CITIES` should be set to the city of your configuration's selected exit node.
|
|
|
|
### Immich
|
|
|
|
[Docs](https://immich.app/docs/install/docker-compose/)
|
|
|
|
My current Immich docker setup has a lot of repetition - when I want to update, I have to change the version in 3 places. I have plans to improve this, but for now this is what works. Also note that the way I set the upload location is not recommended by the Immich docs.
|
|
|
|
```env
|
|
# immich.env
|
|
|
|
UPLOAD_LOCATION=/media/immich
|
|
|
|
TYPESENSE_API_KEY=
|
|
DB_PASSWORD=
|
|
|
|
DB_HOSTNAME=immich_postgres
|
|
DB_USERNAME=postgres
|
|
DB_DATABASE_NAME=immich
|
|
DB_DATA_LOCATION=/docker/immich
|
|
|
|
REDIS_HOSTNAME=immich_redis
|
|
|
|
POSTGRES_PASSWORD= # this should be the same as DB_PASSWORD above
|
|
POSTGRES_USER=postgres
|
|
POSTGRES_DB=immich
|
|
```
|
|
|
|
### Invidious
|
|
|
|
[Docs](https://docs.invidious.io/installation/)
|
|
|
|
Note that the `password` under `db` in `INVIDIOUS_CONFIG` should be the same as the `POSTGRES_PASSWORD`. The `hmac_key` should be a different, randomly generated value
|
|
|
|
```env
|
|
# invidious.env
|
|
|
|
# Invidious
|
|
INVIDIOUS_CONFIG='
|
|
db:
|
|
dbname: invidious
|
|
user: invidious
|
|
password:
|
|
host: invidious-db
|
|
port: 5432
|
|
check_tables: true
|
|
signature_server: invidious-sighelper:12999
|
|
visitor_data:
|
|
po_token:
|
|
external_port: 9080
|
|
https_only: false
|
|
statistics_enabled: false
|
|
registration_enabled: false
|
|
popular_enabled: false
|
|
hmac_key:
|
|
admins: ["april"]
|
|
default_user_preferences:
|
|
quality: dash
|
|
feed_menu: ["Trending", "Subscriptions", "Playlists"]
|
|
default_home: Trending
|
|
'
|
|
|
|
# Database
|
|
POSTGRES_DB=invidious
|
|
POSTGRES_USER=invidious
|
|
POSTGRES_PASSWORD=
|
|
|
|
# to update the visitor_data and po_token:
|
|
# docker run quay.io/invidious/youtube-trusted-session-generator
|
|
# or, for use with gluetun:
|
|
# docker run --network=container:gluetun quay.io/invidious/youtube-trusted-session-generator
|
|
```
|
|
|
|
### LubeLogger
|
|
|
|
[Docs](https://docs.lubelogger.com/Advanced/Environment%20Variables)
|
|
|
|
```env
|
|
# lubelogger.env
|
|
LC_ALL=en_US
|
|
LANG=en_US
|
|
MailConfig__EmailServer=
|
|
MailConfig__EmailFrom=
|
|
MailConfig__Port=587
|
|
MailConfig__Username=
|
|
MailConfig__Password=
|
|
```
|
|
|
|
### Miniflux
|
|
|
|
[Docs](https://miniflux.app/docs/docker.html)
|
|
|
|
```env
|
|
# miniflux.env
|
|
|
|
DATABASE_URL=postgres://miniflux:{...}@rss_db:5432/miniflux?sslmode=disable # replace {...} with your postgres password
|
|
RUN_MIGRATIONS=1
|
|
|
|
POSTGRES_USER=miniflux
|
|
POSTGRES_PASSWORD= # this is the password used above
|
|
POSTGRES_DB=miniflux
|
|
```
|
|
|
|
### MultiScrobbler
|
|
|
|
[Docs](https://foxxmd.github.io/multi-scrobbler/docs/configuration/)
|
|
|
|
```env
|
|
# scrobbler.env
|
|
|
|
TZ=America/Chicago
|
|
PUID=1000
|
|
PGID=1000
|
|
MALOJA_URL=http://maloja:42010
|
|
MALOJA_API_KEY=
|
|
JELLYFIN_URL=http://jellyfin:8096
|
|
JELLYFIN_USER=
|
|
JELLYFIN_APIKEY=
|
|
JELLYFIN_USERS_ALLOW=
|
|
```
|
|
|
|
### Paperless-ngx
|
|
|
|
[Docs](https://docs.paperless-ngx.com/setup/#docker)
|
|
|
|
```env
|
|
# paperless.env
|
|
|
|
USERMAP_UID=1000
|
|
USERMAP_GID=1000
|
|
PUID=1000
|
|
PGID=1000
|
|
|
|
PAPERLESS_URL=
|
|
|
|
# Random secret key, use for example `base64 /dev/urandom | head -c50` to generate one
|
|
PAPERLESS_SECRET_KEY=
|
|
|
|
PAPERLESS_TIME_ZONE=
|
|
|
|
PAPERLESS_OCR_LANGUAGE=eng
|
|
|
|
PAPERLESS_REDIS: redis://paperless_broker:6379
|
|
PAPERLESS_OCR_USER_ARGS: '{"invalidate_digital_signatures": true}'
|
|
|
|
# Optional SMTP email settings
|
|
PAPERLESS_EMAIL_HOST=
|
|
PAPERLESS_EMAIL_PORT=587
|
|
PAPERLESS_EMAIL_USE_TLS=true
|
|
PAPERLESS_EMAIL_HOST_USER=
|
|
PAPERLESS_EMAIL_HOST_PASSWORD=
|
|
PAPERLESS_EMAIL_FROM=
|
|
```
|
|
|
|
### PicoShare
|
|
|
|
[Docs](https://github.com/mtlynch/picoshare)
|
|
|
|
```env
|
|
# picoshare.env
|
|
|
|
PORT=4001
|
|
PS_SHARED_SECRET=
|
|
PS_BEHIND_PROXY=true
|
|
```
|
|
|
|
### Seafile
|
|
|
|
[Docs](https://manual.seafile.com/11.0/docker/deploy_seafile_with_docker/)
|
|
|
|
```env
|
|
# seafile.env
|
|
|
|
DB_HOST=seafile_db
|
|
DB_ROOT_PASSWD=
|
|
SEAFILE_ADMIN_EMAIL=
|
|
SEAFILE_ADMIN_PASSWORD=
|
|
SEAFILE_SERVER_HOSTNAME=
|
|
FORCE_HTTPS_IN_CONF=true
|
|
|
|
MYSQL_ROOT_PASSWORD= # same as DB_ROOT_PASSWD above
|
|
MYSQL_LOG_CONSOLE=true
|
|
MARIADB_AUTO_UPGRADE=1
|
|
```
|
|
|
|
### Tandoor
|
|
|
|
[Docs](https://docs.tandoor.dev/install/docker/)
|
|
|
|
```env
|
|
# tandoor.env
|
|
|
|
# Random secret key, use for example `base64 /dev/urandom | head -c50` to generate one
|
|
SECRET_KEY=
|
|
|
|
# Allowed hosts (see documentation), should be set to your hostname(s) but might be * (default) for some proxies/providers
|
|
ALLOWED_HOSTS=
|
|
|
|
# Add only a database password if you want to run with the default postgres, otherwise change settings accordingly
|
|
DB_ENGINE=django.db.backends.postgresql
|
|
POSTGRES_HOST=tandoor-db
|
|
POSTGRES_DB=tandoor
|
|
POSTGRES_PORT=5432
|
|
POSTGRES_USER=tandoor
|
|
POSTGRES_PASSWORD=
|
|
```
|
|
|
|
### Vaultwarden
|
|
|
|
[Docs](https://github.com/dani-garcia/vaultwarden)
|
|
|
|
Note that the cryptography API used by vaultwarden requires HTTPS, so local access can be a bit of a challenge.
|
|
|
|
These values are only required if you need to use the vaultwarden admin page (for user management, SMTP, hardware 2FA, etc.). The `ADMIN_TOKEN` value gave me trouble - to make it work, I used the 'Using `argon2`' instructions from [Enabling admin page](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page) in the docs. At `your-ip-or-url.com/admin`, the password you used for the hash will unlock it (e.g. `MySecretPassword` per their example).
|
|
|
|
Note: The `ADMIN_TOKEN` value should be enclosed in single quotes. If it is not, all instances of `$` in the value will need to be replaced with `$$` to prevent the value from being split by the parser.
|
|
|
|
```env
|
|
# vaultwarden.env
|
|
|
|
# Public domain or IP
|
|
DOMAIN=
|
|
|
|
ADMIN_TOKEN=
|
|
|
|
# Optional SMTP email settings
|
|
SMTP_HOST=
|
|
SMTP_FROM=
|
|
SMTP_PORT=587
|
|
SMTP_SECURITY=starttls
|
|
SMTP_USERNAME=
|
|
SMTP_PASSWORD=
|
|
```
|
|
|
|
### Wallabag
|
|
|
|
[Docs](https://hub.docker.com/r/wallabag/wallabag/)
|
|
|
|
The domain name should be set to your Wallabag instance's domain (e.g. links.mysite.com). Server name is just a pretty name for your instance. The DB password and secret can be set to randomly generated strings.
|
|
|
|
FOSUSER_REGISTRATION must be set to `true` for at least the first run so a user can be created.
|
|
|
|
Note: The username/password need to be included in the mailer DSN (e.g. smtp://apikey:mykey12345@smtp.sendgrid.net)
|
|
|
|
```env
|
|
# wallabag.env
|
|
|
|
SYMFONY__ENV__DOMAIN_NAME=
|
|
SYMFONY__ENV__SERVER_NAME=
|
|
SYMFONY__ENV__DATABASE_PASSWORD=
|
|
SYMFONY__ENV__SECRET=
|
|
SYMFONY__ENV__FOSUSER_REGISTRATION=false
|
|
SYMFONY__ENV__MAILER_DSN=
|
|
SYMFONY__ENV__FROM_EMAIL=
|
|
```
|
|
|
|
### Workout Tracker
|
|
|
|
[Docs](https://github.com/jovandeginste/workout-tracker#docker)
|
|
|
|
```env
|
|
# workout-tracker.env
|
|
|
|
WT_JWT_ENCRYPTION_KEY=
|
|
```
|