diff --git a/Dockerfile b/Dockerfile index 176fb9d..27d99bd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ FROM ${FROM_SOURCE} RUN apk add --no-cache py3-pip py3-pillow py3-cffi py3-brotli gcc musl-dev python3-dev pango build-base libffi-dev jpeg-dev libxslt-dev RUN pip install \ + beautifulsoup4==4.9.3 \ mkdocs-autolinks-plugin \ mkdocs-htmlproofer-plugin \ mkdocs-git-revision-date-localized-plugin \ diff --git a/manuscript/premix/index.md b/manuscript/premix/index.md index f19d051..30e8fc9 100644 --- a/manuscript/premix/index.md +++ b/manuscript/premix/index.md @@ -1,3 +1,6 @@ +--- +title: Pre-made ansible playbooks to deploy our self-hosted recipes +--- # Premix Repository "Premix" is a private repository shared with [GitHub sponsors](https://github.com/sponsors/funkypenguin), which contains the necessary files and automation to quickly deploy any recipe, or even an entire [swarm](/docker-swarm/) / [cluster](/kubernetes/)! :muscle: diff --git a/manuscript/recipes/archivebox.md b/manuscript/recipes/archivebox.md index 46f1a25..bd8b6a2 100644 --- a/manuscript/recipes/archivebox.md +++ b/manuscript/recipes/archivebox.md @@ -1,5 +1,5 @@ --- -description: A self-hosted internet archiving solution +title: Archivebox - bookmark manager for your self-hosted stack --- # Archivebox diff --git a/manuscript/recipes/bookstack.md b/manuscript/recipes/bookstack.md index 0c60290..26f44ea 100644 --- a/manuscript/recipes/bookstack.md +++ b/manuscript/recipes/bookstack.md @@ -1,5 +1,5 @@ --- -title: Run linuxserver bookstack in Docker +title: How to run BookStack in Docker description: BookStack is a simple, self-hosted, easy-to-use platform for organising and storing information. Here's how to integrate linuxserver's bookstack image into your Docker Swarm stack. --- diff --git a/manuscript/recipes/duplicati.md b/manuscript/recipes/duplicati.md index 832f79d..4c59811 100644 --- a/manuscript/recipes/duplicati.md +++ b/manuscript/recipes/duplicati.md @@ -1,5 +1,6 @@ --- -description: Duplicati - Yet another option to backup your exciting stuff. It's good to have options. +title: Use Duplicati in Docker to backup to backblaze / b2 and friends +description: Duplicati - Yet another boring option to backup your exciting stuff, especially to Backblaze / B2 - It's good to have options. --- # Duplicati diff --git a/manuscript/recipes/duplicity.md b/manuscript/recipes/duplicity.md index f3de483..06d0fdc 100644 --- a/manuscript/recipes/duplicity.md +++ b/manuscript/recipes/duplicity.md @@ -1,4 +1,5 @@ --- +title: Use Duplicity in Docker to backup to backblaze / b2 and friends description: A boring recipe to backup your exciting stuff. Boring is good. --- diff --git a/manuscript/recipes/elkarbackup.md b/manuscript/recipes/elkarbackup.md index f6c3bac..906eeed 100644 --- a/manuscript/recipes/elkarbackup.md +++ b/manuscript/recipes/elkarbackup.md @@ -1,5 +1,6 @@ --- -description: Real heroes backup their shizz! +title: Use elkarbackup in Docker to backup to backblaze / b2 and friends +description: ElkarBackup is a free open-source backup solution based on RSync/RSnapshot. It's basically a web wrapper around rsync/rsnapshot, which means that your backups are just files on a filesystem, utilising hardlinks for tracking incremental changes. --- # Elkar Backup diff --git a/manuscript/recipes/ghost.md b/manuscript/recipes/ghost.md index 6943437..311c356 100644 --- a/manuscript/recipes/ghost.md +++ b/manuscript/recipes/ghost.md @@ -1,5 +1,6 @@ --- -description: Ghost - Beautiful online publicatio (who you gonna call?) +title: Blog with Ghost in Docker +description: How to run the beautiful, publication-focused blogging engine "Ghost" using Docker --- # Ghost diff --git a/manuscript/recipes/gitlab-runner.md b/manuscript/recipes/gitlab-runner.md index 13b714d..bb2af54 100644 --- a/manuscript/recipes/gitlab-runner.md +++ b/manuscript/recipes/gitlab-runner.md @@ -1,5 +1,5 @@ --- -description: Gitlab Runner - A gopher for GitLab +title: How to run Gitlab Runner in Docker --- # Gitlab Runner diff --git a/manuscript/recipes/gitlab.md b/manuscript/recipes/gitlab.md index 177f5ef..ba999d2 100644 --- a/manuscript/recipes/gitlab.md +++ b/manuscript/recipes/gitlab.md @@ -1,3 +1,6 @@ +--- +title: How to run Gitlab in Docker +--- # GitLab GitLab is a self-hosted [alternative to GitHub](https://about.gitlab.com/pricing/self-managed/feature-comparison/). The most common use case is (a set of) developers with the desire for the rich feature-set of GitHub, but with unlimited private repositories. diff --git a/manuscript/recipes/gollum.md b/manuscript/recipes/gollum.md index 7996b88..0c93f2b 100644 --- a/manuscript/recipes/gollum.md +++ b/manuscript/recipes/gollum.md @@ -1,5 +1,5 @@ --- -description: Gollum - A recipe for your own git-based wiki. My preciousssss +title: Run Gollum in Docker --- # Gollum diff --git a/manuscript/recipes/huginn.md b/manuscript/recipes/huginn.md index 2239ee7..2d194f2 100644 --- a/manuscript/recipes/huginn.md +++ b/manuscript/recipes/huginn.md @@ -1,5 +1,5 @@ --- -description: A self-hosted, hackable version of IFFTT / Zapier +title: Run Huggin in Docker --- # Huginn diff --git a/manuscript/recipes/instapy.md b/manuscript/recipes/instapy.md index 93faf2c..9d233ee 100644 --- a/manuscript/recipes/instapy.md +++ b/manuscript/recipes/instapy.md @@ -1,5 +1,6 @@ --- -description: Automate your fake Instagram life with automated fakery! +title: How to run InstaPy in Docker +description: Automate your fake Instagram life with automated fakery using InstaPy in Docker --- # InstaPy diff --git a/manuscript/recipes/ipfs-cluster.md b/manuscript/recipes/ipfs-cluster.md index 4c4e75f..95b1b5e 100644 --- a/manuscript/recipes/ipfs-cluster.md +++ b/manuscript/recipes/ipfs-cluster.md @@ -1,3 +1,7 @@ +--- +title: How to build an IPFS cluster in Docker +description: IPFS is a peer-to-peer distributed file system that seeks to connect all computing devices with the same system of files. In some ways, IPFS is similar to the World Wide Web, but IPFS could be seen as a single BitTorrent swarm, exchanging objects within one Git repository. +--- # IPFS !!! danger "This recipe is a work in progress" @@ -8,7 +12,7 @@ The intention of this recipe is to provide a local IPFS cluster for the purpose { loading=lazy } -Description. IPFS is a peer-to-peer distributed file system that seeks to connect all computing devices with the same system of files. In some ways, IPFS is similar to the World Wide Web, but IPFS could be seen as a single BitTorrent swarm, exchanging objects within one Git repository. +IPFS is a peer-to-peer distributed file system that seeks to connect all computing devices with the same system of files. In some ways, IPFS is similar to the World Wide Web, but IPFS could be seen as a single BitTorrent swarm, exchanging objects within one Git repository. ## Ingredients diff --git a/manuscript/recipes/kanboard.md b/manuscript/recipes/kanboard.md index c6dd7fd..966d057 100644 --- a/manuscript/recipes/kanboard.md +++ b/manuscript/recipes/kanboard.md @@ -1,5 +1,6 @@ --- -description: Get your personal kanban on! +title: How to run Kanboard using Docker +description: Run Kanboard with Docker to get your personal kanban on! --- # Kanboard diff --git a/manuscript/recipes/keycloak/authenticate-against-openldap.md b/manuscript/recipes/keycloak/authenticate-against-openldap.md index aea3136..1ff3c7d 100644 --- a/manuscript/recipes/keycloak/authenticate-against-openldap.md +++ b/manuscript/recipes/keycloak/authenticate-against-openldap.md @@ -1,3 +1,7 @@ +--- +title: Integrate LDAP server with Keycloak for user federation +description: Here's how we'll add an LDAP provider to our KeyCloak server for user federation. +--- # Authenticate KeyCloak against OpenLDAP !!! warning diff --git a/manuscript/recipes/keycloak/create-user.md b/manuscript/recipes/keycloak/create-user.md index c67af71..931b5ab 100644 --- a/manuscript/recipes/keycloak/create-user.md +++ b/manuscript/recipes/keycloak/create-user.md @@ -1,4 +1,8 @@ -# Create KeyCloak Users +--- +title: Create users in Keycloak +description: Unless you plan to authenticate against an outside provider (OpenLDAP, below, for example_), you'll want to create some local users.. +--- +# Create Keycloak Users !!! warning This is not a complete recipe - it's an optional component of the [Keycloak recipe](/recipes/keycloak/), but has been split into its own page to reduce complexity. diff --git a/manuscript/recipes/keycloak/index.md b/manuscript/recipes/keycloak/index.md index 11000ad..e766b74 100644 --- a/manuscript/recipes/keycloak/index.md +++ b/manuscript/recipes/keycloak/index.md @@ -1,4 +1,5 @@ --- +title: How to setup OIDC server in Docker with KeyCloak description: Kick-ass OIDC and identity management --- diff --git a/manuscript/recipes/keycloak/setup-oidc-provider.md b/manuscript/recipes/keycloak/setup-oidc-provider.md index d56d50a..6693bff 100644 --- a/manuscript/recipes/keycloak/setup-oidc-provider.md +++ b/manuscript/recipes/keycloak/setup-oidc-provider.md @@ -1,3 +1,7 @@ +--- +title: How to setup OIDC provider in KeyCloak +description: Having an authentication provider is not much use until you start authenticating things against it! In order to authenticate against KeyCloak using OpenID Connect (OIDC), which is required for Traefik Forward Auth, we'll setup a client in KeyCloak... +--- # Add OIDC Provider to KeyCloak !!! warning diff --git a/manuscript/recipes/komga.md b/manuscript/recipes/komga.md index 539d255..be34b88 100644 --- a/manuscript/recipes/komga.md +++ b/manuscript/recipes/komga.md @@ -1,5 +1,6 @@ --- -description: Bazinga! Comic book management FTW! +title: How to run Komga with Docker +description: Run Komga under Docker Swarm in docker-compose syntax --- # Komga diff --git a/manuscript/recipes/mail.md b/manuscript/recipes/mail.md index a4e2760..af2bdff 100644 --- a/manuscript/recipes/mail.md +++ b/manuscript/recipes/mail.md @@ -1,5 +1,6 @@ --- -description: A self-contained mailserver with spam-fighting friends +title: Run postfix / dovecot with docker-mailserver +description: A self-contained mailserver (postfix, dovecot) in Docker with spam-fighting friends (spamassassin, clamav) --- # Mail Server diff --git a/manuscript/recipes/miniflux.md b/manuscript/recipes/miniflux.md index 4b60da1..4a87198 100644 --- a/manuscript/recipes/miniflux.md +++ b/manuscript/recipes/miniflux.md @@ -1,5 +1,5 @@ --- -description: A lightweight minimalist RSS reader +title: Read RSS in peace with miniflux on Docker --- # Miniflux diff --git a/manuscript/recipes/minio.md b/manuscript/recipes/minio.md index f5282f8..955533a 100644 --- a/manuscript/recipes/minio.md +++ b/manuscript/recipes/minio.md @@ -1,5 +1,6 @@ --- -description: Self-hosted S3-compatible object storage +title: Run Minio on Docker (using compose format in swarm) +description: How to run Minio's self-hosted S3-compatible object storage under Docker Swarm, using docker-compose v3 syntax --- # Minio diff --git a/manuscript/recipes/nextcloud.md b/manuscript/recipes/nextcloud.md index bef6b78..0c5dd52 100644 --- a/manuscript/recipes/nextcloud.md +++ b/manuscript/recipes/nextcloud.md @@ -1,5 +1,6 @@ --- -description: Share docs. Backup files. Share stuff. +title: How to run Nextcloud in Docker (behind Traefik) +description: We can now run Nextcloud in our Docker Swarm, with LetsEncrypt SSL termination handled by Traefik --- # NextCloud diff --git a/manuscript/recipes/openldap.md b/manuscript/recipes/openldap.md index 26aa5bf..8de8217 100644 --- a/manuscript/recipes/openldap.md +++ b/manuscript/recipes/openldap.md @@ -1,5 +1,6 @@ --- -description: Authenticate like it's 1990! +title: Run OpenLDAP in Docker +description: How to run an OpenLDAP server in Docker Swarm, with LDAP Account Manager. Authenticate like it's 1990! --- # OpenLDAP diff --git a/manuscript/recipes/owntracks.md b/manuscript/recipes/owntracks.md index b2b4e92..55db8d7 100644 --- a/manuscript/recipes/owntracks.md +++ b/manuscript/recipes/owntracks.md @@ -1,5 +1,5 @@ --- -description: Spy on yourself. +title: Run OwnTracks under Docker --- # OwnTracks diff --git a/manuscript/recipes/paperless-ng.md b/manuscript/recipes/paperless-ng.md index e5be99f..f52dd56 100644 --- a/manuscript/recipes/paperless-ng.md +++ b/manuscript/recipes/paperless-ng.md @@ -1,8 +1,9 @@ --- -description: Easily index, search, and view archive all of your scanned dead-tree documents +title: Run paperless-ngx under Docker +description: Easily index, search, and view archive all of your scanned dead-tree documents with Paperless NGX, under Docker --- -# Paperless NG +# Paperless NGX Paper is a nightmare. Environmental issues aside, there’s no excuse for it in the 21st century. It takes up space, collects dust, doesn’t support any form of a search feature, indexing is tedious, it’s heavy and prone to damage & loss. [^1] Paperless NG will OCR, index, and store data about your documents so they are easy to search and view, unlike that hulking metal file cabinet you have in your office. diff --git a/manuscript/recipes/phpipam.md b/manuscript/recipes/phpipam.md index 1954132..3c4e77e 100644 --- a/manuscript/recipes/phpipam.md +++ b/manuscript/recipes/phpipam.md @@ -1,5 +1,6 @@ --- -description: Is that IP address in use? +title: Run phpIPAM under Docker +description: Is that IP address in use? Do some DHP / Discovery with phpIPAM under Docker --- # phpIPAM diff --git a/manuscript/recipes/portainer.md b/manuscript/recipes/portainer.md index b7a3594..715477e 100644 --- a/manuscript/recipes/portainer.md +++ b/manuscript/recipes/portainer.md @@ -1,5 +1,6 @@ --- -description: A UI to make Docker less geeky +title: Run Portainer in Docker Swarm (now with Dark Mode!) +description: Portainer is a UI to make Docker less geeky, runs under Docker Swarm (and Kubernetes!) and most importantly, now supports dark mode! --- # Portainer diff --git a/manuscript/recipes/realms.md b/manuscript/recipes/realms.md index 86975cb..b285279 100644 --- a/manuscript/recipes/realms.md +++ b/manuscript/recipes/realms.md @@ -1,4 +1,5 @@ --- +title: Realms is a git-based wiki, and it runs under Docker! description: A git-based wiki with auth and registration --- diff --git a/manuscript/recipes/wallabag.md b/manuscript/recipes/wallabag.md index 7f96339..693d0ff 100644 --- a/manuscript/recipes/wallabag.md +++ b/manuscript/recipes/wallabag.md @@ -1,5 +1,5 @@ --- -description: Read-it-later, mate! +title: Run Wallabag under Docker (compose), mate! --- # Wallabag diff --git a/manuscript/recipes/wekan.md b/manuscript/recipes/wekan.md index 8b86ab2..442ab9c 100644 --- a/manuscript/recipes/wekan.md +++ b/manuscript/recipes/wekan.md @@ -1,5 +1,5 @@ --- -description: A self-hosted Trello +title: Run Wekan under Docker --- # Wekan diff --git a/manuscript/recipes/wetty.md b/manuscript/recipes/wetty.md index 77680a1..a5bf8d4 100644 --- a/manuscript/recipes/wetty.md +++ b/manuscript/recipes/wetty.md @@ -1,5 +1,6 @@ --- -description: Terminal in a browser, baby! +title: Use wetty under Docker for SSH in the browser +description: Use weTTY to run a terminal in a browser, baby! --- # Wetty diff --git a/mkdocs copy.yml b/mkdocs copy.yml new file mode 100644 index 0000000..e07aa7f --- /dev/null +++ b/mkdocs copy.yml @@ -0,0 +1,405 @@ +site_name: Funky Penguin's Geek Cookbook +site_description: 'The Geek Cookbook is a collection of guides for establishing your own highly-available docker container cluster (swarm). This swarm enables you to run self-hosted services such as GitLab, Plex, NextCloud, etc.' +site_author: 'David Young' +site_url: 'https://geek-cookbook.funkypenguin.co.nz' +edit_uri: 'edit/master/manuscript/' + +# Fail to build if we have broken links +# strict: true + +# Repository +repo_name: 'geek-cookbook' +repo_url: 'https://github.com/geek-cookbook/geek-cookbook' + +# Set this to "manuscript" so that we can produce leanpub content +docs_dir: 'manuscript' + +# Copyright +copyright: 'Copyright © 2016 - 2021 David Young, Funky Penguin Limited' + +# Plugins +plugins: + privacy: + search: + minify: + minify_html: true + git-revision-date-localized: + type: date + autolinks: + macros: + verbose: true + # htmlproofer: + # raise_error: True + # raise_error_excludes: + # 504: ['https://www.mkdocs.org/'] + # 404: ['https://github.com/manuzhang/mkdocs-htmlproofer-plugin'] + # 400: ['*'] + git-committers: + repository: geek-cookbook/geek-cookbook + token: !ENV GH_TOKEN + meta-descriptions: # If not provided, auto-generate a description (https://pypi.org/project/mkdocs-meta-descriptions-plugin/) + +#theme_dir: mkdocs-material +nav: + - Home: index.md + - Docker Swarm: + - docker-swarm/index.md + - Preparation: + - Design: docker-swarm/design.md + - Nodes: docker-swarm/nodes.md + - Shared Storage (Ceph): docker-swarm/shared-storage-ceph.md + - Shared Storage (GlusterFS): docker-swarm/shared-storage-gluster.md + - Keepalived: docker-swarm/keepalived.md + - Docker Swarm Mode: docker-swarm/docker-swarm-mode.md + - Traefik: docker-swarm/traefik.md + - Traefik Forward Auth: + - docker-swarm/traefik-forward-auth/index.md + - Dex (static): docker-swarm/traefik-forward-auth/dex-static.md + - Google: docker-swarm/traefik-forward-auth/google.md + - KeyCloak: docker-swarm/traefik-forward-auth/keycloak.md + - Authelia: docker-swarm/authelia.md + - Registry: docker-swarm/registry.md + - Mail Server: recipes/mail.md + - Duplicity: recipes/duplicity.md + - Chef's Favorites: + - Auto Pirate: + - recipes/autopirate/index.md + - Headphones: recipes/autopirate/headphones.md + - Heimdall: recipes/autopirate/heimdall.md + - Jackett: recipes/autopirate/jackett.md + - Lazy Librarian: recipes/autopirate/lazylibrarian.md + - Lidarr: recipes/autopirate/lidarr.md + - Mylar: recipes/autopirate/mylar.md + - NZBGet: recipes/autopirate/nzbget.md + - NZBHydra: recipes/autopirate/nzbhydra.md + - Prowlarr: recipes/autopirate/prowlarr.md + - Ombi: recipes/autopirate/ombi.md + - Radarr: recipes/autopirate/radarr.md + - Readarr: recipes/autopirate/readarr.md + - Rtorrent: recipes/autopirate/rtorrent.md + - SABnzbd: recipes/autopirate/sabnzbd.md + - Sonarr: recipes/autopirate/sonarr.md + - End: recipes/autopirate/end.md + - Emby: recipes/emby.md + - Home Assistant: recipes/homeassistant.md + - Huginn: recipes/huginn.md + - Jellyfin: recipes/jellyfin.md + - Kanboard: recipes/kanboard.md + - KeyCloak: + - recipes/keycloak/index.md + - Users: recipes/keycloak/create-user.md + - OIDC Provider: recipes/keycloak/setup-oidc-provider.md + - OpenLDAP: recipes/keycloak/authenticate-against-openldap.md + - Miniflux: recipes/miniflux.md + - Munin: recipes/munin.md + - NextCloud: recipes/nextcloud.md + - phpIPAM: recipes/phpipam.md + - Plex: recipes/plex.md + - Portainer: recipes/portainer.md + - PrivateBin: recipes/privatebin.md + - Restic: recipes/restic.md + - Swarmprom: recipes/swarmprom.md + - Recipes: + - Archive Box: recipes/archivebox.md + - Bitwarden: recipes/bitwarden.md + - Bookstack: recipes/bookstack.md + - Calibre-Web: recipes/calibre-web.md + - Collabora Online: recipes/collabora-online.md + - CyberChef: recipes/cyberchef.md + - Duplicati: recipes/duplicati.md + - ElkarBackup: recipes/elkarbackup.md + - Funkwhale: recipes/funkwhale.md + - Ghost: recipes/ghost.md + - GitLab: recipes/gitlab.md + - GitLab Runner: recipes/gitlab-runner.md + - Gollum: recipes/gollum.md + - InstaPy: recipes/instapy.md + - KeyCloak: + - recipes/keycloak/index.md + - Users: recipes/keycloak/create-user.md + - OIDC Provider: recipes/keycloak/setup-oidc-provider.md + - OpenLDAP: recipes/keycloak/authenticate-against-openldap.md + - Komga: recipes/komga.md + - Linx: recipes/linx.md + - Mealie: recipes/mealie.md + - Minio: recipes/minio.md + - NightScout: recipes/nightscout.md + - OpenLDAP: recipes/openldap.md + - OwnTracks: recipes/owntracks.md + - Photoprism: recipes/photoprism.md + - Paperless NG: recipes/paperless-ng.md + - Portainer: recipes/portainer.md + - Realms: recipes/realms.md + - Restic: recipes/restic.md + - RSS Bridge: recipes/rss-bridge.md + - Tiny Tiny RSS: recipes/tiny-tiny-rss.md + - Traefik: docker-swarm/traefik.md + - Traefik Forward Auth: + - docker-swarm/traefik-forward-auth/index.md + - Dex (static): docker-swarm/traefik-forward-auth/dex-static.md + - Google: docker-swarm/traefik-forward-auth/google.md + - KeyCloak: docker-swarm/traefik-forward-auth/keycloak.md + - Wallabag: recipes/wallabag.md + - Wekan: recipes/wekan.md + - Wetty: recipes/wetty.md + - Reference: + - OAuth Proxy: reference/oauth_proxy.md + - Data Layout: reference/data_layout.md + - Networks: reference/networks.md + - OpenVPN : reference/openvpn.md + - Troubleshooting: reference/troubleshooting.md + - ⛴ Kubernetes: + - Preparation: + - kubernetes/index.md + - Introduction: kubernetes/index.md + - Cluster: + - kubernetes/cluster/index.md + - Digital Ocean: kubernetes/cluster/digitalocean.md + # - Bare Metal: kubernetes/cluster/baremetal.md + # - Home Lab: kubernetes/cluster/baremetal.md + - k3s: kubernetes/cluster/k3s.md + # - The Hard Way: kubernetes/cluster/the-hard-way.md + - Deployment: + - kubernetes/deployment/index.md + # - YAML: kubernetes/wip.md + # - Helm: kubernetes/wip.md + # - GitHub Actions: kubernetes/wip.md + - Flux: + - kubernetes/deployment/flux/index.md + - Install: kubernetes/deployment/flux/install.md + - Design: kubernetes/deployment/flux/design.md + - Operate: kubernetes/deployment/flux/operate.md + - Essentials: + - Load Balancer: + - kubernetes/loadbalancer/index.md + - k3s: kubernetes/loadbalancer/k3s.md + - MetalLB: + - kubernetes/loadbalancer/metallb/index.md + - pfSense: kubernetes/loadbalancer/metallb/pfsense.md + - Sealed Secrets: kubernetes/sealed-secrets.md + - External DNS: kubernetes/external-dns.md + - SSL Certificates: + - kubernetes/ssl-certificates/index.md + - Cert-Manager: kubernetes/ssl-certificates/cert-manager.md + - LetsEncrypt Issuers: kubernetes/ssl-certificates/letsencrypt-issuers.md + - Wildcard Certificate: kubernetes/ssl-certificates/wildcard-certificate.md + - Secret Replicator: kubernetes/ssl-certificates/secret-replicator.md + - Ingress: + - kubernetes/ingress/index.md + - Traefik: + - kubernetes/ingress/traefik/index.md + # - Dashboard: kubernetes/ingress/traefik/dashboard.md + - Nginx: kubernetes/ingress/nginx.md + - Persistence: + - kubernetes/persistence/index.md + - Local Path Provisioner: kubernetes/persistence/local-path-provisioner.md + - TopoLVM: kubernetes/persistence/topolvm.md + # - Rook Ceph: kubernetes/persistence/rook-ceph.md + # - OpenEBS: kubernetes/persistence/openebs.md + # - LongHorn: kubernetes/persistence/longhorn.md + # - Backup: + # - kubernetes/backup/index.md + # - kubernetes/wip.md + # - Logging: + # - fluent-bit, graylog, etc. + + + # - Monitoring: + # - kubernetes/monitoring/index.md + # - Prometheus: kubernetes/wip.md + # - Grafana: kubernetes/wip.md + # - AlertManager: kubernetes/wip.md + # - Goldilocks: kubernetes/wip.md + # - Reloader: kubernetes/wip.md + # - Dashboard: kubernetes/wip.md + # - Kured: kubernetes/wip.md + # - KeyCloak: kubernetes/wip.md + # - Recipes: + # - Harbor: + # - recipes/kubernetes/harbor/index.md + # Istio: recipes/kubernetes/harbor/istio.md + # - GitHub Actions Runners: kubernetes/wip.md + # - Cilium: kubernetes/wip.md + # - Concourse: kubernetes/wip.md + # - Flagger: kubernetes/wip.md + # - Flagger: kubernetes/wip.md + # - Flux: recipes/kubernetes/wip.md + # - FoundationDB: kubernetes/wip.md + # - Istio: recipes/kubernetes/wip.md + # - Jaeger: kubernetes/wip.md + # - Kiali: kubernetes/wip.md + # - Minio: kubernetes/wip.md + # - NGINX Ingress: kubernetes/wip.md + # - Polaris: kubernetes/wip.md + # - Portainer: kubernetes/wip.md + # - Prometheus: kubernetes/wip.md + # - Traefik: kubernetes/wip.md + # - Vault: kubernetes/wip.md + # - Webook Receiver: kubernetes/wip.md + - 🚀 Get Premix!: + - premix/index.md + - Operation: premix/ansible/operation.md + - Design: premix/ansible/design.md + # - Swarm: premix/swarm.md + # - Kubernetes: premix/kubernetes.md + - CHANGELOG: CHANGELOG.md + - Support: support.md + - Contribute: community/contribute.md + - Community: + - Discord: community/discord.md + - Reddit: community/reddit.md + - Support: support.md + - Contribute: community/contribute.md + - Code of Conduct: community/code-of-conduct.md + + # # - Discourse: community/discourse.md + # # - GitHub: community/github.md + +theme: + name: 'material' + custom_dir: 'overrides' + # disqus: 'geeks-cookbook' + logo: 'images/site-logo.svg' + favicon: 'images/site-logo.svg' + features: + - navigation.tabs + - navigation.tabs.sticky + - navigation.instant + - navigation.sections + - navigation.indexes + - navigation.top + - navigation.pruning + - search.suggest + - search.share + - content.code.annotate + - header.autohide + - announce.dismiss + - toc.follow + icon: + repo: 'fontawesome/brands/github' + palette: + + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + + # Toggle light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: 'black' + accent: 'orange' + toggle: + icon: material/toggle-switch + name: Burn my eyes! + + # Toggle dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: 'black' + accent: 'orange' + toggle: + icon: material/toggle-switch-off-outline + name: Love my eyes! + + font: + text: 'Ubuntu' + code: 'Ubuntu Mono' + +extra: + social: + - icon: 'fontawesome/brands/github' + link: 'https://github.com/funkypenguin' + - icon: 'fontawesome/brands/twitter' + link: 'https://twitter.com/funkypenguin' + - icon: 'fontawesome/brands/stack-overflow' + link: 'https://stackoverflow.com/cv/funkypenguin' + - icon: 'material/rss' + link: 'https://www.funkypenguin.co.nz/' + - icon: 'fontawesome/brands/linkedin' + link: 'https://www.linkedin.com/in/funkypenguin' + - icon: 'material/mailbox' + link: 'mailto:davidy@funkypenguin.co.nz?Subject=Hello%2C%20from%20a%20geek-cookbook%20reader%20%3B%29' + generator: false + # Plausible doesn't use cookies, so no need for this! + # consent: + # title: 'Would you like a cookie? 🍪' + # description: > + + # I know. cookies suck (except the fresh, warm, choc-chip ones!), and so does invasive tracking. Thing is, without cookies, + # analytics can't record your visit, and I can't work out where/how to invest time to make the cookbook better. + + #
So, with your consent, I'd like to record what you look at and where you're from, so that I can make the + # cookbook even better. My analytics are public - here's all I know about you! - David
+ # cookies: + # custom: Plausible Analytics + analytics: + provider: plausible + data_domain: geek-cookbook.funkypenguin.co.nz + feedback: + title: Was this page helpful? + ratings: + - icon: material/emoticon-happy-outline + name: This page was helpful + data: 1 + note: >- + Thanks for your feedback! + - icon: material/emoticon-sad-outline + name: This page could be improved + data: 0 + note: >- + Thanks for your feedback! + +# Help us improve this page by +# using our feedback form. + +extra_css: + - extras/css/icons.css + +extra_javascript: + - extras/javascript/discord.js + - extras/javascript/sortable-tables.js + - extras/javascript/feedback.js + - https://cdnjs.cloudflare.com/ajax/libs/tablesort/5.2.1/tablesort.min.js + + +# Extensions +markdown_extensions: + - attr_list + - admonition + - codehilite: + linenums: true + - toc: + permalink: true + - footnotes + - pymdownx.critic + - pymdownx.arithmatex + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.details + - pymdownx.snippets: + check_paths: true + base_path: _snippets + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.inlinehilite + - pymdownx.magiclink: + repo_url_shorthand: true + user: funkypenguin + repo: geek-cookbook + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + - pymdownx.tabbed + - meta + - md_in_html diff --git a/mkdocs-pdf-print.yml b/mkdocs-pdf-print.yml index 3595377..729ba85 100644 --- a/mkdocs-pdf-print.yml +++ b/mkdocs-pdf-print.yml @@ -13,7 +13,7 @@ plugins: back_cover: true #cover_title: TITLE TEXT #cover_subtitle: SUBTITLE TEXT - #custom_template_path: TEMPLATES PATH + # custom_template_path: pdf_templates #toc_title: TOC TITLE TEXT #heading_shift: true toc_level: 3 @@ -30,10 +30,16 @@ plugins: text: ALTERNATE TEXT - src: ... # two_columns_level: 3 - render_js: true -# headless_chrome_path: headless-chromium + render_js: false + headless_chrome_path: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome output_path: funky-penguins-geek-cookbook.pdf debug_html: true show_anchors: true verbose: true + +extra_css: [] +extra_javascript: [] + +theme: + font: false \ No newline at end of file diff --git a/pdf_event_hook/__pycache__/__init__.cpython-39.pyc b/pdf_event_hook/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..d195681 Binary files /dev/null and b/pdf_event_hook/__pycache__/__init__.cpython-39.pyc differ diff --git a/print-preview.html b/print-preview.html new file mode 100644 index 0000000..bf00750 --- /dev/null +++ b/print-preview.html @@ -0,0 +1,528 @@ +Welcome, fellow geek If you're impatient, just start here
Dive into Docker Swarm
The quickest way to get started, and to get your head around the basics.
Kick it with Kubernetes
Been around for a while? Got a high pain threshold? Jump in!
Geek out in Discord
Join the fun, chat with fellow geeks in realtime!
Fast-track with 🚀 Premix!
Life's too short? Fast-track your stack with Premix!
The "Geek Cookbook" is a collection of how-to guides for establishing your own container-based awesome selfhosted platform, using either Docker Swarm or Kubernetes.
Running such a platform enables you to run selfhosted services such as the AutoPirate (Radarr, Sonarr, NZBGet and friends) stack, Plex, NextCloud etc, and includes elements such as:
Recent updates and additions are posted on the CHANGELOG, and there's a friendly community of like-minded geeks in the Discord server.
You already have a familiarity with concepts such as virtual machines, Docker containers, LetsEncrypt SSL certificates, databases, and command-line interfaces.
You've probably played with self-hosting some mainstream apps yourself, like Plex, NextCloud, Wordpress or Ghost.
So if you're familiar enough with the concepts above, and you've done self-hosting before, why would you read any further?
...how useful the recipes are for people just getting started with containers...
"One of the surprising realizations from following Funky Penguins cookbooks for so long is how useful the recipes are for people just getting started with containers and how it gives them real, interesting usecases to attach to their learning" - DevOps Daniel (@DanielSHouston)
He unblocked me on all the technical hurdles to launching my SaaS in GKE!
By the time I had enlisted Funky Penguin's help, I'd architected myself into a bit of a nightmare with Kubernetes. I knew what I wanted to achieve, but I'd made a mess of it. Funky Penguin (David) was able to jump right in and offer a vital second-think on everything I'd done, pointing out where things could be simplified and streamlined, and better alternatives.
He unblocked me on all the technical hurdles to launching my SaaS in GKE!
With him delivering the container/Kubernetes architecture and helm CI/CD workflow, I was freed up to focus on coding and design, which fast-tracked me to launching on time. And now I have a simple deployment process that is easy for me to execute and maintain as a solo founder.
I have no hesitation in recommending him for your project, and I'll certainly be calling on him again in the future.
-- John McDowall, Founder, kiso.io
I’ve spent 20+ years working with technology. I’m a solution architect, with a broad range of experience and skills. I'm a full-time AWS Certified Solution Architect (Professional), a CNCF-Certified Kubernetes Administrator, Application Developer and Security Specialist.
I want your support, either in the financial sense, or as a member of our friendly geek community (or both!)
The best way to support this work is to become a GitHub Sponsor / Patreon patron. You get:
.. and I get some pocket money every month to buy wine, cheese, and cryptocurrency! 🍷 💰
Impulsively click here (NOW quick do it!) to sponsor me via GitHub, or patronize me via Patreon!
Need some Cloud / Microservices / DevOps / Infrastructure design work done? This stuff is my bread and butter!
Get in touch, and let's talk!
A sponsorship is too much commitment, and a book is TL;DR? Hit me up with a one-time caffine shot!
I'm supported and motivated by GitHub Sponsors and Patreon patrons who have generously sponsored me.
I regularly donate to / sponsor the following projects. Join me in supporting these geeks, and encouraging them to continue building the ingredients for your favourite recipes!
| Project | Donate via.. |
|---|---|
| Komga | GitHub Sponsors |
| Material for MKDocs | GitHub Sponsors |
| Calibre | Credit Card / Patreon / LibrePay |
| LinuxServer.io | PayPal |
| WidgetBot's Discord Widget | Patreon |
| Carl-bot | Patreon |
In the design described below, our "private cloud" platform is:
This means that:
Note
An exception to the 3-nodes decision is running a single-node configuration. If you only have one node, then obviously your swarm is only as resilient as that node. It's still a perfectly valid swarm configuration, ideal for starting your self-hosting journey. In fact, under the single-node configuration, you don't need ceph either, and you can simply use the local volume on your host for storage. You'll be able to migrate to ceph/more nodes if/when you expand.
Where multiple solutions to a requirement exist, preference will be given to the most portable solution.
This means that:
Under this design, the only inbound connections we're permitting to our docker swarm in a minimal configuration (you may add custom services later, like UniFi Controller) are:
Assuming a 3-node configuration, under normal circumstances the following is illustrated:

In the case of a failure (or scheduled maintenance) of one of the nodes, the following is illustrated:

When the failed (or upgraded) host is restored to service, the following is illustrated:

A day after writing this, my environment suffered a fault whereby all 3 VMs were unexpectedly and simultaneously powered off.
Upon restore, docker failed to start on one of the VMs due to local disk space issue1. However, the other two VMs started, established the swarm, mounted their shared storage, and started up all the containers (services) which were managed by the swarm.
In summary, although I suffered an unplanned power outage to all of my infrastructure, followed by a failure of a third of my hosts... all my platforms are 100% available1 with absolutely no manual intervention.
In the design described below, our "private cloud" platform is:
This means that:
Note
An exception to the 3-nodes decision is running a single-node configuration. If you only have one node, then obviously your swarm is only as resilient as that node. It's still a perfectly valid swarm configuration, ideal for starting your self-hosting journey. In fact, under the single-node configuration, you don't need ceph either, and you can simply use the local volume on your host for storage. You'll be able to migrate to ceph/more nodes if/when you expand.
Where multiple solutions to a requirement exist, preference will be given to the most portable solution.
This means that:
Under this design, the only inbound connections we're permitting to our docker swarm in a minimal configuration (you may add custom services later, like UniFi Controller) are:
Assuming a 3-node configuration, under normal circumstances the following is illustrated:

In the case of a failure (or scheduled maintenance) of one of the nodes, the following is illustrated:

When the failed (or upgraded) host is restored to service, the following is illustrated:

A day after writing this, my environment suffered a fault whereby all 3 VMs were unexpectedly and simultaneously powered off.
Upon restore, docker failed to start on one of the VMs due to local disk space issue1. However, the other two VMs started, established the swarm, mounted their shared storage, and started up all the containers (services) which were managed by the swarm.
In summary, although I suffered an unplanned power outage to all of my infrastructure, followed by a failure of a third of my hosts... all my platforms are 100% available1 with absolutely no manual intervention.
Let's start building our cluster. You can use either bare-metal machines or virtual machines - the configuration would be the same. To avoid confusion, I'll be referring to these as "nodes" from now on.
Note
In 2017, I initially chose the "Atomic" CentOS/Fedora image for the swarm hosts, but later found its outdated version of Docker to be problematic with advanced features like GPU transcoding (in Plex), Swarmprom, etc. In the end, I went mainstream and simply preferred a modern Ubuntu installation.
Ingredients
New in this recipe:
Most modern Linux distributions include firewall rules which only only permit minimal required incoming connections (like SSH). We'll want to allow all traffic between our nodes. The steps to achieve this in CentOS/Ubuntu are a little different...
Add something like this to /etc/sysconfig/iptables:
# Allow all inter-node communication
+-A INPUT -s 192.168.31.0/24 -j ACCEPT
+And restart iptables with systemctl restart iptables
Install the (non-default) persistent iptables tools, by running apt-get install iptables-persistent, establishing some default rules (dkpg will prompt you to save current ruleset), and then add something like this to /etc/iptables/rules.v4:
# Allow all inter-node communication
+-A INPUT -s 192.168.31.0/24 -j ACCEPT
+And refresh your running iptables rules with iptables-restore < /etc/iptables/rules.v4
Depending on your hosting environment, you may have DNS automatically setup for your VMs. If not, it's useful to set up static entries in /etc/hosts for the nodes. For example, I setup the following:
Set your local timezone, by running:
ln -sf /usr/share/zoneinfo/<your timezone> /etc/localtime
+After completing the above, you should have:
Summary
Deployed in this recipe:
My first introduction to Kubernetes was a children's story:
Why would you want to Kubernetes for your self-hosted recipes, over simple Docker Swarm? Here's my personal take..
Sorry to say, but from where I sit, there's no innovation or development happening in docker swarm.
Yes, I know, after Docker Inc sold its platform business to Mirantis in Nov 2019, in Feb 2020 Mirantis back-tracked on their original plan to sunset swarm after 2 years, and stated that they'd continue to invest in swarm. But seriously, look around. Nobody is interested in swarm right now...
... Not even Mirantis! As of Nov 2021, the Mirantis blog tag "kubernetes" had 8 posts within the past month. The tag "docker" has 8 posts in the past 2 years, the 8th being the original announcement of the Docker aquisition. The tag "docker swarm" has only 2 posts, ever.
Dead. Extinct. Like the doodoo.
For years now, I've provided Kubernetes design consulting to small clients and large enterprises. The implementation details in each case vary widely, but there are some primitives which I've come to take for granted, and I wouldn't easily do without. A few examples:
Yes, it's more complex than Docker Swarm. And that complexity can definately be a barrier, although with improved tooling, it's continually becoming less-so. However, you don't need to be a mechanic to drive a car or to use a chainsaw. You just need a basic understanding of some core primitives, and then you get on with using the tool to achieve your goals, without needing to know every detail about how it works!
Your end-goal is probably "I want to reliably self-host services I care about", and not "I want to fully understand a complex, scalable, and highly sophisticated container orchestrator". 1
So let's get on with learning how to use the tool...
Primarily you need 2 things:
Practically, you need some extras too, but you can mix-and-match these.
Of course, if you do enjoy understanding the intricacies of how your tools work, you're in good company! ↩