From 27daf9031b34ce39835c37e5ba115268b6b5762f Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Fri, 22 Oct 2021 13:02:01 +0200 Subject: [PATCH] Add miniflux deployment Contains default credentials but these should be overwritten with group or host -destined variables. Add default credentials Hide real credential files from git --- .gitignore | 6 ++- ansible.cfg | 5 ++ inv-dev.yml | 6 +-- roles/miniflux/README.md | 32 ++++++++++++ roles/miniflux/defaults/main.yml | 16 ++++++ roles/miniflux/handlers/main.yml | 53 ++++++++++++++++++++ roles/miniflux/meta/main.yml | 14 ++++++ roles/miniflux/tasks/main.yml | 24 +++++++++ roles/miniflux/templates/docker-stack.yml.j2 | 48 ++++++++++++++++++ roles/miniflux/templates/upstream.json.j2 | 38 ++++++++++++++ roles/miniflux/vars/main.yml | 7 +++ site-dev.yml | 1 + site.yml | 1 + 13 files changed, 244 insertions(+), 7 deletions(-) create mode 100644 roles/miniflux/README.md create mode 100644 roles/miniflux/defaults/main.yml create mode 100644 roles/miniflux/handlers/main.yml create mode 100644 roles/miniflux/meta/main.yml create mode 100644 roles/miniflux/tasks/main.yml create mode 100644 roles/miniflux/templates/docker-stack.yml.j2 create mode 100644 roles/miniflux/templates/upstream.json.j2 create mode 100644 roles/miniflux/vars/main.yml diff --git a/.gitignore b/.gitignore index d7ad54d..3a8c627 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,10 @@ ### ansible private files ### inv-prod.yml -group_vars/staging.yml -host_vars/ssdnodes.yml +group_vars/staging* +group_vars/prod* +host_vars/* +vault_pass.txt ### Linux ### *~ diff --git a/ansible.cfg b/ansible.cfg index 5f7a44a..5b5f05f 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,3 +1,8 @@ [defaults] inventory = ./inv-dev.yml +# ask_vault_pass = True +vault_password_file = vault_pass.txt + +[privilege_escalation] +become_ask_pass = True diff --git a/inv-dev.yml b/inv-dev.yml index d1762fd..29f8c41 100644 --- a/inv-dev.yml +++ b/inv-dev.yml @@ -1,11 +1,7 @@ -stable: +testing: hosts: tau: docker_swarm_manager_node: hosts: tau: - -testing: - hosts: - tau: diff --git a/roles/miniflux/README.md b/roles/miniflux/README.md new file mode 100644 index 0000000..f1ce4c1 --- /dev/null +++ b/roles/miniflux/README.md @@ -0,0 +1,32 @@ +# miniflux + +A minimalist rss feed reader. +Deployed in a docker swarm with caddy. + +## Defaults + +``` +miniflux_upstream_file_dir: "{{ docker_stack_files_dir }}/{{ stack_name }}" +``` + +The on-target directory where the proxy configuration file should be stashed. + +``` +miniflux_use_https: true +``` + +Whether the service should be reachable through http (port 80) or through https (port 443) and provision an https certificate. Usually you will want this to stay `true`. + +``` +miniflux_version: latest +``` + +The docker image version to be used in stack creation. + +``` +subdomain_alias: rss +``` + +If the deployed container should be served over a uri that is not the stack name. +By default, it will be set to `rss.yourdomain.com` - +if this option is not set it will be served on `miniflux.yourdomain.com` instead. diff --git a/roles/miniflux/defaults/main.yml b/roles/miniflux/defaults/main.yml new file mode 100644 index 0000000..61bfc79 --- /dev/null +++ b/roles/miniflux/defaults/main.yml @@ -0,0 +1,16 @@ +--- + +miniflux_version: latest + +miniflux_upstream_file_dir: "{{ docker_stack_files_dir }}/{{ stack_name }}" + +miniflux_use_https: true + +# the subdomain link miniflux will be reachable under +subdomain_alias: rss + +# Should ideally be overwritten in encrypted group/host vars +miniflux_admin_username: MyAdmin +miniflux_admin_password: MyPassword +miniflux_postgres_user: MyPostgresUser +miniflux_postgres_password: MyPostgresPassword diff --git a/roles/miniflux/handlers/main.yml b/roles/miniflux/handlers/main.yml new file mode 100644 index 0000000..864d7c6 --- /dev/null +++ b/roles/miniflux/handlers/main.yml @@ -0,0 +1,53 @@ +## Register reverse proxy +- name: Ensure upstream directory exists + ansible.builtin.file: + path: "{{ miniflux_upstream_file_dir }}" + state: directory + mode: '0755' + become: yes + listen: "update miniflux upstream" + +- name: Update upstream template + ansible.builtin.template: + src: upstream.json.j2 + dest: "{{ miniflux_upstream_file_dir }}/upstream.json" + become: yes + listen: "update miniflux upstream" + +# figure out if upstream id exists +- name: check {{ stack_name }} upstream + community.docker.docker_container_exec: + container: "{{ caddy_container_id }}" + command: > + curl localhost:2019/id/{{ stack_name }}_upstream/ + changed_when: False + register: result + become: yes + listen: "update miniflux upstream" + +# upstream already exists, patch it +- name: remove old {{ stack_name }} upstream + community.docker.docker_container_exec: + container: "{{ caddy_container_id }}" + command: > + curl -X DELETE localhost:2019/id/{{ stack_name }}_upstream/ + become: yes + when: (result.stdout | from_json)['error'] is not defined + listen: "update miniflux upstream" + +# upstream has to be created +- name: add {{ stack_name }} upstream + community.docker.docker_container_exec: + container: "{{ caddy_container_id }}" + command: > + curl -X POST -H "Content-Type: application/json" -d @{{ miniflux_upstream_file_dir }}/upstream.json localhost:2019/config/apps/http/servers/{{ (miniflux_use_https == True) | ternary(caddy_https_server_name, caddy_http_server_name) }}/routes/0/ + become: yes + listen: "update miniflux upstream" + +- name: Ensure upstream directory is gone again + ansible.builtin.file: + path: "{{ miniflux_upstream_file_dir }}" + state: absent + become: yes + listen: "update miniflux upstream" + diff --git a/roles/miniflux/meta/main.yml b/roles/miniflux/meta/main.yml new file mode 100644 index 0000000..50da3df --- /dev/null +++ b/roles/miniflux/meta/main.yml @@ -0,0 +1,14 @@ +--- + +galaxy_info: + author: Marty Oehme + description: Installs miniflux as a docker stack service + license: GPL-3.0-only + min_ansible_version: 2.9 + galaxy_tags: [] + + +dependencies: + - docker + - docker-swarm + - caddy diff --git a/roles/miniflux/tasks/main.yml b/roles/miniflux/tasks/main.yml new file mode 100644 index 0000000..e4dd0ab --- /dev/null +++ b/roles/miniflux/tasks/main.yml @@ -0,0 +1,24 @@ +--- +## install miniflux container +- name: Check upstream status + community.docker.docker_container_exec: + container: "{{ caddy_container_id }}" + command: > + curl localhost:2019/id/{{ stack_name }}_upstream/ + register: result + changed_when: (result.stdout | from_json) != (lookup('template', 'upstream.json.j2') | from_yaml) + become: yes + notify: "update miniflux upstream" + +- name: Deploy miniflux to swarm + community.general.docker_stack: + name: "{{ stack_name }}" + state: present + prune: yes + compose: + - "{{ stack_compose }}" + become: yes + tags: + - docker-swarm + notify: "update miniflux upstream" + diff --git a/roles/miniflux/templates/docker-stack.yml.j2 b/roles/miniflux/templates/docker-stack.yml.j2 new file mode 100644 index 0000000..4481c75 --- /dev/null +++ b/roles/miniflux/templates/docker-stack.yml.j2 @@ -0,0 +1,48 @@ +version: '3.7' + +services: + app: + image: {{ stack_image }}:{{ miniflux_version }} + networks: + - "{{ docker_swarm_public_network_name }}" + - backend + healthcheck: + test: ["CMD", "/usr/bin/miniflux", "-healthcheck", "auto"] + interval: 1m + timeout: 10s + retries: 3 + start_period: 1m + environment: + - DATABASE_URL=postgres://{{ miniflux_postgres_user }}:{{ miniflux_postgres_password }}@db/miniflux?sslmode=disable + - RUN_MIGRATIONS=1 + - CREATE_ADMIN=1 + - ADMIN_USERNAME={{ miniflux_admin_username }} + - ADMIN_PASSWORD={{ miniflux_admin_password }} + - DEBUG=1 +{% if server_domain is not undefined and not none %} + - "BASE_URL={{ (miniflux_use_https == True) | ternary('https', 'http') }}://{{ (subdomain_alias is not undefined and not none) | ternary(subdomain_alias, stack_name) }}.{{server_domain}}" +{% else %} + - "BASE_URL={{ (miniflux_use_https == True) | ternary('https', 'http') }}://localhost/{{ (subdomain_alias is not undefined and not none) | ternary(subdomain_alias, stack_name) }}" +{% endif %} + + db: + image: postgres:11 + networks: + - backend + healthcheck: + test: ["CMD", "pg_isready", "-U", "miniflux"] + interval: 1m + start_period: 30s + environment: + - POSTGRES_USER={{ miniflux_postgres_user }} + - POSTGRES_PASSWORD={{ miniflux_postgres_password }} + volumes: + - db:/var/lib/postgresql/data + +volumes: + db: + +networks: + "{{ docker_swarm_public_network_name }}": + external: true + backend: diff --git a/roles/miniflux/templates/upstream.json.j2 b/roles/miniflux/templates/upstream.json.j2 new file mode 100644 index 0000000..9966f1a --- /dev/null +++ b/roles/miniflux/templates/upstream.json.j2 @@ -0,0 +1,38 @@ +{ + "@id": "{{ stack_name }}_upstream", +{% if server_domain is not undefined and not none %} + "match": [ + { + "host": [ +{% if subdomain_alias is not undefined and not none %} + "{{ subdomain_alias }}.{{ server_domain }}" +{% else %} + "{{ stack_name }}.{{ server_domain }}" +{% endif %} + ] + } + ], +{% else %} + "match": [ + { + "path": [ +{% if subdomain_alias is not undefined and not none %} + "/{{ subdomain_alias }}*" +{% else %} + "/{{ stack_name }}*" +{% endif %} + ] + } + ], +{% endif %} + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "{{ stack_name }}_app:8080" + } + ] + } + ] +} diff --git a/roles/miniflux/vars/main.yml b/roles/miniflux/vars/main.yml new file mode 100644 index 0000000..05bf0b2 --- /dev/null +++ b/roles/miniflux/vars/main.yml @@ -0,0 +1,7 @@ +--- + +stack_name: miniflux + +stack_image: "miniflux/miniflux" + +stack_compose: "{{ lookup('template', 'docker-stack.yml.j2') | from_yaml }}" diff --git a/site-dev.yml b/site-dev.yml index 5f348f6..d85c6de 100644 --- a/site-dev.yml +++ b/site-dev.yml @@ -4,3 +4,4 @@ roles: - whoami - wallabag + - miniflux diff --git a/site.yml b/site.yml index 9b87ec4..4298a10 100644 --- a/site.yml +++ b/site.yml @@ -11,3 +11,4 @@ - caddy - whoami - wallabag + - miniflux