update
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 ""
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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:
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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!
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ADGUARD_PASSWORD=P@ssw0rd
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,4 @@
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
# TZ for container timezone
|
||||
TZ=America/New_York
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 you’ll 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
|
||||
@@ -0,0 +1,4 @@
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
# TZ for container timezone
|
||||
TZ=America/New_York
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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]
|
||||
@@ -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:
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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: {}
|
||||
@@ -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
|
||||
@@ -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 :)
|
||||
@@ -0,0 +1,5 @@
|
||||
WEBPASSWORD=e6z1EBVDERIP7
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
# TZ for container timezone
|
||||
TZ=America/New_York
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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=
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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, we’ll 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'
|
||||
@@ -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:
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
We’re ready now to create the docker-compose.yml file that will hold your Vaultwarden docker configuration. In this tutorial I’m making use of the nano text editor and will give instructions specific to it. If you have a preference for a different editor, however, you’re free to use it instead.
|
||||
|
||||
To begin, let’s enter nano:
|
||||
|
||||
nano docker-compose.yml
|
||||
|
||||
If by some chance your system doesn’t already have nano available already, you can install it on Debian / Ubuntu based systems with this command:
|
||||
|
||||
sudo apt install nano -y
|
||||
|
||||
When you’ve 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 you’ve 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, I’ve divided it into smaller sections.
|
||||
|
||||
Let’s 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
|
||||
|
||||
Let’s 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, I’d 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 we’ve specified vaultwarden/server and then specified to always use the latest version.
|
||||
|
||||
restart
|
||||
|
||||
This tells Docker when to restart this container if it’s not running. While there are other values you could specify, I’d recommend leaving it as I’ve specified. Using unless-stopped will always restart your container when it’s not running unless you’ve 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, you’ll 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 you’re using on the host on the left where I’ve specified XXXX. Any valid port should work fine. IMPORTANT – you’ll need to note which port you’ve chosen to open it in your firewall and specify it in your reverse proxy’s settings.
|
||||
Environment Variables
|
||||
|
||||
Now let’s add the environment variables we’ll 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, let’s 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 you’ve configured your accounts and clients to prevent unauthorized access. Possible values: true/false.
|
||||
Signup Settings
|
||||
|
||||
Finally, we’ll look at settings used to control account signups in Vaultwarden. I think it’s safe to assume that you don’t want just anyone to be able to create an account on your server and that you’d 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
|
||||
|
||||
Let’s 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 you’ll need a SMTP email account for your Vaultwarden service to be able to send emails. This is how we’ll 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 I’ve 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 you’ve 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 we’re exposing for your container on the host system. We need to ensure that port is open in your host’s firewall. If you’re using the UFW firewall package that I previously mentioned under Prerequisites, you can open the port you’ve used with this command.
|
||||
|
||||
sudo ufw allow XXXX/tcp
|
||||
|
||||
Be sure you specify the port you’ve selected in place of XXXX.
|
||||
Accessing The Web Vault
|
||||
|
||||
Once your container is up and running and you’ve 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, you’d 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 system’s IP and the port number you chose for Vaultwarden to confirm that it isn’t the source of your problem. For example, if your host’s IP is 192.168.1.100 and you’ve 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
MP2igeozMSf2rqWLbvgHXDgoI9tOpe5nzscufB89xno=
|
||||
@@ -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
Reference in New Issue
Block a user