diff --git a/inventory.py b/inventory.py index 09a4eb0..4634ca4 100644 --- a/inventory.py +++ b/inventory.py @@ -15,7 +15,7 @@ servers = [ "ssh_user": "root", "web_server": True, "services": [ - "nginx", "immich", "nodered", "keycloak", + "nginx", "immich", "nodered", "authentik", ], }, ), diff --git a/scripts/bw2secrets b/scripts/bw2secrets index 38bd335..8831f99 100755 --- a/scripts/bw2secrets +++ b/scripts/bw2secrets @@ -8,6 +8,8 @@ from pathlib import Path import jinja2 +PROJECT_ROOT_DIRECTORY = Path(__file__).parent.parent.resolve() + bitwarden_session = None @@ -52,7 +54,7 @@ def _add_args(parser: argparse.ArgumentParser): parser.add_argument( "search_paths", help="start directory to walk files to find secret references", - default=".", + default=[PROJECT_ROOT_DIRECTORY], nargs="*", ) parser.add_argument( @@ -65,7 +67,7 @@ def _add_args(parser: argparse.ArgumentParser): def init_bw_session(bw_path: Path): global bitwarden_session - if (pw_file := Path("./.bw2secrets")).exists(): + if (pw_file := (PROJECT_ROOT_DIRECTORY / ".bw2secrets")).exists(): bitwarden_password = pw_file.read_text().strip() else: print("Please, provide your bitwarden master password") @@ -91,14 +93,11 @@ def find_templates(base_dirs: set[Path]) -> set[Path]: env_templates: set[Path] = set() for path in base_dirs: for env_template in path.glob("**/*.template"): + print(f"INFO: Found template at {env_template}") env_templates.add(env_template) return env_templates -# def secret_filter(bw_path: Path, secret_id: str) -> str: -# return fetch_secret(bw_path, secret_id) - - def compile_file(file_path: Path, bw_path: Path): jinja_env = jinja2.Environment( loader=jinja2.FileSystemLoader(file_path.parent), @@ -129,17 +128,20 @@ def main() -> int: print("Bitwarden CLI `bw` executable not found in PATH") return 1 - search_paths: set[Path | None] = set() + search_paths: set[Path] = set() for path in args.search_paths: search_path = Path(path) search_paths.add(search_path) + print(f"INFO: Will be searching {path}") + print("INFO: Searching templates") template_files = find_templates(search_paths) init_bw_session(bw_path) sync_bw_session(bw_path) for file in template_files: + print(f"INFO: Compiling {file}") compile_file(file, bw_path) return 0 diff --git a/services/authentik/.env.template b/services/authentik/.env.template new file mode 100644 index 0000000..ceb7fcc --- /dev/null +++ b/services/authentik/.env.template @@ -0,0 +1,28 @@ +HOST=auth.katuwoss.dev + +POSTGRES_USER={{ username['12c98bf4-a55d-4d2d-85a2-065a1a9b52d8'] }} +POSTGRES_PASSWORD={{ password['12c98bf4-a55d-4d2d-85a2-065a1a9b52d8'] }} +POSTGRES_DATABASE=authentik + +AUTHENTIK_REDIS__HOST=redis + +AUTHENTIK_COOKIE_DOMAIN=auth.katuwoss.dev + +AUTHENTIK_SECRET_KEY={{ password['fb6c881e-3e5c-422c-b057-03a0541aea84'] }} + +AUTHENTIK_POSTGRESQL__HOST=db +AUTHENTIK_POSTGRESQL__USER={{ username['12c98bf4-a55d-4d2d-85a2-065a1a9b52d8'] }} +AUTHENTIK_POSTGRESQL__NAME=authentik +AUTHENTIK_POSTGRESQL__PASSWORD={{ password['12c98bf4-a55d-4d2d-85a2-065a1a9b52d8'] }} + + +AUTHENTIK_EMAIL__HOST=smtp.seznam.cz +AUTHENTIK_EMAIL__PORT=465 +AUTHENTIK_EMAIL__USERNAME={{ username['bd699710-f430-4ec8-815b-2019fa94132f'] }} +AUTHENTIK_EMAIL__PASSWORD={{ password['bd699710-f430-4ec8-815b-2019fa94132f'] }} +AUTHENTIK_EMAIL__USE_SSL=true +AUTHENTIK_EMAIL__FROM=mailer@togetherdays.cz + + +AUTHENTIK_BOOTSTRAP_EMAIL={{ username['e0947cad-cf97-4bc2-9ee2-f74c35005441'] }} +AUTHENTIK_BOOTSTRAP_PASSWORD={{ password['e0947cad-cf97-4bc2-9ee2-f74c35005441'] }} diff --git a/services/authentik/docker-compose.yml b/services/authentik/docker-compose.yml new file mode 100644 index 0000000..ba9f967 --- /dev/null +++ b/services/authentik/docker-compose.yml @@ -0,0 +1,82 @@ +networks: + traefik-net: + name: traefik-net + external: true + +volumes: + authentik-pg-data: + name: authentik-pg-data + authentik-pg-backup: + name: authentik-pg-backup + authentik-redis: + name: authentik-redis + authentik-data: + name: authentik-data + authentik-certs: + name: authentik-certs + +x-authentik: &x-authentik + image: ghcr.io/goauthentik/server:2024.6.1 + restart: unless-stopped + env_file: + - .env + depends_on: + - db + - redis + networks: + - traefik-net + - default + +services: + authentik: + <<: *x-authentik + command: server + volumes: + - authentik-data:/media + deploy: + labels: + - traefik.enable=true + - traefik.docker.network=traefik-net + - traefik.http.routers.authentik.rule=Host(`${HOST}`) + - traefik.http.routers.authentik.entrypoints=websecure + - traefik.http.routers.authentik.tls.certresolver=le + - traefik.http.services.authentik.loadbalancer.server.port=9000 + + + worker: + <<: *x-authentik + command: worker + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - authentik-data:/media + - authentik-certs:/certs + + backup: + image: prodrigestivill/postgres-backup-local:16 + depends_on: + - db + volumes: + - authentik-pg-backup:/backups + environment: + - POSTGRES_EXTRA_OPTS=-Z 6 -F c + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DATABASE} + - POSTGRES_HOST=db + + db: + image: postgres:16 + volumes: + - authentik-pg-data:/var/lib/postgresql/data + restart: unless-stopped + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DATABASE} + + redis: + image: redis:alpine + command: --save 60 1 --loglevel warning + restart: unless-stopped + volumes: + - authentik-redis:/data diff --git a/services/keycloak/.env.template b/services/keycloak/.env.template index b374c80..5ad2389 100644 --- a/services/keycloak/.env.template +++ b/services/keycloak/.env.template @@ -9,7 +9,7 @@ KEYCLOAK_ADMIN_PASSWORD={{ password['fc557059-7c93-4851-8eae-888a664e5594'] }} KC_HTTP_ENABLED=true KC_HOSTNAME=https://auth.katuwoss.dev -KC_HOSTNAME_ADMIN=https://auth.katuwoss.dev +KC_HOSTNAME_STRICT=false KC_PROXY_HEADERS=xforwarded KC_DB=postgres @@ -20,3 +20,4 @@ KC_DB_PASSWORD={{ password['38493af8-18b7-409a-b3ba-84b1b2070873'] }} # DEBUG KC_LOG_LEVEL=DEBUG +KC_HOSTNAME_DEBUG=true