I started building my homelab around 6 years ago when I bought my first Raspberry Pi. Originally, I wanted to use the Pi to host self-coded Discord bots, but I soon realized the endless possibilities of self-hosted software. I started out using Raspberry Pi OS Lite and later switched to Ubuntu Server 20.04, which I have been running ever since (now on 24.04). I also used my newly learned skills to host Minecraft servers for me and my friends, though on VPSs rather than locally. After this, I used a custom-built PC as my server for a very long time (as found in README_OLD.md). Recently, I switched to a pre-built NAS from UGREEN, as the energy costs of my server did not correlate with the power needed to run all my 24/7 homelab services.
I am currently running TrueNAS Scale. I have never used a NAS OS before and wanted to use the server switch as a possibility to make my life a little easier regarding managing my required services. I also wanted to use this opportunity to learn a bit more about permission management using ACLs. I am still going to manage my Docker services via the shell, not the GUI.
Prebuilt UGREEN DXP2800
CPU: Intel N100 (4 cores, 4 threads @ 3.4GHz)
RAM: 8GB DDR5 (single stick from Samsung)
Storage:
- Random 256GB Samsung M.2 SSD I found in an old desktop
Boot drive, also used for storing snapshots.
- 2× Lexar NS100 1TB SATA SSDs
Configured as a RAID-1 mirror for redundant data storage.
-
"truenas_admin" (locked) default user
Permissions: Full Admin -
"nico.admin" my admin user to configure everything
Permissions: Full Admin -
"nico" my user (non-admin) for share access
Permissions: SMB Access
Groups: files_access -
"guest" used to access the Public share
Permissions: SMB Access
- files_access (used to access my private file share)
To use the configuration files from this repository, I clone the repository to my server. For each container, I use /mnt/CrazyBigStorage/Container/ServiceName as the storage path.
All container data is stored on a mirrored and regularly backed-up drive
To clone the repo I first need to create a home folder for my admin as the root path is owned by root.
sudo mkdir -p /home/nico.admin
sudo chown nico.admin:nico.admin /home/nico.admin
sudo chmod 700 /home/nico.admin
In TrueNAS network settings:
- Interface: enp2s0
- IP: 192.168.1.250/24
- Autoconfigure IPv6 disabled (I am not going to use IPv6 in my private network anytime soon)
- DNS server: 192.168.1.1 (my router's DNS server)
- Default gateway: 192.168.1.1
In TrueNAS general settings:
- Web interface port: HTTP 80 -> 8080, HTTPS 443 -> 4443 (Nginx uses these ports)
! Websocket support is required to be enabled in the nginx proxy manager entry or else accessing true nas ui via domain results in infinite loading loop.
My reverse proxy is the highest-level container in my homelab. It should be the only one that has exposed ports on the host, so I create its own network.
docker network create r_proxy
I can add networks to my docker-compose.yml files by adding the following structure:
services:
name:
...
networks:
- r_proxy
networks:
r_proxy:
external: trueBecause of this network, Nginx can access every service via its container name.
Nginx is the only service with exposed host ports:
services:
nginx:
ports:
- "80:80"
- "443:443"Every other service shall only use container-internal ports:
services:
name:
expose:
- "3306"Every service which requires sub-services like databases also receives its own internal network to communicate only with the sub-service.
For example:
services:
immich:
networks:
- r_proxy
- immich_internal
database:
networks:
- immich_internalI use Cloudflare to configure my local domains. In the past, I used it as a reverse proxy for WireGuard, but in this installation, I will be switching from WireGuard to Tailscale.
- I create a new access token:
- Edit Zone-DNS Template
- Permissions: Zone, DNS, Edit
- Zone resources: Include, Specific Zone, nicoshl.de
- I then save my token as a password-protected note in Bitwarden
I configured the name servers of my domain to point to Cloudflare so that I can manage my domain through Cloudflare.
- DNS Entries:
Name: nicoshl.de Type: A Record Content: 192.168.1.250Name: * Type: CNAME Record Content: @(@ = nicoshl.de, so *.nicoshl.de)Name: gateway Type: A Record Content: 192.168.1.251
Nginx Proxy Manager listens to the host ports: 80 (host) -> 80 (local, tcp) : http 81 (host) -> 81 (local, tcp) : web ui 443 (host) -> 443 (local, tcp) : https
-
To use Nginx Proxy Manager with https i need to set up my certificates via web ui: Certificates -> Add Certificate -> Lets Encrypt via DNS -> Domain Names: nicoshl.de & *.nicoshl.de -> Key Type: Default -> DNS Provider: Cloudflare using access token -> Propagation Seconds: 120s
Pool using 2 storage SSDs in a mirror (RAID-1): "CrazyBigStorage"
-
"Public" (SMB preset) a non-password-protected share used to send resources between my devices
Permissions: NFS4_Open preset -
"Files" (SMB preset) my private files which should only be accessible through my own (non-admin) account
Permissions: NFS4_Restricted preset
Groups: files_access (Full Control) -
"Container" (Apps preset) used for my Docker services
First I need to create a new bridge interface for the vm to be able to communicate with the host via ip. (For referenz look at Images/BridgeConfigs)
| Setting | Value |
|---|---|
| Name | Gateway |
| OS | Debian 13.7.0 |
| vCPUs | 1 |
| CPU Mode | Host passthrough |
| Display | VNC |
| RAM | 1 GB |
| Disk | 10 GB |
| Network | Bridged (Virtio) |
| Via VNC: | |
| Language | English |
| Region | Europe/Germany |
| Locales | US |
| Keymap | German |
| Hostname | gateway |
| Root | No password (Initial admin user will become root) |
| Initial user | nico, password: changeme (i will change this as soon as i can copy paste via ssh) |
| Disk | Use entire disk, all files in one partition |
| Software | standard system utilities, ssh server |
After the installation is complete, stop the VM and remove the CD-Rom device containing the boot medium.
Login with local user (admin) and change temp password
passwd
Next lets configure a static ip:
sudo nano /etc/network/interfaces
Paste content of VMs/Gateway/Configs/interfaces (I disabled auto ipv6 adresses because iam only going to use ipv4 adresses for my homelab)
Restart networking and pray:
sudo systemctl restart networking
If this worked restart the system, in my case to fully remove the old ip address.
Because my vm couldnt connect to the internet i had to manually change the cat /etc/resolv.conf file to VMs/Gateway/Configs/resolv.conf
Next we are going to setup shh keys for our admin user:
First lets generate a new key pair (On your pc) ssh-keygen -t ed25519 -C "nico@gateway" Enter(Default Location), Enter(No passphrase), Enter(No passphrase)
Next copy the public key from your pc cat .\id_ed25519.pub
On the server:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys paste key
chmod 600 ~/.ssh/authorized_keys
chown -R nico:nico ~/.ssh
Test the connection via keyfile (I had to convert the private key via puttygen to be able to use it with putty)
Disable password login:
sudo nano /etc/ssh/sshd_config
Paste content of VMs/Gateway/Configs/sshd_config
Restart ssh services sudo systemctl restart ssh
! QUICK SNAPSHOT !
ON GATEWAY VM
sudo apt install curl
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --ssh
tailscale status if server gets recognized:
Activate IP forwarding:
sudo nano /etc/sysctl.conf paste VMs/Gateway/Configs/systctl.conf
sudo sysctl -p
sudo tailscale up \
--advertise-routes=192.168.1.0/24 \
--ssh
Accept connection under gateway->subnets
https://github.com/overleaf/toolkit.git(To the storage location)(/home/nico.admin)
cd toolkit
sudo bash bin/init(/home ist in the noexec group and throws and error when running without bash arg)
sudo bash bin/up to start overleaf (The script uses docker compose)
- Email alerts
- Backups & Snapshots(Encrypt data while uploading to storage box)
- Setup PiHole and filters
- Setup dashboard (Homarr)
- Setup Actual budget manager
- Fix Overleaf
- VM: Gateway Firewall
If you have any questions about service configurations, errors you encountered during setup, or recommendations for this repo, feel free to reach out via the contacts on my https://github.com/Nico-Hei

