From 6b8701ca14e315b7a66e0ab1709156616276ca87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Kucharczyk?= Date: Fri, 1 Dec 2023 21:34:12 +0100 Subject: [PATCH] caddy: add config and scripts --- scripts/README.md | 9 +++ scripts/add | 61 ++++++++++++++++++++ scripts/sites-config.yaml | 114 ++++++++++++++++++++++++++++++++++++++ scripts/template.j2 | 17 ++++++ 4 files changed, 201 insertions(+) create mode 100644 scripts/README.md create mode 100755 scripts/add create mode 100644 scripts/sites-config.yaml create mode 100644 scripts/template.j2 diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..016ee51 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,9 @@ +This folder contains the configuration file, template, and script to generate a Caddyfile for all the services in main repository. + +# Usage + +1. Run the script: +```bash + ./add --config sites-config.yaml --template template.j2 > sites-enabled/generated.caddy +``` +2. Reload Caddy with `caddy reload -c /etc/caddy/Caddyfile` diff --git a/scripts/add b/scripts/add new file mode 100755 index 0000000..8ae3bfe --- /dev/null +++ b/scripts/add @@ -0,0 +1,61 @@ +#!/usr/bin/python3 +import argparse +import yaml +from jinja2 import Template + + +def render_template(template_path, **kwargs): + with open(template_path, "r") as file: + template = Template(file.read()) + output = template.render(**kwargs) + return output + + +def process_sites_config(config_path, template_path, check_mode): + with open(config_path, "r") as file: + sites_config = yaml.safe_load(file) + + total_sites = len(sites_config["sites"]) + enabled_sites = 0 + disabled_sites = 0 + + for site in sites_config["sites"]: + # Check if site is enabled + if site.get("enabled", True): # Default to True if 'enabled' key is not present + enabled_sites += 1 + if not check_mode: + rendered_content = render_template(template_path, **site) + print(f"{rendered_content}\n") + else: + disabled_sites += 1 + + if check_mode: + print(f"Total sites: {total_sites}") + print(f"Enabled sites: {enabled_sites}") + print(f"Disabled sites: {disabled_sites}") + + +def main(): + parser = argparse.ArgumentParser( + description="Process a sites configuration file for Caddyfiles" + ) + parser.add_argument( + "--config", required=True, help="Path to the YAML configuration file" + ) + parser.add_argument( + "--check", + action="store_true", + help="Only check statistics, do not output templates", + ) + parser.add_argument("--template", help="Path to the Jinja2 template file") + args = parser.parse_args() + + if args.template is None and args.check is False: + parser.error("--template argument is required if not using --check") + + template_path = args.template # Replace with the actual path to your template file + process_sites_config(args.config, template_path, args.check) + + +if __name__ == "__main__": + main() diff --git a/scripts/sites-config.yaml b/scripts/sites-config.yaml new file mode 100644 index 0000000..a43012a --- /dev/null +++ b/scripts/sites-config.yaml @@ -0,0 +1,114 @@ +sites: + - hostname: gitea + subdomain: git + port: 3000 + - hostname: rtorrent + subdomain: torrent + port: 9080 + - subdomain: portainer + # fixme: move portainer to docker-compose.yml + # hostname: portainer + hostname: 192.168.0.106 + port: 9000 + - subdomain: radarr + hostname: radarr + port: 7878 + - subdomain: sonarr-tv + hostname: sonarr_tv + port: 8989 + - subdomain: sonarr-anime + hostname: sonarr_anime + port: 8989 + - subdomain: notify + hostname: ntfy + port: 80 + additional_config: | + @httpget { + protocol http + method GET + path_regexp ^/([-_a-z0-9]{0,64}$|docs/|static/) + } + redir @httpget https://{host}{uri} + - subdomain: recipes + hostname: mealie + port: 80 + - subdomain: music + hostname: navidrome + port: 4533 + - subdomain: paperless + hostname: paperless-ngx + port: 8000 + - subdomain: photos + hostname: photoprism + port: 2342 + - subdomain: bookmarks + hostname: linkace + port: 80 + - subdomain: bw + hostname: vaultwarden + port: 80 + - subdomain: drone + # fixme: move to docker compose & change hostname AND PORT!! (80) + # hostname: drone + hostname: 192.168.0.106 + port: 580 + - subdomain: jellyfin + hostname: jellyfin + port: 8096 + - subdomain: comic + hostname: komga + port: 25600 + - subdomain: miniflux + hostname: miniflux + port: 8080 + - subdomain: netboot + # fixme: move to compose + # hostname: netbootxyz + hostname: 192.168.0.106 + port: 3001 + - subdomain: cloud + # fixme: move to compose + # hostname: nextcloud + hostname: 192.168.0.106 + port: 8484 + additional_config: | + redir /.well-known/carddav /remote.php/dav 301 + redir /.well-known/caldav /remote.php/dav 301 + header Strict-Transport-Security "max-age=15552000; includeSubDomains" + - subdomain: registry + # fixme: move to compose + # hostname: registry + hostname: 192.168.0.106 + port: 5000 + - subdomain: tracker + hostname: timetracker + port: 8001 + additional_config: | + handle_path /static/* { + root * /srv/timetracker + file_server + } + handle /robots.txt { + root * /srv/timetracker + file_server + } + - subdomain: notes-old + additional_config: | + root * /srv/notes + file_server + - subdomain: notes + additional_config: | + reverse_proxy https://publish.obsidian.md { + header_up Host {upstream_hostport} + } + rewrite * /serve?url=notes.kucharczyk.xyz{path} + server_config: | + encode zstd gzip + - subdomain: wiki + hostname: mediawiki + port: 80 + - subdomain: baserow + hostname: baserow + port: 80 + + diff --git a/scripts/template.j2 b/scripts/template.j2 new file mode 100644 index 0000000..7c20db5 --- /dev/null +++ b/scripts/template.j2 @@ -0,0 +1,17 @@ +{{ subdomain }}.kucharczyk.xyz { + handle { + {% if reverse_proxy_config %} + reverse_proxy {{ hostname }}:{{ port }} { + {{ reverse_proxy_config }} + } + {% else %} + {% if hostname and port %} + reverse_proxy {{ hostname }}:{{ port }} + {% endif %} + {% endif %} + {% if additional_config %} + {{ additional_config }} + {% endif %} + } + {{ server_config }} +}