Add monica deployment

Added basic monica docker deployment.

A key which is required for monica is automatically generated on
deployment.
Optionally, geolocation and weather api can be enabled.
Mail-sending functionality is disabled by default but can be enabled
with any compatible smtp server set up.
This commit is contained in:
Marty Oehme 2021-10-25 20:23:04 +02:00
parent 3f944df048
commit 010d8f93c4
Signed by: Marty
GPG key ID: B7538B8F50A1C800
12 changed files with 353 additions and 1 deletions

View file

@ -3,13 +3,14 @@
docker_swarm_advertise_addr: eth1 docker_swarm_advertise_addr: eth1
caddy_use_debug: yes caddy_use_debug: yes
caddy_use_https: no
caddy_tls_use_staging: yes caddy_tls_use_staging: yes
caddy_use_https: no
whoami_use_https: no whoami_use_https: no
wallabag_use_https: no wallabag_use_https: no
miniflux_use_https: no miniflux_use_https: no
searx_use_https: no searx_use_https: no
traggo_use_https: no traggo_use_https: no
monica_use_https: no
#server_domain: mytest.com #server_domain: mytest.com

85
roles/monica/README.md Normal file
View file

@ -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: <your-locationiq-key>
monica_app_weather_api_key: <your-darksky-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.

View file

@ -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 }}"

View file

@ -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"

View file

@ -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

View file

@ -0,0 +1,12 @@
---
## install requisites
- name: Ensure openssl installed
ansible.builtin.package:
name: "openssl"
state: present
become: yes
tags:
- apt
- download
- packages

View file

@ -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"

View file

@ -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:

View file

@ -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"
}
]
}
]
}

View file

@ -0,0 +1,9 @@
---
stack_name: monica
stack_image: "monica"
stack_compose: "{{ lookup('template', 'docker-stack.yml.j2') | from_yaml }}"
monica_db_database: monicadb

View file

@ -7,3 +7,4 @@
- miniflux - miniflux
- searx - searx
- traggo - traggo
- monica

View file

@ -14,3 +14,4 @@
- miniflux - miniflux
- searx - searx
- traggo - traggo
- monica