Add Caddy and SearXNG to apps role

This commit is contained in:
Sam A. 2024-02-04 18:03:15 +01:00
parent 0b6f045648
commit 04b209a829
Signed by: samsapti
GPG Key ID: CBBBE7371E81C4EA
18 changed files with 377 additions and 25 deletions

View File

@ -1,6 +1,16 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
apps_include:
- nginx
- postfix
- ipfs
- monerod
- nextcloud
- snowflake
- restic
- watchtower
redis_passwords:
nextcloud: "{{ vault_redis_passwords.nextcloud }}"

View File

@ -0,0 +1,6 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
base_domain: sapti.me
internal_subnet: 10.2.3.0/24
tls_email: "{{ vault_tls_email }}"

View File

@ -0,0 +1,9 @@
$ANSIBLE_VAULT;1.1;AES256
30383865626464383438663561653566646634313937376332336630616566663434373638366337
6632323765633062373438643335656530366537626662370a376165366165303064353863306331
32333430303239643435343865376434623038303238313962303161633338373261663761633361
3361623463346563630a323064333831383535336335363930333235623966663663633265636463
32393139373931336565323838626361616264376333613939626263393837323462373435303731
37353866623639343634393566336131343564616237383762306436616535373138376561613230
63623866323265356338613232626432666335323462653938646562353866366463353965623066
63313138663861626634

View File

@ -1,17 +1,17 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
apps_base_domain: sapti.me
base_domain: sapti.me
internal_subnet: 10.2.16.0/24
postgresql_version: 14
databases:
nextcloud:
username: nextcloud
password: "{{ vault_db_passwords.nextcloud }}"
db_inventory_hostname: sapt-labp-db01
db_host: "{{ hostvars[db_inventory_hostname].internal_ipv4 }}"
proxy_inventory_hostname: sapt-labr-prx01
proxy_host: "{{ hostvars[proxy_inventory_hostname].internal_ipv4 }}"
databases:
nextcloud:
username: nextcloud
password: "{{ vault_db_passwords.nextcloud }}"

View File

@ -1,4 +1,9 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
apps_base_domain: sapti.me
apps_include:
- caddy
- searxng
- watchtower
searxng_secret_key: "{{ vault_searxng_secret_key }}"

View File

@ -0,0 +1,11 @@
$ANSIBLE_VAULT;1.1;AES256
61623537323039313538373562663036346638653365326439373333333236613163633764343665
3434613163333131343732316662303065646462343135300a613630313234316663336437643662
61323861313833383830303732306433653339326231313466643131616438353836666661306564
6535383837633264650a393133636536643434326537636633366665313164373463633862343034
36613030393538373464353166616164363430663361343534623135376563303663633266666332
32383336326563333535646265643638376661356631356434303963646532356133306266353736
37363639613166353038383736633034656637623638656662393539633538663432346665316136
63653130303762323562663562623065326263356561626330636337366164353634323062303062
66356531636261313462656265343731396333393263653733333530386439356665323765393030
3231663733393164383865336531333932393863666636336539

View File

@ -1,17 +1,17 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
apps_base_domain: staging.sapti.me
base_domain: staging.sapti.me
internal_subnet: 10.2.19.0/24
postgresql_version: 14
databases:
nextcloud:
username: nextcloud
password: "{{ vault_db_passwords.nextcloud }}"
db_inventory_hostname: sapt-labs-db01
db_host: "{{ hostvars[db_inventory_hostname].internal_ipv4 }}"
proxy_inventory_hostname: sapt-labr-prx01
proxy_host: "{{ hostvars[proxy_inventory_hostname].internal_ipv4 }}"
databases:
nextcloud:
username: nextcloud
password: "{{ vault_db_passwords.nextcloud }}"

View File

@ -2,11 +2,19 @@
# code: language=ansible
---
apps_data_root: "{{ data_fs }}/apps"
apps_base_domain: "{{ base_domain }}"
apps_local_domain: local.{{ apps_base_domain }}
apps_shared_docker_network: apps_network
apps_postfix_docker_network: postfix_network
apps_vars:
caddy:
backup: false
sender: false
extra_tasks: true
docker_ipv4: 172.17.2.48
version: 2.7.6-alpine
nginx:
backup: false
sender: false
@ -44,6 +52,14 @@ apps_vars:
version: 28-apache
redis_version: 7-alpine
searxng:
backup: false
sender: false
extra_tasks: true
domain: search.{{ apps_base_domain }}
version: latest
redis_version: 7-alpine
snowflake:
backup: false
sender: false

View File

@ -0,0 +1,21 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create subdirectories for Caddy data
ansible.builtin.file:
path: "{{ apps_data_root }}/caddy/data/caddy-{{ item }}"
owner: root
group: root
mode: u=rwx,go=
state: directory
loop:
- config
- data
- name: Copy Caddyfile
ansible.builtin.template:
src: caddy/Caddyfile.j2
dest: "{{ apps_data_root }}/caddy/data/Caddyfile"
owner: root
group: root
mode: u=rw,g=r,o=r

View File

@ -0,0 +1,18 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create subdirectory for SearXNG Redis data
ansible.builtin.file:
path: "{{ apps_data_root }}/searxng/data/redis"
owner: '999'
group: '1000'
mode: u=rwx,g=rx,o=rx
state: directory
- name: Copy SearXNG config
ansible.builtin.template:
src: searxng/settings.yml.j2
dest: "{{ apps_data_root }}/searxng/data/settings.yml"
owner: root
group: root
mode: u=rw,g=r,o=r

View File

@ -0,0 +1,75 @@
{# code: language=ansible-jinja #}
# THIS FILE IS MANAGED BY ANSIBLE
{{ apps_vars.searxng.domain }} {
tls {{ tls_email }}
log {
output discard
}
@api {
path /config
path /healthz
path /stats/errors
path /stats/checker
}
@static {
path /static/*
}
@notstatic {
not path /static/*
}
@imageproxy {
path /image_proxy
}
@notimageproxy {
not path /image_proxy
}
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-XSS-Protection "1; mode=block"
X-Content-Type-Options "nosniff"
Permissions-Policy "accelerometer=(),ambient-light-sensor=(),autoplay=(),camera=(),encrypted-media=(),focus-without-user-activation=(),geolocation=(),gyroscope=(),magnetometer=(),microphone=(),midi=(),payment=(),picture-in-picture=(),speaker=(),sync-xhr=(),usb=(),vr=(),interest-cohort=()"
Referrer-Policy "no-referrer"
X-Robots-Tag "noindex, noarchive, nofollow"
-Server
}
header @api {
Access-Control-Allow-Methods "GET, OPTIONS"
Access-Control-Allow-Origin "*"
}
header @static {
Cache-Control "public, max-age=31536000"
defer
}
header @notstatic {
Cache-Control "no-cache, no-store"
Pragma "no-cache"
}
header @imageproxy {
Content-Security-Policy "default-src 'none'; img-src 'self' data:"
}
header @notimageproxy {
Content-Security-Policy "upgrade-insecure-requests; default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; form-action 'self' https://github.com/searxng/searxng/issues/new; font-src 'self'; frame-ancestors 'self'; base-uri 'self'; connect-src 'self' https://overpass-api.de; img-src 'self' data: https://*.tile.openstreetmap.org; frame-src https://www.youtube-nocookie.com https://player.vimeo.com https://www.dailymotion.com https://www.deezer.com https://www.mixcloud.com https://w.soundcloud.com https://embed.spotify.com"
}
handle {
encode zstd gzip
reverse_proxy searxng:8080 {
header_up X-Forwarded-Port {http.request.port}
header_up X-Forwarded-Proto {http.request.scheme}
}
}
}

View File

@ -0,0 +1,29 @@
{# code: language=ansible-jinja #}
# THIS FILE IS MANAGED BY ANSIBLE
version: "3.8"
services:
web:
image: caddy:{{ apps_vars.caddy.version }}
restart: always
networks:
{{ apps_shared_docker_network }}:
ipv4_address: {{ apps_vars.caddy.docker_ipv4 }}
ports:
- 80:80/tcp
- 443:443/tcp
- 443:443/udp
volumes:
- "./data/Caddyfile:/etc/caddy/Caddyfile:ro"
- "./data/caddy-config:/config:rw"
- "./data/caddy-data:/data:rw"
cap_add:
- net_bind_service
- dac_override
cap_drop:
- all
networks:
{{ apps_shared_docker_network }}:
external: true

View File

@ -56,7 +56,9 @@ services:
- app
networks:
{{ apps_postfix_docker_network }}:
external: true
{{ apps_shared_docker_network }}:
external: true
{% if 'postfix' in apps_include %}
{{ apps_postfix_docker_network }}:
external: true
{% endif %}

View File

@ -0,0 +1,44 @@
{# code: language=ansible-jinja #}
# THIS FILE IS MANAGED BY ANSIBLE
version: "3.8"
services:
redis:
image: redis:{{ apps_vars.searxng.redis_version }}
restart: always
command: redis-server --save 60 1 --appendonly no
volumes:
- "./data/redis:/data:rw"
cap_add:
- dac_override
- setuid
- setgid
cap_drop:
- all
app:
image: searxng/searxng:{{ apps_vars.searxng.version }}
restart: always
environment:
SEARXNG_BASE_URL: https://{{ apps_vars.searxng.domain }}
networks:
default:
{{ apps_shared_docker_network }}:
aliases:
- searxng
volumes:
- "./data/settings.yml:/etc/searxng/settings.yml:ro"
cap_add:
- chown
- dac_override
- setuid
- setgid
cap_drop:
- all
depends_on:
- redis
networks:
{{ apps_shared_docker_network }}:
external: true

View File

@ -1,6 +1,5 @@
{# code: language=ansible-jinja #}
# THIS FILE IS MANAGED BY ANSIBLE
# vim: ft=bash
# code: language=bash
#!/usr/bin/env bash
ARG="$1"
@ -22,10 +21,19 @@ restart)
docker compose -f $app/docker-compose.yml restart
done
;;
{% if 'caddy' in apps_include %}
reload-proxy)
CADDYFILE="/etc/caddy/Caddyfile"
docker compose -f $APPS_DIR/caddy/docker-compose.yml exec web \
sh -c "caddy validate -c $CADDYFILE && caddy reload -c $CADDYFILE" \
2>/dev/null
;;
{% elif 'nginx' in apps_include %}
reload-proxy)
docker compose -f $APPS_DIR/nginx/docker-compose.yml exec web \
sh -c "nginx -t && nginx -s reload"
;;
{% endif %}
*)
echo "Unrecognized argument"
exit 1

View File

@ -0,0 +1,99 @@
# THIS FILE IS MANAGED BY ANSIBLE
# vim: ft=yaml
# code: language=yaml
---
use_default_settings: true
general:
debug: false
instance_name: Sam's SearXNG
privacypolicy_url: https://samsapti.dev/privacy
contact_url: https://samsapti.dev/contact
enable_metrics: true
server:
secret_key: "{{ searxng_secret_key }}"
image_proxy: true
http_protocol_version: '1.1'
method: GET
limiter: true
public_instance: true
ui:
results_on_new_tab: false
center_alignment: true
theme_args:
simple_style: auto
redis:
url: redis://redis:6379/0
search:
formats:
- html
safe_search: 2
suspended_times:
SearxEngineAccessDenied: 0
SearxEngineCaptcha: 600
SearxEngineTooManyRequests: 600
cf_SearxEngineCaptcha: 600
cf_SearxEngineAccessDenied: 1200
recaptcha_SearxEngineCaptcha: 600
outgoing:
enable_http2: true
source_ips:
- 0.0.0.0
enabled_plugins:
- 'Hash plugin'
- 'Self Informations'
- 'Tracker URL remover'
- 'Hostname replace'
hostname_replace:
'^(.*\.)?youtube\.com$': 'yewtu.be'
'^(.*\.)?youtu\.be$': 'yewtu.be'
'^(.*\.)?youtube-noocookie\.com$': 'yewtu.be'
'^(www\.)?twitter\.com$': 'nitter.net'
'^(.*\.)?(m\.)?wiktionary\.org$': '\1m.wiktionary.org'
engines:
- name: bing
disabled: false
- name: brave
disabled: true
- name: ddg definitions
disabled: false
- name: duckduckgo
disabled: false
- name: duckduckgo images
disabled: false
- name: google
disabled: false
- name: mojeek
disabled: true
- name: qwant
disabled: true
- name: qwant images
disabled: false
- name: startpage
disabled: true
- name: wikidata
disabled: true
- name: wikinews
disabled: true
- name: yahoo
disabled: false

View File

@ -4,7 +4,7 @@
{% for env in proxy_environments %}
# BEGIN Environment: {{ env }}
cloud.{{ proxy_vars[env].app01.apps_base_domain }} {
cloud.{{ proxy_vars[env].app01.base_domain }} {
tls {{ tls_email }} {
dns njalla {{ njalla_api_token }}
}
@ -29,9 +29,9 @@ cloud.{{ proxy_vars[env].app01.apps_base_domain }} {
{% endif %}
}
ipfs-gateway.{{ proxy_vars[env].app01.apps_base_domain }},
*.ipfs.ipfs-gateway.{{ proxy_vars[env].app01.apps_base_domain }},
*.ipns.ipfs-gateway.{{ proxy_vars[env].app01.apps_base_domain }} {
ipfs-gateway.{{ proxy_vars[env].app01.base_domain }},
*.ipfs.ipfs-gateway.{{ proxy_vars[env].app01.base_domain }},
*.ipns.ipfs-gateway.{{ proxy_vars[env].app01.base_domain }} {
tls {{ tls_email }} {
dns njalla {{ njalla_api_token }}
}
@ -56,7 +56,7 @@ ipfs-gateway.{{ proxy_vars[env].app01.apps_base_domain }},
{% endif %}
}
ipfs.local.{{ proxy_vars[env].app01.apps_base_domain }} {
ipfs.local.{{ proxy_vars[env].app01.base_domain }} {
tls {{ tls_email }} {
dns njalla {{ njalla_api_token }}
}
@ -77,7 +77,7 @@ ipfs.local.{{ proxy_vars[env].app01.apps_base_domain }} {
respond 403
}
xmr.local.{{ proxy_vars[env].app01.apps_base_domain }} {
xmr.local.{{ proxy_vars[env].app01.base_domain }} {
tls {{ tls_email }} {
dns njalla {{ njalla_api_token }}
}

View File

@ -1,6 +1,5 @@
{# code: language=ansible-jinja #}
# THIS FILE IS MANAGED BY ANSIBLE
# vim: ft=bash
# code: language=bash
#!/usr/bin/env bash
ARG="$1"