commit b290df130431316e608bb95f411d988d02d3cfad
Author: Anton Shubin <2spy4x@gmail.com>
Date: Sun Jan 21 00:22:19 2024 +0800
feat: add Traefik, Uptime Kuma, Transmission, Jellyfin, Gitea, Home Assistant, and a simple homepage
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..96fcf80
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,12 @@
+CONTACT_EMAIL=your@email.com
+SSH_TO_SERVER=user@server
+PATH_APPS=~/apps
+PATH_MOVIES=~/movies
+HOSTNAME_UPTIME_KUMA=uptime.example.com
+HOSTNAME_TORRENTS=torrents.example.com
+HOSTNAME_MOVIES=movies.example.com
+HOSTNAME_GITEA=git.example.com
+HOSTNAME_HOME_ASSISTANT=smart.example.com
+HOSTNAME_HOMEPAGE=ui.example.com
+HOSTNAME_SAGE=sage.example.com
+HOSTNAME_AQS=example.com
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a726ff1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.volumes
+.env
+dist
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/homelab.iml b/.idea/homelab.iml
new file mode 100644
index 0000000..24643cc
--- /dev/null
+++ b/.idea/homelab.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..c5ebe51
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5873f77
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+-include .env
+export $(shell sed 's/=.*//' .env)
+
+# Replace env variables in index.html
+build-homepage:
+ mkdir -p ./homepage/dist
+ envsubst < ./homepage/src/index.html > ./homepage/dist/index.html
+
+deploy:
+ make build-homepage
+ rsync -avz -e 'ssh' --include-from='deploy.files.txt' --exclude '*' ./ $(SSH_TO_SERVER):$(PATH_APPS)
+ ssh homelab "cd $(PATH_APPS) && docker compose up -d"
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c87e3a5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,50 @@
+# Homelab server
+
+This is a collection of services I run on my homelab server.
+It's pretty lightweight (you need at least 2GB RAM) and easy to setup.
+All you need is a linux server with [Docker](https://get.docker.com/) installed.
+Make sure you followed instructions after installation to configure to run Docker as a non-root user.
+
+## Services
+
+### [Traefik](https://github.com/traefik/traefik)
+A reverse proxy that is used to route incoming requests to the correct container by domain name and not by port.
+It's configured to use Let's Encrypt to automatically generate SSL certificates and redirect all HTTP requests to HTTPS.
+Ex: https://movies.example.com -> jellyfin container:8096
+Ex: https://gitea.example.com -> gitea container:3000
+
+### [Uptime Kuma](https://github.com/louislam/uptime-kuma)
+Uptime Kuma is a monitoring tool, that checks the status of your websites and APIs.
+
+### [Transmission](https://github.com/transmission/transmission)
+Transmission is a BitTorrent client with a web interface.
+It is a lightweight, works on the server in background and has zero configuration.
+
+### [Jellyfin](https://github.com/jellyfin/jellyfin)
+Jellyfin is a media server for hosting and managing personal media libraries.
+Think of movies, TV shows, home videos, music, and pictures.
+
+### [Gitea](https://github.com/go-gitea/gitea)
+Gitea is a lightweight self-hosted Git service, similar to GitHub.
+
+### [Home Assistant](https://github.com/home-assistant/home-assistant.io)
+Home Assistant is an open-source home automation platform.
+For your smart home, it is the software "hub" that allows you to control all your devices.
+
+### [Homepage](./homepage/src/index.html)
+A simple homepage with links to all the services.
+
+## Setup
+To start you need to create .env file by copying .env.example:
+```bash
+cp .env.example .env
+```
+and filling in the variables.
+
+Then you can deploy the stack to your server:
+```bash
+make deploy
+```
+
+That's it! You can now access the services by going to the domain names you specified in the .env file.
+If you want to add more services, just add them to the `compose.yml` file and run `make deploy` again.
diff --git a/compose.yml b/compose.yml
new file mode 100644
index 0000000..4ded5cd
--- /dev/null
+++ b/compose.yml
@@ -0,0 +1,228 @@
+version: '3.8'
+services:
+
+ # Traefik is a reverse proxy and load balancer.
+ # It is used to route incoming requests to the correct container by domain name and not by port.
+ # Ex: https://movies.example.com -> jellyfin container:8096
+ # Ex: https://gitea.example.com -> gitea container:3000
+ # It's configured to use Let's Encrypt to automatically generate SSL certificates and redirect all HTTP requests to HTTPS.
+ traefik:
+ container_name: "traefik"
+ image: "traefik"
+ restart: unless-stopped
+ command:
+# - "--log.level=DEBUG"
+ - "--api.insecure=true"
+ - "--providers.docker=true"
+ - "--providers.docker.exposedbydefault=false"
+ - "--entrypoints.websecure.address=:443"
+ - "--entrypoints.web.address=:80"
+ - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
+ - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
+ - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
+ - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
+ # - "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
+ - "--certificatesresolvers.myresolver.acme.email=${CONTACT_EMAIL}"
+ - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
+ ports:
+ - "443:443"
+ - "80:80"
+# - "8080:8080"
+ volumes:
+ - "./letsencrypt:/letsencrypt"
+ - "/var/run/docker.sock:/var/run/docker.sock:ro"
+ deploy:
+ resources:
+ limits:
+ cpus: '0.5'
+ memory: 512M
+
+ # Uptime Kuma is a monitoring tool, that checks the status of your websites and APIs.
+ uptime-kuma:
+ container_name: uptime-kuma
+ image: louislam/uptime-kuma
+ volumes:
+ - ./.volumes/uptime-kuma:/app/data
+ restart: unless-stopped
+ healthcheck:
+ test: [ "CMD", "curl", "-f", "${HOSTNAME_UPTIME_KUMA}" ]
+ interval: 1m
+ timeout: 10s
+ retries: 3
+ start_period: 40s
+ deploy:
+ resources:
+ limits:
+ memory: 256M
+ cpus: '0.25'
+ security_opt:
+ - no-new-privileges:true
+ labels:
+ - "traefik.enable=true"
+ - "traefik.http.routers.uptime-kuma.rule=Host(`${HOSTNAME_UPTIME_KUMA}`)"
+ - "traefik.http.routers.uptime-kuma.entrypoints=websecure"
+ - "traefik.http.routers.uptime-kuma.tls=true"
+ - "traefik.http.routers.uptime-kuma.tls.certresolver=myresolver"
+ - "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001"
+
+ # Transmission is a BitTorrent client with a web interface.
+ # It is a lightweight, works on the server in background and has zero configuration.
+ transmission:
+ image: linuxserver/transmission
+ container_name: transmission
+ environment:
+ - PUID=1000
+ - PGID=1000
+ - TZ=Asia/Singapore
+ volumes:
+ - ./.volumes/transmission:/config
+ - ${PATH_MOVIES}:/downloads
+ ports:
+ - 51413:51413 # Default port for torrent traffic
+ - 51413:51413/udp # Default port for DHT
+ restart: unless-stopped
+ healthcheck:
+ test: [ "CMD", "curl", "-f", "${HOSTNAME_TORRENTS}" ]
+ interval: 1m
+ timeout: 10s
+ retries: 3
+ start_period: 40s
+ deploy:
+ resources:
+ limits:
+ memory: 256M
+ cpus: '0.25'
+ security_opt:
+ - no-new-privileges:true
+ labels:
+ - "traefik.enable=true"
+ - "traefik.http.routers.transmission.rule=Host(`${HOSTNAME_TORRENTS}`)"
+ - "traefik.http.routers.transmission.entrypoints=websecure"
+ - "traefik.http.routers.transmission.tls=true"
+ - "traefik.http.routers.transmission.tls.certresolver=myresolver"
+ - "traefik.http.services.transmission.loadbalancer.server.port=9091"
+
+ # Jellyfin is a media server for hosting and managing personal media libraries.
+ # Think of movies, TV shows, home videos, music, and pictures.
+ jellyfin:
+ container_name: jellyfin
+ image: jellyfin/jellyfin
+ volumes:
+ - ./.volumes/jellyfin:/config
+ - ./.volumes/jellyfin/cache:/cache
+ - ${PATH_MOVIES}:/media
+ restart: unless-stopped
+ healthcheck:
+ test: [ "CMD", "curl", "-f", "${HOSTNAME_MOVIES}" ]
+ interval: 1m
+ timeout: 10s
+ retries: 3
+ start_period: 40s
+ deploy:
+ resources:
+ limits:
+ memory: 2048M
+ cpus: '2'
+ security_opt:
+ - no-new-privileges:true
+ labels:
+ - "traefik.enable=true"
+ - "traefik.http.routers.jellyfin.rule=Host(`${HOSTNAME_MOVIES}`)"
+ - "traefik.http.routers.jellyfin.entrypoints=websecure"
+ - "traefik.http.routers.jellyfin.tls=true"
+ - "traefik.http.routers.jellyfin.tls.certresolver=myresolver"
+ - "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
+
+ # Gitea is a lightweight self-hosted Git service.
+ gitea:
+ container_name: gitea
+ image: gitea/gitea:latest
+ ports:
+ - 222:22
+ volumes:
+ - ./.volumes/gitea:/data
+ - /etc/timezone:/etc/timezone:ro
+ - /etc/localtime:/etc/localtime:ro
+ environment:
+ - USER_UID=1000
+ - USER_GID=1000
+ restart: unless-stopped
+ healthcheck:
+ test: [ "CMD", "curl", "-f", "${HOSTNAME_GITEA}" ]
+ interval: 1m
+ timeout: 10s
+ retries: 3
+ start_period: 40s
+ deploy:
+ resources:
+ limits:
+ memory: 256M
+ cpus: '0.25'
+ security_opt:
+ - no-new-privileges:true
+ labels:
+ - "traefik.enable=true"
+ - "traefik.http.routers.gitea.rule=Host(`${HOSTNAME_GITEA}`)"
+ - "traefik.http.routers.gitea.entrypoints=websecure"
+ - "traefik.http.routers.gitea.tls=true"
+ - "traefik.http.routers.gitea.tls.certresolver=myresolver"
+ - "traefik.http.services.gitea.loadbalancer.server.port=3000"
+
+ # Home Assistant is an open-source home automation platform.
+ # For your smart home, it is the software "hub" that allows you to control all your devices.
+ home-assistant:
+ container_name: home-assistant
+ image: homeassistant/home-assistant:stable
+ volumes:
+ - ./.volumes/home-assistant:/config
+ environment:
+ - TZ=Asia/Singapore
+ restart: unless-stopped
+ healthcheck:
+ test: [ "CMD", "curl", "-f", "${HOSTNAME_HOME_ASSISTANT}" ]
+ interval: 1m
+ timeout: 10s
+ retries: 3
+ start_period: 40s
+ deploy:
+ resources:
+ limits:
+ memory: 512M
+ cpus: '0.25'
+ security_opt:
+ - no-new-privileges:true
+ labels:
+ - "traefik.enable=true"
+ - "traefik.http.routers.home-assistant.rule=Host(`${HOSTNAME_HOME_ASSISTANT}`)"
+ - "traefik.http.routers.home-assistant.entrypoints=websecure"
+ - "traefik.http.routers.home-assistant.tls=true"
+ - "traefik.http.routers.home-assistant.tls.certresolver=myresolver"
+ - "traefik.http.services.home-assistant.loadbalancer.server.port=8123"
+
+ # A simple HTML page to display links to all the services.
+ homepage:
+ container_name: homepage
+ image: nginx:alpine
+ volumes:
+ - ./homepage/dist:/usr/share/nginx/html:ro
+ restart: unless-stopped
+ healthcheck:
+ test: [ "CMD", "curl", "-f", "${HOSTNAME_HOMEPAGE}" ]
+ interval: 1m
+ timeout: 10s
+ retries: 3
+ start_period: 40s
+ deploy:
+ resources:
+ limits:
+ memory: 128M
+ cpus: '0.10'
+ security_opt:
+ - no-new-privileges:true
+ labels:
+ - "traefik.enable=true"
+ - "traefik.http.routers.homepage.rule=Host(`${HOSTNAME_HOMEPAGE}`)"
+ - "traefik.http.routers.homepage.entrypoints=websecure"
+ - "traefik.http.routers.homepage.tls=true"
+ - "traefik.http.routers.homepage.tls.certresolver=myresolver"
+ - "traefik.http.services.homepage.loadbalancer.server.port=80"
\ No newline at end of file
diff --git a/configs/smb.conf b/configs/smb.conf
new file mode 100755
index 0000000..03e5b41
--- /dev/null
+++ b/configs/smb.conf
@@ -0,0 +1,158 @@
+# This is the main Samba configuration file. You should read the
+# smb.conf(5) manual page in order to understand the options listed
+# here. Samba has a huge number of configurable options (perhaps too
+# many!) most of which are not shown in this example
+#
+# For a step to step guide on installing, configuring and using samba,
+# read the Samba-HOWTO-Collection. This may be obtained from:
+# http://www.samba.org/samba/docs/Samba-HOWTO-Collection.pdf
+#
+# Many working examples of smb.conf files can be found in the
+# Samba-Guide which is generated daily and can be downloaded from:
+# http://www.samba.org/samba/docs/Samba-Guide.pdf
+#
+# Any line which starts with a ; (semi-colon) or a # (hash)
+# is a comment and is ignored. In this example we will use a #
+# for commentry and a ; for parts of the config file that you
+# may wish to enable
+#
+# NOTE: Whenever you modify this file you should run the command "testparm"
+# to check that you have not made any basic syntactic errors.
+#
+#======================= Global Settings =====================================
+[global]
+
+# workgroup = NT-Domain-Name or Workgroup-Name, eg: MIDEARTH
+ workgroup = WORKGROUP
+
+# server string is the equivalent of the NT Description field
+ server string = Samba Server
+
+# Server role. Defines in which mode Samba will operate. Possible
+# values are "standalone server", "member server", "classic primary
+# domain controller", "classic backup domain controller", "active
+# directory domain controller".
+#
+# Most people will want "standalone server" or "member server".
+# Running as "active directory domain controller" will require first
+# running "samba-tool domain provision" to wipe databases and create a
+# new domain.
+ server role = standalone server
+
+# This option is important for security. It allows you to restrict
+# connections to machines which are on your local network. The
+# following example restricts access to two C class networks and
+# the "loopback" interface. For more examples of the syntax see
+# the smb.conf man page
+; hosts allow = 192.168.1. 192.168.2. 127.
+
+# Uncomment this if you want a guest account, you must add this to /etc/passwd
+# otherwise the user "nobody" is used
+; guest account = pcguest
+
+# this tells Samba to use a separate log file for each machine
+# that connects
+ log file = /dev/stdout
+
+# Put a capping on the size of the log files (in Kb).
+ max log size = 50
+
+# Specifies the Kerberos or Active Directory realm the host is part of
+; realm = MY_REALM
+
+# Backend to store user information in. New installations should
+# use either tdbsam or ldapsam. smbpasswd is available for backwards
+# compatibility. tdbsam requires no further configuration.
+; passdb backend = tdbsam
+
+# Using the following line enables you to customise your configuration
+# on a per machine basis. The %m gets replaced with the netbios name
+# of the machine that is connecting.
+# Note: Consider carefully the location in the configuration file of
+# this line. The included file is read at that point.
+; include = /usr/local/samba/lib/smb.conf.%m
+
+# Configure Samba to use multiple interfaces
+# If you have multiple network interfaces then you must list them
+# here. See the man page for details.
+; interfaces = 192.168.12.2/24 192.168.13.2/24
+
+# Where to store roving profiles (only for Win95 and WinNT)
+# %L substitutes for this servers netbios name, %U is username
+# You must uncomment the [Profiles] share below
+; logon path = \\%L\Profiles\%U
+
+# Windows Internet Name Serving Support Section:
+# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
+; wins support = yes
+
+# WINS Server - Tells the NMBD components of Samba to be a WINS Client
+# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
+; wins server = w.x.y.z
+
+# WINS Proxy - Tells Samba to answer name resolution queries on
+# behalf of a non WINS capable client, for this to work there must be
+# at least one WINS Server on the network. The default is NO.
+; wins proxy = yes
+
+# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
+# via DNS nslookups. The default is NO.
+ dns proxy = no
+
+# These scripts are used on a domain controller or stand-alone
+# machine to add or delete corresponding unix accounts
+; add user script = /usr/sbin/useradd %u
+; add group script = /usr/sbin/groupadd %g
+; add machine script = /usr/sbin/adduser -n -g machines -c Machine -d /dev/null -s /bin/false %u
+; delete user script = /usr/sbin/userdel %u
+; delete user from group script = /usr/sbin/deluser %u %g
+; delete group script = /usr/sbin/groupdel %g
+
+
+ pam password change = yes
+ map to guest = bad user
+ usershare allow guests = yes
+ create mask = 0664
+ force create mode = 0664
+ directory mask = 0775
+ force directory mode = 0775
+ force user = smbuser
+ force group = smb
+ follow symlinks = yes
+ load printers = no
+ printing = bsd
+ printcap name = /dev/null
+ disable spoolss = yes
+ strict locking = no
+ aio read size = 0
+ aio write size = 0
+ vfs objects = catia fruit streams_xattr
+
+ # Security
+ client ipc max protocol = SMB3
+ client ipc min protocol = SMB2_10
+ client max protocol = SMB3
+ client min protocol = SMB2_10
+ server max protocol = SMB3
+ server min protocol = SMB2_10
+
+ # Time Machine
+ fruit:delete_empty_adfiles = yes
+ fruit:time machine = yes
+ fruit:veto_appledouble = no
+ fruit:wipe_intentionally_left_blank_rfork = yes
+
+ # macOS support for write
+ fruit:metadata = stream
+ fruit:model = MacSamba
+ fruit:posix_rename = yes
+ fruit:nfs_aces = no
+
+[media]
+ path = /home/pi/media
+ browsable = yes
+ read only = no
+ guest ok = no
+ veto files = /.apdisk/.DS_Store/.TemporaryItems/.Trashes/desktop.ini/ehthumbs.db/Network Trash Folder/Temporary Items/Thumbs.db/
+ delete veto files = yes
+
diff --git a/deploy.files.txt b/deploy.files.txt
new file mode 100644
index 0000000..0820acc
--- /dev/null
+++ b/deploy.files.txt
@@ -0,0 +1,3 @@
+compose.yml
+homepage/dist/***
+.env
\ No newline at end of file
diff --git a/homepage/src/index.html b/homepage/src/index.html
new file mode 100644
index 0000000..029cb94
--- /dev/null
+++ b/homepage/src/index.html
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+ Home
+
+
+
+
+Homelab
+
+
+
+
+
\ No newline at end of file