This repository contains the Docker configurations and installation scripts that power my personal homelab server. I've decided to share my setup publicly in case others find it useful for their own homelab projects.
My current homelab runs on:
- Mac Mini M4
- CPU: Apple M4 chipset
- RAM: 32GB
- Storage: 2TB custom Chinese NVMe replaced the internal 256GB SSD. Video
The entire setup is compact, energy-efficient, and powerful enough to run all my services simultaneously without breaking a sweat. All while being silent and having a small size footprint.
Here's what's currently running in my homelab:
Service | Description | Port | URL |
---|---|---|---|
Homepage | Main dashboard for all services | 3000 | http://localhost:3000 |
Portainer | Docker container management | 9000 | http://localhost:9000 |
Cloudflare Tunnel | Secure remote access | N/A | Various subdomains |
Tailscale | VPN for secure remote access | N/A | Via Tailscale client |
Glances | System monitoring | 61208 | http://localhost:61208 |
Transmission | Torrent client | 9091 | http://localhost:9091 |
Plex | Media server | Host networking | http://localhost:32400/web |
Excalidraw | Collaborative drawing tool | 3030 | http://localhost:3030 |
Ollama + OpenWebUI | Self-hosted AI/LLM service | 8083 | http://localhost:8083 |
Speedtest Tracker | Internet speed monitoring | 8081 | http://localhost:8081 |
- macOS system (the script uses Homebrew for dependencies)
- Internet connection
- If you want to replicate my exact setup: a Mac with Apple Silicon
-
Clone this repository:
git clone https://github.com/jiwidi/homelab-server.git cd homelab-server
-
Run the master installation script:
./master_install.sh
-
Follow the interactive prompts to configure your environment.
This is the main orchestration script that:
- Checks and installs dependencies (Homebrew, Docker, tmux)
- Manages configuration through a
.env
file - Sets up all services by iterating through each directory and running individual installation scripts
The script is designed to be idempotent - you can run it multiple times without issues. It will only install dependencies if they're missing and will respect existing configurations.
Each service directory contains:
docker-compose.yaml
- Container configurationinstall.sh
- Service-specific installation script
These modular scripts allow for easier maintenance and give you the flexibility to add or remove services.
I use a .env
file for all sensitive configuration to avoid hardcoding secrets in the repository. The master install script will create this file if it doesn't exist, prompting you for values or generating secure defaults.
Key variables include:
Variable | Purpose | Default |
---|---|---|
CLOUDFLARE_TUNNEL_TOKEN |
Token for Cloudflare Tunnel | (user provided) |
HOMEPAGE_AUTH_TOKEN |
Homepage dashboard auth token | (randomly generated) |
SPEEDTEST_APP_KEY |
Speedtest app auth key | (randomly generated) |
PLEX_CLAIM |
Plex claim token | (user provided) |
TAILSCALE_AUTH_KEY |
Tailscale authentication key | (user provided) |
A .env.example
file is included as a reference.
Security was a priority when designing this setup:
- No hardcoded secrets - All sensitive information lives in the
.env
file (excluded from git) - Minimal permissions - Docker containers run with the minimum required access
- Safe Docker socket access - Socket is exposed securely to prevent unauthorized container access
- Automatic secret generation - The script can generate secure random tokens for services
- VPN Access - Tailscale provides secure access without exposing services directly to the internet
homelab-server/
βββ .env # Your environment variables (not committed)
βββ .env.example # Example environment variables
βββ .gitignore # Git ignore file (includes .env)
βββ LICENSE # MIT License
βββ README.md # This file
βββ master_install.sh # Main installation script
β
βββ cloudfare/ # Cloudflare tunnel configuration
β βββ docker-compose.yaml
β βββ install.sh
β
βββ excalidraw/ # Excalidraw drawing tool
β βββ docker-compose.yaml
β βββ install.sh
β
βββ homepage/ # Homepage dashboard
β βββ docker-compose.yaml
β βββ install.sh
β
βββ ollama_openwbui/ # Ollama and OpenWebUI
β βββ docker-compose.yaml
β βββ install.sh
β
βββ plex/ # Plex media server
β βββ docker-compose.yaml
β βββ install.sh
β
βββ portainer/ # Portainer container management
β βββ docker-compose.yaml
β βββ install.sh
β
βββ transmission/ # Transmission torrent client
β βββ docker-compose.yaml
β βββ install.sh
β
βββ tailscale/ # Tailscale VPN for remote access
βββ docker-compose.yaml
βββ install.sh
βββ README.md # Tailscale-specific documentation
One of the key design principles of this setup is easy expandability:
- Create a new directory for your service
- Add a
docker-compose.yaml
file - Create an
install.sh
script (see existing ones as examples) - Update the main
.env
file if your service needs additional environment variables
Example install.sh
template:
#!/bin/bash
set -e
DIR="$(cd "$(dirname "$0")" && pwd)"
docker-compose -f "$DIR/docker-compose.yaml" up -d
I've made several customizations for my specific needs:
- Media Management: Plex is configured to use my
~/Videos
directory for media - Swedish Timezone: Services are configured for Europe/Stockholm timezone
- Cloudflare Tunnels: Set up for my domain (jiwidi.com) and subdomains
Feel free to adjust these settings in the docker-compose files to match your requirements.
I provide two options for remote access to my homelab:
For public-facing services, I use Cloudflare Tunnels on the free tier. This allows me to expose specific services through a secure tunnel without opening ports on my router.
To use this feature with your own domain:
- Create a Cloudflare account
- Set up a tunnel for your domain
- Update the
CLOUDFLARE_TUNNEL_TOKEN
in your.env
file
For more secure, private access to all services, I use Tailscale. This mesh VPN allows me to connect to my homelab from anywhere without exposing services directly to the internet.
Key features:
- Zero configuration networking - no port forwarding needed
- End-to-end encryption for all traffic
- Access control through Tailscale's admin console
- Exit node capability - route all your internet traffic through your home connection when on public WiFi
Setup:
- Create a Tailscale account at https://tailscale.com/
- Generate an auth key in the admin console
- Add the key to your
.env
file asTAILSCALE_AUTH_KEY
- Run the installation script
Once set up, you can connect to your homelab services using the Tailscale IP address from any device with the Tailscale client installed.
This is an ongoing project, and I'm continually refining and adding services. Some things I'm considering for the future:
- Home automation integration
- NAS functionality with an external 4 NVMe drive enclosure
- Enhanced backup solutions
This project is licensed under the MIT License - see the LICENSE file for details.