├── .env.sample ├── .github └── FUNDING.yml ├── .gitignore ├── Git-QRG.md ├── LICENSE ├── README.md ├── config ├── traefik-2.x-old │ └── docker-compose.yml ├── traefik │ ├── acme │ │ └── acme.json │ ├── rules.toml │ └── traefik.toml └── traefik2 │ ├── acme │ └── acme.json │ ├── rules │ ├── app-edgeos.yml │ ├── app-plex.yml │ ├── app-website.yml │ ├── middleware-chains.yml │ └── middleware.yml │ └── traefik.log ├── dev ├── apprise │ └── compose.yaml ├── authelia │ ├── configuration.yml │ ├── docker-compose.yml │ └── users_database.yml ├── autoheal │ └── compose.yaml ├── babybuddy │ └── compose.yaml ├── backup │ └── docker-compose.yml ├── bookstack │ └── docker-compose.yml ├── cloudflared │ ├── README.md │ └── compose.yml ├── code-server │ ├── .env │ ├── README.md │ └── docker-compose.yml ├── diskover │ └── docker-compose..yml ├── downloaders │ └── docker-compose.yml ├── duplicati │ └── docker-compose.yml ├── emby │ └── docker-compose.yml ├── flaresolverr │ └── docker-compose.yml ├── freeipa │ ├── docker-compose.yml │ ├── docker-compose2.yml │ ├── docker-run.txt │ ├── install-log │ └── traefik configuration.txt ├── gollum │ ├── Dockerfile │ └── docker-compose.yml ├── guacamole │ ├── docker-compose-arm.yml │ ├── docker-compose-x64.yml │ └── initdb.sql ├── hysteria2 │ └── docker-compose.yml ├── immich │ └── compose.yml ├── indexers │ └── docker-compose.yml ├── invoiceninja │ ├── README.md │ ├── compose.yml │ └── config │ │ ├── nginx │ │ ├── invoiceninja.conf │ │ └── laravel.conf │ │ ├── php │ │ ├── php-fpm.conf │ │ └── php.ini │ │ └── supervisor │ │ └── supervisord.conf ├── keycloak │ └── docker-compose.yml ├── komodo │ ├── compose.env │ └── compose.yml ├── media │ └── docker-compose.yml ├── minecraft │ └── docker-compose.yml ├── minetest │ └── docker-compose.yml ├── mosquitto │ ├── docker-compose.yml │ ├── docker-entrypoint.sh │ ├── dockerfile │ ├── mosquitto.conf │ └── passwd ├── mymedia │ └── docker-compose.yml ├── netdata │ └── docker-compose.yml ├── oauth2 │ └── docker-compose.yml ├── obsidian-livesync │ ├── compose.yaml │ └── local.ini ├── organize │ └── docker-compose.yml ├── photoprism │ └── docker-compose.yml ├── pihole │ └── docker-compose.yml ├── portainer │ └── docker-compose.yml ├── prometheus-old │ ├── alertmanager │ │ └── config.yml │ ├── dashboards │ │ ├── Grafana Dashboard With Service.json │ │ ├── Grafana_Dashboard.json │ │ ├── Grafana_Dashboard_prom_2.json │ │ ├── HighLoadDashboard.json │ │ └── System_Monitoring.json │ ├── docker-compose.yml │ ├── grafana │ │ ├── config.monitoring │ │ └── provisioning │ │ │ ├── dashboards │ │ │ ├── Docker Prometheus Monitoring-1533038455876.json │ │ │ └── dashboard.yml │ │ │ └── datasources │ │ │ └── datasource.yml │ └── prometheus │ │ ├── alert.rules │ │ └── prometheus.yml ├── prometheus │ ├── docker-compose.yml │ ├── grafana │ │ ├── config.monitoring │ │ └── provisioning │ │ │ ├── dashboards │ │ │ ├── 1-node-exporter-update-1102_rev2.json │ │ │ ├── Docker Prometheus Monitoring-1533038455876.json │ │ │ ├── dashboard.yml │ │ │ └── node-exporter-full_rev15.json │ │ │ └── datasources │ │ │ └── datasource.yml │ └── prometheus │ │ └── prometheus.yml ├── qbittorrent │ └── docker-compose.yml ├── rclone │ ├── docker-compose.yml │ └── rclone.env ├── rustdesk │ └── compose.yml ├── shadowsocks │ └── docker-compose.yml ├── shiori │ └── docker-compose.yml ├── sing-box │ └── docker-compose.yml ├── smarthome │ └── docker-compose.yml ├── soulseek │ └── docker-compose.yml ├── system │ └── docker-compose.yml ├── teslamate │ └── compose.yaml ├── traefik │ ├── traefik-debug │ │ └── docker-compose.yml │ ├── traefik-v1 │ │ ├── docker-compose.yml │ │ ├── rules.toml │ │ └── traefik.toml │ └── traefik-v2 │ │ └── docker-compose.yml ├── utility │ └── network-concept │ │ ├── Dockerfile │ │ ├── README.md │ │ └── docker-compose.yml ├── watchtower │ └── docker-compose.yml ├── wiki.js │ └── docker-compose.yml ├── wordpress │ └── docker-compose.yml └── wud │ └── compose.yml ├── documentation ├── 0-oauth2.png ├── 1-heimdall.png ├── gotify-icons │ ├── healthchecks-green.png │ ├── healthchecks-green.svg │ ├── healthchecks.png │ ├── healthchecks.svg │ ├── healthchecks2.png │ ├── lidarr.png │ ├── ouroboros.png │ ├── overseerr.png │ ├── pi3.png │ ├── pi4.png │ ├── radarr.png │ ├── sonarr.png │ └── source.psd └── nextcloud │ └── README.md └── stacks ├── backup └── docker-compose.yml ├── bitwarden ├── bitwarden-mysql │ └── Dockerfile └── compose.yaml ├── core ├── README.md └── compose.yaml ├── downloaders ├── README.md ├── docker-compose.yml ├── healthcheck.md └── healthcheck.sh ├── home-assistant └── docker-compose.yml ├── indexers └── docker-compose.yml ├── joplin-server ├── README.md └── docker-compose.yml ├── owncloud-ocis ├── README.md └── compose.yaml ├── paperless-ngx └── docker-compose.yml └── unifi-network-application └── docker-compose.yml /.env.sample: -------------------------------------------------------------------------------- 1 | # Create a .env file and place in the same directory as the docker-compose.yml file. Paste the following content into the .env file. 2 | 3 | # General / common settings 4 | PUID=1000 5 | PGID=1000 6 | TZ=America/New_York 7 | USERDIR=/home/pi 8 | EXTHDD_DIR=/mnt/hdd 9 | CONFIG_DIR=/mnt/hdd/docker/config 10 | VOLUME_DIR=/mnt/hdd/docker/volume 11 | 12 | # Username you want to use for (nearly) everything 13 | USERNAME= 14 | 15 | # Duck DNS / Let's Encrypt / Traefik 16 | EMAIL= 17 | FQDN=example1.duckdns.org 18 | DUCKDNS_SUBDOMAINS=example1,example2 19 | DUCKDNS_TOKEN= 20 | TRAEFIK_PILOT_TOKEN= 21 | 22 | # Nextcloud and database config 23 | POSTGRES_USER= 24 | POSTGRES_PASSWORD= 25 | NEXTCLOUD_PASSWORD= 26 | 27 | # Transmission-VPN 28 | OPENVPN_USERNAME= 29 | OPENVPN_PASSWORD= 30 | 31 | # Used for OAuth 2 authentication 32 | GITHUB_CLIENT_ID= 33 | GITHUB_CLIENT_SECRET= 34 | # Just use a random password to encrypt the cookie (ie: echo "Password" | base64) 35 | OAUTH2_PROXY_COOKIE_SECRET= 36 | # Ensure your email is publicly visible on GitHub, otherwise you will get a "not authorized" message when logging in. 37 | WHITELIST=email1,email2,email3 38 | 39 | # Bitwarden 40 | # Use a long random password for the admin token (example: openssl rand -base64 48) 41 | ADMIN_TOKEN= 42 | SMTP_SERVER= 43 | EMAIL_FROM= 44 | EMAIL_TO= 45 | EMAIL_PASSWORD= 46 | 47 | # Gotify 48 | GOTIFY_PASSWORD= 49 | # Gotify Tokens 50 | GOTIFY_WATCHTOWER= 51 | 52 | # Rclone 53 | RCLONE_CONFIG_REMOTE_CLIENT_ID= 54 | RCLONE_CONFIG_REMOTE_CLIENT_SECRET= 55 | RCLONE_CONFIG_REMOTE_TOKEN= 56 | RCLONE_CONFIG_REMOTE_ROOT_FOLDER_ID= 57 | 58 | # Not currently used 59 | HTTP_USERNAME= 60 | HTTP_PASSWORD= 61 | TRANSMISSION_USERNAME= 62 | TRANSMISSION_PASSWORD= -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: etechonomy 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | polar: # Replace with a single Polar username 14 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # docker-compose env file 2 | .env 3 | *.ovpn 4 | -------------------------------------------------------------------------------- /Git-QRG.md: -------------------------------------------------------------------------------- 1 | # Git Quick Reference Guide 2 | 3 | 4 | ### First time cloning and new branch. 5 | ```bash 6 | git clone PROJECT.git 7 | git checkout -b NEWBRANCH 8 | 9 | # make changes 10 | 11 | git status 12 | git add -A 13 | git commit -m "commit message" 14 | git push origin NEWBRANCH 15 | ``` 16 | 17 | ### If you already have the repo cloned, and branch already exists. 18 | ```bash 19 | git checkout master 20 | git pull 21 | git checkout BRANCHNAME 22 | git merge master 23 | 24 | # make changes 25 | 26 | git status 27 | git add -A 28 | git commit -m "commit message" 29 | git push 30 | ``` 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker Pi-Stacks 2 | 3 | ## Introduction 4 | This repository contains curated stacks of useful Docker containers optimized for the Raspberry Pi — primarily geared toward media/entertainment. 5 | 6 | Many of the containers will require additional configuration upon first use, but after everything is configured, you can easily migrate somewhere else provided you keep a backup of your config directory. 7 | 8 | Once configured, you'll be able to organize all of your containers neatly using Heimdall. For example, my "home page" looks like this: 9 | 10 | ![documentation/1-heimdall.png](documentation/1-heimdall.png) 11 | 12 | The best thing is, this setup integrates Duck DNS and Traefik so you don't have to memorize IP addresses and port numbers, and uses SSL certificates from Let's Encrypt to keep everything secure. Additionally, you can conveniently authenticate only once for many of the containers by leveraging [OAuth 2](documentation/0-oauth2.png) and signing in with GitHub (or any other supported Oauth 2 provider). 13 | 14 | > **_NOTE:_** During the initial setup you may need to uncomment the ports to configure the various microservices. Once everything is fully configured, Traefik will neatly route everything so you only need to keep 2 ports open (80 and 443). 15 | 16 | --- 17 | 18 | ## Getting Started: 19 | Clone this repo, then create a [.env file](.env.sample) and place it into the pi4-stack directory (in the same directory as the docker-compose.yml). Paste the following content into the .env file and input/change variables according to your preferences. 20 | 21 | ```bash 22 | # General / common settings 23 | PUID=1000 24 | PGID=1000 25 | TZ=America/New_York 26 | USERDIR=/home/pi 27 | EXTHDD_DIR=/mnt/hdd 28 | CONFIG_DIR=/mnt/hdd/docker/config 29 | VOLUME_DIR=/mnt/hdd/docker/volume 30 | 31 | # Username you want to use for (nearly) everything 32 | USERNAME= 33 | 34 | # Duck DNS / Let's Encrypt / Traefik 35 | FQDN=example1.duckdns.org 36 | DUCKDNS_SUBDOMAINS=example1,example2 37 | DUCKDNS_TOKEN= 38 | TRAEFIK_PILOT_TOKEN= 39 | 40 | # Nextcloud and database config 41 | POSTGRES_USER= 42 | POSTGRES_PASSWORD= 43 | NEXTCLOUD_PASSWORD= 44 | 45 | # Transmission-VPN 46 | OPENVPN_USERNAME= 47 | OPENVPN_PASSWORD= 48 | 49 | # Used for OAuth 2 authentication 50 | # https://pusher.github.io/oauth2_proxy/auth-configuration 51 | # Just use a random password to encrypt the cookie 52 | GITHUB_ORG= 53 | GITHUB_OAUTH_CLIENT_ID= 54 | GITHUB_OAUTH_CLIENT_SECRET= 55 | OAUTH2_PROXY_COOKIE_SECRET= 56 | 57 | # Bitwarden 58 | # Use a long random password for the admin token (example: openssl rand -base64 48) 59 | ADMIN_TOKEN= 60 | SMTP_SERVER= 61 | EMAIL_FROM= 62 | EMAIL_TO= 63 | EMAIL_PASSWORD= 64 | 65 | # Gotify 66 | GOTIFY_PASSWORD= 67 | # Gotify Tokens 68 | GOTIFY_WATCHTOWER= 69 | 70 | # Rclone 71 | RCLONE_CONFIG_REMOTE_CLIENT_ID= 72 | RCLONE_CONFIG_REMOTE_CLIENT_SECRET= 73 | RCLONE_CONFIG_REMOTE_TOKEN= 74 | RCLONE_CONFIG_REMOTE_ROOT_FOLDER_ID= 75 | 76 | # Not currently used 77 | HTTP_USERNAME= 78 | HTTP_PASSWORD= 79 | TRANSMISSION_USERNAME= 80 | TRANSMISSION_PASSWORD= 81 | ``` 82 | 83 | Ideally you should fully configure Traefik before launching any containers. This is simple, just reference the included Traefik config files (`config/traefik2`) and replace `***FQDN***` in the `middleware.yml` with your own information. 84 | 85 | --- 86 | 87 | ## Launching containers: 88 | 89 | 1. To launch all the containers: 90 | ``` 91 | docker-compose up -d 92 | ``` 93 | 94 | 2. To launch an individual container, specify the service (for example: Radarr): 95 | ``` 96 | docker-compose up -d radarr 97 | ``` 98 | 99 | 3. To launch multiple containers, separate the services with spaces (for example: db1 and nextcloud): 100 | ``` 101 | docker-compose up -d db1 nextcloud 102 | ``` 103 | 104 | --- 105 | 106 | > **_NOTE:_** New containers are evaluated in the dev folder before graduating to the pi-stack. If there's something you want that isn't in the stack you can check for it in the dev folder and move it over. 107 | 108 | > **_NOTE:_** You could technically run this on various chipset architectures, but you'll have to change some of the images if you're not running on a Raspberry Pi or some other ARM-based computer. 109 | 110 | --- 111 | 112 | ## Troubleshooting: 113 | 114 | ### Check if Traefik is running: 115 | 116 | - If things stop working, make sure Traefik is running. 117 | 118 | ```bash 119 | docker container ls | grep traefik 120 | docker-compose up -d traefik 121 | ``` 122 | 123 | ### Starting Traefik results in an error: 124 | 125 | - If you receive an error that port binding failed: 126 | 127 | ``` 128 | Starting traefik ... error 129 | ERROR: for traefik Cannot start service traefik: driver failed programming external connectivity on endpoint traefik: Bind for 0.0.0.0:443 failed: port is already allocated 130 | ``` 131 | 132 | - You can try to resolve this by running: 133 | 134 | ```bash 135 | sudo systemctl restart docker 136 | ``` 137 | 138 | > **NOTE:** If that doesn't fix it, first try the following and then restart Docker: 139 | > ``` 140 | > ❯ sudo fuser 443/tcp 141 | > 443/tcp: 2586 2594 142 | > ❯ ps -p 2586 143 | > PID TTY TIME CMD 144 | > 2586 ? 00:00:00 docker-proxy 145 | > ❯ ps -p 2381 146 | > PID TTY TIME CMD 147 | > ❯ sudo kill 2586 2594 148 | > ``` 149 | 150 | ### Refresh Let's Encrypt certs: 151 | 152 | - If you wish to force Traefik to refresh its certs, you can run: 153 | 154 | ```bash 155 | cd /mnt/hdd/docker/config/traefik2/acme 156 | : > acme.json 157 | docker restart traefik 158 | ``` 159 | -------------------------------------------------------------------------------- /config/traefik-2.x-old/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | 4 | services: 5 | 6 | ######################################################################################## 7 | # Traefik 8 | # https://hub.docker.com/_/traefik 9 | ######################################################################################## 10 | 11 | traefik: 12 | hostname: traefik 13 | image: traefik:latest 14 | container_name: traefik 15 | environment: 16 | - DUCKDNS_TOKEN=${DUCKDNS_TOKEN} 17 | restart: always 18 | domainname: ${FQDN} 19 | networks: 20 | - frontend 21 | #- router 22 | #- middleware 23 | #- service 24 | - backend 25 | ports: 26 | - "80:80" 27 | - "443:443" 28 | #- "8080:8080" 29 | labels: 30 | - "traefik.enable=true" 31 | - "traefik.backend=traefik" 32 | #- "traefik.frontend.rule=Host:traefik.${FQDN}" #Traefik 1.x 33 | #- "traefik.http.routers.router0.rule=Host(`traefik.${FQDN}`)" #Traefik 2.x 34 | - "traefik.http.routers.router0.rule=Host(`${FQDN}`) && PathPrefix(`/traefik`)" #Traefik 2.x 35 | - "traefik.frontend.rule=Host:${FQDN}; PathPrefixStrip: /traefik" 36 | - "traefik.port=8080" 37 | - "traefik.docker.network=backend" 38 | - "traefik.frontend.headers.SSLRedirect=true" 39 | - "traefik.frontend.headers.STSSeconds=315360000" 40 | - "traefik.frontend.headers.browserXSSFilter=true" 41 | - "traefik.frontend.headers.contentTypeNosniff=true" 42 | - "traefik.frontend.headers.forceSTSHeader=true" 43 | - "traefik.frontend.headers.SSLHost=duckdns.org" 44 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 45 | - "traefik.frontend.headers.STSPreload=true" 46 | - "traefik.frontend.headers.frameDeny=true" 47 | #- "traefik.frontend.auth.basic.users=${HTTP_USERNAME}:${HTTP_PASSWORD}" #traefik 1.x 48 | #- "traefik.http.routers.router0.middlewares=auth" #traefik 2.x 49 | #- "traefik.http.middlewares.auth.basicauth.users=${HTTP_USERNAME1}:${HTTP_PASSWORD1},${HTTP_USERNAME2}:${HTTP_PASSWORD2}" #traefik 2.x 50 | # Require oauth2 for authentication 51 | - "traefik.frontend.auth.forward.address=https://${FQDN}/oauth2/auth" 52 | - "traefik.frontend.auth.forward.trustForwardHeader=true" 53 | - "traefik.frontend.auth.forward.authResponseHeaders=X-Auth-Request-User,X-Auth-Request-Email,Authorization,Set-Cookie" 54 | - "traefik.frontend.errors.401.backend=oauth2" 55 | - "traefik.frontend.errors.401.status=401" 56 | - "traefik.frontend.errors.401.query=/oauth2/sign_in" 57 | volumes: 58 | - /var/run/docker.sock:/var/run/docker.sock:ro 59 | - ${CONFIG_DIR}/traefik:/etc/traefik 60 | - ${CONFIG_DIR}/shared:/shared 61 | 62 | 63 | 64 | networks: 65 | frontend: 66 | external: 67 | name: frontend 68 | #run: docker network create --name=frontend 69 | backend: 70 | external: 71 | name: backend 72 | #run: docker network create --name=backend 73 | -------------------------------------------------------------------------------- /config/traefik/acme/acme.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/config/traefik/acme/acme.json -------------------------------------------------------------------------------- /config/traefik/rules.toml: -------------------------------------------------------------------------------- 1 | loglevel = "ERROR" 2 | 3 | [backends] 4 | [backends.backend-cockpit-pi] 5 | [backends.backend-cockpit-pi.servers] 6 | [backends.backend-cockpit-pi.servers.server-cockpit-pi-ext] 7 | url = "http://192.168.1.50:9090" 8 | weight = 0 9 | [backends.backend-cockpit-pc] 10 | [backends.backend-cockpit-pc.servers] 11 | [backends.backend-cockpit-pc.servers.server-cockpit-pc-ext] 12 | url = "http://192.168.1.55:9090" 13 | weight = 0 14 | [backends.backend-plex] 15 | [backends.backend-plex.servers] 16 | [backends.backend-plex.servers.server-plex-ext] 17 | url = "http://192.168.1.50:32400/web/index.html" 18 | weight = 0 19 | [backends.backend-netgear] 20 | [backends.backend-netgear.servers] 21 | [backends.backend-netgear.servers.server-netgear-ext] 22 | url = "http://192.168.1.1" 23 | weight = 0 24 | [backends.backend-guacamole] 25 | [backends.backend-guacamole.servers] 26 | [backends.backend-guacamole.servers.server-guacamole-ext] 27 | url = "http://192.168.1.55:8080" 28 | weight = 0 29 | [backends.backend-freeipa] 30 | [backends.backend-freeipa.servers] 31 | [backends.backend-freeipa.servers.server-freeipa-ext] 32 | url = "https://192.168.1.55:443" 33 | weight = 0 34 | 35 | [frontends] 36 | [frontends.frontend-cockpit-pi] 37 | backend = "backend-cockpit-pi" 38 | passHostHeader = true 39 | [frontends.frontend-cockpit-pi.routes] 40 | [frontends.frontend-cockpit-pi.routes.route-cockpit-pi-ext] 41 | rule = "Host:cockpit-pi.***INSERT_FQDN***" 42 | [frontends.frontend-cockpit-pc] 43 | backend = "backend-cockpit-pc" 44 | passHostHeader = true 45 | [frontends.frontend-cockpit-pc.routes] 46 | [frontends.frontend-cockpit-pc.routes.route-cockpit-pc-ext] 47 | rule = "Host:cockpit-pc.***INSERT_FQDN***" 48 | [frontends.frontend-plex] 49 | backend = "backend-plex" 50 | passHostHeader = true 51 | [frontends.frontend-plex.routes] 52 | [frontends.frontend-plex.routes.route-plex-ext] 53 | rule = "Host:plex.***INSERT_FQDN***" 54 | [frontends.frontend-netgear] 55 | backend = "backend-netgear" 56 | passHostHeader = true 57 | [frontends.frontend-netgear.routes] 58 | [frontends.frontend-netgear.routes.route-netgear-ext] 59 | rule = "Host:netgear.***INSERT_FQDN***" 60 | [frontends.frontend-guacamole] 61 | backend = "backend-guacamole" 62 | passHostHeader = true 63 | [frontends.frontend-guacamole.routes] 64 | [frontends.frontend-guacamole.routes.route-guacamole-ext] 65 | rule = "Host:guacamole.***INSERT_FQDN***;AddPrefix:/guacamole" 66 | [frontends.frontend-freeipa] 67 | backend = "backend-freeipa" 68 | passHostHeader = true 69 | [frontends.frontend-freeipa.routes] 70 | [frontends.frontend-freeipa.routes.route-freeipa-ext] 71 | rule = "Host:ipa.***INSERT_FQDN***" 72 | 73 | -------------------------------------------------------------------------------- /config/traefik/traefik.toml: -------------------------------------------------------------------------------- 1 | logLevel = "WARN" #DEBUG, INFO, WARN, ERROR, FATAL, PANIC 2 | insecureSkipVerify = true # If set to true invalid SSL certificates are accepted for backends. This disables detection of man-in-the-middle attacks so should only be used on secure backend networks 3 | defaultEntryPoints = ["http", "https"] 4 | 5 | # WEB interface of Traefik - it will show web page with overview of frontend and backend configurations 6 | [api] 7 | entryPoint = "traefik" 8 | dashboard = true 9 | address = ":8080" 10 | 11 | # Force HTTPS 12 | [entryPoints] 13 | [entryPoints.http] 14 | address = ":80" 15 | [entryPoints.http.redirect] 16 | entryPoint = "https" 17 | [entryPoints.https] 18 | address = ":443" 19 | [entryPoints.https.tls] 20 | # [entryPoints.https.tls.defaultCertificate] 21 | 22 | # File configuration backends 23 | [file] 24 | filename = "/etc/traefik/rules.toml" 25 | watch = true 26 | 27 | # Let's Encrypt configuration 28 | [acme] 29 | email = "***INSERT_EMAIL***" 30 | storage="/etc/traefik/acme/acme.json" 31 | entryPoint = "https" 32 | acmeLogging=true 33 | onDemand = false # Create certificate when container is created 34 | onHostRule = true 35 | # Use a HTTP-01 acme challenge rather than TLS-SNI-01 challenge 36 | #[acme.httpChallenge] 37 | #entryPoint = "http" 38 | 39 | [[acme.domains]] 40 | main = "*.***INSERT_FQDN***" # The first asterisk (*.FQDN) generates wildcard certificates 41 | sans = ["***INSERT_FQDN***"] 42 | 43 | # List of providers found here: https://docs.traefik.io/configuration/acme/#provider 44 | [acme.dnsChallenge] 45 | provider = "duckdns" 46 | delayBeforeCheck = 0 47 | 48 | # Connection to docker host system (docker.sock) 49 | [docker] 50 | endpoint = "unix:///var/run/docker.sock" 51 | domain = "***INSERT_FQDN***" 52 | watch = true 53 | # This will make containers hidden unless they have a "traefik.enable=true" label 54 | exposedbydefault = false 55 | -------------------------------------------------------------------------------- /config/traefik2/acme/acme.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/config/traefik2/acme/acme.json -------------------------------------------------------------------------------- /config/traefik2/rules/app-edgeos.yml: -------------------------------------------------------------------------------- 1 | http: 2 | routers: 3 | edgeos-rtr: 4 | rule: "Host(`edgeos.***FQDN***`)" # need to use HostHeader if using Traefik 2.2.2 5 | entryPoints: 6 | - websecure # https 7 | middlewares: 8 | - chain-oauth2-proxy@file 9 | service: edgeos-svc 10 | tls: true 11 | services: 12 | edgeos-svc: 13 | loadBalancer: 14 | servers: 15 | - url: "https://192.168.1.1" # some routers may need to specify "http" instead of "https" 16 | -------------------------------------------------------------------------------- /config/traefik2/rules/app-plex.yml: -------------------------------------------------------------------------------- 1 | http: 2 | routers: 3 | plex-rtr: 4 | rule: "Host(`plex.***FQDN***`)" 5 | entryPoints: 6 | - websecure # https 7 | middlewares: 8 | - chain-no-auth 9 | service: plex-svc 10 | tls: true 11 | services: 12 | plex-svc: 13 | loadBalancer: 14 | servers: 15 | - url: "http://192.168.1.50:32400/web/index.html" 16 | -------------------------------------------------------------------------------- /config/traefik2/rules/app-website.yml: -------------------------------------------------------------------------------- 1 | http: 2 | routers: 3 | website-rtr: 4 | rule: "Host(`***domain***.com`)" # need to use HostHeader if using Traefik 2.2.2 5 | entryPoints: 6 | - websecure # https 7 | middlewares: 8 | - chain-no-auth@file 9 | service: website-svc 10 | tls: 11 | certResolver: cloudflare 12 | domains: 13 | - main: "***domain***.com" 14 | sans: "*.***domain***.com" 15 | services: 16 | website-svc: 17 | loadBalancer: 18 | servers: 19 | - url: "http://192.168.1.20:8080" 20 | -------------------------------------------------------------------------------- /config/traefik2/rules/middleware-chains.yml: -------------------------------------------------------------------------------- 1 | http: 2 | middlewares: 3 | chain-no-auth: 4 | chain: 5 | middlewares: 6 | - middlewares-rate-limit 7 | - middlewares-secure-headers 8 | 9 | chain-basic-auth: 10 | chain: 11 | middlewares: 12 | - middlewares-rate-limit 13 | - middlewares-secure-headers 14 | - middlewares-basic-auth 15 | 16 | chain-traefik-forward-auth: 17 | chain: 18 | middlewares: 19 | - middlewares-rate-limit 20 | - middlewares-secure-headers 21 | - middlewares-traefik-forward-auth 22 | 23 | chain-oauth2-proxy: 24 | chain: 25 | middlewares: 26 | - middlewares-rate-limit 27 | - middlewares-secure-headers 28 | - middlewares-oauth2-proxy 29 | 30 | chain-authelia: 31 | chain: 32 | middlewares: 33 | - middlewares-rate-limit 34 | - middlewares-secure-headers 35 | - middlewares-authelia 36 | -------------------------------------------------------------------------------- /config/traefik2/rules/middleware.yml: -------------------------------------------------------------------------------- 1 | http: 2 | middlewares: 3 | middlewares-basic-auth: 4 | basicAuth: 5 | # users: 6 | # - "user:Password123" 7 | usersFile: "/shared/.htpasswd" #be sure to mount the volume through docker-compose.yml 8 | realm: "Traefik 2 Basic Auth" 9 | 10 | middlewares-rate-limit: 11 | rateLimit: 12 | average: 100 13 | burst: 50 14 | 15 | middlewares-secure-headers: 16 | headers: 17 | accessControlAllowMethods: 18 | - GET 19 | - OPTIONS 20 | - PUT 21 | accessControlMaxAge: 100 22 | hostsProxyHeaders: 23 | - "X-Forwarded-Host" 24 | # sslRedirect: true # deprecated in Traefik 2.1 25 | stsSeconds: 63072000 26 | stsIncludeSubdomains: true 27 | stsPreload: true 28 | forceSTSHeader: true 29 | # frameDeny: true #overwritten by customFrameOptionsValue 30 | customFrameOptionsValue: "allow-from https:***FQDN***" #CSP takes care of this but may be needed for organizr. 31 | contentTypeNosniff: true 32 | browserXssFilter: true 33 | # sslForceHost: true # add sslHost to all of the services 34 | # sslHost: "***FQDN***" 35 | referrerPolicy: "same-origin" 36 | # Setting contentSecurityPolicy is more secure but it can break things. Proper auth will reduce the risk. 37 | # the below line also breaks some apps due to 'none' - sonarr, radarr, etc. 38 | # contentSecurityPolicy: "frame-ancestors '*.***FQDN***:*';object-src 'none';script-src 'none';" 39 | permissionsPolicy: "camera 'none'; geolocation 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none';" 40 | customResponseHeaders: 41 | X-Robots-Tag: "none,noarchive,nosnippet,notranslate,noimageindex," 42 | server: "" 43 | 44 | middlewares-traefik-forward-auth: # thomseddon/traefik-forward-auth 45 | forwardAuth: 46 | address: "http://oauth:4181" # Make sure you have the OAuth service in docker-compose.yml 47 | trustForwardHeader: true 48 | authResponseHeaders: 49 | - "X-Forwarded-User" 50 | 51 | middlewares-oauth2-proxy: # oauth2-proxy/oauth2-proxy 52 | forwardAuth: 53 | address: "http://oauth2:4180" 54 | trustForwardHeader: true 55 | authResponseHeaders: 56 | - "X-Auth-Request-Access-Token" 57 | - "Authorization" 58 | # - "X-Auth-Request-User" 59 | # - "X-Auth-Request-Email" 60 | # - "Set-Cookie" 61 | # - "X-Auth-User" 62 | # - "X-Secret 63 | 64 | middlewares-authelia: 65 | forwardAuth: 66 | address: "http://authelia:9091/api/verify?rd=https://authelia.***FQDN***" 67 | trustForwardHeader: true 68 | authResponseHeaders: 69 | - "Remote-User" 70 | - "Remote-Groups" 71 | -------------------------------------------------------------------------------- /config/traefik2/traefik.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/config/traefik2/traefik.log -------------------------------------------------------------------------------- /dev/apprise/compose.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: apprise 3 | services: 4 | apprise: 5 | image: caronc/apprise:latest 6 | container_name: apprise 7 | environment: # Full list is here: https://hub.docker.com/r/caronc/apprise 8 | - APPRISE_STATEFUL_MODE=simple 9 | # - SECRET_KEY=${APPRISE_SECRET_KEY} # Applies only when stateful mode is set to `hash` 10 | volumes: 11 | - ${CONFIG_DIR}/apprise:/config 12 | - ${VOLUME_DIR}/apprise:/attach 13 | # ports: 14 | # - 8000:8000 15 | restart: unless-stopped 16 | networks: 17 | - traefik 18 | labels: 19 | - traefik.enable=true 20 | ## HTTP Routers 21 | - traefik.http.routers.apprise-rtr.entrypoints=websecure 22 | - traefik.http.routers.apprise-rtr.rule=Host(`apprise.$FQDN`) 23 | - traefik.http.routers.apprise-rtr.tls=true 24 | ## Middlewares 25 | # - traefik.http.routers.apprise-rtr.middlewares=chain-no-auth@file # No Authentication 26 | # - traefik.http.routers.apprise-rtr.middlewares=chain-basic-auth@file # Basic Authentication 27 | - traefik.http.routers.apprise-rtr.middlewares=chain-oauth2-proxy@file # OAuth 2.0 28 | ## HTTP Services 29 | - traefik.http.routers.apprise-rtr.service=apprise-svc 30 | - traefik.http.services.apprise-svc.loadbalancer.server.port=8000 31 | 32 | networks: 33 | traefik: 34 | name: traefik 35 | external: true 36 | #run: docker network create traefik 37 | 38 | -------------------------------------------------------------------------------- /dev/authelia/configuration.yml: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # Authelia configuration # 3 | ############################################################### 4 | server: 5 | host: 0.0.0.0 6 | port: 9091 7 | log: 8 | level: debug 9 | # This secret can also be set using the env variables AUTHELIA_JWT_SECRET_FILE 10 | # jwt_secret: ${AUTHELIA_JWT_SECRET_FILE} 11 | default_redirection_url: https://authelia.***FQDN*** 12 | totp: 13 | issuer: authelia.com 14 | period: 30 15 | skew: 1 16 | 17 | # Enable the following for Duo Push Notification support 18 | # https://www.authelia.com/docs/features/2fa/push-notifications.html 19 | #duo_api: 20 | # hostname: api-123456789.example.com 21 | # integration_key: ABCDEF 22 | # # This secret can also be set using the env variables AUTHELIA_DUO_API_SECRET_KEY_FILE 23 | # secret_key: 1234567890abcdefghifjkl 24 | 25 | authentication_backend: 26 | file: 27 | path: /config/users_database.yml 28 | # customize passwords based on https://docs.authelia.com/configuration/authentication/file.html 29 | password: 30 | algorithm: argon2id 31 | iterations: 1 32 | salt_length: 16 33 | parallelism: 8 34 | memory: 1024 35 | 36 | # https://docs.authelia.com/configuration/access-control.html 37 | access_control: 38 | default_policy: deny 39 | rules: 40 | # Rules applied to everyone 41 | - domain: authelia.***FQDN*** 42 | policy: bypass 43 | - domain: "***FQDN***" 44 | policy: one_factor 45 | - domain: "*.***FQDN***" 46 | policy: one_factor 47 | # - domain: secure.example.com 48 | # policy: two_factor 49 | 50 | session: 51 | name: authelia_session 52 | # This secret can also be set using the env variables AUTHELIA_SESSION_SECRET_FILE 53 | # secret: ${AUTHELIA_SESSION_SECRET_FILE} 54 | expiration: 3600 # 1 hour 55 | inactivity: 300 # 5 minutes 56 | domain: ***FQDN*** # Should match whatever your root protected domain is 57 | 58 | # Optional. Can improve performance on a busy system. If not enabled, session info is stored in memory. 59 | # redis: 60 | # host: redis 61 | # port: 6379 62 | # This secret can also be set using the env variables AUTHELIA_SESSION_REDIS_PASSWORD_FILE 63 | # password: $AUTHELIA_SESSION_REDIS_PASSWORD_FILE} 64 | 65 | regulation: 66 | max_retries: 3 67 | find_time: 120 68 | ban_time: 300 69 | 70 | storage: 71 | local: 72 | path: /config/db.sqlite3 73 | 74 | notifier: 75 | # For testing purpose, notifications can be sent in a file 76 | filesystem: 77 | filename: /config/notification.txt 78 | # For email, create an app password, following: https://support.google.com/accounts/answer/185833?hl=en 79 | # smtp: 80 | # username: test 81 | # # This secret can also be set using the env variables AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE 82 | # password: ${AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE} 83 | # host: smtp.gmail.com 84 | # port: 587 85 | # sender: admin@example.com 86 | -------------------------------------------------------------------------------- /dev/authelia/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | 4 | secrets: 5 | authelia_jwt_secret: 6 | file: ${CONFIG_DIR}/authelia/secrets/authelia_jwt_secret 7 | authelia_session_secret: 8 | file: ${CONFIG_DIR}/authelia/secrets/authelia_session_secret 9 | 10 | services: 11 | # Authelia (Lite) - Self-Hosted Single Sign-On and Two-Factor Authentication 12 | authelia: 13 | container_name: authelia 14 | # Check this before upgrading: https://github.com/authelia/authelia/blob/master/BREAKING.md 15 | # image: authelia/authelia:latest 16 | image: authelia/authelia:latest 17 | restart: always 18 | networks: 19 | - backend 20 | # ports: 21 | # - "9091:9091" 22 | volumes: 23 | - ${CONFIG_DIR}/authelia:/config 24 | environment: 25 | - TZ=${TZ} 26 | - FQDN=${FQDN} 27 | - AUTHELIA_JWT_SECRET_FILE=/run/secrets/authelia_jwt_secret 28 | - AUTHELIA_SESSION_SECRET_FILE=/run/secrets/authelia_session_secret 29 | secrets: 30 | - authelia_jwt_secret 31 | - authelia_session_secret 32 | labels: 33 | - "traefik.enable=true" 34 | ## HTTP Routers 35 | - "traefik.http.routers.authelia-rtr.entrypoints=websecure" 36 | - "traefik.http.routers.authelia-rtr.rule=Host(`authelia.${FQDN}`)" 37 | ## Middlewares 38 | - "traefik.http.routers.authelia-rtr.middlewares=chain-authelia@file" 39 | ## HTTP Services 40 | - "traefik.http.routers.authelia-rtr.service=authelia-svc" 41 | - "traefik.http.services.authelia-svc.loadbalancer.server.port=9091" 42 | 43 | networks: 44 | backend: 45 | external: 46 | name: backend 47 | #run: docker network create backend -------------------------------------------------------------------------------- /dev/authelia/users_database.yml: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # Users Database # 3 | ############################################################### 4 | 5 | # This file can be used if you do not have an LDAP set up. 6 | 7 | # See: Password hash algorithm tuning 8 | # https://docs.authelia.com/configuration/authentication/file.html#password-hash-algorithm-tuning 9 | 10 | # List of users 11 | users: 12 | authelia: 13 | displayname: "Authelia User" 14 | password: "$argon2id$v=19$m=65536,t=1,p=8$R3pzNndzN0diOUZ1RG5lRw$8qYy6J98DqaipGE+raTtJ9jImvZjlUBPauTfk/XiLz8" # Password is 'authelia' 15 | email: ${EMAIL} 16 | groups: 17 | - admins 18 | - dev -------------------------------------------------------------------------------- /dev/autoheal/compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | 3 | autoheal: 4 | image: willfarrell/autoheal:latest 5 | container_name: autoheal 6 | environment: 7 | - AUTOHEAL_CONTAINER_LABEL=autoheal 8 | - APPRISE_URL=http://apprise:8000/notify/${APPRISE_CONFIG_ID_HEALTHCHECKS} 9 | #network_mode: none 10 | networks: 11 | - traefik 12 | restart: always 13 | volumes: 14 | - /var/run/docker.sock:/var/run/docker.sock 15 | command: autoheal 16 | 17 | networks: 18 | traefik: 19 | name: traefik 20 | external: true 21 | #run: docker network create traefik 22 | 23 | -------------------------------------------------------------------------------- /dev/babybuddy/compose.yaml: -------------------------------------------------------------------------------- 1 | name: babybuddy 2 | services: 3 | babybuddy: 4 | image: lscr.io/linuxserver/babybuddy 5 | container_name: babybuddy 6 | volumes: 7 | - ${CONFIG_DIR}/babybuddy:/config 8 | # ports: 9 | # - 8000:8000 10 | networks: 11 | - traefik 12 | restart: unless-stopped 13 | labels: 14 | - autoheal=true 15 | - traefik.enable=true 16 | ## HTTP Routers 17 | - traefik.http.routers.babybuddy-rtr.entrypoints=websecure 18 | - traefik.http.routers.babybuddy-rtr.rule=Host(`babybuddy.$FQDN`) 19 | - traefik.http.routers.babybuddy-rtr.tls=true 20 | ## Middlewares 21 | - traefik.http.routers.babybuddy-rtr.middlewares=chain-no-auth@file # No Authentication 22 | # - traefik.http.routers.babybuddy-rtr.middlewares=chain-basic-auth@file # Basic Authentication 23 | # - traefik.http.routers.babybuddy-rtr.middlewares=chain-oauth2-proxy@file # OAuth 2.0 24 | ## HTTP Services 25 | - traefik.http.routers.babybuddy-rtr.service=babybuddy-svc 26 | - traefik.http.services.babybuddy-svc.loadbalancer.server.port=8000 27 | 28 | networks: 29 | traefik: 30 | name: traefik 31 | external: true 32 | #run: docker network create traefik 33 | -------------------------------------------------------------------------------- /dev/backup/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '2' 3 | 4 | volumes: 5 | db: 6 | driver: local 7 | nextcloud: 8 | driver: local 9 | 10 | services: 11 | # db: 12 | # container_name: MariaDB 13 | # image: mariadb:latest 14 | # command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW 15 | # restart: unless-stopped 16 | # volumes: 17 | # - db:/var/lib/mysql 18 | # environment: 19 | # - MYSQL_ROOT_PASSWORD= 20 | # - MYSQL_PASSWORD= 21 | # - MYSQL_DATABASE=nextcloud 22 | # - MYSQL_USER=nextcloud 23 | 24 | db: 25 | env_file: /home/pi/containers/config/variables.env 26 | image: postgres 27 | container_name: PostgreSQL 28 | restart: unless-stopped 29 | volumes: 30 | - db:/var/lib/postgresql/data 31 | environment: 32 | - POSTGRES_DB=whatever 33 | - POSTGRES_USER=nextcloud 34 | - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} 35 | networks: 36 | - default 37 | 38 | Nextcloud: 39 | env_file: /home/pi/containers/config/variables.env 40 | image: nextcloud:latest 41 | container_name: Nextcloud 42 | ports: 43 | - 8081:80 44 | links: 45 | - db 46 | volumes: 47 | - nextcloud:/var/www/html 48 | - /home/pi/containers/config/nextcloud:/var/www/html/data:rw #config directory 49 | - /mnt/hdd/docker/nextcloud:/mnt/hdd/storage #external storage 50 | # Make check_data_directory_permissions => false and enable external storage support (https://github.com/nextcloud/docker/issues/236) 51 | restart: unless-stopped 52 | environment: 53 | - PUID=1000 54 | - PGID=1000 55 | - POSTGRES_DB=nextcloud 56 | - POSTGRES_USER=nextcloud 57 | - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} 58 | - POSTGRES_HOST=db 59 | - NEXTCLOUD_ADMIN_USER=***REMOVED*** 60 | - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_PASSWORD} 61 | - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.***REMOVED***.duckdns.org duckdns.org 62 | domainname: nextcloud.***REMOVED***.duckdns.org 63 | networks: 64 | - default 65 | - traefik_proxy 66 | labels: 67 | - "traefik.enable=true" 68 | - "traefik.backend=Nextcloud" 69 | - "traefik.frontend.rule=Host:nextcloud.***REMOVED***.duckdns.org" 70 | - "traefik.port=80" 71 | - "traefik.docker.network=traefik_proxy" 72 | - "traefik.frontend.headers.SSLRedirect=true" 73 | - "traefik.frontend.headers.STSSeconds=315360000" 74 | - "traefik.frontend.headers.browserXSSFilter=true" 75 | - "traefik.frontend.headers.contentTypeNosniff=true" 76 | - "traefik.frontend.headers.forceSTSHeader=true" 77 | - "traefik.frontend.headers.SSLHost=example.com" 78 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 79 | - "traefik.frontend.headers.STSPreload=true" 80 | - "traefik.frontend.headers.frameDeny=true" 81 | 82 | duplicati: 83 | image: linuxserver/duplicati 84 | container_name: duplicati 85 | environment: 86 | - PUID=1000 87 | - PGID=1000 88 | - TZ=America/Los_Angeles 89 | volumes: 90 | - /home/pi/containers/config/duplicati:/config 91 | - /mnt/hdd/docker/backups:/backups 92 | - /home/pi/containers:/source 93 | #ports: 94 | #- 8200:8200 95 | restart: unless-stopped 96 | networks: 97 | - traefik_proxy 98 | labels: 99 | - "traefik.enable=true" 100 | - "traefik.backend=duplicati" 101 | - "traefik.frontend.rule=Host:duplicati.***REMOVED***.duckdns.org" 102 | - "traefik.port=8200" 103 | - "traefik.docker.network=traefik_proxy" 104 | - "traefik.frontend.headers.SSLRedirect=true" 105 | - "traefik.frontend.headers.STSSeconds=315360000" 106 | - "traefik.frontend.headers.browserXSSFilter=true" 107 | - "traefik.frontend.headers.contentTypeNosniff=true" 108 | - "traefik.frontend.headers.forceSTSHeader=true" 109 | - "traefik.frontend.headers.SSLHost=example.com" 110 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 111 | - "traefik.frontend.headers.STSPreload=true" 112 | - "traefik.frontend.headers.frameDeny=true" 113 | 114 | networks: 115 | traefik_proxy: 116 | external: 117 | name: traefik_proxy 118 | default: 119 | driver: bridge 120 | -------------------------------------------------------------------------------- /dev/bookstack/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3" 3 | services: 4 | 5 | bookstack: 6 | image: linuxserver/bookstack 7 | container_name: bookstack 8 | environment: 9 | - PUID=${PUID} 10 | - PGID=${PGID} 11 | - DB_HOST=bookstack_db 12 | - DB_USER=bookstack 13 | - DB_PASS=${MYSQL_PASSWORD} # Had trouble with this. May not support password with special characters? 14 | - DB_DATABASE=bookstackapp 15 | - APP_URL=https://bookstack.${FQDN} 16 | volumes: 17 | - ${CONFIG_DIR}/bookstack:/config 18 | ports: 19 | - 6875:80 20 | restart: unless-stopped 21 | networks: 22 | - backend 23 | depends_on: 24 | - bookstack_db 25 | labels: 26 | - "traefik.enable=true" 27 | - "traefik.backend=bookstack" 28 | - "traefik.frontend.rule=Host:bookstack.${FQDN}" 29 | - "traefik.port=80" 30 | - "traefik.docker.network=backend" 31 | - "traefik.frontend.headers.SSLRedirect=true" 32 | - "traefik.frontend.headers.STSSeconds=315360000" 33 | - "traefik.frontend.headers.browserXSSFilter=true" 34 | - "traefik.frontend.headers.contentTypeNosniff=true" 35 | - "traefik.frontend.headers.forceSTSHeader=true" 36 | - "traefik.frontend.headers.SSLHost=example.com" 37 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 38 | - "traefik.frontend.headers.STSPreload=true" 39 | - "traefik.frontend.headers.frameDeny=true" 40 | 41 | bookstack_db: 42 | image: linuxserver/mariadb 43 | container_name: bookstack_db 44 | environment: 45 | - PUID=${PUID} 46 | - PGID=${PGID} 47 | - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} 48 | - TZ=${TZ} 49 | - MYSQL_DATABASE=bookstackapp 50 | - MYSQL_USER=bookstack 51 | - MYSQL_PASSWORD=${MYSQL_PASSWORD} 52 | volumes: 53 | - ${CONFIG_DIR}/bookstackdb:/config 54 | restart: unless-stopped 55 | networks: 56 | - backend 57 | 58 | # bookstack_db: 59 | # image: mariadb:latest # There is no armv7 image available from MariaDB 60 | # container_name: bookstack_db 61 | # # command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW 62 | # restart: unless-stopped 63 | # volumes: 64 | # - ${CONFIG_DIR}/bookstackdb:/config 65 | # environment: 66 | # - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} 67 | # - MYSQL_PASSWORD=${MYSQL_PASSWORD} 68 | # - MYSQL_DATABASE=bookstackapp 69 | # - MYSQL_USER=bookstack 70 | 71 | networks: 72 | backend: 73 | external: 74 | name: backend 75 | #run: docker network create --name=backend -------------------------------------------------------------------------------- /dev/cloudflared/README.md: -------------------------------------------------------------------------------- 1 | # Cloudflared Tunnel 2 | 3 | Cloudflared Tunnels are cool, but it imposes limitations on large file data transfers. While it's nice to be able to close off ports 80 and 443 on my firewall, I decided the cons outweighed the advantages for me. 4 | 5 | I would absolutely recommend Cloudflared Tunnels for those in a CGNAT situation or if your ISP blocks ports 80 and 443, but without those restrictions I would not use it. 6 | 7 | Quick notes on configuring Cloudflared: 8 | 9 | 1. Create the tunnel on the Cloudflare Zero Trust console. 10 | 2. Start the tunnel container with your `${CLOUDFLARED_TOKEN}` 11 | 3. Create a public hostname: 12 | - Subdomain: `*` 13 | - Domain: `YOUR_DOMAIN` 14 | - Service: `HTTPS://traefik` 15 | - TLS: `*.YOUR_DOMAIN` 16 | 4. Remove your old `A` records for your domain from the Cloudflare DNS section 17 | 4. Add a DNS entry with the following: 18 | - Type: `CNAME` 19 | - Name: `*` 20 | - Target: `YOUR_TUNNEL_ID.cfargotunnel.com` 21 | 5. Block ports `80` and `443` on your router. -------------------------------------------------------------------------------- /dev/cloudflared/compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: cloudflared 3 | services: 4 | 5 | cloudflared: 6 | container_name: cloudflared 7 | image: cloudflare/cloudflared:latest 8 | restart: always 9 | command: tunnel run 10 | networks: 11 | - traefik 12 | environment: 13 | - TUNNEL_TOKEN=${CLOUDFLARED_TOKEN} 14 | 15 | networks: 16 | traefik: 17 | name: traefik 18 | external: true 19 | #run: docker network create traefik 20 | -------------------------------------------------------------------------------- /dev/code-server/.env: -------------------------------------------------------------------------------- 1 | # General / common settings 2 | PUID=1000 3 | PGID=1000 4 | TZ=America/New_York 5 | CONFIG_DIR=/mnt/hdd/docker/config 6 | FQDN= -------------------------------------------------------------------------------- /dev/code-server/README.md: -------------------------------------------------------------------------------- 1 | # Code-server (VS Code) 2 | 3 | ## Getting Started: 4 | Clone this repo, then create a [.env file](.env) and place it in the same directory as the [docker-compose.yml](docker-compose.yml). Paste the following content into the .env file and input/change variables according to your preferences. 5 | 6 | ```bash 7 | # General / common settings 8 | PUID=1000 9 | PGID=1000 10 | TZ=America/New_York 11 | CONFIG_DIR=/mnt/hdd/docker/config 12 | FQDN= 13 | ``` 14 | 15 | This container runs on a pre-defined network called `backend`. If you don't already have it created, run this: 16 | ```bash 17 | docker network create backend 18 | ``` 19 | 20 | Then simply run the docker-compose file to start the server: 21 | 22 | ```bash 23 | docker-compose up -d 24 | ``` 25 | -------------------------------------------------------------------------------- /dev/code-server/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3.7" 3 | services: 4 | code-server: 5 | image: linuxserver/code-server 6 | container_name: code-server 7 | environment: 8 | - PUID=${PUID} 9 | - PGID=${PGID} 10 | - TZ=${TZ} 11 | #- PASSWORD=password #optional 12 | #- SUDO_PASSWORD=password #optional 13 | - PROXY_DOMAIN=${FQDN} #optional 14 | volumes: 15 | - ${CONFIG_DIR}/code-server:/config 16 | #ports: 17 | #- 8443:8443 18 | restart: unless-stopped 19 | networks: 20 | - backend 21 | labels: 22 | - "traefik.enable=true" 23 | - "traefik.backend=code-server" 24 | - "traefik.frontend.rule=Host:code-server.${FQDN}" 25 | - "traefik.port=8443" 26 | - "traefik.protocol=https" 27 | - "traefik.docker.network=backend" 28 | - "traefik.frontend.headers.SSLRedirect=true" 29 | - "traefik.frontend.headers.STSSeconds=315360000" 30 | - "traefik.frontend.headers.browserXSSFilter=true" 31 | - "traefik.frontend.headers.contentTypeNosniff=true" 32 | - "traefik.frontend.headers.forceSTSHeader=true" 33 | - "traefik.frontend.headers.SSLHost=example.com" 34 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 35 | - "traefik.frontend.headers.STSPreload=true" 36 | - "traefik.frontend.headers.frameDeny=true" 37 | #- "traefik.frontend.auth.basic.users=${HTTP_USERNAME}:${HTTP_PASSWORD}" 38 | # Require oauth2 for authentication 39 | - "traefik.frontend.auth.forward.address=https://${FQDN}/oauth2/auth" 40 | - "traefik.frontend.auth.forward.trustForwardHeader=true" 41 | - "traefik.frontend.auth.forward.authResponseHeaders=X-Auth-Request-User,X-Auth-Request-Email,Authorization,Set-Cookie" 42 | - "traefik.frontend.errors.401.backend=oauth2" 43 | - "traefik.frontend.errors.401.status=401" 44 | - "traefik.frontend.errors.401.query=/oauth2/sign_in" 45 | 46 | networks: 47 | backend: 48 | #external: 49 | name: backend #docker network create backend -------------------------------------------------------------------------------- /dev/diskover/docker-compose..yml: -------------------------------------------------------------------------------- 1 | # https://github.com/linuxserver/docker-diskover 2 | # Still in developement -- Not tested! 3 | 4 | version: '2' 5 | services: 6 | diskover: 7 | image: linuxserver/diskover 8 | container_name: diskover 9 | environment: 10 | - PUID=${PUID} 11 | - PGID=${PGID} 12 | - TZ=${TZ} 13 | - REDIS_HOST=redis 14 | - REDIS_PORT=6379 15 | - ES_HOST=elasticsearch 16 | - ES_PORT=9200 17 | - ES_USER=elastic 18 | - ES_PASS=changeme 19 | - RUN_ON_START=true 20 | - USE_CRON=true 21 | volumes: 22 | - ${CONFIG_DIR}/diskover:/config 23 | - ${VOLUME_DIR}/diskover:/data 24 | ports: 25 | - 80:80 26 | - 9181:9181 27 | - 9999:9999 28 | mem_limit: 4096m 29 | restart: unless-stopped 30 | depends_on: 31 | - elasticsearch 32 | - redis 33 | elasticsearch: 34 | container_name: elasticsearch 35 | image: docker.elastic.co/elasticsearch/elasticsearch:5.6.9 36 | volumes: 37 | - ${VOLUME_DIR}/elasticsearch:/usr/share/elasticsearch/data 38 | environment: 39 | - bootstrap.memory_lock=true 40 | - "ES_JAVA_OPTS=-Xms2048m -Xmx2048m" 41 | ulimits: 42 | memlock: 43 | soft: -1 44 | hard: -1 45 | redis: 46 | container_name: redis 47 | image: redis:alpine 48 | volumes: 49 | - ${VOLUME_DIR}/redis:/data -------------------------------------------------------------------------------- /dev/downloaders/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "2" 3 | services: 4 | 5 | transmission-vpn: 6 | container_name: transmission-vpn 7 | image: haugene/transmission-openvpn:latest-armhf 8 | cap_add: 9 | - NET_ADMIN 10 | devices: 11 | - /dev/net/tun 12 | restart: unless-stopped 13 | # ports: 14 | # - "XXXX:9091" 15 | dns: 16 | - 1.1.1.1 17 | - 1.0.0.1 18 | volumes: 19 | - /etc/localtime:/etc/localtime:ro 20 | - /home/pi/containers/config/transmission-vpn:/data 21 | - /home/pi/containers/config/shared:/shared 22 | - /mnt/hdd/Downloads/Torrents/watch:/data/watch 23 | - /mnt/hdd/Downloads/Torrents/complete:/data/completed 24 | - /mnt/hdd/Downloads/Torrents/incomplete:/data/incomplete 25 | # - /home/pi/containers/config/transmission-vpn/openvpn:/etc/openvpn/torguard-custom 26 | environment: 27 | - OPENVPN_PROVIDER=TORGUARD 28 | # - OPENVPN_PROVIDER=TORGUARD-CUSTOM 29 | - OPENVPN_USERNAME=***REMOVED*** 30 | - OPENVPN_PASSWORD=***REMOVED*** 31 | - OPENVPN_CONFIG=USA-SEATTLE 32 | # - OPENVPN_CONFIG=TorGuard.USA.Seattle.STATIC 33 | - OPENVPN_OPTS=--inactive 3600 --ping 10 --ping-exit 60 34 | - LOCAL_NETWORK=192.168.1.0/24 35 | - PUID=1000 36 | - PGID=1000 37 | - TZ=America/Los_Angeles 38 | - TRANSMISSION_RPC_AUTHENTICATION_REQUIRED=true 39 | # - TRANSMISSION_RPC_HOST_WHITELIST="127.0.0.1,192.168.*.*" 40 | ### - TRANSMISSION_RPC_PASSWORD= 41 | - TRANSMISSION_RPC_USERNAME=***REMOVED*** 42 | - TRANSMISSION_UMASK=002 43 | - TRANSMISSION_RATIO_LIMIT=0.8999 44 | - TRANSMISSION_RATIO_LIMIT_ENABLED=true 45 | networks: 46 | - traefik_proxy 47 | labels: 48 | - "traefik.enable=true" 49 | - "traefik.backend=transmission-vpn" 50 | - "traefik.frontend.rule=Host:***REMOVED***.duckdns.org; PathPrefix: /transmission" 51 | # - "traefik.frontend.rule=Host:transmission.${DOMAINNAME}" 52 | - "traefik.port=9091" 53 | - "traefik.docker.network=traefik_proxy" 54 | - "traefik.frontend.headers.SSLRedirect=true" 55 | - "traefik.frontend.headers.STSSeconds=315360000" 56 | - "traefik.frontend.headers.browserXSSFilter=true" 57 | - "traefik.frontend.headers.contentTypeNosniff=true" 58 | - "traefik.frontend.headers.forceSTSHeader=true" 59 | - "traefik.frontend.headers.SSLHost=example.com" 60 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 61 | - "traefik.frontend.headers.STSPreload=true" 62 | - "traefik.frontend.headers.frameDeny=true" 63 | 64 | networks: 65 | traefik_proxy: 66 | external: 67 | name: traefik_proxy 68 | default: 69 | driver: bridge -------------------------------------------------------------------------------- /dev/duplicati/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | duplicati: 6 | image: duplicati/duplicati 7 | container_name: duplicati 8 | environment: 9 | - PUID=${PUID} 10 | - PGID=${PGID} 11 | - TZ=${TZ} 12 | volumes: 13 | - ${CONFIG_DIR}/duplicati:/data #config directory 14 | - ${VOLUME_DIR}/duplicati:/backups #local backups 15 | - ${EXTHDD_DIR}:/source #backup source directory 16 | #ports: 17 | #- 8200:8200 18 | restart: unless-stopped 19 | networks: 20 | - backend 21 | labels: 22 | - "traefik.enable=true" 23 | ## HTTP Routers 24 | - "traefik.http.routers.duplicati-rtr.entrypoints=websecure" 25 | - "traefik.http.routers.duplicati-rtr.rule=HostHeader(`duplicati.$FQDN`)" 26 | - "traefik.http.routers.duplicati-rtr.tls=true" 27 | ## Middlewares 28 | - "traefik.http.routers.duplicati-rtr.middlewares=chain-no-auth@file" # No Authentication 29 | # - "traefik.http.routers.duplicati-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 30 | # - "traefik.http.routers.duplicati-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 31 | ## HTTP Services 32 | - "traefik.http.routers.duplicati-rtr.service=duplicati-svc" 33 | - "traefik.http.services.duplicati-svc.loadbalancer.server.port=8200" 34 | 35 | networks: 36 | backend: 37 | external: 38 | name: backend 39 | #run: docker network create backend -------------------------------------------------------------------------------- /dev/emby/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | ###################################################################### 6 | # https://hub.docker.com/r/emby/embyserver_arm32v7 7 | # https://hub.docker.com/r/emby/embyserver/ 8 | ###################################################################### 9 | 10 | emby: 11 | image: emby/embyserver_arm32v7 12 | container_name: emby 13 | environment: 14 | - PUID=${PUID} 15 | - PGID=${PGID} 16 | - UID=1000 17 | - GID=100 18 | - TZ=${TZ} 19 | volumes: 20 | - ${CONFIG_DIR}/emby:/config 21 | - ${EXTHDD_DIR}/media:/mnt/media 22 | devices: 23 | - /dev/dri:/dev/dri # To mount all render nodes for VAAPI/NVDEC/NVENC 24 | ports: 25 | - 8096:8096 # http port 26 | - 8920:8920 # https port 27 | networks: 28 | - frontend 29 | restart: unless-stopped 30 | 31 | networks: 32 | frontend: 33 | external: 34 | name: frontend 35 | default: 36 | driver: bridge -------------------------------------------------------------------------------- /dev/flaresolverr/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | flaresolverr: 6 | # DockerHub mirror flaresolverr/flaresolverr:latest 7 | image: ghcr.io/flaresolverr/flaresolverr:latest 8 | container_name: flaresolverr 9 | environment: 10 | - LOG_LEVEL=${LOG_LEVEL:-info} 11 | - LOG_HTML=${LOG_HTML:-false} 12 | - CAPTCHA_SOLVER=${CAPTCHA_SOLVER:-none} 13 | - TZ=${TZ} 14 | # ports: 15 | # - "${PORT:-8191}:8191" 16 | restart: unless-stopped 17 | networks: 18 | - traefik 19 | 20 | networks: 21 | traefik: 22 | name: traefik 23 | external: true 24 | #run: docker network create traefik 25 | -------------------------------------------------------------------------------- /dev/freeipa/docker-compose.yml: -------------------------------------------------------------------------------- 1 | ######################################################################################## 2 | # FreeIPA 3 | # https://hub.docker.com/r/freeipa/freeipa-server 4 | # https://www.freeipa.org/page/Docker 5 | ######################################################################################## 6 | --- 7 | version: '3.7' 8 | 9 | services: 10 | 11 | freeipa: 12 | image: freeipa/freeipa-server 13 | container_name: freeipa 14 | hostname: freeipa.com 15 | restart: unless-stopped 16 | volumes: 17 | - /home/erik/containers/config/freeipa:/data 18 | environment: 19 | - password=test1 # The-directory-server-password 20 | - admin-password=test1 # The-admin-password 21 | #- IPA_SERVER_IP=10.12.0.98 22 | network_mode: host 23 | #networks: 24 | #- backend 25 | #ports: 26 | #- 53:53/udp 27 | #- 53:53 28 | #- 80:80 29 | #- 443:443 30 | #- 389:389 31 | #- 636:636 32 | #- 88:88 33 | #- 464:464 34 | #- 88:88/udp 35 | #- 464:464/udp 36 | #- 123:123/udp 37 | #- 7389:7389 38 | #- 9443:9443 39 | #- 9444:9444 40 | #- 9445:9445 41 | 42 | #networks: 43 | #backend: 44 | #name: backend -------------------------------------------------------------------------------- /dev/freeipa/docker-compose2.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | ################################################################## 4 | # SERVER 5 | # https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/configuring_identity_management/using-the-ui 6 | ################################################################## 7 | FreeIPAServer: 8 | image: freeipa/freeipa-server 9 | container_name: freeipa 10 | restart: always 11 | hostname: freeipa 12 | domainname: ***REMOVED***.duckdns.org 13 | privileged: true 14 | volumes: 15 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 16 | - /home/erik/containers/config/freeipa/freeipa.home.lan/data:/data:Z 17 | ports: 18 | - "8097:80" # HTTP 19 | - "9444:443" # HTTPS 20 | - "389:389" # LDAP 21 | - "636:636" # LDAPS 22 | - "88:88" # Kerberos 23 | - "464:464" # Kerberos 24 | - "88:88/udp" # Kerberos 25 | - "464:464/udp" # Kerberos 26 | - "123:123/udp" # ntp 27 | environment: 28 | - IPA_SERVER_HOSTNAME=ipa.***REMOVED***.duckdns.org 29 | - IPA_SERVER_INSTALL_OPTS=-U -r ETHO201.DUCKDNS.ORG 30 | - IPA_SERVER_IP=192.168.1.54 31 | - PASSWORD=password # at least 8 characters 32 | - VIRTUAL_PROTO=https 33 | - VIRTUAL_HOST=ipa.***REMOVED***.duckdns.org 34 | - VIRTUAL_PORT=443 35 | sysctls: 36 | - net.ipv6.conf.all.disable_ipv6=0 37 | networks: 38 | - backend 39 | cap_add: 40 | - NET_ADMIN 41 | 42 | networks: 43 | backend: 44 | name: backend -------------------------------------------------------------------------------- /dev/freeipa/docker-run.txt: -------------------------------------------------------------------------------- 1 | docker run -d --name freeipa -ti --rm \ 2 | --cap-add NET_ADMIN \ 3 | --sysctl net.ipv6.conf.all.disable_ipv6=0 \ 4 | --tmpfs /run --tmpfs /tmp \ 5 | -v /home/erik/containers/config/freeipa:/data:Z \ 6 | -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ 7 | -h ipa.***REMOVED***.duckdns.org \ 8 | -p 80:80 -p 443:443 -p 389:389 -p 636:636 -p 88:88 -p 464:464 \ 9 | -p 88:88/udp -p 464:464/udp -p 123:123/udp -p 7389:7389 \ 10 | -p 9443:9443 -p 9444:9444 -p 9445:9445 \ 11 | -e PASSWORD=Password1 -e DEBUG_NO_EXIT=1 \ 12 | freeipa/freeipa-server -r ETHO201.DUCKDNS.ORG \ 13 | -U --admin-password=Password1 --ds-password=Password1 -------------------------------------------------------------------------------- /dev/freeipa/install-log: -------------------------------------------------------------------------------- 1 | [1/3]: configuring TLS for DS instance 2 | , [2/3]: adding CA certificate entry 3 | , [3/3]: restarting directory server 4 | ,Done configuring directory server (dirsrv). 5 | ,Configuring ipa-otpd 6 | , [1/2]: starting ipa-otpd 7 | , [2/2]: configuring ipa-otpd to start on boot 8 | ,Done configuring ipa-otpd. 9 | ,Configuring the web interface (httpd) 10 | , [1/21]: stopping httpd 11 | , [2/21]: backing up ssl.conf 12 | , [3/21]: disabling nss.conf 13 | , [4/21]: configuring mod_ssl certificate paths 14 | , [5/21]: setting mod_ssl protocol list to TLSv1.0 - TLSv1.2 15 | , [6/21]: configuring mod_ssl log directory 16 | , [7/21]: disabling mod_ssl OCSP 17 | , [8/21]: adding URL rewriting rules 18 | , [9/21]: configuring httpd 19 | ,Nothing to do for configure_httpd_wsgi_conf 20 | , [10/21]: setting up httpd keytab 21 | , [11/21]: configuring Gssproxy 22 | , [12/21]: setting up ssl 23 | , [13/21]: configure certmonger for renewals 24 | , [14/21]: publish CA cert 25 | , [15/21]: clean up any existing httpd ccaches 26 | , [16/21]: configuring SELinux for httpd 27 | , [17/21]: create KDC proxy config 28 | , [18/21]: enable KDC proxy 29 | , [19/21]: starting httpd 30 | , [20/21]: configuring httpd to start on boot 31 | , [21/21]: enabling oddjobd 32 | ,Done configuring the web interface (httpd). 33 | ,Configuring Kerberos KDC (krb5kdc) 34 | , [1/1]: installing X509 Certificate for PKINIT 35 | ,Done configuring Kerberos KDC (krb5kdc). 36 | ,Applying LDAP updates 37 | ,Upgrading IPA:. Estimated time: 1 minute 30 seconds 38 | , [1/10]: stopping directory server 39 | , [2/10]: saving configuration 40 | , [3/10]: disabling listeners 41 | , [4/10]: enabling DS global lock 42 | , [5/10]: disabling Schema Compat 43 | , [6/10]: starting directory server 44 | , [7/10]: upgrading server 45 | , [8/10]: stopping directory server 46 | , [9/10]: restoring configuration 47 | , [10/10]: starting directory server 48 | ,Done. 49 | ,Restarting the KDC 50 | ,Configuring client side components 51 | ,This program will set up FreeIPA client. 52 | ,Version 4.7.2 53 | , 54 | ,Using existing certificate '/etc/ipa/ca.crt'. 55 | ,Client hostname: ipa.***REMOVED***.duckdns.org 56 | ,Realm: ETHO201.DUCKDNS.ORG 57 | ,DNS Domain: ***REMOVED***.duckdns.org 58 | ,IPA Server: ipa.***REMOVED***.duckdns.org 59 | ,BaseDN: dc=***REMOVED***,dc=duckdns,dc=org 60 | , 61 | ,Configured sudoers in /data/etc/nsswitch.conf 62 | ,Configured /etc/sssd/sssd.conf 63 | ,Systemwide CA database updated. 64 | ,SSSD enabled 65 | ,Configured /etc/openldap/ldap.conf 66 | ,/etc/ssh/ssh_config not found, skipping configuration 67 | ,/etc/ssh/sshd_config not found, skipping configuration 68 | ,Configuring ***REMOVED***.duckdns.org as NIS domain. 69 | ,Client configuration complete. 70 | ,The ipa-client-install command was successful 71 | , 72 | ,Please add records in this file to your DNS system: /tmp/ipa.system.records.f4fw__cx.db 73 | ,============================================================================== 74 | ,Setup complete 75 | , 76 | ,Next steps: 77 | , 1. You must make sure these network ports are open: 78 | , TCP Ports: 79 | , * 80, 443: HTTP/HTTPS 80 | , * 389, 636: LDAP/LDAPS 81 | , * 88, 464: kerberos 82 | , UDP Ports: 83 | , * 88, 464: kerberos 84 | , * 123: ntp 85 | , 86 | , 2. You can now obtain a kerberos ticket using the command: 'kinit admin' 87 | , This ticket will allow you to use the IPA tools (e.g., ipa user-add) 88 | , and the web user interface. 89 | , 3. Kerberos requires time synchronization between clients 90 | , and servers for correct operation. You should consider enabling chronyd. 91 | , 92 | ,Be sure to back up the CA certificates stored in /root/cacert.p12 93 | ,These files are required to create replicas. The password for these 94 | ,files is the Directory Manager password 95 | ,The ipa-server-install command was successful 96 | ,FreeIPA server does not run DNS server, skipping update-self-ip-address. 97 | ,Created symlink /etc/systemd/system/container-ipa.target.wants/ipa-server-update-self-ip-address.service → /usr/lib/systemd/system/ipa-server-update-self-ip-address.service. 98 | ,Created symlink /etc/systemd/system/container-ipa.target.wants/ipa-server-upgrade.service → /usr/lib/systemd/system/ipa-server-upgrade.service. 99 | ,Removed /etc/systemd/system/container-ipa.target.wants/ipa-server-configure-first.service. 100 | ,FreeIPA server configured. 101 | , -------------------------------------------------------------------------------- /dev/freeipa/traefik configuration.txt: -------------------------------------------------------------------------------- 1 | [backends.backend-freeipa] 2 | [backends.backend-freeipa.servers] 3 | [backends.backend-freeipa.servers.server-freeipa-ext] 4 | url = "https://192.168.1.113:443" 5 | weight = 0 6 | 7 | [frontends.frontend-freeipa] 8 | backend = "backend-freeipa" 9 | passHostHeader = true 10 | [frontends.frontend-freeipa.routes] 11 | [frontends.frontend-freeipa.routes.route-freeipa-ext] 12 | rule = "Host:ipa.***REMOVED***.duckdns.org" -------------------------------------------------------------------------------- /dev/gollum/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby 2 | RUN apt-get -y update && apt-get -y install libicu-dev cmake && rm -rf /var/lib/apt/lists/* 3 | RUN gem install github-linguist 4 | RUN gem install gollum 5 | RUN gem install org-ruby # optional 6 | WORKDIR /wiki 7 | ENTRYPOINT ["gollum", "--port", "80"] 8 | EXPOSE 80 -------------------------------------------------------------------------------- /dev/gollum/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | 4 | services: 5 | 6 | wiki: 7 | container_name: gollum 8 | hostname: gollum 9 | build: . 10 | image: etechonomy/gollum 11 | restart: unless-stopped 12 | # ports: 13 | # - 80:80 14 | networks: 15 | - backend 16 | volumes: 17 | - ${VOLUME_DIR}/gollum:/wiki 18 | labels: 19 | - "traefik.enable=true" 20 | - "traefik.backend=gollum" 21 | - "traefik.frontend.rule=Host:gollum.${FQDN}" 22 | - "traefik.port=80" 23 | - "traefik.docker.network=backend" 24 | - "traefik.frontend.headers.SSLRedirect=true" 25 | - "traefik.frontend.headers.STSSeconds=315360000" 26 | - "traefik.frontend.headers.browserXSSFilter=true" 27 | - "traefik.frontend.headers.contentTypeNosniff=true" 28 | - "traefik.frontend.headers.forceSTSHeader=true" 29 | - "traefik.frontend.headers.SSLHost=example.com" 30 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 31 | - "traefik.frontend.headers.STSPreload=true" 32 | - "traefik.frontend.headers.frameDeny=true" 33 | 34 | networks: 35 | backend: 36 | external: 37 | name: backend 38 | #run: docker network create --name=backend -------------------------------------------------------------------------------- /dev/guacamole/docker-compose-arm.yml: -------------------------------------------------------------------------------- 1 | ######################################################################################## 2 | # Apache Guacamole 3 | # https://guacamole.apache.org/ 4 | # https://hub.docker.com/r/guacamole/guacamole 5 | # https://hub.docker.com/r/guacamole/guacd/ 6 | # https://github.com/apache/guacamole-server 7 | # https://github.com/boschkundendienst/guacamole-docker-compose 8 | # 9 | # https://hub.docker.com/r/linuxserver/guacd 10 | # https://hub.docker.com/r/linuxserver/taisun 11 | ######################################################################################## 12 | --- 13 | version: '3.7' 14 | 15 | services: 16 | 17 | #postgres: 18 | #image: postgres 19 | #container_name: postgresql 20 | #hostname: postgres 21 | #restart: unless-stopped 22 | #volumes: 23 | #- guacamole_db:/var/lib/postgresql/data 24 | #- ./initdb.sql:/docker-entrypoint-initdb.d/initdb.sql:ro 25 | #environment: 26 | #- POSTGRES_DB=guacamole_db 27 | #- POSTGRES_USER=${POSTGRES_USER} 28 | #- POSTGRES_PASSWORD=${POSTGRES_PASSWORD} 29 | #networks: 30 | #- backend 31 | #ports: 32 | #- 5432:5432 33 | 34 | guacd: 35 | image: linuxserver/guacd 36 | container_name: guacd 37 | hostname: guacd 38 | restart: unless-stopped 39 | networks: 40 | - backend 41 | #volumes: 42 | #- guacamole_drive:/drive:rw 43 | #- guacamole_record:/record:rw 44 | #ports: 45 | #- 4822:4822 46 | 47 | guacamole: 48 | image: oznu/guacamole:armhf 49 | container_name: guacamole 50 | depends_on: 51 | - guacd 52 | - postgres 53 | restart: unless-stopped 54 | volumes: 55 | - db1:/var/lib/postgresql/data 56 | environment: 57 | - POSTGRES_HOSTNAME=db1 58 | - GUACD_HOSTNAME=guacd 59 | - POSTGRES_DATABASE=guacamole_db 60 | - POSTGRES_USER=${POSTGRES_USER} 61 | - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} 62 | networks: 63 | - backend 64 | #ports: 65 | #- 8080:8080 66 | #- 8443:443 67 | labels: 68 | - "traefik.enable=true" 69 | - "traefik.backend=guacamole" 70 | - "traefik.frontend.rule=Host:guacamole.${FQDN}" 71 | - "traefik.port=443" # See "On containers with Multiple Ports (segment labels)" --> https://docs.traefik.io/configuration/backends/docker/ 72 | - "traefik.docker.network=backend" 73 | - "traefik.frontend.headers.SSLRedirect=true" 74 | - "traefik.frontend.headers.STSSeconds=315360000" 75 | - "traefik.frontend.headers.browserXSSFilter=true" 76 | - "traefik.frontend.headers.contentTypeNosniff=true" 77 | - "traefik.frontend.headers.forceSTSHeader=true" 78 | - "traefik.frontend.headers.SSLHost=example.com" 79 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 80 | - "traefik.frontend.headers.STSPreload=true" 81 | - "traefik.frontend.headers.frameDeny=true" 82 | 83 | taisun: 84 | image: linuxserver/taisun 85 | container_name: taisun 86 | volumes: 87 | - /var/run/docker.sock:/var/run/docker.sock 88 | networks: 89 | - backend 90 | #ports: 91 | #- 3000:3000 92 | restart: unless-stopped 93 | labels: 94 | - "traefik.enable=true" 95 | - "traefik.backend=taisun" 96 | - "traefik.frontend.rule=Host:taisun.${FQDN}" 97 | - "traefik.port=3000" 98 | - "traefik.docker.network=backend" 99 | - "traefik.frontend.headers.SSLRedirect=true" 100 | - "traefik.frontend.headers.STSSeconds=315360000" 101 | - "traefik.frontend.headers.browserXSSFilter=true" 102 | - "traefik.frontend.headers.contentTypeNosniff=true" 103 | - "traefik.frontend.headers.forceSTSHeader=true" 104 | - "traefik.frontend.headers.SSLHost=example.com" 105 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 106 | - "traefik.frontend.headers.STSPreload=true" 107 | - "traefik.frontend.headers.frameDeny=true" 108 | 109 | volumes: 110 | db1: 111 | external: true 112 | name: db1 113 | #run: docker volume create --name=db1 114 | 115 | #volumes: 116 | #guacamole_db: 117 | #name: guacamole_db 118 | #driver: local 119 | #guacamole_drive: 120 | #name: guacamole_drive 121 | #driver: local 122 | #guacamole_record: 123 | #name: guacamole_record 124 | #driver: local 125 | 126 | networks: 127 | #frontend: 128 | #name: frontend 129 | backend: 130 | name: backend 131 | -------------------------------------------------------------------------------- /dev/guacamole/docker-compose-x64.yml: -------------------------------------------------------------------------------- 1 | ######################################################################################## 2 | # Apache Guacamole 3 | # https://guacamole.apache.org/ 4 | # https://hub.docker.com/r/guacamole/guacamole 5 | # https://hub.docker.com/r/guacamole/guacd/ 6 | # https://github.com/apache/guacamole-server 7 | # https://github.com/boschkundendienst/guacamole-docker-compose 8 | # 9 | # https://hub.docker.com/r/linuxserver/guacd 10 | ######################################################################################## 11 | --- 12 | version: '3.7' 13 | 14 | services: 15 | 16 | guacamole-db: 17 | image: postgres 18 | container_name: guacamole-db 19 | hostname: postgres 20 | restart: unless-stopped 21 | volumes: 22 | - guacamole_db:/var/lib/postgresql/data 23 | - ./initdb.sql:/docker-entrypoint-initdb.d/initdb.sql:ro 24 | environment: 25 | - POSTGRES_DB=guacamole 26 | - POSTGRES_USER=guacamole 27 | - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} 28 | networks: 29 | - backend 30 | #ports: 31 | #- 5432:5432 32 | 33 | guacd: 34 | image: guacamole/guacd 35 | container_name: guacd 36 | hostname: guacd 37 | restart: unless-stopped 38 | networks: 39 | - backend 40 | volumes: 41 | - guacamole_drive:/drive:rw 42 | - guacamole_record:/record:rw 43 | #ports: 44 | #- 4822:4822 45 | 46 | guacamole: 47 | image: guacamole/guacamole 48 | container_name: guacamole 49 | depends_on: 50 | - guacd 51 | - guacamole-db 52 | restart: unless-stopped 53 | volumes: 54 | - guacamole_db:/var/lib/postgresql/data 55 | environment: 56 | - POSTGRES_HOSTNAME=guacamole-db 57 | - GUACD_HOSTNAME=guacd 58 | - POSTGRES_DATABASE=guacamole 59 | - POSTGRES_USER=guacamole 60 | - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} 61 | networks: 62 | - backend 63 | - frontend 64 | ports: 65 | - 8080:8080 # http://localhost:8080/guacamole/ 66 | - 8443:443 67 | 68 | volumes: 69 | guacamole_db: 70 | name: guacamole_db 71 | driver: local 72 | guacamole_drive: 73 | name: guacamole_drive 74 | driver: local 75 | guacamole_record: 76 | name: guacamole_record 77 | driver: local 78 | 79 | networks: 80 | frontend: 81 | name: frontend 82 | backend: 83 | name: backend -------------------------------------------------------------------------------- /dev/hysteria2/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3.9" 3 | services: 4 | hysteria: 5 | image: tobyxdd/hysteria:latest 6 | container_name: hysteria 7 | restart: always 8 | network_mode: "host" 9 | volumes: 10 | - ${CONFIG_DIR}/hysteria2/hysteria.yaml:/etc/hysteria.yaml 11 | - ${CONFIG_DIR}/traefik2/acme/dump:/certs 12 | command: ["server", "-c", "/etc/hysteria.yaml"] 13 | 14 | traefik-certs-dumper: 15 | image: ldez/traefik-certs-dumper:latest 16 | container_name: cert-dumper 17 | networks: 18 | - traefik 19 | entrypoint: sh -c ' 20 | traefik-certs-dumper file --domain-subdir --version v2 --watch 21 | --source /data/acme.json --dest /data/dump' 22 | volumes: 23 | - ${CONFIG_DIR}/traefik2/acme:/data 24 | 25 | networks: 26 | traefik: 27 | name: traefik 28 | external: true 29 | #run: docker network create traefik 30 | -------------------------------------------------------------------------------- /dev/immich/compose.yml: -------------------------------------------------------------------------------- 1 | name: immich 2 | 3 | services: 4 | immich-server: 5 | container_name: immich-server 6 | image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} 7 | # extends: 8 | # file: hwaccel.transcoding.yml 9 | # service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding 10 | environment: 11 | DB_PASSWORD: ${IMMICH_DB_PASSWORD} 12 | DB_USERNAME: postgres 13 | DB_DATABASE_NAME: immich 14 | volumes: 15 | - ${VOLUME_DIR}/immich/library:/usr/src/app/upload 16 | - /etc/localtime:/etc/localtime:ro 17 | # ports: 18 | # - 2283:2283 19 | networks: 20 | - traefik 21 | depends_on: 22 | - redis 23 | - database 24 | restart: always 25 | healthcheck: 26 | disable: false 27 | labels: 28 | # - autoheal=true 29 | - traefik.enable=true 30 | ## HTTP Routers 31 | - traefik.http.routers.immich-rtr.entrypoints=websecure 32 | - traefik.http.routers.immich-rtr.rule=Host(`immich.$FQDN`) 33 | - traefik.http.routers.immich-rtr.tls=true 34 | ## Middlewares 35 | - traefik.http.routers.immich-rtr.middlewares=chain-no-auth@file # No Authentication 36 | # - traefik.http.routers.immich-rtr.middlewares=chain-basic-auth@file # Basic Authentication 37 | # - traefik.http.routers.immich-rtr.middlewares=chain-oauth2-proxy@file # OAuth 2.0 38 | ## HTTP Services 39 | - traefik.http.routers.immich-rtr.service=immich-svc 40 | - traefik.http.services.immich-svc.loadbalancer.server.port=2283 41 | 42 | immich-machine-learning: 43 | container_name: immich-machine-learning 44 | # For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag. 45 | # Example tag: ${IMMICH_VERSION:-release}-cuda 46 | image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} 47 | # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration 48 | # file: hwaccel.ml.yml 49 | # service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable 50 | volumes: 51 | - model-cache:/cache 52 | networks: 53 | - traefik 54 | restart: always 55 | healthcheck: 56 | disable: false 57 | 58 | redis: 59 | container_name: immich-redis 60 | image: docker.io/valkey/valkey:8-bookworm@sha256:ff21bc0f8194dc9c105b769aeabf9585fea6a8ed649c0781caeac5cb3c247884 61 | networks: 62 | - traefik 63 | healthcheck: 64 | test: redis-cli ping || exit 1 65 | restart: always 66 | 67 | database: 68 | container_name: immich-db 69 | image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0@sha256:fa4f6e0971f454cd95fec5a9aaed2ed93d8f46725cc6bc61e0698e97dba96da1 70 | environment: 71 | POSTGRES_PASSWORD: ${IMMICH_DB_PASSWORD} 72 | POSTGRES_USER: postgres 73 | POSTGRES_DB: immich 74 | POSTGRES_INITDB_ARGS: '--data-checksums' 75 | # Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs 76 | DB_STORAGE_TYPE: 'HDD' 77 | networks: 78 | - traefik 79 | volumes: 80 | - ${VOLUME_DIR}/immich/db:/var/lib/postgresql/data 81 | restart: always 82 | 83 | volumes: 84 | model-cache: 85 | 86 | networks: 87 | traefik: 88 | name: traefik 89 | external: true 90 | #run: docker network create traefik -------------------------------------------------------------------------------- /dev/indexers/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "2" 3 | services: 4 | 5 | sonarr: 6 | image: linuxserver/sonarr 7 | container_name: sonarr 8 | environment: 9 | - PUID=1000 10 | - PGID=1000 11 | - TZ=America/Los_Angeles 12 | volumes: 13 | - /home/pi/containers/config/sonarr:/config 14 | - /mnt/hdd/Media/TV:/tv 15 | - /mnt/hdd/Downloads:/downloads 16 | - "/etc/localtime:/etc/localtime:ro" 17 | # ports: 18 | # - "XXXX:8989" 19 | restart: unless-stopped 20 | networks: 21 | - traefik_proxy 22 | labels: 23 | - "traefik.enable=true" 24 | - "traefik.backend=sonarr" 25 | - "traefik.frontend.rule=Host:***REMOVED***.duckdns.org; PathPrefix: /sonarr" 26 | # - "traefik.frontend.rule=Host:sonarr.${DOMAINNAME}" 27 | - "traefik.port=8989" 28 | - "traefik.docker.network=traefik_proxy" 29 | - "traefik.frontend.headers.SSLRedirect=true" 30 | - "traefik.frontend.headers.STSSeconds=315360000" 31 | - "traefik.frontend.headers.browserXSSFilter=true" 32 | - "traefik.frontend.headers.contentTypeNosniff=true" 33 | - "traefik.frontend.headers.forceSTSHeader=true" 34 | - "traefik.frontend.headers.SSLHost=example.com" 35 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 36 | - "traefik.frontend.headers.STSPreload=true" 37 | - "traefik.frontend.headers.frameDeny=true" 38 | 39 | radarr: 40 | image: "linuxserver/radarr" 41 | container_name: "radarr" 42 | environment: 43 | - PUID=1000 44 | - PGID=1000 45 | - TZ=America/Los_Angeles 46 | volumes: 47 | - /home/pi/containers/config/radarr:/config 48 | - /mnt/hdd/Downloads:/downloads 49 | - /mnt/hdd/Media/Movies:/movies 50 | - "/etc/localtime:/etc/localtime:ro" 51 | # ports: 52 | # - "XXXX:7878" 53 | restart: unless-stopped 54 | networks: 55 | - traefik_proxy 56 | labels: 57 | - "traefik.enable=true" 58 | - "traefik.backend=radarr" 59 | - "traefik.frontend.rule=Host:***REMOVED***.duckdns.org; PathPrefix: /radarr" 60 | # - "traefik.frontend.rule=Host:radarr.${DOMAINNAME}" 61 | - "traefik.port=7878" 62 | - "traefik.docker.network=traefik_proxy" 63 | - "traefik.frontend.headers.SSLRedirect=true" 64 | - "traefik.frontend.headers.STSSeconds=315360000" 65 | - "traefik.frontend.headers.browserXSSFilter=true" 66 | - "traefik.frontend.headers.contentTypeNosniff=true" 67 | - "traefik.frontend.headers.forceSTSHeader=true" 68 | - "traefik.frontend.headers.SSLHost=example.com" 69 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 70 | - "traefik.frontend.headers.STSPreload=true" 71 | - "traefik.frontend.headers.frameDeny=true" 72 | 73 | jackett: 74 | image: linuxserver/jackett 75 | container_name: jackett 76 | environment: 77 | - PUID=1000 78 | - PGID=1000 79 | - TZ=America/Los_Angeles 80 | volumes: 81 | - /home/pi/containers/config/jackett:/config 82 | - /mnt/hdd/Jackett:/downloads 83 | - "/etc/localtime:/etc/localtime:ro" 84 | # ports: 85 | # - "XXXX:9117" 86 | restart: unless-stopped 87 | networks: 88 | - traefik_proxy 89 | labels: 90 | - "traefik.enable=true" 91 | - "traefik.backend=jackett" 92 | # - "traefik.frontend.rule=Host:jackett.${DOMAINNAME}" 93 | - "traefik.frontend.rule=Host:***REMOVED***.duckdns.org; PathPrefix: /jackett" 94 | - "traefik.port=9117" 95 | - "traefik.docker.network=traefik_proxy" 96 | - "traefik.frontend.headers.SSLRedirect=true" 97 | - "traefik.frontend.headers.STSSeconds=315360000" 98 | - "traefik.frontend.headers.browserXSSFilter=true" 99 | - "traefik.frontend.headers.contentTypeNosniff=true" 100 | - "traefik.frontend.headers.forceSTSHeader=true" 101 | - "traefik.frontend.headers.SSLHost=example.com" 102 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 103 | - "traefik.frontend.headers.STSPreload=true" 104 | - "traefik.frontend.headers.frameDeny=true" 105 | 106 | networks: 107 | traefik_proxy: 108 | external: 109 | name: traefik_proxy 110 | default: 111 | driver: bridge -------------------------------------------------------------------------------- /dev/invoiceninja/README.md: -------------------------------------------------------------------------------- 1 | # Deploy 2 | 3 | 1. Prepare the folder structure and permissions before running `docker compose up`. Run the following as the root user: 4 | 5 | ```bash 6 | DOCKER_VOLUME=/data/docker/volume 7 | mkdir -p ${DOCKER_VOLUME}/invoiceninja/{storage,public} 8 | chown -R 1500:1500 ${DOCKER_VOLUME}/invoiceninja/{storage,public} 9 | ``` 10 | 11 | 2. Run `docker compose up` 12 | 13 | ```bash 14 | docker compose up -d 15 | ``` -------------------------------------------------------------------------------- /dev/invoiceninja/compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: invoiceninja 3 | 4 | x-logging: &default-logging 5 | options: 6 | max-size: "10m" 7 | max-file: "3" 8 | driver: json-file 9 | 10 | services: 11 | invoiceninja: 12 | image: invoiceninja/invoiceninja-debian:latest 13 | container_name: invoiceninja 14 | restart: unless-stopped 15 | environment: 16 | # IN application vars 17 | APP_URL: http://in.${FQDN} 18 | APP_KEY: ${IN_APP_KEY} 19 | APP_ENV: production 20 | APP_DEBUG: false 21 | REQUIRE_HTTPS: true 22 | PHANTOMJS_PDF_GENERATION: false 23 | PDF_GENERATOR: snappdf 24 | TRUSTED_PROXIES: '*' 25 | 26 | CACHE_DRIVER: redis 27 | QUEUE_CONNECTION: redis 28 | SESSION_DRIVER: redis 29 | 30 | REDIS_HOST: invoiceninja-redis.traefik 31 | REDIS_PASSWORD: null 32 | REDIS_PORT: 6379 33 | 34 | FILESYSTEM_DISK: debian_docker 35 | 36 | # DB connection 37 | DB_HOST: invoiceninja-db.traefik 38 | DB_PORT: 3306 39 | DB_DATABASE: ninja 40 | DB_USERNAME: ninja 41 | DB_PASSWORD: ${IN_DB_PASSWORD} 42 | DB_ROOT_PASSWORD: ${IN_DB_ROOT_PASSWORD} 43 | DB_CONNECTION: mysql 44 | 45 | # Create initial user 46 | IN_USER_EMAIL: ${EMAIL} 47 | IN_PASSWORD: ${IN_PASSWORD} 48 | 49 | # Mail options 50 | MAIL_MAILER: log 51 | MAIL_HOST: ${SMTP_SERVER} 52 | MAIL_PORT: 587 53 | MAIL_USERNAME: ${EMAIL_FROM} 54 | MAIL_PASSWORD: ${IN_EMAIL_APP_PASSWORD} 55 | MAIL_ENCRYPTION: STARTTLS 56 | MAIL_FROM_ADDRESS: ${EMAIL_FROM} 57 | MAIL_FROM_NAME: ${EMAIL_FROM_NAME} 58 | 59 | IS_DOCKER: true 60 | SCOUT_DRIVER: null 61 | #SNAPPDF_CHROMIUM_PATH: /usr/bin/google-chrome-stable 62 | volumes: 63 | - type: bind 64 | source: ./config/php/php.ini 65 | target: /usr/local/etc/php/conf.d/invoiceninja.ini 66 | read_only: true 67 | bind: 68 | create_host_path: false 69 | - type: bind 70 | source: ./config/php/php-fpm.conf 71 | target: /usr/local/etc/php-fpm.d/invoiceninja.conf 72 | read_only: true 73 | bind: 74 | create_host_path: false 75 | - type: bind 76 | source: ./config/supervisor/supervisord.conf 77 | target: /etc/supervisor/conf.d/supervisord.conf 78 | read_only: true 79 | bind: 80 | create_host_path: false 81 | - ${VOLUME_DIR}/invoiceninja/public:/var/www/html/public 82 | - ${VOLUME_DIR}/invoiceninja/storage:/var/www/html/storage 83 | networks: 84 | - traefik 85 | depends_on: 86 | invoiceninja-db: 87 | condition: service_healthy 88 | invoiceninja-redis: 89 | condition: service_healthy 90 | logging: *default-logging 91 | 92 | invoiceninja-nginx: 93 | image: nginx:alpine 94 | container_name: invoiceninja-nginx 95 | restart: unless-stopped 96 | # ports: 97 | # - 80:80 98 | volumes: 99 | - source: ./config/nginx/invoiceninja.conf 100 | target: /etc/nginx/conf.d/nginx.conf 101 | type: bind 102 | read_only: true 103 | bind: 104 | create_host_path: false 105 | - source: ./config/nginx/laravel.conf 106 | target: /etc/nginx/conf.d/laravel.conf 107 | type: bind 108 | read_only: true 109 | bind: 110 | create_host_path: false 111 | - ${VOLUME_DIR}/invoiceninja/public:/var/www/html/public:ro 112 | - ${VOLUME_DIR}/invoiceninja/storage:/var/www/html/storage:ro 113 | networks: 114 | - traefik 115 | depends_on: 116 | - invoiceninja 117 | logging: *default-logging 118 | healthcheck: 119 | test: curl --fail http://invoiceninja-nginx/public/images/blank.png || exit 1 120 | interval: 30s 121 | retries: 3 122 | start_period: 10s 123 | timeout: 10s 124 | labels: 125 | - autoheal=true 126 | - traefik.enable=true 127 | ## HTTP Routers 128 | - traefik.http.routers.in-rtr.entrypoints=websecure 129 | - traefik.http.routers.in-rtr.rule=Host(`in.$FQDN`) 130 | - traefik.http.routers.in-rtr.tls=true 131 | ## Middlewares 132 | - traefik.http.routers.in-rtr.middlewares=chain-no-auth@file # No Authentication 133 | # - traefik.http.routers.in-rtr.middlewares=chain-basic-auth@file # Basic Authentication 134 | # - traefik.http.routers.in-rtr.middlewares=chain-oauth2-proxy@file # OAuth 2.0 135 | ## HTTP Services 136 | - traefik.http.routers.in-rtr.service=in-svc 137 | - traefik.http.services.in-svc.loadbalancer.server.port=80 138 | 139 | invoiceninja-db: 140 | image: container-registry.oracle.com/mysql/community-server:8.4-aarch64 141 | container_name: invoiceninja-db 142 | restart: unless-stopped 143 | environment: 144 | - MYSQL_ROOT_PASSWORD=${IN_DB_ROOT_PASSWORD} 145 | - MYSQL_USER=ninja 146 | - MYSQL_PASSWORD=${IN_DB_PASSWORD} 147 | - MYSQL_DATABASE=ninja 148 | - MYSQL_ROOT_HOST=invoiceninja.traefik 149 | volumes: 150 | - ${VOLUME_DIR}/invoiceninja/db:/var/lib/mysql 151 | networks: 152 | - traefik 153 | healthcheck: 154 | test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD 155 | start_period: 5s 156 | interval: 5s 157 | timeout: 5s 158 | retries: 55 159 | logging: *default-logging 160 | 161 | invoiceninja-redis: 162 | image: redis:alpine 163 | container_name: invoiceninja-redis 164 | restart: unless-stopped 165 | volumes: 166 | - ${VOLUME_DIR}/invoiceninja/redis:/data 167 | networks: 168 | - traefik 169 | healthcheck: 170 | test: [ "CMD", "redis-cli", "ping" ] 171 | interval: 10s 172 | timeout: 5s 173 | retries: 5 174 | logging: *default-logging 175 | 176 | networks: 177 | traefik: 178 | name: traefik 179 | external: true 180 | #run: docker network create traefik 181 | -------------------------------------------------------------------------------- /dev/invoiceninja/config/nginx/invoiceninja.conf: -------------------------------------------------------------------------------- 1 | # https://nginx.org/en/docs/http/ngx_http_core_module.html 2 | client_max_body_size 10M; 3 | client_body_buffer_size 10M; 4 | server_tokens off; 5 | 6 | # https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html 7 | fastcgi_buffers 32 16K; 8 | 9 | # https://nginx.org/en/docs/http/ngx_http_gzip_module.html 10 | gzip on; 11 | gzip_comp_level 2; 12 | gzip_min_length 1M; 13 | gzip_proxied any; 14 | gzip_types *; 15 | -------------------------------------------------------------------------------- /dev/invoiceninja/config/nginx/laravel.conf: -------------------------------------------------------------------------------- 1 | # https://laravel.com/docs/master/deployment#nginx 2 | server { 3 | listen 80 default_server; 4 | server_name _; 5 | root /var/www/html/public; 6 | 7 | add_header X-Frame-Options "SAMEORIGIN"; 8 | add_header X-Content-Type-Options "nosniff"; 9 | 10 | index index.php; 11 | 12 | charset utf-8; 13 | 14 | location / { 15 | try_files $uri $uri/ /index.php?$query_string; 16 | } 17 | 18 | location = /favicon.ico { access_log off; log_not_found off; } 19 | location = /robots.txt { access_log off; log_not_found off; } 20 | 21 | error_page 404 /index.php; 22 | 23 | location ~ \.php$ { 24 | fastcgi_pass invoiceninja:9000; 25 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; 26 | include fastcgi_params; 27 | } 28 | 29 | location ~ /\.(?!well-known).* { 30 | deny all; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dev/invoiceninja/config/php/php-fpm.conf: -------------------------------------------------------------------------------- 1 | pm.max_children = 10 2 | -------------------------------------------------------------------------------- /dev/invoiceninja/config/php/php.ini: -------------------------------------------------------------------------------- 1 | [core] 2 | ; https://www.php.net/manual/en/ini.core.php 3 | post_max_size=10M 4 | upload_max_filesize=10M 5 | 6 | [opcache] 7 | ; https://www.php.net/manual/en/opcache.installation.php#opcache.installation.recommended 8 | opcache.enable_cli=1 9 | 10 | [jit] 11 | ; https://wiki.php.net/rfc/jit_config_defaults 12 | opcache.jit=tracing 13 | opcache.jit_buffer_size=64M 14 | 15 | [extra] 16 | ; http://symfony.com/doc/current/performance.html 17 | opcache.memory_consumption=256 18 | opcache.max_accelerated_files=20000 19 | opcache.preload=/var/www/html/preload.php 20 | opcache.preload_user=www-data 21 | opcache.validate_timestamps=0 22 | realpath_cache_size = 4096K 23 | realpath_cache_ttl = 600 24 | -------------------------------------------------------------------------------- /dev/invoiceninja/config/supervisor/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | user=root 4 | logfile=/dev/null 5 | logfile_maxbytes=0 6 | pidfile=/var/run/supervisord.pid 7 | 8 | [rpcinterface:supervisor] 9 | supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface 10 | 11 | [program:php-fpm] 12 | command=/usr/local/sbin/php-fpm -F 13 | autostart=true 14 | autorestart=true 15 | priority=5 16 | stdout_logfile=/dev/fd/1 17 | stdout_logfile_maxbytes=0 18 | redirect_stderr=true 19 | 20 | [program:queue-worker] 21 | process_name=%(program_name)s_%(process_num)02d 22 | command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --max-time=3600 --verbose 23 | autostart=true 24 | autorestart=true 25 | stopasgroup=true 26 | killasgroup=true 27 | user=www-data 28 | numprocs=2 29 | environment=HOME="/var/www" 30 | stdout_logfile=/dev/fd/1 31 | stdout_logfile_maxbytes=0 32 | redirect_stderr=true 33 | stopwaitsecs=3600 34 | 35 | [program:scheduler] 36 | command=php /var/www/html/artisan schedule:work --verbose 37 | autostart=true 38 | autorestart=true 39 | user=www-data 40 | stdout_logfile=/dev/fd/1 41 | stdout_logfile_maxbytes=0 42 | redirect_stderr=true 43 | -------------------------------------------------------------------------------- /dev/keycloak/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.8' 3 | services: 4 | 5 | keycloak: 6 | image: quay.io/keycloak/keycloak 7 | container_name: keycloak 8 | environment: 9 | - KEYCLOAK_ADMIN=admin 10 | - KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD} 11 | - KC_HOSTNAME=keycloak.${FQDN} 12 | # - KC_HOSTNAME_URL=https://keycloak.${FQDN} 13 | - KC_HOSTNAME_STRICT=false 14 | - KC_PROXY=edge 15 | - KC_HTTP_ENABLED=true 16 | - KC_DB=postgres 17 | - KC_DB_URL=jdbc:postgresql://keycloak-db:5432/keycloak 18 | - KC_DB_PASSWORD=${KC_DB_PASSWORD} 19 | - KC_DB_USERNAME=keycloak 20 | # - KC_HEALTH_ENABLED=true 21 | # - KC_METRICS_ENABLED=true 22 | command: 23 | - start 24 | volumes: 25 | - ${CONFIG_DIR}/keycloak:/config 26 | ports: 27 | - 8081:8080 28 | restart: unless-stopped 29 | networks: 30 | - traefik 31 | labels: 32 | # https://www.keycloak.org/server/reverseproxy 33 | - "traefik.enable=true" 34 | ## HTTP Routers 35 | - "traefik.http.routers.keycloak-rtr.entrypoints=websecure" 36 | - "traefik.http.routers.keycloak-rtr.rule=Host(`keycloak.$FQDN`)" 37 | - "traefik.http.routers.keycloak-rtr.tls=true" 38 | ## Middlewares 39 | - "traefik.http.routers.keycloak-rtr.middlewares=chain-no-auth@file" # No Authentication 40 | # - "traefik.http.routers.keycloak-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 41 | # - "traefik.http.routers.keycloak-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 42 | ## HTTP Services 43 | - "traefik.http.routers.keycloak-rtr.service=keycloak-svc" 44 | - "traefik.http.services.keycloak-svc.loadbalancer.server.port=8080" 45 | 46 | keycloak-db: 47 | image: postgres:13 # check POM for postgres version: https://github.com/keycloak/keycloak/blob/main/pom.xml 48 | container_name: keycloak-db 49 | environment: 50 | - POSTGRES_PASSWORD=${KC_DB_PASSWORD} 51 | - POSTGRES_USER=keycloak 52 | - POSTGRES_DB=keycloak 53 | # ports: 54 | # - 5432:5432 55 | volumes: 56 | - ${VOLUME_DIR}/keycloak:/var/lib/postgresql/data 57 | restart: unless-stopped 58 | networks: 59 | - traefik 60 | 61 | networks: 62 | traefik: 63 | name: traefik 64 | external: true 65 | #run: docker network create traefik 66 | -------------------------------------------------------------------------------- /dev/komodo/compose.env: -------------------------------------------------------------------------------- 1 | #################################### 2 | # 🦎 KOMODO COMPOSE - VARIABLES 🦎 # 3 | #################################### 4 | 5 | ## These compose variables can be used with all Komodo deployment options. 6 | ## Pass these variables to the compose up command using `--env-file komodo/compose.env`. 7 | ## Additionally, they are passed to both Komodo Core and Komodo Periphery with `env_file: ./compose.env`, 8 | ## so you can pass any additional environment variables to Core / Periphery directly in this file as well. 9 | 10 | ## Stick to a specific version, or use `latest` 11 | COMPOSE_KOMODO_IMAGE_TAG=latest 12 | 13 | ## Note: 🚨 Podman does NOT support local logging driver 🚨. See Podman options here: 14 | ## `https://docs.podman.io/en/v4.6.1/markdown/podman-run.1.html#log-driver-driver` 15 | COMPOSE_LOGGING_DRIVER=local # Enable log rotation with the local driver. 16 | 17 | ## DB credentials - Ignored for Sqlite 18 | # KOMODO_DB_USERNAME=admin 19 | # KOMODO_DB_PASSWORD=admin 20 | 21 | ## Configure a secure passkey to authenticate between Core / Periphery. 22 | # KOMODO_PASSKEY=a_random_passkey 23 | 24 | #=-------------------------=# 25 | #= Komodo Core Environment =# 26 | #=-------------------------=# 27 | 28 | ## Full variable list + descriptions are available here: 29 | ## 🦎 https://github.com/mbecker20/komodo/blob/main/config/core.config.toml 🦎 30 | 31 | ## Note. Secret variables also support `${VARIABLE}_FILE` syntax to pass docker compose secrets. 32 | ## Docs: https://docs.docker.com/compose/how-tos/use-secrets/#examples 33 | 34 | ## Used for Oauth / Webhook url suggestion / Caddy reverse proxy. 35 | # KOMODO_HOST=https://demo.komo.do 36 | ## Displayed in the browser tab. 37 | KOMODO_TITLE=Komodo 38 | ## Create a server matching this address as the "first server". 39 | ## Use `https://host.docker.internal:8120` when using systemd-managed Periphery. 40 | KOMODO_FIRST_SERVER=https://komodo-periphery:8120 41 | ## Make all buttons just double-click, rather than the full confirmation dialog. 42 | KOMODO_DISABLE_CONFIRM_DIALOG=false 43 | 44 | ## Rate Komodo polls your servers for 45 | ## status / container status / system stats / alerting. 46 | ## Options: 1-sec, 5-sec, 15-sec, 1-min, 5-min. 47 | ## Default: 15-sec 48 | KOMODO_MONITORING_INTERVAL="15-sec" 49 | ## Rate Komodo polls Resources for updates, 50 | ## like outdated commit hash. 51 | ## Options: 1-min, 5-min, 15-min, 30-min, 1-hr. 52 | ## Default: 5-min 53 | KOMODO_RESOURCE_POLL_INTERVAL="5-min" 54 | 55 | ## Used to auth incoming webhooks. Alt: KOMODO_WEBHOOK_SECRET_FILE 56 | # KOMODO_WEBHOOK_SECRET=a_random_secret 57 | ## Used to generate jwt. Alt: KOMODO_JWT_SECRET_FILE 58 | # KOMODO_JWT_SECRET=a_random_jwt_secret 59 | 60 | ## Enable login with username + password. 61 | KOMODO_LOCAL_AUTH=true 62 | ## Disable new user signups. 63 | KOMODO_DISABLE_USER_REGISTRATION=true 64 | ## All new logins are auto enabled 65 | KOMODO_ENABLE_NEW_USERS=false 66 | ## Disable non-admins from creating new resources. 67 | KOMODO_DISABLE_NON_ADMIN_CREATE=false 68 | ## Allows all users to have Read level access to all resources. 69 | KOMODO_TRANSPARENT_MODE=false 70 | 71 | ## Time to live for jwt tokens. 72 | ## Options: 1-hr, 12-hr, 1-day, 3-day, 1-wk, 2-wk 73 | KOMODO_JWT_TTL="1-day" 74 | 75 | ## OIDC Login 76 | KOMODO_OIDC_ENABLED=false 77 | ## Must reachable from Komodo Core container 78 | # KOMODO_OIDC_PROVIDER=https://oidc.provider.internal/application/o/komodo 79 | ## Change the host to one reachable be reachable by users (optional if it is the same as above). 80 | ## DO NOT include the `path` part of the URL. 81 | # KOMODO_OIDC_REDIRECT_HOST=https://oidc.provider.external 82 | ## Your client credentials 83 | # KOMODO_OIDC_CLIENT_ID= # Alt: KOMODO_OIDC_CLIENT_ID_FILE 84 | # KOMODO_OIDC_CLIENT_SECRET= # Alt: KOMODO_OIDC_CLIENT_SECRET_FILE 85 | ## Make usernames the full email. 86 | # KOMODO_OIDC_USE_FULL_EMAIL=true 87 | ## Add additional trusted audiences for token claims verification. 88 | ## Supports comma separated list, and passing with _FILE (for compose secrets). 89 | # KOMODO_OIDC_ADDITIONAL_AUDIENCES=abc,123 # Alt: KOMODO_OIDC_ADDITIONAL_AUDIENCES_FILE 90 | 91 | ## Github Oauth 92 | KOMODO_GITHUB_OAUTH_ENABLED=false 93 | # KOMODO_GITHUB_OAUTH_ID= # Alt: KOMODO_GITHUB_OAUTH_ID_FILE 94 | # KOMODO_GITHUB_OAUTH_SECRET= # Alt: KOMODO_GITHUB_OAUTH_SECRET_FILE 95 | 96 | ## Google Oauth 97 | KOMODO_GOOGLE_OAUTH_ENABLED=false 98 | # KOMODO_GOOGLE_OAUTH_ID= # Alt: KOMODO_GOOGLE_OAUTH_ID_FILE 99 | # KOMODO_GOOGLE_OAUTH_SECRET= # Alt: KOMODO_GOOGLE_OAUTH_SECRET_FILE 100 | 101 | ## Aws - Used to launch Builder instances and ServerTemplate instances. 102 | KOMODO_AWS_ACCESS_KEY_ID= # Alt: KOMODO_AWS_ACCESS_KEY_ID_FILE 103 | KOMODO_AWS_SECRET_ACCESS_KEY= # Alt: KOMODO_AWS_SECRET_ACCESS_KEY_FILE 104 | 105 | ## Hetzner - Used to launch ServerTemplate instances 106 | ## Hetzner Builder not supported due to Hetzner pay-by-the-hour pricing model 107 | KOMODO_HETZNER_TOKEN= # Alt: KOMODO_HETZNER_TOKEN_FILE 108 | 109 | #=------------------------------=# 110 | #= Komodo Periphery Environment =# 111 | #=------------------------------=# 112 | 113 | ## Full variable list + descriptions are available here: 114 | ## 🦎 https://github.com/mbecker20/komodo/blob/main/config/periphery.config.toml 🦎 115 | 116 | ## Periphery passkeys must include KOMODO_PASSKEY to authenticate. 117 | PERIPHERY_PASSKEYS=${KOMODO_PASSKEY} 118 | 119 | ## Specify the root directory used by Periphery agent. 120 | PERIPHERY_ROOT_DIRECTORY=/etc/komodo 121 | 122 | ## Enable SSL using self signed certificates. 123 | ## Connect to Periphery at https://address:8120. 124 | PERIPHERY_SSL_ENABLED=true 125 | 126 | ## If the disk size is overreporting, can use one of these to 127 | ## whitelist / blacklist the disks to filter them, whichever is easier. 128 | ## Accepts comma separated list of paths. 129 | ## Usually whitelisting just /etc/hostname gives correct size. 130 | PERIPHERY_INCLUDE_DISK_MOUNTS=/etc/hostname 131 | # PERIPHERY_EXCLUDE_DISK_MOUNTS=/snap,/etc/repos -------------------------------------------------------------------------------- /dev/komodo/compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | 3 | komodo-db: 4 | image: postgres 5 | container_name: komodo-db 6 | labels: 7 | komodo.skip: # Prevent Komodo from stopping with StopAllContainers 8 | restart: unless-stopped 9 | logging: 10 | driver: ${COMPOSE_LOGGING_DRIVER:-local} 11 | networks: 12 | - traefik 13 | # ports: 14 | # - 5432:5432 15 | volumes: 16 | - ${VOLUME_DIR}/komodo/db:/var/lib/postgresql/data 17 | environment: 18 | - POSTGRES_USER=${KOMODO_DB_USERNAME:-komodo} 19 | - POSTGRES_PASSWORD=${KOMODO_DB_PASSWORD} 20 | - POSTGRES_DB=${KOMODO_DATABASE_DB_NAME:-komodo} 21 | 22 | komodo-ferretdb: 23 | image: ghcr.io/ferretdb/ferretdb 24 | container_name: komodo-ferretdb 25 | labels: 26 | komodo.skip: # Prevent Komodo from stopping with StopAllContainers 27 | restart: unless-stopped 28 | depends_on: 29 | - komodo-db 30 | logging: 31 | driver: ${COMPOSE_LOGGING_DRIVER:-local} 32 | networks: 33 | - traefik 34 | # ports: 35 | # - 27017:27017 36 | environment: 37 | - FERRETDB_POSTGRESQL_URL=postgres://komodo-db:5432/${KOMODO_DATABASE_DB_NAME:-komodo} 38 | 39 | komodo: 40 | image: ghcr.io/mbecker20/komodo:${COMPOSE_KOMODO_IMAGE_TAG:-latest} 41 | container_name: komodo 42 | restart: unless-stopped 43 | depends_on: 44 | - komodo-ferretdb 45 | logging: 46 | driver: ${COMPOSE_LOGGING_DRIVER:-local} 47 | networks: 48 | - traefik 49 | # ports: 50 | # - 9120:9120 51 | env_file: ./compose.env 52 | environment: 53 | KOMODO_HOST: https://komodo.${FQDN} 54 | KOMODO_DATABASE_URI: mongodb://${KOMODO_DB_USERNAME:-komodo}:${KOMODO_DB_PASSWORD}@komodo-ferretdb:27017/${KOMODO_DATABASE_DB_NAME:-komodo}?authMechanism=PLAIN 55 | KOMODO_PASSKEY: ${KOMODO_PASSKEY} 56 | KOMODO_WEBHOOK_SECRET: ${KOMODO_WEBHOOK_SECRET} 57 | KOMODO_JWT_SECRET: ${KOMODO_JWT_SECRET} 58 | volumes: 59 | ## Core cache for repos for latest commit hash / contents 60 | - ${CONFIG_DIR}/komodo/repo-cache:/repo-cache 61 | labels: 62 | - komodo.skip= # Prevent Komodo from stopping with StopAllContainers 63 | - autoheal=true 64 | - traefik.enable=true 65 | ## HTTP Routers 66 | - traefik.http.routers.komodo-rtr.entrypoints=websecure 67 | - traefik.http.routers.komodo-rtr.rule=Host(`komodo.$FQDN`) 68 | - traefik.http.routers.komodo-rtr.tls=true 69 | ## Middlewares 70 | # - traefik.http.routers.komodo-rtr.middlewares=chain-no-auth@file # No Authentication 71 | # - traefik.http.routers.komodo-rtr.middlewares=chain-basic-auth@file # Basic Authentication 72 | - traefik.http.routers.komodo-rtr.middlewares=chain-oauth2-proxy@file # OAuth 2.0 73 | ## HTTP Services 74 | - traefik.http.routers.komodo-rtr.service=komodo-svc 75 | - traefik.http.services.komodo-svc.loadbalancer.server.port=9120 76 | 77 | komodo-periphery: 78 | image: ghcr.io/mbecker20/periphery:${COMPOSE_KOMODO_IMAGE_TAG:-latest} 79 | container_name: komodo-periphery 80 | labels: 81 | komodo.skip: # Prevent Komodo from stopping with StopAllContainers 82 | restart: unless-stopped 83 | logging: 84 | driver: ${COMPOSE_LOGGING_DRIVER:-local} 85 | networks: 86 | - traefik 87 | env_file: ./compose.env 88 | environment: 89 | PERIPHERY_REPO_DIR: ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}/repos 90 | PERIPHERY_STACK_DIR: ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}/stacks 91 | PERIPHERY_SSL_KEY_FILE: ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}/ssl/key.pem 92 | PERIPHERY_SSL_CERT_FILE: ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}/ssl/cert.pem 93 | volumes: 94 | ## Mount external docker socket 95 | - /var/run/docker.sock:/var/run/docker.sock 96 | ## Allow Periphery to see processes outside of container 97 | - /proc:/proc 98 | ## Specify the Periphery agent root directory. 99 | ## Must be the same inside and outside the container, 100 | ## or docker will get confused. See https://github.com/mbecker20/komodo/discussions/180. 101 | - ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}:${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo} 102 | 103 | networks: 104 | traefik: 105 | name: traefik 106 | external: true 107 | #run: docker network create traefik -------------------------------------------------------------------------------- /dev/media/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "2" 3 | services: 4 | 5 | plex: 6 | image: linuxserver/plex 7 | container_name: plex 8 | network_mode: host 9 | environment: 10 | - PUID=1000 11 | - PGID=1000 12 | - VERSION=docker 13 | volumes: 14 | - /mnt/hdd/Plex/Config:/config 15 | - /mnt/hdd/Media/TV:/data/tvshows 16 | - /mnt/hdd/Media/Movies:/data/movies 17 | - /mnt/hdd/Media/Other:/data/other 18 | - /mnt/hdd/Plex/Transcode:/transcode 19 | restart: unless-stopped 20 | #networks: 21 | #- traefik_proxy 22 | labels: 23 | - "traefik.enable=true" 24 | - "traefik.backend=plex" 25 | - "traefik.frontend.rule=Host:***REMOVED***.duckdns.org; PathPrefix: /plex" 26 | #- "traefik.frontend.rule=Host:plex.${DOMAINNAME}" 27 | - "traefik.port=32400" 28 | - "traefik.docker.network=traefik_proxy" 29 | - "traefik.frontend.headers.SSLRedirect=true" 30 | - "traefik.frontend.headers.STSSeconds=315360000" 31 | - "traefik.frontend.headers.browserXSSFilter=true" 32 | - "traefik.frontend.headers.contentTypeNosniff=true" 33 | - "traefik.frontend.headers.forceSTSHeader=true" 34 | - "traefik.frontend.headers.SSLHost=example.com" 35 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 36 | - "traefik.frontend.headers.STSPreload=true" 37 | - "traefik.frontend.headers.frameDeny=true" 38 | 39 | tautulli: 40 | image: linuxserver/tautulli 41 | container_name: tautulli 42 | environment: 43 | - PUID=1000 44 | - PGID=1000 45 | - TZ=America/Los_Angeles 46 | volumes: 47 | - /mnt/hdd/Plex/tautulli:/config 48 | - /mnt/hdd/Plex/Config/Library/Application Support/Plex Media Server/Logs:/logs:ro # Map this to Plex log directory - recommended RO. 49 | ports: 50 | - 8181:8181 51 | restart: unless-stopped 52 | networks: 53 | - traefik_proxy 54 | labels: 55 | - "traefik.enable=true" 56 | - "traefik.backend=tautulli" 57 | - "traefik.frontend.rule=Host:***REMOVED***.duckdns.org; PathPrefix: /tautulli" 58 | #- "traefik.frontend.rule=Host:tautulli.${DOMAINNAME}" 59 | - "traefik.port=8181" 60 | - "traefik.docker.network=traefik_proxy" 61 | - "traefik.frontend.headers.SSLRedirect=true" 62 | - "traefik.frontend.headers.STSSeconds=315360000" 63 | - "traefik.frontend.headers.browserXSSFilter=true" 64 | - "traefik.frontend.headers.contentTypeNosniff=true" 65 | - "traefik.frontend.headers.forceSTSHeader=true" 66 | - "traefik.frontend.headers.SSLHost=example.com" 67 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 68 | - "traefik.frontend.headers.STSPreload=true" 69 | - "traefik.frontend.headers.frameDeny=true" 70 | 71 | networks: 72 | traefik_proxy: 73 | external: 74 | name: traefik_proxy -------------------------------------------------------------------------------- /dev/minecraft/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | ###################################################################### 6 | # https://hub.docker.com/r/itzg/minecraft-server 7 | ###################################################################### 8 | 9 | minecraft-server: 10 | image: itzg/minecraft-server 11 | container_name: minecraft 12 | environment: 13 | - EULA=TRUE 14 | - PUID=1000 15 | - PGID=1000 16 | - TZ=America/Los_Angeles 17 | volumes: 18 | - ${CONFIG_DIR}/minecraft:/data 19 | ports: 20 | - 25565:25565 21 | networks: 22 | - frontend 23 | tty: true 24 | stdin_open: true 25 | restart: unless-stopped 26 | 27 | networks: 28 | frontend: 29 | external: 30 | name: frontend 31 | default: 32 | driver: bridge -------------------------------------------------------------------------------- /dev/minetest/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | ###################################################################### 6 | # https://github.com/linuxserver/docker-minetest 7 | # https://wiki.minetest.net/Minetest.conf 8 | # https://github.com/celeron55/minetest/blob/master/minetest.conf.example 9 | # https://wiki.minetest.net/Command_line 10 | ###################################################################### 11 | 12 | minetest: 13 | image: linuxserver/minetest 14 | container_name: minetest 15 | environment: 16 | - PUID=1000 17 | - PGID=1000 18 | - TZ=America/Los_Angeles 19 | - CLI_ARGS="--gameid minetest" #optional 20 | volumes: 21 | - /home/pi/containers/config/minetest:/config/.minetest 22 | ports: 23 | - 30000:30000/udp 24 | networks: 25 | - frontend 26 | restart: unless-stopped 27 | 28 | networks: 29 | frontend: 30 | external: 31 | name: frontend 32 | default: 33 | driver: bridge -------------------------------------------------------------------------------- /dev/mosquitto/docker-compose.yml: -------------------------------------------------------------------------------- 1 | ######################################################################################## 2 | # Mosquitto 3 | # https://hub.docker.com/_/eclipse-mosquitto 4 | # https://github.com/owntracks/docker-recorder 5 | ######################################################################################## 6 | --- 7 | version: '3.7' 8 | 9 | services: 10 | 11 | mosquitto: 12 | build: . 13 | #image: eclipse-mosquitto 14 | container_name: mosquitto 15 | environment: 16 | - PUID=${PUID} 17 | - PGID=${PGID} 18 | - TZ=${TZ} 19 | - MOSQUITTO_USERNAME=${MOSQUITTO_USERNAME} 20 | - MOSQUITTO_PASSWORD=${MOSQUITTO_PASSWORD} 21 | ports: 22 | - 1883:1883 23 | - 8883:8883 24 | volumes: 25 | - ${VOLUME_DIR}/mosquitto/data:/mosquitto/data 26 | - ${VOLUME_DIR}/mosquitto/logs:/mosquitto/logs 27 | - ${DOCKER_DIR}/mosquitto:/mosquitto/config 28 | restart: unless-stopped 29 | networks: 30 | - frontend 31 | #- traefik_proxy 32 | 33 | networks: 34 | #traefik_proxy: 35 | #external: 36 | #name: traefik_proxy 37 | frontend: 38 | external: 39 | name: frontend 40 | #driver: bridge -------------------------------------------------------------------------------- /dev/mosquitto/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if ( [ -z "${MOSQUITTO_USERNAME}" ] || [ -z "${MOSQUITTO_PASSWORD}" ] ); then 6 | echo "MOSQUITTO_USERNAME or MOSQUITTO_PASSWORD not defined" 7 | exit 1 8 | fi 9 | 10 | # create mosquitto passwordfile 11 | touch passwordfile 12 | mosquitto_passwd -b passwordfile $MOSQUITTO_USERNAME $MOSQUITTO_PASSWORD 13 | 14 | exec "$@" -------------------------------------------------------------------------------- /dev/mosquitto/dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-mosquitto:latest 2 | COPY docker-entrypoint.sh / 3 | ENTRYPOINT ["sh", "/docker-entrypoint.sh"] 4 | CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] -------------------------------------------------------------------------------- /dev/mosquitto/passwd: -------------------------------------------------------------------------------- 1 | ***REMOVED***:$6$DpUCCuA588e2VGJ1$TPIV6VbIt3Vl8PiDKRrYYR5g8yG6EdduwlZnh/AXNqBK58fmM/68k9s+A6a8zW219GYvoruUBa0WSiqNkwasxw== -------------------------------------------------------------------------------- /dev/mymedia/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | ###################################################################### 6 | # https://hub.docker.com/r/bizmodeller/mymediaforalexa 7 | # https://www.mymediaalexa.com/home/docker 8 | ###################################################################### 9 | 10 | mymedia: 11 | image: bizmodeller/mymediaforalexa 12 | container_name: mymediaforalexa 13 | environment: 14 | - PUID=${PUID} 15 | - PGID=${PGID} 16 | - TZ=${TZ} 17 | volumes: 18 | - ${CONFIG_DIR}/mymediaforalexa:/datadir 19 | - ${EXTHDD_DIR}/media/music:/medialibrary 20 | ports: 21 | - 52050:52050 22 | - 52051:52051 23 | networks: 24 | - frontend 25 | restart: unless-stopped 26 | 27 | networks: 28 | frontend: 29 | external: 30 | name: frontend 31 | default: 32 | driver: bridge -------------------------------------------------------------------------------- /dev/netdata/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | ######################################################################################## 6 | # netdata 7 | # https://hub.docker.com/r/netdata/netdata 8 | ######################################################################################## 9 | 10 | netdata: 11 | image: netdata/netdata:latest 12 | container_name: netdata 13 | hostname: ${FQDN} # set to fqdn of host 14 | environment: 15 | - PUID=${PUID} 16 | #- PGID=${PGID} 17 | - PGID=995 #`grep docker /etc/group | cut -d ':' -f 3` 18 | #ports: 19 | #- 19999:19999 20 | cap_add: 21 | - SYS_PTRACE 22 | security_opt: 23 | - apparmor:unconfined 24 | volumes: 25 | - /proc:/host/proc:ro 26 | - /sys:/host/sys:ro 27 | - /var/run/docker.sock:/var/run/docker.sock:ro 28 | restart: unless-stopped 29 | networks: 30 | - backend 31 | labels: 32 | - "traefik.enable=true" 33 | ## HTTP Routers 34 | - "traefik.http.routers.netdata-rtr.entrypoints=websecure" 35 | - "traefik.http.routers.netdata-rtr.rule=HostHeader(`netdata.${FQDN}`)" 36 | - "traefik.http.routers.netdata-rtr.tls=true" 37 | ## Middlewares 38 | # - "traefik.http.routers.netdata-rtr.middlewares=chain-no-auth@file" # No Authentication 39 | # - "traefik.http.routers.netdata-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 40 | - "traefik.http.routers.netdata-rtr.middlewares=chain-oauth2-proxy@file" # Google OAuth 2.0 41 | ## HTTP Services 42 | - "traefik.http.routers.netdata-rtr.service=netdata-svc" 43 | - "traefik.http.services.netdata-svc.loadbalancer.server.port=19999" 44 | 45 | networks: 46 | backend: 47 | external: 48 | name: backend 49 | #run: docker network create backend -------------------------------------------------------------------------------- /dev/oauth2/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.8' 3 | services: 4 | 5 | ######################################################################################## 6 | # oauth2 7 | # https://quay.io/repository/pusher/oauth2_proxy 8 | # https://github.com/pusher/oauth2_proxy 9 | # https://github.com/pusher/oauth2_proxy/issues/46 10 | ######################################################################################## 11 | 12 | oauth2: 13 | container_name: oauth2 14 | image: quay.io/oauth2-proxy/oauth2-proxy:latest-arm64 15 | command: 16 | - "--cookie-domain=${FQDN}" 17 | - "--cookie-secure=true" 18 | - "--email-domain=*" 19 | # - "--github-org=${GITHUB_ORG}" 20 | - "--github-user=${GITHUB_USER}" # allow logins by username, separated by a comma 21 | - "--scope=user:email" 22 | - "--http-address=0.0.0.0:4180" 23 | - "--reverse-proxy=true" 24 | - "--provider=github" 25 | - "--redirect-url=https://oauth2.${FQDN}/oauth2/callback" 26 | - "--whitelist-domain=.${FQDN}" 27 | - "--upstream=static://200" 28 | - "--skip-provider-button=false" 29 | environment: 30 | - "OAUTH2_PROXY_CLIENT_ID=${GITHUB_OAUTH_CLIENT_ID}" 31 | - "OAUTH2_PROXY_CLIENT_SECRET=${GITHUB_OAUTH_CLIENT_SECRET}" 32 | - "OAUTH2_PROXY_COOKIE_SECRET=${OAUTH2_PROXY_COOKIE_SECRET}" 33 | expose: 34 | - "4180" 35 | #ports: 36 | #- 4180:4180 37 | labels: 38 | - "traefik.enable=true" 39 | ## HTTP Routers 40 | - "traefik.http.routers.oauth2-rtr.entrypoints=websecure" 41 | # - "traefik.http.routers.oauth2-rtr.rule=Host(`oauth2.${FQDN}`)" 42 | # - "traefik.http.routers.oauth2-rtr.rule=Host(`oauth2.${FQDN}`) && PathPrefix(`/oauth2`)" 43 | - "traefik.http.routers.oauth2-rtr.rule=Host(`oauth2.${FQDN}`) || PathPrefix(`/oauth2`)" 44 | - "traefik.http.routers.oauth2-rtr.tls=true" 45 | ## Middlewares 46 | - "traefik.http.routers.oauth2-rtr.middlewares=chain-no-auth@file" 47 | ## HTTP Services 48 | - "traefik.http.routers.oauth2-rtr.service=oauth2-svc" 49 | - "traefik.http.services.oauth2-svc.loadbalancer.server.port=4180" 50 | networks: 51 | - traefik 52 | restart: unless-stopped 53 | 54 | whoami: 55 | image: "traefik/whoami" 56 | container_name: "whoami" 57 | networks: 58 | - traefik 59 | labels: 60 | - "traefik.enable=true" 61 | ## HTTP Routers 62 | - "traefik.http.routers.whoami-rtr.entrypoints=websecure" 63 | - "traefik.http.routers.whoami-rtr.rule=Host(`whoami.$FQDN`)" 64 | - "traefik.http.routers.whoami-rtr.tls=true" 65 | ## Middlewares 66 | # - "traefik.http.routers.whoami-rtr.middlewares=chain-no-auth@file" # No Authentication 67 | # - "traefik.http.routers.whoami-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 68 | - "traefik.http.routers.whoami-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 69 | # - "traefik.http.routers.whoami-rtr.middlewares=oauth2-signin,oauth2-verify,default-https" 70 | ## HTTP Services 71 | - "traefik.http.routers.whoami-rtr.service=whoami-svc" 72 | - "traefik.http.services.whoami-svc.loadbalancer.server.port=80" 73 | 74 | networks: 75 | 76 | traefik: 77 | name: traefik 78 | external: true 79 | #run: docker network create traefik 80 | -------------------------------------------------------------------------------- /dev/obsidian-livesync/compose.yaml: -------------------------------------------------------------------------------- 1 | # For details and other explanations about this file refer to: 2 | # https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/setup_own_server.md#traefik 3 | --- 4 | name: obsidian-livesync 5 | services: 6 | couchdb: 7 | image: couchdb:latest 8 | container_name: obsidian-livesync 9 | # user: ${PUID}:${PGID} 10 | environment: 11 | - COUCHDB_USER=${USERNAME} 12 | - COUCHDB_PASSWORD=${OBSIDIAN_LIVESYNC_COUCHDB_PASSWORD} 13 | volumes: 14 | - type: bind 15 | source: ${CONFIG_DIR}/obsidian_livesync/local.ini 16 | target: /opt/couchdb/etc/local.ini 17 | - ${VOLUME_DIR}/obsidian_livesync:/opt/couchdb/data 18 | #ports: 19 | # - 5984:5984 20 | restart: unless-stopped 21 | networks: 22 | - traefik 23 | labels: 24 | - "traefik.enable=true" 25 | ## HTTP Routers 26 | - "traefik.http.routers.obsidian-livesync-rtr.entrypoints=websecure" 27 | - "traefik.http.routers.obsidian-livesync-rtr.rule=Host(`obsidian-livesync.$FQDN`)" 28 | - "traefik.http.routers.obsidian-livesync-rtr.tls=true" 29 | ## Middlewares 30 | - "traefik.http.routers.obsidian-livesync-rtr.middlewares=obsidiancors" 31 | # - "traefik.http.routers.obsidian-livesync-rtr.middlewares=chain-no-auth@file" # No Authentication 32 | # - "traefik.http.routers.obsidian-livesync-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 33 | # - "traefik.http.routers.obsidian-livesync-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 34 | ## HTTP Services 35 | - "traefik.http.routers.obsidian-livesync-rtr.service=obsidian-livesync-svc" 36 | - "traefik.http.services.obsidian-livesync-svc.loadbalancer.server.port=5984" 37 | # The part needed for CORS to work on Traefik 2.x starts here 38 | - "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowmethods=GET,PUT,POST,HEAD,DELETE" 39 | - "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowheaders=accept,authorization,content-type,origin,referer" 40 | - "traefik.http.middlewares.obsidiancors.headers.accesscontrolalloworiginlist=app://obsidian.md,capacitor://localhost,http://localhost" 41 | - "traefik.http.middlewares.obsidiancors.headers.accesscontrolmaxage=3600" 42 | - "traefik.http.middlewares.obsidiancors.headers.addvaryheader=true" 43 | - "traefik.http.middlewares.obsidiancors.headers.accessControlAllowCredentials=true" 44 | 45 | networks: 46 | traefik: 47 | name: traefik 48 | external: true 49 | #run: docker network create traefik 50 | -------------------------------------------------------------------------------- /dev/obsidian-livesync/local.ini: -------------------------------------------------------------------------------- 1 | [couchdb] 2 | single_node=true 3 | max_document_size = 50000000 4 | 5 | [chttpd] 6 | require_valid_user = true 7 | max_http_request_size = 4294967296 8 | 9 | [chttpd_auth] 10 | require_valid_user = true 11 | authentication_redirect = /e=_/_utils/session.html 12 | 13 | [httpd] 14 | WWW-Authenticate = Basic realm="couchdb" 15 | enable_cors = true 16 | 17 | [cors] 18 | origins = app://obsidian.md,capacitor://localhost,http://localhost 19 | credentials = true 20 | headers = accept, authorization, content-type, origin, referer 21 | methods = GET, PUT, POST, HEAD, DELETE 22 | max_age = 3600 23 | -------------------------------------------------------------------------------- /dev/organize/docker-compose.yml: -------------------------------------------------------------------------------- 1 | #https://hub.docker.com/r/linuxserver/heimdall/ 2 | --- 3 | version: "2" 4 | services: 5 | heimdall: 6 | image: linuxserver/heimdall 7 | container_name: heimdall 8 | environment: 9 | - PUID=1000 10 | - PGID=1000 11 | - TZ=America/Los_Angeles 12 | volumes: 13 | - /home/pi/containers/config/heimdall:/config 14 | #ports: 15 | #- 80:80 16 | #- 443:443 17 | restart: unless-stopped 18 | networks: 19 | - traefik_proxy 20 | labels: 21 | - "traefik.enable=true" 22 | - "traefik.backend=heimdall" 23 | - "traefik.frontend.rule=Host:***REMOVED***.duckdns.org" 24 | #- "traefik.frontend.rule=Host:heimdall.${DOMAINNAME}" 25 | - "traefik.port=443" 26 | - "traefik.protocol=https" 27 | - "traefik.docker.network=traefik_proxy" 28 | - "traefik.frontend.headers.SSLRedirect=true" 29 | - "traefik.frontend.headers.STSSeconds=315360000" 30 | - "traefik.frontend.headers.browserXSSFilter=true" 31 | - "traefik.frontend.headers.contentTypeNosniff=true" 32 | - "traefik.frontend.headers.forceSTSHeader=true" 33 | - "traefik.frontend.headers.SSLHost=example.com" 34 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 35 | - "traefik.frontend.headers.STSPreload=true" 36 | - "traefik.frontend.headers.frameDeny=true" 37 | 38 | networks: 39 | traefik_proxy: 40 | external: 41 | name: traefik_proxy -------------------------------------------------------------------------------- /dev/pihole/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3.7" 3 | services: 4 | 5 | ######################################################################################## 6 | # Pihole 7 | # https://github.com/pi-hole/docker-pi-hole/ 8 | # https://docs.pi-hole.net/ 9 | # 10 | # Note: Once running, navigate to https://pihole.${FQDN}/admin 11 | ######################################################################################## 12 | 13 | pihole: 14 | container_name: pihole 15 | domainname: docker 16 | hostname: pihole 17 | image: pihole/pihole:latest 18 | ports: 19 | - '53:53/tcp' 20 | - '53:53/udp' 21 | # - '67:67/udp' 22 | #- 'XXXX:80' 23 | #- 'YYYY:443' 24 | restart: unless-stopped 25 | volumes: 26 | - ${CONFIG_DIR}/pihole/pihole:/etc/pihole 27 | - ${CONFIG_DIR}/pihole/pihole.log:/var/log/pihole.log 28 | - ${CONFIG_DIR}/pihole/dnsmask.d:/etc/dnsmasq.d 29 | # Recommended but not required (DHCP needs NET_ADMIN) 30 | # https://github.com/pi-hole/docker-pi-hole#note-on-capabilities 31 | cap_add: 32 | - NET_ADMIN 33 | networks: 34 | - backend 35 | environment: 36 | - ServerIP=192.168.1.15 37 | - PROXY_LOCATION=pihole 38 | - VIRTUAL_HOST=${FQDN}/pihole 39 | - VIRTUAL_PORT=80 40 | - TZ=${TZ} 41 | #- WEBPASSWORD=RandomWhenCommentedOut 42 | - DNS1=127.0.0.1 43 | - DNS2=1.1.1.1 44 | #- DNS2=1.0.0.1 45 | labels: 46 | - "traefik.enable=true" 47 | ## HTTP Routers 48 | - "traefik.http.routers.pihole-rtr.entrypoints=websecure" 49 | - "traefik.http.routers.pihole-rtr.rule=HostHeader(`pihole.$FQDN`)" 50 | - "traefik.http.routers.pihole-rtr.tls=true" 51 | ## Middlewares 52 | - "traefik.http.routers.pihole-rtr.middlewares=chain-no-auth@file" # No Authentication 53 | # - "traefik.http.routers.pihole-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 54 | # - "traefik.http.routers.pihole-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 55 | ## HTTP Services 56 | - "traefik.http.routers.pihole-rtr.service=pihole-svc" 57 | - "traefik.http.services.pihole-svc.loadbalancer.server.port=80" 58 | 59 | networks: 60 | backend: 61 | external: 62 | name: backend 63 | #run: docker network create backend -------------------------------------------------------------------------------- /dev/portainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | portainer: 6 | image: portainer/portainer-ce 7 | container_name: portainer 8 | environment: 9 | - PUID=${PUID} 10 | - PGID=${PGID} 11 | - TZ=${TZ} 12 | volumes: 13 | - /var/run/docker.sock:/var/run/docker.sock 14 | - portainer:/data 15 | ports: 16 | - "9000:9000" 17 | restart: unless-stopped 18 | networks: 19 | - backend 20 | 21 | volumes: 22 | portainer: 23 | #external: true 24 | name: portainer #docker volume create portainer 25 | 26 | networks: 27 | backend: 28 | #external: 29 | name: backend #docker network create backend 30 | -------------------------------------------------------------------------------- /dev/prometheus-old/alertmanager/config.yml: -------------------------------------------------------------------------------- 1 | route: 2 | receiver: 'slack' 3 | 4 | receivers: 5 | - name: 'slack' 6 | # slack_configs: 7 | # - send_resolved: true 8 | # username: '' 9 | # channel: '#' 10 | # api_url: '' -------------------------------------------------------------------------------- /dev/prometheus-old/dashboards/HighLoadDashboard.json: -------------------------------------------------------------------------------- 1 | { 2 | "__inputs": [ 3 | { 4 | "name": "DS_PROMETHEUS", 5 | "label": "Prometheus", 6 | "description": "", 7 | "type": "datasource", 8 | "pluginId": "prometheus", 9 | "pluginName": "Prometheus" 10 | } 11 | ], 12 | "__requires": [ 13 | { 14 | "type": "panel", 15 | "id": "graph", 16 | "name": "Graph", 17 | "version": "" 18 | }, 19 | { 20 | "type": "grafana", 21 | "id": "grafana", 22 | "name": "Grafana", 23 | "version": "3.1.0" 24 | }, 25 | { 26 | "type": "datasource", 27 | "id": "prometheus", 28 | "name": "Prometheus", 29 | "version": "1.0.0" 30 | } 31 | ], 32 | "id": null, 33 | "title": "High Load", 34 | "tags": [], 35 | "style": "dark", 36 | "timezone": "browser", 37 | "editable": true, 38 | "hideControls": false, 39 | "sharedCrosshair": false, 40 | "rows": [ 41 | { 42 | "collapse": false, 43 | "editable": true, 44 | "height": 323.625, 45 | "panels": [ 46 | { 47 | "aliasColors": {}, 48 | "bars": false, 49 | "datasource": "${DS_PROMETHEUS}", 50 | "editable": true, 51 | "error": false, 52 | "fill": 1, 53 | "grid": { 54 | "threshold1": null, 55 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 56 | "threshold2": null, 57 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 58 | }, 59 | "id": 1, 60 | "isNew": true, 61 | "legend": { 62 | "avg": false, 63 | "current": false, 64 | "max": false, 65 | "min": false, 66 | "show": true, 67 | "total": false, 68 | "values": false 69 | }, 70 | "lines": true, 71 | "linewidth": 2, 72 | "links": [], 73 | "nullPointMode": "connected", 74 | "percentage": false, 75 | "pointradius": 5, 76 | "points": false, 77 | "renderer": "flot", 78 | "seriesOverrides": [], 79 | "span": 12, 80 | "stack": false, 81 | "steppedLine": false, 82 | "targets": [ 83 | { 84 | "expr": "node_load1", 85 | "hide": false, 86 | "intervalFactor": 2, 87 | "legendFormat": "", 88 | "metric": "node_load1", 89 | "refId": "A", 90 | "step": 10 91 | } 92 | ], 93 | "timeFrom": null, 94 | "timeShift": null, 95 | "title": "Panel Title", 96 | "tooltip": { 97 | "msResolution": false, 98 | "shared": true, 99 | "sort": 0, 100 | "value_type": "cumulative" 101 | }, 102 | "type": "graph", 103 | "xaxis": { 104 | "show": true 105 | }, 106 | "yaxes": [ 107 | { 108 | "format": "short", 109 | "label": null, 110 | "logBase": 1, 111 | "max": null, 112 | "min": null, 113 | "show": true 114 | }, 115 | { 116 | "format": "short", 117 | "label": null, 118 | "logBase": 1, 119 | "max": null, 120 | "min": null, 121 | "show": true 122 | } 123 | ] 124 | } 125 | ], 126 | "title": "Row" 127 | }, 128 | { 129 | "collapse": false, 130 | "editable": true, 131 | "height": 407.4375, 132 | "panels": [ 133 | { 134 | "aliasColors": { 135 | "ALERTS{alertname=\"high_load\",alertstate=\"firing\",instance=\"node-exporter:9100\",job=\"prometheus\"}": "#BF1B00" 136 | }, 137 | "bars": false, 138 | "datasource": "${DS_PROMETHEUS}", 139 | "editable": true, 140 | "error": false, 141 | "fill": 1, 142 | "grid": { 143 | "threshold1": null, 144 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 145 | "threshold2": null, 146 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 147 | }, 148 | "id": 3, 149 | "isNew": true, 150 | "legend": { 151 | "alignAsTable": false, 152 | "avg": false, 153 | "current": false, 154 | "max": false, 155 | "min": false, 156 | "rightSide": true, 157 | "show": true, 158 | "sideWidth": null, 159 | "total": false, 160 | "values": false 161 | }, 162 | "lines": true, 163 | "linewidth": 2, 164 | "links": [], 165 | "nullPointMode": "connected", 166 | "percentage": false, 167 | "pointradius": 5, 168 | "points": false, 169 | "renderer": "flot", 170 | "seriesOverrides": [], 171 | "span": 12, 172 | "stack": false, 173 | "steppedLine": false, 174 | "targets": [ 175 | { 176 | "expr": "ALERTS", 177 | "intervalFactor": 1, 178 | "metric": "ALERTS", 179 | "refId": "A", 180 | "step": 5 181 | } 182 | ], 183 | "timeFrom": null, 184 | "timeShift": null, 185 | "title": "Panel Title", 186 | "tooltip": { 187 | "msResolution": false, 188 | "shared": true, 189 | "sort": 0, 190 | "value_type": "cumulative" 191 | }, 192 | "type": "graph", 193 | "xaxis": { 194 | "show": true 195 | }, 196 | "yaxes": [ 197 | { 198 | "format": "short", 199 | "label": null, 200 | "logBase": 1, 201 | "max": null, 202 | "min": null, 203 | "show": true 204 | }, 205 | { 206 | "format": "short", 207 | "label": null, 208 | "logBase": 1, 209 | "max": null, 210 | "min": null, 211 | "show": true 212 | } 213 | ] 214 | } 215 | ], 216 | "title": "New row" 217 | } 218 | ], 219 | "time": { 220 | "from": "now-3h", 221 | "to": "now" 222 | }, 223 | "timepicker": { 224 | "refresh_intervals": [ 225 | "5s", 226 | "10s", 227 | "30s", 228 | "1m", 229 | "5m", 230 | "15m", 231 | "30m", 232 | "1h", 233 | "2h", 234 | "1d" 235 | ], 236 | "time_options": [ 237 | "5m", 238 | "15m", 239 | "1h", 240 | "6h", 241 | "12h", 242 | "24h", 243 | "2d", 244 | "7d", 245 | "30d" 246 | ] 247 | }, 248 | "templating": { 249 | "list": [] 250 | }, 251 | "annotations": { 252 | "list": [] 253 | }, 254 | "refresh": "10s", 255 | "schemaVersion": 12, 256 | "version": 4, 257 | "links": [], 258 | "gnetId": null 259 | } -------------------------------------------------------------------------------- /dev/prometheus-old/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | 4 | volumes: 5 | prometheus_data: {} 6 | grafana_data: {} 7 | 8 | networks: 9 | front-tier: 10 | back-tier: 11 | 12 | ######################################################################################## 13 | # Prometheus 14 | # https://prometheus.io/ 15 | # https://quay.io/repository/prometheus/prometheus 16 | ######################################################################################## 17 | 18 | services: 19 | 20 | prometheus: 21 | image: quay.io/prometheus/prometheus:latest 22 | container_name: prometheus 23 | environment: 24 | - PUID=${PUID} 25 | - PGID=${PGID} 26 | - TZ=${TZ} 27 | volumes: 28 | - ${DOCKER_DIR}/prometheus:/etc/prometheus 29 | - prometheus_data:/prometheus 30 | command: 31 | - '--config.file=/etc/prometheus/prometheus.yml' 32 | - '--web.listen-address=:9010' 33 | - '--storage.tsdb.path=/prometheus' 34 | - '--web.console.libraries=/usr/share/prometheus/console_libraries' 35 | - '--web.console.templates=/usr/share/prometheus/consoles' 36 | ports: 37 | - 9010:9010 38 | links: 39 | #- cadvisor:cadvisor 40 | - alertmanager:alertmanager 41 | depends_on: 42 | - cadvisor 43 | networks: 44 | - back-tier 45 | restart: unless-stopped 46 | 47 | node-exporter: 48 | image: quay.io/prometheus/node-exporter:latest 49 | container_name: node-exporter 50 | environment: 51 | - PUID=${PUID} 52 | - PGID=${PGID} 53 | - TZ=${TZ} 54 | volumes: 55 | - /proc:/host/proc:ro 56 | - /sys:/host/sys:ro 57 | - /:/rootfs:ro 58 | command: 59 | - '--path.procfs=/host/proc' 60 | - '--path.sysfs=/host/sys' 61 | - --collector.filesystem.ignored-mount-points 62 | - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)" 63 | ports: 64 | - 9100:9100 65 | networks: 66 | - back-tier 67 | restart: always 68 | #deploy: 69 | #mode: global 70 | 71 | alertmanager: 72 | image: quay.io/prometheus/alertmanager:latest 73 | container_name: alertmanager 74 | environment: 75 | - PUID=${PUID} 76 | - PGID=${PGID} 77 | - TZ=${TZ} 78 | ports: 79 | - 9093:9093 80 | volumes: 81 | - ${DOCKER_DIR}/alertmanager/:/etc/alertmanager/ 82 | networks: 83 | - back-tier 84 | restart: always 85 | command: 86 | - '--config.file=/etc/alertmanager/config.yml' 87 | - '--storage.path=/alertmanager' 88 | # deploy: 89 | # placement: 90 | # constraints: 91 | # - node.hostname == ${HOSTNAME} 92 | 93 | grafana: 94 | image: grafana/grafana 95 | container_name: grafana 96 | environment: 97 | - PUID=${PUID} 98 | - PGID=${PGID} 99 | - TZ=${TZ} 100 | user: "104" 101 | depends_on: 102 | - prometheus 103 | ports: 104 | - 3000:3000 105 | volumes: 106 | - grafana_data:/var/lib/grafana 107 | - ${DOCKER_DIR}/grafana/provisioning/:/etc/grafana/provisioning/ 108 | env_file: 109 | - ./grafana/config.monitoring 110 | networks: 111 | - back-tier 112 | - front-tier 113 | restart: always -------------------------------------------------------------------------------- /dev/prometheus-old/grafana/config.monitoring: -------------------------------------------------------------------------------- 1 | GF_SECURITY_ADMIN_PASSWORD=foobar 2 | GF_USERS_ALLOW_SIGN_UP=false 3 | -------------------------------------------------------------------------------- /dev/prometheus-old/grafana/provisioning/dashboards/dashboard.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | - name: 'Prometheus' 5 | orgId: 1 6 | folder: '' 7 | type: file 8 | disableDeletion: false 9 | editable: true 10 | options: 11 | path: /etc/grafana/provisioning/dashboards 12 | -------------------------------------------------------------------------------- /dev/prometheus-old/grafana/provisioning/datasources/datasource.yml: -------------------------------------------------------------------------------- 1 | # config file version 2 | apiVersion: 1 3 | 4 | # list of datasources that should be deleted from the database 5 | deleteDatasources: 6 | - name: Prometheus 7 | orgId: 1 8 | 9 | # list of datasources to insert/update depending 10 | # whats available in the database 11 | datasources: 12 | # name of the datasource. Required 13 | - name: Prometheus 14 | # datasource type. Required 15 | Datasource named ${DS_PROMETHEUS_111} was not found 16 | 17 | # access mode. direct or proxy. Required 18 | access: proxy 19 | # org id. will default to orgId 1 if not specified 20 | orgId: 1 21 | # url 22 | url: node-exporter-x1:9090 23 | # database password, if used 24 | password: 25 | # database user, if used 26 | user: 27 | # database name, if used 28 | database: 29 | # enable/disable basic auth 30 | basicAuth: true 31 | # basic auth username 32 | basicAuthUser: admin 33 | # basic auth password 34 | basicAuthPassword: foobar 35 | # enable/disable with credentials headers 36 | withCredentials: 37 | # mark as default datasource. Max one per org 38 | isDefault: true 39 | # fields that will be converted to json and stored in json_data 40 | jsonData: 41 | graphiteVersion: "1.1" 42 | tlsAuth: false 43 | tlsAuthWithCACert: false 44 | # json object of data that will be encrypted. 45 | secureJsonData: 46 | tlsCACert: "..." 47 | tlsClientCert: "..." 48 | tlsClientKey: "..." 49 | version: 1 50 | # allow users to edit datasources from the UI. 51 | editable: true 52 | -------------------------------------------------------------------------------- /dev/prometheus-old/prometheus/alert.rules: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: example 3 | rules: 4 | 5 | # Alert for any instance that is unreachable for >2 minutes. 6 | - alert: service_down 7 | expr: up == 0 8 | for: 2m 9 | labels: 10 | severity: page 11 | annotations: 12 | summary: "Instance {{ $labels.instance }} down" 13 | description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 2 minutes." 14 | 15 | - alert: high_load 16 | expr: node_load1 > 0.5 17 | for: 2m 18 | labels: 19 | severity: page 20 | annotations: 21 | summary: "Instance {{ $labels.instance }} under high load" 22 | description: "{{ $labels.instance }} of job {{ $labels.job }} is under high load." 23 | -------------------------------------------------------------------------------- /dev/prometheus-old/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | # my global config 2 | global: 3 | scrape_interval: 15s # By default, scrape targets every 15 seconds. 4 | evaluation_interval: 15s # By default, scrape targets every 15 seconds. 5 | # scrape_timeout is set to the global default (10s). 6 | 7 | # Attach these labels to any time series or alerts when communicating with 8 | # external systems (federation, remote storage, Alertmanager). 9 | external_labels: 10 | monitor: 'my-project' 11 | 12 | # Load and evaluate rules in this file every 'evaluation_interval' seconds. 13 | rule_files: 14 | - 'alert.rules' 15 | # - "first.rules" 16 | # - "second.rules" 17 | 18 | # alert 19 | alerting: 20 | alertmanagers: 21 | - scheme: http 22 | static_configs: 23 | - targets: 24 | - "alertmanager:9093" 25 | 26 | # A scrape configuration containing exactly one endpoint to scrape: 27 | # Here it's Prometheus itself. 28 | scrape_configs: 29 | # The job name is added as a label `job=` to any timeseries scraped from this config. 30 | 31 | - job_name: 'prometheus' 32 | 33 | # Override the global default and scrape targets from this job every 5 seconds. 34 | scrape_interval: 5s 35 | 36 | static_configs: 37 | - targets: ['localhost:9090'] 38 | 39 | 40 | - job_name: 'cadvisor' 41 | 42 | # Override the global default and scrape targets from this job every 5 seconds. 43 | scrape_interval: 5s 44 | 45 | dns_sd_configs: 46 | - names: 47 | - 'tasks.cadvisor' 48 | type: 'A' 49 | port: 8080 50 | 51 | # static_configs: 52 | # - targets: ['cadvisor:8080'] 53 | 54 | - job_name: 'node-exporter' 55 | 56 | # Override the global default and scrape targets from this job every 5 seconds. 57 | scrape_interval: 5s 58 | 59 | dns_sd_configs: 60 | - names: 61 | - 'tasks.node-exporter' 62 | type: 'A' 63 | port: 9100 64 | 65 | # static_configs: 66 | # - targets: ['node-exporter:9100'] 67 | -------------------------------------------------------------------------------- /dev/prometheus/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | 4 | #volumes: 5 | #prometheus_data: {} 6 | #grafana_data: {} 7 | 8 | services: 9 | 10 | ######################################################################################## 11 | # Prometheus 12 | # https://quay.io/repository/prometheus/prometheus?tab=info 13 | # https://hub.docker.com/r/prom/prometheus/ 14 | # https://prometheus.io/docs/introduction/https://grafana.com/docs/installation/docker/overview/ 15 | ######################################################################################## 16 | 17 | prometheus: 18 | image: quay.io/prometheus/prometheus 19 | container_name: prometheus 20 | restart: unless-stopped 21 | volumes: 22 | - ./prometheus:/etc/prometheus # Prometheus settings 23 | - ${VOLUME_DIR}/prometheus:/prometheus # Data directory 24 | #- prometheus_data:/prometheus # Data directory 25 | environment: 26 | - PUID=${PUID} 27 | - PGID=${PGID} 28 | - TZ=${TZ} 29 | #network_mode: host 30 | networks: 31 | - backend 32 | ports: 33 | - 9090:9090 34 | #labels: 35 | #- "traefik.enable=true" 36 | #- "traefik.backend=prometheus" 37 | #- "traefik.frontend.rule=Host:prometheus.${FQDN}" 38 | #- "traefik.port=9090" 39 | #- "traefik.docker.network=backend" 40 | #- "traefik.frontend.headers.SSLRedirect=true" 41 | #- "traefik.frontend.headers.STSSeconds=315360000" 42 | #- "traefik.frontend.headers.browserXSSFilter=true" 43 | #- "traefik.frontend.headers.contentTypeNosniff=true" 44 | #- "traefik.frontend.headers.forceSTSHeader=true" 45 | #- "traefik.frontend.headers.SSLHost=example.com" 46 | #- "traefik.frontend.headers.STSIncludeSubdomains=true" 47 | #- "traefik.frontend.headers.STSPreload=true" 48 | #- "traefik.frontend.headers.frameDeny=true" 49 | 50 | ######################################################################################## 51 | # Graphana 52 | # https://hub.docker.com/r/grafana/grafana/ 53 | # https://grafana.com/docs/installation/docker/ 54 | ######################################################################################## 55 | 56 | grafana: 57 | image: grafana/grafana 58 | container_name: grafana 59 | environment: 60 | - PUID=${PUID} 61 | - PGID=${PGID} 62 | - TZ=${TZ} 63 | #user: "104" 64 | depends_on: 65 | - prometheus 66 | ports: 67 | - 3000:3000 68 | volumes: 69 | - ./grafana/provisioning/:/etc/grafana/provisioning/ # Graphana settings and dashboards 70 | - ${VOLUME_DIR}/grafana:/var/lib/grafana # Data directory 71 | #- grafana_data:/var/lib/grafana # Data directory 72 | env_file: 73 | - ./grafana/config.monitoring 74 | networks: 75 | - backend 76 | restart: always 77 | #labels: 78 | #- "traefik.enable=true" 79 | #- "traefik.backend=graphana" 80 | #- "traefik.frontend.rule=Host:graphana.${FQDN}" 81 | #- "traefik.port=3000" 82 | #- "traefik.docker.network=backend" 83 | #- "traefik.frontend.headers.SSLRedirect=true" 84 | #- "traefik.frontend.headers.STSSeconds=315360000" 85 | #- "traefik.frontend.headers.browserXSSFilter=true" 86 | #- "traefik.frontend.headers.contentTypeNosniff=true" 87 | #- "traefik.frontend.headers.forceSTSHeader=true" 88 | #- "traefik.frontend.headers.SSLHost=example.com" 89 | #- "traefik.frontend.headers.STSIncludeSubdomains=true" 90 | #- "traefik.frontend.headers.STSPreload=true" 91 | #- "traefik.frontend.headers.frameDeny=true" 92 | 93 | ######################################################################################## 94 | # Node Exporter 95 | # https://hub.docker.com/r/prom/node-exporter/ 96 | # https://github.com/prometheus/node_exporter 97 | # https://prometheus.io/docs/guides/node-exporter/ 98 | ######################################################################################## 99 | 100 | node-exporter: 101 | image: quay.io/prometheus/node-exporter:latest 102 | container_name: node-exporter-x1 103 | environment: 104 | - PUID=${PUID} 105 | - PGID=${PGID} 106 | - TZ=${TZ} 107 | volumes: 108 | - /proc:/host/proc:ro 109 | - /sys:/host/sys:ro 110 | - /:/rootfs:ro 111 | command: 112 | - '--path.procfs=/host/proc' 113 | - '--path.rootfs=/rootfs' 114 | - '--path.sysfs=/host/sys' 115 | - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)' 116 | ports: 117 | - 9100:9100 118 | networks: 119 | - backend 120 | restart: always 121 | 122 | networks: 123 | backend: 124 | external: 125 | name: backend 126 | #run: docker network create --name=backend -------------------------------------------------------------------------------- /dev/prometheus/grafana/config.monitoring: -------------------------------------------------------------------------------- 1 | GF_SECURITY_ADMIN_PASSWORD=foobar 2 | GF_USERS_ALLOW_SIGN_UP=false 3 | -------------------------------------------------------------------------------- /dev/prometheus/grafana/provisioning/dashboards/dashboard.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | - name: 'Prometheus' 5 | orgId: 1 6 | folder: '' 7 | type: file 8 | disableDeletion: false 9 | editable: true 10 | options: 11 | path: /etc/grafana/provisioning/dashboards 12 | -------------------------------------------------------------------------------- /dev/prometheus/grafana/provisioning/datasources/datasource.yml: -------------------------------------------------------------------------------- 1 | # config file version 2 | apiVersion: 1 3 | 4 | # list of datasources that should be deleted from the database 5 | deleteDatasources: 6 | - name: Prometheus 7 | orgId: 1 8 | 9 | # list of datasources to insert/update depending 10 | # whats available in the database 11 | datasources: 12 | # name of the datasource. Required 13 | - name: Prometheus 14 | # datasource type. Required 15 | type: prometheus 16 | # access mode. direct or proxy. Required 17 | access: proxy 18 | # org id. will default to orgId 1 if not specified 19 | orgId: 1 20 | # url 21 | url: http://172.18.0.5:9090 22 | # database password, if used 23 | password: 24 | # database user, if used 25 | user: 26 | # database name, if used 27 | database: 28 | # enable/disable basic auth 29 | basicAuth: true 30 | # basic auth username 31 | basicAuthUser: admin 32 | # basic auth password 33 | basicAuthPassword: foobar 34 | # enable/disable with credentials headers 35 | withCredentials: 36 | # mark as default datasource. Max one per org 37 | isDefault: true 38 | # fields that will be converted to json and stored in json_data 39 | jsonData: 40 | graphiteVersion: "1.1" 41 | tlsAuth: false 42 | tlsAuthWithCACert: false 43 | # json object of data that will be encrypted. 44 | secureJsonData: 45 | tlsCACert: "..." 46 | tlsClientCert: "..." 47 | tlsClientKey: "..." 48 | version: 1 49 | # allow users to edit datasources from the UI. 50 | editable: true 51 | -------------------------------------------------------------------------------- /dev/prometheus/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | # my global config 2 | global: 3 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. 4 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. 5 | # scrape_timeout is set to the global default (10s). 6 | 7 | # Alertmanager configuration 8 | alerting: 9 | alertmanagers: 10 | - static_configs: 11 | - targets: 12 | # - alertmanager:9093 13 | 14 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. 15 | rule_files: 16 | # - "first_rules.yml" 17 | # - "second_rules.yml" 18 | 19 | # A scrape configuration containing exactly one endpoint to scrape: 20 | # Here it's Prometheus itself. 21 | scrape_configs: 22 | # The job name is added as a label `job=` to any timeseries scraped from this config. 23 | 24 | - job_name: node 25 | scrape_interval: 5s 26 | static_configs: 27 | - targets: ['node-exporter-x1:9100'] 28 | 29 | - job_name: prometheus 30 | # metrics_path defaults to '/metrics' 31 | # scheme defaults to 'http'. 32 | # Override the global default and scrape targets from this job every 5 seconds. 33 | scrape_interval: 5s 34 | static_configs: 35 | - targets: ['localhost:9090'] -------------------------------------------------------------------------------- /dev/qbittorrent/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3.7" 3 | services: 4 | qbittorrent: 5 | image: linuxserver/qbittorrent 6 | container_name: qbittorrent 7 | environment: 8 | - PUID=${PUID} 9 | - PGID=${PGID} 10 | - TZ=${TZ} 11 | - UMASK_SET=022 12 | - WEBUI_PORT=8080 13 | volumes: 14 | - ${CONFIG_DIR}/qbittorrent:/config 15 | - ${EXTHDD_DIR}/downloads/torrents/downloads:/downloads 16 | # networks: 17 | # - backend 18 | network_mode: service:wireguard 19 | # ports: 20 | # - 6881:6881 21 | # - 6881:6881/udp 22 | # - 8080:8080 23 | restart: unless-stopped 24 | labels: 25 | - "traefik.enable=true" 26 | ## HTTP Routers 27 | - "traefik.http.routers.qbittorrent-rtr.entrypoints=websecure" 28 | - "traefik.http.routers.qbittorrent-rtr.rule=HostHeader(`qbittorrent.$FQDN`)" 29 | - "traefik.http.routers.qbittorrent-rtr.tls=true" 30 | ## Middlewares 31 | # - "traefik.http.routers.qbittorrent-rtr.middlewares=chain-no-auth@file" # No Authentication 32 | # - "traefik.http.routers.qbittorrent-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 33 | - "traefik.http.routers.qbittorrent-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 34 | ## HTTP Services 35 | - "traefik.http.routers.qbittorrent-rtr.service=qbittorrent-svc" 36 | - "traefik.http.services.qbittorrent-svc.loadbalancer.server.port=8080" 37 | 38 | # networks: 39 | # backend: 40 | # external: 41 | # name: backend 42 | #run: docker network create backend -------------------------------------------------------------------------------- /dev/rclone/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3.7" 3 | services: 4 | 5 | rclone: 6 | image: rclone/rclone:latest 7 | container_name: rclone 8 | env_file: 9 | - rclone.env 10 | volumes: 11 | #- ${CONFIG_DIR}/rclone:/config 12 | - /home/erik/Downloads/TEST:/backup 13 | networks: 14 | - backend 15 | restart: "no" 16 | 17 | networks: 18 | backend: 19 | external: 20 | name: backend 21 | #run: docker network create backend -------------------------------------------------------------------------------- /dev/rclone/rclone.env: -------------------------------------------------------------------------------- 1 | PUID=1000 2 | PGID=1000 3 | TZ=America/New_York 4 | 5 | # Rclone 6 | RCLONE_CONFIG_REMOTE_TYPE=drive 7 | RCLONE_CONFIG_REMOTE_SCOPE=drive 8 | RCLONE_CONFIG_REMOTE_CLIENT_ID= 9 | RCLONE_CONFIG_REMOTE_CLIENT_SECRET= 10 | RCLONE_CONFIG_REMOTE_TOKEN= 11 | RCLONE_CONFIG_REMOTE_ROOT_FOLDER_ID= -------------------------------------------------------------------------------- /dev/rustdesk/compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: rustdesk 3 | 4 | services: 5 | rustdesk-id: 6 | container_name: rustdesk-id 7 | # ports: 8 | # - 21115:21115 9 | # - 21116:21116 10 | # - 21116:21116/udp 11 | # - 21118:21118 12 | image: rustdesk/rustdesk-server:latest 13 | command: hbbs -r http://rustdesk-relay:21117 14 | volumes: 15 | - ${VOLUME_DIR}/rustdesk:/root 16 | networks: 17 | - traefik 18 | depends_on: 19 | - rustdesk-relay 20 | restart: unless-stopped 21 | labels: 22 | - "traefik.enable=true" 23 | ## TCP Routers 24 | - "traefik.tcp.routers.rustdesk-id1-rtr.entrypoints=rd5-tcp" 25 | - "traefik.tcp.routers.rustdesk-id1-rtr.rule=HostSNI(`*`)" 26 | - "traefik.tcp.routers.rustdesk-id1-rtr.tls=false" 27 | - "traefik.tcp.routers.rustdesk-id1-rtr.tls.passthrough=true" 28 | ## Middlewares 29 | # - "traefik.tcp.routers.rustdesk-id1-rtr.middlewares=chain-no-auth@file" # No Authentication 30 | # - "traefik.tcp.routers.rustdesk-id1-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 31 | # - "traefik.tcp.routers.rustdesk-id1-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 32 | ## TCP Services 33 | - "traefik.tcp.routers.rustdesk-id1-rtr.service=rustdesk-id1-svc" 34 | - "traefik.tcp.services.rustdesk-id1-svc.loadbalancer.server.port=21115" 35 | ############################## 36 | ###### Additional Ports ###### 37 | ############################## 38 | ## TCP Routers 39 | - "traefik.tcp.routers.rustdesk-id2-rtr.entrypoints=rd6-tcp" 40 | - "traefik.tcp.routers.rustdesk-id2-rtr.rule=HostSNI(`*`)" 41 | - "traefik.tcp.routers.rustdesk-id2-rtr.tls=false" 42 | - "traefik.tcp.routers.rustdesk-id2-rtr.tls.passthrough=true" 43 | ## Middlewares 44 | # - "traefik.tcp.routers.rustdesk-id2-rtr.middlewares=chain-no-auth@file" # No Authentication 45 | ## TCP Services 46 | - "traefik.tcp.routers.rustdesk-id2-rtr.service=rustdesk-id2-svc" 47 | - "traefik.tcp.services.rustdesk-id2-svc.loadbalancer.server.port=21116" 48 | ############################## 49 | ###### Additional Ports ###### 50 | ############################## 51 | ## UDP Routers 52 | - "traefik.udp.routers.rustdesk-id3-rtr.entrypoints=rd6-udp" 53 | ## Middlewares 54 | # - "traefik.udp.routers.rustdesk-id3-rtr.middlewares=chain-no-auth@file" # No Authentication 55 | ## UDP Services 56 | - "traefik.udp.routers.rustdesk-id3-rtr.service=rustdesk-id3-svc" 57 | - "traefik.udp.services.rustdesk-id3-svc.loadbalancer.server.port=21116" 58 | ############################## 59 | ###### Additional Ports ###### 60 | ############################## 61 | ## TCP Routers 62 | - "traefik.tcp.routers.rustdesk-id4-rtr.entrypoints=rd8-tcp" 63 | - "traefik.tcp.routers.rustdesk-id4-rtr.rule=HostSNI(`*`)" 64 | - "traefik.tcp.routers.rustdesk-id4-rtr.tls=false" 65 | - "traefik.tcp.routers.rustdesk-id4-rtr.tls.passthrough=true" 66 | ## Middlewares 67 | # - "traefik.tcp.routers.rustdesk-id4-rtr.middlewares=chain-no-auth@file" # No Authentication 68 | ## TCP Services 69 | - "traefik.tcp.routers.rustdesk-id4-rtr.service=rustdesk-id4-svc" 70 | - "traefik.tcp.services.rustdesk-id4-svc.loadbalancer.server.port=21118" 71 | # ## URL: rustdesk.${FQDN}.com (Cloudflare) 72 | # - "traefik.tcp.routers.no-proxy-rtr.tls.certresolver=cloudflare" 73 | # - "traefik.tcp.routers.no-proxy-rtr.tls.domains[0].main=rustdesk.${FQDN}.com" 74 | # - "traefik.tcp.routers.no-proxy-rtr.tls.domains[0].sans=*.rustdesk.${FQDN}.com" 75 | # - "traefik.tcp.routers.no-proxy-rtr.rule=Host(`rustdesk.${FQDN}.com`) || Host(`www.rustdesk.${FQDN}.com`)" 76 | 77 | rustdesk-relay: 78 | container_name: rustdesk-relay 79 | # ports: 80 | # - 21117:21117 81 | # - 21119:21119 82 | image: rustdesk/rustdesk-server:latest 83 | command: hbbr 84 | volumes: 85 | - ${VOLUME_DIR}/rustdesk:/root 86 | networks: 87 | - traefik 88 | restart: unless-stopped 89 | labels: 90 | - "traefik.enable=true" 91 | ## TCP Routers 92 | - "traefik.tcp.routers.rustdesk-relay1-rtr.entrypoints=rd7-tcp" 93 | - "traefik.tcp.routers.rustdesk-relay1-rtr.rule=HostSNI(`*`)" 94 | - "traefik.tcp.routers.rustdesk-relay1-rtr.tls=false" 95 | - "traefik.tcp.routers.rustdesk-relay1-rtr.tls.passthrough=true" 96 | ## Middlewares 97 | # - "traefik.tcp.routers.rustdesk-relay1-rtr.middlewares=chain-no-auth@file" # No Authentication 98 | # - "traefik.tcp.routers.rustdesk-relay1-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 99 | # - "traefik.tcp.routers.rustdesk-relay1-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 100 | ## TCP Services 101 | - "traefik.tcp.routers.rustdesk-relay1-rtr.service=rustdesk-relay1-svc" 102 | - "traefik.tcp.services.rustdesk-relay1-svc.loadbalancer.server.port=21117" 103 | ############################## 104 | ###### Additional Ports ###### 105 | ############################## 106 | ## TCP Routers 107 | - "traefik.tcp.routers.rustdesk-relay2-rtr.entrypoints=rd9-tcp" 108 | - "traefik.tcp.routers.rustdesk-relay2-rtr.rule=HostSNI(`*`)" 109 | - "traefik.tcp.routers.rustdesk-relay2-rtr.tls=false" 110 | - "traefik.tcp.routers.rustdesk-relay2-rtr.tls.passthrough=true" 111 | ## Middlewares 112 | # - "traefik.tcp.routers.rustdesk-relay2-rtr.middlewares=chain-no-auth@file" # No Authentication 113 | ## TCP Services 114 | - "traefik.tcp.routers.rustdesk-relay2-rtr.service=rustdesk-relay2-svc" 115 | - "traefik.tcp.services.rustdesk-relay2-svc.loadbalancer.server.port=21119" 116 | 117 | networks: 118 | traefik: 119 | name: traefik 120 | external: true 121 | #run: docker network create traefik 122 | -------------------------------------------------------------------------------- /dev/shadowsocks/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | shadowsocks: 6 | image: ghcr.io/shadowsocks/ssserver-rust:latest 7 | container_name: shadowsocks 8 | volumes: 9 | - ${CONFIG_DIR}/shadowsocks:/etc/shadowsocks-rust 10 | ports: 11 | - 8388:8388 12 | restart: always 13 | networks: 14 | - traefik 15 | labels: 16 | - "traefik.enable=true" 17 | ## HTTP Routers 18 | - "traefik.http.routers.shadowsocks-rtr.entrypoints=websecure" 19 | - "traefik.http.routers.shadowsocks-rtr.rule=Host(`shadowsocks.$FQDN`)" 20 | - "traefik.http.routers.shadowsocks-rtr.tls=true" 21 | ## Middlewares 22 | - "traefik.http.routers.shadowsocks-rtr.middlewares=chain-no-auth@file" # No Authentication 23 | # - "traefik.http.routers.shadowsocks-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 24 | # - "traefik.http.routers.shadowsocks-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 25 | ## HTTP Services 26 | - "traefik.http.routers.shadowsocks-rtr.service=shadowsocks-svc" 27 | - "traefik.http.services.shadowsocks-svc.loadbalancer.server.port=8388" 28 | 29 | networks: 30 | traefik: 31 | name: traefik 32 | external: true 33 | #run: docker network create traefik 34 | -------------------------------------------------------------------------------- /dev/shiori/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | shiori: 6 | image: ghcr.io/go-shiori/shiori 7 | container_name: shiori 8 | environment: 9 | - PUID=${PUID} 10 | - PGID=${PGID} 11 | - TZ=${TZ} 12 | volumes: 13 | - ${CONFIG_DIR}/shiori:/shiori 14 | #ports: 15 | #- 8080:8080 16 | restart: always 17 | networks: 18 | - traefik 19 | labels: 20 | - "traefik.enable=true" 21 | ## HTTP Routers 22 | - "traefik.http.routers.shiori-rtr.entrypoints=websecure" 23 | - "traefik.http.routers.shiori-rtr.rule=Host(`shiori.$FQDN`)" 24 | - "traefik.http.routers.shiori-rtr.tls=true" 25 | ## Middlewares 26 | # - "traefik.http.routers.shiori-rtr.middlewares=chain-no-auth@file" # No Authentication 27 | # - "traefik.http.routers.shiori-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 28 | - "traefik.http.routers.shiori-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 29 | ## HTTP Services 30 | - "traefik.http.routers.shiori-rtr.service=shiori-svc" 31 | - "traefik.http.services.shiori-svc.loadbalancer.server.port=8080" 32 | 33 | networks: 34 | traefik: 35 | name: traefik 36 | external: true 37 | #run: docker network create traefik -------------------------------------------------------------------------------- /dev/sing-box/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | sing-box: 6 | image: ghcr.io/sagernet/sing-box:latest 7 | container_name: sing-box 8 | ports: 9 | - 8443:8443 10 | volumes: 11 | - ${CONFIG_DIR}/sing-box:/etc/sing-box 12 | - ${CONFIG_DIR}/traefik2/acme/dump:/certs 13 | restart: always 14 | networks: 15 | - traefik 16 | command: ["run", "-c", "/etc/sing-box/config.json"] 17 | #command: ["version"] 18 | labels: 19 | - "traefik.enable=true" 20 | ## HTTP Routers 21 | - "traefik.http.routers.sing-box-rtr.entrypoints=websecure" 22 | - "traefik.http.routers.sing-box-rtr.rule=Host(`my.$FQDN`)" 23 | - "traefik.http.routers.sing-box-rtr.tls=true" 24 | ## Middlewares 25 | - "traefik.http.routers.sing-box-rtr.middlewares=chain-no-auth@file" # No Authentication 26 | # - "traefik.http.routers.sing-box-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 27 | # - "traefik.http.routers.sing-box-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 28 | ## HTTP Services 29 | - "traefik.http.routers.sing-box-rtr.service=sing-box-svc" 30 | - "traefik.http.services.sing-box-svc.loadbalancer.server.port=8443" 31 | 32 | 33 | traefik-certs-dumper: 34 | image: ldez/traefik-certs-dumper:latest 35 | container_name: cert-dumper 36 | networks: 37 | - traefik 38 | entrypoint: sh -c ' 39 | traefik-certs-dumper file --crt-ext=.pem --key-ext=.pem --domain-subdir --version v2 --watch 40 | --source /data/acme.json --dest /data/dump' 41 | volumes: 42 | - ${CONFIG_DIR}/traefik2/acme:/data 43 | 44 | 45 | networks: 46 | traefik: 47 | name: traefik 48 | external: true 49 | #run: docker network create traefik 50 | -------------------------------------------------------------------------------- /dev/smarthome/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "2" 3 | services: 4 | 5 | homeassistant: 6 | container_name: home-assistant 7 | image: homeassistant/raspberrypi3-homeassistant 8 | volumes: 9 | - /home/pi/containers/config/home-assistant:/config 10 | - /etc/localtime:/etc/localtime:ro 11 | #devices: 12 | #- /dev/ttyUSB0:/dev/ttyUSB0 13 | #- /dev/ttyUSB1:/dev/ttyUSB1 14 | #- /dev/ttyACM0:/dev/ttyACM0 15 | restart: unless-stopped 16 | ports: 17 | - "8123:8123" 18 | privileged: true 19 | environment: 20 | - PUID=1000 21 | - PGID=1000 22 | - TZ=America/Los_Angeles 23 | networks: 24 | - traefik_proxy 25 | - default 26 | labels: 27 | - "traefik.enable=true" 28 | - "traefik.backend=homeassistant" 29 | - "traefik.frontend.rule=Host:***REMOVED***.duckdns.org; PathPrefix: /hass" 30 | #- "traefik.frontend.rule=Host:hass.${DOMAINNAME}" 31 | - "traefik.port=8123" 32 | - "traefik.docker.network=traefik_proxy" 33 | - "traefik.frontend.headers.SSLRedirect=true" 34 | - "traefik.frontend.headers.STSSeconds=315360000" 35 | - "traefik.frontend.headers.browserXSSFilter=true" 36 | - "traefik.frontend.headers.contentTypeNosniff=true" 37 | - "traefik.frontend.headers.forceSTSHeader=true" 38 | - "traefik.frontend.headers.SSLHost=example.com" 39 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 40 | - "traefik.frontend.headers.STSPreload=true" 41 | - "traefik.frontend.headers.frameDeny=true" 42 | 43 | networks: 44 | traefik_proxy: 45 | external: 46 | name: traefik_proxy 47 | default: 48 | driver: bridge -------------------------------------------------------------------------------- /dev/soulseek/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: soulseek 3 | 4 | services: 5 | soulseek: 6 | image: slskd/slskd 7 | container_name: soulseek 8 | # ports: 9 | # - "5030:5030" 10 | # - "5031:5031" 11 | # - "50300:50300" 12 | environment: 13 | - SLSKD_REMOTE_CONFIGURATION=true 14 | volumes: 15 | - ${EXTHDD_DIR}/downloads/soulseek:/app 16 | restart: always 17 | network_mode: service:wireguard 18 | #ports: 19 | # - 443:443 20 | # - 80:80 21 | # - 3012:3012 # For WebSocket 22 | labels: 23 | - "traefik.enable=true" 24 | ## HTTP Routers 25 | - "traefik.http.routers.soulseek-rtr.entrypoints=websecure" 26 | - "traefik.http.routers.soulseek-rtr.rule=Host(`soulseek.$FQDN`)" 27 | - "traefik.http.routers.soulseek-rtr.tls=true" 28 | ## Middlewares 29 | - "traefik.http.routers.soulseek-rtr.middlewares=chain-no-auth@file" # No Authentication 30 | # - "traefik.http.routers.soulseek-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 31 | # - "traefik.http.routers.soulseek-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 32 | ## HTTP Services 33 | - "traefik.http.routers.soulseek-rtr.service=soulseek-svc" 34 | - "traefik.http.services.soulseek-svc.loadbalancer.server.port=5030" 35 | 36 | networks: 37 | traefik: 38 | name: traefik 39 | external: true 40 | #run: docker network create traefik 41 | -------------------------------------------------------------------------------- /dev/teslamate/compose.yaml: -------------------------------------------------------------------------------- 1 | name: teslamate 2 | services: 3 | 4 | teslamate: 5 | image: teslamate/teslamate:latest 6 | container_name: teslamate 7 | restart: always 8 | environment: 9 | - ENCRYPTION_KEY=${TESLAMATE_ENCRYPTION_KEY} #replace with a secure key to encrypt your Tesla API tokens 10 | - DATABASE_USER=teslamate 11 | - DATABASE_PASS=${TESLAMATE_DATABASE_PASSWORD} #insert your secure database password! 12 | - DATABASE_NAME=teslamate 13 | - DATABASE_HOST=teslamate-db 14 | - MQTT_HOST=${MQTT_HOST} 15 | - MQTT_USERNAME=${USERNAME} 16 | - MQTT_PASSWORD=${MOSQUITTO_PASSWORD} 17 | # ports: 18 | # - 4000:4000 19 | # volumes: 20 | # - ./import:/opt/app/import 21 | networks: 22 | - traefik 23 | cap_drop: 24 | - all 25 | labels: 26 | - autoheal=true 27 | - traefik.enable=true 28 | ## HTTP Routers 29 | - traefik.http.routers.teslamate-rtr.entrypoints=websecure 30 | - traefik.http.routers.teslamate-rtr.rule=Host(`teslamate.$FQDN2`) 31 | - traefik.http.routers.teslamate-rtr.tls=true 32 | ## Middlewares 33 | # - traefik.http.routers.teslamate-rtr.middlewares=chain-no-auth@file # No Authentication 34 | # - traefik.http.routers.teslamate-rtr.middlewares=chain-basic-auth@file # Basic Authentication 35 | - traefik.http.routers.teslamate-rtr.middlewares=chain-oauth2-proxy@file # OAuth 2.0 36 | ## HTTP Services 37 | - traefik.http.routers.teslamate-rtr.service=teslamate-svc 38 | - traefik.http.services.teslamate-svc.loadbalancer.server.port=4000 39 | 40 | teslamate-db: 41 | image: postgres:16 42 | container_name: teslamate-db 43 | restart: always 44 | environment: 45 | - POSTGRES_USER=teslamate 46 | - POSTGRES_PASSWORD=${TESLAMATE_DATABASE_PASSWORD} #insert your secure database password! 47 | - POSTGRES_DB=teslamate 48 | volumes: 49 | - ${VOLUME_DIR}/teslamate/db:/var/lib/postgresql/data 50 | networks: 51 | - traefik 52 | 53 | networks: 54 | traefik: 55 | name: traefik 56 | external: true 57 | #run: docker network create traefik 58 | -------------------------------------------------------------------------------- /dev/traefik/traefik-v1/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "2" 3 | services: 4 | 5 | duckdns: 6 | image: linuxserver/duckdns 7 | container_name: duckdns 8 | environment: 9 | - PUID=1000 10 | - PGID=1000 11 | - TZ=America/Los_Angeles 12 | - SUBDOMAINS=***REMOVED***,***REMOVED*** 13 | - TOKEN=***REMOVED*** 14 | - LOG_FILE=true #optional 15 | #volumes: 16 | #- /home/pi/containers/config/duckdns:/config #optional 17 | restart: unless-stopped 18 | 19 | traefik: 20 | hostname: traefik 21 | image: traefik:latest 22 | container_name: traefik 23 | restart: always 24 | domainname: ***REMOVED***.duckdns.org 25 | networks: 26 | - default 27 | - traefik_proxy 28 | ports: 29 | - "80:80" 30 | - "443:443" 31 | - "8080:8080" 32 | labels: 33 | - "traefik.enable=true" 34 | - "traefik.backend=traefik" 35 | # - "traefik.frontend.rule=Host:traefik.${FQDN}" 36 | - "traefik.frontend.rule=Host:***REMOVED***.duckdns.org; PathPrefixStrip: /traefik" 37 | - "traefik.port=8080" 38 | - "traefik.docker.network=traefik_proxy" 39 | - "traefik.frontend.headers.SSLRedirect=true" 40 | - "traefik.frontend.headers.STSSeconds=315360000" 41 | - "traefik.frontend.headers.browserXSSFilter=true" 42 | - "traefik.frontend.headers.contentTypeNosniff=true" 43 | - "traefik.frontend.headers.forceSTSHeader=true" 44 | - "traefik.frontend.headers.SSLHost=duckdns.org" 45 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 46 | - "traefik.frontend.headers.STSPreload=true" 47 | - "traefik.frontend.headers.frameDeny=true" 48 | ### - "traefik.frontend.auth.basic.users=***REMOVED***:" 49 | volumes: 50 | - /var/run/docker.sock:/var/run/docker.sock:ro 51 | - /home/pi/containers/config/traefik:/etc/traefik 52 | - /home/pi/containers/config/shared:/shared 53 | 54 | networks: 55 | traefik_proxy: 56 | external: 57 | name: traefik_proxy 58 | default: 59 | driver: bridge -------------------------------------------------------------------------------- /dev/traefik/traefik-v1/rules.toml: -------------------------------------------------------------------------------- 1 | loglevel = "ERROR" 2 | 3 | [backends] 4 | [backends.backend-cockpit] 5 | [backends.backend-cockpit.servers] 6 | [backends.backend-cockpit.servers.server-cockpit-ext] 7 | url = "http://192.168.1.15:9090" 8 | weight = 0 9 | 10 | [frontends] 11 | [frontends.frontend-cockpit] 12 | backend = "backend-cockpit" 13 | passHostHeader = true 14 | [frontends.frontend-cockpit.routes] 15 | [frontends.frontend-cockpit.routes.route-cockpit-ext] 16 | rule = "Host:***REMOVED***.duckdns.org; PathPrefixStrip: /cockpit-pi" -------------------------------------------------------------------------------- /dev/traefik/traefik-v1/traefik.toml: -------------------------------------------------------------------------------- 1 | logLevel = "WARN" #DEBUG, INFO, WARN, ERROR, FATAL, PANIC 2 | # InsecureSkipVerify = true 3 | defaultEntryPoints = ["http", "https"] 4 | 5 | # WEB interface of Traefik - it will show web page with overview of frontend and backend configurations 6 | [api] 7 | entryPoint = "traefik" 8 | dashboard = true 9 | address = ":8080" 10 | 11 | # Force HTTPS 12 | [entryPoints] 13 | [entryPoints.http] 14 | address = ":80" 15 | [entryPoints.http.redirect] 16 | entryPoint = "https" 17 | [entryPoints.https] 18 | address = ":443" 19 | [entryPoints.https.tls] 20 | # [entryPoints.https.tls.defaultCertificate] 21 | 22 | # File configuration backends 23 | [file] 24 | filename = "/etc/traefik/rules.toml" 25 | watch = true 26 | 27 | # Let's encrypt configuration 28 | [acme] 29 | email = "***REMOVED***" 30 | storage="/etc/traefik/acme/acme.json" 31 | entryPoint = "https" 32 | acmeLogging=true 33 | onDemand = false #create certificate when container is created 34 | onHostRule = true 35 | # Use a HTTP-01 acme challenge rather than TLS-SNI-01 challenge 36 | [acme.httpChallenge] 37 | entryPoint = "http" 38 | 39 | # Connection to docker host system (docker.sock) 40 | [docker] 41 | endpoint = "unix:///var/run/docker.sock" 42 | domain = "***REMOVED***.duckdns.org" 43 | watch = true 44 | # This will hide all docker containers that don't have explicitly 45 | # set label to "enable" 46 | exposedbydefault = false -------------------------------------------------------------------------------- /dev/traefik/traefik-v2/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | 5 | ########################################################################## 6 | # Traefik v2.0 7 | # 8 | # https://docs.traefik.io/v2.0/getting-started/quick-start/ 9 | ########################################################################## 10 | 11 | reverse-proxy: 12 | # The official v2.0 Traefik docker image 13 | image: traefik:v2.0 14 | # Enables the web UI and tells Traefik to listen to docker 15 | command: 16 | #- "--log.level=DEBUG" 17 | - "--api.insecure=true" 18 | - "--providers.docker=true" 19 | - "--providers.docker.exposedbydefault=false" 20 | - "--entrypoints.web.address=:80" 21 | - "--entrypoints.websecure.address=:443" 22 | # Enable a dns challenge named "mydnschallenge" 23 | - "--certificatesresolvers.mydnschallenge.acme.dnschallenge=true" 24 | # Tell which provider to use 25 | - "--certificatesresolvers.mydnschallenge.acme.dnschallenge.provider=duckdns" # https://docs.traefik.io/v2.0/https/acme/ 26 | #- "--certificatesresolvers.mydnschallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" 27 | - "--certificatesresolvers.mydnschallenge.acme.email=${EMAIL}" 28 | - "--certificatesresolvers.mydnschallenge.acme.storage=/letsencrypt/acme.json" 29 | ports: 30 | - 80:80 # The HTTP port 31 | - 443:443 # The Secure Web port 32 | - 8080:8080 # The Web UI (enabled by --api.insecure=true) 33 | environment: 34 | # For Duck DNS 35 | - DUCKDNS_TOKEN=${DUCKDNS_TOKEN} 36 | # For Cloudflare 37 | #- CF_API_EMAIL 38 | #- CF_API_KEY # Use the Global API Key, not the Origin CA Key 39 | volumes: 40 | - ${CONFIG_DIR}/letsencrypt:/letsencrypt 41 | - /var/run/docker.sock:/var/run/docker.sock:ro # So that Traefik can listen to the Docker events 42 | networks: 43 | - backend 44 | 45 | # ... 46 | whoami: 47 | image: "containous/whoami" 48 | container_name: "simple-service" 49 | networks: 50 | - backend 51 | labels: 52 | - "traefik.enable=true" 53 | - "traefik.http.routers.whoami.rule=Host(`whoami.${FQDN}`)" 54 | - "traefik.http.routers.whoami.entrypoints=websecure" 55 | - "traefik.http.routers.whoami.tls.certresolver=mydnschallenge" # Uses the Host rule to define which certificate to issue 56 | 57 | heimdall: 58 | image: linuxserver/heimdall 59 | container_name: heimdall 60 | environment: 61 | - PUID=${PUID} 62 | - PGID=${PGID} 63 | - TZ=${TZ} 64 | volumes: 65 | - ${CONFIG_DIR}/heimdall:/config 66 | #ports: 67 | #- 80:80 68 | #- 443:443 69 | restart: unless-stopped 70 | networks: 71 | - backend 72 | labels: 73 | - "traefik.enable=true" 74 | - "traefik.http.routers.whoami.rule=Host(`heimdall.${FQDN}`)" 75 | - "traefik.http.routers.whoami.entrypoints=websecure" 76 | - "traefik.http.routers.whoami.tls.certresolver=mydnschallenge" # Uses the Host rule to define which certificate to issue 77 | 78 | networks: 79 | frontend: 80 | external: 81 | name: frontend 82 | #run: docker network create --name=frontend 83 | backend: 84 | external: 85 | name: backend 86 | #run: docker network create --name=backend -------------------------------------------------------------------------------- /dev/utility/network-concept/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | MAINTAINER Erik Thomsen 3 | 4 | RUN apk add openvpn curl 5 | COPY *.ovpn /etc/openvpn/ -------------------------------------------------------------------------------- /dev/utility/network-concept/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /dev/utility/network-concept/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | 4 | services: 5 | 6 | vpn: 7 | container_name: vpn 8 | hostname: vpn 9 | build: . 10 | #image: alpine:latest 11 | cap_add: 12 | - NET_ADMIN 13 | #devices: 14 | #- /dev/net/tun 15 | restart: unless-stopped 16 | dns: 17 | - 1.1.1.1 18 | - 1.0.0.1 19 | networks: 20 | - frontend 21 | - backend 22 | - remote 23 | tty: true 24 | environment: 25 | - 'PS1=\\h:\\w\\$$ ' 26 | 27 | host1: 28 | container_name: host1 29 | hostname: host1 30 | image: alpine:latest 31 | cap_add: 32 | - NET_ADMIN 33 | restart: unless-stopped 34 | dns: 35 | - 1.1.1.1 36 | - 1.0.0.1 37 | networks: 38 | - backend 39 | tty: true 40 | environment: 41 | - 'PS1=\\h:\\w\\$$ ' 42 | command: 43 | - '' 44 | 45 | remote1: 46 | container_name: remote1 47 | hostname: remote1 48 | image: alpine:latest 49 | cap_add: 50 | - NET_ADMIN 51 | restart: unless-stopped 52 | dns: 53 | - 1.1.1.1 54 | - 1.0.0.1 55 | networks: 56 | - remote 57 | tty: true 58 | environment: 59 | - 'PS1=\\h:\\w\\$$ ' 60 | 61 | networks: 62 | frontend: 63 | name: frontend 64 | #driver_opts: 65 | #com.docker.network.bridge.enable_ip_masquerade: 'true' 66 | backend: 67 | name: backend 68 | #internal: true 69 | #attachable: true 70 | remote: 71 | name: remote -------------------------------------------------------------------------------- /dev/watchtower/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "2" 3 | services: 4 | 5 | watchtower: # https://github.com/containrrr/watchtower 6 | container_name: watchtower 7 | restart: always 8 | image: containrrr/watchtower:armhf-latest 9 | environment: 10 | #- WATCHTOWER_NOTIFICATIONS=email 11 | #- WATCHTOWER_NOTIFICATION_EMAIL_FROM=fromaddress@gmail.com 12 | #- WATCHTOWER_NOTIFICATION_EMAIL_TO=toaddress@gmail.com 13 | #- WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.gmail.com 14 | #- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=fromaddress@gmail.com 15 | #- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=app_password 16 | volumes: 17 | - /var/run/docker.sock:/var/run/docker.sock 18 | # Cron Expression of 6 fields: 19 | command: --schedule "0 30 3 * * *" --cleanup 20 | # Checks for new container images everyday at 3:30am 21 | 22 | # As an alternative to Watchtower, look at Ouroboros - https://github.com/pyouroboros/ouroboros -------------------------------------------------------------------------------- /dev/wiki.js/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | 4 | db: 5 | image: postgres 6 | container_name: wikijs-db 7 | environment: 8 | POSTGRES_DB: wiki 9 | POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} 10 | POSTGRES_USER: ${USERNAME} 11 | #logging: 12 | #driver: "none" 13 | restart: unless-stopped 14 | networks: 15 | - backend 16 | volumes: 17 | #- db-data:/var/lib/postgresql/data 18 | - ${VOLUME_DIR}/wikijs-db:/var/lib/postgresql/data #data directory 19 | 20 | wiki: 21 | image: requarks/wiki:2 22 | container_name: wikijs 23 | depends_on: 24 | - db 25 | environment: 26 | DB_TYPE: postgres 27 | DB_HOST: db 28 | DB_PORT: 5432 29 | DB_USER: ${USERNAME} 30 | DB_PASS: ${POSTGRES_PASSWORD} 31 | DB_NAME: wiki 32 | restart: unless-stopped 33 | networks: 34 | - backend 35 | # ports: 36 | # - "80:3000" 37 | labels: 38 | - "traefik.enable=true" 39 | - "traefik.backend=wiki" 40 | - "traefik.frontend.rule=Host:wiki.${FQDN}" 41 | - "traefik.port=3000" 42 | - "traefik.docker.network=backend" 43 | - "traefik.frontend.headers.SSLRedirect=true" 44 | - "traefik.frontend.headers.STSSeconds=315360000" 45 | - "traefik.frontend.headers.browserXSSFilter=true" 46 | - "traefik.frontend.headers.contentTypeNosniff=true" 47 | - "traefik.frontend.headers.forceSTSHeader=true" 48 | - "traefik.frontend.headers.SSLHost=example.com" 49 | - "traefik.frontend.headers.STSIncludeSubdomains=true" 50 | - "traefik.frontend.headers.STSPreload=true" 51 | - "traefik.frontend.headers.frameDeny=true" 52 | 53 | networks: 54 | backend: 55 | external: 56 | name: backend 57 | #run: docker network create --name=backend 58 | -------------------------------------------------------------------------------- /dev/wordpress/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | services: 4 | 5 | ######################################################################################## 6 | # Wordpress 7 | # https://hub.docker.com/_/wordpress 8 | ######################################################################################## 9 | 10 | wordpress: 11 | image: wordpress 12 | container_name: wordpress 13 | environment: 14 | - PUID=${PUID} 15 | - PGID=${PGID} 16 | - TZ=${TZ} 17 | restart: always 18 | ports: 19 | - 8080:80 20 | environment: 21 | WORDPRESS_DB_HOST: db 22 | WORDPRESS_DB_USER: ${USERNAME} 23 | WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD} 24 | WORDPRESS_DB_NAME: ${DB_NAME} 25 | volumes: 26 | - wordpress:/var/www/html 27 | 28 | ######################################################################################## 29 | # MySQL (MariaDB) 30 | # The only official MySQL compatible database compiled for ARM is MariaDB 31 | # https://hub.docker.com/_/mariadb 32 | ######################################################################################## 33 | 34 | db: 35 | image: mariadb 36 | container_name: mariadb 37 | environment: 38 | - PUID=${PUID} 39 | - PGID=${PGID} 40 | - TZ=${TZ} 41 | restart: always 42 | environment: 43 | MYSQL_ROOT_PASSWORD: ${MYSQL_ROOTPW} 44 | MYSQL_USER: ${USERNAME} 45 | MYSQL_PASSWORD: ${MYSQL_PASSWORD} 46 | MYSQL_DATABASE: ${DB_NAME} 47 | volumes: 48 | - wordpress_db:/var/lib/mysql 49 | 50 | ######################################################################################## 51 | # Volumes 52 | ######################################################################################## 53 | 54 | volumes: 55 | wordpress: 56 | name: wordpress 57 | wordpress_db: 58 | #external: true 59 | name: wordpress_db 60 | #run: docker volume create --name=wordpress_db 61 | -------------------------------------------------------------------------------- /dev/wud/compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: wud 3 | services: 4 | 5 | whatsupdocker: 6 | image: getwud/wud 7 | container_name: wud 8 | volumes: 9 | - /var/run/docker.sock:/var/run/docker.sock 10 | # ports: 11 | # - 3000:3000 12 | networks: 13 | - traefik 14 | labels: 15 | - "traefik.enable=true" 16 | ## HTTP Routers 17 | - "traefik.http.routers.wud-rtr.entrypoints=websecure" 18 | - "traefik.http.routers.wud-rtr.rule=Host(`wud.$FQDN`)" 19 | - "traefik.http.routers.wud-rtr.tls=true" 20 | ## Middlewares 21 | # - "traefik.http.routers.wud-rtr.middlewares=chain-no-auth@file" # No Authentication 22 | # - "traefik.http.routers.wud-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 23 | - "traefik.http.routers.wud-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 24 | ## HTTP Services 25 | - "traefik.http.routers.wud-rtr.service=wud-svc" 26 | - "traefik.http.services.wud-svc.loadbalancer.server.port=3000" 27 | 28 | networks: 29 | traefik: 30 | name: traefik 31 | external: true 32 | #run: docker network create traefik -------------------------------------------------------------------------------- /documentation/0-oauth2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/0-oauth2.png -------------------------------------------------------------------------------- /documentation/1-heimdall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/1-heimdall.png -------------------------------------------------------------------------------- /documentation/gotify-icons/healthchecks-green.png: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | -------------------------------------------------------------------------------- /documentation/gotify-icons/healthchecks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/healthchecks.png -------------------------------------------------------------------------------- /documentation/gotify-icons/healthchecks.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | -------------------------------------------------------------------------------- /documentation/gotify-icons/healthchecks2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/healthchecks2.png -------------------------------------------------------------------------------- /documentation/gotify-icons/lidarr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/lidarr.png -------------------------------------------------------------------------------- /documentation/gotify-icons/ouroboros.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/ouroboros.png -------------------------------------------------------------------------------- /documentation/gotify-icons/overseerr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/overseerr.png -------------------------------------------------------------------------------- /documentation/gotify-icons/pi3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/pi3.png -------------------------------------------------------------------------------- /documentation/gotify-icons/pi4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/pi4.png -------------------------------------------------------------------------------- /documentation/gotify-icons/radarr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/radarr.png -------------------------------------------------------------------------------- /documentation/gotify-icons/sonarr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/sonarr.png -------------------------------------------------------------------------------- /documentation/gotify-icons/source.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etho201/docker-pi-stacks/a8a3463fa102c5ac270eafeebe32a1c7f85cd0f0/documentation/gotify-icons/source.psd -------------------------------------------------------------------------------- /documentation/nextcloud/README.md: -------------------------------------------------------------------------------- 1 | # Nextcloud Documentation 2 | 3 | ## When you have trouble logging in from the Android App: 4 | 1. Login to the Nextcloud desktop interface. 5 | 1. Click the `User Icon` → `Settings` → `Personal` → `Security`. 6 | 1. Click on `Create new app password` 7 | 1. Click on `Show QR code for mobile apps` 8 | 1. From the Android app, click on `Alternative log in using app token`. 9 | 10 | --- 11 | ## Manually adding files 12 | 13 | Scan for new files and update the file cache: 14 | 15 | ```bash 16 | docker exec -ti --user www-data nextcloud /var/www/html/occ files:scan --all 17 | ``` 18 | --- 19 | ## Too many requests error 20 | 21 | ```bash 22 | docker exec -it nextcloud-db bash 23 | psql -U nextcloud -d nextcloud 24 | SELECT * FROM oc_bruteforce_attempts; 25 | DELETE FROM oc_bruteforce_attempts WHERE IP="xxx.xxx.xxx.xxx"; 26 | ``` 27 | --- -------------------------------------------------------------------------------- /stacks/backup/docker-compose.yml: -------------------------------------------------------------------------------- 1 | cron: 2 | image: demo-image:latest 3 | entrypoint: /bin/bash 4 | command: ["cron", "-f"] 5 | volumes: 6 | - data:/app-data -------------------------------------------------------------------------------- /stacks/bitwarden/bitwarden-mysql/Dockerfile: -------------------------------------------------------------------------------- 1 | ################################################################## 2 | # Using multistage build: 3 | # https://docs.docker.com/develop/develop-images/multistage-build/ 4 | # https://whitfin.io/speeding-up-rust-docker-builds/ 5 | ####################### VAULT BUILD IMAGE ####################### 6 | FROM alpine:3.10 as vault 7 | 8 | ENV VAULT_VERSION "v2.12.0" 9 | 10 | ENV URL "https://github.com/dani-garcia/bw_web_builds/releases/download/$VAULT_VERSION/bw_web_$VAULT_VERSION.tar.gz" 11 | 12 | RUN apk add --no-cache --upgrade \ 13 | curl \ 14 | tar 15 | 16 | RUN mkdir /web-vault 17 | WORKDIR /web-vault 18 | 19 | SHELL ["/bin/ash", "-eo", "pipefail", "-c"] 20 | 21 | RUN curl -L $URL | tar xz 22 | RUN ls 23 | 24 | ########################## BUILD IMAGE ########################## 25 | # We need to use the Rust build image, because 26 | # we need the Rust compiler and Cargo tooling 27 | FROM rust:1.38 as build 28 | 29 | # set mysql backend 30 | ARG DB=mysql 31 | 32 | RUN apt-get update \ 33 | && apt-get install -y \ 34 | --no-install-recommends \ 35 | gcc-arm-linux-gnueabihf \ 36 | && mkdir -p ~/.cargo \ 37 | && echo '[target.armv7-unknown-linux-gnueabihf]' >> ~/.cargo/config \ 38 | && echo 'linker = "arm-linux-gnueabihf-gcc"' >> ~/.cargo/config 39 | 40 | ENV CARGO_HOME "/root/.cargo" 41 | ENV USER "root" 42 | 43 | WORKDIR /app 44 | 45 | # Prepare openssl armhf libs 46 | RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ 47 | /etc/apt/sources.list.d/deb-src.list \ 48 | && dpkg --add-architecture armhf \ 49 | && apt-get update \ 50 | && apt-get install -y \ 51 | --no-install-recommends \ 52 | libssl-dev:armhf \ 53 | libc6-dev:armhf \ 54 | libmariadb-dev:armhf 55 | 56 | 57 | ENV CC_armv7_unknown_linux_gnueabihf="/usr/bin/arm-linux-gnueabihf-gcc" 58 | ENV CROSS_COMPILE="1" 59 | ENV OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabihf" 60 | ENV OPENSSL_LIB_DIR="/usr/lib/arm-linux-gnueabihf" 61 | 62 | # Copies the complete project 63 | # To avoid copying unneeded files, use .dockerignore 64 | COPY . . 65 | 66 | # Build 67 | RUN rustup target add armv7-unknown-linux-gnueabihf 68 | RUN cargo build --features ${DB} --release --target=armv7-unknown-linux-gnueabihf -v 69 | 70 | ######################## RUNTIME IMAGE ######################## 71 | # Create a new stage with a minimal image 72 | # because we already have a binary built 73 | FROM balenalib/armv7hf-debian:buster 74 | 75 | ENV ROCKET_ENV "staging" 76 | ENV ROCKET_PORT=80 77 | ENV ROCKET_WORKERS=10 78 | 79 | RUN [ "cross-build-start" ] 80 | 81 | # Install needed libraries 82 | RUN apt-get update && apt-get install -y \ 83 | --no-install-recommends \ 84 | openssl \ 85 | ca-certificates \ 86 | curl \ 87 | libmariadbclient-dev \ 88 | && rm -rf /var/lib/apt/lists/* 89 | 90 | RUN mkdir /data 91 | 92 | RUN [ "cross-build-end" ] 93 | 94 | VOLUME /data 95 | EXPOSE 80 96 | 97 | # Copies the files from the context (Rocket.toml file and web-vault) 98 | # and the binary from the "build" stage to the current stage 99 | COPY Rocket.toml . 100 | COPY --from=vault /web-vault ./web-vault 101 | COPY --from=build /app/target/armv7-unknown-linux-gnueabihf/release/bitwarden_rs . 102 | 103 | COPY docker/healthcheck.sh ./healthcheck.sh 104 | 105 | HEALTHCHECK --interval=30s --timeout=3s CMD sh healthcheck.sh || exit 1 106 | 107 | # Configures the startup! 108 | CMD ["./bitwarden_rs"] 109 | -------------------------------------------------------------------------------- /stacks/bitwarden/compose.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: bitwarden 3 | services: 4 | 5 | ######################################################################################## 6 | # Bitwarden_rs - Bitwarden server API implementation written in Rust compatible with upstream Bitwarden clients 7 | # https://github.com/dani-garcia/vaultwarden/wiki/Using-Docker-Compose 8 | ######################################################################################## 9 | 10 | bitwarden: 11 | image: vaultwarden/server:latest 12 | container_name: bitwarden 13 | restart: always 14 | volumes: 15 | - ${VOLUME_DIR}/bitwarden:/data 16 | environment: 17 | - ADMIN_TOKEN=${BITWARDEN_ADMIN_TOKEN} # https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page 18 | - DOMAIN=https://bitwarden.${FQDN} # Required for correct generation of invite links 19 | - SIGNUPS_ALLOWED=false 20 | - SMTP_HOST=${SMTP_RELAY_SERVER} # https://github.com/dani-garcia/vaultwarden/wiki/SMTP-Configuration 21 | - SMTP_FROM=${EMAIL_FROM} 22 | - SMTP_PORT=587 23 | - SMTP_SECURITY=starttls 24 | - SMTP_USERNAME=${EMAIL_FROM} # Must 'enable 2FA and use app password' if using Gmail --> https://support.google.com/accounts/answer/185833?hl=en 25 | - SMTP_PASSWORD=${BITWARDEN_EMAIL_APP_PASSWORD} 26 | - LOG_FILE=/data/bitwarden.log 27 | - DATABASE_URL=mysql://vaultwarden:${BITWARDEN_MYSQL_PASSWORD}@bitwarden-db/vaultwarden #FORMAT: DATABASE_URL=mysql://[[user]:[password]@]host[:port][/database] 28 | - DISABLE_ICON_DOWNLOAD=true 29 | networks: 30 | - traefik 31 | #ports: 32 | # - 443:443 33 | # - 80:80 34 | depends_on: 35 | bitwarden-db: 36 | condition: service_healthy 37 | labels: 38 | - "traefik.enable=true" 39 | ## HTTP Routers 40 | - "traefik.http.routers.bitwarden-rtr.entrypoints=websecure" 41 | - "traefik.http.routers.bitwarden-rtr.rule=Host(`bitwarden.$FQDN`)" 42 | - "traefik.http.routers.bitwarden-rtr.tls=true" 43 | ## Middlewares 44 | - "traefik.http.routers.bitwarden-rtr.middlewares=chain-no-auth@file" # No Authentication 45 | # - "traefik.http.routers.bitwarden-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 46 | # - "traefik.http.routers.bitwarden-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 47 | ## HTTP Services 48 | - "traefik.http.routers.bitwarden-rtr.service=bitwarden-svc" 49 | - "traefik.http.services.bitwarden-svc.loadbalancer.server.port=80" 50 | 51 | ######################################################################################## 52 | # MariaDB 53 | # Vaultwarden is based upon MariaDB client libraries since that is what Debian provides. 54 | # https://hub.docker.com/_/mariadb 55 | # 56 | # Notes: https://github.com/dani-garcia/bitwarden_rs/wiki/Using-the-MySQL-Backend 57 | ######################################################################################## 58 | 59 | bitwarden-db: 60 | image: container-registry.oracle.com/mysql/community-server:8.4-aarch64 61 | container_name: bitwarden-db 62 | restart: always 63 | networks: 64 | - traefik 65 | environment: 66 | MYSQL_USER: vaultwarden 67 | MYSQL_DATABASE: vaultwarden 68 | MYSQL_ROOT_PASSWORD: ${BITWARDEN_MYSQL_ROOTPW} 69 | MYSQL_PASSWORD: ${BITWARDEN_MYSQL_PASSWORD} 70 | MYSQL_ROOT_HOST: bitwarden.traefik 71 | volumes: 72 | - ${VOLUME_DIR}/bitwarden/db:/var/lib/mysql #Data Directory 73 | - /etc/localtime:/etc/localtime:ro 74 | healthcheck: 75 | test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD 76 | start_period: 5s 77 | interval: 5s 78 | timeout: 5s 79 | retries: 55 80 | 81 | networks: 82 | traefik: 83 | name: traefik 84 | external: true 85 | #run: docker network create traefik 86 | -------------------------------------------------------------------------------- /stacks/core/README.md: -------------------------------------------------------------------------------- 1 | To launch all the containers: 2 | ``` 3 | docker compose up -d 4 | ``` 5 | 6 | To launch an individual container, specify the service (for example: Lidarr): 7 | ``` 8 | docker compose up -d gotify 9 | ``` 10 | 11 | To launch multiple containers, separate the services with spaces (for example: db1 and nextcloud): 12 | ``` 13 | docker compose up -d nextcloud nextcloud-db 14 | ``` 15 | 16 | --- 17 | 18 | ## Troubleshooting: 19 | 20 | - If trying to put Plex behind a reverse proxy and you're using Cloudflare, you'll need to either disable the proxy in Cloudflare (DNS only routing) for `plex.${FQDN}`, or create a Configuration Rule for `https://plex.${FQDN}/web/index.html` that turns off the Cloudflare Rocket Loader. See [here](https://www.reddit.com/r/PleX/comments/n4l2fu/web_client_stuck_on_the_plex_logo_when_accessing/?utm_source=share&utm_medium=ios_app&utm_name=iossmf) for more info. -------------------------------------------------------------------------------- /stacks/downloaders/README.md: -------------------------------------------------------------------------------- 1 | # Implementing a health check 2 | 3 | Create a Cron job that calls the `healthcheck.sh` file. If the health check determines that Transmission is inaccessible, it will automatically rebuild the containers for Wireguard, Transmission, and qBittorrent and a notification will be sent via Gotify. 4 | 5 | > **Important:** Ensure `docker` can be found in one of the paths specified in the script. Example: `/usr/bin/docker` 6 | 7 | Example of Cron job: 8 | 9 | ```bash 10 | */5 * * * * bash /path/to/healthcheck.sh -t GOTIFY_TOKEN >/dev/null 2>&1 11 | ``` 12 | 13 | | Option | Description | Required? | 14 | |--------|-------------|-----------| 15 | |`-t`|Gotify **T**oken|`True`| 16 | 17 | > **Example:** This will run the health check **every 5 minutes**. See [https://crontab.guru](https://crontab.guru/#*/5_*_*_*_*) for help creating cron expressions. 18 | 19 | --- 20 | 21 | # TorGuard – Check My IP Torrent 22 | 23 | Get link from here: https://torguard.net/checkmytorrentipaddress.php 24 | 25 | In the magnet URL, replace `checkmyiptorrent+Tracking+Link` with `TorGuard%20<--->%20checkmyiptorrent`. 26 | 27 | --- 28 | 29 | # Troubleshooting 30 | 31 | ## UUID/GUID 32 | 33 | If you launch the Transmission container and cannot find any settings or download history, check the file/directory permissions of the Transmission directory `${config_dir}/transmission` on the host. It could be that you set your local username to be the owner of everything in that directory (a logical choice), but Transmission (especially when using Podman) expects the ownership to be `100999`. If that is the case, you may need to run `sudo chown -R 100999:100999 ${config_dir}/transmission` to fix the issue. -------------------------------------------------------------------------------- /stacks/downloaders/healthcheck.md: -------------------------------------------------------------------------------- 1 | # Check if Transmission is working 2 | */1 * * * * FQDN=etho201.duckdns.org; GOTIFY_TOKEN=APrH9XJORPIm0Qq; if [[ "$(curl -L -s -o /dev/null -w "%{http_code}" transmission.${FQDN})" == "404" ]]; then docker restart wireguard transmission qbittorrent && curl "https://gotify.${FQDN}/message?token=${GOTIFY_TOKEN}" -F "title=Transmission" -F "message=Restarted Transmission" -F "priority=5"; fi 3 | 4 | 5 | 6 | 7 | */1 * * * * 8 | FQDN=etho201.duckdns.org 9 | GOTIFY_TOKEN=APrH9XJORPIm0Qq 10 | 11 | ``` 12 | */1 * * * * sh test.sh -d etho201.duckdns.org -g APrH9XJORPIm0Qq 13 | ``` 14 | 15 | ```bash 16 | #!/bin/bash 17 | 18 | while getopts d:g: flag 19 | do 20 | case "${flag}" in 21 | d) FQDN=${OPTARG};; 22 | g) GOTIFY_TOKEN=${OPTARG};; 23 | esac 24 | done 25 | 26 | if [[ $(curl -L -s -o /dev/null -w "%{http_code}" transmission.${FQDN}) == "404" ]] 27 | then docker restart wireguard transmission qbittorrent && curl "https://gotify.${FQDN}/message?token=${GOTIFY_TOKEN}" -F "title=Transmission" -F "message=Restarted Transmission" -F "priority=5" 28 | fi 29 | ``` 30 | 31 | 32 | # Gotify 33 | 34 | FQDN=etho201.duckdns.org; GOTIFY_TOKEN=APrH9XJORPIm0Qq; curl "https://gotify.$FQDN/message?token=$GOTIFY_TOKEN" -F "title=Transmission" -F "message=Restarted Transmission" -F "priority=5" -------------------------------------------------------------------------------- /stacks/downloaders/healthcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 3 | 4 | while getopts t: flag 5 | do 6 | case "${flag}" in 7 | t) GOTIFY_TOKEN=${OPTARG};; 8 | esac 9 | done 10 | 11 | if [[ $(docker inspect wireguard -f '{{.State.Running}}' 2>/dev/null) == "false" || $(docker inspect wireguard -f '{{.State.Health.Status}}') == "unhealthy" ]]; then 12 | docker compose up -d --force-recreate wireguard transmission sabnzbd qbittorrent soulseek 13 | docker run --network=traefik --rm curlimages/curl "http://gotify/message?token=${GOTIFY_TOKEN}" -F "title=Wireguard" -F "message=Wireguard container found to be unhealthy. Successfully restarted the container!" -F "priority=5" 14 | fi 15 | -------------------------------------------------------------------------------- /stacks/home-assistant/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | services: 3 | 4 | ######################################################################################## 5 | # Home Assistant 6 | # https://www.home-assistant.io/installation/raspberrypi#docker-compose 7 | ######################################################################################## 8 | 9 | homeassistant: 10 | image: ghcr.io/home-assistant/home-assistant:stable 11 | container_name: homeassistant 12 | volumes: 13 | - ${CONFIG_DIR}/home-assistant:/config 14 | - ${VOLUME_DIR}/home-assistant:/media 15 | - /etc/localtime:/etc/localtime:ro 16 | # ports: 17 | # - 8123:8123 18 | restart: always 19 | privileged: true 20 | network_mode: host 21 | # devices: 22 | # - /dev/ttyUSB0:/dev/ttyUSB0 23 | 24 | zwavejs2mqtt: 25 | container_name: zwavejs2mqtt 26 | image: zwavejs/zwavejs2mqtt:latest 27 | restart: always 28 | tty: true 29 | stop_signal: SIGINT 30 | environment: 31 | - SESSION_SECRET=${ZWAVEJS2MQTT_SESSION_SECRET} 32 | - ZWAVEJS_EXTERNAL_CONFIG=/usr/src/app/store/.config-db 33 | - TZ=${TZ} 34 | networks: 35 | - traefik 36 | devices: 37 | # Do not use /dev/ttyUSBX serial devices, as those mappings can change over time. 38 | # Instead, use the /dev/serial/by-id/X serial device for your Z-Wave stick. 39 | - '/dev/serial/by-id/${ZWAVE_DEVICE_ID}:/dev/zwave' 40 | volumes: 41 | - ${CONFIG_DIR}/zwavejs2mqtt:/usr/src/app/store 42 | ports: 43 | - '3000:3000' # port for Z-Wave JS websocket server 44 | # - '8091:8091' # port for web interface 45 | labels: 46 | - "traefik.enable=true" 47 | ## HTTP Routers 48 | - "traefik.http.routers.zwavejs2mqtt-rtr.entrypoints=websecure" 49 | - "traefik.http.routers.zwavejs2mqtt-rtr.rule=Host(`zwavejs2mqtt.$FQDN`)" 50 | - "traefik.http.routers.zwavejs2mqtt-rtr.tls=true" 51 | ## Middlewares 52 | # - "traefik.http.routers.zwavejs2mqtt-rtr.middlewares=chain-no-auth@file" # No Authentication 53 | # - "traefik.http.routers.zwavejs2mqtt-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 54 | - "traefik.http.routers.zwavejs2mqtt-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 55 | ## HTTP Services 56 | - "traefik.http.routers.zwavejs2mqtt-rtr.service=zwavejs2mqtt-svc" 57 | - "traefik.http.services.zwavejs2mqtt-svc.loadbalancer.server.port=8091" 58 | 59 | ring-mqtt: 60 | container_name: ring-mqtt 61 | restart: always 62 | image: tsightler/ring-mqtt 63 | network_mode: host 64 | # networks: 65 | # - traefik 66 | # ports: 67 | # - 8554:8554 # Enable RTSP port for external media player access 68 | volumes: 69 | - ${VOLUME_DIR}/ring-mqtt:/data # Mapping of local folder to provide persistant storage 70 | environment: 71 | - RINGTOKEN=${RINGTOKEN} # Required for initial startup, see: https://github.com/tsightler/ring-mqtt/blob/main/docs/DOCKER.md#authentication 72 | - MQTTHOST=127.0.0.1 # Hostname or IP of MQTT Broker !! MUST UPDATE HOSTNAME IN config.json FILE AS WELL !! 73 | - MQTTPORT=1883 # TCP port for MQTT Broker 74 | - MQTTUSER=${USERNAME} # CHANGE ME -- Username for MQTT Broker (remove for anonymous) 75 | - MQTTPASSWORD=${MOSQUITTO_PASSWORD} # CHANGE ME -- Password for MQTT Broker (remove for anonymous) 76 | - ENABLECAMERAS=false # Enable camera support 77 | - SNAPSHOTMODE=disabled # Snapshot options (see: https://github.com/tsightler/ring-mqtt#snapshot-options) 78 | # - LIVESTREAMUSER=stream_user # CHANGE ME -- Highly recommended if RTSP server is exposed 79 | # - LIVESTREAMPASSWORD=stream_pass # CHANGE ME -- Highly recommended if RTSP server is exposed 80 | logging: #limit logs to 10m and 3 files 81 | options: 82 | max-size: 10m 83 | max-file: "3" 84 | 85 | mosquitto: 86 | image: eclipse-mosquitto 87 | container_name: mosquitto 88 | environment: 89 | - PUID=${PUID} 90 | - PGID=${PGID} 91 | - TZ=${TZ} 92 | - MOSQUITTO_USERNAME=${USERNAME} 93 | - MOSQUITTO_PASSWORD=${MOSQUITTO_PASSWORD} 94 | # ports: 95 | # - 1883:1883 96 | # - 8883:8883 97 | volumes: 98 | - ${VOLUME_DIR}/mosquitto/data:/mosquitto/data 99 | - ${VOLUME_DIR}/mosquitto/logs:/mosquitto/log 100 | - ${CONFIG_DIR}/mosquitto:/mosquitto/config 101 | restart: always 102 | # networks: 103 | # - traefik 104 | network_mode: host 105 | 106 | eufy-security-ws: 107 | container_name: eufy-security-ws 108 | restart: always 109 | image: bropat/eufy-security-ws 110 | # networks: 111 | # - traefik 112 | network_mode: host 113 | # ports: 114 | # - 3000:3000 115 | volumes: 116 | - ${VOLUME_DIR}/eufy-security-ws:/data # Mapping of local folder to provide persistant storage 117 | environment: 118 | - USERNAME=${EUFY_USERNAME} 119 | - PASSWORD=${EUFY_PASSWORD} 120 | - TRUSTED_DEVICE_NAME=${EUFY_TRUSTED_DEVICE} 121 | - PORT=3001 122 | 123 | rtsp-simple-server: 124 | container_name: rtsp-simple-server 125 | restart: always 126 | image: aler9/rtsp-simple-server:latest 127 | # networks: 128 | # - traefik 129 | network_mode: host 130 | # ports: 131 | # - 8554:8554 132 | # - 1935:1935 133 | environment: 134 | - RTSP_PROTOCOLS=tcp 135 | 136 | govee2mqtt: 137 | image: ghcr.io/wez/govee2mqtt:latest 138 | container_name: govee2mqtt 139 | restart: unless-stopped 140 | environment: 141 | - GOVEE_EMAIL=${GOVEE_EMAIL} 142 | - GOVEE_PASSWORD=${GOVEE_PASSWORD} 143 | # Optional, but recommended 144 | - GOVEE_API_KEY=${GOVEE_API_KEY} 145 | 146 | - GOVEE_MQTT_HOST=127.0.0.1 147 | - GOVEE_MQTT_PORT=1883 148 | # Uncomment if your mqtt broker requires authentication 149 | - GOVEE_MQTT_USER=${USERNAME} 150 | - GOVEE_MQTT_PASSWORD=${MOSQUITTO_PASSWORD} 151 | 152 | # Specify the temperature scale to use, either C for Celsius 153 | # or F for Farenheit 154 | - GOVEE_TEMPERATURE_SCALE=F 155 | # Always use colorized output 156 | - RUST_LOG_STYLE=always 157 | 158 | # If you are asked to set the debug level, uncomment the next line 159 | # - RUST_LOG=govee=trace 160 | 161 | # Set the timezone for timestamps in the log 162 | - TZ=${TZ} 163 | # Host networking is required 164 | network_mode: host 165 | 166 | esphome: 167 | container_name: esphome 168 | image: esphome/esphome:latest 169 | restart: always 170 | environment: 171 | - TZ=${TZ} 172 | networks: 173 | - traefik 174 | volumes: 175 | - ${CONFIG_DIR}/esphome:/config 176 | # ports: 177 | # - '6052:6052' 178 | labels: 179 | - "traefik.enable=true" 180 | ## HTTP Routers 181 | - "traefik.http.routers.esphome-rtr.entrypoints=websecure" 182 | - "traefik.http.routers.esphome-rtr.rule=Host(`esphome.$FQDN`)" 183 | - "traefik.http.routers.esphome-rtr.tls=true" 184 | ## Middlewares 185 | # - "traefik.http.routers.esphome-rtr.middlewares=chain-no-auth@file" # No Authentication 186 | # - "traefik.http.routers.esphome-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 187 | - "traefik.http.routers.esphome-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 188 | ## HTTP Services 189 | - "traefik.http.routers.esphome-rtr.service=esphome-svc" 190 | - "traefik.http.services.esphome-svc.loadbalancer.server.port=6052" 191 | 192 | networks: 193 | traefik: 194 | name: traefik 195 | external: true 196 | #run: docker network create traefik 197 | -------------------------------------------------------------------------------- /stacks/joplin-server/README.md: -------------------------------------------------------------------------------- 1 | # Joplin Server 2 | 3 | ## Info: 4 | 5 | Pre-release announcement: https://discourse.joplinapp.org/t/joplin-server-pre-release-is-now-available/13605 6 | 7 | Official GitHub Repo: https://github.com/laurent22/joplin/tree/dev/packages/server 8 | 9 | Docker images: 10 | - https://hub.docker.com/r/joplin/server 11 | - https://hub.docker.com/r/florider89/joplin-server 12 | 13 | ## Variables: 14 | 15 | List of required variables for Joplin Server: 16 | 17 | |Variable|Description|Required?| 18 | |--------|-----------|---------| 19 | | `FQDN` | Fully qualified domain name | Yes | 20 | | `VOLUME_DIR` | Location to store persistent data | Yes | 21 | | `JOPLIN_DB_PASS` | The password for the PostgreSQL Joplin Database | Yes | -------------------------------------------------------------------------------- /stacks/joplin-server/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: joplin-server 3 | services: 4 | joplin-server: 5 | image: etechonomy/joplin-server:latest 6 | container_name: joplin-server 7 | environment: 8 | - APP_BASE_URL=https://joplin.${FQDN} 9 | - APP_PORT=22300 10 | - POSTGRES_PASSWORD=${JOPLIN_DB_PASS} 11 | - POSTGRES_DATABASE=joplin 12 | - POSTGRES_USER=joplin 13 | - POSTGRES_PORT=5432 14 | - POSTGRES_HOST=joplin-db 15 | - DB_CLIENT=pg 16 | # ports: 17 | # - 22300:22300 18 | restart: always 19 | networks: 20 | - traefik 21 | labels: 22 | - "traefik.enable=true" 23 | ## HTTP Routers 24 | - "traefik.http.routers.joplin-rtr.entrypoints=websecure" 25 | - "traefik.http.routers.joplin-rtr.rule=Host(`joplin.$FQDN`)" 26 | - "traefik.http.routers.joplin-rtr.tls=true" 27 | ## Middlewares 28 | - "traefik.http.routers.joplin-rtr.middlewares=chain-no-auth@file" # No Authentication 29 | # - "traefik.http.routers.joplin-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 30 | # - "traefik.http.routers.joplin-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 31 | ## HTTP Services 32 | - "traefik.http.routers.joplin-rtr.service=joplin-svc" 33 | - "traefik.http.services.joplin-svc.loadbalancer.server.port=22300" 34 | 35 | joplin-db: 36 | image: postgres:16 # latest as of 1/27/2024 37 | container_name: joplin-db 38 | environment: 39 | - POSTGRES_PASSWORD=${JOPLIN_DB_PASS} 40 | - POSTGRES_USER=joplin 41 | - POSTGRES_DB=joplin 42 | # ports: 43 | # - 5432:5432 44 | volumes: 45 | - ${VOLUME_DIR}/joplin-data:/var/lib/postgresql/data 46 | restart: always 47 | networks: 48 | - traefik 49 | 50 | networks: 51 | traefik: 52 | name: traefik 53 | external: true 54 | #run: docker network create traefik 55 | -------------------------------------------------------------------------------- /stacks/owncloud-ocis/README.md: -------------------------------------------------------------------------------- 1 | # ownCloud OCIS 2 | 3 | 1. OCIS is still being developed, so if changes to the `ocis.yaml` file take place upstream, but not for your server, you may need to generate a new file and/or add environment variables that are missing. Check the [release notes](https://doc.owncloud.com/ocis_release_notes.html) for any breaking changes before upgrading. 4 | 5 | 2. Initialize the `ocis.yaml` file to see what's new. 6 | 7 | ```bash 8 | docker run --rm -it -v $(pwd):/etc/ocis/ owncloud/ocis:latest 9 | ``` 10 | 11 | 3. Check for new entries required in the `ocis.yaml` file. This can be done using the ocis cli: 12 | 13 | ```bash 14 | cd /etc/ocis 15 | ocis init --diff 16 | ``` 17 | 18 | 4. To recover your old accounts and files, simply merge everything from the deltas between the old and new configuration. 19 | 20 | ```bash 21 | patch < ocis.config.patch 22 | ``` 23 | 24 | 5. Update the ocis version in your `compose.yaml` file and recreate the container. 25 | 26 | --- 27 | 28 | ## Troubleshooting: 29 | 30 | 31 | ### Unexpected HTTP response: 500 32 | 33 | 1. If you try to login to OwnCloud and receive the error: "**Unexpected HTTP response: 500. Please check your connection and try again.**" This is probably due to an expired cert. You can confirm this by viewing the logs (may need to put the logging into `DEBUG` mode to see). 34 | 2. Within the logs, you may see issues such as: 35 | ```bash 36 | "ldap identifier backend logon connect error: LDAP Result Code 200 \"Network Error\": tls: failed to verify certificate: x509: certificate has expired or is not yet valid: current time 2025-03-25T20:51:42Z is after 2025-03-24T19:07:03Z" 37 | 38 | "remote error: tls: bad certificate" 39 | ``` 40 | 3. To fix this, kill the `owncloud` container. Then navigate to the `idm` directory and rename the `ldap.crt` and `ldap.key` files. 41 | ```bash 42 | cd ${VOLUME_DIR}/owncloud/idm 43 | mv ldap.crt ldap.crt.bak 44 | mv ldap.key ldap.key.bak 45 | ``` 46 | 4. Recreate owncloud 47 | ```bash 48 | docker compose up -d --force-recreate 49 | ``` 50 | 5. Check if you can login, and if so, go ahead and delete the old `ldap` (`*.bak`) files as they're no longer needed. 51 | 52 | --- 53 | 54 | ## Environment Variables: 55 | - https://doc.owncloud.com/ocis/next/deployment/services/s-list/search.html 56 | 57 | 58 | -------------------------------------------------------------------------------- /stacks/owncloud-ocis/compose.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: owncloud-ocis 3 | services: 4 | owncloud: 5 | image: owncloud/ocis:7 6 | container_name: owncloud 7 | volumes: 8 | - source: ${CONFIG_DIR}/owncloud/ocis.yaml 9 | target: /etc/ocis/ocis.yaml 10 | type: bind 11 | bind: 12 | create_host_path: false 13 | - ${VOLUME_DIR}/owncloud:/var/lib/ocis 14 | environment: 15 | #- PROXY_ENABLE_BASIC_AUTH=true # rclone 16 | - OCIS_INSECURE=false 17 | - PROXY_TLS=false 18 | - OCIS_URL=https://owncloud.${FQDN} 19 | - OCIS_LOG_LEVEL=info 20 | logging: 21 | driver: local 22 | networks: 23 | - traefik 24 | # ports: 25 | # - 9200:9200 26 | restart: always 27 | labels: 28 | - "traefik.enable=true" 29 | ## HTTP Routers 30 | - "traefik.http.routers.owncloud-rtr.entrypoints=websecure" 31 | - "traefik.http.routers.owncloud-rtr.rule=Host(`owncloud.$FQDN`)" 32 | - "traefik.http.routers.owncloud-rtr.tls=true" 33 | ## Middlewares 34 | - "traefik.http.routers.owncloud-rtr.middlewares=chain-no-auth@file" # No Authentication 35 | # - "traefik.http.routers.owncloud-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 36 | # - "traefik.http.routers.owncloud-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 37 | ## HTTP Services 38 | - "traefik.http.routers.owncloud-rtr.service=owncloud-svc" 39 | - "traefik.http.services.owncloud-svc.loadbalancer.server.port=9200" 40 | 41 | networks: 42 | traefik: 43 | name: traefik 44 | external: true 45 | #run: docker network create traefik 46 | -------------------------------------------------------------------------------- /stacks/paperless-ngx/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3.7' 3 | 4 | name: paperless 5 | services: 6 | 7 | paperless-broker: 8 | image: docker.io/library/redis:7 9 | container_name: paperless-broker 10 | restart: unless-stopped 11 | volumes: 12 | - ${VOLUME_DIR}/paperless/redisdata:/data 13 | networks: 14 | - traefik 15 | 16 | paperless-db: 17 | image: container-registry.oracle.com/mysql/community-server:8.3-aarch64 18 | container_name: paperless-db 19 | restart: unless-stopped 20 | volumes: 21 | - type: bind 22 | source: ${CONFIG_DIR}/paperless/database/my.cnf 23 | target: /etc/my.cnf 24 | - ${VOLUME_DIR}/paperless/database:/var/lib/mysql 25 | command: 26 | - --character-set-server=utf8mb3 27 | environment: 28 | - TZ=${TZ} 29 | - MYSQL_DATABASE=paperless 30 | - MYSQL_ROOT_PASSWORD=${PAPERLESS_DB_ROOT_PW} 31 | - MYSQL_ROOT_HOST=paperless.traefik 32 | # - COLLATION-SERVER=utf8mb4_bin 33 | # - MYSQL_USER=paperless 34 | # - MYSQL_PASSWORD=${PAPERLESS_DB_PW} 35 | # ports: 36 | # - 3306:3306 37 | networks: 38 | - traefik 39 | 40 | paperless: 41 | image: ghcr.io/paperless-ngx/paperless-ngx:latest 42 | container_name: paperless 43 | restart: unless-stopped 44 | depends_on: 45 | - paperless-db 46 | - paperless-broker 47 | # ports: 48 | # - "8000:8000" 49 | volumes: 50 | - ${VOLUME_DIR}/paperless/data:/usr/src/paperless/data 51 | - ${VOLUME_DIR}/paperless/media:/usr/src/paperless/media 52 | - ${CONFIG_DIR}/paperless/export:/usr/src/paperless/export 53 | - ${CONFIG_DIR}/paperless/consume:/usr/src/paperless/consume 54 | environment: 55 | PAPERLESS_REDIS: redis://paperless-broker.traefik:6379 56 | PAPERLESS_DBENGINE: mariadb 57 | PAPERLESS_DBHOST: paperless-db 58 | PAPERLESS_DBUSER: root # only needed if non-default username 59 | PAPERLESS_DBPASS: ${PAPERLESS_DB_ROOT_PW} # only needed if non-default password 60 | PAPERLESS_DBPORT: 3306 61 | PAPERLESS_SECRET_KEY: ${PAPERLESS_SECRET_KEY} # Set using "openssl rand -base64 48" 62 | PAPERLESS_URL: https://paperless.${FQDN} 63 | PAPERLESS_TIME_ZONE: ${TZ} 64 | PAPERLESS_OCR_LANGUAGE: eng 65 | USERMAP_UID: ${PUID} 66 | USERMAP_GID: ${PGID} 67 | PAPERLESS_ADMIN_USER: ${USERNAME} 68 | PAPERLESS_ADMIN_PASSWORD: ${PAPERLESS_ADMIN_PASSWORD} 69 | PAPERLESS_ADMIN_MAIL: ${EMAIL} 70 | PAPERLESS_OCR_DESKEW: false 71 | networks: 72 | - traefik 73 | labels: 74 | - "traefik.enable=true" 75 | ## HTTP Routers 76 | - "traefik.http.routers.paperless-rtr.entrypoints=websecure" 77 | - "traefik.http.routers.paperless-rtr.rule=Host(`paperless.$FQDN`)" 78 | - "traefik.http.routers.paperless-rtr.tls=true" 79 | ## Middlewares 80 | - "traefik.http.routers.paperless-rtr.middlewares=chain-no-auth@file" # No Authentication 81 | # - "traefik.http.routers.paperless-rtr.middlewares=chain-basic-auth@file" # Basic Authentication 82 | # - "traefik.http.routers.paperless-rtr.middlewares=chain-oauth2-proxy@file" # OAuth 2.0 83 | ## HTTP Services 84 | - "traefik.http.routers.paperless-rtr.service=paperless-svc" 85 | - "traefik.http.services.paperless-svc.loadbalancer.server.port=8000" 86 | 87 | networks: 88 | traefik: 89 | name: traefik 90 | external: true 91 | #run: docker network create traefik 92 | -------------------------------------------------------------------------------- /stacks/unifi-network-application/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: unifi-network-application 3 | services: 4 | 5 | ######################################################################################## 6 | # Unifi Controller 7 | # https://hub.docker.com/r/linuxserver/unifi-controller 8 | ######################################################################################## 9 | 10 | unifi-db: 11 | image: docker.io/mongo:7.0 12 | container_name: unifi-db 13 | volumes: 14 | - ${VOLUME_DIR}/unifi-network-application/db:/data/db #Data dir grows to 250MB+ 15 | - source: ${VOLUME_DIR}/unifi-network-application/init-mongo.js 16 | target: /docker-entrypoint-initdb.d/init-mongo.js 17 | type: bind 18 | bind: 19 | create_host_path: false 20 | restart: unless-stopped 21 | networks: 22 | - traefik 23 | 24 | unifi-network-application: 25 | image: lscr.io/linuxserver/unifi-network-application:latest 26 | container_name: unifi-network-application 27 | environment: 28 | - PUID=${PUID} 29 | - PGID=${PGID} 30 | - TZ=${TZ} 31 | - MONGO_USER=unifi 32 | - MONGO_PASS=${UNIFI_MONGO_PASS} 33 | - MONGO_HOST=unifi-db 34 | - MONGO_PORT=27017 35 | - MONGO_DBNAME=unifi 36 | - MEM_LIMIT=1024 #optional 37 | - MEM_STARTUP=1024 #optional 38 | # - MONGO_TLS= #optional 39 | # - MONGO_AUTHSOURCE= #optional 40 | volumes: 41 | - ${CONFIG_DIR}/unifi-network-application:/config #Config 42 | ports: 43 | # - 8443:8443 44 | - 3478:3478/udp # For STUN 45 | # - 10001:10001/udp 46 | - 8080:8080 47 | # - 1900:1900/udp #optional 48 | # - 8843:8843 #optional 49 | # - 8880:8880 #optional 50 | # - 6789:6789 #optional 51 | # - 5514:5514/udp #optional 52 | restart: unless-stopped 53 | networks: 54 | - traefik 55 | labels: 56 | # https://github.com/containous/traefik/issues/5783 (--serverstransport.insecureskipverify=true) 57 | # https://community.containo.us/t/problem-using-ssl-backend-with-selfsigned-certificates/1974 58 | # Traefik Configuration 59 | - "traefik.enable=true" 60 | ## HTTP Routers 61 | - "traefik.http.routers.unifi-controller-rtr.entrypoints=websecure" 62 | - "traefik.http.routers.unifi-controller-rtr.rule=Host(`unifi.${FQDN}`)" 63 | - "traefik.http.routers.unifi-controller-rtr.tls=true" 64 | ## Middlewares 65 | - "traefik.http.routers.unifi-controller-rtr.middlewares=chain-no-auth@file" # No Authentication 66 | ## HTTP Services 67 | - "traefik.http.routers.unifi-controller-rtr.service=unifi-controller-svc" 68 | - "traefik.http.services.unifi-controller-svc.loadbalancer.server.port=8443" 69 | - "traefik.http.services.unifi-controller-svc.loadbalancer.server.scheme=https" # IMPORTANT! This is required for the Unifi Controller! 70 | 71 | networks: 72 | traefik: 73 | name: traefik 74 | external: true 75 | #run: docker network create traefik 76 | --------------------------------------------------------------------------------