migrate
This commit is contained in:
@@ -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,27 @@
|
||||
services:
|
||||
# Open-WebUI - User-friendly AI Interface
|
||||
open-webui:
|
||||
image: ghcr.io/open-webui/open-webui:main
|
||||
container_name: open-webui
|
||||
restart: unless-stopped
|
||||
profiles: [ "apps", "all" ]
|
||||
networks:
|
||||
- default
|
||||
depends_on:
|
||||
- ollama
|
||||
ports:
|
||||
- "$OPENWEBUI_PORT:8080"
|
||||
environment:
|
||||
- OLLAMA_BASE_URL=http://$SERVER_LAN_IP:$OLLAMA_PORT
|
||||
- WEBUI_SECRET_KEY=$OPENWEBUI_SECRET_KEY
|
||||
# - CORS_ALLOW_ORIGIN=
|
||||
- USER_AGENT=Open-WebUI
|
||||
volumes:
|
||||
- $DOCKERDIR/appdata/open-webui:/app/backend/data
|
||||
# DOCKER-LABELS-PLACEHOLDER
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "-f", "http://localhost:3000" ]
|
||||
interval: 10s
|
||||
retries: 3
|
||||
timeout: 10s
|
||||
start_period: 30s
|
||||
@@ -0,0 +1,20 @@
|
||||
services:
|
||||
searxng:
|
||||
container_name: searxng
|
||||
image: docker.io/searxng/searxng:latest
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- /opt/Docker-Deployments/searxng:/etc/searxng:rw
|
||||
- /opt/Docker-Deployments/searxng/data:/var/cache/searxng:rw
|
||||
environment:
|
||||
- SEARXNG_BASE_URL=https://search.mikemcfetridge.com
|
||||
- UWSGI_WORKERS=${SEARXNG_UWSGI_WORKERS:-4}
|
||||
- UWSGI_THREADS=${SEARXNG_UWSGI_THREADS:-4}
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "-f", "http://localhost:8080" ]
|
||||
interval: 10s
|
||||
retries: 3
|
||||
timeout: 10s
|
||||
start_period: 30s
|
||||
@@ -0,0 +1,54 @@
|
||||
##### My SearXNG personal settings. #
|
||||
use_default_settings: true
|
||||
|
||||
general:
|
||||
debug: false
|
||||
instance_name: "McFetridge Private Search" # Changes the name on the homepage and browser tabs
|
||||
|
||||
brand:
|
||||
docs_url: "" # Use empty strings instead of false
|
||||
issue_url: "" # Hides the links without crashing the parser
|
||||
custom:
|
||||
links:
|
||||
"Dockhand": "http://192.168.2.3:3200"
|
||||
"My Dashboard": "http://192.168.2.15:3100"
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
bind_address: "0.0.0.0"
|
||||
secret_key: "ee072bb45348da92be54b5224bee58b982a4279d3531f056b727c4dd3397bc3e"
|
||||
image_proxy: true # Proxies images through your server to protect your IP
|
||||
|
||||
search:
|
||||
default_lang: "en-US" # Force results to a specific region
|
||||
safe_search: 1 # 0 = None, 1 = Moderate, 2 = Strict
|
||||
autocomplete: "duckduckgo" # Upstream source for search suggestions
|
||||
formats:
|
||||
- html
|
||||
- json # Adds API capabilities for external script ingestion
|
||||
|
||||
ui:
|
||||
theme: simple
|
||||
results_on_new_tab: true # Keeps your engine open when browsing links
|
||||
default_locale: "en"
|
||||
default_interface: "general" # The default tab ("general", "images", "videos", "news", "it")
|
||||
|
||||
# This is the standard way to cleanly enable/disable specific engines in SearXNG
|
||||
engines:
|
||||
- name: google
|
||||
disabled: true
|
||||
|
||||
- name: duckduckgo
|
||||
disabled: false
|
||||
|
||||
- name: wikipedia
|
||||
disabled: false
|
||||
|
||||
- name: wikidata
|
||||
disabled: false
|
||||
|
||||
- name: bing
|
||||
disabled: false
|
||||
|
||||
- name: brave
|
||||
disabled: false
|
||||
@@ -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,9 @@
|
||||
services:
|
||||
myspeed:
|
||||
container_name: MySpeed
|
||||
image: germannewsmaker/myspeed
|
||||
ports:
|
||||
- '5216:5216'
|
||||
volumes:
|
||||
- ./myspeed:/myspeed/data
|
||||
restart: unless-stopped
|
||||
@@ -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 @@
|
||||
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,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,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,5 @@
|
||||
HOMARR_PORT=7575
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
# TZ for container timezone
|
||||
TZ=America/New_York
|
||||
@@ -0,0 +1,30 @@
|
||||
services:
|
||||
# Homarr - Application Dashboard
|
||||
homarr:
|
||||
image: ghcr.io/ajnart/homarr:latest
|
||||
container_name: homarr
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
networks:
|
||||
- default
|
||||
- socket_proxy
|
||||
ports:
|
||||
- "$HOMARR_PORT:7575"
|
||||
volumes:
|
||||
# - /var/run/docker.sock:/var/run/docker.sock # Optional, only if you want docker integration
|
||||
- ./appdata/homarr/configs:/app/data/configs
|
||||
- ./appdata/homarr/icons:/app/public/icons
|
||||
- ./appdata/homarr/data:/data
|
||||
environment:
|
||||
- DOCKER_HOST
|
||||
PUID: ${PUID} # Reference PUID from .env
|
||||
PGID: ${PGID} # # DOCKER-LABELS-PLACEHOLDER
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:7575"]
|
||||
interval: 10s
|
||||
retries: 3
|
||||
timeout: 10s
|
||||
start_period: 30s
|
||||
@@ -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,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,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,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,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,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,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,16 @@
|
||||
services:
|
||||
# DeUnhealth - Restart your unhealthy containers safely (e.g. containers depending on VPN and VPN reconnects)
|
||||
deunhealth:
|
||||
image: qmcgaw/deunhealth
|
||||
container_name: deunhealth
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
restart: unless-stopped
|
||||
profiles: ["apps", "all"]
|
||||
networks:
|
||||
- socket_proxy
|
||||
environment:
|
||||
- LOG_LEVEL=info
|
||||
- HEALTH_SERVER_ADDRESS=127.0.0.1:9999
|
||||
- TZ=$TZ
|
||||
- DOCKER_HOST
|
||||
@@ -0,0 +1,25 @@
|
||||
services:
|
||||
# qBittorrent - Torrent downloader
|
||||
qbittorrent-vpn:
|
||||
image: lscr.io/linuxserver/qbittorrent:latest
|
||||
container_name: qbittorrent-vpn
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
restart: unless-stopped
|
||||
profiles: ["apps", "downloads", "all"]
|
||||
network_mode: "service:gluetun"
|
||||
volumes:
|
||||
- $DOCKERDIR/appdata/qbittorrent-vpn:/config
|
||||
- $DOWNLOADSDIR:/data/downloads # Ensure that downloads folder is set to /data/downloads in qBittorrent
|
||||
environment:
|
||||
TZ: $TZ
|
||||
PUID: $PUID
|
||||
PGID: $PGID
|
||||
UMASK_SET: 002
|
||||
healthcheck: # https://github.com/qdm12/gluetun/issues/641#issuecomment-933856220
|
||||
test: "curl -sf https://example.com || exit 1"
|
||||
interval: 1m
|
||||
timeout: 10s
|
||||
retries: 1
|
||||
labels: # Traefik labels added via file provider app-qbittorrent.yml in rules folder
|
||||
- "deunhealth.restart.on.unhealthy=true"
|
||||
@@ -0,0 +1,22 @@
|
||||
services:
|
||||
# qBittorrent - Torrent downloader
|
||||
qbittorrent:
|
||||
image: lscr.io/linuxserver/qbittorrent:latest
|
||||
container_name: qbittorrent
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
restart: unless-stopped
|
||||
profiles: ["apps", "downloads", "all"]
|
||||
networks:
|
||||
- default
|
||||
ports:
|
||||
- "$QBITTORRENT_PORT:8080"
|
||||
volumes:
|
||||
- $DOCKERDIR/appdata/qbittorrent:/config
|
||||
- $DOWNLOADSDIR:/data/downloads # Ensure that downloads folder is set to /data/downloads in qBittorrent
|
||||
environment:
|
||||
TZ: $TZ
|
||||
PUID: $PUID
|
||||
PGID: $PGID
|
||||
UMASK_SET: 002
|
||||
# DOCKER-LABELS-PLACEHOLDER
|
||||
@@ -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,18 @@
|
||||
---
|
||||
services:
|
||||
duplicati:
|
||||
image: lscr.io/linuxserver/duplicati:latest
|
||||
container_name: duplicati
|
||||
environment:
|
||||
- PUID=1000 # Your host user ID
|
||||
- PGID=1000 # Your host group ID
|
||||
- TZ=America/New_York
|
||||
- SETTINGS_ENCRYPTION_KEY=84Jo17Ecw5muzGgqVjpeZQYnWBH7XFM7R01CdR646jSIfNbxgp # <-- Add this line
|
||||
volumes:
|
||||
- /home/miker/docker/duplicati/config:/config
|
||||
- /home/miker/docker/immich/library:/source/photos:ro # Mounts your photo directory as read-only
|
||||
- /home/miker/docker:/source/apps:ro # Mounts your application data files
|
||||
- /home/miker/docker/duplicati/backups:/backups # Optional local backup location
|
||||
ports:
|
||||
- 8250:8200
|
||||
restart: unless-stopped
|
||||
@@ -0,0 +1,6 @@
|
||||
OWNCLOUD_VERSION=latest
|
||||
OWNCLOUD_DOMAIN=129.213.86.62:8080
|
||||
OWNCLOUD_TRUSTED_DOMAINS=129.213.86.62,owncloud.mcfetridge.us,localhost
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=admin
|
||||
HTTP_PORT=8080
|
||||
@@ -0,0 +1,72 @@
|
||||
version: "3"
|
||||
|
||||
volumes:
|
||||
files:
|
||||
driver: local
|
||||
mysql:
|
||||
driver: local
|
||||
redis:
|
||||
driver: local
|
||||
|
||||
services:
|
||||
owncloud:
|
||||
image: owncloud/server:${OWNCLOUD_VERSION}
|
||||
container_name: owncloud_server
|
||||
restart: always
|
||||
ports:
|
||||
- ${HTTP_PORT}:8080
|
||||
depends_on:
|
||||
- mariadb
|
||||
- redis
|
||||
environment:
|
||||
- OWNCLOUD_DOMAIN=${OWNCLOUD_DOMAIN}
|
||||
- OWNCLOUD_TRUSTED_DOMAINS=${OWNCLOUD_TRUSTED_DOMAINS}
|
||||
- OWNCLOUD_DB_TYPE=mysql
|
||||
- OWNCLOUD_DB_NAME=owncloud
|
||||
- OWNCLOUD_DB_USERNAME=owncloud
|
||||
- OWNCLOUD_DB_PASSWORD=owncloud
|
||||
- OWNCLOUD_DB_HOST=mariadb
|
||||
- OWNCLOUD_ADMIN_USERNAME=${ADMIN_USERNAME}
|
||||
- OWNCLOUD_ADMIN_PASSWORD=${ADMIN_PASSWORD}
|
||||
- OWNCLOUD_MYSQL_UTF8MB4=true
|
||||
- OWNCLOUD_REDIS_ENABLED=true
|
||||
- OWNCLOUD_REDIS_HOST=redis
|
||||
healthcheck:
|
||||
test: ["CMD", "/usr/bin/healthcheck"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
volumes:
|
||||
- files:/mnt/data
|
||||
|
||||
mariadb:
|
||||
image: mariadb:10.11 # minimum required ownCloud version is 10.9
|
||||
container_name: owncloud_mariadb
|
||||
restart: always
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=owncloud
|
||||
- MYSQL_USER=owncloud
|
||||
- MYSQL_PASSWORD=owncloud
|
||||
- MYSQL_DATABASE=owncloud
|
||||
- MARIADB_AUTO_UPGRADE=1
|
||||
command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=owncloud"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
volumes:
|
||||
- mysql:/var/lib/mysql
|
||||
|
||||
redis:
|
||||
image: redis:6
|
||||
container_name: owncloud_redis
|
||||
restart: always
|
||||
command: ["--databases", "1"]
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
volumes:
|
||||
- redis:/data
|
||||
@@ -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,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,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,21 @@
|
||||
services:
|
||||
metube:
|
||||
image: alexta69/metube:latest
|
||||
container_name: metube
|
||||
ports:
|
||||
- "7000:8080"
|
||||
volumes:
|
||||
- /home/miker/docker/metube/downloads:/downloads # Mounts a local 'downloads' directory to the container's /downloads
|
||||
- /home/miker/docker/metube/config:/config # Mounts a local 'config' directory for MeTube's configuration
|
||||
- /home/miker/docker/metube/.cache:/.cache
|
||||
environment:
|
||||
- DOWNLOAD_DIR=/downloads
|
||||
- UID=1000
|
||||
- GID=1000
|
||||
- DEFAULT_THEME=dark
|
||||
- URL_PREFIX=/metube # If running behind a reverse proxy with a subpath
|
||||
- 'YTDL_OPTIONS={"format": "best", "exec": "ffmpeg -i %(filepath)q -c:v libx264 -c:a aac %(filepath)q.h264.mp4"}'
|
||||
- HTTPS=true # If you're directly configuring HTTPS in MeTube
|
||||
- OUTPUT_TEMPLATE=%(title)s.%(id)s.%(ext)s # Corrected format
|
||||
- DELETE_FILE_ON_TRASHCAN=true
|
||||
restart: unless-stopped
|
||||
@@ -0,0 +1,91 @@
|
||||
build the server
|
||||
|
||||
1. ) sudo -i # Switch to root
|
||||
2.) apt update && apt upgrade -y
|
||||
3.) Create /data directory structure.
|
||||
sudo mkdir -p /data/{torrents/{movies,tv,music},media/{movies,tv,music}}
|
||||
sudo chown -R $(id -u):$(id -g) /data
|
||||
sudo chmod -R 775 /data
|
||||
|
||||
4.) Install fail2ban then stop and disable it (as it freezes the install program)
|
||||
Stop service: sudo systemctl stop fail2ban
|
||||
Disable on boot: sudo systemctl disable fail2ban
|
||||
|
||||
4.) curl -fsSL https://get.tomsparkbox.com/install.sh | sudo bash
|
||||
|
||||
5.) Run through the checklist wizard.
|
||||
|
||||
6.) When the wizard is done, you will need to go into the gluetun config file and add the preshared key and the FIREWALL_VPN_INPUT_PORTS
|
||||
# Edit your credentials
|
||||
nano /opt/sparkbox/.env
|
||||
# Fix VPN_PROVIDER, WIREGUARD_PRIVATE_KEY, etc.
|
||||
sparkbox restart media
|
||||
|
||||
7.) Go into the systems and set them up.
|
||||
Prawlarr up a couple of indexers.
|
||||
radaar, sonarr, and qbittorrent and setup the login page
|
||||
qbit login and change password (password in /opt/sparkbox/state/qbittorrent-admin-password.txt)
|
||||
Jellyfin wizard + Seerr sign-in, run:
|
||||
|
||||
9.) (Auto) Libraries created by media-finish, run sudo sparkbox media-finish
|
||||
|
||||
|
||||
Finding Auto-Generated Credentials
|
||||
SparkBox pre-seeds a few service passwords and stores them in plaintext files under /opt/sparkbox/state/:
|
||||
|
||||
Service File Where to enter it
|
||||
Portainer portainer-admin-password.txt First login at :9000
|
||||
qBittorrent qbittorrent-admin-password.txt First login at :8089 (user admin)
|
||||
Sonarr / Radarr / Prowlarr auto-configured by arr-bootstrap Auth disabled on LAN; no password needed
|
||||
Jellyfin none — you pick it First-run wizard at :8096
|
||||
Nginx Proxy Manager none — upstream default First login: admin@example.com / changeme
|
||||
|
||||
|
||||
|
||||
"Root Folder Does Not Exist" in Radarr/Sonarr
|
||||
The /data directory structure has not been created.
|
||||
|
||||
sudo mkdir -p /data/{torrents/{movies,tv,music},media/{movies,tv,music}}
|
||||
sudo chown -R $(id -u):$(id -g) /data
|
||||
sudo chmod -R 775 /data
|
||||
|
||||
/data/
|
||||
├── torrents/ # qBittorrent downloads here
|
||||
│ ├── movies/
|
||||
│ ├── tv/
|
||||
│ └── music/
|
||||
└── media/ # Radarr/Sonarr organize here (Jellyfin reads from here)
|
||||
├── movies/
|
||||
├── tv/
|
||||
└── music/
|
||||
|
||||
|
||||
|
||||
|
||||
CLI Quick Reference
|
||||
bash
|
||||
Copy
|
||||
sparkbox status # See what's running
|
||||
sparkbox up # Start all enabled modules
|
||||
sparkbox down # Stop everything
|
||||
sparkbox restart # Restart all services
|
||||
sparkbox restart privacy # Restart just one module
|
||||
sparkbox update # Pull latest app images
|
||||
sparkbox upgrade # Upgrade SparkBox itself to the latest release
|
||||
sparkbox logs sb-NAME # View service logs
|
||||
sparkbox modules # List all modules
|
||||
sparkbox enable cloud # Enable a module
|
||||
sparkbox disable files # Disable a module
|
||||
sparkbox backup # Create a backup
|
||||
sparkbox restore FILE # Restore from backup
|
||||
sparkbox urls # Show all service URLs
|
||||
sparkbox help # Full command list
|
||||
|
||||
|
||||
|
||||
Uninstalling
|
||||
bash
|
||||
Copy
|
||||
sparkbox down
|
||||
rm -rf /opt/sparkbox
|
||||
rm -f /usr/local/bin/sparkbox
|
||||
@@ -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,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,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,73 @@
|
||||
services:
|
||||
postgresql-server:
|
||||
image: postgres:latest
|
||||
container_name: postgresql-server
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
volumes:
|
||||
- postgresql-data:/var/lib/postgresql/data
|
||||
|
||||
zabbix-server:
|
||||
image: zabbix/zabbix-server-pgsql:latest
|
||||
container_name: zabbix-server
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- postgresql-server
|
||||
environment:
|
||||
DB_SERVER_HOST: postgresql-server
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
ports:
|
||||
- "10051:10051"
|
||||
volumes:
|
||||
- zabbix-server-data:/var/lib/zabbix
|
||||
- zabbix-snmptraps-data:/var/lib/zabbix/snmptraps
|
||||
- zabbix-export-data:/var/lib/zabbix/export
|
||||
|
||||
zabbix-web-nginx-pgsql:
|
||||
image: zabbix/zabbix-web-nginx-pgsql:latest
|
||||
container_name: zabbix-web
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- postgresql-server
|
||||
- zabbix-server
|
||||
environment:
|
||||
DB_SERVER_HOST: postgresql-server
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
ZBX_SERVER_HOST: zabbix-server
|
||||
PHP_TZ: ${PHP_TZ}
|
||||
ports:
|
||||
- "${ZABBIX_FRONTEND_PORT}:8080"
|
||||
volumes:
|
||||
- zabbix-web-data:/usr/share/zabbix
|
||||
|
||||
zabbix-agent:
|
||||
image: zabbix/zabbix-agent:latest
|
||||
container_name: zabbix-agent
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- zabbix-server
|
||||
environment:
|
||||
ZBX_HOSTNAME: "zabbix-server"
|
||||
ZBX_SERVER_HOST: zabbix-server
|
||||
ZBX_SERVER_PORT: '10051'
|
||||
ZBX_SERVER_ACTIVE: zabbix-server
|
||||
volumes:
|
||||
- /:/rootfs:ro
|
||||
- /var/run:/var/run
|
||||
privileged: true
|
||||
|
||||
volumes:
|
||||
postgresql-data:
|
||||
zabbix-server-data:
|
||||
zabbix-snmptraps-data:
|
||||
zabbix-export-data:
|
||||
zabbix-web-data:
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
POSTGRES_USER=zabbix
|
||||
POSTGRES_PASSWORD=EpvfxaNSbtaJ6HYBQCZl
|
||||
POSTGRES_DB=zabbix
|
||||
PHP_TZ=America/New_York
|
||||
ZABBIX_FRONTEND_PORT=4080
|
||||
@@ -0,0 +1,12 @@
|
||||
services:
|
||||
dozzle-agent:
|
||||
image: amir20/dozzle:latest
|
||||
container_name: dozzle-agent
|
||||
command: agent
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
ports:
|
||||
- 7007:7007
|
||||
# volumes:
|
||||
# - /var/run/docker.sock:/var/run/docker.sock # Use Docker Socket Proxy instead for improved security
|
||||
# DOCKER-LABELS-PLACEHOLDER
|
||||
@@ -0,0 +1,22 @@
|
||||
services:
|
||||
dozzle:
|
||||
container_name: dozzle
|
||||
image: amir20/dozzle:latest
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
environment:
|
||||
- DOZZLE_REMOTE_AGENT=192.168.2.16:7007
|
||||
- DOZZLE_LEVEL=info
|
||||
- DOZZLE_TAILSIZE=300
|
||||
- DOZZLE_FILTER="status=running"
|
||||
# - DOZZLE_FILTER="label=log_me" # limits logs displayed to containers with this label
|
||||
- DOCKER_HOST
|
||||
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
ports:
|
||||
- 8089:8080
|
||||
|
||||
restart: unless-stopped
|
||||
@@ -0,0 +1,26 @@
|
||||
services:
|
||||
speedtest-tracker:
|
||||
image: lscr.io/linuxserver/speedtest-tracker:latest
|
||||
container_name: speedtest-tracker
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
restart: unless-stopped
|
||||
profiles: ["apps", "all"]
|
||||
networks:
|
||||
- default
|
||||
ports:
|
||||
- "$SPEEDTESTTRACKER_PORT:80"
|
||||
environment:
|
||||
TZ: $TZ
|
||||
PUID: $PUID
|
||||
PGID: $PGID
|
||||
DB_CONNECTION: sqlite
|
||||
APP_KEY: $SPEEDTEST_TRACKER_APP_KEY #optional
|
||||
# DB_HOST: mariadb #optional
|
||||
# DB_PORT: 3306 #optional
|
||||
# DB_DATABASE: speedtest #optional
|
||||
# DB_USERNAME: speedtest_user #optional
|
||||
# DB_PASSWORD: ST-DB-PASSWORD-PLACEHOLDER #optional
|
||||
volumes:
|
||||
- $DOCKERDIR/appdata/speedtest-tracker:/config
|
||||
# DOCKER-LABELS-PLACEHOLDER
|
||||
@@ -0,0 +1,62 @@
|
||||
version: "3.9"
|
||||
|
||||
# Common defaults for all services - use with: <<: *default-service
|
||||
x-common: &default-service
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
networks:
|
||||
- home_network
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
services:
|
||||
my-service:
|
||||
# Inherit common defaults
|
||||
<<: *default-service
|
||||
|
||||
# Use specific image version tag, never :latest
|
||||
image: example/app:1.2.3
|
||||
|
||||
# Environment Management
|
||||
environment:
|
||||
TZ: America/New_York
|
||||
PUID: "1000"
|
||||
PGID: "1000"
|
||||
# Add service-specific env vars here
|
||||
|
||||
# Networking - port mapping (optional)
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
||||
# Resource Constraints (native Compose limits, not Swarm deploy)
|
||||
mem_limit: 512M
|
||||
cpus: 0.5
|
||||
|
||||
# Persistent Storage
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- ./data:/data
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
|
||||
# Health Checks (customize based on your service)
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
networks:
|
||||
home_network:
|
||||
external: true
|
||||
# If proxy_network does not exist, create it first:
|
||||
# docker network create proxy_network
|
||||
|
||||
# Alternatively, manage the network in this file:
|
||||
# driver: bridge
|
||||
# driver_opts:
|
||||
# com.docker.network.bridge.name: "br-proxy"
|
||||
@@ -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,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,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.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
services:
|
||||
wg-easy:
|
||||
image: ghcr.io/wg-easy/wg-easy:latest # The Docker image to use.
|
||||
container_name: wireguard # Name of the container.
|
||||
env_file:
|
||||
- .env
|
||||
environment: # Environment variables to configure the ins>
|
||||
- LANG=en # Language settings.
|
||||
- WG_HOST=${WG_HOST} # Public IP or domain name whe>
|
||||
- PASSWORD=${PASSWORD} # Password for accessing the WG-Easy web i>
|
||||
- PORT=${PORT} # Port for the web interface.
|
||||
- WG_PORT=${WG_PORT} # WireGuard port for VPN traffic.
|
||||
volumes:
|
||||
- ./data:/etc/wireguard # Volume mapping for WireG>
|
||||
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 network>
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
sysctls: # Kernel parameters that need to be set for >
|
||||
- net.ipv4.conf.all.src_valid_mark=1
|
||||
- net.ipv4.ip_forward=1
|
||||
restart: unless-stopped # Ensures the container restarts automatical>
|
||||
|
||||
# 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
|
||||
+249
@@ -0,0 +1,249 @@
|
||||
# Setting up a Remote Access Wireguard VPN with Netmaker
|
||||
|
||||
<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/X-BYDYoM_3w" width="560"></iframe>
|
||||
|
||||
In Business, or home use, networking is often a very *tough nut to crack*. In today's world, where we choose privacy over convenience, the search continues for solutions to help us have a seamless experience in accessing our data, applications, system, and media. I've done literally hundreds of videos on so many amazing applications, but at the end of the day it all comes down to access. We want to have access to our systems regardless of where we are in the world.
|
||||
|
||||
Netmaker is an absolute beast of a tool that provides exactly what we are all looking for. It runs on top of the very secure, very fast, Wireguard protocol. This means we can setup a cloud based network, but make it feel like we are right there at our office, or in our home on the local network. The little bit of what I'll discuss in this post, and demonstrate to you in the video is just the tip of the metaphorical iceberg. The limitations are only what you can think up for your networking needs. But tools like Netmaker are what make open source such a valuable asset.
|
||||
|
||||
### Installation
|
||||
|
||||
#### What we'll cover today
|
||||
|
||||
1. How to install the Netmaker server, and create a network.
|
||||
2. How to install the Netmaker Client and join a network.
|
||||
3. How to setup Ingress and Egress nodes (and what those are).
|
||||
4. How to setup external clients (and what that means)
|
||||
5. How to connect back to our Local Area Network without opening any firewall ports.
|
||||
|
||||
#### What you'll need
|
||||
|
||||
- A server with a static public IP address. (I used a Digital Ocean droplet with 1 vCPU and 1 GB RAM)
|
||||
- A machine inside our Local Area network that we can use as a gateway device on our Wireguard network.
|
||||
- A machine we want to connect to our LAN from outside (a smart phone, tablet, laptop, or even a machine on another network somewhere).
|
||||
- Preferably a Domain name that you own, and can add a subdomain and A-record DNS entry for.
|
||||
- Docker and Docker-Compose on our server.
|
||||
- About 30 minutes of time.
|
||||
|
||||
##### Installing the Server
|
||||
|
||||
As always, I highly recommend that you follow the instructions on the netmaker site for server installation, as this will be the most up to date method based on version. As of the making of this article and accompanying video, Netmaker is on version 0.16.0. You can find [their instructions for installation here.](https://docs.netmaker.org/quick-start.html)
|
||||
|
||||
First, we'll need a server (netmaker is known to run well on Ubuntu servers, so I made mine 22.04) to install the Netmaker server on. I highly recommend setting this up on a ninexpensive VPS. If you use [my Digital Ocean link](https://m.do.co/c/a6a61ae5524) you can sign up for a 60 Day / $200.00 US trial. Which means you'll pay nothing for the first 2 months of the $6 server we'll use for this purpose. That said, feel free to use a server on Linode, Vultr, Hertzner, or whoever you prefer.
|
||||
|
||||
<p class="callout warning">NOTE: The Netmaker folks have identified issues with using the Oracle Cloud Free Tier server for Wireguard in general, and do not suggest you use that service for this purpose.</p>
|
||||
|
||||
When you've got your server created, you'll get a public IPv4 IP address assigned to it. You'll want to get that IPv4 address, and create an A-record for a subdomain on a domain that you own. I own the domain "theitpros.org", so I setup an A-record in my registrar's DNS settings to point the subdomain of "\**.*netmaker.theitpros.org" to my public IPv4 address. You should do something similar, with your domain. Create an A-record for "*\**.netmaker.<your-super-domain>" pointing to your server's IPv4 address.
|
||||
|
||||
Next, you'll need to install Docker and Docker-Compose. In the Netmaker instructions they give you a single command to install docker.io, docker-compose, and Wireguard on a server. I however, prefer to use Docker-CE to docker.io. It's completely up to you, and the system works with either one.
|
||||
|
||||
Follow these steps to install Docker-CE and Docker-Compose using my method:
|
||||
|
||||
```
|
||||
wget https://gitlab.com/bmcgonag/docker_installs/-/raw/main/install_docker_nproxyman.sh
|
||||
```
|
||||
|
||||
Next, change the permissions on the downloaded file:
|
||||
|
||||
`chmod +x install_docker_nproxyman.sh`
|
||||
|
||||
And run the script with:
|
||||
|
||||
`./install_docker_nproxyman.sh`
|
||||
|
||||
Now, select your base OS by number. Next, you need to answer "y" to the first two questions about installing Docker-CE and Docker-Compose. Feel free to answer "n" to the other questions. The script will attempt to update and upgrade your install first.
|
||||
|
||||
Next, install Wireguard with one of the following commands:
|
||||
|
||||
Ubuntu:
|
||||
|
||||
`sudo apt install wireguard -y`
|
||||
|
||||
Fedora
|
||||
|
||||
`sudo dnf install wireguard-tools -y`
|
||||
|
||||
Arch
|
||||
|
||||
`sudo pacman -S wireguard-tools`
|
||||
|
||||
<p class="callout info">Please run any upgrades before running the script, as many VPS upgrades will show a prompt that my script down not display.</p>
|
||||
|
||||
After the script completes, you can continue with the installation of Netmaker.
|
||||
|
||||
If you have a firewall enabled in front of your chosen server, you'll need to open a few ports to allow Wireguard traffic to flow (this is why we want this installed in a VPS).
|
||||
|
||||
Open Ports:
|
||||
|
||||
- 443 (TCP)
|
||||
- 51821-51899 (UDP) You can make this range smaller, but if you want to eventually setup more than one network, you'll want to have a port for each network to run on.
|
||||
|
||||
```
|
||||
sudo ufw allow proto tcp from any to any port 443 && sudo ufw allow 51821:51830/udp
|
||||
```
|
||||
|
||||
```
|
||||
iptables --policy FORWARD ACCEPT
|
||||
```
|
||||
|
||||
Next, you'll get your docker-compose.yml file ready. First run the command:
|
||||
|
||||
```
|
||||
ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
|
||||
```
|
||||
|
||||
The following lines will pull down the docker-compose.yml file that's already prepared, from the Netmaker repository. After that you'll replace the parts surrounded with angle-brackets "<" and ">" with your actual base subdomain (mine was "netmaker.theitpros.org"). You'll need to replace the angle-brackets themselves as well. For IP, put the public IPv4 address you received for your server. For email, you can use any email you want.
|
||||
|
||||
```
|
||||
wget -O docker-compose.yml https://raw.githubusercontent.com/gravitl/netmaker/master/compose/docker-compose.yml
|
||||
sed -i 's/NETMAKER_BASE_DOMAIN/<your base domain>/g' docker-compose.yml
|
||||
sed -i 's/SERVER_PUBLIC_IP/<your server ip>/g' docker-compose.yml
|
||||
sed -i 's/YOUR_EMAIL/<your email>/g' docker-compose.yml
|
||||
```
|
||||
|
||||
Next, we'll create a secret key value for our server as well.
|
||||
|
||||
```
|
||||
tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo ''
|
||||
```
|
||||
|
||||
And now we'll place that key value into the docker-compose file using the same method as the commands above. Replace the value with the angle brackets, **including the angle-brackets themselves**, with the actual key value.
|
||||
|
||||
```
|
||||
sed -i 's/REPLACE_MASTER_KEY/<your generated key>/g' docker-compose.yml
|
||||
```
|
||||
|
||||
Now we need to download one more file. The last file we need is a Mosquitto (MQTT Server) file. Mosquitto is a message queue server application. This is the software that allows messages to be sent and recieved on a network, and is part of how netmaker keeps your client machines in sync.
|
||||
|
||||
```
|
||||
wget -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf
|
||||
```
|
||||
|
||||
<p class="callout info">NOTE: After version 0.16.1, you'll need to do two more steps.
|
||||
1. Cretae a unique, strong password for the Mosquitto configuration file, and add it to the docker-compose.
|
||||
2. Download a "wait" script, for use on the server.
|
||||
|
||||
The commands for these 2 steps are:
|
||||
</p>
|
||||
|
||||
```
|
||||
sed -i "s/REPLACE_MQ_ADMIN_PASSWORD/<mqtt admin password>/g" docker-compose.yml
|
||||
```
|
||||
|
||||
<p class="callout info">Where you'll replace the the angle-brackets and information between them with a password of your creation.</p>
|
||||
|
||||
```
|
||||
wget -q -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/develop/docker/wait.sh
|
||||
chmod +x wait.sh
|
||||
```
|
||||
|
||||
We are now ready to start the Netmaker server with the following command:
|
||||
|
||||
`sudo docker-compose up -d`
|
||||
|
||||
Once the images have all been pulled down, and you have started your containers (you see 'done' in the command line for all containers, and you are back at the prompt), you'll want to open your favorite modern browser of choice, and navigate to the address:
|
||||
|
||||
https://dashboard.netmaker.<your super domain>
|
||||
|
||||
In my case, I went to
|
||||
|
||||
[https://dashboard.netmaker.theitpros.org](https://dashboard.netmaker.theitpros.org)
|
||||
|
||||
Once at your new domain, you'll be prompted to create an account. Enter an email you want, doesn't have to be the same as the one you put in the docker-compose file, and a strong password.
|
||||
|
||||
Once saved, you'll be taken to the login screen. Lovin, and you'll see your Netmaker dashboard.
|
||||
|
||||
##### Create a Network
|
||||
|
||||
Now, you'll want to create a network in Netmaker. Click the 'Networks' tile on the dashboard, or in the left navigation panel click 'Networks'.
|
||||
|
||||
On the Networks screen, you'll want to click on the 'Create Network' button.
|
||||
|
||||
In the subsequent form, give you network a name, and then enter a private IP address and range in CIDR notation, you'd like for the network. Alternatively, there is an 'Autofill' button you can click, and then change the name, or network IP generated by the autofill option.
|
||||
|
||||
[](https://wiki.opensourceisawesome.com/uploads/images/gallery/2022-10/image.png)
|
||||
|
||||
Next, select whether to add IPv6, and whether you want UDP hole punching to be enabled. UDP hole punching can be usefule, but is not always necessary. If you leave it off, and later determine you want to enable it, you can edit the network.
|
||||
|
||||
Finally, after selecting the options you want, click 'Create Network'.
|
||||
|
||||
You new network will be created if you have entered a name that is 12 characters or less, and have not tried to enter an improper IP address and / or range.
|
||||
|
||||
#### Netmaker Client Installation
|
||||
|
||||
Now that you have a Wireguard server in the cloud, running Netmaker, you'll likely want to connect a machine or 50 to the network. The easiest way with the most benefits is to use the Netmaker client. This is a tool you install on any machine / device that you want to be able to connect to the Netmaker network / server you just created. There are clients for MacOS, Linux, BSD, and yes...even Windows. There is also a graphical client (GUI) which is installed by default on Windows and MacOS, but is a separate install for Linux / BSD. You can download the GUI for Linux and BSD on their [Github releases page](https://github.com/gravitl/netmaker/releases).
|
||||
|
||||
To avoid causing issues, I will only provide the link to the client install page. There are instructions for many different distributions there, and as those change, I don't want my documentation to give bad information. [Please go to the official Netmaker documentation pages for the proper installation instruction of the Netclient](https://docs.netmaker.org/netclient.html).
|
||||
|
||||
Once you have the Netclient installed, you'll want to go back to your Web Admin page, and go to "Access Keys" in the dashboard or left navigation.
|
||||
|
||||
Once in Access Keys, select the network you'd like to add a node for.
|
||||
|
||||
<p class="callout info">You can add multiple networks in Netmaker, and add nodes to each network individually. A single machine can be a node on multiple networks by using the Netclient to join those networks.</p>
|
||||
|
||||
Then click Create Access Key.
|
||||
|
||||
[](https://wiki.opensourceisawesome.com/uploads/images/gallery/2022-10/n4Yimage.png)
|
||||
|
||||
Next, increase the number of access keys. You can use an access key more than once. You could provide Fred an access key for his Laptop, Desktop, and CI Server. You only need to create once access key for Fred, but allocate it for three (3) uses.
|
||||
|
||||
[](https://wiki.opensourceisawesome.com/uploads/images/gallery/2022-10/ySjimage.png)
|
||||
|
||||
Now click the 'Create' button.
|
||||
|
||||
You'll see a bunch of different lines with options for adding the key to various nodes.
|
||||
|
||||
[](https://wiki.opensourceisawesome.com/uploads/images/gallery/2022-10/TrJimage.png)
|
||||
|
||||
<p class="callout warning">Don't worry, the example join above isn't functional anymore.</p>
|
||||
|
||||
Now, you'll paste this into the terminal of your desired client, and be joined to the network. You should now be able to ping the IP of your server machine, and any other peer machines on the network. If you have trouble joining with the Netclient, you can start through any troubleshooting steps in the Netmaker documentation, and you can always jump over to their Discord server to ask for help as well.
|
||||
|
||||
#### Ingress and Egress Nodes
|
||||
|
||||
The terminology is set from the perspective of the internet to the Netmaker netwrok. Ingress, meaning to come into, or a path inward is therefore indicative of a node that has been setup and identified as a method for an external client to connect the Network (we'll cover connecting external clients in the next section). Egress, means a point where the client machine can exit the Netmaker network, and go into another network such as a LAN inside your home or business.
|
||||
|
||||
What we want to setup is a network where we have an external client or netclient node external to our LAN, that can then successfully get back into our LAN via our Netmaker network, and access our various servers / machines / services inside the LAN.
|
||||
|
||||
In order to set this up, we'll need to first identify an Egress Node. Inside our Local Area Network, we'll install the Netclient, and join our Netmaker Network with it. You'll be able to see the node show up in the Netmaker Web Admin panel on the 'Nodes' view.
|
||||
|
||||
Next to this node, you'll see several icons. One is in the column form Egress. Click this corresponding icon,
|
||||
|
||||
[](https://wiki.opensourceisawesome.com/uploads/images/gallery/2022-10/Vxtimage.png)
|
||||
|
||||
You'll be prompted for two pieces of information.
|
||||
1\. The network interface you'll be using as the Egress point. You can find your network information from the command line with the command:
|
||||
|
||||
`ip -br -c a`
|
||||
|
||||
2\. The IP address range in CIDR notation, you want give access to on this network. In my case, my network is 192.168.10.x, so to give an external device access to the whole network, I would make the entry be
|
||||
|
||||
`192.168.10.0/24`
|
||||
|
||||
Now click on Create Egress. You should see the double arrow icon turn into a check mark for that node.
|
||||
|
||||
With your Egress gateway defined, you should now be able to ping any machine that can respond to ping requests that resides inside you selected LAN, from outside that LAN.
|
||||
|
||||
Next, we'll create an Ingress node. You generally don't want this to be the same node as your egress node, but it can be done. I simply setup my main Netmaker server node as my Ingress node. An ingress node is used to allow an "external" client into the netmaker network. Some machines / devices won't be running the Netclient, but fear not! These devices can still run Wireguard, and connect to the network using the External Client configuration file that can be generated in the server. Then simply use the wireguard app on mobile devices, or the CLI or a graphical Wireguard tool to connect these devices to your Netmaker networks.
|
||||
|
||||
Before you can create any external client configurations, you need to define an "Ingress" node. So, let's just use our Netmaker server for this...but note that any host that is reachable by a device can be used, but a public, static IP is preferred for this purpose.
|
||||
|
||||
In your 'Nodes' view, find your Netmaker server, and click the icon in its row that is in the "Ingress" column. Accept the prompt, and you should see the double tail icon turn into a check mark. You're done. You can now start creating External Clients.
|
||||
|
||||
#### External Clients
|
||||
|
||||
External clients are clients that will not have their setting synced when changes to the networks / other nodes are made. These are clients setup with a static configuration file. These clients will be able to connect to your network, and interact just fine, but don't get any automatic updates from the network. So, when possible, the Netclient (IMO) is a better choice.
|
||||
|
||||
Click on the 'External Clients' option from the dashboard, or from the left navigation panel. Select the Network for which you wish to create an external client. On the left side of the interface, you'll see a list of any Ingress nodes you've defined. Click the "+" icon next to the node you want to create external clients for.
|
||||
|
||||
[](https://wiki.opensourceisawesome.com/uploads/images/gallery/2022-10/g0Jimage.png)
|
||||
|
||||
On the right side you'll see External Client configurations being created. Feel free to click the QR Code to expand it onto the screen, or to download the client configuration to your desktop / laptop and use that to connect.
|
||||
|
||||
Notice, you can delete a client at any time, and you can remove / disable netclients, and change nodes back from being Egress or Ingress points. You really have total control over your Netmaker network from the ADmin dashboard and tools.
|
||||
|
||||
You now have the tools to make all kinds of amazing networks from Netmaker using Wireguard. Go forth, and be awesome!
|
||||
|
||||
#### Support my Channel and ongoing efforts through Patreon:
|
||||
|
||||
[https://www.patreon.com/bePatron?u=234177](https://www.patreon.com/bePatron?u=234177)
|
||||
@@ -0,0 +1,35 @@
|
||||
services:
|
||||
# WG-EASY - WireGuard Easy
|
||||
wg-easy:
|
||||
image: ghcr.io/wg-easy/wg-easy
|
||||
container_name: wg-easy
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
restart: unless-stopped
|
||||
profiles: ["core", "all"]
|
||||
networks:
|
||||
- default
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
sysctls:
|
||||
- net.ipv4.ip_forward=1
|
||||
- net.ipv4.conf.all.src_valid_mark=1
|
||||
ports:
|
||||
- "51820:51820/udp"
|
||||
- "$WGEASY_PORT:51821/tcp" # WebUI
|
||||
volumes:
|
||||
- $DOCKERDIR/appdata/wireguard:/etc/wireguard
|
||||
environment:
|
||||
- WG_HOST=SUBDOMAIN-PLACEHOLDER.$DOMAINNAME_1
|
||||
- PASSWORD_HASH=WG-EASY-PASSWORD-HASH-PLACEHOLDER
|
||||
- WG_DEFAULT_ADDRESS=$WGEASY_DEFAULT_ADDRESS
|
||||
- WG_DEFAULT_DNS=$WGEASY_DEFAULT_DNS
|
||||
- WG_ALLOWED_IPS=$WGEASY_ALLOWED_IPS
|
||||
- UI_TRAFFIC_STATS=true
|
||||
- UI_CHART_TYPE=3
|
||||
# - WG_PRE_UP=echo "Pre Up" > /etc/wireguard/pre-up.txt
|
||||
# - WG_POST_UP=echo "Post Up" > /etc/wireguard/post-up.txt
|
||||
# - WG_PRE_DOWN=echo "Pre Down" > /etc/wireguard/pre-down.txt
|
||||
# - WG_POST_DOWN=echo "Post Down" > /etc/wireguard/post-down.txt
|
||||
# DOCKER-LABELS-PLACEHOLDER
|
||||
@@ -0,0 +1,32 @@
|
||||
services:
|
||||
# Cloudflare DDNS - Dynamic DNS Updater
|
||||
ddns-updater:
|
||||
image: qmcgaw/ddns-updater
|
||||
container_name: ddns-updater
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
restart: unless-stopped
|
||||
profiles: ["core", "all"]
|
||||
networks:
|
||||
- default
|
||||
ports:
|
||||
- "$DDNSUPDATER_PORT:8000"
|
||||
volumes:
|
||||
- $DOCKERDIR/appdata/ddns-updater:/updater/data # Owned by UID 1000
|
||||
environment:
|
||||
TZ: $TZ
|
||||
PUID: $PUID
|
||||
PGID: $PGID
|
||||
PERIOD: 12h
|
||||
UPDATE_COOLDOWN_PERIOD: 5m
|
||||
PUBLICIP_DNS_TIMEOUT: 3s
|
||||
HTTP_TIMEOUT: 10s
|
||||
# Web UI
|
||||
LISTENING_PORT: 8000
|
||||
# Backup
|
||||
BACKUP_PERIOD: 96h # 0 to disable
|
||||
BACKUP_DIRECTORY: /updater/data/backups
|
||||
# Other
|
||||
LOG_LEVEL: info
|
||||
# SHOUTRRR_ADDRESSES: $DISCORD_SHOUTRRR_ADDRESS
|
||||
# DOCKER-LABELS-PLACEHOLDER
|
||||
@@ -0,0 +1,33 @@
|
||||
services:
|
||||
# Gluetun - VPN Client for Docker Containers and More
|
||||
# Gluetun only for use by torrent clients + on demand lan devices.
|
||||
# Arr apps do not need VPN (not recommended), unless you have ISP/country restrictions.
|
||||
gluetun:
|
||||
image: qmcgaw/gluetun
|
||||
container_name: gluetun
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
restart: unless-stopped
|
||||
profiles: ["core", "all"]
|
||||
networks:
|
||||
- default
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
# ports:
|
||||
# - $QBITTORRENTVPN_PORT:8080 # qBittorrent available at http://DOCKER-HOST-IP:$QBITTORRENTVPN_PORT
|
||||
# - 8888:8888/tcp # HTTP proxy
|
||||
# - 8388:8388/tcp # Shadowsocks
|
||||
# - 8388:8388/udp # Shadowsocks
|
||||
volumes:
|
||||
- $DOCKERDIR/appdata/gluetun:/gluetun
|
||||
environment:
|
||||
TZ: $TZ
|
||||
VPN_SERVICE_PROVIDER: $GLUETUN_VPN_SERVICE_PROVIDER
|
||||
VPN_TYPE: $GLUETUN_VPN_TYPE # wireguard / openvpn
|
||||
# WIREGUARD_PRIVATE_KEY: $GLUETUN_WIREGUARD_PRIVATE_KEY
|
||||
# WIREGUARD_ADDRESSES: $GLUETUN_WIREGUARD_ADDRESSES
|
||||
# OPENVPN_USER: $GLUETUN_OPENVPN_USERNAME
|
||||
# OPENVPN_PASSWORD: $GLUETUN_OPENVPN_PASSWORD
|
||||
# DOCKER-LABELS-PLACEHOLDER
|
||||
@@ -0,0 +1,5 @@
|
||||
POSTGRES_USER=n8n
|
||||
POSTGRES_PASSWORD=qqWoLCgg8ElAX6
|
||||
POSTGRES_DB=n8n
|
||||
N8N_BASIC_AUTH_USER=mmcfetridge
|
||||
N8N_BASIC_AUTH_PASSWORD=qqWoLCgg8ElAX6
|
||||
@@ -0,0 +1,38 @@
|
||||
services:
|
||||
n8n:
|
||||
image: n8nio/n8n
|
||||
ports:
|
||||
- "5678:5678"
|
||||
container_name: n8n
|
||||
env_file:
|
||||
- .env
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
environment:
|
||||
- N8N_BASIC_AUTH_ACTIVE=true
|
||||
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
|
||||
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
|
||||
- DB_TYPE=postgresdb
|
||||
- DB_POSTGRESDB_HOST=db
|
||||
- DB_POSTGRESDB_PORT=5432
|
||||
- DB_POSTGRESDB_DATABASE=${POSTGRES_USER}
|
||||
- DB_POSTGRESDB_USER=${POSTGRES_USER}
|
||||
- DB_POSTGRESDB_PASSWORD=$(POSTGRES_PASSWORD)
|
||||
- NODE_FUNCTION_ALLOW_EXTERNAL=axios,qs
|
||||
volumes:
|
||||
- ./appdata/n8n:/home/node/.n8n
|
||||
depends_on:
|
||||
- db
|
||||
restart: unless-stopped
|
||||
|
||||
db:
|
||||
image: postgres:12
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- /home/miker/docker/n8n/data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_USER=${POSTGRES_USER}
|
||||
- POSTGRES_PASSWORD=$(POSTGRES_PASSWORD)
|
||||
- POSTGRES_DB=n8n
|
||||
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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user