This commit is contained in:
Mike McFetridge
2026-07-23 19:38:14 -04:00
parent 72272e4006
commit 84e1ead50c
283 changed files with 0 additions and 206 deletions
+40
View File
@@ -0,0 +1,40 @@
services:
arcane:
image: ghcr.io/ofkm/arcane:latest
container_name: arcane
ports:
- '3552:3552'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/miker/docker/arcane/data:/app/data
- /home/miker/docker/arcane/projects:/app/data/projects
environment:
- APP_URL=http://192.168.2.21:3552
- PUID=1000
- PGID=1000
- ENCRYPTION_KEY=OjYxMUkyZVdqYjd1QWVZbw==FUwh8qzl
- JWT_SECRET=FIw1uz3TbDH7U9y
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3552"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
# Default creds: arcane / arcane-admin
# arcane agent Install
services:
arcane-agent:
image: ghcr.io/getarcaneapp/arcane-headless:latest
container_name: arcane-agent
ports:
- '3553:3553'
environment:
- AGENT_MODE=true
# Use a strong, temporary bootstrap token for pairing:
- AGENT_BOOTSTRAP_TOKEN=FIw1uz3TbDH7U9y
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
restart: unless-stopped
+150
View File
@@ -0,0 +1,150 @@
# ============================================================
# Tom Spark's ARR Stack — Environment Configuration
# https://github.com/loponai/arrstack
#
# INSTRUCTIONS:
# 1. Copy this file: cp .env.example .env
# 2. Fill in your VPN credentials below
# 3. Adjust timezone and user IDs if needed
# 4. Run: docker compose up -d
# ============================================================
# ============================================================
# SYSTEM SETTINGS
# ============================================================
# Your timezone (list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
TZ=America/New_York
# Your Linux user/group ID. Find yours with: id
# Most systems default to 1000. If yours is different, change these.
PUID=1000
PGID=1000
# ============================================================
# VPN SETTINGS — Pick your provider and fill in credentials
# Full provider list: https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers
#
# IMPORTANT: VPN credentials are NOT your login email/password!
# You need service credentials from your VPN provider's manual
# setup or API section. See the provider examples at the bottom of this file.
# ============================================================
# Your VPN provider (surfshark, nordvpn, protonvpn, airvpn, mullvad, private internet access, windscribe, etc.)
VPN_SERVICE_PROVIDER=airvpn
# Protocol: wireguard (recommended, faster) or openvpn
VPN_TYPE=wireguard
# --- WIREGUARD CREDENTIALS ---
# For Surfshark: go to https://my.surfshark.com/vpn/manual-setup/main → WireGuard
# For other providers: see the examples at the bottom of this file
WIREGUARD_PRIVATE_KEY=eDgf3GPFy2ltgx2RkD/Vx5wKZ4dVi28YbQmSJOrbWmk=
WIREGUARD_ADDRESSES=10.175.23.30
# Only needed for some providers (AirVPN). Leave blank if not required.
# WIREGUARD_PUBLIC_KEY=
WIREGUARD_PRESHARED_KEY=+0+hrSdzRUxKDNk1Q37PNmNJ2jsj2EzF45JtbZad4lI=
# --- OPENVPN CREDENTIALS ---
# Only needed if VPN_TYPE=openvpn. Leave blank if using WireGuard.
# OPENVPN_USER=
# OPENVPN_PASSWORD=
# --- SERVER SELECTION ---
# Pick a country close to you for best speeds
SERVER_COUNTRIES=Canada
# --- PORT FORWARDING ---
# Supported by: ProtonVPN, AirVPN, PIA. Can help with upload speeds and seeding.
# Not required for downloading. Most users don't need this.
# Set to "on" if your provider supports it, leave blank otherwise (Surfshark, NordVPN, etc.).
#VPN_PORT_FORWARDING=
# If your provider requires manually specifying a port (e.g. AirVPN):
FIREWALL_VPN_INPUT_PORTS=29261
# ============================================================
# NETWORK — Static IPs for each service
# You shouldn't need to change these unless you have a conflict.
# ============================================================
IP_GLUETUN=172.39.0.2
IP_RADARR=172.39.0.3
IP_SONARR=172.39.0.4
IP_LIDARR=172.39.0.5
IP_BAZARR=172.39.0.6
IP_JELLYFIN=172.39.0.7
IP_SEERR=172.39.0.8
IP_AUDIO=172.39.0.9
IP_NAVI=172.39.0.10
IP_LIST=172.39.0.11
IP_WATCH=172.39.0.12
# ============================================================
# PROVIDER-SPECIFIC EXAMPLES
# Uncomment and fill in the section for your VPN provider.
# ============================================================
# --- NORDVPN ---
# 1. Go to: https://my.nordaccount.com/dashboard/nordvpn/manual-configuration/
# 2. Generate a WireGuard private key (NordLynx)
# 3. Paste the private key below
# VPN_SERVICE_PROVIDER=nordvpn
# VPN_TYPE=wireguard
# WIREGUARD_PRIVATE_KEY=your_nordvpn_private_key_here
# WIREGUARD_ADDRESSES=10.5.0.2/16
# SERVER_COUNTRIES=United States
# --- PROTONVPN ---
# 1. Go to: https://account.protonvpn.com/ → Downloads → WireGuard configuration
# 2. Generate a config, open the file, copy the PrivateKey and Address
# 3. Port forwarding is supported on paid plans
# VPN_SERVICE_PROVIDER=protonvpn
# VPN_TYPE=wireguard
# WIREGUARD_PRIVATE_KEY=your_proton_private_key_here
# WIREGUARD_ADDRESSES=10.2.0.2/32
# SERVER_COUNTRIES=United States
# VPN_PORT_FORWARDING=on
# --- SURFSHARK ---
# 1. Go to: https://my.surfshark.com/vpn/manual-setup/main
# 2. Get WireGuard credentials
# VPN_SERVICE_PROVIDER=surfshark
# VPN_TYPE=wireguard
# WIREGUARD_PRIVATE_KEY=your_surfshark_private_key_here
# WIREGUARD_ADDRESSES=10.14.0.2/16
# SERVER_COUNTRIES=United States
# --- AIRVPN ---
# 1. Go to: https://airvpn.org/ → Client Area → Config Generator
# 2. Select Linux → WireGuard → pick a server → Generate
# 3. Copy all keys and the assigned IP
# VPN_SERVICE_PROVIDER=airvpn
# VPN_TYPE=wireguard
# WIREGUARD_PRIVATE_KEY=your_airvpn_private_key_here
# WIREGUARD_PUBLIC_KEY=your_airvpn_public_key_here
# WIREGUARD_PRESHARED_KEY=your_airvpn_preshared_key_here
# WIREGUARD_ADDRESSES=your_assigned_ip/32
# FIREWALL_VPN_INPUT_PORTS=your_forwarded_port
# VPN_PORT_FORWARDING=on
# --- MULLVAD ---
# 1. Go to: https://mullvad.net/en/account → WireGuard configuration
# VPN_SERVICE_PROVIDER=mullvad
# VPN_TYPE=wireguard
# WIREGUARD_PRIVATE_KEY=your_mullvad_private_key_here
# WIREGUARD_ADDRESSES=your_assigned_ip/32
# SERVER_COUNTRIES=United States
# --- Watchtower ---
WATCHTOWER_CLEANUP=true
WATCHTOWER_INCLUDE_RESTARTING=true
WATCHTOWER_ROLLING_RESTARTING=true
WATCHTOWER_SCHEDULE=0 0 4 * * *
WATCHTOWER_INCLUDE_STOPPED=true
WATCHTOWER_NOTIFICATIONS=email
WATCHTOWER_NOTIFICATIONS_HOSTNAME=Docker-Deply # Add Server Name or IP Address
WATCHTOWER_NOTIFICATION_EMAIL_FROM=miker@mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_TO=miker@mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_SERVER=mail.mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=465
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=miker@mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=!Sucyetat123
WATCHTOWER_NOTIFICATION_EMAIL_DELAY=2
PUID=1000
PGID=1000
+440
View File
@@ -0,0 +1,440 @@
# Tom Spark's ARR Stack — Automated Media Server
# https://github.com/loponai/arrstack
#
# Usage:
# 1. Copy .env.example to .env and fill in your VPN credentials
# 2. Run: bash setup-folders.sh
# 3. Run: docker compose up -d
#
# All VPN-protected services (qBittorrent, Prowlarr, FlareSolverr) run
# through Gluetun. If the VPN drops, traffic stops. Zero leaks.
#
# Radarr, Sonarr, Lidarr, Bazarr, Jellyfin, and Seerr do NOT run through
# the VPN — they need direct network access for speed and local connectivity.
networks:
arrnetwork:
name: arrnetwork
ipam:
config:
- subnet: 172.39.0.0/24
services:
# ============================================================
# GLUETUN — VPN Container (kill switch + tunnel)
# All VPN-protected services route through this container.
# Ports for those services are mapped HERE, not on the services themselves.
# Docs: https://github.com/qdm12/gluetun-wiki
# ============================================================
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
networks:
arrnetwork:
ipv4_address: ${IP_GLUETUN}
ports:
- 8000:8000 # Gluetun Control Server
- 8080:8080 # qBittorrent WebUI
- 6881:6881 # qBittorrent torrenting port
- 6881:6881/udp
- 9696:9696 # Prowlarr
- 8191:8191 # FlareSolverr
volumes:
- gluetun_volume:/gluetun
environment:
- VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER}
- VPN_TYPE=${VPN_TYPE}
# --- WireGuard credentials (most providers) ---
- WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY}
- WIREGUARD_ADDRESSES=${WIREGUARD_ADDRESSES}
# - WIREGUARD_PUBLIC_KEY=${WIREGUARD_PUBLIC_KEY}
- WIREGUARD_PRESHARED_KEY=${WIREGUARD_PRESHARED_KEY}
# --- OpenVPN credentials (if using OpenVPN instead) ---
# - OPENVPN_USER=${OPENVPN_USER}
# - OPENVPN_PASSWORD=${OPENVPN_PASSWORD}
# --- Server selection ---
- SERVER_COUNTRIES=${SERVER_COUNTRIES}
# --- Port forwarding (ProtonVPN, AirVPN, PIA) ---
# - VPN_PORT_FORWARDING=${VPN_PORT_FORWARDING}
- FIREWALL_VPN_INPUT_PORTS=${FIREWALL_VPN_INPUT_PORTS}
- FIREWALL_OUTBOUND_SUBNETS=192.168.0.0/22
# --- General ---
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
- BLOCK_MALICIOUS=off
- HTTP_CONTROL_SERVER_ADDRESS=:8000
- HTTP_CONTROL_SERVER_LOG=on
- HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE={"auth":"none"}
healthcheck:
test: wget -qO /dev/null http://127.0.0.1:9999 || exit 1
interval: 20s
timeout: 10s
retries: 5
restart: unless-stopped
# ============================================================
# QBITTORRENT — Torrent Client (runs through Gluetun VPN)
# ALL traffic goes through the VPN tunnel. No direct internet.
# ============================================================
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
network_mode: service:gluetun
depends_on:
gluetun:
condition: service_healthy
restart: true
labels:
- deunhealth.restart.on.unhealthy=true
environment:
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
- WEBUI_PORT=8080
- TORRENTING_PORT=${FIREWALL_VPN_INPUT_PORTS}
volumes:
- qbittorrent_volume:/config
- /data:/data
healthcheck:
test: wget -q --spider http://localhost:8080 || exit 1
interval: 60s
timeout: 10s
retries: 3
start_period: 20s
restart: unless-stopped
# ============================================================
# DEUNHEALTH — Auto-restarts unhealthy containers
# If qBittorrent loses VPN connection, this restarts it automatically.
# ============================================================
deunhealth:
image: qmcgaw/deunhealth
container_name: deunhealth
network_mode: none
environment:
- LOG_LEVEL=info
- HEALTH_SERVER_ADDRESS=127.0.0.1:9999
- TZ=${TZ}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- deunhealth_volume:/config
restart: always
# ============================================================
# PROWLARR — Indexer Manager (runs through Gluetun VPN)
# Manages torrent/usenet indexers. Syncs to Radarr/Sonarr/Lidarr.
# ============================================================
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
container_name: prowlarr
network_mode: service:gluetun
depends_on:
gluetun:
condition: service_healthy
restart: true
environment:
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
volumes:
- prowlarr_volume:/config
restart: unless-stopped
# ============================================================
# FLARESOLVERR — Cloudflare Bypass (runs through Gluetun VPN)
# Some indexers use Cloudflare protection. This gets around it.
# ============================================================
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: flaresolverr
network_mode: service:gluetun
depends_on:
gluetun:
condition: service_healthy
restart: true
volumes:
- flaresolverr_volume:/config
environment:
- LOG_LEVEL=info
- TZ=${TZ}
restart: unless-stopped
# ============================================================
# RADARR — Movie Manager (NOT behind VPN)
# Searches via Prowlarr, sends downloads to qBittorrent,
# renames and hard-links completed files to media folder.
# ============================================================
radarr:
image: lscr.io/linuxserver/radarr:latest
container_name: radarr
environment:
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
volumes:
- radarr_volume:/config
- /data:/data
ports:
- 7878:7878
networks:
arrnetwork:
ipv4_address: ${IP_RADARR}
restart: unless-stopped
# ============================================================
# SONARR — TV Show Manager (NOT behind VPN)
# Same pattern as Radarr but for TV series.
# ============================================================
sonarr:
image: lscr.io/linuxserver/sonarr:latest
container_name: sonarr
environment:
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
volumes:
- sonarr_volume:/config
- /data:/data
ports:
- 8989:8989
networks:
arrnetwork:
ipv4_address: ${IP_SONARR}
restart: unless-stopped
# ============================================================
# LIDARR — Music Manager (NOT behind VPN)
# Optional. Comment out if you don't need music automation.
# ============================================================
lidarr:
image: lscr.io/linuxserver/lidarr:latest
container_name: lidarr
environment:
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
volumes:
- lidarr_volume:/config
- /data:/data
ports:
- 8686:8686
networks:
arrnetwork:
ipv4_address: ${IP_LIDARR}
restart: unless-stopped
# ============================================================
# BAZARR — Subtitle Manager (NOT behind VPN)
# Automatically downloads subtitles for movies and TV shows.
# ============================================================
bazarr:
image: lscr.io/linuxserver/bazarr:latest
container_name: bazarr
environment:
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
volumes:
- bazarr_volume:/config
- /data:/data
ports:
- 6767:6767
networks:
arrnetwork:
ipv4_address: ${IP_BAZARR}
restart: unless-stopped
# ============================================================
# JELLYFIN — Media Server (NOT behind VPN)
# Your personal streaming service. Plays movies, TV, music.
# Needs full bandwidth — never put this behind the VPN.
# ============================================================
jellyfin:
image: lscr.io/linuxserver/jellyfin:latest
container_name: jellyfin
environment:
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
volumes:
- jellyfin_volume:/config
- /data/media:/data/media
ports:
- 8096:8096
# Uncomment the lines below to enable hardware transcoding (Intel Quick Sync / VAAPI).
# Only works if your system has Intel/AMD integrated graphics (/dev/dri must exist).
# If you get an error about /dev/dri not found, leave these commented out.
# devices:
# - /dev/dri:/dev/dri
networks:
arrnetwork:
ipv4_address: ${IP_JELLYFIN}
restart: unless-stopped
# ============================================================
# SEERR — Request System (NOT behind VPN)
# Netflix-like UI for requesting movies and TV shows.
# Share this with family — they never need to touch Radarr.
#
# Seerr is the unified successor to Overseerr and Jellyseerr
# (merged under seerr-team). Supports Plex, Jellyfin, and Emby.
#
# Config uses a NAMED Docker volume (not a bind mount). This is
# required: Seerr runs as the `node` user (UID 1000) and a
# bind-mounted host folder is created root-owned, causing a
# permission-denied crash loop. On Windows/WSL, bind mounts also
# corrupt the SQLite DB over SMB. Named volumes fix both cases
# (matches upstream Seerr docs).
#
# Migrating from ./jellyseerr or ./seerr bind mount? See README
# troubleshooting "Migrating Seerr config to a named volume".
# ============================================================
seerr:
image: ghcr.io/seerr-team/seerr:v3.0.1
init: true
container_name: seerr
environment:
- LOG_LEVEL=info
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
- PORT=5055
volumes:
- seerr_volume:/app/config # <--- Needed or will cause a permissions issue.
ports:
- 5055:5055
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/settings/public || exit 1
start_period: 20s
timeout: 3s
interval: 15s
retries: 3
networks:
arrnetwork:
ipv4_address: ${IP_SEERR}
restart: unless-stopped
listenarr:
image: ghcr.io/listenarrs/listenarr:canary
container_name: listenarr
ports:
- "4545:4545"
environment:
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
volumes:
- listenarr_volume:/app/config
- /data/media/audiobookshelf/books:/audiobooks
- /data/torrents/books:/downloads
restart: unless-stopped
networks:
arrnetwork:
ipv4_address: ${IP_LIST}
audiobookshelf:
image: ghcr.io/advplyr/audiobookshelf:latest
container_name: audiobookshelf
ports:
- 13378:80
environment:
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
volumes:
- /data/media/books/audiobookshelf/books:/audiobooks
- /data/media/books/audiobookshelf/podcasts:/podcasts
- /data/media/books/audiobookshelf/metadata:/metadata
- audiobookshelf_volume:/config
restart: unless-stopped
networks:
arrnetwork:
ipv4_address: ${IP_AUDIO}
navidrome:
image: deluan/navidrome:latest
container_name: navidrome
ports:
- 4533:4533
restart: unless-stopped
environment:
- ND_SCANSCHEDULE=1h
- ND_LOGLEVEL=info
- ND_SESSIONTIMEOUT=24h
- PUID=${PUID}
- PGID=${PGID}
- UMASK=002
- TZ=${TZ}
volumes:
- navidrome_volume:/data
- /data/media/music:/music:ro
networks:
arrnetwork:
ipv4_address: ${IP_NAVI}
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
env_file: .env
environment:
- DOCKER_API_VERSION=1.44
- TZ=${TZ}
- PUID:=${PUID} # Reference PUID from .env
- PGID=${PGID} # Reference PGID from .env
- WATCHTOWER_CLEANUP=${WATCHTOWER_CLEANUP}
- WATCHTOWER_INCLUDE_RESTARTING=${WATCHTOWER_INCLUDE_RESTARTING}
- WATCHTOWER_ROLLING_RESTARTING=${WATCHTOWER_ROLLING_RESTARTING}
- WATCHTOWER_SCHEDULE=${WATCHTOWER_SCHEDULE}
- WATCHTOWER_INCLUDE_STOPPED=${WATCHTOWER_INCLUDE_STOPPED}
- WATCHTOWER_NOTIFICATIONS=${WATCHTOWER_NOTIFICATIONS}
- WATCHTOWER_NOTIFICATIONS_HOSTNAME=${WATCHTOWER_NOTIFICATIONS_HOSTNAME}
- WATCHTOWER_NOTIFICATION_EMAIL_FROM=${WATCHTOWER_NOTIFICATION_EMAIL_FROM}
- WATCHTOWER_NOTIFICATION_EMAIL_TO=${WATCHTOWER_NOTIFICATION_EMAIL_TO}
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER}
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT}
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER}
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD}
security_opt:
- no-new-privileges:true
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- watchtower_volume:/config
networks:
arrnetwork:
ipv4_address: ${IP_WATCH}
# Go to the VERY BOTTOM of your file (outside of services) and add this:
volumes:
gluetun_volume:
qbittorrent_volume:
deunhealth_volume:
prowlarr_volume:
flaresolverr_volume:
radarr_volume:
sonarr_volume:
lidarr_volume:
bazarr_volume:
jellyfin_volume:
seerr_volume:
listenarr_volume:
audiobookshelf_volume:
navidrome_volume:
watchtower_volume:
@@ -0,0 +1,44 @@
GNU nano 8.3 setup-folders.bat
@echo off
REM ============================================================
REM Tom Spark's ARR Stack — Folder Structure Setup (Windows)
REM https://github.com/loponai/arrstack
REM
REM Creates the folder structure required for hard links.
REM Run this ONCE before starting the stack.
REM
REM Edit DATA_DIR below if your media drive is different.
REM ============================================================
set DATA_DIR=D:\data
echo.
echo === Tom Spark's ARR Stack — Folder Setup (Windows) ===
echo.
echo Creating folder structure at %DATA_DIR%...
echo.
mkdir "%DATA_DIR%\torrents\movies" 2>nul
mkdir "%DATA_DIR%\torrents\tv" 2>nul
mkdir "%DATA_DIR%\torrents\music" 2>nul
mkdir "%DATA_DIR%\media\movies" 2>nul
mkdir "%DATA_DIR%\media\tv" 2>nul
mkdir "%DATA_DIR%\media\music" 2>nul
echo Done! Folder structure:
echo.
echo %DATA_DIR%\
echo +-- torrents\
echo ¦ +-- movies\
echo ¦ +-- tv\
echo ¦ +-- music\
echo +-- media\
echo +-- movies\
echo +-- tv\
echo +-- music\
echo.
echo IMPORTANT: For hard links to work, torrents and media
echo must be on the SAME drive (both under %DATA_DIR%).
echo.
pause
+72
View File
@@ -0,0 +1,72 @@
#!/bin/bash
# ============================================================
# Tom Spark's ARR Stack — Folder Structure Setup
# https://github.com/loponai/arrstack
#
# Creates the /data directory structure required for hard links
# to work correctly. Run this ONCE before starting the stack.
#
# Usage: sudo bash setup-folders.sh
# ============================================================
set -e
DATA_DIR="/data"
echo ""
echo "=== Tom Spark's ARR Stack — Folder Setup ==="
echo ""
echo "This will create the following structure:"
echo ""
echo " /data/"
echo " ├── torrents/"
echo " │ ├── movies/"
echo " │ ├── tv/"
echo " │ └── music/"
echo " └── media/"
echo " ├── movies/"
echo " ├── tv/"
echo " └── music/"
echo ""
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "ERROR: This script needs sudo to create /data and set permissions."
echo "Run: sudo bash setup-folders.sh"
exit 1
fi
# Get the real user (not root) for ownership
REAL_USER=${SUDO_USER:-$USER}
REAL_UID=$(id -u "$REAL_USER")
REAL_GID=$(id -g "$REAL_USER")
echo "Creating folders..."
mkdir -p "$DATA_DIR"/{torrents/{movies,tv,music,books},media/{movies,tv,music,books}}
echo "Setting ownership to $REAL_USER ($REAL_UID:$REAL_GID)..."
chown -R "$REAL_UID":"$REAL_GID" "$DATA_DIR"
echo "Setting permissions..."
chmod -R 775 "$DATA_DIR"
# Comment this out if you are not deploying this through Gitea CI/CD process.
echo "Setting up directory nd ownership"
# Create the directory if it doesn't exist yet
sudo mkdir -p /opt/Docker-Deployments
# Change the ownership to your deployment user
sudo chown -R miker:miker /opt/Docker-Deployments
echo ""
echo "Done! Folder structure:"
if command -v tree &> /dev/null; then
tree "$DATA_DIR"
else
find "$DATA_DIR" -type d | head -20
fi
echo ""
echo "Your PUID=$REAL_UID and PGID=$REAL_GID"
echo "Make sure these match your .env file."
echo ""
+329
View File
@@ -0,0 +1,329 @@
#!/bin/bash
# ============================================================
# Tom Spark's ARR Stack — Health Check & Troubleshooting
# https://github.com/loponai/arrstack
#
# Run this after 'docker compose up -d' to verify everything
# is working correctly. It checks each service, tests VPN
# connectivity, and provides specific fixes for any issues.
#
# Usage: bash test-stack.sh
# ============================================================
set -o pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
PASS="${GREEN}✓ PASS${NC}"
FAIL="${RED}✗ FAIL${NC}"
WARN="${YELLOW}! WARN${NC}"
TOTAL_PASS=0
TOTAL_FAIL=0
TOTAL_WARN=0
pass() { echo -e " ${PASS} $1"; ((TOTAL_PASS++)); }
fail() { echo -e " ${FAIL} $1"; ((TOTAL_FAIL++)); }
warn() { echo -e " ${WARN} $1"; ((TOTAL_WARN++)); }
header() { echo -e "\n${CYAN}${BOLD}[$1]${NC}"; }
fix() { echo -e " ${YELLOW}Fix: $1${NC}"; }
echo ""
echo "========================================="
echo " Tom Spark's ARR Stack — Health Check"
echo "========================================="
echo ""
# ============================================================
# TEST 1: Docker running?
# ============================================================
header "Docker"
if docker info > /dev/null 2>&1; then
pass "Docker is running"
else
fail "Docker is not running"
fix "Start Docker: sudo systemctl start docker"
fix "Or install: curl -fsSL https://get.docker.com | sh"
echo ""
echo "Cannot continue without Docker. Exiting."
exit 1
fi
# ============================================================
# TEST 2: .env file exists and has VPN credentials?
# ============================================================
header "Configuration"
if [ -f .env ]; then
pass ".env file exists"
else
fail ".env file not found"
fix "Run: cp .env.example .env && nano .env"
fix "Then fill in your VPN credentials"
fi
if [ -f .env ]; then
VPN_KEY=$(grep -E "^WIREGUARD_PRIVATE_KEY=" .env 2>/dev/null | cut -d= -f2)
VPN_PROVIDER=$(grep -E "^VPN_SERVICE_PROVIDER=" .env 2>/dev/null | cut -d= -f2)
if [ -n "$VPN_KEY" ] && [ "$VPN_KEY" != "" ]; then
pass "VPN private key is set (provider: $VPN_PROVIDER)"
else
fail "VPN private key is empty"
fix "Edit .env and paste your WireGuard private key"
fix "Get it from your VPN provider's manual setup page"
fi
fi
# ============================================================
# TEST 3: Folder structure exists?
# ============================================================
header "Folder Structure"
ALL_FOLDERS_OK=true
for dir in /data/torrents/movies /data/torrents/tv /data/torrents/music /data/torrents/books /data/media/movies /data/media/tv /data/media/music /data/media/books; do
if [ -d "$dir" ]; then
pass "$dir exists"
else
fail "$dir missing"
ALL_FOLDERS_OK=false
fi
done
if [ "$ALL_FOLDERS_OK" = false ]; then
fix "Run: sudo bash setup-folders.sh"
fi
# Check permissions
if [ -d /data ]; then
OWNER=$(stat -c '%u' /data 2>/dev/null)
ENV_PUID=$(grep -E "^PUID=" .env 2>/dev/null | cut -d= -f2)
if [ "$OWNER" = "$ENV_PUID" ] || [ "$OWNER" = "$(id -u)" ]; then
pass "/data ownership matches PUID ($OWNER)"
else
warn "/data owned by $OWNER but PUID is ${ENV_PUID:-1000}"
fix "Run: sudo chown -R ${ENV_PUID:-1000}:${ENV_PUID:-1000} /data"
fi
fi
# ============================================================
# TEST 4: Container status
# ============================================================
header "Containers"
EXPECTED_SERVICES="gluetun qbittorrent deunhealth prowlarr flaresolverr radarr sonarr lidarr bazarr jellyfin seerr"
for svc in $EXPECTED_SERVICES; do
STATUS=$(docker inspect --format '{{.State.Status}}' "$svc" 2>/dev/null)
HEALTH=$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}no-healthcheck{{end}}' "$svc" 2>/dev/null)
if [ -z "$STATUS" ]; then
fail "$svc — not found (not created)"
fix "Run: docker compose up -d"
elif [ "$STATUS" = "running" ]; then
if [ "$HEALTH" = "healthy" ]; then
pass "$svc — running (healthy)"
elif [ "$HEALTH" = "unhealthy" ]; then
fail "$svc — running but UNHEALTHY"
if [ "$svc" = "gluetun" ]; then
fix "VPN probably can't connect. Check credentials in .env"
fix "Check logs: docker logs gluetun | tail -20"
fix "Try: rm -rf gluetun && docker compose up -d gluetun"
elif [ "$svc" = "qbittorrent" ]; then
fix "Usually means VPN dropped. Deunhealth should auto-restart it."
fix "Check: docker logs qbittorrent | tail -20"
fi
elif [ "$HEALTH" = "starting" ]; then
warn "$svc — running (health check starting, wait 30s and rerun)"
else
pass "$svc — running"
fi
elif [ "$STATUS" = "created" ]; then
warn "$svc — created but not started"
if [ "$svc" = "qbittorrent" ] || [ "$svc" = "prowlarr" ] || [ "$svc" = "flaresolverr" ]; then
fix "Waiting for Gluetun to be healthy. Check Gluetun status first."
fix "If Gluetun is healthy, try: docker compose up -d $svc"
elif [ "$svc" = "seerr" ]; then
fix "Port 5055 may be in use. Check: ss -tlnp | grep 5055"
fix "Or change the port in docker-compose.yml"
else
fix "Try: docker compose up -d $svc"
fi
elif [ "$STATUS" = "restarting" ]; then
fail "$svc — crash-looping (restarting)"
fix "Check logs: docker logs $svc | tail -30"
if [ "$svc" = "seerr" ]; then
fix "Seerr may have a corrupt config. Try: docker compose down seerr && rm -rf seerr && docker compose up -d seerr"
fix "WSL/Windows users: if it keeps crashing, try a named volume instead of a bind mount"
else
fix "Try: docker compose down $svc && docker compose up -d $svc"
fi
elif [ "$STATUS" = "exited" ]; then
fail "$svc — exited (crashed)"
fix "Check logs: docker logs $svc | tail -30"
fix "Try restarting: docker compose up -d $svc"
else
warn "$svc — status: $STATUS"
fi
done
# ============================================================
# TEST 5: VPN connectivity
# ============================================================
header "VPN Connection"
GLUETUN_STATUS=$(docker inspect --format '{{.State.Status}}' gluetun 2>/dev/null)
GLUETUN_HEALTH=$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{end}}' gluetun 2>/dev/null)
if [ "$GLUETUN_STATUS" = "running" ] && [ "$GLUETUN_HEALTH" = "healthy" ]; then
# Get VPN IP
VPN_IP=$(docker exec gluetun wget -qO- --timeout=10 ipinfo.io/ip 2>/dev/null)
if [ -n "$VPN_IP" ]; then
pass "Gluetun VPN IP: $VPN_IP"
# Get VPN location
VPN_LOCATION=$(docker exec gluetun wget -qO- --timeout=10 "ipinfo.io/${VPN_IP}/city" 2>/dev/null)
VPN_COUNTRY=$(docker exec gluetun wget -qO- --timeout=10 "ipinfo.io/${VPN_IP}/country" 2>/dev/null)
if [ -n "$VPN_LOCATION" ]; then
pass "VPN location: $VPN_LOCATION, $VPN_COUNTRY"
fi
else
fail "Gluetun is healthy but can't reach the internet"
fix "Check logs: docker logs gluetun | tail -20"
fi
# Check if qBittorrent is tunneled
QBIT_STATUS=$(docker inspect --format '{{.State.Status}}' qbittorrent 2>/dev/null)
if [ "$QBIT_STATUS" = "running" ]; then
QBIT_IP=$(docker exec qbittorrent wget -qO- --timeout=10 ipinfo.io/ip 2>/dev/null)
if [ "$QBIT_IP" = "$VPN_IP" ]; then
pass "qBittorrent tunneled through VPN ($QBIT_IP)"
elif [ -n "$QBIT_IP" ]; then
fail "qBittorrent IP ($QBIT_IP) doesn't match VPN IP ($VPN_IP)!"
fix "This should not happen. Check network_mode in docker-compose.yml"
else
warn "Could not check qBittorrent IP (container may still be starting)"
fi
fi
# Check if Prowlarr is tunneled
PROWLARR_STATUS=$(docker inspect --format '{{.State.Status}}' prowlarr 2>/dev/null)
if [ "$PROWLARR_STATUS" = "running" ]; then
PROWLARR_IP=$(docker exec prowlarr wget -qO- --timeout=10 ipinfo.io/ip 2>/dev/null)
if [ "$PROWLARR_IP" = "$VPN_IP" ]; then
pass "Prowlarr tunneled through VPN ($PROWLARR_IP)"
elif [ -n "$PROWLARR_IP" ]; then
fail "Prowlarr IP ($PROWLARR_IP) doesn't match VPN IP ($VPN_IP)!"
fi
fi
# Verify your real IP is different
REAL_IP=$(wget -qO- --timeout=10 ipinfo.io/ip 2>/dev/null)
if [ -n "$REAL_IP" ] && [ "$REAL_IP" != "$VPN_IP" ]; then
pass "Real IP ($REAL_IP) differs from VPN IP — VPN is working!"
elif [ "$REAL_IP" = "$VPN_IP" ]; then
warn "Real IP matches VPN IP — are you already running a system-wide VPN?"
fi
else
if [ "$GLUETUN_HEALTH" = "unhealthy" ]; then
fail "Gluetun is unhealthy — VPN not connected"
fix "Check credentials in .env (these are NOT your VPN login email/password)"
fix "Check logs: docker logs gluetun 2>&1 | tail -30"
fix "Try resetting: docker compose down && rm -rf gluetun && docker compose up -d"
elif [ "$GLUETUN_HEALTH" = "starting" ]; then
warn "Gluetun health check still starting — wait 30-60 seconds and rerun"
else
warn "Gluetun not running — can't test VPN"
fix "Run: docker compose up -d"
fi
fi
# ============================================================
# TEST 6: Service web UI accessibility
# ============================================================
header "Web UI Access"
check_http() {
local name=$1 port=$2
local code=$(curl -sL -o /dev/null -w "%{http_code}" --max-time 5 "http://localhost:$port" 2>/dev/null)
if [ "$code" = "200" ] || [ "$code" = "302" ] || [ "$code" = "301" ] || [ "$code" = "307" ]; then
pass "$name — http://localhost:$port (HTTP $code)"
elif [ "$code" = "000" ]; then
# Container might be behind gluetun, check if it's running
local status=$(docker inspect --format '{{.State.Status}}' "$name" 2>/dev/null)
if [ "$status" = "running" ]; then
warn "$name — container running but port $port not reachable from host"
fix "Port may be mapped on Gluetun. Try: http://localhost:$port"
else
fail "$name — not reachable (container not running)"
fi
else
warn "$name — http://localhost:$port returned HTTP $code"
fi
}
check_http qbittorrent 8080
check_http prowlarr 9696
check_http radarr 7878
check_http sonarr 8989
check_http lidarr 8686
check_http bazarr 6767
check_http jellyfin 8096
check_http seerr 5055
# ============================================================
# TEST 7: Hard link capability
# ============================================================
header "Hard Links"
if [ -d /data/torrents ] && [ -d /data/media ]; then
# Check if same filesystem
FS_TORRENTS=$(df /data/torrents --output=source 2>/dev/null | tail -1)
FS_MEDIA=$(df /data/media --output=source 2>/dev/null | tail -1)
if [ "$FS_TORRENTS" = "$FS_MEDIA" ]; then
pass "torrents/ and media/ are on the same filesystem ($FS_TORRENTS)"
pass "Hard links will work correctly"
else
fail "torrents/ ($FS_TORRENTS) and media/ ($FS_MEDIA) are on DIFFERENT filesystems!"
fix "Hard links only work on the same filesystem/drive"
fix "Move both directories to the same drive"
fi
# Quick hard link test
TEST_FILE="/data/torrents/.hardlink_test_$$"
TEST_LINK="/data/media/.hardlink_test_$$"
if touch "$TEST_FILE" 2>/dev/null && ln "$TEST_FILE" "$TEST_LINK" 2>/dev/null; then
pass "Hard link test succeeded"
rm -f "$TEST_FILE" "$TEST_LINK" 2>/dev/null
elif [ -f "$TEST_FILE" ]; then
fail "Hard link test failed — filesystem may not support hard links"
fix "Check filesystem type: df -T /data"
fix "Hard links work on ext4, btrfs, xfs. NOT on exFAT or ntfs-3g"
rm -f "$TEST_FILE" 2>/dev/null
else
warn "Could not write to /data/torrents (permission issue?)"
fix "Run: sudo chown -R $(id -u):$(id -g) /data"
fi
else
warn "Folder structure not found — skipping hard link test"
fix "Run: sudo bash setup-folders.sh"
fi
# ============================================================
# SUMMARY
# ============================================================
echo ""
echo "========================================="
echo -e " ${GREEN}Passed: $TOTAL_PASS${NC} ${RED}Failed: $TOTAL_FAIL${NC} ${YELLOW}Warnings: $TOTAL_WARN${NC}"
echo "========================================="
if [ $TOTAL_FAIL -eq 0 ] && [ $TOTAL_WARN -eq 0 ]; then
echo -e "\n ${GREEN}${BOLD}All checks passed! Your stack is ready to go.${NC}\n"
elif [ $TOTAL_FAIL -eq 0 ]; then
echo -e "\n ${YELLOW}${BOLD}No failures, but check the warnings above.${NC}\n"
else
echo -e "\n ${RED}${BOLD}Some checks failed. Follow the fix instructions above.${NC}"
echo -e " ${BOLD}If stuck, check: docker logs <container-name>${NC}\n"
fi
@@ -0,0 +1,38 @@
### EXAMPLE DOCKER COMPOSE ###
services:
audiobookshelf:
image: ghcr.io/advplyr/audiobookshelf:latest
# ABS runs on port 13378 by default. If you want to change
# the port, only change the external port, not the internal port
# set the container name within docker
container_name: audiobookshelf
# ports:
# - 13378:80
volumes:
# These volumes are needed to keep your library persistent
# and allow media to be accessed by the ABS server.
# The path to the left of the colon is the path on your computer,
# and the path to the right of the colon is where the data is
# available to ABS in Docker.
# You can change these media directories or add as many as you want
- ./audiobooks:/audiobooks
- ./podcasts:/podcasts
# The metadata directory can be stored anywhere on your computer
- ./metadata:/metadata
# The config directory needs to be on the same physical machine
# you are running ABS on
- ./config:/config
restart: unless-stopped
# You can use the following environment variable to run the ABS
# docker container as a specific user. You will need to change
# the UID and GID to the correct values for your user.
#environment:
# - user=1000:1000
# Network to join in docker which is named below
networks:
- proxy
# create PROXY network for NPM security. This will allow NPM to see and talk to >
networks:
proxy:
external: true
+20
View File
@@ -0,0 +1,20 @@
#For a fresh authentik installation, you need to generate a password and a secret key.
PG_PASS=vXqYGFaTTldI8+DydREqaf3RRvHVRDXAlyKfaEXQ92Nw570A
AUTHENTIK_SECRET_KEY=voCiuozip37G/UISer4WV8FBLrMD8diHINmALHvWQ0A7PkzMoYH9xf3MnTDWEylN1TS1dp7JJ2f3nv1V
#Enable error reporting
AUTHENTIK_ERROR_REPORTING__ENABLED=true
# SMTP Host Emails are sent to
AUTHENTIK_EMAIL__HOST=mail.mmcfetridge.net
AUTHENTIK_EMAIL__PORT=587
AUTHENTIK_EMAIL__USERNAME=miker@mmcfetridge.net
AUTHENTIK_EMAIL__PASSWORD=!Sucyetat123
AUTHENTIK_EMAIL__USE_TLS=true
AUTHENTIK_EMAIL__USE_SSL=false
AUTHENTIK_EMAIL__TIMEOUT=10
AUTHENTIK_EMAIL__FROM=miker@mmcfetridge.net
# Authentik listens on port 9000 for HTTP and 9443 for HTTPS. To change the exposed ports change these values
COMPOSE_PORT_HTTP=9500
COMPOSE_PORT_HTTPS=9543
+100
View File
@@ -0,0 +1,100 @@
---
services:
postgresql:
image: docker.io/library/postgres:16-alpine
restart: unless-stopped
container_name: authentik-db
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- ./database:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
POSTGRES_USER: ${PG_USER:-authentik}
POSTGRES_DB: ${PG_DB:-authentik}
env_file:
- .env
networks:
- authentik
redis:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
container_name: authentik-redis
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
- ./redis:/data
networks:
- authentik
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.8.1}
restart: unless-stopped
container_name: authentik-server
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
volumes:
- ./media:/media
- ./custom-templates:/templates
env_file:
- .env
ports:
- "${COMPOSE_PORT_HTTP:-9000}:9000"
- "${COMPOSE_PORT_HTTPS:-9443}:9443"
depends_on:
- postgresql
- redis
networks:
- authentik
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.8.1}
restart: unless-stopped
container_name: authentik-worker
command: worker
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
# `user: root` and the docker socket volume are optional.
# See more for the docker socket integration here:
# https://goauthentik.io/docs/outposts/integrations/docker
# Removing `user: root` also prevents the worker from fixing the permissions
# on the mounted folders, so when removing this make sure the folders have the correct UID/GID
# (1000:1000 by default)
user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./media:/media
- ./certs:/certs
- ./custom-templates:/templates
env_file:
- .env
depends_on:
- postgresql
- redis
networks:
- authentik
networks:
authentik:
external: true
@@ -0,0 +1,75 @@
# Increase buffer size for large headers
# This is needed only if you get 'upstream sent too big header while reading response
# header from upstream' error when trying to access an application protected by goauthentik
proxy_buffers 8 16k;
proxy_buffer_size 32k;
# Make sure not to redirect traffic to a port 4443
port_in_redirect off;
location / {
# Put your proxy_pass to your application here
proxy_pass $forward_scheme://$server:$port;
# Set any other headers your application might need
# proxy_set_header Host $host;
# proxy_set_header ...
# Support for websocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
##############################
# authentik-specific config
##############################
auth_request /outpost.goauthentik.io/auth/nginx;
error_page 401 = @goauthentik_proxy_signin;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
# translate headers from the outposts back to the actual upstream
auth_request_set $authentik_username $upstream_http_x_authentik_username;
auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
auth_request_set $authentik_entitlements $upstream_http_x_authentik_entitlements;
auth_request_set $authentik_email $upstream_http_x_authentik_email;
auth_request_set $authentik_name $upstream_http_x_authentik_name;
auth_request_set $authentik_uid $upstream_http_x_authentik_uid;
proxy_set_header X-authentik-username $authentik_username;
proxy_set_header X-authentik-groups $authentik_groups;
proxy_set_header X-authentik-entitlements $authentik_entitlements;
proxy_set_header X-authentik-email $authentik_email;
proxy_set_header X-authentik-name $authentik_name;
proxy_set_header X-authentik-uid $authentik_uid;
# This section should be uncommented when the "Send HTTP Basic authentication" option
# is enabled in the proxy provider
# auth_request_set $authentik_auth $upstream_http_authorization;
# proxy_set_header Authorization $authentik_auth;
}
# all requests to /outpost.goauthentik.io must be accessible without authentication
location /outpost.goauthentik.io {
# When using the embedded outpost, use:
proxy_pass https://192.168.2.7:9543/outpost.goauthentik.io;
# For manual outpost deployments:
# proxy_pass http://outpost.company:9000;
# Note: ensure the Host header matches your external authentik URL:
proxy_set_header Host $host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
add_header Set-Cookie $auth_cookie;
auth_request_set $auth_cookie $upstream_http_set_cookie;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
# Special location for when the /auth endpoint returns a 401,
# redirect to the /start URL which initiates SSO
location @goauthentik_proxy_signin {
internal;
add_header Set-Cookie $auth_cookie;
return 302 /outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
# For domain level, use the below error_page to redirect to your authentik server with the full redirect path
# return 302 https://authentik.company/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
}
+27
View File
@@ -0,0 +1,27 @@
services:
beszel:
image: henrygd/beszel:latest
container_name: beszel
restart: unless-stopped
ports:
- 8090:8090
volumes:
- /home/miker/docker/beszel/data:/beszel_data
- /home/miker/docker/beszel/socket:/beszel_socket
# Agent Install
# beszel-agent:
# image: henrygd/beszel-agent:latest
# container_name: beszel-agent
# restart: unless-stopped
# network_mode: host
# volumes:
# - /home/miker/docker/beszel/agent:/var/lib/beszel-agent
# - /home/miker/docker/beszel/socket:/beszel_socket
# - /var/run/docker.sock:/var/run/docker.sock:ro
# environment:
# LISTEN: /beszel_socket/beszel.sock
# HUB_URL: http://192.168.2.7:8090
# TOKEN: <token>
# KEY: "<key>"
+35
View File
@@ -0,0 +1,35 @@
services:
checkmk:
container_name: checkmk
image: checkmk/check-mk-raw:2.3.0p7
tmpfs:
- /opt/omd/sites/cmk/tmp:uid=1000,gid=1000
ulimits:
nofile: 1024
volumes:
- /home/miker/docker/checkmk/monitoring:/omd/sites
- /etc/localtime:/etc/localtime:ro
environment:
- /var/run/docker.sock:/var/run/docker.sock
- TZ=America/New_York
ports:
- "8080:8000"
- "5000:5000"
restart: unless-stopped
networks:
checkmk:
networks:
checkmk:
# When build is complete, you need to look in the logs for the default username and password.
# Passwd for checkmk - Uv8bJ0nDFxLxXz9qJxe0
# To install the agent on a linux system:
# sudo wget http://192.168.0.183:8180/cmk/check_mk/agents/check-mk-agent_2.3.0p7-1_all.deb
# sudo dpkg -i check-mk-agent_2.3.0p7-1_all.deb
scp check-mk-agent_2.3.0p7-1_all.deb miker@107.175.245.171 /home/miker
+70
View File
@@ -0,0 +1,70 @@
# Store environmental variables here. All variables are optional.
# Lines beginning in '#' are ignored.
# Can be either development, production or test
# NODE_ENV=production
# The port to expose the running application on
# PORT=4000
# If you've proved SSL certs, then can set HTTPS port
# SSL_PORT=4001
# The host that Dashy is running on, domain or IP
# HOST=localhost
# The default base path for serving up static assets
# BASE_URL=./
# Optionally, specify the path of SSL private + public keys
# SSL_PRIV_KEY_PATH=/etc/ssl/certs/dashy-priv.key
# SSL_PUB_KEY_PATH=/etc/ssl/certs/dashy-pub.pem
# If SSL enabled, choose whether or not to redirect http to https
# Defaults to true
# REDIRECT_HTTPS=true
# The path to the user data directory
# USER_DATA_DIR=user-data
# Enable HTTP basic auth to protect your *.yml config files
# ENABLE_HTTP_AUTH=true
# Enable basic HTTP auth to protect your *.yml config files
# BASIC_AUTH_USERNAME
# BASIC_AUTH_PASSWORD
# If you'd like frontend to automatically authenticate when basic auth enabled, set credentials here too
# VUE_APP_BASIC_AUTH_USERNAME
# VUE_APP_BASIC_AUTH_PASSWORD
# Override where the path to the configuration file is, can be a remote URL
# VUE_APP_CONFIG_PATH=/conf.yml
# Usually the same as BASE_URL, but accessible in frontend
# VUE_APP_DOMAIN=https://dashy.to
# Override the page title for the frontend app
# VUE_APP_TITLE=''
# Set the default view to load on startup (can be `minimal`, `workspace` or `home`)
# VUE_APP_STARTING_VIEW=home
# Set the Vue app routing mode (can be 'hash', 'history' or 'abstract')
# VUE_APP_ROUTING_MODE=history
# Should enable SRI for build script and link resources
# INTEGRITY=true
# Computed automatically on build. Indicates if running in container
# IS_DOCKER=true
# Again, set automatically using package.json during build time
# VUE_APP_VERSION=2.0.0
# Directory for conf.yml backups
# BACKUP_DIR=./user-data/config-backups
# Setup any other user defined vars by prepending VUE_APP_ to the var name
# VUE_APP_pihole_ip=http://your.pihole.ip
# VUE_APP_pihole_key=your_pihole_secret_key
+297
View File
@@ -0,0 +1,297 @@
# Need to be stored in the dashy/config directory
pageInfo:
title: Hello, Miker
description: My Homepage of Services
logo: https://i.ibb.co/71WyyzM/little-bot-3.png
appConfig:
statusCheck: false
theme: glass-2
fontAwesomeKey: c94dc2b452
customCss: '.clock p.time { font-size: 3rem !important; }'
layout: vertical
iconSize: small
language: en
sections:
- name: My Public IP Address
widgets:
- type: public-ip
id: 0_1764_publicip
- name: Holidays
widgets:
- type: public-holidays
options:
country: US
holidayType: all
monthsToShow: 4
lang: en
id: 0_829_publicholidays
- name: Date and Time
widgets:
- type: clock
options:
timeZone: America/New_york
format: en-GB
hideDate: false
customCityName: Bealeton, Va.
use12Hour: true
hideSeconds: true
id: 0_396_clock
- name: RackNerd Server
items:
- title: Proxy Service
description: Nginx Proxy Manager
icon: icons/nginx-proxy-manager.png
url: https://proxy.mikeandrebel.com
target: newtab
statusCheck: true
- title: Search Engine
description: MIker's Search Engine
icon: icons/searxng.png
url: https://search.mikeandrebel.com/
target: newtab
statusCheck: true
- title: Portainer
description: Portainer
icon: icons/portainer.png
url: https://port.mikeandrebel.com/#!/home
target: newtab
statusCheck: true
- title: Rack Nerd Control Panel
description: Rack Nerd Control Panel
icon: icons/cloudflare.png
url: https://nerdvm.racknerd.com/login.php
target: newtab
- title: Rack Nerd
description: Rack Nerd
icon: icons/cloudflare.png
url: https://my.racknerd.com/index.php?rp=/login
target: newtab
- title: Mealie
description: Mealie
icon: icons/mealie.png
url: https://meal.mikeandrebel.com/
target: newtab
statusCheck: true
displayData:
sortBy: default
rows: 1
cols: 1
collapsed: true
hideForGuests: false
- name: Home Server 1
items:
- title: JellyFin
description: Jellyfin Movies
icon: icons/jellyfin.png
url: http://192.168.1.151:8096
target: newtab
- title: Local Proxy Server
description: Nginx Proxy Manager
icon: icons/nginx-proxy-manager.png
url: http://192.168.1.151:81/
target: newtab
- title: Portainer
description: Portainer
icon: icons/portainer.png
url: http://192.168.1.151:9000/
target: newtab
- title: Router
description: Orbi System
icon: icons/router.png
url: http://192.168.1.1/
target: newtab
- title: Router
description: Arris System
icon: icons/arris.png
url: http://192.168.0.1/
target: newtab
displayData:
sortBy: default
rows: 1
cols: 1
collapsed: true
hideForGuests: false
- name: Home Server 2 internal
items:
- title: Proxmox
icon: icons/proxmox.png
url: https://192.168.0.171:8006
target: newtab
statusCheck: true
- title: Portatiner
icon: icons/portainer.png
url: https://192.168.0.181:7443
target: newtab
- title: NPM
icon: icons/nginx-proxy-manager.png
url: http://192.168.0.235:81
target: newtab
- title: PiHole
icon: icons/pi-hole.png
url: http://192.168.0.185/admin/
target: newtab
- title: VSCode
icon: icons/vscode.png
url: http://192.168.0.187:8680
target: newtab
- title: Authelia
icon: icons/authelia.png
url: http://192.168.0.181:9091
target: newtab
- title: Dashy
icon: icons/dashy.png
url: http://192.168.0.181:4000
target: newtab
statusCheck: true
displayData:
sortBy: default
rows: 1
cols: 1
collapsed: true
hideForGuests: false
- name: Home Server External
items:
- title: Proxmox
icon: icons/proxmox.png
url: https://pve1.mikemcfetridge.com
target: newtab
statusCheck: true
- title: Potainer
icon: icons/portainer.png
url: https://port.mikemcfetridge.com
target: newtab
statusCheck: true
- title: NPM
icon: icons/nginx-proxy-manager.png
url: https://proxy.mikemcfetridge.com
target: newtab
- title: PiHole
icon: icons/pi-hole.png
url: https://pihole.mikemcfetridge.com
target: newtab
- title: VSCode
icon: icons/vscode.png
url: https://vscode.mikemcfetridge.com
target: newtab
- title: Authelia
icon: icons/authelia.png
url: https://auth.mikemcfetridge.com
target: newtab
- title: Dashy
icon: icons/dashy.png
url: https://dashy.mikemcfetridge.com
target: newtab
displayData:
sortBy: default
rows: 1
cols: 1
collapsed: true
hideForGuests: false
- name: Oracle Server
items:
- title: Hestia Control Panel
description: Hestia Control Panel
icon: icons/hestia.png
url: https://hcp.mcfetridge.us:8083
target: newtab
statusCheck: true
- title: Next Cloud
description: Next Cloud
icon: icons/nextcloud.png
url: https://next.mcfetridge.us
target: newtab
statusCheck: true
- title: Web Mail
description: Web Email
icon: si-reddit
url: https://webmail.mcfetridge.us
target: newtab
statusCheck: true
- title: Family Website
description: Wordpress Website
icon: icons/wordpress.png
url: https://mcfetridge.us/
target: newtab
statusCheck: true
- title: WordPress Admin
description: WordPress Admin
icon: icons/wordpress.png
url: https://mcfetridge.us/wp-admin
target: newtab
statusCheck: true
- title: Webstats
description: Hestia Webstats
icon: icons/hestia.png
url: https://mcfetridge.us/vstats/
target: newtab
statusCheck: true
displayData:
sortBy: default
rows: 1
cols: 1
collapsed: true
hideForGuests: false
- name: Oracle Test Server
items:
- title: Poratiner
description: Poratiner
icon: icons/portainer.png
url: http://
target: newtab
displayData:
sortBy: default
rows: 1
cols: 1
collapsed: true
hideForGuests: false
- name: Bookmarks
items:
- title: Name Cheap
description: Name Cheap
icon: icons/namecheap.png
url: https://www.namecheap.com/
target: newtab
- title: Oracle Cloud
description: Oracle Cloud
icon: icons/oracle-cloud.png
url: https://cloud.oracle.com/compute/instances?region=us-ashburn-1
target: newtab
- title: Send Blue
description: Send Blue STMP
icon: icons/sendinblue.png
url: https://app.brevo.com/
target: newtab
- title: Github
description: Git Hub
icon: icons/github.png
url: https://github.com/mmcfetridge1969
target: newtab
- title: DuckDNS
description: Duck DNS
icon: icons/duckdns.png
url: https://www.duckdns.org
displayData:
collapsed: true
hideForGuests: false
@@ -0,0 +1,56 @@
---
# Welcome to Dashy! To get started, run `docker compose up -d`
# You can configure your container here, by modifying this file
# If you need to download the Icons from GIT. Go to the root directory of Dashy >
# sudo git clone https://github.com/walkxcode/dashboard-icons.git
# This will create a dashboard-icons directory with all the png and svg files.
services:
dashy:
container_name: dashy
# Pull latest image
image: 'lissy93/dashy'
# To build from source, replace 'image: lissy93/dashy' with 'build: .'
# build: .
# You can also use an image with a different tag, or pull from a different r>
# image: ghcr.io/lissy93/dashy or image: lissy93/dashy:3.0.0
# Mapping data to the volume created for this service
volumes:
- /home/miker/docker/dashy/data/config/conf.yml:/app/user-data/conf.yml
- /home/miker/docker/dashy/png:/app/user-data/icons
# Set port that web service will be served on. Keep container port as 8080
# ports:
# - 4000:8080
# Set any environmental variables
environment:
- NODE_ENV=production
# Specify your user ID and group ID. You can find this by running `id -u` an>
- UID=1000 # Update to match your UID
- GID=1000 # Update to match your GID.
# Sets the service to restart always unless it is stopped manually.
restart: unless-stopped
# Configure healthchecks
healthcheck:
test: ['CMD', 'node', '/app/services/healthcheck']
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- proxy
# Service will be place in the proxy network for NPM security
networks:
proxy:
external: true
+27
View File
@@ -0,0 +1,27 @@
services:
# Dashy - Application Dashboard
dashy:
container_name: dashy
image: lissy93/dashy
security_opt:
- no-new-privileges:true
restart: unless-stopped
profiles: ["apps", "all"]
networks:
- default
ports:
- $DASHY_PORT:8080
healthcheck:
test: ['CMD', 'node', '/app/services/healthcheck']
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
volumes:
- $DOCKERDIR/appdata/dashy/conf.yml:/app/public/conf.yml
- $DOCKERDIR/appdata/dashy/item-icons:/app/public/item-icons
environment:
- NODE_ENV=production
- UID=$PUID
- GID=$PGID
# DOCKER-LABELS-PLACEHOLDER
+11
View File
@@ -0,0 +1,11 @@
ADMIN_USERNAME=admin
ADMIN_PASSWORD=super_secret_password_change_me
# Base Paths
DOCKER_BASE_PATH=/home/miker/docker
# Ports
DOCKHAND_PORT=3200
# Container Names
PROXY_NAME=docker-socket-proxy
DOCKHAND_NAME=dock-hand
@@ -0,0 +1,46 @@
services:
socket-proxy:
image: tecnativa/docker-socket-proxy:latest
container_name: ${PROXY_NAME}
restart: unless-stopped
environment:
# These flags allow only the actions Dockhand needs
- CONTAINERS=1
- IMAGES=1
- NETWORKS=1
- VOLUMES=1
- INFO=1
# Disable anything not strictly necessary
- POST=1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
dockhand:
image: fnsys/dockhand:latest
container_name: ${DOCKHAND_NAME}
restart: unless-stopped
ports:
- 3200:3000
volumes:
- ${DOCKER_BASE_PATH}/dockhand:/app/data
- ${DOCKER_BASE_PATH}/dockhand/stack:/stack
- ${DOCKER_BASE_PATH}:/DockerConfigs
environment:
# Point Dockhand to the proxy instead of the local socket file
- DOCKER_HOST=tcp://socket-proxy:2375
- ADMIN_USERNAME=${ADMIN_USERNAME}
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
- TZ=UTC
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
networks:
- management-net
depends_on:
- socket-proxy
networks:
management-net:
driver: bridge
+13
View File
@@ -0,0 +1,13 @@
services:
hawser:
image: ghcr.io/finsys/hawser:latest
container_name: hawser_agent
ports:
- "2376:2376"
environment:
- DOCKER_SOCKET=/var/run/docker.sock
- TOKEN=sj8GwEiPz7hncCpZB69P01ValE9ayXpGwTY5AYQFYxo
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/miker/docker/dockhand/stack:/stack
restart: unless-stopped
+65
View File
@@ -0,0 +1,65 @@
# =============================================================================
# Nginx Proxy Manager Platform — Environment Variables
# =============================================================================
MYSQL_ROOT_PASSWORD=rhDGjilZm6XEMJ
MYSQL_DATABASE=npm
MYSQL_USER=npm
MYSQL_PASSWORD=rhDGjilZm6XEMJ
# TZ for container timezone
TZ=America/New_York
# =============================================================================
# WAF Management Platform — Environment Variables
# Copy this file to .env and fill in all CHANGE_ME values before first run.
# Never commit .env to source control.
# =============================================================================
# --- Image version -------------------------------------------------------
# Pin a release tag (e.g. v1.0.0) for reproducible deploys. "latest" tracks
# the newest published image.
WAF_IMAGE_TAG=latest
# --- GeoIP (MaxMind GeoLite2) --------------------------------------------
# Host path to your own GeoLite2-City.mmdb. MaxMind licensing prevents us
# from bundling it. See the README "GeoIP setup" section to obtain one free.
GEOIP_DB_PATH=./GeoLite2-City.mmdb
# --- PostgreSQL ----------------------------------------------------------
POSTGRES_DB=wafdb
POSTGRES_USER=wafuser
POSTGRES_PASSWORD=ioGjIVo4zu4b6Bj
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
# --- Redis ---------------------------------------------------------------
REDIS_URL=redis://redis:6379/0
# --- API Security --------------------------------------------------------
# Generate with: python3 -c "import secrets; print(secrets.token_hex(32))"
SECRET_KEY=ef210e8acc8c0ecdafe3b2096c8923fed5b766d2e86885fa387f3ad600e2de0e
# Comma-separated list of allowed CORS origins (no wildcard).
# For the default local deploy, use the UI's HTTPS URL:
ALLOWED_ORIGINS=https://localhost:8443
# TOTP encryption key — generate with:
# python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
TOTP_ENCRYPTION_KEY=G1WN75rpulrIprSgn56Ctb8qiXdZM7K2m2FjksRsmu8=
# --- Caddy Admin API (container-internal) --------------------------------
CADDY_ADMIN_URL=http://caddy-waf:2019
# --- SMTP (for alert notifications) --------------------------------------
SMTP_HOST=mail.mmcfetridge.net
SMTP_PORT=465
SMTP_USER=miker@mmcfetridge.net
SMTP_PASSWORD="!Sucyetat123"
SMTP_FROM=miker@mmcfetridge.net
# --- Bootstrap superadmin (seeded on first run only) ---------------------
# Change the password immediately after first login.
BOOTSTRAP_ADMIN_EMAIL=miker@mmcfetridge.net
BOOTSTRAP_ADMIN_PASSWORD=PVGpjJOId5djMO5
+252
View File
@@ -0,0 +1,252 @@
---
services:
db:
image: 'jc21/mariadb-aria:latest'
container_name: npm-db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MARIADB_AUTO_UPGRADE=1
volumes:
- ./npm/data/mysql:/var/lib/mysql
networks:
# - proxydb
- waf-internal
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}"]
interval: 20s
timeout: 5s
retries: 5
start_period: 30s
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
env_file: .env
environment:
- TZ=${TZ}
- DB_MYSQL_HOST=db
- DB_MYSQL_PORT=3306
- DB_MYSQL_USER=${MYSQL_USER}
- DB_MYSQL_PASSWORD=${MYSQL_PASSWORD}
- DB_MYSQL_NAME=${MYSQL_DATABASE}
ports:
- '81:81' # Kept so you can access the NPM dashboard on host-ip:81
# '80:80' and '443:443' REMOVED here. They are reachable internally via the network.
volumes:
- ./npm/data/npm:/data
- ./npm/data/letsencrypt:/etc/letsencrypt
depends_on:
- db
networks:
# - proxy
# - proxydb
- waf-internal
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:81/api/status"]
interval: 20s
timeout: 5s
retries: 5
start_period: 40s
# ---------------------------------------------------------------------------
# Caddy + Coraza: WAF engine and reverse proxy
# ---------------------------------------------------------------------------
caddy-waf:
image: ghcr.io/socfortress/waf-caddy:${WAF_IMAGE_TAG:-latest}
container_name: caddy-waf
ports:
- "80:80"
- "443:443"
# Lets the WAF proxy to apps running on the Docker host (e.g. an nginx
# upstream) via http://host.docker.internal:<port>. See demo/README.md.
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- coraza-rules:/etc/coraza/rules
- caddy-config:/etc/caddy
- coraza-custom:/etc/coraza/custom
- crs-data:/etc/coraza/crs-rules # live CRS dir (seeded by admin-api)
- coraza-logs:/var/log/coraza
networks:
- waf-internal
depends_on:
http-echo:
condition: service_started
healthcheck:
test: ["CMD", "wget", "-q", "-O-", "http://localhost:2019/config/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
restart: unless-stopped
# ---------------------------------------------------------------------------
# Dummy upstream — replace with your real protected app(s)
# ---------------------------------------------------------------------------
http-echo:
image: hashicorp/http-echo:0.2.3
container_name: http-echo
command: ["-text=upstream-ok"]
user: "65534:65534"
networks:
- waf-internal
healthcheck:
test: ["NONE"]
deploy:
resources:
limits:
cpus: "0.25"
memory: 64M
restart: unless-stopped
# ---------------------------------------------------------------------------
# FastAPI Admin API
# ---------------------------------------------------------------------------
admin-api:
image: ghcr.io/socfortress/waf-admin-api:${WAF_IMAGE_TAG:-latest}
container_name: admin-api
env_file: .env
volumes:
- tls-certs:/certs # shared TLS cert volume (see admin-ui)
# GeoLite2 DB is user-supplied — MaxMind licensing forbids redistribution.
# Point GEOIP_DB_PATH at your downloaded GeoLite2-City.mmdb (see README).
- ./GeoLite2-City/GeoLite2-City.mmdb:/etc/geoip-bundle/GeoLite2-City.mmdb:ro
- geoip-data:/etc/geoip
- coraza-rules:/etc/coraza/rules
- caddy-config:/etc/caddy
- coraza-custom:/etc/coraza/custom
- crs-data:/etc/coraza/crs-rules # live CRS dir (seeded from image bundle)
- coraza-logs:/var/log/coraza
networks:
- waf-internal
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "-q", "-O-", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
restart: unless-stopped
# ---------------------------------------------------------------------------
# React Admin UI (served by Nginx, HTTPS on 8443)
# ---------------------------------------------------------------------------
admin-ui:
image: ghcr.io/socfortress/waf-admin-ui:${WAF_IMAGE_TAG:-latest}
container_name: admin-ui
ports:
- "8443:8080"
volumes:
- tls-certs:/etc/nginx/certs # shared with admin-api for cert upload + reload
networks:
- waf-internal
depends_on:
admin-api:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "-q", "--no-check-certificate", "-O-", "https://localhost:8080/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
deploy:
resources:
limits:
cpus: "0.5"
memory: 128M
restart: unless-stopped
# ---------------------------------------------------------------------------
# PostgreSQL 16
# ---------------------------------------------------------------------------
postgres:
image: postgres:16.3-alpine
container_name: postgres
env_file: .env
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- waf-internal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
restart: unless-stopped
# ---------------------------------------------------------------------------
# Redis 7
# ---------------------------------------------------------------------------
redis:
image: redis:7.2.5-alpine
container_name: redis
user: redis
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
networks:
- waf-internal
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
start_period: 5s
deploy:
resources:
limits:
cpus: "0.5"
memory: 256M
restart: unless-stopped
# =============================================================================
# Networks
# =============================================================================
networks:
proxy:
external: true
proxydb:
external: true
waf-internal:
driver: bridge
# =============================================================================
# Named volumes
# =============================================================================
volumes:
coraza-rules:
coraza-custom:
coraza-logs:
caddy-config:
crs-data:
geoip-data:
postgres-data:
redis-data:
tls-certs:
+3
View File
@@ -0,0 +1,3 @@
Account ID: 1370812
License key: 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
Download link: https://download.maxmind.com/app/geoip_download_by_token?date=20260630&edition_id=GeoLite2-City&suffix=tar.gz&token=v2.local.tR9DihzEGIIYMbcbukGNpnBXVsi6EAxtwhQu147OaPcWj_fvkcboMf5hMqL3Wqn0rD8KpW6ujxku8yNaaL3Ylr9LsshJdIHWns1V14pzm82AKrQ9oldDCS-yR7a4kRow8Ofmhr4KBxo1DxoHfTiI8JJB_5qRDwI5ugbmiJr65lzkZKxfpQGCr9kMcM4ueZJzWlJqyQQ
+24
View File
@@ -0,0 +1,24 @@
services:
emulatorjs:
image: lscr.io/linuxserver/emulatorjs:latest
container_name: emulatorjs
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
volumes:
- /home/miker/docker/emulatorjs/config:/config
- /home/miker/docker/emulatorjs/rompack:/data
- /home/miker/docker/emulatorjs/rompack/atari2600/roms:/data/atari2600/roms:ro
- /home/miker/docker/emulatorjs/rompack/gba/roms:/data/gba/roms:ro
- /home/miker/docker/emulatorjs/rompack/n64/roms:/data/n64/roms:ro
- /home/miker/docker/emulatorjs/rompack/nes/roms:/data/nes/roms:ro
- /home/miker/docker/emulatorjs/rompack/ngp/roms:/data/ngp/roms:ro
- /home/miker/docker/emulatorjs/rompack/segaMD/roms:/data/segaMD/roms:ro
- /home/miker/docker/emulatorjs/rompack/segaMS/roms:/data/segaMS/roms:ro
- /home/miker/docker/emulatorjs/rompack/snes/rom:/data/snes/roms:ro
ports:
- 3000:3000
- 8080:80
- 4001:4001 #optional
restart: unless-stopped
+135
View File
@@ -0,0 +1,135 @@
---
services:
gitlab:
image: docker.io/gitlab/gitlab-ce:latest
container_name: gitlab
shm_size: '256m'
environment:
PUID: 1000
PGID: 1000
volumes:
- /home/miker/docker/gitlab/config:/etc/gitlab
- /home/miker/docker/gitlab/logs:/var/log/gitlab
- /home/miker/docker/gitlab/data:/var/opt/gitlab
ports:
# --> (Optional) Remove when using traefik...
- "8080:80"
- "8443:443"
- '222:22'
restart: unless-stopped
# Lookup password assigned at install
# sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
To use the GitLab runner in GitLab, you need to configure it. For correct configuration, we will need a token copied from the portal. To do this, go to the address: http://localhost:8080/admin/runners and click the Copy token button.
In the next step, it goes to the console and run the following command:
> docker exec -it gitlab-runner gitlab-runner register --url "http://gitlab-ce" --clone-url "http://gitlab-ce"
After launching, a configuration module will appear. The module provides the following information:
Enter the GitLab instance URL: confirm the entered value (click enter)
Enter the registration token: enter the token copied before.
Enter a description for the runner: enter the name of the runner, e.g. docker-runner
Enter tags for the runner: leave the field blank here
Enter an executor: enter docker here
Enter the default Docker image: here we provide the default docker image, e.g. maven: latest
After proper configuration, we should see confirmation Runner registred successfully:
In addition to the basic configuration, we also need to allow access for containers launched from the runner to the virtual network in which GitLab operates. To do this, we run the editor (e.g. vi)
> sudo vi gitlab/gitlab-runner/config.toml
Then we add new line to the end of the runner configuration: network_mode = “gitlab-network”
To check if the runner is available from the GitLab level, go to the following address:http://localhost:8080/admin/runners
We create our first repository
After setting up the runner, we can create our first repository. To do this, go to the page: http://localhost:8080/projects/new and click Import project.
Na następnym ekranie wybieramy Import project from: Repo from URL. Następnie podajemy w Git repository URL adress: https://github.com/czerniga/helloworld.git. Na końcu zatwierdzamy klikając Create project.
On the next screen, select Import project from: Repo from URL. Then we provide the Git repository URL address: https://github.com/czerniga/helloworld.git. Finally, confirm by clicking Create project.
After a while you should have the first repository copied to your GitLab.
We create the CI/CD pipeline
To create a CI/CD pipeline for the project, click the main menu on the left, CI/CD, and then Editor. An option to create a .gitlab-ci.yml file, which will contain our pipeline definitions, will appear on the screen. This file will be created in the Git repository.
On the new screen we can see our pipeline editor. In the editor, paste the following content:
image: maven:latest
stages:
- build
- test
build-job:
stage: build
script:
- echo "Compiling the code..."
- mvn clean package
- echo "Compile complete."
artifacts:
paths:
- target
test-job:
stage: test
dependencies:
- build-job
script:
- ls -al
- echo "Running tests"
- java -cp target/helloworld-1.1.jar com.coveros.demo.helloworld.HelloWorld
The above definition describes how the CI / CD process should work. The most important elements are:
image: docker image that we will use to build our project
stages: a list of our process steps
build-job: the first step in our process to build our project. Additionally, we save the artifacts for use in the next step
test-job: the second step to run our project
After pasting our file, confirm the changes by clicking Commit changes.
Once approved, GitLab will launch the process. To check its results, go to CI/CD -> Pipelines in the menu on the left. On the screen we should see that our first task has already been started.
We can go to the details of this task by clicking on the pending button or the build number #1
After a while, the task should be built and tested.
How to install GitLab using Docker Compose
How to install GitLab using Docker Compose
Congratulations, you have just created your first CI/CD job in GitLab!
+22
View File
@@ -0,0 +1,22 @@
# -- Change GitLab settings here...
external_url 'http://192.168.2.3' # <-- Replace with your GitLab FQDN
# Setting Timezone
gitlab_rails['time_zone'] = 'America/New_York'
# -- (Optional) Change GitLab Shell settings here...
gitlab_rails['gitlab_shell_ssh_port'] = 222
# -- Change internal web service settings here...
letsencrypt['enable'] = false
nginx['listen_port'] = 80
nginx['listen_https'] = false
# EMAIL SMTP Seetings
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "mail.mmcfetridge.net"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "miker@mmcfetridge.net"
gitlab_rails['smtp_password'] = "!Sucyetat123"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
+16
View File
@@ -0,0 +1,16 @@
MYSQL_ROOT_PASSWORD=Lzh8CMp3K0c84n
MYSQL_DATABASE=gitea
MYSQL_USER=gitea
MYSQL_PASSWORD=Lzh8CMp3K0c84n
GITEA_APP_NAME=Gitea
GITEA__database__DB_TYPE=mysql
GITEA__database__HOST=db:3306
GITEA__database__NAME=gitea
GITEA__database__USER=gitea
GITEA__database__PASSWD=VEoE4sTtt8oQqR47rtGkcry4HKYtcOZU
GITEA_INSTANCE_URL=https://gitea.mikemcfetridge.com
GITEA_RUNNER_REGISTRATION_TOKEN=skQ2WOtD22Oy0g
GITEA_RUNNER_NAME=local-runner
GITEA_RUNNER_LABELS=ubuntu-latest:docker://node:16-bullseye,ubuntu-22.04:docker://node:16-bullseye,ubuntu-20.04:docker://node:16-bullseye
+128
View File
@@ -0,0 +1,128 @@
Gitea Install Guide
Okay, let's break down the user's request first. They want me to explain a Docker Compose file and provide installation steps. The provided context shows two different Docker Compose configurations - one for Gitea with MySQL database using standard images, and another for MariaDB with npm-db service.
Hmm, interesting that they're asking about both files though the user didn't explicitly mention which one. Looking at Context 0: It's a Gitea setup file with three services (db, gitea, runner) all in a bridge network called 'gitea'. This seems to be for setting up Git hosting services locally.
Context 1 appears different - it mentions npm-db and MariaDB with volume './data/mysql:/var/lib/mysql', which suggests this might be for Node.js related projects. The user didn't specify which file they're referring to though.
The user's follow-up question is actually quite broad since we don't know exactly which service configuration they need help with. They want both an explanation and installation instructions, but without knowing the exact use case (Git server vs database setup), I can only focus on the first context provided about Gitea.
I should explain that while they requested one docker-compose file, two different configurations were provided in the contexts - one for Git hosting services and another possibly related to npm with MariaDB. Since we don't know which was originally intended, I'll focus on explaining the available information (the Gitea configuration) as much as possible.
The user seems technically proficient enough to handle Docker setups but might be looking for clarification about how specific components interact in this environment. They're likely setting up some development or testing infrastructure and need guidance.
</think>
Okay, here is a technical explanation of the `docker-compose.yml` content provided (Context 0), followed by step-by-step instructions on how to use it.
**Technical Explanation**
This Docker Compose file (`docker-compose.yml`) defines three distinct services within named networks called "gitea":
1. **Database Service (`db`):**
* Uses the official MySQL image version 8.
* Container Name: `gitea-db`
* Restart Policy: `unless-stopped` - The container will automatically restart if it stops, unless explicitly stopped by an administrator command or Docker daemon rules (like on shutdown).
* Environment Variables: Loaded from a `.env` file and sets standard database credentials (`MYSQL_ROOT_PASSWORD`, `MYSQL_DATABASE`, etc.).
* Volumes: Mounts the host's current directory (`./mysql`) into the container's default MySQL data location (`/var/lib/mysql`). This stores the Dockerized database files on your host machine for persistence.
* Networks: Connects to the "gitea" bridge network so other services can communicate with it via its internal name ("db").
* Healthcheck: Uses `mysqladmin ping` command against the local MySQL server (`localhost`) using user and password from environment variables. Checks occur every 10 seconds, wait up to 5s for a response, retry 5 times (total 50s). If it fails, the service is marked unhealthy.
2. **Gitea Service (`gitea`):**
* Uses the official Gitea image from Docker Hub (`gitea/gitea:latest`). This sets up a Git server.
* Container Name: `gitea`
* Restart Policy: `unless-stopped` - Same behavior as the database service regarding automatic restarts.
* Environment Variables: Loaded from `.env`. It requires user ID and group ID (`USER_UID=1000`, `USER_GID=1000`) for proper file ownership within its data volume. The crucial Gitea configuration variables are set here, pointing it to the database server ("db"), specifying the DB type (likely "mysql", loaded from `.env`), and providing credentials (`GITEA__database__...`). It also sets a higher priority port mapping for access.
* Volumes: Mounts two directories on the host:
- `./gitea:/data`: Stores Gitea's application data (repositories, configuration files, logs) in `/data` within the container. Host directory is `./gitea`.
- `/etc/localtime:/etc/localtime:ro`: Makes this container use your host system's timezone setting.
* Networks: Connects to the "gitea" bridge network.
* Depends On: The service definition includes a condition (`service_healthy`) that ensures it waits for the `db` service (named dependency) to pass its health checks before starting. Gitea itself uses an internal healthcheck via `curl`.
* Ports:
- `"3000:3000"`: Exposes Gitea's web UI port from container 3000 to host 3000.
- `"222:22"`: Exposes the SSH server port from container 22 (default for Docker image) to host 222. This allows accessing Git repositories via SSH clients.
3. **Gitea Runner Service (`runner`):**
* Uses a dedicated Gitea CI runner image (`gitea/act_runner:latest`).
* Container Name: `gitea-runner`
* Restart Policy: `unless-stopped`.
* Depends On: Will wait for the `gitea` service (named dependency) to be healthy before starting.
* Environment Variables: Loaded from `.env`. Key variables include Gitea's instance URL (`GITEA_INSTANCE_URL`) and a registration token (`GITEA_RUNNER_REGISTRATION_TOKEN`). It also specifies its name, labels for job routing, and log level (trace). Crucially, it sets the `GITEA_RUNNER_JOB_CONTAINER_NETWORK` to "gitea".
* Volumes: Mounts three directories:
- `./runner-data:/data`: Stores CI artifacts or runner-specific data in a subdirectory of Gitea's main directory.
- `/config.yaml`: This line seems incorrect as provided. Assuming it means mounting the host-side generated configuration file (which is typically done elsewhere) but based on the pattern, it should likely be `- ./runner-config.yaml:/config.yaml`. The `act_runner` *needs* this config file internally, so providing one via volume mount from `./runner-config.yaml` would configure it appropriately. This directory (`./runner-data`) exists and holds persistent data for jobs.
- `/var/run/docker.sock:/var/run/docker.sock`: Mounts the host's Docker socket into this container. The Gitea runner executes CI commands within a separate Docker container (using `act`). Access to the host's Docker socket is necessary for it to perform these actions (`docker run ...`).
**Common Elements:**
* `.env`: Used by multiple services to load environment variables, likely containing secrets and configuration values.
* `gitea` network: A bridge network connecting all three services. They communicate via their internal names (like `db`, `gitea`, `runner`) on this network.
**Purpose:** This setup creates a self-contained local instance of Gitea and its CI runner, with an accompanying MySQL database. It's useful for testing Git functionalities locally or setting up a personal/private Git server without needing to install the software directly on the host OS.
---
**Step-by-Step Installation Guide (Based on Context 0)**
This guide assumes you want to set up Gitea and its runner using Docker Compose with a MySQL database. The instructions are for this specific configuration file structure shown in Context 0.
1. **Prerequisites:**
* Ensure your host machine meets the [requirements](https://docs.gitea.com/installation/requirements) for running Gitea.
* Install [Docker Engine](https://docs.docker.com/engine/install/) and [Docker Compose V2](https://docs.docker.com/compose/v2/) on your system (Windows, macOS, Linux).
* Have a `.env` file ready or create one. This file should contain the necessary environment variables for Gitea and MySQL.
* Example contents of your `.env` file might include:
```
MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_DATABASE=gitea_db_name # Name for the database used by Gitea
MYSQL_USER=mysql_user # Database user (Gitea)
MYSQL_PASSWORD=mysql_password # Password for that user
GITEA_APP_NAME=Gitea_Instance_Name # Can be set here or in .env file, but also might default to image name.
GITEA__database__DB_TYPE=mysql
GITEA__database__HOST=db:3306 # "db" is the internal hostname for the MySQL service (from context)
GITEA__database__NAME=gitea_db_name # Same as MYSQL_DATABASE above, *or* this might override it. Check consistency.
GITEA__database__USER=mysql_user # Same as MYSQL_USER
GITEA__database__PASSWD=mysql_password # Same as MYSQL_PASSWORD
# For the runner (optional if you don't need CI)
GITEA_INSTANCE_URL=http://localhost:3000 # Should match your host mapping for gitea service (typically :3000)
GITEA_RUNNER_REGISTRATION_TOKEN=your_token
```
2. **Prepare the Directory Structure:**
* Create a directory where you want to run this setup.
* Copy both `docker-compose.yml` and `.env` files into that directory from wherever they are located (ensure Context 0's `docker-compose.yml` is used).
* Example structure:
```
/path/to/my/gitea/installation/
├── docker-compose.yml
├── .env
├── gitea/ # Will be created by the first run. Contains Gitea data (repositories, logs)
└── runner-data/ # Will be created by the Gitea runner container when it starts for the first time.
```
* Alternatively, if you are using a single `docker-compose.yml` file from Context 0 and want to manage other services later, ensure your chosen directory is correct.
3. **Start the Services:**
* Open a terminal or command prompt in the directory containing `docker-compose.yml`.
* Run the following command:
```
docker compose up -d
```
This command starts all three defined services (`db`, `gitea`, and `runner`) in detached mode (background).
4. **Verify Service Startup:**
* Check if the database service is healthy first, as it's critical for Gitea:
```
docker compose ps # Lists running containers
docker compose inspect gitea-db | grep -A10 'healthcheck.*Status' # Inspect container details to see health status (requires Docker Compose V2)
```
* Check the logs of all services if necessary for startup errors:
```
docker compose logs # Shows logs from all services
# Or specific one, e.g., `docker compose logs gitea` or `docker compose logs runner`
```
5. **Accessing Gitea:**
* Open a web browser and navigate to `http://localhost:3000`. The default username is `admin`, password is `root`.
* You might see an initial setup page if this is the first run.
**Note:** This configuration maps the SSH port (22 for container) to host 222. Remember that ports below 1024 often require root privileges on Linux systems, but Docker Compose handles these mappings appropriately regardless of OS usually.
+118
View File
@@ -0,0 +1,118 @@
---
networks:
internal:
name: internal
driver: bridge
external:
name: external
driver: bridge
services:
# -------------------------------------------------------------------
# 1. THE REPOSITORY: Gitea Backend
# -------------------------------------------------------------------
db:
image: mysql:8
container_name: gitea-db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
volumes:
- ./mysql:/var/lib/mysql
networks:
- internal
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -u${MYSQL_USER} -p${MYSQL_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
# -------------------------------------------------------------------
# 2. THE REPOSITORY: Gitea Frontend
# -------------------------------------------------------------------
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: unless-stopped
env_file: .env
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__server__SSH_PORT=222
- GITEA__server__SSH_LISTEN_PORT=22
- GITEA__server__SSH_DOMAIN=mygitea.mikemcfetridge.com
- GITEA_APP_NAME=${GITEA_APP_NAME}
- GITEA__database__DB_TYPE=${GITEA__database__DB_TYPE}
- GITEA__database__HOST=${GITEA__database__HOST}
- GITEA__database__NAME=${GITEA__database__NAME}
- GITEA__database__USER=${GITEA__database__USER}
- GITEA__database__PASSWD=${GITEA__database__PASSWD}
depends_on:
db:
condition: service_healthy
ports:
- "3000:3000"
- "222:22"
volumes:
- ./gitea:/data
- /etc/localtime:/etc/localtime:ro
networks:
- internal
- external
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
# -------------------------------------------------------------------
# 3. THE GITEA runner using docker compose
# -------------------------------------------------------------------
runner:
image: gitea/act_runner:latest
container_name: gitea-runner
restart: unless-stopped
depends_on:
gitea:
condition: service_healthy
env_file: .env
environment:
- GITEA_INSTANCE_URL=${GITEA_INSTANCE_URL}
- GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_REGISTRATION_TOKEN}
- GITEA_RUNNER_NAME=${GITEA_RUNNER_NAME}
- GITEA_RUNNER_LABELS=${GITEA_RUNNER_LABELS}
- GITEA_RUNNER_LOG_LEVEL=trace
- GITEA_RUNNER_JOB_CONTAINER_NETWORK=external
volumes:
- ./runner-data:/data
- ./runner-config.yaml:/config.yaml
- /var/run/docker.sock:/var/run/docker.sock
networks:
- internal
- external
# -------------------------------------------------------------------
# 4. THE SECURITY LAYER: Docker Socket Proxy
# -------------------------------------------------------------------
docker-proxy:
image: tecnativa/docker-socket-proxy:latest
container_name: docker_proxy
privileged: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
- NETWORKS=1
- SERVICES=1
- VOLUMES=1
- POST=1 # Allows Semaphore to create/start components
networks:
- external
restart: unless-stopped
+1
View File
@@ -0,0 +1 @@
ADGUARD_PASSWORD=P@ssw0rd
+439
View File
@@ -0,0 +1,439 @@
# icon: si:immich # si for Simple icons https://simpleicons.org/
# icon: sh:immich # sh for selfh.st icons https://selfh.st/icons/
# icon: di:immich # di for Dashboard icons https://github.com/homarr-labs/dashboard-icons
# icon: mdi:camera # mdi for Material Design icons https://pictogrammers.com/library/mdi/
pages:
- name: Home
hide-desktop-navigation: false
center-vertically: true
columns:
- size: small
widgets:
- type: calendar
- type: rss
limit: 10
collapse-after: 3
cache: 3h
feeds:
- url: https://omgubuntu.co.uk/feed
title: OmgUbuntu
limit: 4
- url: https://9to5linux.com/feed/atom
title: 9to5Linux
limit: 4
- type: twitch-channels
channels:
- technotim
- piratesoftware
- size: full
widgets:
- type: group
widgets:
- type: hacker-news
- type: lobsters
- type: search
autofocus: true
search-engine: google
new-tab: true
bangs:
- title: YouTube
shortcut: "!yt"
url: https://www.youtube.com/results?search_query={QUERY}
- title: Github
shortcut: "!gh"
url: https://github.com/search?q={QUERY}&type=repositories
- type: group
widgets:
- type: reddit
subreddit: technology
show-thumbnails: true
- type: reddit
subreddit: selfhosted
show-thumbnails: true
- type: videos
channels:
- UCVls1GmFKf6WlTraIb_IaJg # Distro Tube
- UCjSEJkpGbcZhvo0lr-44X_w # Tech Hut
- UCZNhwA1B5YqiY1nLzmM0ZRg # Christian Lempa
- UCVy16RS5eEDh8anP8j94G2A # DB TEch
- UCwFpzG5MK5Shg_ncAhrgr9g # Awesome Open Source
- UCxQKHvKbmSzGMvUrVtJYnUA # Learn Linux TV
- size: small
widgets:
- type: weather
location: Bealeton, Virginia, United States
units: imperial
hour-format: 12h # alternatively "24h"
- type: custom-api
title: Random Fact
cache: 6h
url: https://uselessfacts.jsph.pl/api/v2/facts/random
template: |
<p class="size-h4 color-paragraph">{{ .JSON.String "text" }}</p>
- type: custom-api
title: Immich stats
cache: 1d
url: http://192.168.2.13:2283/api/server/statistics
headers:
x-api-key: fYDkorU0ik0xOOvfwGiuYtcHWZmggaNYfvHARDTdWo
Accept: application/json
template: |
<div class="flex justify-between text-center">
<div>
<div class="color-highlight size-h3">{{ .JSON.Int "photos" | formatNumber }}</div>
<div class="size-h6">PHOTOS</div>
</div>
<div>
<div class="color-highlight size-h3">{{ .JSON.Int "videos" | formatNumber }}</div>
<div class="size-h6">VIDEOS</div>
</div>
<div>
<div class="color-highlight size-h3">{{ div (.JSON.Int "usage" | toFloat) 1073741824 | toInt | formatNumber }}GB</div>
<div class="size-h6">USAGE</div>
</div>
</div>
- type: releases
show-source-icon: true
repositories:
- go-gitea/gitea
- jellyfin/jellyfin
- glanceapp/glance
- dockerhub:gotify/server
- type: repository
repository: mmcfetridge1969/ansible
pull-requests-limit: 5
issues-limit: 3
commits-limit: 3
- type: repository
repository: ChristianLempa/boilerplates
pull-requests-limit: 5
issues-limit: 3
commits-limit: 3
- name: Monitoring
# Optionally, if you only have a single page you can hide the desktop navigation for a cleaner look
# hide-desktop-navigation: true
columns:
- size: small
widgets:
- type: calendar
- size: full
widgets:
- type: monitor
cache: 1m
title: Services
sites:
- title: Proxmox1
url: https://192.168.2.1:8006
check-url: https://192.168.2.1:8006
allow-insecure: true
icon: di:proxmox
- title: Proxmox2
url: https://192.168.2.2:8006
check-url: https://192.168.2.2:8006
allow-insecure: true
icon: di:proxmox
- title: Jellyfin
url: https://jellyfin.mikemcfetridge.com
check-url: http://192.168.2.16:8096
icon: di:jellyfin
- title: Immich
url: https://immich.mikemcfetridge.com
check-url: http://192.168.2.13:2283/
icon: di:immich
- title: Vaultwarden
url: https://vault.mikemcfetridge.com/
check-url: https://192.168.2.19:8000/
allow-insecure: true
icon: di:vaultwarden-light
- title: NGINX Proxy Manager
url: https://proxy.mikemcfetridge.com/
check-url: http://192.168.2.22:81/
icon: di:nginx-proxy-manager
- title: Wireguard
url: https://wg2.mikemcfetridge.com/
check-url: http://192.168.2.10:10086
icon: di:wireguard
- title: Gitea
url: https://gitea.mikemcfetridge.com/
check-url: http://192.168.2.24:3000/
icon: di:gitea
- title: IT-Tools
url: https://ittools.mikemcfetridge.com/
check-url: http://192.168.2.7:8089/
icon: di:it-tools
- title: Mealie
url: https://mealie.mikemcfetridge.com/
check-url: http://192.168.2.7:9925/
icon: di:mealie
- title: Wallabag
url: https://wall.mikemcfetridge.com
check-url: http://192.168.2.13:8667/
icon: di:wallabag
- title: Pi-Hole
url: http://192.168.2.8/admin
check-url: http://192.168.2.8/admin
icon: di:pi-hole
- title: Immich
url: https://immich.mikemcfetridge.com
check-url: http://192.168.2.13:2283/
icon: di:immich
- title: Searxng
url: https://search.mikemcfetridge.com
check-url: http://192.168.2.23:8888/
icon: di:searxng
- title: Authentik
url: https://authentik.mikemcfetridge.com
check-url: https://192.168.2.7:9443
allow-insecure: true
icon: di:authentik
- title: Portainer-1
url: https://port.mikemcfetridge.com
check-url: https://192.168.2.7:9445
allow-insecure: true
icon: di:portainer
- title: Portainer-2
url: https://192.168.2.13:9445
check-url: https://192.168.2.13:9445
allow-insecure: true
icon: di:portainer
- title: Tianji
url: https://tianji.mikemcfetridge.com/login
check-url: http://192.168.2.7:12345
allow-insecure: true
icon: di:tianji
- title: Technitium DNS
url: http://192.168.2.9:5380/
check-url: http://192.168.2.9:5380/
allow-insecure: true
icon: sh:technitium
- type: monitor
cache: 1m
title: Servarr
sites:
- title: Jellyseerr
url: http://192.168.2.16:5055
check-url: http://192.168.2.16:5055
icon: di:jellyseerr
- title: Homarr
url: https://dashboard.mikemcfetridge.com/
check-url: http://192.168.2.7:7575/
icon: di:homarr
- title: Radarr
url: http://192.168.2.16:7878
check-url: http://192.168.2.16:7878
icon: di:radarr
- title: Sonarr
url: http://192.168.2.16:8989
check-url: http://192.168.2.16:8989
icon: di:sonarr
- title: Lidarr
url: http://192.168.2.16:8686
check-url: http://192.168.2.16:8686
icon: di:lidarr
- title: Bazarr
url: http://192.168.2.16:6767
check-url: http://192.168.2.16:6767
icon: di:bazarr
- title: Prowlarr
url: http://192.168.2.16:9696
check-url: http://192.168.2.16:9696
icon: di:prowlarr
- title: qBittorrent
url: http://192.168.2.16:8118
check-url: http://192.168.2.16:8118
icon: di:qbittorrent
- title: Audio Book Shelf
url: https://audio.mikemcfetridge.com
check-url: http://192.168.2.16:13378
icon: di:audiobookshelf
- size: small
widgets:
- type: rss
limit: 10
collapse-after: 3
cache: 3h
feeds:
- url: https://omgubuntu.co.uk/feed
title: OmgUbuntu
limit: 4
- url: https://9to5linux.com/feed/atom
title: 9to5Linux
limit: 4
- name: Widget testing
# Optionally, if you only have a single page you can hide the desktop navigation for a cleaner look
# hide-desktop-navigation: true
columns:
- size: small
widgets:
- type: calendar
- size: full
widgets:
- type: custom-api
title: Netbird Devices
title-url: https://app.netbird.io/peers
url: https://api.netbird.io/api/peers
headers:
Accept: application/json
Authorization: Token ${nbp_bz2jNZN9MnkMErrBi8jFjrNsweZuY108oYSo}
cache: 10m
template: |
{{ $enableOnlineIndicator := false }}
<style>
.device-info-container {
position: relative;
overflow: hidden;
height: 1.5em;
}
.device-info {
display: flex;
transition: transform 0.2s ease, opacity 0.2s ease;
}
.device-ip {
position: absolute;
top: 0;
left: 0;
transform: translateY(-100%);
opacity: 0;
transition: transform 0.2s ease, opacity 0.2s ease;
}
.device-info-container:hover .device-info {
transform: translateY(100%);
opacity: 0;
}
.device-info-container:hover .device-ip {
transform: translateY(0);
opacity: 1;
}
.offline-indicator,
.online-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
display: inline-block;
margin-left: 4px;
vertical-align: middle;
}
.online-indicator {
background-color: var(--color-positive);
}
.offline-indicator {
background-color: var(--color-negative);
}
.device-name-container {
display: flex;
align-items: center;
gap: 8px;
}
.indicators-container {
display: flex;
align-items: center;
gap: 4px;
}
</style>
<ul class="list list-gap-10 collapsible-container" data-collapse-after="4">
{{ range .JSON.Array "" }}
<li>
<div class="flex items-center gap-10">
<div class="device-name-container grow">
<span class="size-h4 block text-truncate color-primary">
{{ .String "hostname" }}
</span>
<div class="indicators-container">
{{ if .Bool "connected" }}
{{ if $enableOnlineIndicator }}
<span class="online-indicator" data-popover-type="text" data-popover-text="Online"></span>
{{ end }}
{{ else }}
{{ $lastSeen := .String "last_seen" | parseTime "rfc3339" }}
<span class="offline-indicator" data-popover-type="text" data-popover-text="Offline - Last seen {{ $lastSeen.Format "Jan 2 3:04pm" }}"></span>
{{ end }}
</div>
</div>
</div>
<div class="device-info-container">
<ul class="list-horizontal-text device-info">
<li>{{ .String "os" }}</li>
<li>{{ .String "city_name" }}, {{ .String "country_code"}}</li>
</ul>
<div class="device-ip">
{{ .String "ip" }}
{{ .String "dns_label"}}
</div>
</div>
</li>
{{ end }}
</ul>
- size: small
widgets:
- type: rss
limit: 10
collapse-after: 3
cache: 3h
feeds:
- url: https://omgubuntu.co.uk/feed
title: OmgUbuntu
limit: 4
- url: https://9to5linux.com/feed/atom
title: 9to5Linux
limit: 4
+17
View File
@@ -0,0 +1,17 @@
services:
glance:
image: glanceapp/glance # Uses the official Glance Docker image.
container_name: glance # Assigns a custom container name for easy management.
volumes:
- /home/miker/dockerapps/glance/config:/app/config # Mounts the glance.yml configuration file.
- /etc/timezone:/etc/timezone:ro # Ensures container timezone sync.
- /etc/localtime:/etc/localtime:ro # Ensures container localtime sync.
ports:
- 8280:8080 # Exposes Glance on port 8280.
restart: unless-stopped # Restarts container unless manually stopped.
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8280"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
+18
View File
@@ -0,0 +1,18 @@
services:
gotify:
image: gotify/server
container_name: gotify
volumes:
- /home/miker/dockerapps/gotify:/app/data
restart: unless-stopped
# ports:
# - '8091:80'
security_opt:
- no-new-privileges:true
networks:
proxy:
environment:
- TZ=America/New_York
networks:
proxy:
external: true
+4
View File
@@ -0,0 +1,4 @@
PUID=1000
PGID=1000
# TZ for container timezone
TZ=America/New_York
+22
View File
@@ -0,0 +1,22 @@
---
services:
heimdall:
image: lscr.io/linuxserver/heimdall:2.6.1
container_name: heimdall
environment:
PUID: ${PUID} # Reference PUID from .env
PGID: ${PGID} # Reference PGID from .env
env_file:
- .env
volumes:
- ./heimdall/config:/config
ports:
- 8080:80
- 8443:443
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
+20
View File
@@ -0,0 +1,20 @@
services:
# Heimdall - Application Dashboard
heimdall:
image: lscr.io/linuxserver/heimdall:latest
container_name: heimdall
security_opt:
- no-new-privileges:true
restart: unless-stopped
profiles: ["apps", "all"]
networks:
- default
ports:
- "$HEIMDALL_PORT:80"
volumes:
- $DOCKERDIR/appdata/heimdall:/config
environment:
PUID: $PUID
PGID: $PGID
TZ: $TZ
# DOCKER-LABELS-PLACEHOLDER
+39
View File
@@ -0,0 +1,39 @@
Hestia Control Panel Setup
** 1. Change to sudo **
sudo su -
** 2. Get the install script **
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
** 3. Important - CHANGE THE NEXT LINE TO USE YOUR OWN DETAILS, recommend using a subdomain like 'hcp' for your panel as I've done here **
bash hst-install.sh --interactive no --email admin@mcfetridge.us --password S>>>>>>>>123 --hostname hcp.mcfetridge.us -f
** Make sure to capture this information
Ready to get started? Log in using the following credentials:
Admin URL: https://hcp.mcfetridge.us:8083
Backup URL: https://129.213.145.20:8083
Username: admin
Password: The password you chose during installation. My Default = S>>>>>>>>123
Sendblue SMTP key for HCP: xsmtpsib-1d075358c732f0ae42994d033cd552a43b867e08ddf1057f2414dec226c34ecc-UP2QRnLwmZvB7N3V
SMTP Server: smtp-relay.brevo.com
Port: 587
Login: mmcfetridg@aol.com
Password: Is the smtp key generated.
For a smoother setup you can point the subdomain for your hostname over to the Oracle public IP address. In our video we used Namecheap, but all domain hosts will have a similar setup.
After installing, the ports youll need to add to your ingress rules are here:
8083,80,443,143,993,110,995,25,465,587
Blog: https://ideaspot.com.au/blog/cloudflare-hestia-setup/
YouTube: https://www.youtube.com/watch?v=BK7qyPa-VmI
+4
View File
@@ -0,0 +1,4 @@
PUID=1000
PGID=1000
# TZ for container timezone
TZ=America/New_York
@@ -0,0 +1,3 @@
---
+516
View File
@@ -0,0 +1,516 @@
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:opsz@9..40&family=Fira+Code&family=Poppins&family=Source+Code+Pro&family=Work+Sans&display=swap');
.theme-gray {
font-family: 'DM Sans', sans-serif;
/* DRACULA COLORS */
--dracula-background: #282a36;
--dracula-background-dark: #15161d;
--dracula-foreground: #44475a;
--dracula-text: #f8f8f2;
--dracula-slate: #6272a4;
--dracula-cyan: #8be9fd;
--dracula-green: #50fa7ae8;
--dracula-orange: #ffb86c;
--dracula-pink: #ff79c6;
--dracula-purple: #bd93f9;
--dracula-red: #ff5555;
--dracula-yellow: #f1fa8c;
/* Theme preset colors */
--color-50: 249 250 251;
--color-100: 243 244 246;
--color-200: 248 248 242; /* Text Color - use Dracula text color */
--color-300: 209 213 219;
--color-400: 156 163 175;
--color-500: 107 114 128;
--color-600: 75 85 99;
--color-700: 55 65 81;
--color-800: 40 42 54; /* Background color - use Dracula theme color */
--color-900: 21 22 29; /* Dracula specific */
--color-logo-start: 156 163 175;
--color-logo-stop: 55 65 81;
--standard-bg: #44475a8e;
/* INFO WIDGET COLORS */
--info-widgets: var(--dracula-purple);
--resource-bar-bg: var(--standard-bg);
--resource-bar-fg: var(--dracula-green);
--widget-border: var(--dracula-foreground);
/* SERVICES COLORS */
--service-group: var(--dracula-purple);
--service-name: var(--dracula-text);
--service-description: var(--dracula-purple);
--service-block-bg: #232530;
--service-block-text: var(--dracula-pink);
/* BOOKMARKS COLORS */
--bookmark-group: var(--dracula-purple);
--bookmark-icon-bg: #44475a60;
--bookmark-icon: var(--dracula-purple);
--bookmark-name: var(--dracula-text);
/* ALL CARD COLORS */
--card-color: #44475a46;
--card-color-hover: #44475a91;
/* FOOTER COLORS */
--footer-items: var(--dracula-pink);
/* FOOTER COLORS */
--scrollbar-fg: var(--dracula-purple);
--scrollbar-bg: var(--standard-bg);
/*Class color values */
.service-tags .dark\:bg-theme-900\/50 {
background-color: rgb(var(--color-900) / 0.3) !important;
}
/*******************************
* INFORMATION WIDGETS STYLES *
*******************************/
#information-widgets {
border-color: var(--widget-border);
}
#information-widgets * {
color: var(--info-widgets);
}
.resource-usage {
background-color: var(--resource-bar-bg);
}
.resource-usage > div {
background-color: var(--resource-bar-fg);
}
/*******************************
* SERVICES STYLES *
*******************************/
.service-group-icon > div {
background: var(--service-group) !important; /* group label ICON color */
}
.service-group-name {
color: var(--service-group); /* group label NAME color */
}
.services-group > button > svg {
color: var(--service-group); /* group label EXPAND/COLLAPSE ICON color */
}
.service-card {
background-color: var(--card-color);
}
.service-card:hover {
background-color: var(--card-color-hover);
}
.service-name.text-sm {
font-size: 0.95rem;
color: var(--service-name);
}
.service-description.text-xs {
font-size: 0.75rem;
color: var(--service-description);
}
.service img {
border-radius: 25%;
}
.service-block {
background: var(--service-block-bg);
}
.service-block .uppercase {
color: var(--service-block-text);
}
.service-block .font-thin {
color: var(--dracula-text);
}
/*******************************
* BOOKMARK STYLES *
*******************************/
.bookmark-group-name {
color: var(--bookmark-group);
}
.bookmark-icon {
background-color: var(--bookmark-icon-bg) !important;
}
.bookmark-icon > div > div {
background: var(
--bookmark-icon
) !important; /* If using si or md icons, make default purple */
}
.bookmark-name.text-xs {
font-size: 0.85rem;
color: var(--bookmark-name);
}
li.bookmark > a {
background-color: var(--card-color);
}
li.bookmark > a:hover {
background-color: var(--card-color-hover);
}
/*******************************
* CALENDAR STYLES *
*******************************/
#dracula-calendar .flex.justify-between.flex-wrap span {
color: var(--dracula-purple);
}
/*******************************
* FOOTER STYLES *
*******************************/
#footer svg {
color: var(--footer-items);
}
/*******************************
* SCROLLBAR STYLES *
*******************************/
* {
--scrollbar-thumb: var(--scrollbar-fg);
--scrollbar-track: var(--scrollbar-bg);
}
/*******************************
* GLANCES STYLES *
*******************************/
li[id^='glances-'] .recharts-surface > g:nth-of-type(1) path:nth-child(1) {
fill: var(--dracula-green);
fill-opacity: 0.15;
}
li[id^='glances-'] .recharts-surface g:nth-of-type(1) path:nth-child(2) {
stroke: var(--dracula-green);
stroke-opacity: 0.5;
}
li[id^='glances-'] .recharts-surface g:nth-of-type(2) path:nth-child(1) {
fill: var(--dracula-purple);
fill-opacity: 0.15;
}
li[id^='glances-'] .recharts-surface g:nth-of-type(2) path:nth-child(2) {
stroke: var(--dracula-purple);
stroke-opacity: 0.5;
}
li[id^='glances-'] .bottom-3.left-3 {
color: var(--dracula-pink);
}
li[id^='glances-'] .bottom-3.right-3 .opacity-75 {
color: var(--dracula-cyan);
opacity: 1;
font-size: 0.8rem;
}
li[id^='glances-'] .top-3.right-3 .opacity-50 {
color: var(--dracula-cyan);
opacity: 1;
font-size: 0.8rem;
}
li[id^='glances-'] .opacity-50 {
opacity: 0.8;
}
li[id^='glances-'] .flex.items-center.text-xs .text-right {
color: var(--dracula-cyan);
}
li[id^='glances-'] .flex.items-center .opacity-25.w-14.text-right {
color: var(--dracula-purple);
opacity: 0.85;
}
li[id^='glances-']
.bottom-4.right-3.left-3.z-20
.w-3.h-3.mr-1\.5.opacity-50
> div {
background: var(--dracula-green) !important;
opacity: 1;
}
li[id^='glances-'] .bottom-4.right-3.left-3.z-20 .opacity-75.grow {
color: var(--dracula-pink) !important;
opacity: 0.75;
}
/*******************************
* HOMEPAGE PRESETS *
*******************************/
.bg-amber-500 {
background-color: var(--dracula-orange);
}
.bg-black {
background-color: rgb(0 0 0);
}
.bg-blue-500 {
background-color: var(--dracula-cyan);
}
.bg-cyan-500 {
background-color: var(--dracula-cyan);
}
.bg-emerald-500 {
background-color: var(--dracula-green);
}
.bg-fuchsia-500 {
background-color: var(--dracula-pink);
}
.bg-gray-500 {
background-color: var(--dracula-foreground);
}
.bg-green-500 {
background-color: var(--dracula-green);
}
.bg-indigo-500 {
background-color: var(--dracula-purple);
}
.bg-lime-500 {
background-color: var(--dracula-green);
}
.bg-neutral-500 {
background-color: rgb(115 115 115);
}
.bg-orange-400 {
background-color: var(--dracula-orange);
}
.bg-orange-500 {
background-color: var(--dracula-orange);
}
.bg-pink-500 {
background-color: var(--dracula-pink);
}
.bg-purple-500 {
background-color: var(--dracula-purple);
}
.bg-red-500 {
background-color: var(--dracula-red);
}
.bg-rose-100 {
background-color: rgb(255, 205, 205);
}
.bg-rose-500 {
background-color: var(--dracula-red);
}
.bg-rose-900\/80 {
background-color: var(--dracula-red);
}
.bg-sky-500 {
background-color: var(--dracula-cyan);
}
.bg-slate-500 {
background-color: var(--dracula-slate);
}
.bg-stone-500 {
background-color: rgb(120 113 108);
}
.bg-teal-500 {
background-color: rgb(20 184 166);
}
.bg-violet-500 {
background-color: var(--dracula-purple);
}
.bg-white {
background-color: var(--dracula-text);
}
.bg-white\/50 {
background-color: hsla(0, 0%, 100%, 0.5);
}
.bg-yellow-500 {
background-color: var(--dracula-yellow);
}
.bg-zinc-500 {
background-color: rgb(113 113 122);
}
.text-amber-800 {
color: var(--dracula-orange);
}
.text-black {
color: rgb(0 0 0);
}
.text-black\/20 {
color: rgba(0, 0, 0, 0.2);
}
.text-blue-500\/80 {
color: rgba(139, 233, 253, 0.8);
}
.text-emerald-300 {
color: var(--dracula-green);
}
.text-emerald-500\/80 {
color: rgba(80, 250, 123, 0.8);
}
.text-gray-500 {
color: rgb(107 114 128);
}
.text-green-500 {
color: var(--dracula-green);
}
.text-orange-400\/50 {
color: rgba(255, 184, 108, 0.5);
}
.text-red-400 {
color: var(--dracula-red);
}
.text-red-500 {
color: var(--dracula-red);
}
.text-red-500\/40 {
color: rgba(255, 85, 85, 0.4);
}
.text-rose-300 {
color: var(--dracula-red);
}
.text-rose-500 {
color: var(--dracula-red);
}
.text-rose-500\/80 {
color: rgba(255, 85, 85, 0.8);
}
.text-rose-900 {
color: var(--dracula-red);
}
.text-white {
color: var(--dracula-text);
}
}
/* ********************************************************************************************* */
/* CARD COLOURING - DONE VIA "ID:" TAGS IN SERVICES.YAML */
.service-card::before {
content: "";
opacity: 0.40;
position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 0;
}
/* DARK */
#red .dark\:hover\:bg-white\/10:is(.dark *).service-card::before { background-color: #812020; }
#yellow .dark\:hover\:bg-white\/10:is(.dark *).service-card::before { background-color: #818120; }
#green .dark\:hover\:bg-white\/10:is(.dark *).service-card::before { background-color: #208120; }
#cyan .dark\:hover\:bg-white\/10:is(.dark *).service-card::before { background-color: #208181; }
#blue .dark\:hover\:bg-white\/10:is(.dark *).service-card::before { background-color: #202081; }
#purple .dark\:hover\:bg-white\/10:is(.dark *).service-card::before { background-color: #812081; }
#black .dark\:hover\:bg-white\/10:is(.dark *).service-card::before { background-color: #000000; }
#white .dark\:hover\:bg-white\/10:is(.dark *).service-card::before { background-color: #ffffff; }
/* LIGHT */
#red .hover\:bg-theme-300\/20.service-card::before { background-color: #ff0000; }
#yellow .hover\:bg-theme-300\/20.service-card::before { background-color: #ffff00; }
#green .hover\:bg-theme-300\/20.service-card::before { background-color: #00ff00; }
#cyan .hover\:bg-theme-300\/20.service-card::before { background-color: #00ffff; }
#blue .hover\:bg-theme-300\/20.service-card::before { background-color: #0000ff; }
#purple .hover\:bg-theme-300\/20.service-card::before { background-color: #ff00ff; }
#black .hover\:bg-theme-300\/20.service-card::before { background-color: #ffffff; }
#white .hover\:bg-theme-300\/20.service-card::before { background-color: #000000; }
#orange .hover\:bg-theme-300\/20.service-card::before { background-color: #ffa500; }
#pink .hover\:bg-theme-300\/20.service-card::before { background-color: #ffc0cb; }
#teal .hover\:bg-theme-300\/20.service-card::before { background-color: #008080; }
#magenta .hover\:bg-theme-300\/20.service-card::before { background-color: #ff00ff; }
#lime .hover\:bg-theme-300\/20.service-card::before { background-color: #00ff00; }
#navy .hover\:bg-theme-300\/20.service-card::before { background-color: #000080; }
#maroon .hover\:bg-theme-300\/20.service-card::before { background-color: #800000; }
#olive .hover\:bg-theme-300\/20.service-card::before { background-color: #808000; }
#silver .hover\:bg-theme-300\/20.service-card::before { background-color: #c0c0c0; }
#gray .hover\:bg-theme-300\/20.service-card::before { background-color: #808080; }
#gold .hover\:bg-theme-300\/20.service-card::before { background-color: #ffd700; }
#coral .hover\:bg-theme-300\/20.service-card::before { background-color: #ff7f50; }
#salmon .hover\:bg-theme-300\/20.service-card::before { background-color: #fa8072; }
#indigo .hover\:bg-theme-300\/20.service-card::before { background-color: #4b0082; }
#violet .hover\:bg-theme-300\/20.service-card::before { background-color: #ee82ee; }
#turquoise .hover\:bg-theme-300\/20.service-card::before { background-color: #40e0d0; }
#plum .hover\:bg-theme-300\/20.service-card::before { background-color: #dda0dd; }
#orchid .hover\:bg-theme-300\/20.service-card::before { background-color: #da70d6; }
#tan .hover\:bg-theme-300\/20.service-card::before { background-color: #d2b48c; }
#beige .hover\:bg-theme-300\/20.service-card::before { background-color: #f5f5dc; }
#mint .hover\:bg-theme-300\/20.service-card::before { background-color: #98ff98; }
#lavender .hover\:bg-theme-300\/20.service-card::before { background-color: #e6e6fa; }
#chocolate .hover\:bg-theme-300\/20.service-card::before { background-color: #d2691e; }
#crimson .hover\:bg-theme-300\/20.service-card::before { background-color: #dc143c; }
#khaki .hover\:bg-theme-300\/20.service-card::before { background-color: #f0e68c; }
#aqua .hover\:bg-theme-300\/20.service-card::before { background-color: #00ffff; }
#azure .hover\:bg-theme-300\/20.service-card::before { background-color: #f0ffff; }
#bisque .hover\:bg-theme-300\/20.service-card::before { background-color: #ffe4c4; }
#bronze .hover\:bg-theme-300\/20.service-card::before { background-color: #cd7f32; }
#charcoal .hover\:bg-theme-300\/20.service-card::before { background-color: #36454f; }
#emerald .hover\:bg-theme-300\/20.service-card::before { background-color: #50c878; }
#ivory .hover\:bg-theme-300\/20.service-card::before { background-color: #fffff0; }
#jade .hover\:bg-theme-300\/20.service-card::before { background-color: #00a86b; }
#peach .hover\:bg-theme-300\/20.service-card::before { background-color: #ffe5b4; }
#rose .hover\:bg-theme-300\/20.service-card::before { background-color: #ff007f; }
#ruby .hover\:bg-theme-300\/20.service-card::before { background-color: #e0115f; }
#sapphire .hover\:bg-theme-300\/20.service-card::before { background-color: #0f52ba; }
#sepia .hover\:bg-theme-300\/20.service-card::before { background-color: #704214; }
#steel .hover\:bg-theme-300\/20.service-card::before { background-color: #4682b4; }
#amber .hover\:bg-theme-300\/20.service-card::before { background-color: #ffbf00; }
#cerulean .hover\:bg-theme-300\/20.service-card::before { background-color: #007ba7; }
#periwinkle .hover\:bg-theme-300\/20.service-card::before { background-color: #ccccff; }
#scarlet .hover\:bg-theme-300\/20.service-card::before { background-color: #ff2400; }
#slate .hover\:bg-theme-300\/20.service-card::before { background-color: #708090; }
@@ -0,0 +1,10 @@
---
# For configuration options and examples, please see:
# https://gethomepage.dev/configs/docker/
# my-docker:
# host: 127.0.0.1
# port: 2375
# my-docker:
# socket: /var/run/docker.sock
@@ -0,0 +1,2 @@
---
# sample kubernetes config
@@ -0,0 +1,5 @@
---
# pve:
# url: https://proxmox.host.or.ip:8006
# token: username@pam!Token ID
# secret: secret
@@ -0,0 +1,341 @@
---
######################################### HOME TAB SERVICES ######################################################################
- Infrastructure:
- Proxmox 1:
id: blue
tab: Home
href: https://192.168.2.1:8006
icon: proxmox.png
description: Virtual Server 1
widget:
type: proxmox
url: https://192.168.2.1:8006
username: api@pam!homepage
password: faca2bd5-e6df-4192-85ce-928fccde4623
node: pve
fields: ["vms", "lxc", "resources.cpu", "resources.mem"]
- Proxmox 2:
id: yellow
tab: Home
href: https://192.168.2.2:8006
icon: proxmox.png
description: Virtual Server 2
widget:
type: proxmox
url: https://192.168.2.2:8006
username: api@pam!homepage
password: 1b2fa246-a994-4f93-ab4d-1c91a4aea614
node: pve
fields: ["vms", "lxc", "resources.cpu", "resources.mem"]
- Authentik:
id: red
tab: Home
href: https://auth.mikemcfetridge.com
icon: authentik.png
description: Authentik SSO
widget:
type: authentik
url: https://192.168.2.3:9543
key: NW5ldUK8qDRY91ny67dE6ckWCMXThF9nwj6EZw7pKbS5FzXx5wouAo4sC19n
version: 2
- Dockhand:
id: cyan
tab: Home
href: http://192.168.2.3:3200
icon: dockhand.png
description: Dockhand
widget:
type: dockhand
url: http://192.168.2.3:3200
username: mmcfetridge
password: "!Sucyetat123"
- Applications:
- OwnCloud:
id: purple
tab: Home
icon: owncloud.png
href: https://owncloud.mcfetridge.us
description: File Sync & Share
- Immich:
id: white
tab: Home
href: https://immich.mikemcfetridge.com
icon: immich.png
description: Photos Server
widget:
type: immich
url: http://192.168.2.3:2283
key: "MLbcal27A67J6FZV1PIb3AdMsRf8xZC1uruOLB7js"
fields: ["users", "photos", "storage"]
version: 2
- Trilium:
id: gold
tab: Home
href: http://192.168.2.3:8180
icon: trilium.png
description: Trilium Server
widget:
type: trilium
url: http://192.168.2.3:8180
key: "Z0qLO33tMHgy_c0nq/pZAJMR/8Em5xrwOEJ6EfiyNEWkMurMSnRdVdtM="
- Forgejo:
id: green
tab: Home
href: https://forgejo.mikemcfetridge.com
icon: forgejo.png
description: Forgejo Git & CICD
- MySpeed:
id: lime
tab: Home
icon: myspeed.png
href: http://192.168.2.3:5216
widget:
type: myspeed
url: http://192.168.2.3:5216
password: "!Sucyetat123" # only required if password is set
- mealie:
id: cobalt
tab: Home
icon: mealie.png
href: http://192.168.2.7:9000/
widget:
type: mealie
url: http://192.168.2.7:9000
key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb25nX3Rva2VuIjp0cnVlLCJpZCI6IjVlYzIwNTk2LTEyY2QtNDFkMS05MTc5LWUzOWFkYjk3OWE2MyIsIm5hbWUiOiJob21lcGFnZSIsImludGVncmF0aW9uX2lkIjoiZ2VuZXJpYyIsImV4cCI6MTkzNjU0MzE3N30.C1PWK51JOpmzHwR9zmlvVShWC7sasKv0aO6PS47LQqo
version: 2 # only required if version > 1, defaults to 1
############################################## MEDIA TAB Services ###########################################################
- Media downloader:
- Calendar:
id: gray
tab: Media
name: Calendar
widget:
type: calendar
view: agenda
maxEvents: 6
firstDayInWeek: sunday
integrations:
- type: sonarr
service_group: Media downloader
service_name: Sonarr
- type: radarr
service_group: Media downloader
service_name: Radarr
- Sonarr:
id: crimson
tab: Media
href: http://192.168.2.16:8989
icon: sonarr.png
description: TV Show Service
widget:
type: sonarr
url: http://192.168.2.16:8989
key: 8746f486831545e3b6c9014657ac9c11
fields: ["wanted", "queued", "series"]
- Radarr:
id: lavender
tab: Media
href: http://192.168.2.16:7878
icon: radarr.png
description: Movie Service
widget:
type: radarr
url: http://192.168.2.16:7878
key: ee95503f6fca4cf7b9c8c3f3fc45df39
fields: ["wanted", "missing", "queued", "movies"]
- Qbittorrent:
id: teal
tab: Media
href: http://192.168.2.16:8118
icon: qbittorrent.png
description: Download Client
widget:
type: qbittorrent
url: http://192.168.2.16:8118
username: admin
password: "!Sucyetat123"
- Media Apps:
- Jellyfin:
id: violet
tab: Media
href: http://192.168.2.16:8096
icon: jellyfin.png
description: Movies & TV Shows
widget:
type: jellyfin
url: http://192.168.2.16:8096
key: 617cc65c15da4b3eaac10568c25a8c36
enableBlocks: true
enableNowPlaying: true
- Jellyseerr:
id: aqua
tab: Media
href: http://192.168.2.16:5055
icon: jellyseerr.png
description: Movie/show Database
widget:
type: jellyseerr
url: http://192.168.2.16:5055
key: MTc1NDI2NTczOTQyMDA2ODRjOWY0LWJmZmEtNGE1OC05MzM2LTAwMDM4OWRmYmQ3Yg==
fields: ["pending", "approved", "available"]
- Navidrome:
id: navy
tab: Media
icon: navidrome.png
href: http://192.168.2.16:4533
widget:
type: navidrome
url: http://192.168.2.16:4533
user: mmcfetridge
token: 05dee16046666bb05d98291b9c6e39d3
salt: 50c05a
- AudioBookShelf:
id: beige
tab: Media
href: http://192.168.2.16:13378
icon: audiobookshelf.png
description: Index Server
widget:
type: audiobookshelf
url: http://192.168.2.16:13378
key: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI4MDQ5Y2U4Mi0xZjlmLTRiYTEtOWY3Zi03N2U4YmRiYjg0OGEiLCJ1c2VybmFtZSI6Im1tY2ZldHJpZGdlIiwiaWF0IjoxNzQ4MTk4NzUyfQ.Tey3wxo61euuJEwc2ziE_PukdOUz7pNZKG8SmOdWB-c"
fields: ["podcasts", "books"]
##################################### Network & System TAB Services ##############################################################
- Network:
- Pi-hole:
id: slate
tab: Network
href: http://192.168.2.8/admin/login
icon: pi-hole.png
widget:
type: pihole
url: http://192.168.2.8
version: 6
key: "!Sucyetat123"
fields: ["queries", "blocked", "blocked_percent", "gravity"]
- Technitium:
id: burgundy
tab: Network
href: http://192.168.2.9:5380
icon: technitium.png
description: Technitium DNS Server
widget:
type: technitium
url: http://192.168.2.9:5380
key: 03348d06cd472fbd091d8232b1c13321ff70a8628dad7b0c23dd4512a18fb34b
range: LastDay
fields: ["totalQueries", "totalAuthoritative", "totalCached", "totalServerFailure"]
- Proxy Manager:
id: emerald
tab: Network
href: http://192.168.2.3:81
icon: nginx-proxy-manager.png
description: Nginx Proxy Manager
widget:
type: npm
url: http://192.168.2.3:81
username: mmcfetridg@aol.com
password: "!Sucyetat123"
fields: ["enabled", "disabled", "total"]
- Pangolin:
id: salmon
tab: Network
icon: pangolin.png
href: https://pangolin.mmcfetridge.net
description: External network
widget:
type: pangolin
url: https://api.mmcfetridge.net/v1
key: "2o4g9gak61mig2i.5s5yxu4o2ek7haepzumar2ldl4mmzqpbrcfnpqdf"
org: homelab
- Systems:
- Gluetun:
id: jade
tab: System
href: http://192.168.2.16:8000
icon: gluetun.png
description: Media VPN Server
widget:
type: gluetun
url: http://192.168.2.16:8000
fields: ["public_ip", "region", "country"]
- Public IP:
icon: mdi-web
href: https://whatismyipaddress.com/
widget:
type: customapi
url: https://api.ipify.org?format=json
refreshInterval: 3600000 # Refreshes once an hour (in milliseconds)
method: GET
mappings:
- field: ip
label: WAN IP
format: text
############################################## Bookmark TAB Services #############################################################
- Bookmarks:
- Github:
id: indigo
tab: Bookmarks
abbr: GH
href: https://github.com
icon: github-light.png
description: GitHub
- Linkwarden:
id: charcoal
tab: Bookmarks
href: https://lw.mikemcfetridge.com
icon: linkwarden.png
description: Web Bookmarker
widget:
type: linkwarden
url: http://192.168.2.12:3000
key: "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..ZLJgig_ol-n3i1tv.vhWCnMSHVd81bdidL85-imXKpxGC0U3mHlvmkQyIJqJvcFRRJVBAasw9C0cmfSXVPq08HT-B-3zUAmftnPRymPHMJCkfo8pv_XBbEPneIFH-n59_dg26.qcXSK2REP3M_Vdgp0aOqcA"
fields: ["links", "collections"]
- Semaphore:
id: cerulean
tab: Bookmarks
icon: semaphore.png
href: http://192.168.2.11:3000
description: CI/CD Automation
- Wg-Easy:
id: rose
tab: Bookmarks
icon: wireguard.png
href: http://192.168.2.3:10086
description: Wireguard VPN
- YouTube:
id: coral
tab: Bookmarks
icon: youtube.png
href: https://youtube.com/
description: Video Platform
@@ -0,0 +1,55 @@
---
title: Miker's Homepage
description: Here is my awesome homepage
background:
image: https://backiee.com/static/wallpapers/1000x563/412861.webp
blur: sm
saturate: 50
brightness: 75
opacity: 75
theme: dark
color: slate
layout:
Infrastructure:
icon: mdi-folder-network
tab: Home
header: true
columns: 3
Applications:
icon: mdi-application
tab: Home
header: true
columns: 3
Media downloader:
icon: mdi-multimedia
tab: Media
header: true
columns: 3
Media Apps:
icon: mdi-movie
tab: Media
header: true
columns: 3
Network:
tab: System
icon: mdi-switch
header: true
columns: 3
Systems:
tab: System
icon: mdi-television
header: true
columns: 3
Bookmarks:
tab: Bookmarks
icon: mdi-baby
style: row
columns: 4
fiveColumns: true
useEqualHeights: true
showStats: true
@@ -0,0 +1,42 @@
# Homepage Widgets Configuration
# Organized by System, Environment, and Search
- logo:
icon: wireguard.svg # optional
- resources:
cpu: true
memory: true
disk: /
cputemp: true
tempmin: 0
tempmax: 100
uptime: true
units: imperial
refresh: 3000
diskUnits: bytes
network: true
- openmeteo:
label: Bealeton
latitude: 38.5718
longitude: -77.7639
timezone: America/New_York
units: imperial
cache: 5
format:
maximumFractionDigits: 1
- datetime:
text_size: sm
format:
dateStyle: short
timeStyle: short
hour12: true
timeZone: 'America/New_York'
- search:
provider: custom
url: http://localhost:8080/search?q=
focus: true
target: _blank
showSearchSuggestions: true
@@ -0,0 +1,44 @@
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
environment:
HOMEPAGE_ALLOWED_HOSTS: "*" # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
PUID: ${PUID} # Reference PUID from .env
PGID: ${PGID} # Reference PGID from .env
DOCKER_HOST: tcp://socket-proxy:2375
ports:
- 3000:3000
env_file:
- .env # Link to the .env file
volumes:
- ./config:/app/config # Make sure your local config directory exists
- ./images:/app/public/images
- /var/run/docker.sock:/var/run/docker.sock:ro # optional, for docker integrations
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
dockerproxy:
image: ghcr.io/tecnativa/docker-socket-proxy:latest
container_name: dockerproxy
environment:
- CONTAINERS=1 # Allow access to viewing containers
- SERVICES=1 # Allow access to viewing services (necessary when using Docker Swarm)
- TASKS=1 # Allow access to viewing tasks (necessary when using Docker Swarm)
- POST=0 # Disallow any POST operations (effectively read-only)
ports:
- 127.0.0.1:2375:2375
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # Mounted as read-only
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:2375"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

@@ -0,0 +1,13 @@
services:
it-tools:
image: 'corentinth/it-tools:latest'
ports:
- '8080:80'
restart: unless-stopped
container_name: it-tools
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
+29
View File
@@ -0,0 +1,29 @@
# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables
# The location where your uploaded files are stored
UPLOAD_LOCATION=/home/ubuntu/docker/immich/upload
# The location where your database files are stored
DB_DATA_LOCATION=/home/miker/docker/immich/postgres
# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/Lis>
TZ=America/New_York
# The Immich version to use. You can pin this to a specific version like "v1.71.0"
IMMICH_VERSION=release
# Connection secrets for postgres and typesense. You should change these to random passwords
TYPESENSE_API_KEY=hOEZ7Tei3iIp
DB_PASSWORD=ee438M3pcXo6
# The values below this line do not need to be changed
###################################################################################
DB_HOSTNAME=immich_postgres
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
REDIS_HOSTNAME=immich_redis
IMMICH_SERVER_URL=https://immich.mikemcfetridge.com
IMMICH_WEB_URL=https://immich.mikemcfetridge.com
+60
View File
@@ -0,0 +1,60 @@
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
volumes:
- /home/miker/dockerapps/immich/upload:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
- /home/miker/docker/immich/upload/import:/import
env_file:
- .env
ports:
- 2283:3001
depends_on:
- redis
- database
restart: always
immich-microservices:
container_name: immich_microservices
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION}
extends:
file: hwaccel.yml
service: hwaccel
command: [ "start.sh", "microservices" ]
volumes:
- /home/miker/dockerapps/immich/upload:/usr/src/app/upload
env_file:
- .env
depends_on:
- redis
- database
restart: always
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
volumes:
- /home/miker/dockerapps/immich/model-cache:/cache
env_file:
- .env
restart: always
redis:
container_name: immich_redis
image: redis:6.2-alpine@sha256:70a7a5b641117670beae0d80658430853896b5ef269ccf00d1827427e3263fa3
restart: always
database:
container_name: immich_postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0@sha256:fa4f6e0971f454cd95fec5a9aaed2ed93d8f46725cc6bc61e0698e97dba96da1
env_file:
- .env
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: '--data-checksums'
volumes:
- /home/miker/dockerapps/immich/pgdata:/var/lib/postgresql/data
restart: always
+23
View File
@@ -0,0 +1,23 @@
version: "3.8"
# Hardware acceleration for transcoding - Optional
# This is only needed if you want to use hardware acceleration for transcoding.
# Depending on your hardware, you should uncomment the relevant lines below.
services:
hwaccel:
devices:
- /dev/dri:/dev/dri # If using Intel QuickSync or VAAPI
# volumes:
# - /usr/lib/wsl:/usr/lib/wsl # If using VAAPI in WSL2
# environment:
# - NVIDIA_DRIVER_CAPABILITIES=all # If using NVIDIA GPU
# - LD_LIBRARY_PATH=/usr/lib/wsl/lib # If using VAAPI in WSL2
# - LIBVA_DRIVER_NAME=d3d12 # If using VAAPI in WSL2
# deploy: # Uncomment this section if using NVIDIA GPU
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu,video]
+32
View File
@@ -0,0 +1,32 @@
services:
# Immich - Photo/video server
immich:
container_name: immich
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
profiles: ["apps", "all"]
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- default
ports:
- "${IMMICH_PORT}:2283"
depends_on:
- redis
- immich-db
healthcheck:
disable: false
# extends:
# file: hwaccel.transcoding.yml
# service: nvenc # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
volumes:
# Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
- ${IMMICH_FOLDER}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
environment:
DB_PASSWORD: ${IMMICHDB_POSTGRESQL_PASSWORD}
DB_HOSTNAME: immich-db
DB_USERNAME: immich_db_user
DB_DATABASE_NAME: immich
REDIS_HOSTNAME: redis
# DOCKER-LABELS-PLACEHOLDER
@@ -0,0 +1,19 @@
services:
periphery:
image: ghcr.io/moghtech/komodo-periphery:latest # Or a specific version
container_name: komodo-periphery
ports:
- "8120:8120" # Expose Periphery API port
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Required to interact with Docker daemon
- komodo-periphery-data:/app/data # Persistent storage for periphery data
environment:
# Optional: Set a specific log level (e.g., info, debug, error)
- LOG_LEVEL=info
- KOMODO_CORE_ADDRESS=192.168.2.7 # Replace with your Komodo Core IP
- KOMODO_CORE_PASSKEY=HModV9yPmOBD4P # Replace with your Komodo Core passkey
- PERIPHERY_SSL_ENABLED=true
- PERIPHERY_DISABLE_TERMINALS=false
restart: unless-stopped
volumes:
komodo-periphery-data:
+142
View File
@@ -0,0 +1,142 @@
####################################
# 🦎 KOMODO COMPOSE - VARIABLES 🦎 #
####################################
## These compose variables can be used with all Komodo deployment options.
## Pass these variables to the compose up command using `--env-file komodo/compose.env`.
## Additionally, they are passed to both Komodo Core and Komodo Periphery with `env_file: ./compose.env`,
## so you can pass any additional environment variables to Core / Periphery directly in this file as well.
## Stick to a specific version, or use `latest`
COMPOSE_KOMODO_IMAGE_TAG=latest
## DB credentials
KOMODO_DB_USERNAME=admin
KOMODO_DB_PASSWORD=PCjFCsX0yC0G44
## Configure a secure passkey to authenticate between Core / Periphery.
KOMODO_PASSKEY=HModV9yPmOBD4P
## Set your time zone for schedules
## https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=America/New_York
#=-------------------------=#
#= Komodo Core Environment =#
#=-------------------------=#
## Full variable list + descriptions are available here:
## 🦎 https://github.com/moghtech/komodo/blob/main/config/core.config.toml 🦎
## Note. Secret variables also support `${VARIABLE}_FILE` syntax to pass docker compose secrets.
## Docs: https://docs.docker.com/compose/how-tos/use-secrets/#examples
## Used for Oauth / Webhook url suggestion / Caddy reverse proxy.
KOMODO_HOST=https://komodo.mikemcfetridge.com
## Displayed in the browser tab.
KOMODO_TITLE=Komodo
## Create a server matching this address as the "first server".
## Use `https://host.docker.internal:8120` when using systemd-managed Periphery.
KOMODO_FIRST_SERVER=https://192.168.2.21:8120
## Make all buttons just double-click, rather than the full confirmation dialog.
KOMODO_DISABLE_CONFIRM_DIALOG=true
## Rate Komodo polls your servers for
## status / container status / system stats / alerting.
## Options: 1-sec, 5-sec, 15-sec, 1-min, 5-min, 15-min
## Default: 15-sec
KOMODO_MONITORING_INTERVAL="15-sec"
## Interval at which to poll Resources for any updates / automated actions.
## Options: 15-min, 1-hr, 2-hr, 6-hr, 12-hr, 1-day
## Default: 1-hr
KOMODO_RESOURCE_POLL_INTERVAL="15-min"
## Used to auth incoming webhooks. Alt: KOMODO_WEBHOOK_SECRET_FILE
KOMODO_WEBHOOK_SECRET=oop28TaGucFUTh
## Used to generate jwt. Alt: KOMODO_JWT_SECRET_FILE
KOMODO_JWT_SECRET=rm4O312hzsl6Pt
## Time to live for jwt tokens.
## Options: 1-hr, 12-hr, 1-day, 3-day, 1-wk, 2-wk
KOMODO_JWT_TTL="1-day"
## Enable login with username + password.
KOMODO_LOCAL_AUTH=true
## Disable new user signups.
KOMODO_DISABLE_USER_REGISTRATION=true
## All new logins are auto enabled
KOMODO_ENABLE_NEW_USERS=false
## Disable non-admins from creating new resources.
KOMODO_DISABLE_NON_ADMIN_CREATE=false
## Allows all users to have Read level access to all resources.
KOMODO_TRANSPARENT_MODE=false
## Prettier logging with empty lines between logs
KOMODO_LOGGING_PRETTY=false
## More human readable logging of startup config (multi-line)
KOMODO_PRETTY_STARTUP_CONFIG=false
## OIDC Login
KOMODO_OIDC_ENABLED=false
## Must reachable from Komodo Core container
# KOMODO_OIDC_PROVIDER=https://oidc.provider.internal/application/o/komodo
## Change the host to one reachable be reachable by users (optional if it is the same as above).
## DO NOT include the `path` part of the URL.
# KOMODO_OIDC_REDIRECT_HOST=https://oidc.provider.external
## Your OIDC client id
# KOMODO_OIDC_CLIENT_ID= # Alt: KOMODO_OIDC_CLIENT_ID_FILE
## Your OIDC client secret.
## If your provider supports PKCE flow, this can be ommitted.
# KOMODO_OIDC_CLIENT_SECRET= # Alt: KOMODO_OIDC_CLIENT_SECRET_FILE
## Make usernames the full email.
## Note. This does not work for all OIDC providers.
# KOMODO_OIDC_USE_FULL_EMAIL=true
## Add additional trusted audiences for token claims verification.
## Supports comma separated list, and passing with _FILE (for compose secrets).
# KOMODO_OIDC_ADDITIONAL_AUDIENCES=abc,123 # Alt: KOMODO_OIDC_ADDITIONAL_AUDIENCES_FILE
## Github Oauth
KOMODO_GITHUB_OAUTH_ENABLED=false
# KOMODO_GITHUB_OAUTH_ID= # Alt: KOMODO_GITHUB_OAUTH_ID_FILE
# KOMODO_GITHUB_OAUTH_SECRET= # Alt: KOMODO_GITHUB_OAUTH_SECRET_FILE
## Google Oauth
KOMODO_GOOGLE_OAUTH_ENABLED=false
# KOMODO_GOOGLE_OAUTH_ID= # Alt: KOMODO_GOOGLE_OAUTH_ID_FILE
# KOMODO_GOOGLE_OAUTH_SECRET= # Alt: KOMODO_GOOGLE_OAUTH_SECRET_FILE
## Aws - Used to launch Builder instances.
KOMODO_AWS_ACCESS_KEY_ID= # Alt: KOMODO_AWS_ACCESS_KEY_ID_FILE
KOMODO_AWS_SECRET_ACCESS_KEY= # Alt: KOMODO_AWS_SECRET_ACCESS_KEY_FILE
#=------------------------------=#
#= Komodo Periphery Environment =#
#=------------------------------=#
## Full variable list + descriptions are available here:
## 🦎 https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml 🦎
## Specify the root directory used by Periphery agent.
PERIPHERY_ROOT_DIRECTORY=/etc/komodo
## Periphery passkeys must include KOMODO_PASSKEY to authenticate.
PERIPHERY_PASSKEYS=${KOMODO_PASSKEY}
## Specify whether to disable the terminals feature
## and disallow remote shell access (inside the Periphery container).
PERIPHERY_DISABLE_TERMINALS=false
## Enable SSL using self signed certificates.
## Connect to Periphery at https://address:8120.
PERIPHERY_SSL_ENABLED=true
## If the disk size is overreporting, can use one of these to
## whitelist / blacklist the disks to filter them, whichever is easier.
## Accepts comma separated list of paths.
## Usually whitelisting just /etc/hostname gives correct size.
PERIPHERY_INCLUDE_DISK_MOUNTS=/etc/hostname
# PERIPHERY_EXCLUDE_DISK_MOUNTS=/snap,/etc/repos
## Prettier logging with empty lines between logs
PERIPHERY_LOGGING_PRETTY=false
## More human readable logging of startup config (multi-line)
PERIPHERY_PRETTY_STARTUP_CONFIG=false
+106
View File
@@ -0,0 +1,106 @@
###################################
# 🦎 KOMODO COMPOSE - FERRETDB 🦎 #
###################################
## This compose file will deploy:
## 1. Postgres + FerretDB Mongo adapter (https://www.ferretdb.com)
## 2. Komodo Core
## 3. Komodo Periphery
services:
postgres:
# Recommended: Pin to a specific version
# https://github.com/FerretDB/documentdb/pkgs/container/postgres-documentdb
image: ghcr.io/ferretdb/postgres-documentdb
labels:
komodo.skip: # Prevent Komodo from stopping with StopAllContainers
restart: unless-stopped
# ports:
# - 5432:5432
env_file: ./compose.env
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: PCjFCsX0yC0G44
POSTGRES_DB: postgres
ferretdb:
# Recommended: Pin to a specific version
# https://github.com/FerretDB/FerretDB/pkgs/container/ferretdb
image: ghcr.io/ferretdb/ferretdb
labels:
komodo.skip: # Prevent Komodo from stopping with StopAllContainers
restart: unless-stopped
depends_on:
- postgres
# ports:
# - 27017:27017
env_file: ./compose.env
volumes:
- ferretdb-state:/state
environment:
FERRETDB_POSTGRESQL_URL: postgres://admin:PCjFCsX0yC0G44@postgres:5432/postgres
core:
image: ghcr.io/moghtech/komodo-core:${COMPOSE_KOMODO_IMAGE_TAG:-latest}
labels:
komodo.skip: # Prevent Komodo from stopping with StopAllContainers
restart: unless-stopped
depends_on:
- ferretdb
ports:
- 9120:9120
env_file: ./compose.env
environment:
KOMODO_DATABASE_ADDRESS: ferretdb:27017
KOMODO_DATABASE_USERNAME: admin
KOMODO_DATABASE_PASSWORD: PCjFCsX0yC0G44
volumes:
## Core cache for repos for latest commit hash / contents
- repo-cache:/repo-cache
## Store sync files on server
# - /path/to/syncs:/syncs
## Optionally mount a custom core.config.toml
# - /path/to/core.config.toml:/config/config.toml
## Allows for systemd Periphery connection at
## "http://host.docker.internal:8120"
# extra_hosts:
# - host.docker.internal:host-gateway
## Deploy Periphery container using this block,
## or deploy the Periphery binary with systemd using
## https://github.com/moghtech/komodo/tree/main/scripts
periphery:
image: ghcr.io/moghtech/komodo-periphery:${COMPOSE_KOMODO_IMAGE_TAG:-latest}
labels:
komodo.skip: # Prevent Komodo from stopping with StopAllContainers
restart: unless-stopped
env_file: ./compose.env
# Need to make sure you add this or deploying agents will be a pain.
ports:
- 8120:8120
volumes:
## Mount external docker socket
- /var/run/docker.sock:/var/run/docker.sock
## Allow Periphery to see processes outside of container
- /proc:/proc
## Specify the Periphery agent root directory.
## Must be the same inside and outside the container,
## or docker will get confused. See https://github.com/moghtech/komodo/discussions/180.
## Default: /etc/komodo.
- ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}:${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}
volumes:
# Postgres
postgres-data: # FerretDB
ferretdb-state: # Core
repo-cache:
# To start up - Run
# docker compose -p komodo -f komodo/ferretdb.compose.yaml --env-file komodo/compose.env up -d
# To stop up - Run
# docker compose -p komodo -f komodo/ferretdb.compose.yaml --env-file komodo/compose.env up -d
+11
View File
@@ -0,0 +1,11 @@
PUID=1000
PGID=1000
# TZ for container timezone
TZ=America/New_York
SMTP_HOST=smtp.zoho.com
SMTP_FROM_NAME=miker@mcfetridge.us
SMTP_AUTH_STRATEGY=TLS
SMTP_FROM_EMAIL=miker@mcfetridge.us
SMTP_USER=miker@mcfetridge.us
SMTP_PASSWORD="!Sucyetat123"
SMTP_PORT=465
+37
View File
@@ -0,0 +1,37 @@
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:latest # Specifies the Mealie Docker i>
container_name: mealie # Names the container for easier>
restart: always
networks:
- proxy # Ensures the container restart>
# ports:
# - "9925:9000" # Maps port 9925 on the host to >
deploy:
resources:
limits:
memory: 1000M # Limits the container to use a >
volumes:
- /home/miker/docker/mealie/data:/app/data/ # Persists data in>
- ./config/addons_config/mealie/config.yaml:/config/config.yanl
environment:
- ALLOW_SIGNUP=false # Allows new user signups on the>
- PUID=${PUID} # Sets the user ID for the conta>
- PGID=${PGID} # Sets the group ID for the cont>
- TZ=${TZ} # Sets the timezone for the cont>
- MAX_WORKERS=1 # Limits the number of workers t>
- WEB_CONCURRENCY=1 # Sets the concurrency level for>
- BASE_URL=mealie.mikemcfetridge.com # The base URL where Mealie is a>
# Email Settings
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_FROM_NAME=${SMTP_FROM_NAME}
- SMTP_AUTH_STRATEGY=${SMTP_AUTH_STRATEGY}
- SMTP_FROM_EMAIL=${SMTP_FROM_EMAI}
- SMTP_USER=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWORD}
env_file:
- .env
networks:
proxy:
external: true
@@ -0,0 +1,23 @@
version: '3'
services:
meshcentral:
restart: always
container_name: meshcentral
image: typhonragewind/meshcentral:latest
ports:
- 8086:443 #MeshCentral will moan and try everything not to use port 80, but you can also use it if you so desire, just change the config.json according to your needs
environment:
- HOSTNAME=mesh.mikeandrebel.com #your hostname
- REVERSE_PROXY=107.175.245.171 #set to your reverse proxy IP if you want to put meshcentral behind a reverse proxy
- REVERSE_PROXY_TLS_PORT=443
- IFRAME=false #set to true if you wish to enable iframe support
- ALLOW_NEW_ACCOUNTS=false #set to false if you want disable self-service creation of new accounts besides the first (admin)
- WEBRTC=true #set to true to enable WebRTC - per documentation it is not officially released with meshcentral, but is solid enough to work with. Use with caution
- TZ=America/New_York
- BACKUPS_PW=!password #password for the autobackup function
- BACKUP_INTERVAL=24 # Interval in hours for the autobackup function
- BACKUP_KEEP_DAYS=3 #number of days of backups the function keeps
volumes:
- ./data:/opt/meshcentral/meshcentral-data #config.json and other important files live here. A must for data persistence
- ./user_files:/opt/meshcentral/meshcentral-files #where file uploads for users live
- ./backups:/opt/meshcentral/meshcentral-backups #Backups location
@@ -0,0 +1,9 @@
services:
myspeed:
container_name: MySpeed
image: germannewsmaker/myspeed
ports:
- '5216:5216'
volumes:
- ./myspeed:/myspeed/data
restart: unless-stopped
+13
View File
@@ -0,0 +1,13 @@
services:
navidrome:
image: deluan/navidrome:latest
user: 1000:1000 # should be owner of volumes
ports:
- "4533:4533"
restart: unless-stopped
environment:
# Optional: put your config options customization here. Examples:
# ND_LOGLEVEL: debug
volumes:
- /home/miker/docker/navidrome/data:/data
- /home/miker/docker/data/music:/music:ro
@@ -0,0 +1,32 @@
services:
nextcloud-aio-mastercontainer:
image: nextcloud/all-in-one:latest
init: true
sig-proxy: false
restart: always
container_name: nextcloud-aio-mastercontainer
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- 8080:8080
environment:
- APACHE_PORT=11000
- APACHE_IP_BINDING=0.0.0.0
- APACHE_ADDITIONAL_NETWORK=""
- SKIP_DOMAIN_VALIDATION=true
volumes:
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer # This line is not allowed to be changed.
# My Passphase
# resigned lubricant petty eternal gumball coroner stream nervy
# admin
$ f34920a6ecaa8cb825d6c46972841250e4ec0fa68c46f64f
# Backup information
# This is your encryption password for backups: f5b3a3dc742ac7b354d3e2d3926d8bce9fb50bcd1b75afc4
+7
View File
@@ -0,0 +1,7 @@
MYSQL_ROOT_PASSWORD=rhDGjilZm6XEMJ
MYSQL_DATABASE=npm
MYSQL_USER=npm
MYSQL_PASSWORD=rhDGjilZm6XEMJ
# TZ for container timezone
TZ=America/New_York
@@ -0,0 +1,101 @@
# Docker Compose File Guide
## Overview
The Docker Compose file is a YAML file defining services, networks, and volumes. This file is used to spin up multiple containers at once using docker-compose CLI tool. It's designed to be a part of your development process rather than being deployed on its own.
In this guide, we will explore the `docker-compose.yml` file in detail and provide steps for its installation and usage.
## Understanding Docker Compose File
Let's take a look at an example of a docker compose file:
```yaml
version: '3'
services:
db:
image: 'jc21/mariadb-aria:latest'
container_name: npm-db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MARIADB_AUTO_UPGRADE=1
volumes:
- ./data/mysql:/var/lib/mysql
networks:
- proxy
- proxydb
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}"]
interval: 20s
timeout: 5s
retries: 5
start_period: 30s
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
env_file: .env
environment:
- TZ=${TZ}
- DB_MYSQL_HOST=db
- DB_MYSQL_PORT=3306
- DB_MYSQL_USER=${MYSQL_USER}
- DB_MYSQL_PASSWORD=${MYSQL_PASSWORD}
- DB_MYSQL_NAME=${MYSQL_DATABASE}
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data/npm:/data
- ./data/letsencrypt:/etc/letsencrypt
depends_on:
- db
networks:
- proxy
- proxydb
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:81/api/status"]
interval: 20s
timeout: 5s
retries: 5
start_period: 40s
networks:
proxy:
external: true
proxydb:
external: true
```
This Docker Compose file defines two services, `db` and `app`. Each service is defined with its own configuration such as the image to use, ports to expose, volumes to mount, etc. It also has a network section where it lists the networks that these services should connect to.
.env
```yaml
MYSQL_ROOT_PASSWORD=rhDGjilZm6XEMJ
MYSQL_DATABASE=npm
MYSQL_USER=npm
MYSQL_PASSWORD=rhDGjilZm6XEMJ
# TZ for container timezone
TZ=America/New_York
```
## Installation Guide
1. **Install Docker**: Follow instructions on the official [Docker website](https://docs.docker.com/get-docker/) for your specific operating system.
2. **Install Docker Compose**: On Linux, run `sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose` followed by `sudo chmod +x /usr/local/bin/docker-compose`. On Windows or MacOS, follow the instructions on [Docker Compose's Github page](https://github.com/docker/compose).
3. **Pull Docker Images**: Before running docker-compose up, make sure to pull all necessary images with `docker-compose pull` command.
## Running the Services
4. **Running the services**: In your terminal, navigate to the directory containing your docker-compose file and run `docker-compose up -d`. This will start all the services defined in the compose file.
5. **Checking the running status of services**: You can check the status of running services with `docker-compose ps` command.
Remember to replace placeholders like `${MYSQL_ROOT_PASSWORD}`, `${MYSQL_DATABASE}`, and `${MYSQL_USER}`, etc., in your environment variables files (.env) with actual values before starting the services. Also, ensure all paths mentioned in volumes section exist on your system or adjust them accordingly.
## Conclusion
With this guide you should now have a solid understanding of Docker Compose file and how to use it for running multi-container applications. It's worth noting that Docker Compose is just one tool among many, each having its own strengths and weaknesses depending on the specific use case.
@@ -0,0 +1,61 @@
---
services:
db:
image: 'jc21/mariadb-aria:latest'
container_name: npm-db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MARIADB_AUTO_UPGRADE=1
volumes:
- ./data/mysql:/var/lib/mysql
networks:
- proxy
- proxydb
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}"]
interval: 20s
timeout: 5s
retries: 5
start_period: 30s
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
env_file: .env
environment:
- TZ=${TZ}
- DB_MYSQL_HOST=db
- DB_MYSQL_PORT=3306
- DB_MYSQL_USER=${MYSQL_USER}
- DB_MYSQL_PASSWORD=${MYSQL_PASSWORD}
- DB_MYSQL_NAME=${MYSQL_DATABASE}
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data/npm:/data
- ./data/letsencrypt:/etc/letsencrypt
depends_on:
- db
networks:
- proxy
- proxydb
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:81/api/status"]
interval: 20s
timeout: 5s
retries: 5
start_period: 40s
networks:
proxy:
external: true
proxydb:
external: true
@@ -0,0 +1,26 @@
services:
couchdb-obsidian-livesync:
container_name: obsidian-livesync
# image: couchdb:3.3.3 # Specify a stable CouchDB version
image: 'docker.io/oleduc/docker-obsidian-livesync-couchdb:master'
environment:
# User and password for CouchDB admin access
- COUCHDB_USER=miker
- COUCHDB_PASSWORD=tw9222dvO91ZHb
- COUCHDB_DATABASE=obsidian
- SERVER_DOMAIN=https://obsidian.mikemcfetridge.com
# Optional: Set PUID, PGID, UMASK, and TZ for user/group permissions and timezone
- PUID=1000
- PGID=1000
- UMASK=0022
- TZ=America/New_York # Adjust timezone as needed
volumes:
# Mount a local directory for CouchDB data persistence
- /home/miker/docker/obsidian/data:/opt/couchdb/data
# Mount a local directory for CouchDB configuration files
- /home/miker/docker/obsidian/config:/opt/couchdb/etc/local.d
ports:
# Map CouchDB's default port 5984 to the host machine
- "5984:5984"
restart: unless-stopped # Ensure the container restarts automatically unless explicitly stopped
@@ -0,0 +1,26 @@
---
services:
obsidian:
image: lscr.io/linuxserver/obsidian:latest
container_name: obsidian
security_opt:
- seccomp:unconfined #optional
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
volumes:
- ./config:/config
ports:
- 3000:3000
- 3001:3001
devices:
- /dev/dri:/dev/dri #optional
shm_size: "1gb"
restart: always
# used to place in the NPM / traefik network so they can talk with each other.
networks:
- proxy
networks:
proxy:
external: true
+54
View File
@@ -0,0 +1,54 @@
version: '3.6'
services:
ollama:
# Uncomment below for GPU support
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities:
# - gpu
volumes:
- ollama:/root/.ollama
ports:
- 11434:11434
container_name: ollama
pull_policy: always
tty: true
restart: unless-stopped
image: ollama/ollama:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:11434"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
ollama-webui:
build:
context: .
args:
OLLAMA_API_BASE_URL: '/ollama/api'
image: ollama-webui:latest
container_name: ollama-webui
depends_on:
- ollama
ports:
- 3000:8080
environment:
- "OLLAMA_API_BASE_URL=http://ollama:11434/api"
extra_hosts:
- host.docker.internal:host-gateway
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
volumes:
ollama: {}
+23
View File
@@ -0,0 +1,23 @@
services:
# Ollama - Local Open-source AI Models
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
profiles: ["apps", "all"]
networks:
- default
ports:
- "$OLLAMA_PORT:11434"
volumes:
- $DOCKERDIR/appdata/ollama:/root/.ollama
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# device_ids: ['all']
# capabilities: [gpu]
environment:
- OLLAMA_KEEP_ALIVE=24h
# DOCKER-LABELS-PLACEHOLDER
+5
View File
@@ -0,0 +1,5 @@
1. Clone the repo from: https://github.com/ollama-webui/ollama-webui
2. Tweak the docker-compose to your liking
3. Run the container: sudo docker compose up -d
Let it build :)
+5
View File
@@ -0,0 +1,5 @@
WEBPASSWORD=e6z1EBVDERIP7
PUID=1000
PGID=1000
# TZ for container timezone
TZ=America/New_York
+40
View File
@@ -0,0 +1,40 @@
---
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
env_file:
- .env
ports:
- "53:53/tcp"
- "53:53/udp"
- "67:67/udp"
- "500:80/tcp"
# - "443:443/tcp"
networks:
pihole_internal:
ipv4_address: 172.70.9.3
pihole:
environment:
TZ: ${TZ}
PUID: ${PUID} # Reference PUID from .env
PGID: ${PGID} #
WEBPASSWORD: ${WEBPASSWORD}
PIHOLE_DNS_: '172.70.9.2#5053'
DNSMASQ_LISTENING: 'all'
VIRTUAL_HOST: pihole.mikemcfetridge.com
volumes:
- /home/miker/dockerapps/pihole/appdata/pihole/etc:/etc/pihole
- /home/miker/dockerapps/pihole/appdata/pihole/etc/dnsmasq.d:/etc/dnsmasq.d
- /home/miker/dockerapps/pihole/appdata/pihole/log:/var/log/pihole
restart: unless-stopped
networks:
pihole_internal:
ipam:
config:
- subnet: 172.70.9.0/29
name: pihole_internal
pihole:
external: true
+41
View File
@@ -0,0 +1,41 @@
services:
# Pi-hole - DNS Server and AdBlocker
pihole:
image: pihole/pihole:latest
container_name: pihole
security_opt:
- no-new-privileges:true
restart: unless-stopped
profiles: ["all", "core"]
networks:
- default
# cap_add:
# # See https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
# # Required if you are using Pi-hole as your DHCP server, else not needed
# - NET_ADMIN
# # Required if you are using Pi-hole as your NTP client to be able to set the host's system time
# - SYS_TIME
# # Optional, if Pi-hole should get some more processing time
# - SYS_NICE
ports:
- "53:53/tcp"
- "53:53/udp"
# - "67:67/udp" # DHCP Server
- "80:80/tcp" # HTTP
# - "123:123/udp" # NTP
# - "443:443" # HTTPS
volumes:
- "/home/miker/dockerapps/pihole/appdata/pihole/etc:/etc/pihole"
- "/home/miker/dockerapps/pihole/appdata/pihole/etc/dnsmasq.d:/etc/dnsmasq.d"
- "/home/miker/dockerapps/pihole/appdata/pihole/log:/var/log/pihole"
environment:
# https://docs.pi-hole.net/docker/upgrading/v5-v6/?h=pihole_dns#misc Variables list for v6
TZ: ${TZ}
FTLCONF_webserver_api_password: !Sucyetat123
FTLCONF_dns_listeningMode: 'all'
FTLCONF_dns_upstreams: 9.9.9.9;1.1.1.1;192.168.2.5
FTLCONF_dns_bogusPriv: "true"
FTLCONF_dns_domainNeeded: "true"
FTLCONF_dns_domain: home.mikemcfetridge
FTLCONF_webserver_interface_theme: "default_dark"
# DOCKER-LABELS-PLACEHOLDER
+7
View File
@@ -0,0 +1,7 @@
#run these commands to fix port bind error
sudo sed -r -i.orig 's/#?DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf
sudo sh -c 'rm /etc/resolv.conf && ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf'
systemctl restart systemd-resolved
@@ -0,0 +1,13 @@
---
services:
app:
container_name: portainer-agent
deploy:
mode: global
image: docker.io/portainer/agent:latest
ports:
- 9001:9001
volumes:
- /run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
restart: unless-stopped
@@ -0,0 +1,19 @@
---
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
ports:
- 9445:9443
volumes:
- ./data:/data
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
# Network to join in docker which is named below
networks:
- proxy
# create PROXY network for NPM security. This will allow NPM to see and talk to >
networks:
proxy:
external: true
+22
View File
@@ -0,0 +1,22 @@
services:
# Portainer - WebUI for Containers
portainer:
container_name: portainer
image: portainer/portainer-ce:latest
security_opt:
- no-new-privileges:true
restart: unless-stopped
profiles: ["core", "all"]
networks:
- default
- socket_proxy
# command: -H unix:///var/run/docker.sock # Use Docker Socket Proxy instead for improved security
command: -H tcp://socket-proxy:2375
ports:
- "$PORTAINER_PORT:9000"
volumes:
# - /var/run/docker.sock:/var/run/docker.sock:ro # Use Docker Socket Proxy instead for improved security
- $DOCKERDIR/appdata/portainer/data:/data
environment:
- TZ=$TZ
# DOCKER-LABELS-PLACEHOLDER
+7
View File
@@ -0,0 +1,7 @@
RACKPAD_IMAGE=ghcr.io/kobii-git/rackpad
RACKPAD_TAG=latest
RACKPAD_PORT=3850
MONITOR_INTERVAL_MS=300000
TRUST_PROXY=0
TRUSTED_HOSTS=
TRUSTED_ORIGINS=
+58
View File
@@ -0,0 +1,58 @@
services:
rackpad:
image: ${RACKPAD_IMAGE:-ghcr.io/kobii-git/rackpad}:${RACKPAD_TAG:-1.5.2}
container_name: rackpad
init: true
restart: unless-stopped
environment:
NODE_ENV: production
HOST: 0.0.0.0
PORT: 3000
DATABASE_PATH: /data/rackpad.db
MONITOR_INTERVAL_MS: ${MONITOR_INTERVAL_MS:-300000}
TRUST_PROXY: ${TRUST_PROXY:-0}
TRUSTED_HOSTS: ${TRUSTED_HOSTS:-}
TRUSTED_ORIGINS: ${TRUSTED_ORIGINS:-}
APP_URL: ${APP_URL:-}
OIDC_ENABLED: ${OIDC_ENABLED:-0}
OIDC_ISSUER_URL: ${OIDC_ISSUER_URL:-}
OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-}
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-}
OIDC_REDIRECT_URI: ${OIDC_REDIRECT_URI:-}
OIDC_LABEL: ${OIDC_LABEL:-OIDC}
OIDC_DEFAULT_ROLE: ${OIDC_DEFAULT_ROLE:-viewer}
OIDC_DEBUG: ${OIDC_DEBUG:-0}
OIDC_ADMIN_USERS: ${OIDC_ADMIN_USERS:-}
OIDC_EDITOR_USERS: ${OIDC_EDITOR_USERS:-}
OIDC_VIEWER_USERS: ${OIDC_VIEWER_USERS:-}
OIDC_ADMIN_GROUPS: ${OIDC_ADMIN_GROUPS:-}
OIDC_EDITOR_GROUPS: ${OIDC_EDITOR_GROUPS:-}
OIDC_VIEWER_GROUPS: ${OIDC_VIEWER_GROUPS:-}
OUI_AUTO_UPDATE: ${OUI_AUTO_UPDATE:-1}
DISCOVERY_MAC_SCAN_MODE: ${DISCOVERY_MAC_SCAN_MODE:-auto}
ports:
- "${RACKPAD_PORT:-3000}:3000"
volumes:
- rackpad_data:/data
read_only: true
tmpfs:
- /tmp
security_opt:
- no-new-privileges:true
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://127.0.0.1:3000/api/health').then((res) => process.exit(res.ok ? 0 : 1)).catch(() => process.exit(1))",
]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
volumes:
rackpad_data:
+31
View File
@@ -0,0 +1,31 @@
services:
semaphore:
ports:
- 3300:3300
image: semaphoreui/semaphore:latest
container_name: semaphore
environment:
SEMAPHORE_DB_DIALECT: sqlite
SEMAPHORE_ADMIN: mmcfetridge
SEMAPHORE_ADMIN_PASSWORD: Dy7zxAyDqdYN443g4pI3
SEMAPHORE_ADMIN_NAME: Mike McFetridge
SEMAPHORE_ADMIN_EMAIL: mmcfetridg@aol.com
SEMAPHORE_PORT: "3300"
ANSIBLE_HOST_KEY_CHECKING: "False"
SEMAPHORE_ACCESS_KEY_ENCRYPTION: "mrmKv7EztqRCnlGo34IvlvoilXqvDKYnFIWX2lg+hZc="
volumes:
- semaphore_data:/var/lib/semaphore
- semaphore_config:/etc/semaphore
- semaphore_tmp:/tmp/semaphore
networks:
- semaphore-net
volumes:
semaphore_data:
semaphore_config:
semaphore_tmp:
networks:
semaphore-net:
driver: bridge
+22
View File
@@ -0,0 +1,22 @@
URL for the task template
ansible/update/update-apt-packages.yaml
Need to create two files:
In order to ensure Semaphore can run commands properly, well need a line similar to the one below added to /etc/sudoers.d/semaphore on the target (the instance that our Semaphore server will be configuring). Be sure to replace semaphore in both the file name and inside the file to match the username of the user you intend to use with Semaphore.
semaphore file
semaphore ALL=(ALL) NOPASSWD: ALL
miker file
miker ALL=(ALL) NOPASSWD: ALL
Need to be logged into Ubuntu03, go to the .ssh directory and run the following command to copy over the rsa.pub file.
scp id_rsa.pub miker@192.168.0.181:/home/miker/.ssh
or
ssh-copy-id miker@192.168.0.185
@@ -0,0 +1,51 @@
services:
dns-server:
container_name: technitium-dns-server
hostname: dns-server
image: technitium/dns-server:latest
# For DHCP deployments, use "host" network mode and remove all the port mappings, including the ports array by commenting them
# network_mode: "host"
ports:
- "5380:5380/tcp" #DNS web console (HTTP)
- "5381:53443/tcp" #DNS web console (HTTPS)
- "53:53/udp" #DNS service
- "53:53/tcp" #DNS service
# - "853:853/udp" #DNS-over-QUIC service
# - "853:853/tcp" #DNS-over-TLS service
# - "443:443/udp" #DNS-over-HTTPS service (HTTP/3)
# - "443:443/tcp" #DNS-over-HTTPS service (HTTP/1.1, HTTP/2)
# - "80:80/tcp" #DNS-over-HTTP service (use with reverse proxy or certbot certificate renewal)
- "8053:8053/tcp" #DNS-over-HTTP service (use with reverse proxy)
# - "67:67/udp" #DHCP service
environment:
- DNS_SERVER_DOMAIN=technitium-dns-server #The primary domain name used by this DNS Server to identify itself.
- DNS_SERVER_ADMIN_PASSWORD=password #DNS web console admin user password.
# - DNS_SERVER_ADMIN_PASSWORD_FILE=password.txt #The path to a file that contains a plain text password for the DNS web console admin user.
# - DNS_SERVER_PREFER_IPV6=false #DNS Server will use IPv6 for querying whenever possible with this option enabled.
# - DNS_SERVER_WEB_SERVICE_LOCAL_ADDRESSES=172.17.0.1,127.0.0.1 #Comma separated list of network interface IP addresses that you want the web service to listen on for requests. The "172.17.0.1" address is the built-in Docker bridge. The "[::]" is the default value if not specified. Note! This must be used only with "host" network mode.
- DNS_SERVER_WEB_SERVICE_HTTP_PORT=5380 #The TCP port number for the DNS web console over HTTP protocol.
# - DNS_SERVER_WEB_SERVICE_HTTPS_PORT=53443 #The TCP port number for the DNS web console over HTTPS protocol.
# - DNS_SERVER_WEB_SERVICE_ENABLE_HTTPS=false #Enables HTTPS for the DNS web console.
# - DNS_SERVER_WEB_SERVICE_USE_SELF_SIGNED_CERT=false #Enables self signed TLS certificate for the DNS web console.
- DNS_SERVER_OPTIONAL_PROTOCOL_DNS_OVER_HTTP=false #Enables DNS server optional protocol DNS-over-HTTP on TCP port 8053 to be used with a TLS terminating reverse proxy like nginx.
# - DNS_SERVER_RECURSION=AllowOnlyForPrivateNetworks #Recursion options: Allow, Deny, AllowOnlyForPrivateNetworks, UseSpecifiedNetworks.
# - DNS_SERVER_RECURSION_DENIED_NETWORKS=1.1.1.0/24 #Comma separated list of IP addresses or network addresses to deny recursion. Valid only for `UseSpecifiedNetworks` recursion option.
# - DNS_SERVER_RECURSION_ALLOWED_NETWORKS=127.0.0.1, 192.168.1.0/24 #Comma separated list of IP addresses or network addresses to allow recursion. Valid only for `UseSpecifiedNetworks` recursion option.
# - DNS_SERVER_ENABLE_BLOCKING=false #Sets the DNS server to block domain names using Blocked Zone and Block List Zone.
# - DNS_SERVER_ALLOW_TXT_BLOCKING_REPORT=false #Specifies if the DNS Server should respond with TXT records containing a blocked domain report for TXT type requests.
# - DNS_SERVER_BLOCK_LIST_URLS= #A comma separated list of block list URLs.
- DNS_SERVER_FORWARDERS=1.1.1.1, 8.8.8.8 #Comma separated list of forwarder addresses.
- DNS_SERVER_FORWARDER_PROTOCOL=Tcp #Forwarder protocol options: Udp, Tcp, Tls, Https, HttpsJson.
# - DNS_SERVER_LOG_USING_LOCAL_TIME=true #Enable this option to use local time instead of UTC for logging.
volumes:
- ./config:/etc/dns
restart: unless-stopped
sysctls:
- net.ipv4.ip_local_port_range=1024 65000
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5380"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
@@ -0,0 +1,10 @@
services:
trilium:
image: zadam/trilium:latest
hostname: trilium
container_name: trilium
restart: unless-stopped
volumes:
- /home/miker/docker/trillium/data:/home/node/trilium-data
ports:
- '8180:8080'
+15
View File
@@ -0,0 +1,15 @@
services:
agent:
container_name: tugtainer-agent
image: quenary/tugtainer-agent:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
environment:
# The list of available variables is in env.example
AGENT_SECRET: home-mikemcfetridge-com
read_only: true
tmpfs:
- /run
ports:
- '8001:8001'
@@ -0,0 +1,12 @@
services:
app:
container_name: tugtainer
image: quenary/tugtainer:latest
volumes:
- tugtainer_data:/tugtainer
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
ports:
- '9412:80'
volumes:
tugtainer_data:
+14
View File
@@ -0,0 +1,14 @@
services:
uptime-kuma:
container_name: uptime-kuma
image: elestio/uptime-kuma
environment:
- DB_TYPE=sqlite
- DB_STORAGE=/app/data/uptime-kuma.db
- SOFTWARE_VERSION_TAG=latest
- URL=https://kuma.mikeandrebel.com
volumes:
- /home/miker/docker/kuma/data:/app/data
- /var/run/docker.sock:/var/run/docker.sock
restart: always
+8
View File
@@ -0,0 +1,8 @@
DOMAIN=https://vault.mikeandrebel.com
ADMIN_TOKEN=kane9RVtkbgu3j0NNZiAOA1mQ
SIGNUPS_DOMAINS_WHITELIST=aol.com,mcfetridge.us
SMTP_HOST=mail.mcfetridge.us
SMTP_FROM=miker@mcfetridge.us
SMTP_FROM_NAME=Vaultwarden
SMTP_USERNAME=miker@mcfetridge.us
SMTP_PASSWORD="!Sucyetat123"
@@ -0,0 +1,40 @@
services:
vaultwarden:
container_name: vaultwarden
image: vaultwarden/server:latest
restart: unless-stopped
env_file:
- .env
volumes:
- ./data/:/data/
# ports:
# - 8780:80
environment:
- DOMAIN=${DOMAIN}
- LOGIN_RATELIMIT_MAX_BURST=10
- LOGIN_RATELIMIT_SECONDS=60
- ADMIN_RATELIMIT_MAX_BURST=10
- ADMIN_RATELIMIT_SECONDS=60
- ADMIN_TOKEN=${ ADMIN_TOKEN}
- SENDS_ALLOWED=true
- EMERGENCY_ACCESS_ALLOWED=true
- WEB_VAULT_ENABLED=true
- SIGNUPS_ALLOWED=false
- SIGNUPS_VERIFY=false
- SIGNUPS_VERIFY_RESEND_TIME=3600
- SIGNUPS_VERIFY_RESEND_LIMIT=5
- SIGNUPS_DOMAINS_WHITELIST=${SIGNUPS_DOMAINS_WHITELIST}
- SMTP_HOST=${SMTP_HOST}
- SMTP_FROM=${SMTP_FROM}
- SMTP_FROM_NAME=${SMTP_FROM_NAME}
- SMTP_SECURITY=starttls
- SMTP_PORT=587
- SMTP_USERNAME=${SMTP_USERNAME}
- SMTP_PASSWORD=${SMTP_PASSWORD}
- SMTP_AUTH_MECHANISM="Login"
networks:
- proxy
networks:
proxy:
external: true
+315
View File
@@ -0,0 +1,315 @@
Install VaultWarden
https://www.techaddressed.com/tutorials/vaultwarden-docker-compose/
Docker Compose yml file
version: '3'
services:
vaultwarden:
container_name: vaultwarden
image: vaultwarden/server:latest
restart: unless-stopped
volumes:
- /home/miker/vaultwarden/data/:/data/
ports:
- 9050:80
environment:
- DOMAIN=https://vault.mikeandrebel.com
- LOGIN_RATELIMIT_MAX_BURST=10
- LOGIN_RATELIMIT_SECONDS=60
- ADMIN_RATELIMIT_MAX_BURST=10
- ADMIN_RATELIMIT_SECONDS=60
- ADMIN_TOKEN=create_token
- SENDS_ALLOWED=true
- EMERGENCY_ACCESS_ALLOWED=true
- WEB_VAULT_ENABLED=true
- SIGNUPS_ALLOWED=false
- SIGNUPS_VERIFY=true
- SIGNUPS_VERIFY_RESEND_TIME=3600
- SIGNUPS_VERIFY_RESEND_LIMIT=5
- SIGNUPS_DOMAINS_WHITELIST=example.us,example1.com
- SMTP_HOST=mail.mcfetridge.us
- SMTP_FROM=vaultwarden@example.us
- SMTP_FROM_NAME=Vaultwarden
- SMTP_SECURITY=starttls
- SMTP_PORT=587
- SMTP_USERNAME=vaultwarden@example.us
- SMTP_PASSWORD= !password
- SMTP_AUTH_MECHANISM="Login"
Create docker-compose.yml
Were ready now to create the docker-compose.yml file that will hold your Vaultwarden docker configuration. In this tutorial Im making use of the nano text editor and will give instructions specific to it. If you have a preference for a different editor, however, youre free to use it instead.
To begin, lets enter nano:
nano docker-compose.yml
If by some chance your system doesnt already have nano available already, you can install it on Debian / Ubuntu based systems with this command:
sudo apt install nano -y
When youve entered nano, you should start with a blank file. Your editor should look like the screenshot, below.
Blank docker-compose.yml file in nano
Blank docker-compose.yml file in nano
Instead of typing in the entire configuration, I recommend copying the entire configuration found under the Putting It All Together heading and pasting it into nano and then making the necessary changes. When youve finished making modifications, press CTRL + O then ENTER on your keyboard to save the file then press CTRL + X to exit nano.
The Basics
The contents of the docker-compose.yml file can be a bit much to take in at once. To make it easier to understand, Ive divided it into smaller sections.
Lets start with the bare minimum configuration required to get Vaultwarden running though I would NOT deploy a system using only these basic settings.
version: '3'
services:
vaultwarden:
container_name: vaultwarden
image: vaultwarden/server:latest
restart: unless-stopped
volumes:
- ./data/:/data/
ports:
- XXXX:80
Lets examine what these settings do.
container_name
This is the name that your container will be identified as in Docker. This can be anything you wish it to be, however, Id recommend just keeping it as vaultwarden to make it easy to identify.
image
The image setting informs docker which container image to use and which version. Here weve specified vaultwarden/server and then specified to always use the latest version.
restart
This tells Docker when to restart this container if its not running. While there are other values you could specify, Id recommend leaving it as Ive specified. Using unless-stopped will always restart your container when its not running unless youve stopped it yourself.
volumes
This is where we tell Docker how to map the data directory we created to be used inside the container. If you created a directory other than the one I specified earlier in this tutorial, youll want to be sure to modify the value on the. If you followed my directions, you can leave this as-is.
ports
This is where we map a port on the host system to the necessary port used inside the container. Inside the Vaultwarden container the software uses port 80. Specify which port youre using on the host on the left where Ive specified XXXX. Any valid port should work fine. IMPORTANT youll need to note which port youve chosen to open it in your firewall and specify it in your reverse proxys settings.
Environment Variables
Now lets add the environment variables well be adding into the file to help customize our Vaultwarden configuration. Note, these are not the only possible variables Vaultwarden has available for us to use. These are simply the ones I find the most necessary. You can consult the Vaultwarden environment variable documentation, if you wish, for additional options.
System Settings
This collection of settings deal with the configuration of Valutwarden itself.
- DOMAIN=https://subdomain.yourdomain.com
- LOGIN_RATELIMIT_MAX_BURST=10
- LOGIN_RATELIMIT_SECONDS=60
- ADMIN_RATELIMIT_MAX_BURST=10
- ADMIN_RATELIMIT_SECONDS=60
- ADMIN_TOKEN=YourReallyStrongAdminTokenHere
- SENDS_ALLOWED=true
- EMERGENCY_ACCESS_ALLOWED=true
- WEB_VAULT_ENABLED=true
Again, lets look at what each individual settings does.
DOMAIN
This is the domain you wish to associate with your Vaultwarden instance.
LOGIN_RATELIMIT_MAX_BURST
This is the maximum number of requests allowed in a burst of login / two-factor attempts while maintaining the average specified in LOGIN_RATELIMIT_SECONDS.
LOGIN_RATELIMIT_SECONDS
This is the average number of seconds between login requests from the same IP before Vaultwarden rate limits logins.
ADMIN_RATELIMIT_MAX_BURST
This is the same as LOGIN_RATELIMIT_MAX_BURST, only for the admin panel.
ADMIN_RATELIMIT_SECONDS
This is the same as LOGIN_RATELIMIT_SECONDS, only for the admin panel.
ADMIN_TOKEN
This value is the token (a type of password) for the Vaultwarden admin panel. For security, this should be a long random string of characters. The admin panel is disabled if this value is not set.
SENDS_ALLOWED
This setting determines whether users are allowed to create Bitwarden Sends a form of credential sharing.
EMERGENCY_ACCESS_ALLOWED
This setting controls whether users can enable emergency access to their accounts. This is useful, for example, so a spouse can access a password vault in the event of death so they can gain access to account credentials. Possible values: true / false.
WEB_VAULT_ENABLED
This setting determines whether or not the web vault is accessible. Stopping your container then switching this value to false and restarting Vaultwarden could be useful once youve configured your accounts and clients to prevent unauthorized access. Possible values: true/false.
Signup Settings
Finally, well look at settings used to control account signups in Vaultwarden. I think its safe to assume that you dont want just anyone to be able to create an account on your server and that youd like to add some sensible settings to improve security.
- SIGNUPS_ALLOWED=false
- SIGNUPS_VERIFY=true
- SIGNUPS_VERIFY_RESEND_TIME=3600
- SIGNUPS_VERIFY_RESEND_LIMIT=5
- SIGNUPS_DOMAINS_WHITELIST=yourdomainhere.com,anotherdomain.com
Lets look at the individual settings.
SIGNUPS_ALLOWED
This setting controls whether or not new users can register for accounts without an invitation. Possible values: true / false.
SIGNUPS_VERIFY
This setting determines whether or not new accounts must verify their email address before being able to login to Vaultwarden. Possible values: true / false.
SIGNUPS_VERIFY_RESEND_TIME
If SIGNUPS_VERIFY is set to true, this value specifies how many seconds a user must wait before another verification email can be sent.
SIGNUPS_VERIFY_RESEND_LIMIT
If SIGNUPS_VERIFY is set to true, this value specifies the maximum number of times an email verification may be re-sent.
SIGNUPS_DOMAINS_WHITELIST
This setting is a comma separated list of domains that can register for Vaultwarden accounts, even if SIGNUPS_ALLOWED is set to false. This is useful for when your Vaultwarden accounts are to be used specifically by email addresses whose domains you control.
SMTP Settings
I previously mentioned youll need a SMTP email account for your Vaultwarden service to be able to send emails. This is how well configure those account settings. A reminder these settings will depend on how your email provider has their systems configured.
- SMTP_HOST=smtp.youremaildomain.com
- SMTP_FROM=vaultwarden@youremaildomain.com
- SMTP_FROM_NAME=Vaultwarden
- SMTP_SECURITY=SECURITYMETHOD
- SMTP_PORT=XXXX
- SMTP_USERNAME=vaultwarden@youremaildomain.com
- SMTP_PASSWORD=YourReallyStrongPasswordHere
- SMTP_AUTH_MECHANISM="Mechanism"
Finally, our last group of settings.
SMTP_HOST
This is your SMTP mailserver.
SMTP_FROM
This is the email address messages will be sent from.
SMTP_FROM_NAME
The name you wish to appear as the email account name on sent messages
SMTP_SECURITY
The security method used by your SMTP server. Possible values: “starttls” / “force_tls” / “off”.
SMTP_PORT
This is the SMTP port used by your mail server. Possible values: 587 / 465.
SMTP_USERNAME
This is the login for your SMTP mail server.
SMTP_PASSWORD
This is the password for your SMTP credentials.
SMTP_AUTH_MECHANISM
This is the SMTP authentication mechanism of your mail server. Possible values: “Plain” / “Login” / “Xoauth2”.
Putting It All Together
Putting all the pieces together gives us this complete docker-compose.yml file. As Ive previously mentioned, copy and paste this into your editor and make the appropriate changes for your deployment.
version: '3'
services:
vaultwarden:
container_name: vaultwarden
image: vaultwarden/server:latest
restart: unless-stopped
volumes:
- ./data/:/data/
ports:
- XXXX:80
environment:
- DOMAIN=https://subdomain.yourdomain.com
- LOGIN_RATELIMIT_MAX_BURST=10
- LOGIN_RATELIMIT_SECONDS=60
- ADMIN_RATELIMIT_MAX_BURST=10
- ADMIN_RATELIMIT_SECONDS=60
- ADMIN_TOKEN=YourReallyStrongAdminTokenHere
- SENDS_ALLOWED=true
- EMERGENCY_ACCESS_ALLOWED=true
- WEB_VAULT_ENABLED=true
- SIGNUPS_ALLOWED=false
- SIGNUPS_VERIFY=true
- SIGNUPS_VERIFY_RESEND_TIME=3600
- SIGNUPS_VERIFY_RESEND_LIMIT=5
- SIGNUPS_DOMAINS_WHITELIST=yourdomainhere.com,anotherdomain.com
- SMTP_HOST=smtp.youremaildomain.com
- SMTP_FROM=vaultwarden@youremaildomain.com
- SMTP_FROM_NAME=Vaultwarden
- SMTP_SECURITY=SECURITYMETHOD
- SMTP_PORT=XXXX
- SMTP_USERNAME=vaultwarden@youremaildomain.com
- SMTP_PASSWORD=YourReallyStrongPasswordHere
- SMTP_AUTH_MECHANISM="Mechanism"
Starting The Container
Once youve finished editing the docker-compose.yml file, run this command from the vaultwarden directory to both create and start the container.
docker-compose up -d
The -d flag tells docker to run the container “detached” in the background instead of running in the foreground of your terminal. Without this flag, your container would stop running as soon as you close the terminal it was launched from.
The example screenshot, below, illustrates what you can expect to see once your container is created.
Example Output - "docker-compose up -d"
Example Output
Stopping The Container
If you ever have a need to stop your Vaultwarden container, simply run this command from your vaultwarden directory:
docker-compose down
Updating The Container
The same command you used to launch and start your container can also be used to update your container. First change into the vaultwarden directory:
cd ~/docker/vaultwarden
Then run:
docker-compose up -d
TIP: To simplify the process of updating my containers, I create a bash script that navigates to each docker subdirectory on my system and runs the necessary docker-compose command.
Containers do not have to be stopped in advance in order to perform updates.
Firewall Settings
Earlier, I specified to make note of what public port were exposing for your container on the host system. We need to ensure that port is open in your hosts firewall. If youre using the UFW firewall package that I previously mentioned under Prerequisites, you can open the port youve used with this command.
sudo ufw allow XXXX/tcp
Be sure you specify the port youve selected in place of XXXX.
Accessing The Web Vault
Once your container is up and running and youve confirmed that your reverse proxy is configured properly and your firewall port is open, accessing the web vault for the first time to create your Vaultwarden account should be as simple as entering your chosen domain into a browser. So, for example, if your domain is vault.mydomain.com, youd use this as the URL:
https://vault.mydomain.com/
If accessing Vaultwarden this way returns an error, attempt to access the system instead using your host systems IP and the port number you chose for Vaultwarden to confirm that it isnt the source of your problem. For example, if your hosts IP is 192.168.1.100 and youve chosen port 8000 the URL would be:
http://192.168.1.100:8000
If Vaultwarden loads in this way, the problem likely resides with your reverse proxy.
@@ -0,0 +1,20 @@
services:
# Vaultwarden Password Manager
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
security_opt:
- no-new-privileges:true
restart: unless-stopped
profiles: ["apps", "all"]
networks:
- default
ports:
- "$VAULTWARDEN_PORT:80"
environment:
# This is required to allow vaultwarden to verify the TLS certificate!
- DOMAIN=https://SUBDOMAIN-PLACEHOLDER.$DOMAINNAME_1
# - ADMIN_TOKEN=ADMIN-TOKEN-PLACEHOLDER
volumes:
- $DOCKERDIR/appdata/vaultwarden/data:/data
# DOCKER-LABELS-PLACEHOLDER
+17
View File
@@ -0,0 +1,17 @@
TZ=America/New_York
WATCHTOWER_CLEANUP=true
WATCHTOWER_INCLUDE_RESTARTING=true
WATCHTOWER_ROLLING_RESTARTING=true
WATCHTOWER_SCHEDULE=0 0 4 * * *
WATCHTOWER_INCLUDE_STOPPED=true
WATCHTOWER_NOTIFICATIONS=email
WATCHTOWER_NOTIFICATIONS_HOSTNAME=Docker-Deply # Add Server Name or IP Address
WATCHTOWER_NOTIFICATION_EMAIL_FROM=miker@mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_TO=miker@mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_SERVER=mail.mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=465
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=miker@mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=!Sucyetat123
WATCHTOWER_NOTIFICATION_EMAIL_DELAY=2
PUID=1000
PGID=1000
@@ -0,0 +1,31 @@
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
env_file: .env
environment:
- DOCKER_API_VERSION=1.44
- TZ=${TZ}
- PUID:=${PUID} # Reference PUID from .env
- PGID=${PGID} # Reference PGID from .env
- WATCHTOWER_CLEANUP=${WATCHTOWER_CLEANUP}
- WATCHTOWER_INCLUDE_RESTARTING=${WATCHTOWER_INCLUDE_RESTARTING}
- WATCHTOWER_ROLLING_RESTARTING=${WATCHTOWER_ROLLING_RESTARTING}
- WATCHTOWER_SCHEDULE=${WATCHTOWER_SCHEDULE}
- WATCHTOWER_INCLUDE_STOPPED=${WATCHTOWER_INCLUDE_STOPPED}
# - WATCHTOWER_NOTIFICATIONS=${WATCHTOWER_NOTIFICATIONS}
# - WATCHTOWER_NOTIFICATIONS_HOSTNAME=${WATCHTOWER_NOTIFICATIONS_HOSTNAME}
# - WATCHTOWER_NOTIFICATION_EMAIL_FROM=${WATCHTOWER_NOTIFICATION_EMAIL_FROM}
# - WATCHTOWER_NOTIFICATION_EMAIL_TO=${WATCHTOWER_NOTIFICATION_EMAIL_TO}
# - WATCHTOWER_NOTIFICATION_EMAIL_SERVER=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER}
# - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT}
# - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER}
# - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD}
security_opt:
- no-new-privileges:true
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
+4
View File
@@ -0,0 +1,4 @@
WG_HOST=wireguard.mikemcfetridge.com # Public IP or domain name whe>
PASSWORD="!Sucyetat123" # Password for accessing the WG-Easy web i>
PORT=51821 # Port for the web interface.
WG_PORT=51820
+1
View File
@@ -0,0 +1 @@
MP2igeozMSf2rqWLbvgHXDgoI9tOpe5nzscufB89xno=
+1
View File
@@ -0,0 +1 @@
3jCGyeho+tdqj6yrLa6NY5HAkQkVP+kL/ekHMgEyWHk=
@@ -0,0 +1,12 @@
[Interface]
PrivateKey = 4IliWQXfjdWFGafNmhCUnAaFdEQhdspjv0awh2MJ2XE=
Address = 10.8.0.4/24
DNS = 1.1.1.1
[Peer]
PublicKey = yqo3AIh4UpZMJm439z/ic++/op3T0Jrt27wBfgDthhY=
PresharedKey = dzf33VaZ0mSbS5HEVoLS3JqWsPP1tiwGTedEDLnqNuY=
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 0
Endpoint = wgeasy.mikemcfetridge.com:51820
@@ -0,0 +1,30 @@
Wireguard Made Easy
# Need to setup portforwarding on your router for 51820
# Enter domain url wg.example.com
# Enter in a password, this is for the gui.
# Docs - https://docs.techdox.nz/wgeasy/
version: '3.8'
services:
wg-easy:
image: ghcr.io/wg-easy/wg-easy # The Docker image to use.
container_name: wireguard # Name of the container.
environment: # Environment variables to configure the instance.
- LANG=en # Language settings.
- WG_HOST=wg.example.com # Public IP or domain name where WG-Easy is accessible.
- PASSWORD=<Password> # Password for accessing the WG-Easy web interface.
- PORT=51821 # Port for the web interface.
- WG_PORT=51820 # WireGuard port for VPN traffic.
volumes:
- /home/docker/wireguard:/etc/wireguard # Volume mapping for WireGuard configuration files.
ports:
- "51820:51820/udp" # UDP port used by WireGuard.
- "51821:51821/tcp" # TCP port for accessing the web interface.
cap_add: # Capabilities required for managing networking features.
- NET_ADMIN
- SYS_MODULE
sysctls: # Kernel parameters that need to be set for WireGuard.
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
restart: unless-stopped # Ensures the container restarts automatically unless manually stopped.

Some files were not shown because too many files have changed in this diff Show More