Add stuff

- Add sapt-labn-prx02 for apps on *.local.sapti.me
- Remove Pi-Hole (will be on my RPi)
- Unify app configuration in one file (not finished yet)
- Upload Compose files to hosts (not finished yet)
This commit is contained in:
Sam A. 2023-10-31 22:06:25 +01:00
parent 056e1bfa63
commit 423dbe2f7f
Signed by: samsapti
GPG key ID: CBBBE7371E81C4EA
24 changed files with 173 additions and 253 deletions

View file

@ -1,5 +1,6 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
collections:
- name: community.general
version: '>=7.5.0'

View file

@ -0,0 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
db_inventory_hostname: sapt-labp-db01
db_host_ip: "{{ hostvars[db_inventory_hostname].ansible_default_ipv4.address }}"

View file

@ -0,0 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
db_inventory_hostname: sapt-labs-db01
db_host_ip: "{{ hostvars[db_inventory_hostname].ansible_default_ipv4.address }}"

View file

@ -0,0 +1,4 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
proxy_mode: global

View file

@ -0,0 +1,4 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
proxy_mode: local

View file

@ -5,6 +5,5 @@ apps_include:
- postfix
- emby
- nextcloud
- pihole
- restic
- watchtower

View file

@ -5,6 +5,5 @@ apps_include:
- postfix
- emby
- nextcloud
- pihole
- restic
- watchtower

View file

@ -14,6 +14,7 @@ sapt-labs-db01 ansible_host=sapt-labs-db01.servers.local.sapti.me
[proxy_shd]
sapt-labn-prx01 ansible_host=sapt-labn-prx01.servers.local.sapti.me
sapt-labn-prx02 ansible_host=sapt-labn-prx02.servers.local.sapti.me
[monitoring_shd]
sapt-labn-mon01 ansible_host=sapt-labn-mon01.servers.local.sapti.me

View file

@ -10,61 +10,56 @@ apps_vars:
postfix:
domain: smtp.{{ apps_base_domain }}
volume: "{{ apps_data_root }}/postfix"
extra_tasks: true
version: latest-alpine
emby:
domain: watch.{{ apps_base_domain }}
volume: "{{ apps_data_root }}/emby"
extra_tasks: true
version: latest
ipfs:
domain: ipfs.{{ apps_local_domain }}
gateway_domain: ipfs-gateway.{{ apps_base_domain }}
volume: "{{ apps_data_root }}/ipfs"
extra_tasks: true
version: v0.19.2 # https://github.com/ipfs/kubo/issues/9901
monerod:
domain: xmr.{{ apps_base_domain }}
volume: "{{ apps_data_root }}/monerod"
extra_tasks: false
version: latest
nextcloud:
domain: cloud.{{ apps_base_domain }}
volume: "{{ apps_data_root }}/nextcloud"
extra_tasks: true
version: 27-apache
postgres_version: 14-alpine
redis_version: 7-alpine
snowflake:
extra_tasks: false
version: latest
pihole:
domain: pi-hole.{{ apps_local_domain }}
volume: "{{ apps_data_root }}/pi-hole"
docker_ipv4: 172.18.3.2
version: '2023.05.2'
unbound_version: latest
restic:
repo: /restic
extra_tasks: false
version: '1.7'
watchtower:
extra_tasks: false
version: '1.5.3'
apps_include: [] # empty == all
apps_local_ipv4s:
- '192.168.1.0/24'
- '192.168.8.0/24'
apps_include: "{{ apps_vars | dict2items | map(attribute='key') | list }}"
apps_restic_volumes:
- "/var/run/docker.sock:/var/run/docker.sock:rw"
- "{{ apps_vars.caddy.volume }}:/mnt/volumes/caddy:ro"
- "{{ apps_vars.postfix.volume }}:/mnt/volumes/postfix:ro"
- "{{ apps_vars.emby.volume }}:/mnt/volumes/emby:ro"
- "{{ apps_vars.nextcloud.volume }}:/mnt/volumes/nextcloud:ro"
- "{{ apps_vars.pihole.volume }}:/mnt/volumes/pi-hole:ro"
apps_sender_domains:
- "{{ apps_vars.nextcloud.domain }}"

View file

@ -1,10 +0,0 @@
private-domain: local.sapti.me
forward-zone:
name: "."
forward-tls-upstream: yes
forward-no-cache: yes
forward-addr: 91.239.100.100@853#anycast.censurfridns.dk
forward-addr: 2001:67c:28a4::@853#anycast.censurfridns.dk
forward-addr: 89.233.43.71@853#unicast.censurfridns.dk
forward-addr: 2a01:3a0:53:53::@853#unicast.censurfridns.dk

20
roles/apps/tasks/apps.yml Normal file
View file

@ -0,0 +1,20 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create volume folder for app {{ app_name }}
ansible.builtin.file:
name: "{{ app_vars.volume }}"
owner: root
mode: u=rwx,g=rx,o=rx
state: directory
- name: Upload Compose file for app {{ app_name }}
ansible.builtin.template:
src: compose-files/{{ app_name }}.yml.j2
dest: "{{ app_vars.volume }}/docker-compose.yml"
owner: root
mode: u=rw,g=r,o=r
- name: Run extra configuration tasks for app {{ app_name }}
ansible.builtin.include_tasks: extra_tasks/{{ app_name }}.yml
when: app_vars.extra_tasks is defined and app_vars.extra_tasks

View file

@ -1,109 +0,0 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Nextcloud apache2 directory
ansible.builtin.file:
name: "{{ services.nextcloud.volume }}/apache2"
owner: root
mode: u=rwx,g=rx,o=rx
state: directory
- name: Create Nextcloud app directory
ansible.builtin.file:
name: "{{ services.nextcloud.volume }}/app"
owner: root
group: '33'
mode: u=rwx,g=rx,o=rx
state: directory
- name: Create Nextcloud PostgreSQL directory
ansible.builtin.file:
name: "{{ services.nextcloud.volume }}/postgres"
owner: '70'
mode: u=rwx,go=
state: directory
- name: Copy Apache2 remoteip config file
ansible.builtin.template:
src: nextcloud/remoteip.conf.j2
dest: "{{ services.nextcloud.volume }}/apache2/remoteip.conf"
owner: root
mode: u=rw,g=r,o=r
- name: Deploy Nextcloud with Docker Compose
community.docker.docker_compose:
project_name: nextcloud
state: "{{ 'absent' if down is defined and down else 'present' }}"
restarted: "{{ restart is defined and restart }}"
recreate: "{{ 'always' if recreate is defined and recreate else 'smart' }}"
pull: true
definition:
version: '3.8'
services:
postgres:
image: postgres:{{ services.nextcloud.postgres_version }}
restart: always
environment:
POSTGRES_DB: nextcloud
POSTGRES_USER: nextcloud
POSTGRES_PASSWORD: "{{ secrets.nextcloud.postgres_pw }}"
volumes:
- "{{ services.nextcloud.volume }}/postgres:/var/lib/postgresql/data:rw"
redis:
image: redis:{{ services.nextcloud.redis_version }}
restart: always
command: redis-server --requirepass {{ secrets.nextcloud.redis_pw }}
tmpfs:
- /var/lib/redis
app:
image: nextcloud:{{ services.nextcloud.version }}
restart: always
environment:
POSTGRES_HOST: postgres
POSTGRES_DB: nextcloud
POSTGRES_USER: nextcloud
POSTGRES_PASSWORD: "{{ secrets.nextcloud.postgres_pw }}"
REDIS_HOST: redis
REDIS_HOST_PASSWORD: "{{ secrets.nextcloud.redis_pw }}"
MAIL_FROM_ADDRESS: noreply
MAIL_DOMAIN: "{{ services.nextcloud.domain }}"
SMTP_AUTHTYPE: PLAIN
SMTP_HOST: postfix
SMTP_PORT: 587
TRUSTED_PROXIES: "{{ services.caddy.docker_ipv4 }}"
OVERWRITEHOST: "{{ services.nextcloud.domain }}"
OVERWRITEPROTOCOL: https
OVERWRITECLIURL: https://{{ services.nextcloud.domain }}
NEXTCLOUD_INIT_LOCK: 'true'
PHP_MEMORY_LIMIT: 2G
PHP_UPLOAD_LIMIT: 16G
networks:
default:
postfix:
services:
aliases:
- nextcloud
volumes:
- "{{ services.nextcloud.volume }}/app:/var/www/html:rw"
- "{{ services.nextcloud.volume }}/apache2/remoteip.conf:/etc/apache2/conf-enabled/remoteip.conf:ro"
depends_on:
- postgres
- redis
cron:
image: nextcloud:{{ services.nextcloud.version }}
restart: always
entrypoint: /cron.sh
volumes:
- "{{ services.nextcloud.volume }}/app:/var/www/html:rw"
depends_on:
- app
networks:
postfix:
external: true
services:
external: true

View file

@ -1,81 +0,0 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Pi-hole volume base directory
ansible.builtin.file:
name: "{{ services.pihole.volume }}"
owner: root
mode: u=rwx,g=rx,o=rx
state: directory
- name: Create Pi-hole volume directory pihole
ansible.builtin.file:
name: "{{ services.pihole.volume }}/pihole"
owner: '999'
group: '1000'
mode: u=rwx,g=rwx,o=rx
state: directory
- name: Create other Pi-hole volume directories
ansible.builtin.file:
name: "{{ services.pihole.volume }}/{{ dir }}"
owner: root
mode: u=rwx,g=rx,o=rx
state: directory
loop:
- dnsmasq.d
- unbound
loop_control:
loop_var: dir
- name: Copy forward-records.conf for Unbound
ansible.builtin.copy:
src: pihole/forward-records.conf
dest: "{{ services.pihole.volume }}/unbound/forward-records.conf"
owner: root
mode: u=rw,g=r,o=r
- name: Deploy Pi-hole with Docker Compose
community.docker.docker_compose:
project_name: pihole
state: "{{ 'absent' if down is defined and down else 'present' }}"
restarted: "{{ restart is defined and restart }}"
recreate: "{{ 'always' if recreate is defined and recreate else 'smart' }}"
pull: true
definition:
version: '3.8'
services:
app:
image: pihole/pihole:{{ services.pihole.version }}
restart: always
environment:
DNSMASQ_LISTENING: all
DHCP_ACTIVE: 'false'
DNSSEC: 'true'
PIHOLE_DNS_: unbound
WEBPASSWORD: "{{ secrets.pihole.web_pw }}"
TZ: "{{ timezone }}"
networks:
default:
services:
aliases:
- pihole
volumes:
- "{{ services.pihole.volume }}/pihole:/etc/pihole:rw"
- "{{ services.pihole.volume }}/dnsmasq.d:/etc/dnsmasq.d:rw"
ports:
- 53:53/tcp
- 53:53/udp
depends_on:
- unbound
unbound:
image: mvance/unbound-rpi:{{ services.pihole.unbound_version }}
restart: always
volumes:
- "{{ services.pihole.volume }}/unbound/forward-records.conf:/opt/unbound/etc/unbound/forward-records.conf:ro"
networks:
services:
external: true

View file

@ -1,16 +1,16 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Emby volume directories
- name: Create subfolders for Emby data
ansible.builtin.file:
name: "{{ dir }}"
owner: '1000'
mode: u=rwx,g=rx,o=rx
state: directory
loop:
- "{{ services.emby.volume }}/programdata"
- "{{ services.emby.data_volume }}/tvshows"
- "{{ services.emby.data_volume }}/movies"
- "{{ apps_vars.emby.volume }}/programdata"
- "{{ apps_vars.emby.data_volume }}/tvshows"
- "{{ apps_vars.emby.data_volume }}/movies"
loop_control:
loop_var: dir
@ -20,7 +20,7 @@
state: "{{ 'absent' if down is defined and down else 'started' }}"
restart: "{{ restart is defined and restart }}"
recreate: "{{ recreate is defined and recreate }}"
image: emby/embyserver_arm64v8:{{ services.emby.version }}
image: emby/embyserver_arm64v8:{{ apps_vars.emby.version }}
restart_policy: always
env:
UID: '1000'
@ -30,8 +30,8 @@
aliases:
- emby
volumes:
- "{{ services.emby.volume }}/programdata:/config:rw"
- "{{ services.emby.data_volume }}/tvshows:/mnt/share1:rw"
- "{{ services.emby.data_volume }}/movies:/mnt/share2:rw"
- "{{ apps_vars.emby.volume }}/programdata:/config:rw"
- "{{ apps_vars.emby.data_volume }}/tvshows:/mnt/share1:rw"
- "{{ apps_vars.emby.data_volume }}/movies:/mnt/share2:rw"
devices:
- /dev/vchiq:/dev/vchiq # MMAL/OMX on Raspberry Pi

View file

@ -1,22 +1,22 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create IPFS Kubo volume directories
- name: Create subfolders for IPFS data
ansible.builtin.file:
name: "{{ dir }}"
owner: root
mode: u=rwx,g=rx,o=rx
state: directory
loop:
- "{{ services.ipfs.volume }}/data"
- "{{ services.ipfs.volume }}/staging"
- "{{ apps_vars.ipfs.volume }}/data"
- "{{ apps_vars.ipfs.volume }}/staging"
loop_control:
loop_var: dir
- name: Copy ipfs-config.sh
ansible.builtin.copy:
src: ipfs/ipfs-config.sh
dest: "{{ services.ipfs.volume }}/ipfs-config.sh"
dest: "{{ apps_vars.ipfs.volume }}/ipfs-config.sh"
owner: root
mode: u=rwx,g=rx,o=rx
@ -26,21 +26,21 @@
state: "{{ 'absent' if down is defined and down else 'started' }}"
restart: "{{ restart is defined and restart }}"
recreate: "{{ recreate is defined and recreate }}"
image: ipfs/kubo:{{ services.ipfs.version }}
image: ipfs/kubo:{{ apps_vars.ipfs.version }}
restart_policy: always
default_host_ip: ''
env:
IPFS_DOMAIN: "{{ services.ipfs.gateway_domain }}"
IPFS_DOMAIN: "{{ apps_vars.ipfs.gateway_domain }}"
IPFS_PROFILE: server
LOCAL_DOMAIN: "{{ services.ipfs.domain }}"
LOCAL_DOMAIN: "{{ apps_vars.ipfs.domain }}"
networks:
- name: services
aliases:
- ipfs_kubo
volumes:
- "{{ services.ipfs.volume }}/ipfs-config.sh:/container-init.d/ipfs-config.sh:ro"
- "{{ services.ipfs.volume }}/data:/data/ipfs:rw"
- "{{ services.ipfs.volume }}/staging:/export:rw"
- "{{ apps_vars.ipfs.volume }}/ipfs-config.sh:/container-init.d/ipfs-config.sh:ro"
- "{{ apps_vars.ipfs.volume }}/data:/data/ipfs:rw"
- "{{ apps_vars.ipfs.volume }}/staging:/export:rw"
published_ports:
- 4001:4001/tcp
- 4001:4001/udp

View file

@ -3,7 +3,7 @@
---
- name: Create Monero node volume directory
ansible.builtin.file:
name: "{{ services.monerod.volume }}"
name: "{{ apps_vars.monerod.volume }}"
owner: '1000'
mode: u=rwx,g=rx,o=rx
state: directory
@ -14,7 +14,7 @@
state: "{{ 'absent' if down is defined and down else 'started' }}"
restart: "{{ restart is defined and restart }}"
recreate: "{{ recreate is defined and recreate }}"
image: sethsimmons/simple-monerod:{{ services.monerod.version }}
image: sethsimmons/simple-monerod:{{ apps_vars.monerod.version }}
restart_policy: always
default_host_ip: ''
networks:
@ -22,6 +22,6 @@
aliases:
- monerod
volumes:
- "{{ services.monerod.volume }}:/home/monero/.bitmonero:rw"
- "{{ apps_vars.monerod.volume }}:/home/monero/.bitmonero:rw"
published_ports:
- 18080:18080/tcp

View file

@ -0,0 +1,24 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create subfolder for Nextcloud Apache2 config
ansible.builtin.file:
name: "{{ apps_vars.nextcloud.volume }}/apache2"
owner: root
mode: u=rwx,g=rx,o=rx
state: directory
- name: Create Nextcloud app subfolder
ansible.builtin.file:
name: "{{ apps_vars.nextcloud.volume }}/app"
owner: root
group: '33'
mode: u=rwx,g=rx,o=rx
state: directory
- name: Copy Apache2 remoteip config file
ansible.builtin.template:
src: nextcloud/remoteip.conf.j2
dest: "{{ apps_vars.nextcloud.volume }}/apache2/remoteip.conf"
owner: root
mode: u=rw,g=r,o=r

View file

@ -6,9 +6,9 @@
name: postfix
state: present
- name: Create Postfix volume directories
- name: Create subfolder for Postfix DKIM keys
ansible.builtin.file:
name: "{{ services.postfix.volume }}/dkim"
name: "{{ apps_vars.postfix.volume }}/dkim"
owner: root
mode: u=rwx,g=rx,o=rx
state: directory
@ -19,13 +19,13 @@
state: "{{ 'absent' if down is defined and down else 'started' }}"
restart: "{{ restart is defined and restart }}"
recreate: "{{ recreate is defined and recreate }}"
image: boky/postfix:{{ services.postfix.version }}
image: boky/postfix:{{ apps_vars.postfix.version }}
restart_policy: always
env:
ALLOWED_SENDER_DOMAINS: "{{ sender_domains | join(' ') }}"
HOSTNAME: "{{ services.postfix.domain }}"
HOSTNAME: "{{ apps_vars.postfix.domain }}"
DKIM_AUTOGENERATE: "true"
networks:
- name: postfix
volumes:
- "{{ services.postfix.volume }}/dkim:/etc/opendkim/keys:rw"
- "{{ apps_vars.postfix.volume }}/dkim:/etc/opendkim/keys:rw"

View file

@ -13,12 +13,12 @@
services:
backup:
image: mazzolino/restic:{{ services.restic.version }}
image: mazzolino/restic:{{ apps_vars.restic.version }}
restart: always
environment:
RUN_ON_STARTUP: 'false'
BACKUP_CRON: 0 0 3 * * *
RESTIC_REPOSITORY: b2:{{ secrets.restic.b2.bucket }}:{{ services.restic.repo }}
RESTIC_REPOSITORY: b2:{{ secrets.restic.b2.bucket }}:{{ apps_vars.restic.repo }}
RESTIC_PASSWORD: "{{ secrets.restic.repo_pw }}"
RESTIC_BACKUP_SOURCES: /mnt/volumes
RESTIC_BACKUP_ARGS: >-
@ -40,12 +40,12 @@
volumes: "{{ restic_volumes }}"
prune:
image: mazzolino/restic:{{ services.restic.version }}
image: mazzolino/restic:{{ apps_vars.restic.version }}
restart: always
environment:
RUN_ON_STARTUP: 'false'
PRUNE_CRON: 0 0 4 * * *
RESTIC_REPOSITORY: b2:{{ secrets.restic.b2.bucket }}:{{ services.restic.repo }}
RESTIC_REPOSITORY: b2:{{ secrets.restic.b2.bucket }}:{{ apps_vars.restic.repo }}
RESTIC_PASSWORD: "{{ secrets.restic.repo_pw }}"
RESTIC_PRUNE_ARGS: >-
--verbose
@ -54,12 +54,12 @@
TZ: "{{ timezone }}"
check:
image: mazzolino/restic:{{ services.restic.version }}
image: mazzolino/restic:{{ apps_vars.restic.version }}
restart: always
environment:
RUN_ON_STARTUP: 'false'
CHECK_CRON: 0 0 5 * * *
RESTIC_REPOSITORY: b2:{{ secrets.restic.b2.bucket }}:{{ services.restic.repo }}
RESTIC_REPOSITORY: b2:{{ secrets.restic.b2.bucket }}:{{ apps_vars.restic.repo }}
RESTIC_PASSWORD: "{{ secrets.restic.repo_pw }}"
RESTIC_CHECK_ARGS: >-
--verbose

View file

@ -7,6 +7,6 @@
state: "{{ 'absent' if down is defined and down else 'started' }}"
restart: "{{ restart is defined and restart }}"
recreate: "{{ recreate is defined and recreate }}"
image: thetorproject/snowflake-proxy:{{ services.snowflake.version }}
image: thetorproject/snowflake-proxy:{{ apps_vars.snowflake.version }}
restart_policy: always
network_mode: host

View file

@ -12,7 +12,7 @@
state: "{{ 'absent' if down is defined and down else 'started' }}"
restart: "{{ restart is defined and restart }}"
recreate: "{{ recreate is defined and recreate }}"
image: containrrr/watchtower:{{ services.watchtower.version }}
image: containrrr/watchtower:{{ apps_vars.watchtower.version }}
restart_policy: always
networks:
- name: watchtower

View file

@ -18,5 +18,9 @@
state: directory
- name: Configure apps
ansible.builtin.include_tasks: apps/{{ item.key }}.yml
loop: "{{ apps_vars | dict2items }}"
ansible.builtin.include_tasks:
file: apps.yml
vars:
app_name: "{{ item }}"
app_vars: "{{ apps_vars[item] }}"
loop: "{{ apps_include }}"

View file

@ -0,0 +1,59 @@
# code: language=ansible-jinja
version: "3.8"
services:
redis:
image: redis:{{ apps_vars.nextcloud.redis_version }}
restart: always
command: redis-server --requirepass {{ secrets.nextcloud.redis_pw }}
tmpfs:
- /var/lib/redis
app:
image: nextcloud:{{ apps_vars.nextcloud.version }}
restart: always
environment:
POSTGRES_HOST: "{{ db_host_ip }}"
POSTGRES_DB: nextcloud
POSTGRES_USER: nextcloud
POSTGRES_PASSWORD: {{ secrets.nextcloud.postgres_pw }}
REDIS_HOST: redis
REDIS_HOST_PASSWORD: {{ secrets.nextcloud.redis_pw }}
MAIL_FROM_ADDRESS: noreply
MAIL_DOMAIN: {{ apps_vars.nextcloud.domain }}
SMTP_AUTHTYPE: PLAIN
SMTP_HOST: postfix
SMTP_PORT: 587
TRUSTED_PROXIES: "{{ apps_vars.caddy.docker_ipv4 }}"
OVERWRITEHOST: {{ apps_vars.nextcloud.domain }}
OVERWRITEPROTOCOL: https
OVERWRITECLIURL: https://{{ apps_vars.nextcloud.domain }}
NEXTCLOUD_INIT_LOCK: true
PHP_MEMORY_LIMIT: 2G
PHP_UPLOAD_LIMIT: 16G
networks:
default:
postfix:
{{ apps_docker_network }}:
aliases:
- nextcloud
volumes:
- "{{ apps_vars.nextcloud.volume }}/app:/var/www/html:rw"
- "{{ apps_vars.nextcloud.volume }}/apache2/remoteip.conf:/etc/apache2/conf-enabled/remoteip.conf:ro"
depends_on:
- redis
cron:
image: nextcloud:{{ apps_vars.nextcloud.version }}
restart: always
entrypoint: /cron.sh
volumes:
- "{{ apps_vars.nextcloud.volume }}/app:/var/www/html:rw"
depends_on:
- app
networks:
postfix:
external: true
{{ apps_docker_network }}:
external: true

View file

@ -1,4 +1,4 @@
# code: language=ansible-jinja
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy {{ services.caddy.docker_ipv4 }}
RemoteIPInternalProxy {{ apps_vars.caddy.docker_ipv4 }}