Unify app config in one file + upload Compose files

This commit is contained in:
Sam A. 2023-11-03 23:38:15 +01:00
parent 423dbe2f7f
commit 4da17ee4f5
Signed by: samsapti
GPG Key ID: CBBBE7371E81C4EA
22 changed files with 180 additions and 231 deletions

View File

@ -3,3 +3,6 @@
---
base_domain: sapti.me
local_domain: local.{{ base_domain }}
db_passwords: "{{ vault_db_passwords }}"
redis_passwords: "{{ vault_redis_passwords }}"

View File

@ -3,3 +3,6 @@
---
base_domain: staging.sapti.me
local_domain: local.{{ base_domain }}
db_passwords: "{{ vault_db_passwords }}"
redis_passwords: "{{ vault_redis_passwords }}"

View File

@ -3,7 +3,6 @@
---
apps_include:
- postfix
- emby
- nextcloud
- restic
- watchtower

View File

@ -3,7 +3,6 @@
---
apps_include:
- postfix
- emby
- nextcloud
- restic
- watchtower

View File

@ -4,7 +4,8 @@
apps_base_domain: "example.com"
apps_local_domain: "local.{{ apps_base_domain }}"
apps_data_root: /apps
apps_docker_network: apps_network
apps_shared_docker_network: apps_network
apps_postfix_docker_network: postfix_network
apps_vars:
postfix:
@ -24,12 +25,12 @@ apps_vars:
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
version: v0.23.0
monerod:
domain: xmr.{{ apps_base_domain }}
volume: "{{ apps_data_root }}/monerod"
extra_tasks: false
extra_tasks: true
version: latest
nextcloud:
@ -47,15 +48,15 @@ apps_vars:
restic:
repo: /restic
extra_tasks: false
version: '1.7'
version: '1.7.0'
watchtower:
extra_tasks: false
version: '1.5.3'
version: '1.6.0'
apps_include: "{{ apps_vars | dict2items | map(attribute='key') | list }}"
apps_restic_volumes:
apps_restic_volumes: |
- "/var/run/docker.sock:/var/run/docker.sock:rw"
- "{{ apps_vars.postfix.volume }}:/mnt/volumes/postfix:ro"
- "{{ apps_vars.emby.volume }}:/mnt/volumes/emby:ro"

View File

@ -5,7 +5,7 @@
ansible.builtin.file:
name: "{{ app_vars.volume }}"
owner: root
mode: u=rwx,g=rx,o=rx
mode: u=rwx,go=
state: directory
- name: Upload Compose file for app {{ app_name }}
@ -13,7 +13,7 @@
src: compose-files/{{ app_name }}.yml.j2
dest: "{{ app_vars.volume }}/docker-compose.yml"
owner: root
mode: u=rw,g=r,o=r
mode: u=rw,go=
- name: Run extra configuration tasks for app {{ app_name }}
ansible.builtin.include_tasks: extra_tasks/{{ app_name }}.yml

View File

@ -1,37 +0,0 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create subfolders for Emby data
ansible.builtin.file:
name: "{{ dir }}"
owner: '1000'
mode: u=rwx,g=rx,o=rx
state: directory
loop:
- "{{ apps_vars.emby.volume }}/programdata"
- "{{ apps_vars.emby.data_volume }}/tvshows"
- "{{ apps_vars.emby.data_volume }}/movies"
loop_control:
loop_var: dir
- name: Deploy Emby Docker container
community.docker.docker_container:
name: emby
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:{{ apps_vars.emby.version }}
restart_policy: always
env:
UID: '1000'
GID: '1000'
networks:
- name: services
aliases:
- emby
volumes:
- "{{ 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

@ -19,28 +19,3 @@
dest: "{{ apps_vars.ipfs.volume }}/ipfs-config.sh"
owner: root
mode: u=rwx,g=rx,o=rx
- name: Deploy IPFS Kubo Docker container
community.docker.docker_container:
name: ipfs_kubo
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:{{ apps_vars.ipfs.version }}
restart_policy: always
default_host_ip: ''
env:
IPFS_DOMAIN: "{{ apps_vars.ipfs.gateway_domain }}"
IPFS_PROFILE: server
LOCAL_DOMAIN: "{{ apps_vars.ipfs.domain }}"
networks:
- name: services
aliases:
- ipfs_kubo
volumes:
- "{{ 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

@ -1,27 +1,9 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Monero node volume directory
- name: Create subfolder for Monero blockchain
ansible.builtin.file:
name: "{{ apps_vars.monerod.volume }}"
name: "{{ apps_vars.monerod.volume }}/blockchain"
owner: '1000'
mode: u=rwx,g=rx,o=rx
state: directory
- name: Deploy Monero node Docker container
community.docker.docker_container:
name: monerod
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:{{ apps_vars.monerod.version }}
restart_policy: always
default_host_ip: ''
networks:
- name: services
aliases:
- monerod
volumes:
- "{{ apps_vars.monerod.volume }}:/home/monero/.bitmonero:rw"
published_ports:
- 18080:18080/tcp

View File

@ -8,7 +8,7 @@
mode: u=rwx,g=rx,o=rx
state: directory
- name: Create Nextcloud app subfolder
- name: Create subfolder for Nextcloud data
ansible.builtin.file:
name: "{{ apps_vars.nextcloud.volume }}/app"
owner: root

View File

@ -1,31 +1,9 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Docker network for Postfix
community.docker.docker_network:
name: postfix
state: present
- name: Create subfolder for Postfix DKIM keys
ansible.builtin.file:
name: "{{ apps_vars.postfix.volume }}/dkim"
owner: root
mode: u=rwx,g=rx,o=rx
state: directory
- name: Deploy Postfix Docker container
community.docker.docker_container:
name: postfix
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:{{ apps_vars.postfix.version }}
restart_policy: always
env:
ALLOWED_SENDER_DOMAINS: "{{ sender_domains | join(' ') }}"
HOSTNAME: "{{ apps_vars.postfix.domain }}"
DKIM_AUTOGENERATE: "true"
networks:
- name: postfix
volumes:
- "{{ apps_vars.postfix.volume }}/dkim:/etc/opendkim/keys:rw"

View File

@ -1,68 +0,0 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Deploy Restic with Docker Compose
community.docker.docker_compose:
project_name: restic
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:
backup:
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 }}:{{ apps_vars.restic.repo }}
RESTIC_PASSWORD: "{{ secrets.restic.repo_pw }}"
RESTIC_BACKUP_SOURCES: /mnt/volumes
RESTIC_BACKUP_ARGS: >-
--tag docker-volumes
--exclude '*.tmp'
--verbose
RESTIC_FORGET_ARGS: >-
--keep-last 10
--keep-daily 7
--keep-weekly 5
--keep-monthly 12
PRE_COMMANDS: |-
docker exec -u www-data nextcloud_app_1 php occ maintenance:mode --on
POST_COMMANDS_EXIT: |-
docker exec -u www-data nextcloud_app_1 php occ maintenance:mode --off
B2_ACCOUNT_ID: "{{ secrets.restic.b2.id }}"
B2_ACCOUNT_KEY: "{{ secrets.restic.b2.key }}"
TZ: "{{ timezone }}"
volumes: "{{ restic_volumes }}"
prune:
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 }}:{{ apps_vars.restic.repo }}
RESTIC_PASSWORD: "{{ secrets.restic.repo_pw }}"
RESTIC_PRUNE_ARGS: >-
--verbose
B2_ACCOUNT_ID: "{{ secrets.restic.b2.id }}"
B2_ACCOUNT_KEY: "{{ secrets.restic.b2.key }}"
TZ: "{{ timezone }}"
check:
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 }}:{{ apps_vars.restic.repo }}
RESTIC_PASSWORD: "{{ secrets.restic.repo_pw }}"
RESTIC_CHECK_ARGS: >-
--verbose
B2_ACCOUNT_ID: "{{ secrets.restic.b2.id }}"
B2_ACCOUNT_KEY: "{{ secrets.restic.b2.key }}"
TZ: "{{ timezone }}"

View File

@ -1,12 +0,0 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Deploy snowflake-proxy Docker container
community.docker.docker_container:
name: snowflake-proxy
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:{{ apps_vars.snowflake.version }}
restart_policy: always
network_mode: host

View File

@ -1,22 +0,0 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Docker network for Watchtower
community.docker.docker_network:
name: watchtower
state: present
- name: Deploy Watchtower Docker container
community.docker.docker_container:
name: watchtower
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:{{ apps_vars.watchtower.version }}
restart_policy: always
networks:
- name: watchtower
env:
WATCHTOWER_POLL_INTERVAL: '3600'
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw

View File

@ -3,23 +3,29 @@
---
- name: Create Docker network for apps
community.docker.docker_network:
name: "{{ apps_docker_network }}"
name: "{{ apps_shared_docker_network }}"
enable_ipv6: true
ipam_config:
- subnet: 172.17.2.0/24
- subnet: fd02::/64
state: present
- name: Create base directories for Docker volumes
- name: Create Docker network for Postfix
community.docker.docker_network:
name: "{{ apps_postfix_docker_network }}"
state: present
when: "'postfix' in apps_include"
- name: Create base folder for apps
ansible.builtin.file:
name: "{{ apps_data_root }}"
owner: root
mode: u=rwx,g=rx,o=rx
mode: u=rwx,go=
state: directory
- name: Configure apps
ansible.builtin.include_tasks:
file: apps.yml
file: configure_app.yml
vars:
app_name: "{{ item }}"
app_vars: "{{ apps_vars[item] }}"

View File

@ -0,0 +1,26 @@
# code: language=ansible-jinja
version: "3.8"
services:
kubo:
image: ipfs/kubo:{{ apps_vars.ipfs.version }}
restart: always
environment:
IPFS_DOMAIN: {{ apps_vars.ipfs.gateway_domain }}
IPFS_PROFILE: server
LOCAL_DOMAIN: {{ apps_vars.ipfs.domain }}
networks:
{{ apps_shared_docker_network }}:
aliases:
- ipfs
ports:
- 4001:4001/tcp
- 4001:4001/udp
volumes:
- "./ipfs-config.sh:/container-init.d/ipfs-config.sh:ro"
- "./data:/data/ipfs:rw"
- "./staging:/export:rw"
networks:
{{ apps_shared_docker_network }}:
external: true

View File

@ -0,0 +1,19 @@
# code: language=ansible-jinja
version: "3.8"
services:
node:
image: sethsimmons/simple-monerod:{{ apps_vars.monerod.version }}
restart: always
networks:
{{ apps_shared_docker_network }}:
aliases:
- monerod
ports:
- 18080:18080/tcp
volumes:
- "./blockchain:/home/monero/.bitmonero:rw"
networks:
{{ apps_shared_docker_network }}:
external: true

View File

@ -5,7 +5,7 @@ services:
redis:
image: redis:{{ apps_vars.nextcloud.redis_version }}
restart: always
command: redis-server --requirepass {{ secrets.nextcloud.redis_pw }}
command: redis-server --requirepass {{ redis_passwords.nextcloud }}
tmpfs:
- /var/lib/redis
@ -16,9 +16,9 @@ services:
POSTGRES_HOST: "{{ db_host_ip }}"
POSTGRES_DB: nextcloud
POSTGRES_USER: nextcloud
POSTGRES_PASSWORD: {{ secrets.nextcloud.postgres_pw }}
POSTGRES_PASSWORD: {{ db_passwords.nextcloud }}
REDIS_HOST: redis
REDIS_HOST_PASSWORD: {{ secrets.nextcloud.redis_pw }}
REDIS_HOST_PASSWORD: {{ redis_passwords.nextcloud }}
MAIL_FROM_ADDRESS: noreply
MAIL_DOMAIN: {{ apps_vars.nextcloud.domain }}
SMTP_AUTHTYPE: PLAIN
@ -33,13 +33,13 @@ services:
PHP_UPLOAD_LIMIT: 16G
networks:
default:
postfix:
{{ apps_docker_network }}:
{{ apps_postfix_docker_network }}:
{{ apps_shared_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"
- "./app:/var/www/html:rw"
- "./apache2/remoteip.conf:/etc/apache2/conf-enabled/remoteip.conf:ro"
depends_on:
- redis
@ -48,12 +48,12 @@ services:
restart: always
entrypoint: /cron.sh
volumes:
- "{{ apps_vars.nextcloud.volume }}/app:/var/www/html:rw"
- "./app:/var/www/html:rw"
depends_on:
- app
networks:
postfix:
{{ apps_postfix_docker_network }}:
external: true
{{ apps_docker_network }}:
{{ apps_shared_docker_network }}:
external: true

View File

@ -0,0 +1,19 @@
# code: language=ansible-jinja
version: "3.8"
services:
app:
image: boky/postfix:{{ apps_vars.postfix.version }}
restart: always
environment:
ALLOWED_SENDER_DOMAINS: "{{ apps_sender_domains | join(' ') }}"
HOSTNAME: "{{ apps_vars.postfix.domain }}"
DKIM_AUTOGENERATE: "true"
networks:
- {{ apps_postfix_docker_network }}
volumes:
- "./dkim:/etc/opendkim/keys:rw"
networks:
{{ apps_postfix_docker_network }}:
external: true

View File

@ -0,0 +1,59 @@
# code: language=ansible-jinja
version: "3.8"
services:
backup:
image: mazzolino/restic:{{ apps_vars.restic.version }}
restart: always
environment:
RUN_ON_STARTUP: false
BACKUP_CRON: 0 0 3 * * *
RESTIC_REPOSITORY: b2:{{ restic.b2.bucket }}:{{ restic.repo }}
RESTIC_PASSWORD: {{ restic.repo_password }}
RESTIC_BACKUP_SOURCES: /mnt/volumes
RESTIC_BACKUP_ARGS: >-
--tag docker-volumes
--exclude '*.tmp'
--verbose
RESTIC_FORGET_ARGS: >-
--keep-last 10
--keep-daily 7
--keep-weekly 5
--keep-monthly 12
PRE_COMMANDS: |-
docker exec -u www-data nextcloud_app_1 php occ maintenance:mode --on
POST_COMMANDS_EXIT: |-
docker exec -u www-data nextcloud_app_1 php occ maintenance:mode --off
B2_ACCOUNT_ID: {{ restic.b2.id }}
B2_ACCOUNT_KEY: {{ restic.b2.key }}
TZ: {{ timezone }}
volumes:
{{ apps_restic_volumes }}
prune:
image: mazzolino/restic:{{ apps_vars.restic.version }}
restart: always
environment:
RUN_ON_STARTUP: false
PRUNE_CRON: 0 0 4 * * *
RESTIC_REPOSITORY: b2:{{ restic.b2.bucket }}:{{ restic.repo }}
RESTIC_PASSWORD: {{ restic.repo_password }}
RESTIC_PRUNE_ARGS: >-
--verbose
B2_ACCOUNT_ID: {{ restic.b2.id }}
B2_ACCOUNT_KEY: {{ restic.b2.key }}
TZ: {{ timezone }}
check:
image: mazzolino/restic:{{ apps_vars.restic.version }}
restart: always
environment:
RUN_ON_STARTUP: false
CHECK_CRON: 0 0 5 * * *
RESTIC_REPOSITORY: b2:{{ restic.b2.bucket }}:{{ restic.repo }}
RESTIC_PASSWORD: {{ restic.repo_password }}
RESTIC_CHECK_ARGS: >-
--verbose
B2_ACCOUNT_ID: {{ restic.b2.id }}
B2_ACCOUNT_KEY: {{ restic.b2.key }}
TZ: {{ timezone }}

View File

@ -0,0 +1,8 @@
# code: language=ansible-jinja
version: "3.8"
services:
proxy:
image: thetorproject/snowflake-proxy:{{ apps_vars.snowflake.version }}
restart: always
network_mode: host

View File

@ -0,0 +1,11 @@
# code: language=ansible-jinja
version: "3.8"
services:
app:
image: containrrr/watchtower:{{ apps_vars.watchtower.version }}
restart: always
environment:
WATCHTOWER_POLL_INTERVAL: 3600
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:rw"