Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
356fdf206e | ||
|
|
a7c94ddc6c | ||
|
|
0a5ef19ef9 | ||
|
|
f394bf3b0e | ||
|
|
91ca20bd21 | ||
|
|
627e9ca241 | ||
|
|
0d2b5203ba | ||
|
|
57b8b41a17 | ||
|
|
467f3ce148 | ||
|
|
23f0f2cc46 |
@@ -1,44 +1,45 @@
|
||||
:4533 {
|
||||
# Code-Server (VS Code)
|
||||
:raspberrypi-1.tail46eacb.ts.net {
|
||||
tls {
|
||||
get_certificate tailscale
|
||||
}
|
||||
|
||||
# VS Code
|
||||
handle_path /edit* {
|
||||
reverse_proxy code-server:8443
|
||||
}
|
||||
handle_path /ntfy* {
|
||||
reverse_proxy ntfy:80
|
||||
reverse_proxy 127.0.0.1:8443
|
||||
}
|
||||
|
||||
# qBittorrent (Stripping path to avoid 404)
|
||||
handle_path /tr* {
|
||||
reverse_proxy qbittorrent:8081
|
||||
# File Browser
|
||||
handle_path /drive* {
|
||||
reverse_proxy 127.0.0.1:8082
|
||||
}
|
||||
|
||||
# Navidrome
|
||||
# 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
|
||||
handle_path /git* {
|
||||
reverse_proxy gitea:3000
|
||||
reverse_proxy 127.0.0.1:3001
|
||||
}
|
||||
|
||||
# ROMM
|
||||
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)
|
||||
# Homarr Dashboard (Root)
|
||||
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
|
||||
+63
-79
@@ -1,44 +1,70 @@
|
||||
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:
|
||||
image: caddy:latest
|
||||
container_name: caddy
|
||||
restart: always
|
||||
ports:
|
||||
- "4533:4533"
|
||||
network_mode: host
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
|
||||
homarr:
|
||||
image: ghcr.io/homarr-labs/homarr:latest
|
||||
container_name: homarr
|
||||
restart: always
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- SECRET_ENCRYPTION_KEY=31ba05520db9d1dc463c66d81c3195db8c4b5010e97c352c11377877ef1a8d50
|
||||
# This fixes the encryption error
|
||||
- SECRET_ENCRYPTION_KEY=a90069963afd0d7fab70f044426f1c7a7f8ba322df8b4193cd975fd1f981462b
|
||||
volumes:
|
||||
- /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:
|
||||
image: deluan/navidrome:latest
|
||||
container_name: navidrome
|
||||
restart: always
|
||||
user: "1000:1000"
|
||||
ports:
|
||||
- "4533:4533"
|
||||
environment:
|
||||
- ND_BASEURL=/music
|
||||
- ND_MUSICFOLDER=/music
|
||||
volumes:
|
||||
- /home/miles/navidrome-data:/data
|
||||
- /home/miles/navidrome-music:/music
|
||||
@@ -47,54 +73,11 @@ code-server:
|
||||
image: triliumnext/notes:latest
|
||||
container_name: trilium
|
||||
restart: always
|
||||
environment:
|
||||
- TRILIUM_BASE_URL=notes
|
||||
- TRILIUM_PORT=8082
|
||||
ports:
|
||||
- "8081:8080"
|
||||
volumes:
|
||||
- /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:
|
||||
image: lscr.io/linuxserver/qbittorrent:latest
|
||||
container_name: qbittorrent
|
||||
@@ -102,27 +85,28 @@ code-server:
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=Etc/UTC
|
||||
- WEBUI_PORT=8081
|
||||
ports:
|
||||
- "8085:8081"
|
||||
volumes:
|
||||
- /home/miles/qbittorrent-config:/config
|
||||
- /home/miles/downloads:/downloads
|
||||
- /home/miles/torrent-config:/config
|
||||
- /home/miles/files/downloads:/downloads
|
||||
|
||||
excalidraw:
|
||||
image: excalidraw/excalidraw:latest
|
||||
container_name: excalidraw
|
||||
ntfy:
|
||||
image: binwiederhier/ntfy:latest
|
||||
container_name: ntfy
|
||||
restart: always
|
||||
ports:
|
||||
- "8083:80"
|
||||
command: ["serve"]
|
||||
|
||||
watchtower:
|
||||
image: containrrr/watchtower:latest
|
||||
container_name: watchtower
|
||||
gitea:
|
||||
image: gitea/gitea:latest
|
||||
container_name: gitea
|
||||
restart: always
|
||||
environment:
|
||||
- WATCHTOWER_NOTIFICATIONS=shoutrrr
|
||||
- WATCHTOWER_NOTIFICATION_URL=ntfy://ntfy:80/miles-test
|
||||
ports:
|
||||
- "3001:3000"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /home/miles/gitea-data:/data
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
caddy_data:
|
||||
@@ -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