I am running a home server for a while now. I have been using it to host some services that I use regularly. In this post, I will share my experience with some of the services I have set up on my home server.
This initial post will go over local git
hosting using gitea, audiobook streaming using audiobookshelf and a self-hosted RSS reader using tt-rss.
Preliminaries
Just some notes before we start with the different service configurtions:
- based upon my basic homeserver setup.
- the nginx configuration file is
/etc/nginx/sites-enabled/default
- all services will be placed behind a reverse proxy (nginx) and will be accessed through
https://meltingpot.social/<servicename>
- docker compose is used to run the services. We will make sure that docker services are only exposed through the nginx reverse-proxy and not directly to the network
- I use
/media/data/container/<container-name>
for container-data.
- Within my homedirectory (
/home/andy/
), I create a simple directory per service, copy the docker-compose.yaml
file into it and then start it through docker compose up
in a tmux
session
- I start everything with tmux and detaching from tmux (
ctrl-b d
) after I manually mount the encrypted data harddrive.
- Typically, you will have do to some sort of configuration when you first access the container’s website. If I remember something “special” was needed during setup, I will note this here.
And now for the services..
Audiobook-Server for my Humble Audio-Bundles
I got a couple of audiobooks from humblebundle over time. Initially I just copied them on my android phone and used vlc
for playing them. There were some problems: I wanted some sort of sleep-timer, in addition I ran in to problems with audiobooks that were split up into multiple parts.
The solution was to user audiobookshelf. It is a self-hosted audiobook server that allows you to stream your audiobooks to your devices. It has a nice web interface and works well with the android app. This allows for a sleeping timer, resuming playback, and even offline use within the android app.
I only store audiobooks on the data drive, as I don’t use podcasts (yet).
I am using the following docker-compose.yaml
file:
1
2
3
4
5
6
7
8
9
10
11
12
|
services:
audiobookshelf:
image: ghcr.io/advplyr/audiobookshelf:latest
ports:
- 127.0.0.1:13378:80
volumes:
- /media/data/media/audiobooks:/audiobooks
- /media/data/containers/audiobookshelf/podcasts:/podcasts
- /media/data/containers/audiobookshelf/config:/config
- /media/data/containers/audiobookshelf/metadata:/metadata
environment:
- TZ=Europe/Vienna
|
To put audiobookshelf
behind the nginx reverse proxy, I add the following to the nginx configuration (in /etc/nginx/sites-enabled/default
):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
server {
# other stuff..
location /audiobookshelf {
proxy_pass http://127.0.0.1:13378/audiobookshelf;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_redirect http:// https://;
#proxy_set_header X-Real-IP $remote_addr;
}
# other stuff ..
}
|
Git-Server for Obsidian Sync (gitea)
I am using obisidan for my notes. To sync notes between devices I am using the git plugin. Before having the home-server, I was using a private github repository as git backend, but now that I have a local server it made sense to move the repository to my home server. I am using gitea for this as it is a lightweight and easy-to-use solution for hosting your own git repositories.
This is the docker-compose.yaml
file I am using:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
version: "3"
services:
server:
image: gitea/gitea:latest
container_name: gitea
restart: always
environment:
- USER_UID=1000
- USER_GID=1000
volumes:
- /media/data/containers/gitea/data:/data
- /media/data/containers/gitea/custom:/app/gitea/custom
- /media/data/containers/gitea/log:/app/gitea/log
ports:
- "127.0.0.1:3000:3000"
- "2222:22"
|
After the intial start, a new configuration file is created at /media/data/containers/gitea/data/gitea/conf/app.ini
. You can edit this file to change the configuration of gitea. The most important settings changes are:
1
2
3
4
5
6
7
8
|
[server]
...
ROOT_URL = https://meltingpot.social/gitea
...
SSH_PORT = 2222
DOMAIN = meltingpot.social
SSH_DOMAIN = meltingpot.social
...
|
This changes make sure that the git clone
URLs displayed within gitea are actually working.
Finally, we also have to add the following to the nginx configuration (in /etc/nginx/sites-enabled/default
):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
server {
# other configuraiton..
location ~ ^/(gitea|v2)($|/) {
client_max_body_size 512M;
# make nginx use unescaped URI, keep "%2F" as-is, remove the "/gitea" sub-path prefix, pass "/v2" as-is.
rewrite ^ $request_uri;
rewrite ^/(gitea($|/))?(.*) /$3 break;
proxy_pass http://127.0.0.1:3000$uri;
# other common HTTP headers, see the "Nginx" config section above
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# other configuration..
}
|
TT-RSS for news aggregation and processing
The final part for this blog post will be tt-rss. It is a self-hosted RSS reader that allows you to read and manage your RSS feeds. It has a nice web interface and works well with the android app. I am using it to filter and read my RSS feeds from various sources.
In addition, I am installing the ironfeed
plugin. This plugin can be used to grab full news items (instead of only having the summary typically included in the RSS feed), remove ads, and combine multi-page posts into a single news item.
Configuration is a bit more involved than the other two services. Create the service directory, e.g. /home/andy/tt-rss
and copy the following .env
file as well as the docker-compose.yaml
file into it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# Put any local modifications here.
# Run FPM under this UID/GID.
# OWNER_UID=1000
# OWNER_GID=1000
# FPM settings.
#PHP_WORKER_MAX_CHILDREN=5
#PHP_WORKER_MEMORY_LIMIT=256M
# ADMIN_USER_* settings are applied on every startup.
# Set admin user password to this value. If not set, random password
# will be generated on startup, look for it in the 'app' container logs.
#ADMIN_USER_PASS=
# Sets admin user access level to this value. Valid values:
# -2 - forbidden to login
# -1 - readonly
# 0 - default user
# 10 - admin
#ADMIN_USER_ACCESS_LEVEL=
# Auto create another user (in addition to built-in admin) unless it already exists.
#AUTO_CREATE_USER=
#AUTO_CREATE_USER_PASS=
#AUTO_CREATE_USER_ACCESS_LEVEL=0
# Default database credentials.
TTRSS_DB_USER=postgres
TTRSS_DB_NAME=postgres
TTRSS_DB_PASS=password
# You can customize other config.php defines by setting overrides here.
# See tt-rss/.docker/app/Dockerfile for a complete list.
# You probably shouldn't disable auth_internal unless you know what you're doing.
TTRSS_PLUGINS=auth_internal,auth_remote
# TTRSS_SINGLE_USER_MODE=true
# TTRSS_SESSION_COOKIE_LIFETIME=2592000
# TTRSS_FORCE_ARTICLE_PURGE=30
# ...
# Bind exposed port to 127.0.0.1 to run behind reverse proxy on the same host.
# If you plan to expose the container, remove "127.0.0.1:".
HTTP_PORT=8280
#HTTP_PORT=8280
|
In the docker-compose.yaml
file, we are using the environmental configuration from the .env
file. We also make sure that tt-rss is not exposed to the network, but only to the nginx reverse proxy and enable periodic backups:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
version: '3'
services:
# see FAQ entry below if upgrading from a different PostgreSQL major version (e.g. 12 to 15):
# https://tt-rss.org/wiki/InstallationNotes/#i-got-the-updated-compose-file-above-and-now-my-database-keeps-restarting
db:
image: postgres:15-alpine
restart: unless-stopped
env_file:
- .env
environment:
- POSTGRES_USER=${TTRSS_DB_USER}
- POSTGRES_PASSWORD=${TTRSS_DB_PASS}
- POSTGRES_DB=${TTRSS_DB_NAME}
volumes:
- /media/data/containers/tt-rss/db:/var/lib/postgresql/data
app:
image: cthulhoo/ttrss-fpm-pgsql-static:latest
restart: unless-stopped
env_file:
- .env
volumes:
- /media/data/containers/tt-rss/app:/var/www/html
- /media/data/containers/tt-rss/config.d:/opt/tt-rss/config.d:ro
depends_on:
- db
# optional, makes weekly backups of your install
backups:
image: cthulhoo/ttrss-fpm-pgsql-static:latest
restart: unless-stopped
env_file:
- .env
volumes:
- /media/data/containers/tt-rss/backups:/backups
- /media/data/containers/tt-rss/app:/var/www/html
depends_on:
- db
command: /opt/tt-rss/dcron.sh -f
updater:
image: cthulhoo/ttrss-fpm-pgsql-static:latest
restart: unless-stopped
env_file:
- .env
volumes:
- /media/data/containers/tt-rss/app:/var/www/html
- /media/data/containers/tt-rss/config.d:/opt/tt-rss/config.d:ro
depends_on:
- app
command: /opt/tt-rss/updater.sh
web-nginx:
image: cthulhoo/ttrss-web-nginx:latest
restart: unless-stopped
env_file:
- .env
ports:
- 127.0.0.1:${HTTP_PORT}:80
volumes:
- /media/data/containers/tt-rss/app:/var/www/html:ro
depends_on:
- app
|
Stanza for nginx:
1
2
3
4
5
6
7
|
location /tt-rss {
proxy_pass http://127.0.0.1:8280/tt-rss;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
|
Start this using docker compose up
and then go to https://meltingpot.social/tt-rss
to finish the setup. Check the output of docker compose
for the randomly generated password for the admin
user.
For setup of feediron
we need to install the plugin. This is done by cloning the repository into the plugins.local
directory of tt-rss:
1
2
|
$ /media/data/containers/tt-rss/app/tt-rss
$ git clone https://github.com/feediron/ttrss_plugin-feediron.git plugins.local/feediron
|
and enable it in the admin
-> configuration
-> plugins
section