From 9e47b289bc84b21400235c26e642f30e88cfcb21 Mon Sep 17 00:00:00 2001 From: Ahmed AbdelHalim Date: Thu, 16 Jul 2026 14:39:19 +0200 Subject: Refactor pve cgit to use generic proxy This is refactoring the PoC for deploying cgit on pve, to now move to a more standard deployment with dedicated agnonstic proxy role/container --- group_vars/containers.yml | Bin 62 -> 45 bytes host_vars/git.home.arpa.yml | Bin 531 -> 531 bytes host_vars/git.home.arpa.yml.example | 8 ++-- host_vars/proxy.home.arpa.yml | Bin 0 -> 432 bytes host_vars/proxy.home.arpa.yml.example | 16 ++++++++ host_vars/rpi5.local.yml | Bin 3707 -> 3974 bytes inventory/hosts.yml | 1 + roles/caddy/defaults/main.yml | 1 - roles/caddy/handlers/main.yml | 2 +- roles/caddy/meta/argument_specs.yml | 6 +-- roles/caddy/meta/main.yml | 3 ++ roles/caddy/tasks/main.yml | 4 +- roles/cgit/defaults/main.yml | 5 ++- roles/cgit/handlers/main.yml | 14 +++++++ roles/cgit/meta/argument_specs.yml | 10 +++-- roles/cgit/tasks/main.yml | 60 +++++++++++++++++++++++++---- roles/cgit/templates/cgit.caddy.j2 | 3 ++ roles/cgit/templates/cgit.lighttpd.conf.j2 | 24 ++++++++++++ roles/cgit/templates/cgit.nginx.conf.j2 | 25 ++++++------ roles/cgit/templates/cgitrc.j2 | 4 +- roles/nginx/handlers/main.yml | 2 +- roles/nginx/meta/main.yml | 4 +- roles/nginx/tasks/main.yml | 4 +- roles/nginx/vars/alpine.yml | 2 + roles/proxy/meta/main.yml | 3 ++ roles/pve-lxc/tasks/main.yml | 6 ++- service.yml | 7 ++++ site.yml | 2 +- 28 files changed, 170 insertions(+), 46 deletions(-) create mode 100644 host_vars/proxy.home.arpa.yml create mode 100644 host_vars/proxy.home.arpa.yml.example create mode 100644 roles/cgit/templates/cgit.caddy.j2 create mode 100644 roles/cgit/templates/cgit.lighttpd.conf.j2 create mode 100644 roles/nginx/vars/alpine.yml diff --git a/group_vars/containers.yml b/group_vars/containers.yml index e6d29eb5..91d4d786 100644 Binary files a/group_vars/containers.yml and b/group_vars/containers.yml differ diff --git a/host_vars/git.home.arpa.yml b/host_vars/git.home.arpa.yml index f01929e3..f3c35fa6 100644 Binary files a/host_vars/git.home.arpa.yml and b/host_vars/git.home.arpa.yml differ diff --git a/host_vars/git.home.arpa.yml.example b/host_vars/git.home.arpa.yml.example index 90db04b3..518e4f5f 100644 --- a/host_vars/git.home.arpa.yml.example +++ b/host_vars/git.home.arpa.yml.example @@ -1,15 +1,15 @@ --- -network_ipv4_address: "10.0.0.100" +network_ipv4_address: "10.0.0.102" network_ipv4_gateway: "10.0.0.254" network_ipv4_dns: "10.0.0.254" -pve_lxc_id: 100 +pve_lxc_id: 102 pve_lxc_hostname: "git" pve_lxc_template: "alpine-3.23-default_20260116_amd64.tar.xz" -pve_lxc_disk: "local-lvm:4" +pve_lxc_disk: "local-lvm:4" # storage:sizeGB pve_lxc_cores: 1 pve_lxc_memory: 256 -pve_lxc_ip: "10.0.0.100/24" +pve_lxc_ip: "10.0.0.102/24" pve_lxc_gateway: "10.0.0.254" pve_lxc_dns: "10.0.0.254" diff --git a/host_vars/proxy.home.arpa.yml b/host_vars/proxy.home.arpa.yml new file mode 100644 index 00000000..c3a0d7ea Binary files /dev/null and b/host_vars/proxy.home.arpa.yml differ diff --git a/host_vars/proxy.home.arpa.yml.example b/host_vars/proxy.home.arpa.yml.example new file mode 100644 index 00000000..87ea12fc --- /dev/null +++ b/host_vars/proxy.home.arpa.yml.example @@ -0,0 +1,16 @@ +--- +network_ipv4_address: "10.0.0.101" +network_ipv4_gateway: "10.0.0.254" +network_ipv4_dns: "10.0.0.254" + +pve_lxc_id: 101 +pve_lxc_hostname: "proxy" +pve_lxc_template: "alpine-3.23-default_20260116_amd64.tar.xz" +pve_lxc_disk: "local-lvm:2" # storage:sizeGB +pve_lxc_cores: 1 +pve_lxc_memory: 128 +pve_lxc_ip: "10.0.0.101/24" +pve_lxc_gateway: "10.0.0.254" +pve_lxc_dns: "10.0.0.254" + +proxy_type: "caddy" diff --git a/host_vars/rpi5.local.yml b/host_vars/rpi5.local.yml index c8d6c59a..bb378ce0 100644 Binary files a/host_vars/rpi5.local.yml and b/host_vars/rpi5.local.yml differ diff --git a/inventory/hosts.yml b/inventory/hosts.yml index b35c1d42..cbe858c6 100644 --- a/inventory/hosts.yml +++ b/inventory/hosts.yml @@ -13,4 +13,5 @@ containers: vars: ansible_connection: ssh hosts: + proxy.home.arpa: git.home.arpa: diff --git a/roles/caddy/defaults/main.yml b/roles/caddy/defaults/main.yml index 9eed9960..ed97d539 100644 --- a/roles/caddy/defaults/main.yml +++ b/roles/caddy/defaults/main.yml @@ -1,2 +1 @@ --- -caddy_server_name: "{{ ansible_facts['hostname'] }}.local" diff --git a/roles/caddy/handlers/main.yml b/roles/caddy/handlers/main.yml index acfe3947..a871e3cf 100644 --- a/roles/caddy/handlers/main.yml +++ b/roles/caddy/handlers/main.yml @@ -1,6 +1,6 @@ --- - name: "Restart caddy" become: true - ansible.builtin.systemd_service: + ansible.builtin.service: name: "caddy" state: "restarted" diff --git a/roles/caddy/meta/argument_specs.yml b/roles/caddy/meta/argument_specs.yml index 7a55e9a2..5af49897 100644 --- a/roles/caddy/meta/argument_specs.yml +++ b/roles/caddy/meta/argument_specs.yml @@ -1,8 +1,4 @@ --- argument_specs: main: - options: - caddy_server_name: - type: "str" - description: "The server name for caddy configuration" - default: "{{ ansible_facts['hostname'] }}.local" + options: {} diff --git a/roles/caddy/meta/main.yml b/roles/caddy/meta/main.yml index a22dcce9..13d01c13 100644 --- a/roles/caddy/meta/main.yml +++ b/roles/caddy/meta/main.yml @@ -15,3 +15,6 @@ galaxy_info: - name: "Debian" versions: - "bookworm" + - name: "Alpine" + versions: + - "all" diff --git a/roles/caddy/tasks/main.yml b/roles/caddy/tasks/main.yml index f057f2b6..51b21502 100644 --- a/roles/caddy/tasks/main.yml +++ b/roles/caddy/tasks/main.yml @@ -1,7 +1,7 @@ --- - name: "Stop and disable nginx" become: true - ansible.builtin.systemd_service: + ansible.builtin.service: name: "nginx" state: "stopped" enabled: false @@ -34,7 +34,7 @@ - name: "Start and enable caddy" become: true - ansible.builtin.systemd_service: + ansible.builtin.service: name: "caddy" state: "started" enabled: true diff --git a/roles/cgit/defaults/main.yml b/roles/cgit/defaults/main.yml index 5acf53fb..02168d34 100644 --- a/roles/cgit/defaults/main.yml +++ b/roles/cgit/defaults/main.yml @@ -1,8 +1,9 @@ --- cgit_hostname: "git.example.com" -cgit_port: 80 +cgit_port: 3000 cgit_repos_dir: "/srv/git" cgit_title: "git" cgit_description: "personal git repositories" -cgit_clone_prefix: "https://{{ cgit_hostname }}" +cgit_clone_prefix: "ssh://{{ cgit_ssh_user }}@{{ cgit_hostname }}" cgit_ssh_user: "git" +cgit_proxy_host: "proxy.home.arpa" diff --git a/roles/cgit/handlers/main.yml b/roles/cgit/handlers/main.yml index d4481590..52ffdbee 100644 --- a/roles/cgit/handlers/main.yml +++ b/roles/cgit/handlers/main.yml @@ -1,6 +1,20 @@ --- +- name: "Restart lighttpd" + become: true + ansible.builtin.service: + name: lighttpd + state: restarted + +- name: "Restart caddy" + become: true + delegate_to: "{{ cgit_proxy_host }}" + ansible.builtin.service: + name: caddy + state: restarted + - name: "Restart nginx" become: true + delegate_to: "{{ cgit_proxy_host }}" ansible.builtin.service: name: nginx state: restarted diff --git a/roles/cgit/meta/argument_specs.yml b/roles/cgit/meta/argument_specs.yml index e0fa14d5..9dbe28b1 100644 --- a/roles/cgit/meta/argument_specs.yml +++ b/roles/cgit/meta/argument_specs.yml @@ -8,8 +8,8 @@ argument_specs: default: "git.example.com" cgit_port: type: "int" - description: "Port nginx listens on" - default: 80 + description: "Port lighttpd listens on internally" + default: 3000 cgit_repos_dir: type: "str" description: "Directory containing bare git repositories" @@ -25,8 +25,12 @@ argument_specs: cgit_clone_prefix: type: "str" description: "Clone URL prefix shown in cgit UI" - default: "https://{{ cgit_hostname }}" + default: "ssh://{{ cgit_ssh_user }}@{{ cgit_hostname }}" cgit_ssh_user: type: "str" description: "System user for SSH git push access" default: "git" + cgit_proxy_host: + type: "str" + description: "Inventory hostname of the proxy container to deploy vhost on" + default: "proxy.home.arpa" diff --git a/roles/cgit/tasks/main.yml b/roles/cgit/tasks/main.yml index fed97fef..17a5675b 100644 --- a/roles/cgit/tasks/main.yml +++ b/roles/cgit/tasks/main.yml @@ -4,8 +4,7 @@ ansible.builtin.package: name: - cgit - - nginx - - fcgiwrap + - lighttpd - openssh state: present @@ -43,15 +42,61 @@ group: "root" mode: "0644" -- name: "Deploy nginx config" +- name: "Deploy lighttpd config" become: true ansible.builtin.template: - src: "cgit.nginx.conf.j2" - dest: "/etc/nginx/http.d/cgit.conf" + src: "cgit.lighttpd.conf.j2" + dest: "/etc/lighttpd/lighttpd.conf" owner: "root" group: "root" mode: "0644" - notify: "Restart nginx" + notify: "Restart lighttpd" + +- name: "Deploy caddy vhost on proxy" + when: hostvars[cgit_proxy_host]['proxy_type'] == "caddy" + delegate_to: "{{ cgit_proxy_host }}" + block: + - name: "Ensure caddy sites directory exists" + become: true + ansible.builtin.file: + path: "/etc/caddy/sites" + state: directory + owner: "root" + group: "caddy" + mode: "0750" + + - name: "Deploy caddy vhost" + become: true + ansible.builtin.template: + src: "cgit.caddy.j2" + dest: "/etc/caddy/sites/{{ cgit_hostname }}.caddy" + owner: "root" + group: "caddy" + mode: "0640" + notify: "Restart caddy" + +- name: "Deploy nginx vhost on proxy" + when: hostvars[cgit_proxy_host]['proxy_type'] == "nginx" + delegate_to: "{{ cgit_proxy_host }}" + block: + - name: "Ensure nginx vhosts directory exists" + become: true + ansible.builtin.file: + path: "/etc/nginx/vhosts.d" + state: directory + owner: "root" + group: "root" + mode: "0755" + + - name: "Deploy nginx vhost" + become: true + ansible.builtin.template: + src: "cgit.nginx.conf.j2" + dest: "/etc/nginx/vhosts.d/{{ cgit_hostname }}.conf" + owner: "root" + group: "root" + mode: "0644" + notify: "Restart nginx" - name: "Enable and start services" become: true @@ -60,6 +105,5 @@ enabled: true state: started loop: - - nginx - - fcgiwrap + - lighttpd - sshd diff --git a/roles/cgit/templates/cgit.caddy.j2 b/roles/cgit/templates/cgit.caddy.j2 new file mode 100644 index 00000000..8ddc6d88 --- /dev/null +++ b/roles/cgit/templates/cgit.caddy.j2 @@ -0,0 +1,3 @@ +{{ cgit_hostname }} { + reverse_proxy {{ network_ipv4_address }}:{{ cgit_port }} +} diff --git a/roles/cgit/templates/cgit.lighttpd.conf.j2 b/roles/cgit/templates/cgit.lighttpd.conf.j2 new file mode 100644 index 00000000..0fd1d535 --- /dev/null +++ b/roles/cgit/templates/cgit.lighttpd.conf.j2 @@ -0,0 +1,24 @@ +server.port = {{ cgit_port }} +server.bind = "{{ network_ipv4_address }}" +server.modules = ("mod_cgi", "mod_rewrite") + +server.document-root = "/usr/share/webapps/cgit" +server.pid-file = "/run/lighttpd.pid" + +mimetype.assign = ( + ".css" => "text/css", + ".png" => "image/png", + ".ico" => "image/x-icon", + ".txt" => "text/plain", + ".html" => "text/html", +) + +cgi.assign = (".cgi" => "") + +url.rewrite-once = ( + "^/cgit\.css$" => "/cgit.css", + "^/cgit\.png$" => "/cgit.png", + "^/favicon\.ico$" => "/favicon.ico", + "^/robots\.txt$" => "/robots.txt", + "^(/.*)?$" => "/cgit.cgi$1", +) diff --git a/roles/cgit/templates/cgit.nginx.conf.j2 b/roles/cgit/templates/cgit.nginx.conf.j2 index 14256054..62fa6669 100644 --- a/roles/cgit/templates/cgit.nginx.conf.j2 +++ b/roles/cgit/templates/cgit.nginx.conf.j2 @@ -1,19 +1,22 @@ server { - listen {{ cgit_port }}; - listen [::]:{{ cgit_port }}; + listen 80; + listen [::]:80; server_name {{ cgit_hostname }}; - root /usr/share/webapps/cgit; + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + + server_name {{ cgit_hostname }}; - try_files $uri @cgit; + ssl_certificate {{ nginx_ssl_certificate }}; + ssl_certificate_key {{ nginx_ssl_certificate_key }}; - location @cgit { - fastcgi_pass unix:/run/fcgiwrap/fcgiwrap.sock; - fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi; - fastcgi_param PATH_INFO $uri; - fastcgi_param QUERY_STRING $args; - fastcgi_param HTTP_HOST $server_name; - include fastcgi_params; + location / { + proxy_pass http://{{ network_ipv4_address }}:{{ cgit_port }}; } } diff --git a/roles/cgit/templates/cgitrc.j2 b/roles/cgit/templates/cgitrc.j2 index a23e2d0b..89578a7c 100644 --- a/roles/cgit/templates/cgitrc.j2 +++ b/roles/cgit/templates/cgitrc.j2 @@ -1,5 +1,5 @@ -css=/cgit/cgit.css -logo=/cgit/cgit.png +css=/cgit.css +logo=/cgit.png virtual-root=/ diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml index f7c0adc8..cb84a8ce 100644 --- a/roles/nginx/handlers/main.yml +++ b/roles/nginx/handlers/main.yml @@ -1,6 +1,6 @@ --- - name: "Restart nginx" become: true - ansible.builtin.systemd_service: + ansible.builtin.service: name: "nginx" state: "restarted" diff --git a/roles/nginx/meta/main.yml b/roles/nginx/meta/main.yml index 86ced342..9f5dc152 100644 --- a/roles/nginx/meta/main.yml +++ b/roles/nginx/meta/main.yml @@ -1,6 +1,5 @@ --- dependencies: - - role: "systemd" - role: "openssl" - role: "logrotate" galaxy_info: @@ -18,3 +17,6 @@ galaxy_info: - name: "Debian" versions: - "bookworm" + - name: "Alpine" + versions: + - "all" diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml index e37e51f1..e9095dcc 100644 --- a/roles/nginx/tasks/main.yml +++ b/roles/nginx/tasks/main.yml @@ -4,7 +4,7 @@ - name: "Stop and disable caddy" become: true - ansible.builtin.systemd_service: + ansible.builtin.service: name: "caddy" state: "stopped" enabled: false @@ -94,7 +94,7 @@ - name: "Start and enable nginx" become: true - ansible.builtin.systemd_service: + ansible.builtin.service: name: "nginx" state: "started" enabled: true diff --git a/roles/nginx/vars/alpine.yml b/roles/nginx/vars/alpine.yml new file mode 100644 index 00000000..a9864eda --- /dev/null +++ b/roles/nginx/vars/alpine.yml @@ -0,0 +1,2 @@ +--- +nginx_user: "nginx" diff --git a/roles/proxy/meta/main.yml b/roles/proxy/meta/main.yml index 3715eae2..5cc03ec2 100644 --- a/roles/proxy/meta/main.yml +++ b/roles/proxy/meta/main.yml @@ -15,3 +15,6 @@ galaxy_info: - name: "Debian" versions: - "bookworm" + - name: "Alpine" + versions: + - "all" diff --git a/roles/pve-lxc/tasks/main.yml b/roles/pve-lxc/tasks/main.yml index c0fd0c17..b719bfd0 100644 --- a/roles/pve-lxc/tasks/main.yml +++ b/roles/pve-lxc/tasks/main.yml @@ -63,8 +63,10 @@ alpine) apk add --no-cache python3 ;; debian|ubuntu) apt-get install -y python3 ;; *) echo "Unsupported distro: $ID" && exit 1 ;; - esac' - changed_when: false + esac; + echo "python3 installed"' + register: cgit_python_bootstrap + changed_when: "'python3 installed' in cgit_python_bootstrap.stdout" tags: # PVE API not available in containers — requires proxmox-ve package - "molecule-notest" diff --git a/service.yml b/service.yml index 7fbccd8f..18a89540 100644 --- a/service.yml +++ b/service.yml @@ -1,4 +1,11 @@ --- +- name: "Proxy configure" + gather_facts: true + hosts: + - proxy.home.arpa + roles: + - role: "proxy" + - name: "Git configure" gather_facts: true hosts: diff --git a/site.yml b/site.yml index 94e2e831..85a8da55 100644 --- a/site.yml +++ b/site.yml @@ -2,7 +2,7 @@ - name: "Bootstrap" gather_facts: true tags: ["required_for_boot"] - hosts: all + hosts: homelab roles: - role: "hostname" - role: "network" -- cgit v1.2.3