Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
356fdf206e | ||
|
|
a7c94ddc6c | ||
|
|
0a5ef19ef9 | ||
|
|
f394bf3b0e | ||
|
|
91ca20bd21 | ||
|
|
627e9ca241 | ||
|
|
0d2b5203ba | ||
|
|
57b8b41a17 | ||
|
|
467f3ce148 | ||
|
|
23f0f2cc46 |
@@ -1,44 +1,45 @@
|
|||||||
:4533 {
|
:raspberrypi-1.tail46eacb.ts.net {
|
||||||
# Code-Server (VS Code)
|
tls {
|
||||||
|
get_certificate tailscale
|
||||||
|
}
|
||||||
|
|
||||||
|
# VS Code
|
||||||
handle_path /edit* {
|
handle_path /edit* {
|
||||||
reverse_proxy code-server:8443
|
reverse_proxy 127.0.0.1:8443
|
||||||
}
|
|
||||||
handle_path /ntfy* {
|
|
||||||
reverse_proxy ntfy:80
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# qBittorrent (Stripping path to avoid 404)
|
# File Browser
|
||||||
handle_path /tr* {
|
handle_path /drive* {
|
||||||
reverse_proxy qbittorrent:8081
|
reverse_proxy 127.0.0.1:8082
|
||||||
}
|
}
|
||||||
|
|
||||||
# Navidrome
|
# Music
|
||||||
handle /music* {
|
handle /music* {
|
||||||
reverse_proxy navidrome:4533
|
reverse_proxy 127.0.0.1:4533
|
||||||
|
}
|
||||||
|
|
||||||
|
# Trilium Notes
|
||||||
|
handle_path /notes* {
|
||||||
|
reverse_proxy 127.0.0.1:8081
|
||||||
|
}
|
||||||
|
|
||||||
|
# qBittorrent
|
||||||
|
handle_path /tr* {
|
||||||
|
reverse_proxy 127.0.0.1:8085
|
||||||
|
}
|
||||||
|
|
||||||
|
# ntfy
|
||||||
|
handle_path /ntfy* {
|
||||||
|
reverse_proxy 127.0.0.1:8083
|
||||||
}
|
}
|
||||||
|
|
||||||
# Gitea
|
# Gitea
|
||||||
handle_path /git* {
|
handle_path /git* {
|
||||||
reverse_proxy gitea:3000
|
reverse_proxy 127.0.0.1:3001
|
||||||
}
|
}
|
||||||
|
|
||||||
# ROMM
|
# Homarr Dashboard (Root)
|
||||||
handle_path /roms* {
|
|
||||||
reverse_proxy romm:8080
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trilium
|
|
||||||
handle_path /notes* {
|
|
||||||
reverse_proxy trilium:8082
|
|
||||||
}
|
|
||||||
|
|
||||||
# Excalidraw
|
|
||||||
handle_path /draw* {
|
|
||||||
reverse_proxy excalidraw:80
|
|
||||||
}
|
|
||||||
|
|
||||||
# Homarr (root dashboard)
|
|
||||||
handle {
|
handle {
|
||||||
reverse_proxy homarr:7575
|
reverse_proxy 127.0.0.1:3000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
# Miles' Home Server Stack
|
||||||
|
|
||||||
|
This repository contains a fully automated, containerized home server stack. It uses Docker for containerization, Caddy for reverse proxying, and is optimized for access via Tailscale.
|
||||||
|
|
||||||
|
## Quick Start (New System)
|
||||||
|
|
||||||
|
If you are setting this up on a fresh install, follow these three steps:
|
||||||
|
|
||||||
|
1. **Prepare the Script**: Run `chmod +x setup.sh`
|
||||||
|
2. **Run the Setup**: Execute `./setup.sh` (This will install Docker if missing, create all required folders in `/home/miles/`, and set correct permissions.)
|
||||||
|
3. **Launch**: Choose "Option 1" from the script menu to pull the images and start the services.
|
||||||
|
|
||||||
|
## Service Map & Navigation
|
||||||
|
|
||||||
|
All services are accessible via: `http://raspberrypi.tail46eacb.ts.net:4533` (or your local IP)
|
||||||
|
|
||||||
|
| Service | Path | Function |
|
||||||
|
|--------------|---------|---------------------------|
|
||||||
|
| Homarr | / | Central Dashboard (Landing Page) |
|
||||||
|
| Code-Server | /edit | VS Code Web IDE |
|
||||||
|
| Gitea | /git | Private Git Server |
|
||||||
|
| Navidrome | /music | Music Streaming |
|
||||||
|
| RomM | /roms | Retro Game Manager |
|
||||||
|
| Trilium | /notes | Knowledge Base / Notes |
|
||||||
|
| Excalidraw | /draw | Digital Whiteboard |
|
||||||
|
| qBittorrent | /tr | Download Manager |
|
||||||
|
| ntfy | /ntfy | Push Notifications |
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
The `setup.sh` script automatically manages these paths:
|
||||||
|
|
||||||
|
- **Configs**: `/home/miles/code-config`, `/home/miles/qbittorrent-config`
|
||||||
|
- **Data**: `/home/miles/gitea-data`, `/home/miles/trilium-data`, `/home/miles/homarr-data`
|
||||||
|
- **Media**: `/home/miles/navidrome-music`, `/home/miles/roms`, `/home/miles/downloads`
|
||||||
|
|
||||||
|
## Maintenance via setup.sh
|
||||||
|
|
||||||
|
Run `./setup.sh` at any time to access the management menu:
|
||||||
|
|
||||||
|
- **Update Apps**: Option 4 pulls the latest versions and restarts.
|
||||||
|
- **Check Status**: Option 5 shows which containers are running.
|
||||||
|
- **Logs**: Option 3 is vital for debugging startup issues.
|
||||||
|
|
||||||
|
## Troubleshooting Guide
|
||||||
|
|
||||||
|
### [A] Permissions Issues
|
||||||
|
If a container won't start or says "Access Denied":
|
||||||
|
- Fix: `sudo chown -R 1000:1000 /home/miles/`
|
||||||
|
|
||||||
|
### [B] Caddy Routing Problems
|
||||||
|
If you see a "404" or "Blank Page" on a sub-path:
|
||||||
|
- Ensure container names in `Caddyfile` match `docker-compose.yml`.
|
||||||
|
- Run: `docker exec -it caddy caddy validate --config /etc/caddy/Caddyfile`
|
||||||
|
|
||||||
|
### [C] Database Locks
|
||||||
|
If an app hangs (Gitea/Trilium), it may have a database lock.
|
||||||
|
- Fix: `docker compose restart [service-name]`
|
||||||
|
|
||||||
|
### [D] Networking Conflicts
|
||||||
|
If port 4533 is in use, Caddy will fail.
|
||||||
|
- Check: `sudo netstat -tulpn | grep 4533`
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
- **Watchtower**: Runs in the background to auto-update apps.
|
||||||
|
- **Security**: Change the code-server password in `docker-compose.yml`.
|
||||||
|
- **Tailscale**: Must be "Connected" for the Gitea URL to work.
|
||||||
|
- **custom domans**: you can use custm domands but you need to use cloudefar tunnel with canday
|
||||||
+62
-78
@@ -1,44 +1,70 @@
|
|||||||
services:
|
services:
|
||||||
code-server:
|
|
||||||
image: lscr.io/linuxserver/code-server:latest
|
|
||||||
container_name: code-server
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- PUID=1000
|
|
||||||
- PGID=1000
|
|
||||||
- TZ=Etc/UTC
|
|
||||||
- PASSWORD=miles-code # Change this to your preferred login password
|
|
||||||
- DEFAULT_WORKSPACE=/config/workspace
|
|
||||||
volumes:
|
|
||||||
- /home/miles/code-config:/config
|
|
||||||
- /home/miles/projects:/config/workspace # This is where your HTML files will live
|
|
||||||
caddy:
|
caddy:
|
||||||
image: caddy:latest
|
image: caddy:latest
|
||||||
container_name: caddy
|
container_name: caddy
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
network_mode: host
|
||||||
- "4533:4533"
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||||
|
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
|
||||||
- caddy_data:/data
|
- caddy_data:/data
|
||||||
- caddy_config:/config
|
|
||||||
|
|
||||||
homarr:
|
homarr:
|
||||||
image: ghcr.io/homarr-labs/homarr:latest
|
image: ghcr.io/homarr-labs/homarr:latest
|
||||||
container_name: homarr
|
container_name: homarr
|
||||||
restart: always
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
environment:
|
environment:
|
||||||
- SECRET_ENCRYPTION_KEY=31ba05520db9d1dc463c66d81c3195db8c4b5010e97c352c11377877ef1a8d50
|
# This fixes the encryption error
|
||||||
|
- SECRET_ENCRYPTION_KEY=a90069963afd0d7fab70f044426f1c7a7f8ba322df8b4193cd975fd1f981462b
|
||||||
volumes:
|
volumes:
|
||||||
- /home/miles/homarr-data:/appdata
|
- /home/miles/homarr-data:/appdata
|
||||||
|
|
||||||
|
code-server:
|
||||||
|
image: lscr.io/linuxserver/code-server:latest
|
||||||
|
container_name: code-server
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "8443:8443"
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=Etc/UTC
|
||||||
|
- DEFAULT_WORKSPACE=/config/workspace
|
||||||
|
volumes:
|
||||||
|
- /home/miles/code-config:/config
|
||||||
|
|
||||||
|
watchtower:
|
||||||
|
image: containrrr/watchtower:latest
|
||||||
|
container_name: watchtower
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
command: --interval 86400 --cleanup
|
||||||
|
|
||||||
|
filebrowser:
|
||||||
|
image: filebrowser/filebrowser:latest
|
||||||
|
container_name: filebrowser
|
||||||
|
restart: always
|
||||||
|
user: "1000:1000"
|
||||||
|
ports:
|
||||||
|
- "8082:8082"
|
||||||
|
command: ["--port", "8082", "--baseurl", "/drive"]
|
||||||
|
volumes:
|
||||||
|
- /home/miles/files:/srv
|
||||||
|
- /home/miles/filebrowser.db:/database/filebrowser.db
|
||||||
|
- /home/miles/filebrowser-config:/config
|
||||||
|
|
||||||
navidrome:
|
navidrome:
|
||||||
image: deluan/navidrome:latest
|
image: deluan/navidrome:latest
|
||||||
container_name: navidrome
|
container_name: navidrome
|
||||||
restart: always
|
restart: always
|
||||||
|
user: "1000:1000"
|
||||||
|
ports:
|
||||||
|
- "4533:4533"
|
||||||
environment:
|
environment:
|
||||||
- ND_BASEURL=/music
|
- ND_BASEURL=/music
|
||||||
- ND_MUSICFOLDER=/music
|
|
||||||
volumes:
|
volumes:
|
||||||
- /home/miles/navidrome-data:/data
|
- /home/miles/navidrome-data:/data
|
||||||
- /home/miles/navidrome-music:/music
|
- /home/miles/navidrome-music:/music
|
||||||
@@ -47,54 +73,11 @@ code-server:
|
|||||||
image: triliumnext/notes:latest
|
image: triliumnext/notes:latest
|
||||||
container_name: trilium
|
container_name: trilium
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
ports:
|
||||||
- TRILIUM_BASE_URL=notes
|
- "8081:8080"
|
||||||
- TRILIUM_PORT=8082
|
|
||||||
volumes:
|
volumes:
|
||||||
- /home/miles/trilium-data:/home/node/trilium-data
|
- /home/miles/trilium-data:/home/node/trilium-data
|
||||||
|
|
||||||
gitea:
|
|
||||||
image: gitea/gitea:latest
|
|
||||||
container_name: gitea
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- GITEA__server__ROOT_URL=http://raspberrypi.tail46eacb.ts.net:4533/git/
|
|
||||||
- GITEA__server__APP_URL=http://raspberrypi.tail46eacb.ts.net:4533/git/
|
|
||||||
- GITEA__server__HTTP_PORT=3000
|
|
||||||
volumes:
|
|
||||||
- /home/miles/gitea-data:/data
|
|
||||||
|
|
||||||
romm:
|
|
||||||
image: rommapp/romm:latest
|
|
||||||
container_name: romm
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- ROMM_BASE_URL=/roms
|
|
||||||
- ROMM_PORT=8080
|
|
||||||
- REDIS_HOST=romm-redis
|
|
||||||
- REDIS_PORT=6379
|
|
||||||
depends_on:
|
|
||||||
- romm-redis
|
|
||||||
volumes:
|
|
||||||
- /home/miles/roms:/roms
|
|
||||||
- /home/miles/romm-data:/data
|
|
||||||
|
|
||||||
romm-redis:
|
|
||||||
image: redis:alpine
|
|
||||||
container_name: romm-redis
|
|
||||||
restart: always
|
|
||||||
|
|
||||||
ntfy:
|
|
||||||
image: binwiederhier/ntfy:latest
|
|
||||||
container_name: ntfy
|
|
||||||
restart: always
|
|
||||||
command: serve
|
|
||||||
environment:
|
|
||||||
- NTFY_BEHIND_PROXY=true
|
|
||||||
volumes:
|
|
||||||
- /home/miles/ntfy-cache:/var/cache/ntfy
|
|
||||||
- /home/miles/ntfy-config:/etc/ntfy
|
|
||||||
|
|
||||||
qbittorrent:
|
qbittorrent:
|
||||||
image: lscr.io/linuxserver/qbittorrent:latest
|
image: lscr.io/linuxserver/qbittorrent:latest
|
||||||
container_name: qbittorrent
|
container_name: qbittorrent
|
||||||
@@ -102,27 +85,28 @@ code-server:
|
|||||||
environment:
|
environment:
|
||||||
- PUID=1000
|
- PUID=1000
|
||||||
- PGID=1000
|
- PGID=1000
|
||||||
- TZ=Etc/UTC
|
ports:
|
||||||
- WEBUI_PORT=8081
|
- "8085:8081"
|
||||||
volumes:
|
volumes:
|
||||||
- /home/miles/qbittorrent-config:/config
|
- /home/miles/torrent-config:/config
|
||||||
- /home/miles/downloads:/downloads
|
- /home/miles/files/downloads:/downloads
|
||||||
|
|
||||||
excalidraw:
|
ntfy:
|
||||||
image: excalidraw/excalidraw:latest
|
image: binwiederhier/ntfy:latest
|
||||||
container_name: excalidraw
|
container_name: ntfy
|
||||||
restart: always
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "8083:80"
|
||||||
|
command: ["serve"]
|
||||||
|
|
||||||
watchtower:
|
gitea:
|
||||||
image: containrrr/watchtower:latest
|
image: gitea/gitea:latest
|
||||||
container_name: watchtower
|
container_name: gitea
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
ports:
|
||||||
- WATCHTOWER_NOTIFICATIONS=shoutrrr
|
- "3001:3000"
|
||||||
- WATCHTOWER_NOTIFICATION_URL=ntfy://ntfy:80/miles-test
|
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /home/miles/gitea-data:/data
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
caddy_data:
|
caddy_data:
|
||||||
caddy_config:
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# --- CONFIGURATION ---
|
||||||
|
BASE_DIR="/home/miles"
|
||||||
|
# List of folders to create based on your docker-compose
|
||||||
|
FOLDERS=(
|
||||||
|
"code-config" "projects" "homarr-data" "navidrome-data"
|
||||||
|
"navidrome-music" "trilium-data" "gitea-data" "roms"
|
||||||
|
"romm-data" "ntfy-cache" "qbittorrent-config" "downloads"
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- 1. INSTALL DOCKER ---
|
||||||
|
if ! [ -x "$(command -v docker)" ]; then
|
||||||
|
echo "🚀 Docker not found. Installing..."
|
||||||
|
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||||
|
sudo sh get-docker.sh
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
|
echo "✅ Docker installed. (Note: You may need to logout and back in for group changes to take effect)"
|
||||||
|
else
|
||||||
|
echo "✅ Docker is already installed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 2. CREATE FOLDERS ---
|
||||||
|
echo "📂 Creating directory structure..."
|
||||||
|
for folder in "${FOLDERS[@]}"; do
|
||||||
|
mkdir -p "$BASE_DIR/$folder"
|
||||||
|
done
|
||||||
|
# Set permissions to PUID 1000
|
||||||
|
sudo chown -R $USER:$USER $BASE_DIR/
|
||||||
|
echo "✅ Folders created and permissions set to user $USER."
|
||||||
|
|
||||||
|
# --- 3. MANAGEMENT MENU ---
|
||||||
|
show_menu() {
|
||||||
|
echo "------------------------------------------"
|
||||||
|
echo " HOME SERVER MANAGEMENT MENU"
|
||||||
|
echo "------------------------------------------"
|
||||||
|
echo "1) Start/Update Stack (Up -d)"
|
||||||
|
echo "2) Stop Stack (Down)"
|
||||||
|
echo "3) View Logs (Follow)"
|
||||||
|
echo "4) Update Images (Pull)"
|
||||||
|
echo "5) Check Container Status"
|
||||||
|
echo "6) Exit"
|
||||||
|
echo "------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
show_menu
|
||||||
|
read -p "Choose an option [1-6]: " choice
|
||||||
|
case $choice in
|
||||||
|
1) docker compose up -d ;;
|
||||||
|
2) docker compose down ;;
|
||||||
|
3) docker compose logs -f --tail=50 ;;
|
||||||
|
4) docker compose pull && docker compose up -d ;;
|
||||||
|
5) docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" ;;
|
||||||
|
6) exit 0 ;;
|
||||||
|
*) echo "Invalid option. Try again." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user