feat(reverse-proxy): Add Caddy for reverse proxy
Signed-off-by: Tuan-Dat Tran <tuan-dat.tran@tudattr.dev>
This commit is contained in:
@@ -50,3 +50,7 @@ if ! shopt -oq posix; then
|
||||
. /etc/bash_completion
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f /etc/profile ]; then
|
||||
. /etc/profile
|
||||
fi
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
services:
|
||||
{% if enable_nginx %}
|
||||
{% for service in services %}
|
||||
{% if service.name == 'nginx' and inventory_hostname in service.vm %}
|
||||
nginx:
|
||||
container_name: "nginx"
|
||||
image: "jc21/nginx-proxy-manager:latest"
|
||||
@@ -16,7 +17,7 @@ services:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
{% endif %}
|
||||
|
||||
{% if enable_syncthing %}
|
||||
{% if service.name == 'syncthing' and inventory_hostname in service.vm %}
|
||||
syncthing:
|
||||
image: syncthing/syncthing
|
||||
container_name: syncthing
|
||||
@@ -38,7 +39,7 @@ services:
|
||||
hostname: syncthing
|
||||
{% endif %}
|
||||
|
||||
{% if enable_kuma %}
|
||||
{% if service.name == 'status' and inventory_hostname in service.vm %}
|
||||
kuma:
|
||||
container_name: kuma
|
||||
image: louislam/uptime-kuma:1
|
||||
@@ -57,7 +58,7 @@ services:
|
||||
- "/opt/local/kuma/:/app/data"
|
||||
{% endif %}
|
||||
|
||||
{% if enable_plex %}
|
||||
{% if service.name == 'plex' and inventory_hostname in service.vm %}
|
||||
plex:
|
||||
image: lscr.io/linuxserver/plex:latest
|
||||
container_name: plex
|
||||
@@ -89,7 +90,7 @@ services:
|
||||
- "/media/songs:/music:ro"
|
||||
{% endif %}
|
||||
|
||||
{% if enable_arr %}
|
||||
{% if service.name == 'sonarr' and inventory_hostname in service.vm %}
|
||||
sonarr:
|
||||
image: lscr.io/linuxserver/sonarr:latest
|
||||
container_name: sonarr
|
||||
@@ -106,7 +107,9 @@ services:
|
||||
- /opt/local/sonarr/config:/config
|
||||
- /media/series:/tv #optional
|
||||
- /media/docker/data/arr_downloads/sonarr:/downloads #optional
|
||||
{% endif %}
|
||||
|
||||
{% if service.name == 'radarr' and inventory_hostname in service.vm %}
|
||||
radarr:
|
||||
image: lscr.io/linuxserver/radarr:latest
|
||||
container_name: radarr
|
||||
@@ -123,7 +126,9 @@ services:
|
||||
- /opt/local/radarr/config:/config
|
||||
- /media/movies:/movies #optional
|
||||
- /media/docker/data/arr_downloads/radarr:/downloads #optional
|
||||
{% endif %}
|
||||
|
||||
{% if service.name == 'lidarr' and inventory_hostname in service.vm %}
|
||||
lidarr:
|
||||
image: lscr.io/linuxserver/lidarr:latest
|
||||
container_name: lidarr
|
||||
@@ -140,7 +145,9 @@ services:
|
||||
- /opt/local/lidarr/config:/config
|
||||
- /media/songs:/music #optional
|
||||
- /media/docker/data/arr_downloads/lidarr:/downloads #optional
|
||||
{% endif %}
|
||||
|
||||
{% if service.name == 'prowlarr' and inventory_hostname in service.vm %}
|
||||
prowlarr:
|
||||
image: lscr.io/linuxserver/prowlarr:latest
|
||||
container_name: prowlarr
|
||||
@@ -155,7 +162,9 @@ services:
|
||||
- TZ=Europe/Berlin
|
||||
volumes:
|
||||
- /opt/local/prowlarr/config:/config
|
||||
{% endif %}
|
||||
|
||||
{% if service.name == 'tl' and inventory_hostname in service.vm %}
|
||||
gluetun:
|
||||
image: qmcgaw/gluetun
|
||||
container_name: gluetun
|
||||
@@ -181,7 +190,9 @@ services:
|
||||
- SERVER_COUNTRIES=Hungary
|
||||
- OPENVPN_USER=MfCOtzTIEsmu1wY-q2lAZ3X1+pmp
|
||||
- OPENVPN_PASSWORD=knCl1Zl5PHz4HMWVCGR77dYa
|
||||
{% endif %}
|
||||
|
||||
{% if service.name == 'tl' and inventory_hostname in service.vm %}
|
||||
torrentleech:
|
||||
image: qbittorrentofficial/qbittorrent-nox
|
||||
container_name: torrentleech
|
||||
@@ -198,7 +209,9 @@ services:
|
||||
volumes:
|
||||
- /opt/docker/config/torrentleech/config:/config
|
||||
- /media/docker/data/arr_downloads:/downloads
|
||||
{% endif %}
|
||||
|
||||
{% if service.name == 'qbit' and inventory_hostname in service.vm %}
|
||||
qbit:
|
||||
image: qbittorrentofficial/qbittorrent-nox
|
||||
container_name: qbit
|
||||
@@ -217,7 +230,7 @@ services:
|
||||
- /media/docker/data/arr_downloads:/downloads
|
||||
{% endif %}
|
||||
|
||||
{% if enable_prometheus %}
|
||||
{% if service.name == 'prometheus' and inventory_hostname in service.vm %}
|
||||
prometheus:
|
||||
image: prom/prometheus
|
||||
container_name: prometheus
|
||||
@@ -235,7 +248,7 @@ services:
|
||||
- prometheus_data:/prometheus/
|
||||
{% endif %}
|
||||
|
||||
{% if enable_grafana %}
|
||||
{% if service.name == 'grafana' and inventory_hostname in service.vm %}
|
||||
grafana:
|
||||
image: grafana/grafana-oss
|
||||
container_name: grafana
|
||||
@@ -254,7 +267,7 @@ services:
|
||||
- /opt/docker/config/grafana/config/:/etc/grafana/
|
||||
{% endif %}
|
||||
|
||||
{% if enable_ddns_updater %}
|
||||
{% if service.name == 'ddns' and inventory_hostname in service.vm %}
|
||||
ddns-updater:
|
||||
container_name: ddns-updater
|
||||
image: "ghcr.io/qdm12/ddns-updater"
|
||||
@@ -267,7 +280,7 @@ services:
|
||||
- "/opt/docker/config/ddns-updater/data/:/updater/data/"
|
||||
{% endif %}
|
||||
|
||||
{% if enable_homeassistant %}
|
||||
{% if service.name == 'hass' and inventory_hostname in service.vm %}
|
||||
homeassistant:
|
||||
container_name: homeassistant
|
||||
image: "ghcr.io/home-assistant/home-assistant:stable"
|
||||
@@ -287,7 +300,7 @@ services:
|
||||
- 5683:5683/udp
|
||||
{% endif %}
|
||||
|
||||
{% if enable_stirling %}
|
||||
{% if service.name == 'pdf' and inventory_hostname in service.vm %}
|
||||
stirling:
|
||||
container_name: stirling
|
||||
image: frooodle/s-pdf:latest
|
||||
@@ -298,7 +311,7 @@ services:
|
||||
net: {}
|
||||
{% endif %}
|
||||
|
||||
{% if enable_jellyfin %}
|
||||
{% if service.name == 'jellyfin' and inventory_hostname in service.vm %}
|
||||
jellyfin:
|
||||
container_name: jellyfin
|
||||
image: jellyfin/jellyfin
|
||||
@@ -319,7 +332,7 @@ services:
|
||||
- "8096:8096"
|
||||
{% endif %}
|
||||
|
||||
{% if enable_paperless %}
|
||||
{% if service.name == 'paperless' and inventory_hostname in service.vm %}
|
||||
paperless-broker:
|
||||
container_name: paperless-broker
|
||||
image: docker.io/library/redis:7
|
||||
@@ -378,7 +391,7 @@ services:
|
||||
- "PAPERLESS_OCR_LANGUAGE=deu"
|
||||
{% endif %}
|
||||
|
||||
{% if enable_gitea %}
|
||||
{% if service.name == 'git' and inventory_hostname in service.vm %}
|
||||
git:
|
||||
container_name: git
|
||||
image: gitea/gitea:1.20.5-rootless
|
||||
@@ -400,7 +413,7 @@ services:
|
||||
- USER_GID=1000
|
||||
{% endif %}
|
||||
|
||||
{% if enable_changedetection %}
|
||||
{% if service.name == 'changedetection' and inventory_hostname in service.vm %}
|
||||
changedetection:
|
||||
container_name: changedetection
|
||||
image: dgtlmoon/changedetection.io
|
||||
@@ -413,7 +426,7 @@ services:
|
||||
- "/opt/docker/config/changedetection/data/:/datastore"
|
||||
{% endif %}
|
||||
|
||||
{% if enable_calibre %}
|
||||
{% if service.name == 'calibre' and inventory_hostname in service.vm %}
|
||||
calibre:
|
||||
container_name: calibre
|
||||
image: lscr.io/linuxserver/calibre-web:latest
|
||||
@@ -431,6 +444,7 @@ services:
|
||||
- "/opt/local/calibre/:/config"
|
||||
- "/media/docker/data/calibre/:/books"
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
networks:
|
||||
net:
|
||||
|
||||
6
roles/reverse_proxy/defaults/main.yml
Normal file
6
roles/reverse_proxy/defaults/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
caddy_version: latest
|
||||
caddy_config_path: /etc/caddy/Caddyfile
|
||||
caddy_binary: ./caddy
|
||||
|
||||
go_version: 1.23.4
|
||||
4
roles/reverse_proxy/handlers/main.yml
Normal file
4
roles/reverse_proxy/handlers/main.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
- name: Restart Caddy
|
||||
ansible.builtin.command: "{{ caddy_binary }} reload --config {{ caddy_config_path }}"
|
||||
become: true
|
||||
15
roles/reverse_proxy/tasks/configure.yml
Normal file
15
roles/reverse_proxy/tasks/configure.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Ensure Caddy configuration directory exists
|
||||
ansible.builtin.file:
|
||||
path: /etc/caddy
|
||||
state: directory
|
||||
mode: "0755"
|
||||
become: true
|
||||
|
||||
- name: Deploy Caddy configuration file
|
||||
ansible.builtin.template:
|
||||
src: Caddyfile.j2
|
||||
dest: "{{ caddy_config_path }}"
|
||||
mode: "0644"
|
||||
become: true
|
||||
notify: Restart Caddy
|
||||
32
roles/reverse_proxy/tasks/install.yml
Normal file
32
roles/reverse_proxy/tasks/install.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
- name: Download xCaddy GPG key
|
||||
ansible.builtin.get_url:
|
||||
url: "https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key"
|
||||
dest: /etc/apt/keyrings/caddy-xcaddy.asc
|
||||
mode: "0644"
|
||||
become: true
|
||||
|
||||
- name: Add xCaddy repository to apt sources
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb [signed-by=/etc/apt/keyrings/caddy-xcaddy.asc] https://dl.cloudsmith.io/public/caddy/xcaddy/deb/debian any-version main"
|
||||
state: present
|
||||
update_cache: true
|
||||
become: true
|
||||
|
||||
- name: Update apt cache
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
become: true
|
||||
|
||||
- name: Install xCaddy
|
||||
ansible.builtin.apt:
|
||||
name: xcaddy
|
||||
state: present
|
||||
become: true
|
||||
|
||||
- name: Install Caddy
|
||||
ansible.builtin.command: xcaddy build --with github.com/caddy-dns/netcup
|
||||
environment:
|
||||
PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin"
|
||||
register: xcaddy_build
|
||||
failed_when: xcaddy_build.rc != 0
|
||||
9
roles/reverse_proxy/tasks/main.yml
Normal file
9
roles/reverse_proxy/tasks/main.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
- name: Install Prerequisites
|
||||
ansible.builtin.include_tasks: prereq.yml
|
||||
- name: Install Caddy
|
||||
ansible.builtin.include_tasks: install.yml
|
||||
- name: Configure Caddy
|
||||
ansible.builtin.include_tasks: configure.yml
|
||||
- name: Start Caddy
|
||||
ansible.builtin.include_tasks: start.yml
|
||||
44
roles/reverse_proxy/tasks/prereq.yml
Normal file
44
roles/reverse_proxy/tasks/prereq.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
- name: Install prerequisites for Caddy
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- debian-keyring
|
||||
- debian-archive-keyring
|
||||
- apt-transport-https
|
||||
- curl
|
||||
state: present
|
||||
update_cache: true
|
||||
become: true
|
||||
|
||||
- name: Remove existing Go installation
|
||||
ansible.builtin.file:
|
||||
path: /usr/local/go
|
||||
state: absent
|
||||
become: true
|
||||
|
||||
- name: Download Go tarball
|
||||
ansible.builtin.get_url:
|
||||
url: "https://go.dev/dl/go{{ go_version }}.linux-amd64.tar.gz"
|
||||
dest: "/tmp/go{{ go_version }}.linux-amd64.tar.gz"
|
||||
mode: "0755"
|
||||
|
||||
- name: Extract Go tarball to /usr/local
|
||||
ansible.builtin.unarchive:
|
||||
src: /tmp/go1.23.4.linux-amd64.tar.gz
|
||||
dest: /usr/local
|
||||
remote_src: true
|
||||
become: true
|
||||
register: go_install
|
||||
|
||||
- name: Ensure Go binary path is added to /etc/profile
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/profile
|
||||
line: "PATH=$PATH:/usr/local/go/bin"
|
||||
state: present
|
||||
regexp: "^PATH=.*:/usr/local/go/bin$"
|
||||
become: true
|
||||
|
||||
- name: Source /etc/profile to update PATH for the current session
|
||||
ansible.builtin.shell: "source /etc/profile"
|
||||
args:
|
||||
executable: /bin/bash
|
||||
4
roles/reverse_proxy/tasks/start.yml
Normal file
4
roles/reverse_proxy/tasks/start.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
- name: Ensure Caddy service is running
|
||||
ansible.builtin.command: "{{ caddy_binary }} start --config {{ caddy_config_path }}"
|
||||
become: true
|
||||
26
roles/reverse_proxy/templates/Caddyfile.j2
Normal file
26
roles/reverse_proxy/templates/Caddyfile.j2
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
email {{ caddy.admin_email | default('admin@example.com') }}
|
||||
acme_ca {{ caddy.acme_ca | default('https://acme-v02.api.letsencrypt.org/directory') }}
|
||||
}
|
||||
|
||||
{% for service in services %}
|
||||
{{ service.name }}.{{ domain }} {
|
||||
{% for vm in service.vm %}
|
||||
reverse_proxy {{ hostvars[vm].ansible_host }}:{{ service.port }}
|
||||
{% endfor %}
|
||||
log {
|
||||
output file /var/log/caddy/{{ service.name }}.log
|
||||
format json
|
||||
}
|
||||
tls {
|
||||
dns netcup {
|
||||
customer_number {{ vault.netcup.customer_number }}
|
||||
api_key {{ vault.netcup.api_key}}
|
||||
api_password {{ vault.netcup.api_password }}
|
||||
}
|
||||
propagation_timeout 900s
|
||||
propagation_delay 600s
|
||||
resolvers 1.1.1.1
|
||||
}
|
||||
}
|
||||
{% endfor %}
|
||||
Reference in New Issue
Block a user