infrastructure: move .env + CrowdSec key into org with noweb references

This commit is contained in:
root
2026-06-06 12:42:48 -04:00
parent 54827a4256
commit c12910d0f1
2 changed files with 258 additions and 21 deletions

View File

@@ -230,6 +230,11 @@ Why each piece:
Shared middleware used by all routers. Defined once here, referenced by name
in every router block.
#+NAME: crowdsec_key
#+BEGIN_SRC sh :results raw :exports none
echo "Xvx3UTjAdThkqtNuVhciWzEOJuBZoWH58KE+E7C3L6I"
#+END_SRC
#+BEGIN_SRC yaml :tangle /docker/appdata/traefik/dynamic.yaml
http:
middlewares:
@@ -261,7 +266,7 @@ http:
crowdsec-bouncer-traefik-plugin:
enabled: "true"
crowdsecMode: live
crowdsecLapiKey: __CROWDSEC_LAPI_KEY__
crowdsecLapiKey: <<crowdsec_key()>>
crowdsecLapiHost: crowdsec:8080
crowdsecLapiScheme: http
updateFrequencySec: 5
@@ -1529,3 +1534,252 @@ http:
#+END_SRC
service: http://10.10.10.29:8082
middleware: tunnel-headers@file
* Environment Variables
Tangled to /docker/compose/.env. The CROWDSEC_LAPI_KEY is a noweb reference
to the shared crowdsec_key block, so it stays in sync with dynamic.yaml.
#+BEGIN_SRC dotenv :tangle /docker/compose/.env
## Auto-generated from infrastructure.org -- do not edit directly.
## Edit infrastructure.org and tangle to update.
#################################################################################
#################################################################################
#################################################################################
##
## Docker Compose Environment Variable file for Jellyfin / *ARR Media Stack
##
## Update any of the environment variables below as required.
##
## It is highly recommended Linux users set up a "docker" user, so the
## applications can access the local filesystem with this user's access
## privileges. Use PUID / PGID to map user access between the Docker apps
## and local filesystem.
##
## The MediaStack Guide is located at https://MediaStack.Guide
##
#################################################################################
#################################################################################
#################################################################################
###################################################
## add /dev/net/tun to LXC
## https://pve.proxmox.com/wiki/OpenVPN_in_LXC
###################################################
# Name of the project in Docker
COMPOSE_PROJECT_NAME=docker-production
COMPOSE_BAKE=true
# This is the network subnet which will be used inside the docker "media_network", change as required.
# LOCAL_SUBNET is your home network and is needed so the VPN client allows access to your home computers.
DOCKER_SUBNET=172.28.10.0/24
DOCKER_GATEWAY=172.28.10.1
LOCAL_SUBNET=10.10.10.0/24 # This is the IP Subnet used on your home network
LOCAL_DOCKER_IP=10.10.10.201 # This is the IP Address of your Docker computer
# Each of the "*ARR" applications have been configured so the theme can be changed to your needs.
# Refer to Theme Park for more info / options: https://docs.theme-park.dev/theme-options/aquamarine/
TP_THEME=nord
# If you intend to use Plex as your Media Server, then enter your Plex Claim
# information below, to link this Plex Media Server to your Plex account
# Access Plex claim at: https://account.plex.tv/en/claim
PLEX_CLAIM=claim-1234567890abcdef
# These are the folders on your local host computer / NAS running docker, they MUST exist
# and have correct permissions for PUID and PGUI prior to running the docker compose.
#
# Use the commands in the Guide to create all the sub-folders in each of these folders.
# Host Data Folders - Will accept Linux, Windows, NAS folders.
# Make sure these folders exists before running the "docker compose" command.
FOLDER_FOR_MEDIA=/library
# <-- Update for your folders - Synology Example: /volume1/media
FOLDER_FOR_DATA=/docker/appdata
# <-- Update for your folders - Synology Example: /volume1/docker/appdata
FOLDER_FOR_MORE=/more
# File access, date and time details for the containers / applications to use.
# Run "sudo id docker" on host computer to find PUID / PGID and update these to suit.
PUID=1000
PGID=1000
UMASK=0002
TIMEZONE=America/New_York
# Update your own Internet VPN provide details below
# Online documentation: https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers
VPN_TYPE=openvpn
VPN_SERVICE_PROVIDER=privado
VPN_USERNAME=nhmpxamumlrj
VPN_PASSWORD=ulm8kRtJdmFLAum3tEb
# You MUST provide at least one entry to the SERVER variables below, that supports your VPN provider's settings.
# If you want to add more than one entry per line, use comma separated values: "one,two,three" etc...
SERVER_COUNTRIES=Netherlands
SERVER_REGIONS=
SERVER_CITIES=
SERVER_HOSTNAMES=
SERVER_CATEGORIES=
# Fill in this item ONLY if you're using a custom OpenVPN configuration
# Should be inside gluetun data folder - Example: /gluetun/custom-openvpn.conf
# You can then edit it inside the FOLDER_FOR_DATA location for gluetun.
OPENVPN_CUSTOM_CONFIG=
GLUETUN_CONTROL_PORT=8320
# Fill in these items ONLY if you change VPN_TYPE to "wireguard"
VPN_ENDPOINT_IP=
VPN_ENDPOINT_PORT=
WIREGUARD_PUBLIC_KEY=
WIREGUARD_PRIVATE_KEY=
WIREGUARD_PRESHARED_KEY=
WIREGUARD_ADDRESSES=
# These are the ports used to access each of the applications in your web browser.
# You can safely change these if you need, but they can't conflict with other active ports.
QBIT_PORT=6881
FLARESOLVERR_PORT=8191
TDARR_SERVER_PORT=8266
# WebUI ports for internal access to applications
WEBUI_PORT_AUDIOBOOKSHELF=13378
WEBUI_PORT_AUTHENTIK=6080
WEBUI_PORT_BAZARR=6767
WEBUI_PORT_CHROMIUM=3650
WEBUI_PORT_DDNS_UPDATER=8310
WEBUI_PORT_FILEBOT=5454
WEBUI_PORT_GUACAMOLE=9200
WEBUI_PORT_GRAFANA=3800
WEBUI_PORT_HEADPLANE=3500
WEBUI_PORT_HEIMDALL=2080
WEBUI_PORT_HOMARR=3200
WEBUI_PORT_HOMEPAGE=3000
WEBUI_PORT_HUNTARR=9705
WEBUI_PORT_JELLYFIN=8096
WEBUI_PORT_JELLYSEERR=5055
WEBUI_PORT_LAZYLIBRARIAN=5299
WEBUI_PORT_LIDARR=8686
WEBUI_PORT_MYLAR=8090
WEBUI_PORT_PLEX=32400
WEBUI_PORT_PORTAINER=9000
WEBUI_PORT_PROMETHEUS=9090
WEBUI_PORT_PROWLARR=9696
WEBUI_PORT_QBITTORRENT=8200
WEBUI_PORT_RADARR=7878
WEBUI_PORT_READARR=8787
WEBUI_PORT_SABNZBD=8100
WEBUI_PORT_SONARR=8989
WEBUI_PORT_STASH=7777
WEBUI_PORT_TDARR=8265
WEBUI_PORT_TRAEFIK=8080
WEBUI_PORT_WHISPARR=6969
CHROMIUM_START_PAGE="https://github.com/geekau/mediastack/"
# Traefik is configured for Reverse Proxy. Set your Internet gateway to redirect incoming ports 80 and 443
# to the ports used below (using Docker IP Address), and they will be translated back to 80 and 443 by Traefik.
# Change these port numbers if you have conflicting services running on the Docker host computer.
# If ports 80 and 443 are already used, then adjust and redirect incoming ports to 5080 and 5443, or similar.
REVERSE_PROXY_PORT_HTTP=80
REVERSE_PROXY_PORT_HTTPS=443
# Traefik Configuration
# Your CloudFlare Account Email Address
CLOUDFLARE_EMAIL=gharbeia@riseup.net
# Your CloudFlare Registered Domain Name
CLOUDFLARE_DNS_ZONE=gharbeia.net
# Your CloudFlare Read / Write API Token
CLOUDFLARE_DNS_API_TOKEN=cfut_unDIAx2wqL2tm8OmcZWpzrQTRPPA5FlenlVfeL7Nf94c360b
# Headscale / Headplane / Tailscale VPN Wireguard Mesh Networking
# These port settings are only to change the internal port due to conflicts, Headscale, Tailscale and Headplane will
# all function normally using the default ports as they are routed through Traefik reverse proxy.
CONNECT_PORT_HEADSCALE=4080
METRICS_PORT_HEADSCALE=4090
CROWDSEC_PORT=9080
METRICS_PORT_TRAEFIK=8082
INTERNAL_PORT_TRAEFIK=8083
METRICS_PORT_UNPACKERR=5656
# The Tailscale Docker container is configured as an exit node inside your home network, so traffic can route securely
# across the Internet, and break out behind your home gateway / router.
# sudo docker exec -it headscale headscale users create exit-node
# sudo docker exec -it headscale headscale --user exit-node preauthkeys create
# NOTE: Headscale must be running before the commands can be executed, then update authkey below and restart Tailscale.
TAILSCALE_AUTHKEY=57332c4f29ef77727d3310a34d903ae83ccae4c6392460fc
# Connect to the following address to complete the initial setup of Authentik after first deployment:
# http://<DOCKER-IP-ADDRESS>:6080/if/flow/initial-setup/
# echo AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')
AUTHENTIK_SECRET_KEY=P)'K"7sF#>Ia+m-8jOyn6\]6S
AUTHENTIK_VERSION=2025.4.1
AUTHENTIK_ERROR_REPORTING__ENABLED=true
POSTGRESQL_PORT=5432
VALKEY_PORT=6379
# echo POSTGRESQL_PASSWORD=$(openssl rand -base64 60 | tr -d '\n')
POSTGRESQL_PASSWORD=1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
POSTGRESQL_USERNAME=library-postgresql
AUTHENTIK_DATABASE=library-authentik
GUACAMOLE_DATABASE=library-guacamole
GUACD_PORT=4822
# SMTP Host Emails are sent to
EMAIL_SERVER_HOST=smtp.fastmail.com
EMAIL_SERVER_PORT=25
# Optionally authenticate (don't add quotation marks to your password)
EMAIL_ADDRESS=amr@gharbeia.net
EMAIL_PASSWORD=3a58334x8a9r8x7e
# Use StartTLS
EMAIL_TLS=true
# Use SSL - StartTLS and SSL can't both be true
EMAIL_SSL=false
# Email address authentik will send from, should have a correct @domain.name
EMAIL_SENDER=authentik@gharbeia.net
#### Gitea
GITEA__database__DB_TYPE=sqlite3
GITEA__database__PATH=/data/gitea/gitea.db
GITEA__server__DOMAIN=10.10.10.201
GITEA__server__HTTP_PORT=3001
GITEA__server__SSH_PORT=2222
GITEA__server__ROOT_URL=http://10.10.10.201:3000/
GITEA__security__INSTALL_LOCK=true
GITEA__service__DISABLE_REGISTRATION=false
# ports:
# - "127.0.0.1:3000:3000"
# - "127.0.0.1:2222:22"
# Cloudflare Tunnel token for cloudflared
TUNNEL_TOKEN=eyJhIjoiYWY0Y2RkYWM0N2UwMDFmZDZkNWMyMGFjNmRkZGFkM2QiLCJ0IjoiYzI5Mjk1YzUtOTQ2YS00ZGRmLWJkZmUtN2VhZmNkNzRmYWEzIiwicyI6Ik5qQm1aVEV4TjJFdFptRTFPUzAwTjJWbUxUZ3pORE10TURKa1lqRXhNMlptT1RVNCJ9
# Tube Archivist
TA_USERNAME=admin
TA_PASSWORD=DsO1BPfMEXMJROG9NlgEslOd
WEBUI_PORT_AUDIOMUSE=8005
# khaledfahmy.org
KHALEDFAHMY_DB_ROOT_PASSWORD=kf_root_ch4ng3_m3
KHALEDFAHMY_DB_PASSWORD=t1)~Bt~1uwmwe?pq}sZj%b!t8
# Nancy Okail (WordPress)
NANCYOKAIL_DB_ROOT_PASSWORD=changeme_placeholder
NANCYOKAIL_DB_PASSWORD=changeme_placeholder
# Rim Naguib (WordPress)
RIMNAGUIB_DB_ROOT_PASSWORD=changeme_placeholder
RIMNAGUIB_DB_PASSWORD=changeme_placeholder
# Fishere (WordPress)
FISHERE_DB_ROOT_PASSWORD=changeme_placeholder
FISHERE_DB_PASSWORD=changeme_placeholder
CROWDSEC_LAPI_KEY=<<crowdsec_key()>>
#+END_SRC

23
tangle-deploy.sh Normal file → Executable file
View File

@@ -1,4 +1,5 @@
#!/usr/bin/env bash
# tangle-deploy — Tangle infrastructure.org and restart affected services
GITEA_URL='ssh://git@git.gharbeia.net:2222/amr/infrastructure.git'
REPO_DIR="${1:-/docker/compose/infrastructure}"
ORG_FILE="${REPO_DIR}/infrastructure.org"
@@ -16,15 +17,8 @@ fi
echo "=== Tangling $ORG_FILE ==="
emacs --batch -Q --load /usr/share/emacs/28.2/lisp/org/org-loaddefs.el \
--eval "(require 'org)" \
--eval "(org-babel-tangle-file \"$ORG_FILE\")" 2>&1
# Substitute env vars in tangled files
# Read key from .env directly (avoid sourcing due to quoting issues in other vars)
CROWDSEC_LAPI_KEY=$(grep ^CROWDSEC_LAPI_KEY /docker/compose/.env | cut -d= -f2-)
if [ -z "$CROWDSEC_LAPI_KEY" ] || [ "$CROWDSEC_LAPI_KEY" = "__CROWDSEC_LAPI_KEY__" ]; then
echo "ERROR: CROWDSEC_LAPI_KEY not set or still a placeholder in .env!"
exit 1
fi
sed -i "s|__CROWDSEC_LAPI_KEY__|${CROWDSEC_LAPI_KEY}|g" /docker/appdata/traefik/dynamic.yaml
--eval "(require 'ob-shell)" \
--eval '(let ((org-confirm-babel-evaluate nil)) (org-babel-tangle-file "'"$ORG_FILE"'"))' 2>&1
echo "=== Restarting services ==="
cd /docker/compose
if [ -f /docker/appdata/traefik/traefik.yaml ] || \
@@ -33,17 +27,6 @@ if [ -f /docker/appdata/traefik/traefik.yaml ] || \
[ -f /docker/appdata/traefik/dynamic.yaml ]; then
echo 'Traefik config changed -- restarting...'
docker compose up -d traefik
# Verify CrowdSec bouncer is working after restart
sleep 2
STATUS=$(docker exec traefik wget -q -O /dev/null -S http://traefik:8081/application/o/authorize/ --header="Host: auth.gharbeia.net" 2>&1 | head -1 | awk '{print $2}')
if [ "$STATUS" = "403" ]; then
echo "WARNING: auth.gharbeia.net still returns 403 after deploy!"
echo " CrowdSec bouncer may have a bad API key."
echo " Run: docker exec crowdsec cscli bouncers add traefik-bouncer"
echo " Then update CROWDSEC_LAPI_KEY in /docker/compose/.env and re-deploy."
else
echo "OK: auth.gharbeia.net returns $STATUS (expected: 400)"
fi
fi
if [ -f /docker/compose/docker-compose.yaml ]; then
echo 'Docker compose changed -- restarting all services'