From ecd79e5a165cbbf224df0b62bdb24ead64720b85 Mon Sep 17 00:00:00 2001 From: Mathieu Gauthier-Pilote Date: Thu, 26 Jan 2023 15:55:34 -0500 Subject: [PATCH 1/4] New role for hedgedoc --- webapps/hedgedoc/LISEZMOI.md | 58 +++++++++ webapps/hedgedoc/README.md | 58 +++++++++ webapps/hedgedoc/defaults/main.yml | 14 ++ webapps/hedgedoc/handlers/main.yml | 2 + webapps/hedgedoc/meta/main.yml | 52 ++++++++ webapps/hedgedoc/tasks/main.yml | 123 ++++++++++++++++++ webapps/hedgedoc/tasks/upgrade.yml | 57 ++++++++ webapps/hedgedoc/templates/config.json.j2 | 46 +++++++ .../hedgedoc/templates/hedgedoc.service.j2 | 46 +++++++ webapps/hedgedoc/templates/vhost.j2 | 49 +++++++ webapps/hedgedoc/tests/inventory | 2 + webapps/hedgedoc/tests/test.yml | 5 + webapps/hedgedoc/vars/main.yml | 2 + 13 files changed, 514 insertions(+) create mode 100644 webapps/hedgedoc/LISEZMOI.md create mode 100644 webapps/hedgedoc/README.md create mode 100644 webapps/hedgedoc/defaults/main.yml create mode 100644 webapps/hedgedoc/handlers/main.yml create mode 100644 webapps/hedgedoc/meta/main.yml create mode 100644 webapps/hedgedoc/tasks/main.yml create mode 100644 webapps/hedgedoc/tasks/upgrade.yml create mode 100644 webapps/hedgedoc/templates/config.json.j2 create mode 100644 webapps/hedgedoc/templates/hedgedoc.service.j2 create mode 100644 webapps/hedgedoc/templates/vhost.j2 create mode 100644 webapps/hedgedoc/tests/inventory create mode 100644 webapps/hedgedoc/tests/test.yml create mode 100644 webapps/hedgedoc/vars/main.yml diff --git a/webapps/hedgedoc/LISEZMOI.md b/webapps/hedgedoc/LISEZMOI.md new file mode 100644 index 00000000..4c87f281 --- /dev/null +++ b/webapps/hedgedoc/LISEZMOI.md @@ -0,0 +1,58 @@ +hedgedoc +========= + +Ce rôle installe le serveur de HedgeDoc, une application rédaction collaborative en temps-réel utilisant la syntaxe Markdown. + +Notez qu'hormis le présent fichier LISEZMOI.md, tous les fichiers du rôle hedgedoc sont rédigés en anglais afin de suivre les conventions de la communauté Ansible, favoriser sa réutilisation et son amélioration, etc. Libre à vous cependant de faire appel à ce role dans un playbook rédigé principalement en français ou toute autre langue. + +Requis +------ + +... + +Variables du rôle +----------------- + +Plusieurs des valeurs par défaut dans defaults/main.yml doivent être changées soit directement dans defaults/main.yml ou mieux encore en les supplantant ailleurs, par exemple dans votre playbook (voir l'exemple ci-bas). + +Dépendances +------------ + +Ce rôle Ansible dépend des rôles suivants : + +- nodejs + +Exemple de playbook +------------------- + +``` +- name: "Déployer un serveur HedgeDoc" + hosts: + - all + vars: + # Supplanter ici les variables du rôle + domains: ['votre-vrai-domaine.org'] + service: 'mon-hedgedoc' + db_host: 'localhost' + db_user: "{{ service }}" + db_name: "{{ service }}" + db_password: 'zKEh-CHANGEZ-MOI-qIKc' + + pre_tasks: + - name: "Installer les rôles systèmes" + roles: + - { role: nodejs, nodejs_apt_version: 'node_16.x', nodejs_install_yarn: True } + + roles: + - { role: webapps/hedgedoc , tags: "hedgedoc" } +``` + +Licence +------- + +GPLv3 + +Infos sur l'auteur +------------------ + +Mathieu Gauthier-Pilote, administrateur de systèmes chez Evolix. diff --git a/webapps/hedgedoc/README.md b/webapps/hedgedoc/README.md new file mode 100644 index 00000000..98bb0f6d --- /dev/null +++ b/webapps/hedgedoc/README.md @@ -0,0 +1,58 @@ +hedgedoc +========= + +This role installs or upgrades the server for the real-time markdown collaborative editor HedgeDoc. + +FRENCH: Voir le fichier LISEZMOI.md pour le français. + +Requirements +------------ + +... + +Role Variables +-------------- + +Several of the default values in defaults/main.yml must be changed either directly in defaults/main.yml or better even by overwriting them somewhere else, for example in your playbook (see the example below). + +Dependencies +------------ + +This Ansible role depends on the following other roles: + +- nodejs + +Example Playbook +---------------- + +``` +- name: "Deploy a HedgeDoc server" + hosts: + - all + vars: + # Overwrite the role variable here + domains: ['your-real-domain.org'] + service: 'my-hedgedoc' + db_host: 'localhost' + db_user: "{{ service }}" + db_name: "{{ service }}" + db_password: 'zKEh-CHANGE-ME-qIKc' + + pre_tasks: + - name: "Install system roles" + roles: + - { role: nodejs, nodejs_apt_version: 'node_16.x', nodejs_install_yarn: True } + + roles: + - { role: webapps/hedgedoc , tags: "hedgedoc" } +``` + +License +------- + +GPLv3 + +Author Information +------------------ + +Mathieu Gauthier-Pilote, sys. admin. at Evolix. diff --git a/webapps/hedgedoc/defaults/main.yml b/webapps/hedgedoc/defaults/main.yml new file mode 100644 index 00000000..f49ce18f --- /dev/null +++ b/webapps/hedgedoc/defaults/main.yml @@ -0,0 +1,14 @@ +--- +# defaults file for mastodon +system_dep: "['apt-transport-https', 'postgresql', 'python3-psycopg2', 'nginx', 'git', 'wget', 'certbot']" +git_url: 'https://github.com/hedgedoc/hedgedoc.git' +git_version: '1.9.6' +node_version: 'node_16.x' +node_port: '3000' +service: 'example' +domains: ['example.domain.org'] + +db_host: 'localhost' +db_user: "{{ service }}" +db_name: "{{ service }}" +db_password: 'CHANGE_ME' diff --git a/webapps/hedgedoc/handlers/main.yml b/webapps/hedgedoc/handlers/main.yml new file mode 100644 index 00000000..ba8d85b1 --- /dev/null +++ b/webapps/hedgedoc/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for mastodon diff --git a/webapps/hedgedoc/meta/main.yml b/webapps/hedgedoc/meta/main.yml new file mode 100644 index 00000000..b065fb2a --- /dev/null +++ b/webapps/hedgedoc/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: Mathieu Gauthier-Pilote + description: sys. admin. + company: Evolix + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license GPL-3.0-only + + min_ansible_version: 2.10 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/webapps/hedgedoc/tasks/main.yml b/webapps/hedgedoc/tasks/main.yml new file mode 100644 index 00000000..700bf9d7 --- /dev/null +++ b/webapps/hedgedoc/tasks/main.yml @@ -0,0 +1,123 @@ +--- +# tasks file for hedgedoc install + +- name: Install main system dependencies + apt: + name: "{{ system_dep }}" + +- name: Install node-gyp from yarn + shell: npm install --global node-gyp + +- name: Add UNIX account + user: + name: "{{ service }}" + shell: /bin/bash + +- name: Add PostgreSQL user + postgresql_user: + name: "{{ db_user }}" + password: "{{ db_password }}" + no_password_changes: true + become_user: postgres + +- name: Add PostgreSQL database + postgresql_db: + name: "{{ db_name }}" + owner: "{{ db_user }}" + become_user: postgres + +- block: + - name: Clone hedgedoc repo (git) + git: + repo: "{{ git_url }}" + dest: "~/hedgedoc/" + version: "{{ git_version | default(omit) }}" + update: yes + umask: '0022' + - name: Run setup + shell: "bin/setup" + args: + chdir: "~/hedgedoc" + - name: Install dependencies for frontend app + shell: "yarn install --frozen-lockfile" + args: + chdir: "~/hedgedoc" + - name: Build frontend app + shell: "yarn build" + args: + chdir: "~/hedgedoc" + become_user: "{{ service }}" + +- name: Template json config file + template: + src: "config.json.j2" + dest: "~{{ service }}/hedgedoc/config.json" + owner: "{{ service }}" + group: "{{ service }}" + mode: "0640" + +- name: Add systemd unit + template: + src: "hedgedoc.service.j2" + dest: "/etc/systemd/system/{{ service }}.service" + +- name: Enable systemd units + systemd: + name: "{{ service }}.service" + enabled: yes + daemon_reload: yes + +- name: Start service + service: + name: "{{ service }}.service" + state: started + +- name: Check if SSL certificate is present and register result + stat: + path: "/etc/letsencrypt/live/{{ domains |first }}/fullchain.pem" + register: ssl + +- name: Generate certificate only if required (first time) + block: + - name: Template vhost without SSL for successfull LE challengce + template: + src: "vhost.j2" + dest: "/etc/nginx/sites-available/{{ service }}" + - name: Enable temporary nginx vhost for LE + file: + src: "/etc/nginx/sites-available/{{ service }}" + dest: "/etc/nginx/sites-enabled/{{ service }}" + state: link + - name: Reload nginx conf + service: + name: nginx + state: reloaded + - name: Make sure /var/lib/letsencrypt exists and has correct permissions + file: + path: /var/lib/letsencrypt + state: directory + mode: '0755' +# - name: Generate certificate with certbot +# shell: certbot certonly --webroot --webroot-path /var/lib/letsencrypt -d {{ domains |first }} + when: ssl.stat.exists == false + +- name: (Re)check if SSL certificate is present and register result + stat: + path: "/etc/letsencrypt/live/{{ domains |first }}/fullchain.pem" + register: ssl + +- name: (Re)template conf file for nginx vhost with SSL + template: + src: "vhost.j2" + dest: "/etc/nginx/sites-available/{{ service }}" + +- name: Enable nginx vhost for hedgedoc + file: + src: "/etc/nginx/sites-available/{{ service }}" + dest: "/etc/nginx/sites-enabled/{{ service }}" + state: link + +- name: Reload nginx conf + service: + name: nginx + state: reloaded diff --git a/webapps/hedgedoc/tasks/upgrade.yml b/webapps/hedgedoc/tasks/upgrade.yml new file mode 100644 index 00000000..0153d882 --- /dev/null +++ b/webapps/hedgedoc/tasks/upgrade.yml @@ -0,0 +1,57 @@ +--- +# tasks file for hedgedoc upgrade + +- name: Dump database to a file with compression + postgresql_db: + name: "{{ service }}" + state: dump + target: "~/{{ service }}.sql.gz" + become_user: postgres + +- name: Stop service + service: + name: "{{ service }}.service" + state: stopped + +- block: + - name: Clone hedgedoc repo (git) + git: + repo: "{{ git_url }}" + dest: "~/hedgedoc/" + version: "{{ git_version }}" + update: yes + - name: Run setup + shell: "bin/setup" + args: + chdir: "~/hedgedoc" + - name: Install dependencies for frontend app + shell: "yarn install --frozen-lockfile" + args: + chdir: "~/hedgedoc" + - name: Build frontend app + shell: "yarn build" + args: + chdir: "~/hedgedoc" + become_user: "{{ service }}" + +- name: Restart services + service: + name: "{{ service }}.service" + state: restarted + +- name: Define variable to skip next task by default + set_fact: + keep_db_dump: true + +- name: Remove database dump + file: + path: "~/{{ service }}.sql.gz" + state: absent + become_user: postgres + when: keep_db_dump is undefined + tags: clean + +- name: Reload nginx conf + service: + name: nginx + state: reloaded diff --git a/webapps/hedgedoc/templates/config.json.j2 b/webapps/hedgedoc/templates/config.json.j2 new file mode 100644 index 00000000..a92ab98e --- /dev/null +++ b/webapps/hedgedoc/templates/config.json.j2 @@ -0,0 +1,46 @@ +{ + "test": { + "db": { + "dialect": "sqlite", + "storage": ":memory:" + }, + "linkifyHeaderStyle": "gfm" + }, + "development": { + "loglevel": "debug", + "db": { + "dialect": "sqlite", + "storage": "./db.hedgedoc.sqlite" + }, + "domain": "localhost", + "urlAddPort": true + }, + "production": { + "domain": "{{ domains }}", + "loglevel": "info", + "protocolUseSSL": "true", + "urlAddPort": false, + "hsts": { + "enable": true, + "maxAgeSeconds": 31536000, + "includeSubdomains": true, + "preload": true + }, + "csp": { + "enable": true, + "directives": { + }, + "upgradeInsecureRequests": "auto", + "addDefaults": true + }, + "cookiePolicy": "lax", + "db": { + "username": "{{ db_user }}", + "password": "{{ db_password }}", + "database": "{{ db_name }}", + "host": "{{ db_host }}", + "port": "5432", + "dialect": "postgres" + } + } +} diff --git a/webapps/hedgedoc/templates/hedgedoc.service.j2 b/webapps/hedgedoc/templates/hedgedoc.service.j2 new file mode 100644 index 00000000..73736094 --- /dev/null +++ b/webapps/hedgedoc/templates/hedgedoc.service.j2 @@ -0,0 +1,46 @@ +[Unit] +Description=HedgeDoc - The best platform to write and share markdown. +Documentation=https://docs.hedgedoc.org/ +After=network.target +# Uncomment if you use MariaDB/MySQL +# After=mysql.service +# Uncomment if you use PostgreSQL +After=postgresql.service + +[Service] +Type=exec +Environment=NODE_ENV=production +Restart=always +RestartSec=2s +ExecStart=/usr/bin/yarn start --production +CapabilityBoundingSet= +NoNewPrivileges=true +PrivateDevices=true +RemoveIPC=true +LockPersonality=true +ProtectControlGroups=true +ProtectKernelTunables=true +ProtectKernelModules=true +ProtectKernelLogs=true +ProtectClock=true +ProtectHostname=true +ProtectProc=noaccess +RestrictRealtime=true +RestrictSUIDSGID=true +RestrictNamespaces=true +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 +ProtectSystem=strict +PrivateTmp=true +SystemCallArchitectures=native +SystemCallFilter=@system-service + +# You may have to adjust these settings +User={{service}} +Group={{service}} +WorkingDirectory=/home/{{service}}/hedgedoc + +# Example: local storage for uploads and SQLite +# ReadWritePaths=/opt/hedgedoc/public/uploads /opt/hedgedoc/db + +[Install] +WantedBy=multi-user.target diff --git a/webapps/hedgedoc/templates/vhost.j2 b/webapps/hedgedoc/templates/vhost.j2 new file mode 100644 index 00000000..177416c3 --- /dev/null +++ b/webapps/hedgedoc/templates/vhost.j2 @@ -0,0 +1,49 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + listen [::]:80; + server_name {{ domains |first }}; + + # For Let's Encrypt + location /.well-known/acme-challenge/ { allow all; } + + {% if ssl.stat.exists %} + location / { return 301 https://$host$request_uri; } + {% endif %} +} + +{% if ssl.stat.exists %} +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name {{ domains |first }}; + + # For Let's Encrypt + location /.well-known/acme-challenge/ { allow all; } + ssl_certificate /etc/letsencrypt/live/{{ domains |first }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ domains |first }}/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/{{ domains |first }}/chain.pem; + + location / { + proxy_pass http://127.0.0.1:{{ node_port }}; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /socket.io/ { + proxy_pass http://127.0.0.1:{{ node_port }}; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } +} +{% endif %} diff --git a/webapps/hedgedoc/tests/inventory b/webapps/hedgedoc/tests/inventory new file mode 100644 index 00000000..878877b0 --- /dev/null +++ b/webapps/hedgedoc/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/webapps/hedgedoc/tests/test.yml b/webapps/hedgedoc/tests/test.yml new file mode 100644 index 00000000..53e7a5f9 --- /dev/null +++ b/webapps/hedgedoc/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - hedgedoc diff --git a/webapps/hedgedoc/vars/main.yml b/webapps/hedgedoc/vars/main.yml new file mode 100644 index 00000000..2053e362 --- /dev/null +++ b/webapps/hedgedoc/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file -- 2.39.2 From fa6433c00e047dbfe0ed7f66f2d9d084f471baa4 Mon Sep 17 00:00:00 2001 From: Mathieu Gauthier-Pilote Date: Fri, 27 Jan 2023 08:36:30 -0500 Subject: [PATCH 2/4] Update README.md/LISEZMOI.md: use node_version in example playbook --- webapps/hedgedoc/LISEZMOI.md | 2 +- webapps/hedgedoc/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/webapps/hedgedoc/LISEZMOI.md b/webapps/hedgedoc/LISEZMOI.md index 4c87f281..a2116980 100644 --- a/webapps/hedgedoc/LISEZMOI.md +++ b/webapps/hedgedoc/LISEZMOI.md @@ -41,7 +41,7 @@ Exemple de playbook pre_tasks: - name: "Installer les rôles systèmes" roles: - - { role: nodejs, nodejs_apt_version: 'node_16.x', nodejs_install_yarn: True } + - { role: nodejs, nodejs_apt_version: "{{ node_version }}" } roles: - { role: webapps/hedgedoc , tags: "hedgedoc" } diff --git a/webapps/hedgedoc/README.md b/webapps/hedgedoc/README.md index 98bb0f6d..babf877c 100644 --- a/webapps/hedgedoc/README.md +++ b/webapps/hedgedoc/README.md @@ -41,7 +41,7 @@ Example Playbook pre_tasks: - name: "Install system roles" roles: - - { role: nodejs, nodejs_apt_version: 'node_16.x', nodejs_install_yarn: True } + - { role: nodejs, nodejs_apt_version: "{{ node_version }}" } roles: - { role: webapps/hedgedoc , tags: "hedgedoc" } -- 2.39.2 From e6969d76ba6300708a39c05c533a07bae16d4ae3 Mon Sep 17 00:00:00 2001 From: Mathieu Gauthier-Pilote Date: Thu, 4 May 2023 13:37:36 -0400 Subject: [PATCH 3/4] Now installs a LE SSL cert via certbot by default --- webapps/hedgedoc/defaults/main.yml | 5 +-- webapps/hedgedoc/tasks/main.yml | 36 +++++++++++++++---- .../hedgedoc/templates/letsencrypt.conf.j2 | 5 +++ webapps/hedgedoc/templates/ssl.conf.j2 | 22 ++++++++++++ .../templates/{vhost.j2 => vhost.conf.j2} | 15 ++++---- 5 files changed, 67 insertions(+), 16 deletions(-) create mode 100644 webapps/hedgedoc/templates/letsencrypt.conf.j2 create mode 100644 webapps/hedgedoc/templates/ssl.conf.j2 rename webapps/hedgedoc/templates/{vhost.j2 => vhost.conf.j2} (73%) diff --git a/webapps/hedgedoc/defaults/main.yml b/webapps/hedgedoc/defaults/main.yml index f49ce18f..cff858b3 100644 --- a/webapps/hedgedoc/defaults/main.yml +++ b/webapps/hedgedoc/defaults/main.yml @@ -2,11 +2,12 @@ # defaults file for mastodon system_dep: "['apt-transport-https', 'postgresql', 'python3-psycopg2', 'nginx', 'git', 'wget', 'certbot']" git_url: 'https://github.com/hedgedoc/hedgedoc.git' -git_version: '1.9.6' -node_version: 'node_16.x' +git_version: '1.9.7' +node_version: 'node_16.x' # Node 18 is NOT supported as of May 2023; See https://docs.hedgedoc.org/setup/manual-setup/ node_port: '3000' service: 'example' domains: ['example.domain.org'] +certbot_admin_email: 'mgauthier@evolix.ca' db_host: 'localhost' db_user: "{{ service }}" diff --git a/webapps/hedgedoc/tasks/main.yml b/webapps/hedgedoc/tasks/main.yml index 700bf9d7..cf2a9864 100644 --- a/webapps/hedgedoc/tasks/main.yml +++ b/webapps/hedgedoc/tasks/main.yml @@ -4,10 +4,14 @@ - name: Install main system dependencies apt: name: "{{ system_dep }}" + update_cache: yes -- name: Install node-gyp from yarn +- name: Install node-gyp from npm shell: npm install --global node-gyp +- name: Enable yarn (via corepack) + shell: "corepack enable; yarn set version classic" + - name: Add UNIX account user: name: "{{ service }}" @@ -34,6 +38,10 @@ version: "{{ git_version | default(omit) }}" update: yes umask: '0022' +# - name: Set cache dir for yarn +# shell: yarn config set cache-folder /var/tmp/cache/yarn +# args: +# chdir: "~/" - name: Run setup shell: "bin/setup" args: @@ -70,7 +78,12 @@ - name: Start service service: name: "{{ service }}.service" - state: started + state: restarted + +- name: Template nginx snippet for Let's Encrypt/Certbot + template: + src: "letsencrypt.conf.j2" + dest: "/etc/nginx/snippets/letsencrypt.conf" - name: Check if SSL certificate is present and register result stat: @@ -81,7 +94,7 @@ block: - name: Template vhost without SSL for successfull LE challengce template: - src: "vhost.j2" + src: "vhost.conf.j2" dest: "/etc/nginx/sites-available/{{ service }}" - name: Enable temporary nginx vhost for LE file: @@ -97,9 +110,18 @@ path: /var/lib/letsencrypt state: directory mode: '0755' -# - name: Generate certificate with certbot -# shell: certbot certonly --webroot --webroot-path /var/lib/letsencrypt -d {{ domains |first }} - when: ssl.stat.exists == false + - name: Generate certificate with certbot + shell: certbot certonly --webroot --webroot-path /var/lib/letsencrypt --non-interactive --agree-tos --email {{ certbot_admin_email }} -d {{ domains |first }} + - name: Create the ssl dir if needed + file: + path: /etc/nginx/ssl + state: directory + mode: '0750' + - name: Template ssl bloc for nginx vhost + template: + src: "ssl.conf.j2" + dest: "/etc/nginx/ssl/{{ domains |first }}.conf" + when: ssl.stat.exists != true - name: (Re)check if SSL certificate is present and register result stat: @@ -108,7 +130,7 @@ - name: (Re)template conf file for nginx vhost with SSL template: - src: "vhost.j2" + src: "vhost.conf.j2" dest: "/etc/nginx/sites-available/{{ service }}" - name: Enable nginx vhost for hedgedoc diff --git a/webapps/hedgedoc/templates/letsencrypt.conf.j2 b/webapps/hedgedoc/templates/letsencrypt.conf.j2 new file mode 100644 index 00000000..6b33847e --- /dev/null +++ b/webapps/hedgedoc/templates/letsencrypt.conf.j2 @@ -0,0 +1,5 @@ +location ~ /.well-known/acme-challenge { + alias /var/lib/letsencrypt/; + try_files $uri =404; + allow all; +} diff --git a/webapps/hedgedoc/templates/ssl.conf.j2 b/webapps/hedgedoc/templates/ssl.conf.j2 new file mode 100644 index 00000000..86194389 --- /dev/null +++ b/webapps/hedgedoc/templates/ssl.conf.j2 @@ -0,0 +1,22 @@ +## +# Certificates +# you need a certificate to run in production. see https://letsencrypt.org/ +## +ssl_certificate /etc/letsencrypt/live/{{ domains | first }}/fullchain.pem; +ssl_certificate_key /etc/letsencrypt/live/{{ domains | first }}/privkey.pem; + +## +# Security hardening (as of Nov 15, 2020) +# based on Mozilla Guideline v5.6 +## + +ssl_protocols TLSv1.2 TLSv1.3; +ssl_prefer_server_ciphers on; +ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; # add ECDHE-RSA-AES256-SHA if you want compatibility with Android 4 +ssl_session_timeout 1d; # defaults to 5m +ssl_session_cache shared:SSL:10m; # estimated to 40k sessions +ssl_session_tickets off; +ssl_stapling on; +ssl_stapling_verify on; +# HSTS (https://hstspreload.org), requires to be copied in 'location' sections that have add_header directives +#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; diff --git a/webapps/hedgedoc/templates/vhost.j2 b/webapps/hedgedoc/templates/vhost.conf.j2 similarity index 73% rename from webapps/hedgedoc/templates/vhost.j2 rename to webapps/hedgedoc/templates/vhost.conf.j2 index 177416c3..ecd89214 100644 --- a/webapps/hedgedoc/templates/vhost.j2 +++ b/webapps/hedgedoc/templates/vhost.conf.j2 @@ -8,8 +8,8 @@ server { listen [::]:80; server_name {{ domains |first }}; - # For Let's Encrypt - location /.well-known/acme-challenge/ { allow all; } + # For certbot + include /etc/nginx/snippets/letsencrypt.conf; {% if ssl.stat.exists %} location / { return 301 https://$host$request_uri; } @@ -20,13 +20,14 @@ server { server { listen 443 ssl http2; listen [::]:443 ssl http2; + server_name {{ domains |first }}; - # For Let's Encrypt - location /.well-known/acme-challenge/ { allow all; } - ssl_certificate /etc/letsencrypt/live/{{ domains |first }}/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/{{ domains |first }}/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/{{ domains |first }}/chain.pem; + access_log /var/log/nginx/{{ service }}.access.log; + error_log /var/log/nginx/{{ service }}.error.log; + + include /etc/nginx/snippets/letsencrypt.conf; + include /etc/nginx/ssl/{{ domains | first }}.conf; location / { proxy_pass http://127.0.0.1:{{ node_port }}; -- 2.39.2 From e787d62926f31f4549e497b27de1ba1b9d1a8489 Mon Sep 17 00:00:00 2001 From: Mathieu Gauthier-Pilote Date: Wed, 12 Jun 2024 15:46:12 -0400 Subject: [PATCH 4/4] WIP: Deploying v1.9.9 with Node 18.x on Deb 12 --- webapps/hedgedoc/defaults/main.yml | 4 ++-- webapps/hedgedoc/tasks/main.yml | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/webapps/hedgedoc/defaults/main.yml b/webapps/hedgedoc/defaults/main.yml index cff858b3..c9fe250b 100644 --- a/webapps/hedgedoc/defaults/main.yml +++ b/webapps/hedgedoc/defaults/main.yml @@ -1,9 +1,9 @@ --- # defaults file for mastodon -system_dep: "['apt-transport-https', 'postgresql', 'python3-psycopg2', 'nginx', 'git', 'wget', 'certbot']" +system_dep: "['apt-transport-https', 'postgresql', 'python3-psycopg2', 'nginx', 'git', 'wget', 'certbot', 'npm']" git_url: 'https://github.com/hedgedoc/hedgedoc.git' git_version: '1.9.7' -node_version: 'node_16.x' # Node 18 is NOT supported as of May 2023; See https://docs.hedgedoc.org/setup/manual-setup/ +node_version: 'node_18.x' # Node 18 is NOT supported as of May 2023; See https://docs.hedgedoc.org/setup/manual-setup/ node_port: '3000' service: 'example' domains: ['example.domain.org'] diff --git a/webapps/hedgedoc/tasks/main.yml b/webapps/hedgedoc/tasks/main.yml index cf2a9864..80e3cd2c 100644 --- a/webapps/hedgedoc/tasks/main.yml +++ b/webapps/hedgedoc/tasks/main.yml @@ -7,10 +7,16 @@ update_cache: yes - name: Install node-gyp from npm - shell: npm install --global node-gyp + shell: npm install --global node-gyp corepack - name: Enable yarn (via corepack) - shell: "corepack enable; yarn set version classic" + shell: "corepack enable" + +- name: Fix permissions + file: + path: /usr/local/lib/node_modules + mode: g+rx,o+rx + recurse: yes - name: Add UNIX account user: -- 2.39.2