From d4a8216680b21c7ea5504e06e72e6ad9a7230e0e Mon Sep 17 00:00:00 2001 From: Javier Feliz Date: Mon, 21 Jul 2025 18:00:18 -0400 Subject: [PATCH] Added linkwarden and some maintenance stuff --- group_vars/{ => all}/all.yml | 0 group_vars/all/secrets.yml | 22 ++++++++ .../maintenance/backup_postgres_instances.yml | 13 +++++ playbooks/maintenance/setup-pg-backup.yml | 56 +++++++++++++++++++ playbooks/nodes/portainer-main.yml | 9 +++ playbooks/proxy/external.yml | 6 +- roles/apps/linkwarden/defaults/main.yml | 0 roles/apps/linkwarden/tasks/main.yml | 34 +++++++++++ roles/util/mount_nfs/tasks/main.yml | 11 ++-- 9 files changed, 141 insertions(+), 10 deletions(-) rename group_vars/{ => all}/all.yml (100%) create mode 100644 group_vars/all/secrets.yml create mode 100644 playbooks/maintenance/backup_postgres_instances.yml create mode 100644 playbooks/maintenance/setup-pg-backup.yml create mode 100644 playbooks/nodes/portainer-main.yml create mode 100644 roles/apps/linkwarden/defaults/main.yml create mode 100644 roles/apps/linkwarden/tasks/main.yml diff --git a/group_vars/all.yml b/group_vars/all/all.yml similarity index 100% rename from group_vars/all.yml rename to group_vars/all/all.yml diff --git a/group_vars/all/secrets.yml b/group_vars/all/secrets.yml new file mode 100644 index 0000000..1401540 --- /dev/null +++ b/group_vars/all/secrets.yml @@ -0,0 +1,22 @@ +$ANSIBLE_VAULT;1.1;AES256 +39373266356536656663653438363463633264366465316163353764366463383431376131643433 +6433303537373830643432633533663334326632656364390a303161333635343966393537303665 +65383565643732386333613139623235623262353834313464333136383637666361373764333164 +3138643563373137380a363934613635343431346339393130643266666532613438656535386535 +62643332656437326131336366396365666333346230613863306137353162313032393262303366 +38663932343962323161643836353031303638623037303831656464663664373265396163643661 +36623638353337663132336164336466383139613264353136663833633438303835333436386430 +61363832643136323933343261356236396363396266393932343732653664393931653237373832 +37303665353764343466333534323833396532373563663863363766303230616538343535316334 +31663139626562393837393163356337303236363739333738363735386434656437366232636666 +64393031323964313239346436323162356231366662623635323834356339323866653864333231 +61613464303065666262623466343165393238373232636637376434636538316639393437366236 +36386337313361383632333737313437386336326633353934656566343064636237623361366262 +63323632613336303237613764376636316166666530666136653661336232333536393231663936 +33396661636331663362663930323466346466383236353830313966363133366137353063613033 +31623936343865326336366361396464383733393561663962613039653466366235666364363162 +35623865646438336532313231343633663762643066303632353762343435663630363562313332 +37363237313662313933636630396231343134383034366330616134633233663537393334373332 +65343763313133353035623438646361613038333732613438303336643861333034383531336335 +34613530656664353238363231386565306134366131373538623631616334616463356637356164 +3939 diff --git a/playbooks/maintenance/backup_postgres_instances.yml b/playbooks/maintenance/backup_postgres_instances.yml new file mode 100644 index 0000000..bd6af84 --- /dev/null +++ b/playbooks/maintenance/backup_postgres_instances.yml @@ -0,0 +1,13 @@ +--- +- name: Mount backup share to a VM + hosts: prod_services + become: true + tasks: + - name: Mount the backup share to the VM + ansible.builtin.include_role: + role: util/mount_nfs + vars: + mount_to: "/mnt/backups" + share: "backups" + - name: Backup instances + ansible.builtin.command: \ No newline at end of file diff --git a/playbooks/maintenance/setup-pg-backup.yml b/playbooks/maintenance/setup-pg-backup.yml new file mode 100644 index 0000000..87cf967 --- /dev/null +++ b/playbooks/maintenance/setup-pg-backup.yml @@ -0,0 +1,56 @@ +- name: Setup hourly Postgres backup + hosts: prod_services + become: true + vars: + backup_path: /mnt/backups/server_postgres_prod + pg_container: postgres_main + pg_password: password + script_path: /usr/local/bin/pg_backup.sh + + tasks: + - name: Mount the backup share to the VM + ansible.builtin.include_role: + role: util/mount_nfs + vars: + mount_to: "/mnt/backups" + share: "backups" + + - name: Create the backup script + ansible.builtin.copy: + dest: "{{ script_path }}" + mode: '0755' + content: | + #!/bin/bash + BACKUP_FILE_NAME="pg_backup_$(date +%F_%H-%M-%S).sql" + BACKUP_PATH="{{ backup_path }}" + echo "Running pg_dumpall" + docker exec -t {{ pg_container }} bash -c 'PGPASSWORD={{ pg_password }} pg_dumpall -U postgres' > "$BACKUP_PATH/$BACKUP_FILE_NAME" + echo "Compressing the backup" + gzip "$BACKUP_PATH/$BACKUP_FILE_NAME" + # 3 days = 72 hours = 4320 minutes + echo "Deleting backups older than 72 hours" + find "$BACKUP_PATH" -type f -name "*.sql.gz" -mmin +4320 -print -delete + + - name: Add logrotate config for pg_backup + ansible.builtin.copy: + dest: /etc/logrotate.d/pg_backup + owner: root + group: root + mode: '0644' + content: | + /var/log/pg_backup.log { + daily + rotate 7 + compress + missingok + notifempty + create 0644 root root + } + + + + - name: Set up hourly cron job for postgres backup + ansible.builtin.cron: + name: "Hourly Postgres Backup" + job: "{{ script_path }} >> /var/log/pg_backup.log 2>&1" + minute: "0" diff --git a/playbooks/nodes/portainer-main.yml b/playbooks/nodes/portainer-main.yml new file mode 100644 index 0000000..5cd9eb8 --- /dev/null +++ b/playbooks/nodes/portainer-main.yml @@ -0,0 +1,9 @@ +--- +- name: Deploy apps to portainer main + hosts: portainer_main + become: true + roles: + - role: apps/linkwarden + vars: + port: 5010 + url: "https://linkwarden.thegrind.dev" \ No newline at end of file diff --git a/playbooks/proxy/external.yml b/playbooks/proxy/external.yml index 2c9131a..18c3e74 100644 --- a/playbooks/proxy/external.yml +++ b/playbooks/proxy/external.yml @@ -45,9 +45,6 @@ - name: "pdf" host: "{{ lookup('hostip', 'apps') }}" port: 7075 - - name: "linkwarden" - host: "{{ lookup('hostip', 'portainer_main') }}" - port: 5010 - name: "vaultwarden" host: "{{ lookup('hostip', 'apps') }}" port: 7072 @@ -71,6 +68,9 @@ - name: "thegrind.dev" dynamic_dns: true sites: + - name: "linkwarden" + host: "{{ lookup('hostip', 'portainer_main') }}" + port: 5010 - name: "blog" host: "{{ lookup('hostip', 'portainer_main') }}" port: 5007 diff --git a/roles/apps/linkwarden/defaults/main.yml b/roles/apps/linkwarden/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/apps/linkwarden/tasks/main.yml b/roles/apps/linkwarden/tasks/main.yml new file mode 100644 index 0000000..69624df --- /dev/null +++ b/roles/apps/linkwarden/tasks/main.yml @@ -0,0 +1,34 @@ +- name: Create app DB + ansible.builtin.include_role: + role: app/database + vars: + app_name: "linkwarden" + +- name: Set up container data folder + ansible.builtin.include_role: + role: docker/container-data + vars: + dir_name: "linkwarden" + +- name: Deploy linkwarden container + community.docker.docker_container: + name: linkwarden + image: ghcr.io/linkwarden/linkwarden:latest + restart_policy: always + state: started + restart: true + env: + DATABASE_URL: "postgresql://linkwarden:password@{{ pg_host }}:{{ pg_port }}/linkwarden" + NEXT_PUBLIC_AUTHENTIK_ENABLED: "true" + AUTHENTIK_ISSUER: "https://auth.thegrind.dev/application/o/linkwarden" + AUTHENTIK_CLIENT_ID: "{{ linkwarden.authentik_client_id }}" + AUTHENTIK_CLIENT_SECRET: "{{ linkwarden.authentik_client_secret }}" + NEXT_PUBLIC_DISABLE_REGISTRATION: "true" + AUTHENTIK_CUSTOM_NAME: "BlinkerAuth" + NEXT_PUBLIC_CREDENTIALS_ENABLED: "false" + NEXTAUTH_SECRET: "{{ linkwarden.nextauth_secret }}" + NEXTAUTH_URL: "{{ url }}/api/v1/auth" + ports: + - "{{ port }}:3000" + volumes: + - "{{ container_data_base_path }}/linkwarden:/data/data" \ No newline at end of file diff --git a/roles/util/mount_nfs/tasks/main.yml b/roles/util/mount_nfs/tasks/main.yml index 9173c44..6440141 100755 --- a/roles/util/mount_nfs/tasks/main.yml +++ b/roles/util/mount_nfs/tasks/main.yml @@ -3,19 +3,16 @@ ansible.builtin.package: name: nfs-common state: present - become: true - name: Create mount point directory ansible.builtin.file: - path: "{{ mount_path }}" + path: "{{ mount_to }}" state: directory mode: '0777' - become: true - name: Mount share ansible.posix.mount: - src: "{{ mount_host }}:{{ share }}" - path: "{{ mount_path }}" + src: "{{ lookup('hostip', 'nas') }}:/mnt/main/{{ share }}" + path: "{{ mount_to }}" fstype: nfs - state: mounted - become: true \ No newline at end of file + state: mounted \ No newline at end of file