commit 34cca6337649a43469d6e04cdd920f6bad72d6fa Author: Steve Dudenhoeffer Date: Sun Dec 24 18:54:49 2023 +0000 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1ba4268 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +dashy.yml +traefik.yml \ No newline at end of file diff --git a/audiobookshelf/.env.example b/audiobookshelf/.env.example new file mode 100644 index 0000000..c378c6a --- /dev/null +++ b/audiobookshelf/.env.example @@ -0,0 +1,2 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld \ No newline at end of file diff --git a/audiobookshelf/docker-compose.yml b/audiobookshelf/docker-compose.yml new file mode 100755 index 0000000..b9ecffe --- /dev/null +++ b/audiobookshelf/docker-compose.yml @@ -0,0 +1,47 @@ +--- +version: "3.8" +services: + audiobookshelf: + image: advplyr/audiobookshelf + container_name: audiobookshelf + restart: unless-stopped + + environment: + - DOMAIN_ROOT=${DOMAIN_ROOT} + + labels: + - "traefik.http.services.audiobookshelf.loadbalancer.server.port=80" + - "traefik.enable=true" + - "traefik.http.routers.audiobookshelf.rule=Host(`audiobookshelf.${DOMAIN_ROOT}`)" + - 'traefik.http.routers.audiobookshelf.middlewares=authelia@docker' + + volumes: + - audiobookshelf_config:/config + - audiobookshelf_metadata:/metadata + - audiobookshelf_audiobooks:/audiobooks + - audiobookshelf_podcasts:/podcasts + + networks: + - home-proxy + + +volumes: + audiobookshelf_config: + external: true + + audiobookshelf_metadata: + external: true + + audiobookshelf_audiobooks: + external: true + + audiobookshelf_podcasts: + external: true + + +networks: + home-proxy: + external: true + + + diff --git a/bitwarden/.env.example b/bitwarden/.env.example new file mode 100644 index 0000000..c378c6a --- /dev/null +++ b/bitwarden/.env.example @@ -0,0 +1,2 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld \ No newline at end of file diff --git a/bitwarden/docker-compose.yml b/bitwarden/docker-compose.yml new file mode 100755 index 0000000..57140bd --- /dev/null +++ b/bitwarden/docker-compose.yml @@ -0,0 +1,35 @@ +--- +version: "3.8" +services: + bitwarden: + image: vaultwarden/server:latest + container_name: bitwarden + restart: unless-stopped + + environment: + - DOMAIN_ROOT=${DOMAIN_ROOT} + + labels: + - "traefik.http.services.bitwarden.loadbalancer.server.port=80" + - "traefik.enable=true" + - "traefik.http.routers.bitwarden.rule=Host(`bitwarden.${DOMAIN_ROOT}`)" + - 'traefik.http.routers.bitwarden.middlewares=authelia@docker' + + volumes: + - vaultwarden_data:/data + + networks: + - home-proxy + + +volumes: + vaultwarden_data: + external: true + + +networks: + home-proxy: + external: true + + + diff --git a/changedetection/.env.example b/changedetection/.env.example new file mode 100644 index 0000000..f13a136 --- /dev/null +++ b/changedetection/.env.example @@ -0,0 +1,8 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld + +# USER_ID is the user id to run the service as. 0 for root +USER_ID=1000 + +# GROUP_ID is the group id to run the service as. 0 for root +GROUP_ID=1000 \ No newline at end of file diff --git a/changedetection/docker-compose.yml b/changedetection/docker-compose.yml new file mode 100755 index 0000000..0749c72 --- /dev/null +++ b/changedetection/docker-compose.yml @@ -0,0 +1,57 @@ +version: '3.8' + +services: + changedetection: + image: dgtlmoon/changedetection.io + container_name: changedetection + + env_file: + - ../.env + + volumes: + - changedetection_data:/datastore + + environment: + - DOMAIN_ROOT=${DOMAIN_ROOT} + - PORT=5000 + - PUID=${USER_ID} + - PGID=${GROUP_ID} + - PLAYWRIGHT_DRIVER_URL=ws://playwright-chrome:3000/ + - BASE_URL="https://changedetection.${DOMAIN_ROOT}" + + networks: + - home-proxy + + labels: + - "traefik.enable=true" + - 'traefik.http.routers.changedetection.rule=Host(`changedetection.${DOMAIN_ROOT}`)' + - 'traefik.http.routers.changedetection.middlewares=authelia@docker' + - "traefik.http.services.changedetection.loadbalancer.server.port=5000" + + restart: unless-stopped + + playwright: + container_name: playwright + image: browserless/chrome + restart: unless-stopped + + environment: + - DOMAIN_ROOT=${DOMAIN_ROOT} + + networks: + - home-proxy + + labels: + - "traefik.enable=true" + - 'traefik.http.routers.playwright.rule=Host(`playwright.${DOMAIN_ROOT}`)' + - 'traefik.http.routers.playwright.middlewares=authelia@docker' + - "traefik.http.services.playwright.loadbalancer.server.port=3000" + +volumes: + changedetection_data: + external: true + + +networks: + home-proxy: + external: true \ No newline at end of file diff --git a/dashy/.env.example b/dashy/.env.example new file mode 100644 index 0000000..f13a136 --- /dev/null +++ b/dashy/.env.example @@ -0,0 +1,8 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld + +# USER_ID is the user id to run the service as. 0 for root +USER_ID=1000 + +# GROUP_ID is the group id to run the service as. 0 for root +GROUP_ID=1000 \ No newline at end of file diff --git a/dashy/dashy.yml.example b/dashy/dashy.yml.example new file mode 100644 index 0000000..e69de29 diff --git a/dashy/docker-compose.yml b/dashy/docker-compose.yml new file mode 100644 index 0000000..cff3022 --- /dev/null +++ b/dashy/docker-compose.yml @@ -0,0 +1,37 @@ +version: '3.8' +services: + dashy: + image: lissy93/dashy:latest + container_name: dashy + restart: unless-stopped + + labels: + - "traefik.enable=true" + - 'traefik.http.routers.dashy.rule=Host(`dashy.${DOMAIN_ROOT}`) || Host(`dash.${DOMAIN_ROOT}`) || Host(`${DOMAIN_ROOT}`)' + - "traefik.http.services.dashy.loadbalancer.server.port=80" + - 'traefik.http.routers.dashy.middlewares=authelia@docker' + + volumes: + - ./dashy.yml:/app/public/conf.yml + + networks: + - home-proxy + + environment: + - DOMAIN_ROOT=${DOMAIN_ROOT} + - NODE_ENV=production + - UID=${USER_ID} + - GID=${GROUP_ID} + + # Configure healthchecks + healthcheck: + test: ['CMD', 'node', '/app/services/healthcheck'] + interval: 1m30s + timeout: 10s + retries: 3 + start_period: 40s + + +networks: + home-proxy: + external: true diff --git a/drone/.env.example b/drone/.env.example new file mode 100644 index 0000000..8f5306a --- /dev/null +++ b/drone/.env.example @@ -0,0 +1,20 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.ltd + +# HOST_IP is the address of the host machine +HOST_IP=192.168.0.69 + +# GITEA_CLIENT_ID is the client id for your oauth2 application +GITEA_CLIENT_ID=XXX + +# GITEA_CLIENT_SECRET is the secret for your oauth2 application +GITEA_CLIENT_SECRET=gto_xxx + +# GITEA_SERVER is the location of your gitea server +GITEA_SERVER=https://gitea + +# DRONE_RPC_SECRET is the rpc secret for the drone server +DRONE_RPC_SECRET=xxx + +# DRONE_USER is the username for the drone actions to run as +DRONE_USER=user \ No newline at end of file diff --git a/drone/docker-compose.yml b/drone/docker-compose.yml new file mode 100644 index 0000000..ff19ef2 --- /dev/null +++ b/drone/docker-compose.yml @@ -0,0 +1,74 @@ +version: "3.8" +services: + drone: + image: drone/drone:2 + container_name: drone + labels: + - "traefik.http.services.drone.loadbalancer.server.port=80" + - "traefik.enable=true" + - "traefik.http.routers.drone.rule=Host(`drone.${DOMAIN_ROOT}`)" + - 'traefik.http.routers.drone.middlewares=authelia@docker' + + + environment: + - DRONE_GITEA_SERVER=https://gitea.${DOMAIN_ROOT} + - DRONE_GITEA_CLIENT_ID=${GITEA_CLIENT_ID} + - DRONE_GITEA_CLIENT_SECRET=${GITEA_CLIENT_SECRET} + - DRONE_RPC_SECRET=${DRONE_RPC_SECRET} + - DRONE_SERVER_HOST=drone.${DOMAIN_ROOT} + - DRONE_SERVER_PROTO=https + - DRONE_USER_CREATE=username:${DRONE_USER},admin:true + - DOMAIN_ROOT=${DOMAIN_ROOT} + - HOST_IP=${HOST_IP} + volumes: + - drone_data:/data + - /var/run/docker.sock:/var/run/docker.sock + + networks: + - home-proxy + + + extra_hosts: + - gitea.${DOMAIN_ROOT}:${HOST_IP} + - nuc.${DOMAIN_ROOT}:${HOST_IP} + - gitea-ssh.${DOMAIN_ROOT}:${HOST_IP} + + runner: + image: drone/drone-runner-docker:1 + + environment: + - DRONE_RPC_PROTO=http + - DRONE_RPC_HOST=drone + - DRONE_RPC_SECRET=${DRONE_RPC_SECRET} + - DRONE_RUNNER_CAPACITY=2 + - DRONE_RUNNER_NAME=runners + - HOST_IP=${HOST_IP} + +# ports: +# - 3000:3000/tcp + + depends_on: + - drone + + volumes: + - /var/run/docker.sock:/var/run/docker.sock + + networks: + - home-proxy + + extra_hosts: + - gitea.${DOMAIN_ROOT}:${HOST_IP} + - nuc.${DOMAIN_ROOT}:${HOST_IP} + - gitea-ssh.${DOMAIN_ROOT}:${HOST_IP} + +volumes: + drone_data: + external: true + + +networks: + home-proxy: + external: true + + + diff --git a/freshrss/.env.example b/freshrss/.env.example new file mode 100644 index 0000000..af2a310 --- /dev/null +++ b/freshrss/.env.example @@ -0,0 +1,5 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld + +# TIMEZONE +TIMEZONE=America/New_York diff --git a/freshrss/docker-compose.yml b/freshrss/docker-compose.yml new file mode 100644 index 0000000..4bf4b9c --- /dev/null +++ b/freshrss/docker-compose.yml @@ -0,0 +1,35 @@ +version: "3.8" +services: + freshrss: + image: freshrss/freshrss + + environment: + - TZ=${TIMEZONE} + - 'CRON_MIN=1,31' + - DOMAIN_ROOT=${DOMAIN_ROOT} + + labels: + - "traefik.http.services.freshrss.loadbalancer.server.port=80" + - "traefik.enable=true" + - "traefik.http.routers.freshrss.rule=Host(`freshrss.${DOMAIN_ROOT}`)" + - 'traefik.http.routers.freshrss.middlewares=authelia@docker' + + volumes: + - freshrss_extensions:/var/www/FreshRSS/extensions + - freshrss_data:/var/www/FreshRSS/data + + networks: + - home-proxy + +volumes: + freshrss_extensions: + external: true + freshrss_data: + external: true + +networks: + home-proxy: + external: true + + + diff --git a/gitea/.env.example b/gitea/.env.example new file mode 100644 index 0000000..e02c296 --- /dev/null +++ b/gitea/.env.example @@ -0,0 +1,11 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld + +# USER_ID is the user id to run the service as. 0 for root +USER_ID=1000 + +# GROUP_ID is the group id to run the service as. 0 for root +GROUP_ID=1000 + +# SSH_PORT is the port that will be opened for ssh +SSH_PORT=222 diff --git a/gitea/docker-compose.yml b/gitea/docker-compose.yml new file mode 100755 index 0000000..0917da6 --- /dev/null +++ b/gitea/docker-compose.yml @@ -0,0 +1,41 @@ +version: "3" + +services: + gitea: + image: gitea/gitea:latest + container_name: gitea + + hostname: gitea + + environment: + - USER_UID=${GROUP_ID} + - USER_GID=${USER_ID} + - DOMAIN_ROOT=${DOMAIN_ROOT} + - "SSH_PORT=${SSH_PORT:-222}" + + restart: always + + labels: + - "traefik.enable=true" + - "traefik.http.routers.gitea.rule=Host(`gitea.${DOMAIN_ROOT}`)" + - "traefik.http.services.gitea.loadbalancer.server.port=3000" + - 'traefik.http.routers.gitea.middlewares=authelia@docker' + + + volumes: + - gitea_data:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - "${SSH_PORT}:22" + + networks: + - home-proxy + +volumes: + gitea_data: + external: true + +networks: + home-proxy: + external: true \ No newline at end of file diff --git a/mort/.env.example b/mort/.env.example new file mode 100644 index 0000000..5589fd5 --- /dev/null +++ b/mort/.env.example @@ -0,0 +1,25 @@ +DOMAIN_ROOT=domain.tld +CLOUDFLARE_TUNNEL_TOKEN=XXXXX +MARIADB_ROOT_PASSWORD=XXXXX + +DISCORD_BOT_TOKEN=xxx +DATABASE_DSN=USER:PASSWORD@tcp(hostname:3306)/DATABASE?parseTime=true +WOLFRAM_APPID=APPID +TENOR_API_KEY=KEY +TENOR_API_CLI=APP ID +OPENAI_KEY=sk-XXXXXXX +GITEA_ENDPOINT=http://gitea.DOMAIN +GITEA_TOKEN=XXXXXXX +GITEA_USER=username +GITEA_PASS=password +BOBROSS_ENDPOINT=https://bobross.DOMAIN +BOBROSS_API_KEY=KEY +HUGGINGFACE_TOKEN=hf_XXXX +TODOIST_TOKEN=XXXXXX +TVDB_API_KEY=XXXXX +TMDB_API_KEY=XXXXX +TMDB_READ_ACCESS_TOKEN=XXXXX +OVERSEERR_ENDPOINT=https://overseerr.DOMAIN +PLEX_ENDPOINT=https://plex.DOMAIN +PLEX_TOKEN=TOKEN +OPENWEATHERMAP_API_KEY=KEY \ No newline at end of file diff --git a/mort/docker-compose.yml b/mort/docker-compose.yml new file mode 100644 index 0000000..983ab0e --- /dev/null +++ b/mort/docker-compose.yml @@ -0,0 +1,84 @@ +version: "3.8" +services: + mort: + image: gitea.dudenhoeffer.casa/steve/mort:latest + restart: unless-stopped + container_name: mort + command: ./mort --env /app/.env + + environment: + - DOMAIN_ROOT=${DOMAIN_ROOT} + + volumes: + - .env:/app/.env + labels: + - "traefik.enable=true" + - "traefik.http.services.bobross-receiver-mort.loadbalancer.server.port=8080" + - "traefik.http.routers.bobross-receiver-mort.rule=Host(`bobross-receiver-mort.dudenhoeffer.casa`)" + - 'traefik.http.routers.bobross-receiver-mort.middlewares=authelia@docker' + + + networks: + - home-proxy + + extra_hosts: + - "gitea.dudenhoeffer.casa:192.168.0.197" + + + tunnel: + image: cloudflare/cloudflared:latest + command: tunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN} + restart: unless-stopped + networks: + - home-proxy + environment: + - CLOUDFLARE_TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN} + + redis: + container_name: redis + image: redis:latest + + networks: + - home-proxy + + labels: + - "traefik.enabled=false" + + mariadb: + image: mariadb + restart: always + container_name: mariadb + environment: + MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD} + + networks: + - home-proxy + + volumes: + - mariadb_data:/var/lib/mysql + + + adminer: + image: adminer + restart: always + container_name: adminer + networks: + - home-proxy + + environment: + - DOMAIN_ROOT=${DOMAIN_ROOT} + + labels: + - "traefik.enable=true" + - "traefik.http.routers.adminer.rule=Host(`adminer.${DOMAIN_ROOT}`)" + - "traefik.http.services.adminer.loadbalancer.server.port=8080" + - 'traefik.http.routers.adminer.middlewares=authelia@docker' + +networks: + home-proxy: + external: true + + +volumes: + mariadb_data: + external: true \ No newline at end of file diff --git a/pihole/.env.example b/pihole/.env.example new file mode 100644 index 0000000..d410fe8 --- /dev/null +++ b/pihole/.env.example @@ -0,0 +1,8 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld + +# WEB_UI_PASSWORD is the password for the web ui interface. If unset, it will be randomly generated and retrievable from the logs. +WEB_UI_PASSWORD=password + +# TIMEZONE is the timezone you're set in +TIMEZONE=America/New_York \ No newline at end of file diff --git a/pihole/docker-compose.yml b/pihole/docker-compose.yml new file mode 100644 index 0000000..625257e --- /dev/null +++ b/pihole/docker-compose.yml @@ -0,0 +1,61 @@ +version: "3" + +# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/ +services: + pihole: + container_name: pihole + image: pihole/pihole:latest + environment: + - TZ=${TIMEZONE} + - CORS_HOSTS=pihole.${DOMAIN_ROOT} + - DOMAIN_ROOT=${DOMAIN_ROOT} + - WEBPASSWORD=${WEB_UI_PASSWORD} + + ports: + - "53:53/tcp" + - "53:53/udp" + + # Volumes store your data between container upgrades + volumes: + - pihole-config_data:/etc/pihole + - pihole-dnsmasq_data:/etc/dnsmasq.d + - ./pihole-lighttpd.conf:/etc/lighttpd/lighttpd.conf + cap_add: + - NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed + + labels: + - "traefik.enable=true" + - "traefik.http.routers.pihole.rule=Host(`pihole.${DOMAIN_ROOT}`)" + - "traefik.http.services.pihole.loadbalancer.server.port=8081" + - 'traefik.http.routers.pihole.middlewares=authelia@docker' + + networks: + - home-proxy + + restart: unless-stopped + +# pihole-proxy: +# container_name: pihole-proxy +# image: gitea.dudenhoeffer.casa/steve/simpleproxy:latest +# command: http://192.168.0.197:8081/ +# +# labels: +# - "traefik.enable=true" +# - "traefik.http.routers.pihole.rule=Host(`pihole.dudenhoeffer.casa`)" +# - "traefik.http.services.pihole.loadbalancer.server.port=8080" +# - 'traefik.http.routers.pihole.middlewares=authelia@docker' +# +# networks: +# - home-proxy +# +# restart: unless-stopped +# +networks: + home-proxy: + external: true + +volumes: + pihole-config_data: + external: true + pihole-dnsmasq_data: + external: true diff --git a/pihole/pihole-lighttpd.conf b/pihole/pihole-lighttpd.conf new file mode 100644 index 0000000..cdf68a8 --- /dev/null +++ b/pihole/pihole-lighttpd.conf @@ -0,0 +1,54 @@ +server.modules = ( + "mod_indexfile", + "mod_access", + "mod_alias", + "mod_redirect", +) + +server.document-root = "/var/www/html" +server.upload-dirs = ( "/var/cache/lighttpd/uploads" ) +server.errorlog = "/var/log/lighttpd/error.log" +server.pid-file = "/run/lighttpd.pid" +server.username = "www-data" +server.groupname = "www-data" +server.port = 8081 + +# features +#https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_feature-flagsDetails +server.feature-flags += ("server.h2proto" => "enable") +server.feature-flags += ("server.h2c" => "enable") +server.feature-flags += ("server.graceful-shutdown-timeout" => 5) +#server.feature-flags += ("server.graceful-restart-bg" => "enable") + +# strict parsing and normalization of URL for consistency and security +# https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_http-parseoptsDetails +# (might need to explicitly set "url-path-2f-decode" = "disable" +# if a specific application is encoding URLs inside url-path) +server.http-parseopts = ( + "header-strict" => "enable",# default + "host-strict" => "enable",# default + "host-normalize" => "enable",# default + "url-normalize-unreserved"=> "enable",# recommended highly + "url-normalize-required" => "enable",# recommended + "url-ctrls-reject" => "enable",# recommended + "url-path-2f-decode" => "enable",# recommended highly (unless breaks app) + #"url-path-2f-reject" => "enable", + "url-path-dotseg-remove" => "enable",# recommended highly (unless breaks app) + #"url-path-dotseg-reject" => "enable", + #"url-query-20-plus" => "enable",# consistency in query string +) + +index-file.names = ( "index.php", "index.html" ) +url.access-deny = ( "~", ".inc" ) +static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" ) + +# default listening port for IPv6 falls back to the IPv4 port +include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port +include_shell "/usr/share/lighttpd/create-mime.conf.pl" +include "/etc/lighttpd/conf-enabled/*.conf" + +#server.compat-module-load = "disable" +server.modules += ( + "mod_dirlisting", + "mod_staticfile", +) diff --git a/privatebin/.env.example b/privatebin/.env.example new file mode 100644 index 0000000..c378c6a --- /dev/null +++ b/privatebin/.env.example @@ -0,0 +1,2 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld \ No newline at end of file diff --git a/privatebin/cfg/conf.php b/privatebin/cfg/conf.php new file mode 100644 index 0000000..0468cc4 --- /dev/null +++ b/privatebin/cfg/conf.php @@ -0,0 +1,261 @@ +;project page." + +; (optional) notice to display +; notice = "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service." + +; by default PrivateBin will guess the visitors language based on the browsers +; settings. Optionally you can enable the language selection menu, which uses +; a session cookie to store the choice until the browser is closed. +languageselection = false + +; set the language your installs defaults to, defaults to English +; if this is set and language selection is disabled, this will be the only language +; languagedefault = "en" + +; (optional) URL shortener address to offer after a new paste is created. +; It is suggested to only use this with self-hosted shorteners as this will leak +; the pastes encryption key. +; urlshortener = "https://shortener.example.com/api?link=" + +; (optional) Let users create a QR code for sharing the paste URL with one click. +; It works both when a new paste is created and when you view a paste. +; qrcode = true + +; (optional) IP based icons are a weak mechanism to detect if a comment was from +; a different user when the same username was used in a comment. It might get +; used to get the IP of a comment poster if the server salt is leaked and a +; SHA512 HMAC rainbow table is generated for all (relevant) IPs. +; Can be set to one these values: +; "none" / "identicon" (default) / "jdenticon" / "vizhash". +; icon = "none" + +; Content Security Policy headers allow a website to restrict what sources are +; allowed to be accessed in its context. You need to change this if you added +; custom scripts from third-party domains to your templates, e.g. tracking +; scripts or run your site behind certain DDoS-protection services. +; Check the documentation at https://content-security-policy.com/ +; Notes: +; - If you use a bootstrap theme, you can remove the allow-popups from the +; sandbox restrictions. +; - By default this disallows to load images from third-party servers, e.g. when +; they are embedded in pastes. If you wish to allow that, you can adjust the +; policy here. See https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-it-load-embedded-images +; for details. +; - The 'unsafe-eval' is used in two cases; to check if the browser supports +; async functions and display an error if not and for Chrome to enable +; webassembly support (used for zlib compression). You can remove it if Chrome +; doesn't need to be supported and old browsers don't need to be warned. +; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval'; style-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads" + +; stay compatible with PrivateBin Alpha 0.19, less secure +; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of +; sha256 in HMAC for the deletion token +; zerobincompatibility = false + +; Enable or disable the warning message when the site is served over an insecure +; connection (insecure HTTP instead of HTTPS), defaults to true. +; Secure transport methods like Tor and I2P domains are automatically whitelisted. +; It is **strongly discouraged** to disable this. +; See https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-it-show-me-an-error-about-an-insecure-connection for more information. +; httpwarning = true + +; Pick compression algorithm or disable it. Only applies to pastes/comments +; created after changing the setting. +; Can be set to one these values: "none" / "zlib" (default). +; compression = "zlib" + +[expire] +; expire value that is selected per default +; make sure the value exists in [expire_options] +default = "1week" + +[expire_options] +; Set each one of these to the number of seconds in the expiration period, +; or 0 if it should never expire +5min = 300 +10min = 600 +1hour = 3600 +1day = 86400 +1week = 604800 +; Well this is not *exactly* one month, it's 30 days: +1month = 2592000 +1year = 31536000 +never = 0 + +[formatter_options] +; Set available formatters, their order and their labels +plaintext = "Plain Text" +syntaxhighlighting = "Source Code" +markdown = "Markdown" + +[traffic] +; time limit between calls from the same IP address in seconds +; Set this to 0 to disable rate limiting. +limit = 10 + +; (optional) Set IPs addresses (v4 or v6) or subnets (CIDR) which are exempted +; from the rate-limit. Invalid IPs will be ignored. If multiple values are to +; be exempted, the list needs to be comma separated. Leave unset to disable +; exemptions. +; exempted = "1.2.3.4,10.10.10/24" + +; (optional) If you want only some source IP addresses (v4 or v6) or subnets +; (CIDR) to be allowed to create pastes, set these here. Invalid IPs will be +; ignored. If multiple values are to be exempted, the list needs to be comma +; separated. Leave unset to allow anyone to create pastes. +; creators = "1.2.3.4,10.10.10/24" + +; (optional) if your website runs behind a reverse proxy or load balancer, +; set the HTTP header containing the visitors IP address, i.e. X_FORWARDED_FOR +; header = "X_FORWARDED_FOR" + +[purge] +; minimum time limit between two purgings of expired pastes, it is only +; triggered when pastes are created +; Set this to 0 to run a purge every time a paste is created. +limit = 300 + +; maximum amount of expired pastes to delete in one purge +; Set this to 0 to disable purging. Set it higher, if you are running a large +; site +batchsize = 10 + +[model] +; name of data model class to load and directory for storage +; the default model "Filesystem" stores everything in the filesystem +class = Filesystem +[model_options] +dir = PATH "data" + +;[model] +; example of a Google Cloud Storage configuration +;class = GoogleCloudStorage +;[model_options] +;bucket = "my-private-bin" +;prefix = "pastes" +;uniformacl = false + +;[model] +; example of DB configuration for MySQL +;class = Database +;[model_options] +;dsn = "mysql:host=localhost;dbname=privatebin;charset=UTF8" +;tbl = "privatebin_" ; table prefix +;usr = "privatebin" +;pwd = "Z3r0P4ss" +;opt[12] = true ; PDO::ATTR_PERSISTENT + +;[model] +; example of DB configuration for SQLite +;class = Database +;[model_options] +;dsn = "sqlite:" PATH "data/db.sq3" +;usr = null +;pwd = null +;opt[12] = true ; PDO::ATTR_PERSISTENT + +;[model] +; example of DB configuration for PostgreSQL +;class = Database +;[model_options] +;dsn = "pgsql:host=localhost;dbname=privatebin" +;tbl = "privatebin_" ; table prefix +;usr = "privatebin" +;pwd = "Z3r0P4ss" +;opt[12] = true ; PDO::ATTR_PERSISTENT + +;[model] +; example of S3 configuration for Rados gateway / CEPH +;class = S3Storage +;[model_options] +;region = "" +;version = "2006-03-01" +;endpoint = "https://s3.my-ceph.invalid" +;use_path_style_endpoint = true +;bucket = "my-bucket" +;accesskey = "my-rados-user" +;secretkey = "my-rados-pass" + +;[model] +; example of S3 configuration for AWS +;class = S3Storage +;[model_options] +;region = "eu-central-1" +;version = "latest" +;bucket = "my-bucket" +;accesskey = "access key id" +;secretkey = "secret access key" + +;[model] +; example of S3 configuration for AWS using its SDK default credential provider chain +; if relying on environment variables, the AWS SDK will look for the following: +; - AWS_ACCESS_KEY_ID +; - AWS_SECRET_ACCESS_KEY +; - AWS_SESSION_TOKEN (if needed) +; for more details, see https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html#default-credential-chain +;class = S3Storage +;[model_options] +;region = "eu-central-1" +;version = "latest" +;bucket = "my-bucket" + +[yourls] +; When using YOURLS as a "urlshortener" config item: +; - By default, "urlshortener" will point to the YOURLS API URL, with or without +; credentials, and will be visible in public on the PrivateBin web page. +; Only use this if you allow short URL creation without credentials. +; - Alternatively, using the parameters in this section ("signature" and +; "apiurl"), "urlshortener" needs to point to the base URL of your PrivateBin +; instance with "shortenviayourls?link=" appended. For example: +; urlshortener = "${basepath}shortenviayourls?link=" +; This URL will in turn call YOURLS on the server side, using the URL from +; "apiurl" and the "access signature" from the "signature" parameters below. + +; (optional) the "signature" (access key) issued by YOURLS for the using account +; signature = "" +; (optional) the URL of the YOURLS API, called to shorten a PrivateBin URL +; apiurl = "https://yourls.example.com/yourls-api.php" diff --git a/privatebin/docker-compose.yml b/privatebin/docker-compose.yml new file mode 100644 index 0000000..111f2a7 --- /dev/null +++ b/privatebin/docker-compose.yml @@ -0,0 +1,34 @@ +version: "3.8" +services: + privatebin: + image: privatebin/nginx-fpm-alpine:latest + container_name: privatebin + restart: unless-stopped + environment: + - DOMAIN_ROOT=${DOMAIN_ROOT} + + labels: + - "traefik.http.services.privatebin.loadbalancer.server.port=8080" + - "traefik.enable=true" + - "traefik.http.routers.privatebin.rule=Host(`privatebin.${DOMAIN_ROOT}`)" + - 'traefik.http.routers.privatebin.middlewares=authelia@docker' + + volumes: + - privatebin_data:/srv/data + - ./cfg/conf.php:/srv/cfg/conf.php:ro + + networks: + - home-proxy + + +volumes: + privatebin_data: + external: true + + +networks: + home-proxy: + external: true + + + diff --git a/traefik/.env.example b/traefik/.env.example new file mode 100644 index 0000000..80f17e5 --- /dev/null +++ b/traefik/.env.example @@ -0,0 +1,26 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld + +# USER_ID is the user id to run the service as. 0 for root +USER_ID=1000 + +# GROUP_ID is the group id to run the service as. 0 for root +GROUP_ID=1000 + +# TIMEZONE is the timezone the server is in +TIMZEONE=America/New_York + +# CLOUDFLARE_EMAIL is the email for the cloudflare credentials +CLOUDFLARE_EMAIL=email@address.com + +# CLOUDFLARE_KEY is the key for your cloudflare credentials +CLOUDFLARE_KEY=XXXX + +# AUTH_JWT_SECRET is the secret used for authelia's json web tokens. (can just be a random string) +AUTH_JWT_SECRET=SOMErandomSTRING + +# AUTH_SESSION_SECRET is the secret (random string) used to encrypt session data in redis +AUTH_SESSION_SECRET=SOMEotherRANDOMstring + +# AUTH_STORAGE_KEY is the secret (random string) used to encrypt the data at rest +AUTH_STORAGE_KEY=ANOTHERrandomSTRING \ No newline at end of file diff --git a/traefik/docker-compose.yml b/traefik/docker-compose.yml new file mode 100644 index 0000000..4df3662 --- /dev/null +++ b/traefik/docker-compose.yml @@ -0,0 +1,87 @@ +--- +version: "3.8" +services: + traefik: + image: traefik:latest + container_name: traefik + hostname: traefik + + + environment: + - CLOUDFLARE_EMAIL=${CLOUDFLARE_EMAIL} + - CLOUDFLARE_DNS_API_TOKEN=${CLOUDFLARE_KEY} + - DOMAIN_ROOT=${DOMAIN_ROOT} + + ports: + - mode: host + protocol: tcp + published: 80 + target: 80 + - mode: host + protocol: tcp + published: 443 + target: 443 + + volumes: + - ./traefik.yml:/etc/traefik/traefik.yml:ro + - /var/run/docker.sock:/tmp/docker.sock:ro + - certs:/letsencrypt + + networks: + - home-proxy + + + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN_ROOT}`)' + - "traefik.http.routers.traefik.entrypoints=websecure" + - 'entrypoints.websecure.http.tls=true' + - 'entrypoints.websecure.http.tls.certResolver=letsencrypt' + - 'entrypoints.websecure.http.tls.domains[0].main=${DOMAIN_ROOT}' + - 'entrypoints.websecure.http.tls.domains[0].sans=*.${DOMAIN_ROOT}' + - "traefik.http.routers.traefik.service=api@internal" + - 'traefik.http.routers.traefik.middlewares=strip' + - 'traefik.http.middlewares.strip.stripprefix.prefixes=/traefik' + - 'traefik.http.services.traefik.loadbalancer.server.port=8080' + - 'traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/verify?rd=https://login.${DOMAIN_ROOT}/' + - 'traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true' + - 'traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email' + - 'certificatesresolvers.letsencrypt.acme.dnschallenge=true' + - 'certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare' + - 'certificatesresolvers.letsencrypt.acme.email=${CLOUDFLARE_EMAIL}' + - 'certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json' + + + + authelia: + image: docker.io/authelia/authelia:latest + container_name: authelia + restart: unless-stopped + networks: + - home-proxy + environment: + - TZ=${TIMEZONE} + - AUTHELIA_JWT_SECRET=${AUTH_JWT_SECRET} + - AUTHELIA_SESSION_SECRET=${AUTH_SESSION_SECRET} + - AUTHELIA_STORAGE_ENCRYPTION_KEY=${AUTH_STORAGE_KEY} + - DOMAIN_ROOT=${DOMAIN_ROOT} + + volumes: + - authelia_config:/config + + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.authelia.rule=Host(`login.${DOMAIN_ROOT}`)' + - 'traefik.http.services.authelia.loadbalancer.server.port=9091' + +volumes: + certs: + external: true + + authelia_config: + external: true + + +networks: + home-proxy: + external: true diff --git a/traefik/traefik.yml.example b/traefik/traefik.yml.example new file mode 100644 index 0000000..e69de29 diff --git a/whoogle/.env.example b/whoogle/.env.example new file mode 100644 index 0000000..c378c6a --- /dev/null +++ b/whoogle/.env.example @@ -0,0 +1,2 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld \ No newline at end of file diff --git a/whoogle/docker-compose.yml b/whoogle/docker-compose.yml new file mode 100644 index 0000000..0319876 --- /dev/null +++ b/whoogle/docker-compose.yml @@ -0,0 +1,25 @@ +version: "3.8" +services: + whoogle: + image: benbusby/whoogle-search + container_name: whoogle + restart: unless-stopped + + labels: + - "traefik.http.services.whoogle.loadbalancer.server.port=5000" + - "traefik.enable=true" + - "traefik.http.routers.whoogle.rule=Host(`whoogle.${DOMAIN_ROOT}`)" + - 'traefik.http.routers.whoogle.middlewares=authelia@docker' + + environment: + - DOMAIN_ROOT=${DOMAIN_ROOT} + + networks: + - home-proxy + + + +networks: + home-proxy: + external: true + diff --git a/wireguard/.env.example b/wireguard/.env.example new file mode 100644 index 0000000..8741bcc --- /dev/null +++ b/wireguard/.env.example @@ -0,0 +1,5 @@ +# DOMAIN_ROOT is the root domain that this service will register as with Traefik +DOMAIN_ROOT=domain.tld + +# UI_PASSWORD if set, will be the required password for the admin UI +UI_PASSWORD= \ No newline at end of file diff --git a/wireguard/docker-compose.yml b/wireguard/docker-compose.yml new file mode 100644 index 0000000..f626309 --- /dev/null +++ b/wireguard/docker-compose.yml @@ -0,0 +1,53 @@ +version: "3" +services: + wireguard: + image: ghcr.io/wg-easy/wg-easy + restart: unless-stopped + container_name: wireguard + labels: + - "traefik.enable=true" + - "traefik.http.routers.wireguard.rule=Host(`wireguard.${DOMAIN_ROOT}`)" + - "traefik.http.services.wireguard.loadbalancer.server.port=51821" + - 'traefik.http.routers.wireguard.middlewares=authelia@docker' + + ports: + - target: 51820 + published: 51820 + protocol: tcp + mode: host + - target: 51820 + published: 51820 + protocol: udp + mode: host + + volumes: + - wireguard_data:/etc/wireguard + + environment: + - WG_HOST=wireguard.${DOMAIN_ROOT} + - PASSWORD=${UI_PASSWORD} + - DOMAIN_ROOT=${DOMAIN_ROOT} + + cap_add: + - NET_ADMIN + - SYS_MODULE + + sysctls: + - "net.ipv4.conf.all.src_valid_mark=1" + - "net.ipv4.ip_forward=1" + + networks: + - default + - home-proxy + + +volumes: + wireguard_data: + external: true + +networks: + default: + home-proxy: + external: true + +