diff --git a/group_vars/testing.yml b/group_vars/testing.yml index 6ccf603..da723a8 100644 --- a/group_vars/testing.yml +++ b/group_vars/testing.yml @@ -3,13 +3,14 @@ docker_swarm_advertise_addr: eth1 caddy_use_debug: yes -caddy_use_https: no caddy_tls_use_staging: yes +caddy_use_https: no whoami_use_https: no wallabag_use_https: no miniflux_use_https: no searx_use_https: no traggo_use_https: no +monica_use_https: no #server_domain: mytest.com diff --git a/roles/monica/README.md b/roles/monica/README.md new file mode 100644 index 0000000..c95ec92 --- /dev/null +++ b/roles/monica/README.md @@ -0,0 +1,85 @@ +# monica + +A minimalist rss feed reader. +Deployed in a docker swarm with caddy. + +## Defaults + +``` +monica_upstream_file_dir: "{{ docker_stack_files_dir }}/{{ stack_name }}" +``` + +The on-target directory where the proxy configuration file should be stashed. + +``` +monica_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`. + +``` +monica_version: latest +``` + +The docker image version to be used in stack creation. + +``` +subdomain_alias: prm +``` + +If the deployed container should be served over a uri that is not the stack name. +By default, it will be set to `prm.yourdomain.com` (personal relationship manager) - +if this option is not set it will be served on `monica.yourdomain.com` instead. + +``` +monica_db_root_password: mysupersecretdbrootpass +monica_db_username: mymonicadbusername +monica_db_password: mymonicadbpassword +``` + +Set the default username and password combination on first container start. +If loading from an existing volume this does nothing, otherwise it sets the +first user so you can instantly log in. + +``` +monica_app_disable_signups: true +``` + +Sets the behavior on the login screen --- +if set to true (default) will not let anyone but the first user sign up, +who automatically becomes an administrative user. +If set to false will allow multiple users to sign up on the instance. + +``` +monica_app_geolocation_api_key: +monica_app_weather_api_key: +``` + +If `monica_app_geolocation_api_key` is set, Monica will translate addresses +input into the app to geographical latitude/ longitude data. +It requires an api key from https://locationiq.com/, which are free for +10.000 daily requests. + +Similarly, if `monica_app_weather_api_key` is set, monica will (afaik) show +weather data for the location of individual contacts. +It requires an API key from https://darksky.net/dev/register, where +1.000 daily requests are free. +Be aware, however, that since darksky's sale to Apple, no new API signups are possible. +To use this feature, `monica_app_geolocation_api_key` must also be filled out. + +``` +monica_mail_host: smtp.eu.mailgun.org +monica_mail_port: 465 +monica_mail_encryption: tls +monica_mail_username: +monica_mail_password: +monica_mail_from: monica@yourserver.com +monica_mail_from_name: Monica +monica_mail_new_user_notification_address: "{{ caddy_email }}" +``` + +Sets up the necessary details for Monica to send out registration and reminder e-mails. +Requires an smtp server set up, most easily doable through things like mailgun or sendgrid. +Variables should be relatively self-explanatory, +with `monica_mail_new_user_notification_address` being the address the notifications should be sent *to*, +so in all probability some sort of administration address. diff --git a/roles/monica/defaults/main.yml b/roles/monica/defaults/main.yml new file mode 100644 index 0000000..f4d1d5e --- /dev/null +++ b/roles/monica/defaults/main.yml @@ -0,0 +1,28 @@ +--- + +monica_version: latest + +monica_upstream_file_dir: "{{ docker_stack_files_dir }}/{{ stack_name }}" + +monica_use_https: true + +# the subdomain link monica will be reachable under +subdomain_alias: prm + +monica_app_disable_signups: true + +monica_db_root_password: mysupersecretdbrootpass +monica_db_username: mymonicadbusername +monica_db_password: mymonicadbpassword + +#monica_app_geolocation_api_key: +#monica_app_weather_api_key: + +#monica_mail_host: smtp.eu.mailgun.org +#monica_mail_username: +#monica_mail_password: +monica_mail_port: 465 +monica_mail_encryption: tls +#monica_mail_from: monica@yourserver.com +monica_mail_from_name: Monica +monica_mail_new_user_notification_address: "{{ caddy_email }}" diff --git a/roles/monica/handlers/main.yml b/roles/monica/handlers/main.yml new file mode 100644 index 0000000..00c7001 --- /dev/null +++ b/roles/monica/handlers/main.yml @@ -0,0 +1,53 @@ +## Register reverse proxy +- name: Ensure upstream directory exists + ansible.builtin.file: + path: "{{ monica_upstream_file_dir }}" + state: directory + mode: '0755' + become: yes + listen: "update monica upstream" + +- name: Update upstream template + ansible.builtin.template: + src: upstream.json.j2 + dest: "{{ monica_upstream_file_dir }}/upstream.json" + become: yes + listen: "update monica 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 monica 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 monica 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 @{{ monica_upstream_file_dir }}/upstream.json localhost:2019/config/apps/http/servers/{{ (monica_use_https == True) | ternary(caddy_https_server_name, caddy_http_server_name) }}/routes/0/ + become: yes + listen: "update monica upstream" + +- name: Ensure upstream directory is gone again + ansible.builtin.file: + path: "{{ monica_upstream_file_dir }}" + state: absent + become: yes + listen: "update monica upstream" + diff --git a/roles/monica/meta/main.yml b/roles/monica/meta/main.yml new file mode 100644 index 0000000..3858e67 --- /dev/null +++ b/roles/monica/meta/main.yml @@ -0,0 +1,14 @@ +--- + +galaxy_info: + author: Marty Oehme + description: Installs monica 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/monica/tasks/Ubuntu.yml b/roles/monica/tasks/Ubuntu.yml new file mode 100644 index 0000000..a67147d --- /dev/null +++ b/roles/monica/tasks/Ubuntu.yml @@ -0,0 +1,12 @@ +--- +## install requisites +- name: Ensure openssl installed + ansible.builtin.package: + name: "openssl" + state: present + become: yes + tags: + - apt + - download + - packages + diff --git a/roles/monica/tasks/main.yml b/roles/monica/tasks/main.yml new file mode 100644 index 0000000..0c0ce63 --- /dev/null +++ b/roles/monica/tasks/main.yml @@ -0,0 +1,40 @@ +--- +- name: "Select tasks for {{ ansible_distribution }} {{ ansible_distribution_major_version }}" + include_tasks: "{{ distribution }}" + with_first_found: + - "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml" + - "{{ ansible_distribution }}.yml" + - "{{ ansible_os_family }}.yml" + loop_control: + loop_var: distribution + +- name: Generate key + ansible.builtin.shell: echo -n 'base64:'; openssl rand -base64 32 + register: monica_app_key + +- set_fact: + monica_app_key={{ monica_app_key.stdout }} + +## install 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 monica upstream" + +- name: Deploy to swarm + community.general.docker_stack: + name: "{{ stack_name }}" + state: present + prune: yes + compose: + - "{{ stack_compose }}" + become: yes + tags: + - docker-swarm + notify: "update monica upstream" + diff --git a/roles/monica/templates/docker-stack.yml.j2 b/roles/monica/templates/docker-stack.yml.j2 new file mode 100644 index 0000000..704617c --- /dev/null +++ b/roles/monica/templates/docker-stack.yml.j2 @@ -0,0 +1,70 @@ +version: '3.7' + +services: + app: + image: {{ stack_image }}:{{ monica_version }} + networks: + - "{{ docker_swarm_public_network_name }}" + - backend + volumes: + - data:/var/www/html/storage + environment: +{% if server_domain is not undefined and not none %} + - APP_ENV=production +{% else %} + - APP_ENV=local +{% endif %} + - APP_KEY={{ monica_app_key }} +{% if monica_app_disable_signups is sameas true %} + - APP_DISABLE_SIGNUP=true +{% endif %} + - DB_HOST=db + - DB_DATABASE={{ monica_db_database }} + - DB_USERNAME={{ monica_db_username }} + - DB_PASSWORD={{ monica_db_password }} +{% if server_domain is not undefined and not none %} + - "APP_URL={{ (monica_use_https == True) | ternary('https', 'http') }}://{{ (subdomain_alias is not undefined and not none) | ternary(subdomain_alias, stack_name) }}.{{server_domain}}" +{% if monica_app_geolocation_api_key is not undefined and not none %} + - ENABLE_GEOLOCATION=true + - LOCATION_IQ_API_KEY={{ monica_app_geolocation_api_key }} +{% if monica_app_weather_api_key is not undefined and not none %} + - ENABLE_WEATHER=true + - DARKSKY_API_KEY={{ monica_app_weather_api_key }} +{% endif %} +{% endif %} +{% if monica_mail_host is not undefined and not none %} + - MAIL_MAILER=smtp + - MAIL_HOST={{ monica_mail_host }} + - MAIL_PORT={{ monica_mail_port }} + - MAIL_ENCRYPTION={{ monica_mail_encryption }} + - MAIL_USERNAME={{ monica_mail_username }} + - MAIL_PASSWORD={{ monica_mail_password }} + - MAIL_FROM_ADDRESS={{ monica_mail_from }} + - MAIL_FROM_NAME="{{ monica_mail_from_name }}" + - APP_EMAIL_NEW_USERS_NOTIFICATION={{ monica_mail_new_user_notification_address }} +{% endif %} +{% else %} + - "APP_URL={{ (monica_use_https == True) | ternary('https', 'http') }}://localhost/{{ (subdomain_alias is not undefined and not none) | ternary(subdomain_alias, stack_name) }}/" + - APP_FORCE_URL=true +{% endif %} + + db: + image: mariadb:10 + environment: + - MYSQL_ROOT_PASSWORD={{ monica_db_root_password }} + - MYSQL_DATABASE={{ monica_db_database }} + - MYSQL_USER={{ monica_db_username }} + - MYSQL_PASSWORD={{ monica_db_password }} + networks: + - backend + volumes: + - db:/var/lib/mysql + +volumes: + data: + db: + +networks: + "{{ docker_swarm_public_network_name }}": + external: true + backend: diff --git a/roles/monica/templates/upstream.json.j2 b/roles/monica/templates/upstream.json.j2 new file mode 100644 index 0000000..a20061f --- /dev/null +++ b/roles/monica/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:80" + } + ] + } + ] +} diff --git a/roles/monica/vars/main.yml b/roles/monica/vars/main.yml new file mode 100644 index 0000000..a4495b4 --- /dev/null +++ b/roles/monica/vars/main.yml @@ -0,0 +1,9 @@ +--- + +stack_name: monica + +stack_image: "monica" + +stack_compose: "{{ lookup('template', 'docker-stack.yml.j2') | from_yaml }}" + +monica_db_database: monicadb diff --git a/site-dev.yml b/site-dev.yml index ad24dbf..b258679 100644 --- a/site-dev.yml +++ b/site-dev.yml @@ -7,3 +7,4 @@ - miniflux - searx - traggo + - monica diff --git a/site.yml b/site.yml index 0c82e38..0535f0c 100644 --- a/site.yml +++ b/site.yml @@ -14,3 +14,4 @@ - miniflux - searx - traggo + - monica