Prepare multi-host Ansible repo
This commit is contained in:
parent
a6b721c888
commit
ee351c8304
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,5 @@
|
|||
# ---> Ansible
|
||||
*.retry
|
||||
|
||||
# ---> VS Code
|
||||
.vscode/
|
|
@ -1,3 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
collections:
|
||||
- name: community.general
|
||||
version: '>=7.5.0'
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
# vim: ft=yaml.ansible
|
||||
---
|
||||
hostname: default
|
||||
timezone: Europe/Copenhagen
|
||||
|
||||
users:
|
||||
- name: ubuntu
|
||||
comment: System Administration
|
||||
password: $6$YitakVLuUxjnPfDd$aFnEDcc98y6MlRYxLPAhb.eHsKqSIz385i4VrHW1Q8b986IqUhtu62gaOIALzM4FAU3dnWaHNUTGxY0zgA6jC0
|
||||
groups:
|
||||
- sudo
|
||||
ssh_keys:
|
||||
- sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIFWZGLov8wPBNxuvnaPK+8vv6wK5hHUVEFzXKsN9QeuBAAAADHNzaDpzYW1zYXB0aQ== ssh:samsapti
|
||||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPd/4fQV7CL8/KVwbo/phiV5UdXFBIDlkZ+ps8C7FeRf cardno:14 336 332
|
||||
|
||||
open_ports:
|
||||
- { port: '22', proto: 'tcp', comment: 'SSH (not port-forwarded)' }
|
||||
- { port: '53', proto: 'tcp', comment: 'Pi-hole (not port-forwarded)' }
|
||||
- { port: '53', proto: 'udp', comment: 'Pi-hole (not port-forwarded)' }
|
||||
- { port: '80', proto: 'tcp', comment: 'HTTP' }
|
||||
- { port: '443', proto: 'tcp', comment: 'HTTPS' }
|
||||
- { port: '443', proto: 'udp', comment: 'HTTPS' }
|
||||
- { port: '4001', proto: 'tcp', comment: 'IPFS Kubo P2P' }
|
||||
- { port: '4001', proto: 'udp', comment: 'IPFS Kubo P2P' }
|
||||
- { port: '18080', proto: 'tcp', comment: 'monerod P2P' }
|
||||
- { port: '18089', proto: 'tcp', comment: 'monerod RPC' }
|
|
@ -1,5 +0,0 @@
|
|||
[appservers]
|
||||
sapt-lapb-app01.servers.local.sapti.me
|
||||
|
||||
[dbservers]
|
||||
sapt-labp-db01.servers.local.sapti.me
|
12
inventories/production/group_vars/all/vars.yml
Normal file
12
inventories/production/group_vars/all/vars.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
base_domain: sapti.me
|
||||
local_domain: local.{{ base_domain }}
|
||||
|
||||
encrypted_fs: /data
|
||||
docker_data_root: "{{ encrypted_fs }}/docker"
|
||||
|
||||
hostname: "{{ inventory_hostname_short }}"
|
||||
timezone: Europe/Copenhagen
|
||||
username: lab_admin
|
6
inventories/production/group_vars/appservers/vars.yml
Normal file
6
inventories/production/group_vars/appservers/vars.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
apps_base_domain: "{{ base_domain }}"
|
||||
apps_local_domain: "{{ local_domain }}"
|
||||
apps_data_root: "{{ encrypted_fs }}/apps"
|
4
inventories/production/group_vars/dbservers/vars.yml
Normal file
4
inventories/production/group_vars/dbservers/vars.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
db_data_root: "{{ encrypted_fs }}/db"
|
10
inventories/production/host_vars/sapt-labp-app01.yml
Normal file
10
inventories/production/host_vars/sapt-labp-app01.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
apps_include:
|
||||
- postfix
|
||||
- emby
|
||||
- nextcloud
|
||||
- pihole
|
||||
- restic
|
||||
- watchtower
|
8
inventories/production/host_vars/sapt-labp-app02.yml
Normal file
8
inventories/production/host_vars/sapt-labp-app02.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
apps_include:
|
||||
- ipfs
|
||||
- monerod
|
||||
- snowflake
|
||||
- watchtower
|
6
inventories/production/hosts
Normal file
6
inventories/production/hosts
Normal file
|
@ -0,0 +1,6 @@
|
|||
[appservers]
|
||||
sapt-labp-app01.servers.local.sapti.me
|
||||
sapt-labp-app02.servers.local.sapti.me
|
||||
|
||||
[dbservers]
|
||||
sapt-labp-db01.servers.local.sapti.me
|
|
@ -1,8 +0,0 @@
|
|||
[shdservers]
|
||||
sapt-labn-shd01.servers.local.sapti.me
|
||||
|
||||
[trnservers]
|
||||
sapt-labn-trn01.servers.local.sapti.me
|
||||
|
||||
[monservers]
|
||||
sapt-labn-mon01.servers.local.sapti.me
|
5
inventories/shared/hosts
Normal file
5
inventories/shared/hosts
Normal file
|
@ -0,0 +1,5 @@
|
|||
[proxyservers]
|
||||
sapt-labn-prx01.servers.local.sapti.me
|
||||
|
||||
[monitoringservers]
|
||||
sapt-labn-mon01.servers.local.sapti.me
|
|
@ -1,5 +0,0 @@
|
|||
[appservers]
|
||||
sapt-labv-app01.servers.local.sapti.me
|
||||
|
||||
[dbservers]
|
||||
sapt-labv-db01.servers.local.sapti.me
|
54
inventories/staging/group_vars/all/secrets.yml
Normal file
54
inventories/staging/group_vars/all/secrets.yml
Normal file
|
@ -0,0 +1,54 @@
|
|||
$ANSIBLE_VAULT;1.1;AES256
|
||||
65653764303436313934646462396636636335303334636532306438613635333362313530323731
|
||||
3236383962303039393238646362626665613463666335610a353261343163663934353366656630
|
||||
65356562616661326535626238373635366233326366343631386165653735373637656330343735
|
||||
3330376331306633300a393530313436653737366630336165653839616437626531346331653466
|
||||
35626530373932303962333933626265326166656136623139666533643934653666383436383838
|
||||
35643430383763323038646461313563373462353736376137323230613338613430303763376164
|
||||
32633833653236323561643636373461353932663232663561636164383361663361346263376436
|
||||
33346335323530666436393538326531623931643838633631646137306563306630336238333166
|
||||
34346634306337313938626632663131333534356631386564363233643339623338363539326262
|
||||
62336331646134626439313032626231383833353831343038393739366435663766333262633461
|
||||
61383830656566666262376162376637313933336533396664303830306266323234323463613966
|
||||
33383864393964323866613937623331343966373432643732383663343335316562326637353837
|
||||
32646362613631633263386566353930363665353361353934393537353461383333343331356639
|
||||
31633861346635386432363835373736363133303266383835633436313533393835616231313165
|
||||
62363835623866323961313664333430656131373061373764316331343639653437633037636339
|
||||
37656363366137666138333835353661613363333963333134313338386362656435633063353538
|
||||
64346464336230323131346537653565383630613532356264633035363962303131663036343065
|
||||
31363536366362303164373339333462653166333031616362653631383234303836613532633332
|
||||
64333337343362613161626166393634636336373265643561323230383534326663643536366333
|
||||
63393230343735346631306461653636396634343864623532306661326564633661623131346639
|
||||
38363331613463616266633863303161326237313037643934383032663834366634363965396238
|
||||
63633330636130373331393533393531623535656361306165623539383962653839353334643233
|
||||
35663566383434396135323531353230643763326134323865343863616461326530353963376232
|
||||
31373965353732386630366130656266623464666333383433393062613366363136333933343461
|
||||
61323832626466386433636134383765383834643536363635623830303535646530613238343437
|
||||
36363566396465313830326137396532393762623436646663643663393266396631363663343936
|
||||
32383561643237386630353730323563313636663633623036363131366139396235343138306134
|
||||
66653538663937616266343065333366613236313235346635326337633866363263313832653732
|
||||
35663634363432383066386561663661643265613532386165646230313531356535353165343666
|
||||
38663764643439633664353439366536323763663063626664623365613734386265393934383532
|
||||
66323963303133653465366138666132666339353630323739383633383462373532323762663432
|
||||
30643436376539303430343164663238376634346437623063656466653138626237663538626436
|
||||
30623836393362666231323435383238643731623931396235346330323539643966663365363632
|
||||
65646564656563303064643161353930396663363638383965616662663238646434373862316430
|
||||
39343932656532626631323035633563373730393163396338653064326631626436373533333734
|
||||
65626361346162383530626134336230346234653936366462393538353137373933376533313839
|
||||
34383932343637623262373134636233373839313339393433303337363566643833353066396337
|
||||
66643966373436393937363064353365363239323461653034626161383936303236313364366535
|
||||
65316335333235623463613766633836643730363634666465386663386235306334376364323162
|
||||
39333466383333643339633538336632376333623439646234643666333162326135663130303536
|
||||
39663234633761633632346534383966313234613763323038626466346235333165303934633431
|
||||
36313565346631623166383338643739346634393663303264373962343932376430663333376165
|
||||
62613462396531323634613966616331623538306636343235393362396437633239366136616436
|
||||
65323638393566363034633231643565636431356431386234316233636266663136656139663532
|
||||
38613637636432626236323066643632343661316565343361323764353335313265383831373764
|
||||
64323361333463346438626134323166623231393338373333653161623663336434383931393163
|
||||
36633163393235636435323931313265633234623433653134616132346262653234636364376238
|
||||
66313761333436336663323663626563656566366665336439643461623837666338313565313964
|
||||
31666466663863623334316164316432353362316336616662666666363766306231653664306663
|
||||
37613839383864386533326634336433633464343831303835656366616339393332633965323431
|
||||
65643136643866653834353538356233623662663237303261333564346566643839633532366262
|
||||
66653162366563666463353533656665323661326566383966306332626566663732353730313732
|
||||
65323034326161306165613364336336386265313735396237623633346263333966
|
12
inventories/staging/group_vars/all/vars.yml
Normal file
12
inventories/staging/group_vars/all/vars.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
base_domain: staging.sapti.me
|
||||
local_domain: local.{{ base_domain }}
|
||||
|
||||
encrypted_fs: /data
|
||||
docker_data_root: "{{ encrypted_fs }}/docker"
|
||||
|
||||
hostname: "{{ inventory_hostname_short }}"
|
||||
timezone: Europe/Copenhagen
|
||||
username: lab_admin
|
6
inventories/staging/group_vars/appservers/vars.yml
Normal file
6
inventories/staging/group_vars/appservers/vars.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
apps_base_domain: "{{ base_domain }}"
|
||||
apps_local_domain: "{{ local_domain }}"
|
||||
apps_data_root: "{{ encrypted_fs }}/apps"
|
4
inventories/staging/group_vars/dbservers/vars.yml
Normal file
4
inventories/staging/group_vars/dbservers/vars.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
db_data_root: "{{ encrypted_fs }}/db"
|
10
inventories/staging/host_vars/sapt-labs-app01.yml
Normal file
10
inventories/staging/host_vars/sapt-labs-app01.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
apps_include:
|
||||
- postfix
|
||||
- emby
|
||||
- nextcloud
|
||||
- pihole
|
||||
- restic
|
||||
- watchtower
|
8
inventories/staging/host_vars/sapt-labs-app02.yml
Normal file
8
inventories/staging/host_vars/sapt-labs-app02.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
apps_include:
|
||||
- ipfs
|
||||
- monerod
|
||||
- snowflake
|
||||
- watchtower
|
6
inventories/staging/hosts
Normal file
6
inventories/staging/hosts
Normal file
|
@ -0,0 +1,6 @@
|
|||
[appservers]
|
||||
sapt-labs-app01.servers.local.sapti.me
|
||||
sapt-labs-app02.servers.local.sapti.me
|
||||
|
||||
[dbservers]
|
||||
sapt-labs-db01.servers.local.sapti.me
|
|
@ -1,9 +1,10 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: App server configuration
|
||||
hosts: appservers
|
||||
become: true
|
||||
become_method: sudo
|
||||
become_method: ansible.builtin.sudo
|
||||
roles:
|
||||
- docker
|
||||
- apps
|
||||
|
|
|
@ -1,41 +1,36 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
base_domain: sapti.me
|
||||
local_domain: local.{{ base_domain }}
|
||||
base_volume: "{{ ssd_mount_point }}/apps"
|
||||
mass_data_volume: "{{ hdd_mount_point }}/apps"
|
||||
|
||||
services:
|
||||
caddy:
|
||||
volume: "{{ base_volume }}/caddy"
|
||||
docker_ipv4: 172.16.3.2
|
||||
version: '2.7.4'
|
||||
apps_base_domain: "example.com"
|
||||
apps_local_domain: "local.{{ apps_base_domain }}"
|
||||
apps_data_root: /apps
|
||||
apps_docker_network: apps_network
|
||||
|
||||
apps_vars:
|
||||
postfix:
|
||||
domain: smtp.{{ base_domain }}
|
||||
volume: "{{ base_volume }}/postfix"
|
||||
domain: smtp.{{ apps_base_domain }}
|
||||
volume: "{{ apps_data_root }}/postfix"
|
||||
version: latest-alpine
|
||||
|
||||
emby:
|
||||
domain: watch.{{ base_domain }}
|
||||
volume: "{{ base_volume }}/emby"
|
||||
data_volume: "{{ mass_data_volume }}/emby"
|
||||
domain: watch.{{ apps_base_domain }}
|
||||
volume: "{{ apps_data_root }}/emby"
|
||||
version: latest
|
||||
|
||||
ipfs:
|
||||
domain: ipfs.{{ local_domain }}
|
||||
gateway_domain: ipfs-gateway.{{ base_domain }}
|
||||
volume: "{{ base_volume }}/ipfs"
|
||||
domain: ipfs.{{ apps_local_domain }}
|
||||
gateway_domain: ipfs-gateway.{{ apps_base_domain }}
|
||||
volume: "{{ apps_data_root }}/ipfs"
|
||||
version: v0.19.2 # https://github.com/ipfs/kubo/issues/9901
|
||||
|
||||
monerod:
|
||||
domain: xmr.{{ base_domain }}
|
||||
volume: "{{ base_volume }}/monerod"
|
||||
domain: xmr.{{ apps_base_domain }}
|
||||
volume: "{{ apps_data_root }}/monerod"
|
||||
version: latest
|
||||
|
||||
nextcloud:
|
||||
domain: cloud.{{ base_domain }}
|
||||
volume: "{{ base_volume }}/nextcloud"
|
||||
domain: cloud.{{ apps_base_domain }}
|
||||
volume: "{{ apps_data_root }}/nextcloud"
|
||||
version: 27-apache
|
||||
postgres_version: 14-alpine
|
||||
redis_version: 7-alpine
|
||||
|
@ -44,8 +39,8 @@ services:
|
|||
version: latest
|
||||
|
||||
pihole:
|
||||
domain: pi-hole.{{ local_domain }}
|
||||
volume: "{{ base_volume }}/pi-hole"
|
||||
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
|
||||
|
@ -57,17 +52,19 @@ services:
|
|||
watchtower:
|
||||
version: '1.5.3'
|
||||
|
||||
local_ipv4s:
|
||||
apps_include: [] # empty == all
|
||||
|
||||
apps_local_ipv4s:
|
||||
- '192.168.1.0/24'
|
||||
- '192.168.8.0/24'
|
||||
|
||||
restic_volumes:
|
||||
apps_restic_volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock:rw"
|
||||
- "{{ services.caddy.volume }}:/mnt/volumes/caddy:ro"
|
||||
- "{{ services.postfix.volume }}:/mnt/volumes/postfix:ro"
|
||||
- "{{ services.emby.volume }}:/mnt/volumes/emby:ro"
|
||||
- "{{ services.nextcloud.volume }}:/mnt/volumes/nextcloud:ro"
|
||||
- "{{ services.pihole.volume }}:/mnt/volumes/pi-hole:ro"
|
||||
- "{{ 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"
|
||||
|
||||
sender_domains:
|
||||
- "{{ services.nextcloud.domain }}"
|
||||
apps_sender_domains:
|
||||
- "{{ apps_vars.nextcloud.domain }}"
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
# vim: ft=yaml.ansible
|
||||
---
|
||||
- name: Build Caddy Docker image
|
||||
community.docker.docker_image:
|
||||
name: custom/caddy:{{ services.caddy.version }}-alpine
|
||||
source: build
|
||||
build:
|
||||
path: "{{ services.caddy.volume }}"
|
||||
dockerfile: caddy.Dockerfile
|
||||
state: present
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Create Emby volume directories
|
||||
ansible.builtin.file:
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Create IPFS Kubo volume directories
|
||||
ansible.builtin.file:
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Create Monero node volume directory
|
||||
ansible.builtin.file:
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Create Nextcloud apache2 directory
|
||||
ansible.builtin.file:
|
||||
|
@ -24,7 +25,7 @@
|
|||
|
||||
- name: Copy Apache2 remoteip config file
|
||||
ansible.builtin.template:
|
||||
src: remoteip.conf.j2
|
||||
src: nextcloud/remoteip.conf.j2
|
||||
dest: "{{ services.nextcloud.volume }}/apache2/remoteip.conf"
|
||||
owner: root
|
||||
mode: u=rw,g=r,o=r
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Create Pi-hole volume base directory
|
||||
ansible.builtin.file:
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Create Docker network for Postfix
|
||||
community.docker.docker_network:
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Deploy Restic with Docker Compose
|
||||
community.docker.docker_compose:
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Deploy snowflake-proxy Docker container
|
||||
community.docker.docker_container:
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Create Docker network for Watchtower
|
||||
community.docker.docker_network:
|
|
@ -1,28 +0,0 @@
|
|||
# vim: ft=yaml.ansible
|
||||
---
|
||||
- name: Copy Docker daemon config file
|
||||
ansible.builtin.template:
|
||||
src: daemon.json.j2
|
||||
dest: /etc/docker/daemon.json
|
||||
owner: root
|
||||
mode: u=rw,g=r,o=r
|
||||
register: daemon_config
|
||||
|
||||
- name: Disable and (re)start Docker daemon
|
||||
ansible.builtin.service:
|
||||
name: "{{ item }}"
|
||||
enabled: false
|
||||
state: "{{ 'restarted' if daemon_config.changed else 'started' }}"
|
||||
loop:
|
||||
- docker.socket
|
||||
- docker.service
|
||||
when: down is undefined or not down
|
||||
|
||||
- name: Configure cron job to prune unused Docker data weekly
|
||||
ansible.builtin.cron:
|
||||
name: Prune unused Docker data
|
||||
cron_file: ansible_docker_prune
|
||||
job: 'docker system prune -fa && docker volume prune -fa'
|
||||
special_time: weekly
|
||||
user: root
|
||||
state: present
|
|
@ -1,50 +1,22 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Add Docker PGP key
|
||||
ansible.builtin.apt_key:
|
||||
keyserver: keyserver.ubuntu.com
|
||||
id: '0x8D81803C0EBFCD88'
|
||||
- name: Create Docker network for apps
|
||||
community.docker.docker_network:
|
||||
name: "{{ apps_docker_network }}"
|
||||
enable_ipv6: true
|
||||
ipam_config:
|
||||
- subnet: 172.17.2.0/24
|
||||
- subnet: fd02::/64
|
||||
state: present
|
||||
|
||||
- name: Add Docker apt repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: 'deb [arch=arm64] https://download.docker.com/linux/ubuntu focal stable'
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Install Docker
|
||||
ansible.builtin.apt:
|
||||
name: "{{ pkgs }}"
|
||||
state: present
|
||||
vars:
|
||||
pkgs:
|
||||
- docker-ce
|
||||
- docker-compose-plugin
|
||||
|
||||
- name: Create docker-compose symlink
|
||||
- name: Create base directories for Docker volumes
|
||||
ansible.builtin.file:
|
||||
name: /usr/local/bin/docker-compose
|
||||
src: /usr/libexec/docker/cli-plugins/docker-compose
|
||||
state: link
|
||||
name: "{{ apps_data_root }}"
|
||||
owner: root
|
||||
mode: u=rwx,g=rx,o=rx
|
||||
state: directory
|
||||
|
||||
- name: Install Python bindings for Docker
|
||||
ansible.builtin.pip:
|
||||
name: "{{ pkgs }}"
|
||||
state: present
|
||||
executable: pip3
|
||||
vars:
|
||||
pkgs:
|
||||
- docker
|
||||
- docker-compose
|
||||
|
||||
- name: Configure Docker
|
||||
ansible.builtin.import_tasks: config.yml
|
||||
tags:
|
||||
- docker_config
|
||||
- reboot
|
||||
|
||||
- name: Set up Docker services
|
||||
ansible.builtin.import_tasks: services.yml
|
||||
tags:
|
||||
- services
|
||||
- reboot
|
||||
- name: Configure apps
|
||||
ansible.builtin.include_tasks: apps/{{ item.key }}.yml
|
||||
loop: "{{ apps_vars | dict2items }}"
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
# vim: ft=yaml.ansible
|
||||
---
|
||||
- name: Create Docker network for services
|
||||
community.docker.docker_network:
|
||||
name: services
|
||||
enable_ipv6: true
|
||||
ipam_config:
|
||||
- subnet: 172.16.0.0/16
|
||||
- subnet: fd02::/64
|
||||
state: present
|
||||
|
||||
- name: Create base directories for Docker volumes
|
||||
ansible.builtin.file:
|
||||
name: "{{ item }}"
|
||||
owner: root
|
||||
mode: u=rwx,g=rx,o=rx
|
||||
state: directory
|
||||
loop:
|
||||
- "{{ base_volume }}"
|
||||
- "{{ mass_data_volume }}"
|
||||
|
||||
- name: Deploy services
|
||||
ansible.builtin.include_tasks: services/{{ item.key }}.yml
|
||||
loop: "{{ services | dict2items }}"
|
||||
when: single_service is not defined
|
||||
|
||||
- name: Deploy single service
|
||||
ansible.builtin.include_tasks: services/{{ single_service }}.yml
|
||||
when: single_service is defined and
|
||||
single_service in services
|
|
@ -1,59 +0,0 @@
|
|||
# vim: ft=yaml.ansible
|
||||
---
|
||||
- name: Create Caddy volume directories
|
||||
ansible.builtin.file:
|
||||
name: "{{ services.caddy.volume }}/{{ dir }}"
|
||||
owner: root
|
||||
mode: u=rwx,g=rx,o=rx
|
||||
state: directory
|
||||
loop:
|
||||
- config
|
||||
- data
|
||||
loop_control:
|
||||
loop_var: dir
|
||||
|
||||
- name: Copy Caddyfile
|
||||
ansible.builtin.template:
|
||||
src: Caddyfile.j2
|
||||
dest: "{{ services.caddy.volume }}/Caddyfile"
|
||||
owner: root
|
||||
mode: u=rw,g=r,o=r
|
||||
|
||||
- name: Copy caddy.Dockerfile
|
||||
ansible.builtin.template:
|
||||
src: caddy.Dockerfile.j2
|
||||
dest: "{{ services.caddy.volume }}/caddy.Dockerfile"
|
||||
owner: root
|
||||
mode: u=rw,g=r,o=r
|
||||
register: dockerfile
|
||||
notify: Build Caddy Docker image
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: Deploy Caddy Docker container
|
||||
community.docker.docker_container:
|
||||
name: caddy
|
||||
state: "{{ 'absent' if down is defined and down else 'started' }}"
|
||||
restart: "{{ restart is defined and restart }}"
|
||||
recreate: "{{ dockerfile.changed or (recreate is defined and recreate) }}"
|
||||
image: custom/caddy:{{ services.caddy.version }}-alpine
|
||||
restart_policy: always
|
||||
default_host_ip: ''
|
||||
networks:
|
||||
- name: services
|
||||
ipv4_address: 172.16.3.2
|
||||
published_ports:
|
||||
- 80:80/tcp
|
||||
- 443:443/tcp
|
||||
- 443:443/udp
|
||||
- 18089:18089/tcp
|
||||
volumes:
|
||||
- "{{ services.caddy.volume }}/Caddyfile:/etc/caddy/Caddyfile:ro"
|
||||
- "{{ services.caddy.volume }}/config:/config:rw"
|
||||
- "{{ services.caddy.volume }}/data:/data:rw"
|
||||
capabilities:
|
||||
- net_bind_service
|
||||
- dac_override
|
||||
cap_drop:
|
||||
- all
|
|
@ -1,96 +0,0 @@
|
|||
{
|
||||
admin off
|
||||
}
|
||||
|
||||
{{ services.emby.domain }} {
|
||||
tls {{ secrets.tls_email }}
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
-Server
|
||||
}
|
||||
|
||||
reverse_proxy emby:8096
|
||||
}
|
||||
|
||||
{{ services.ipfs.domain }} {
|
||||
tls {{ secrets.tls_email }} {
|
||||
dns njalla {{ secrets.caddy.njalla_api_token }}
|
||||
}
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
-Server
|
||||
}
|
||||
|
||||
@local {
|
||||
remote_ip {{ local_ipv4s | join(' ') }}
|
||||
}
|
||||
|
||||
handle @local {
|
||||
reverse_proxy ipfs_kubo:5001
|
||||
}
|
||||
|
||||
respond 403
|
||||
}
|
||||
|
||||
{{ services.ipfs.gateway_domain }},
|
||||
*.ipfs.{{ services.ipfs.gateway_domain }},
|
||||
*.ipns.{{ services.ipfs.gateway_domain }} {
|
||||
tls {{ secrets.tls_email }} {
|
||||
dns njalla {{ secrets.caddy.njalla_api_token }}
|
||||
}
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
-Server
|
||||
}
|
||||
|
||||
reverse_proxy ipfs_kubo:8080
|
||||
}
|
||||
|
||||
{{ services.monerod.domain }}:18089 {
|
||||
tls {{ secrets.tls_email }}
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
-Server
|
||||
}
|
||||
|
||||
reverse_proxy monerod:18089
|
||||
}
|
||||
|
||||
{{ services.nextcloud.domain }} {
|
||||
tls {{ secrets.tls_email }}
|
||||
|
||||
rewrite /.well-known/caldav /remote.php/dav
|
||||
rewrite /.well-known/carddav /remote.php/dav
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
-Server
|
||||
}
|
||||
|
||||
reverse_proxy nextcloud:80
|
||||
}
|
||||
|
||||
{{ services.pihole.domain }} {
|
||||
tls {{ secrets.tls_email }} {
|
||||
dns njalla {{ secrets.caddy.njalla_api_token }}
|
||||
}
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
-Server
|
||||
}
|
||||
|
||||
@local {
|
||||
remote_ip {{ local_ipv4s | join(' ') }}
|
||||
}
|
||||
|
||||
handle @local {
|
||||
reverse_proxy pihole:80
|
||||
}
|
||||
|
||||
respond 403
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
FROM caddy:{{ services.caddy.version }}-builder-alpine AS builder
|
||||
|
||||
RUN xcaddy build v{{ services.caddy.version }} \
|
||||
--with github.com/caddy-dns/njalla
|
||||
|
||||
FROM caddy:{{ services.caddy.version }}-alpine
|
||||
|
||||
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"data-root": "{{ ssd_mount_point }}/docker-runtime",
|
||||
"default-address-pools": [
|
||||
{
|
||||
"base": "172.17.0.0/16",
|
||||
"size": 24
|
||||
}
|
||||
],
|
||||
"experimental": true,
|
||||
"ip6tables": true
|
||||
}
|
|
@ -1,2 +1,4 @@
|
|||
# code: language=ansible-jinja
|
||||
|
||||
RemoteIPHeader X-Forwarded-For
|
||||
RemoteIPInternalProxy {{ services.caddy.docker_ipv4 }}
|
|
@ -1,41 +1,11 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Restart systemd-resolved
|
||||
ansible.builtin.service:
|
||||
name: systemd-resolved
|
||||
state: restarted
|
||||
|
||||
- name: Create .env for apt-update-push
|
||||
ansible.builtin.template:
|
||||
src: env.j2
|
||||
dest: /home/{{ ansible_user }}/apt-update-push/.env
|
||||
owner: root
|
||||
mode: u=rw,go=
|
||||
listen: apt-update-push
|
||||
|
||||
- name: Install apt-update-push
|
||||
ansible.builtin.command: /home/{{ ansible_user }}/apt-update-push/install.sh
|
||||
listen: apt-update-push
|
||||
|
||||
- name: Change GPIO_PIN
|
||||
ansible.builtin.lineinfile:
|
||||
path: /home/{{ ansible_user }}/pi-fan-controller/fancontrol.py
|
||||
regexp: '^GPIO_PIN = '
|
||||
line: GPIO_PIN = 14
|
||||
state: present
|
||||
listen: pi-fan-controller
|
||||
|
||||
- name: Install requirements for pi-fan-controller
|
||||
ansible.builtin.pip:
|
||||
requirements: /home/{{ ansible_user }}/pi-fan-controller/requirements.txt
|
||||
executable: pip3
|
||||
state: present
|
||||
listen: pi-fan-controller
|
||||
|
||||
- name: Install pi-fan-controller
|
||||
ansible.builtin.command: /home/{{ ansible_user }}/pi-fan-controller/script/install
|
||||
listen: pi-fan-controller
|
||||
|
||||
- name: Restart sshd
|
||||
ansible.builtin.service:
|
||||
name: sshd
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Set hostname
|
||||
ansible.builtin.hostname:
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
# vim: ft=yaml.ansible
|
||||
---
|
||||
- name: (Create and) open LUKS containers
|
||||
community.crypto.luks_device:
|
||||
uuid: "{{ item.disk.uuid }}"
|
||||
passphrase: "{{ item.disk.luks_pw }}"
|
||||
name: "{{ item.name }}"
|
||||
type: luks2
|
||||
state: opened
|
||||
loop:
|
||||
- disk: "{{ secrets.hdd }}"
|
||||
name: "{{ hdd_name }}"
|
||||
- disk: "{{ secrets.ssd }}"
|
||||
name: "{{ ssd_name }}"
|
||||
no_log: true
|
||||
|
||||
- name: Create filesystems if they do not exist
|
||||
community.general.filesystem:
|
||||
dev: "{{ item }}"
|
||||
fstype: ext4
|
||||
state: present
|
||||
loop:
|
||||
- /dev/mapper/{{ hdd_name }}
|
||||
- /dev/mapper/{{ ssd_name }}
|
||||
|
||||
- name: Mount filesystems
|
||||
ansible.posix.mount:
|
||||
src: "{{ item.dev }}"
|
||||
path: "{{ item.path }}"
|
||||
fstype: ext4
|
||||
state: ephemeral
|
||||
loop:
|
||||
- dev: /dev/mapper/{{ hdd_name }}
|
||||
path: "{{ hdd_mount_point }}"
|
||||
- dev: /dev/mapper/{{ ssd_name }}
|
||||
path: "{{ ssd_mount_point }}"
|
||||
when: ansible_mounts | selectattr('device', 'eq', item.dev) | length == 0
|
||||
|
||||
- name: Create swapfile
|
||||
community.general.filesize:
|
||||
path: "{{ ssd_mount_point }}/swapfile"
|
||||
size: 2G
|
||||
blocksize: 512B
|
||||
owner: root
|
||||
mode: u=rw,go=
|
||||
when: ansible_swaptotal_mb == 0
|
||||
|
||||
- name: Mount swapfile
|
||||
ansible.builtin.shell: |
|
||||
mkswap {{ ssd_mount_point }}/swapfile
|
||||
swapon {{ ssd_mount_point }}/swapfile
|
||||
when: ansible_swaptotal_mb == 0
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Allow necessary ports in UFW
|
||||
community.general.ufw:
|
||||
|
|
|
@ -1,34 +1,14 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Configure user accounts
|
||||
ansible.builtin.import_tasks: users.yml
|
||||
tags:
|
||||
- users
|
||||
|
||||
- name: Configure system base
|
||||
ansible.builtin.import_tasks: base.yml
|
||||
tags:
|
||||
- base
|
||||
|
||||
- name: Reboot if needed
|
||||
ansible.builtin.import_tasks: reboot.yml
|
||||
tags:
|
||||
- reboot
|
||||
|
||||
- name: Configure firewall
|
||||
ansible.builtin.import_tasks: firewall.yml
|
||||
tags:
|
||||
- firewall
|
||||
|
||||
- name: Configure SSH
|
||||
ansible.builtin.import_tasks: ssh.yml
|
||||
tags:
|
||||
- ssh
|
||||
|
||||
- name: Configure disks
|
||||
ansible.builtin.import_tasks: disks.yml
|
||||
tags:
|
||||
- reboot
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
# vim: ft=yaml.ansible
|
||||
---
|
||||
- name: Check if a reboot is needed
|
||||
ansible.builtin.stat:
|
||||
path: /var/run/reboot-required
|
||||
register: needs_reboot
|
||||
|
||||
- name: Include docker_services role for service shutdown
|
||||
ansible.builtin.include_role:
|
||||
name: docker_services
|
||||
tasks_from: services.yml
|
||||
apply:
|
||||
ignore_errors: true
|
||||
vars:
|
||||
down: true
|
||||
when: needs_reboot.stat.exists or
|
||||
(do_reboot is defined and do_reboot)
|
||||
|
||||
- name: Reboot host
|
||||
ansible.builtin.reboot:
|
||||
when: needs_reboot.stat.exists or
|
||||
(do_reboot is defined and do_reboot)
|
||||
register: rebooted
|
||||
|
||||
- name: Re-gather facts
|
||||
ansible.builtin.setup:
|
||||
filter:
|
||||
- ansible_mounts
|
||||
- ansible_swaptotal_mb
|
||||
when: rebooted.rebooted is defined and rebooted.rebooted
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Allow SSH login with public keys
|
||||
ansible.builtin.lineinfile:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Add users
|
||||
ansible.builtin.user:
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
topic={{ secrets.ntfy_topic }}
|
||||
hour=20
|
4
roles/docker/defaults/main.yml
Normal file
4
roles/docker/defaults/main.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
docker_data_root: /var/lib/docker
|
7
roles/docker/handlers/main.yml
Normal file
7
roles/docker/handlers/main.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Restart Docker daemon
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: restarted
|
46
roles/docker/tasks/main.yml
Normal file
46
roles/docker/tasks/main.yml
Normal file
|
@ -0,0 +1,46 @@
|
|||
# vim: ft=yaml.ansible
|
||||
# code: language=ansible
|
||||
---
|
||||
- name: Add Docker PGP key
|
||||
ansible.builtin.apt_key:
|
||||
keyserver: keyserver.ubuntu.com
|
||||
id: '0x8D81803C0EBFCD88'
|
||||
state: present
|
||||
|
||||
- name: Add Docker apt repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: 'deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable'
|
||||
update_cache: true
|
||||
state: present
|
||||
|
||||
- name: Install Docker
|
||||
ansible.builtin.apt:
|
||||
name: "{{ pkgs }}"
|
||||
state: present
|
||||
vars:
|
||||
pkgs:
|
||||
- docker-ce
|
||||
- docker-compose-plugin
|
||||
|
||||
- name: Copy Docker daemon config file
|
||||
ansible.builtin.template:
|
||||
src: etc/docker/daemon.json.j2
|
||||
dest: /etc/docker/daemon.json
|
||||
owner: root
|
||||
mode: u=rw,g=r,o=r
|
||||
notify: Restart Docker daemon
|
||||
|
||||
- name: Ensure Docker daemon is enabled and running
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
- name: Configure cron job to prune unused Docker data weekly
|
||||
ansible.builtin.cron:
|
||||
name: Prune unused Docker data
|
||||
cron_file: ansible_docker_prune
|
||||
job: 'docker system prune -fa && docker volume prune -fa'
|
||||
special_time: weekly
|
||||
user: root
|
||||
state: present
|
5
roles/docker/templates/etc/docker/daemon.json.j2
Normal file
5
roles/docker/templates/etc/docker/daemon.json.j2
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"data-root": "{{ docker_data_root }}",
|
||||
"experimental": true,
|
||||
"ip6tables": true
|
||||
}
|
Loading…
Reference in a new issue