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