commit bb71afccaa8866ac61c90f8390945b7c83f515e3 Author: muppeth Date: Sun Nov 14 14:56:49 2021 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8000dd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vagrant diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8dc6c17 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +MIT License Copyright (c) 2021 "Stichting Disroot.org" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Playbooks/pleroma.yml b/Playbooks/pleroma.yml new file mode 100644 index 0000000..365571b --- /dev/null +++ b/Playbooks/pleroma.yml @@ -0,0 +1,10 @@ +--- + +- hosts: pleroma + roles: + - nginx + - postgresql + - pleroma + + vars_files: + - ../defaults/main.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..c7430bb --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Pleroma role +Pleroma role is was initially based on role by (Luke Hoersten)[https://src.nth.io/ansible-roles/file/2d705e63f6cb/pleroma/otp] with heavy modifications (basically re-written). +This role deploys and updates OTP pleroma instance with soapbox ui. Currently supported distributions are debian based. Role requires disroot's (nginx)[https://git.disroot.org/Disroot-Ansible/nginx] role and (postgresql)[https://github.com/ANXS/postgresql.git]. Other nginx / postgres roles could be used but may require changes in variables. + + +Role is deployable with vagrant for test purposes (See Vagrantfile). + +To update pleroma include `upgrade` **tag**. + + diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..90c80ae --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,20 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + #config.ssh.insert_key = false + config.vm.define "pleroma" do |pleroma| + pleroma.vm.box = "generic/debian10" + pleroma.vm.provider :libvirt do |libvirt| + libvirt.memory = 256 + end + pleroma.vm.network "forwarded_port", guest: 80, host: 8888, host_ip: "192.168.33.15" + pleroma.vm.network "forwarded_port", guest: 443, host: 4443, host_ip: "192.168.33.15" + pleroma.vm.network "private_network", ip: "192.168.33.15" + +end +end diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..9d03fbf --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,142 @@ +--- + +pleroma_user: 'pleroma' +pleroma_group: 'pleroma' +pleroma_tmp_dir: '/tmp/pleroma/' +pleroma_app_dir: '/opt/pleroma' + +pleroma_apt_list: + - 'libmagic-dev' + - 'libtinfo5' + - 'git' + - 'build-essential' + - 'cmake' + - 'elixir' + - 'erlang-dev' + - 'erlang-nox' + - 'imagemagick' + - 'ffmpeg' + - 'libimage-exiftool-perl' + - 'unzip' + + + +pleroma_host: "192.168.33.2" +pleroma_port: 4000 +pleroma_scheme: "http" + +pleroma_proxy_pass: "{{pleroma_scheme}}://{{pleroma_host}}:{{pleroma_port}}" + +pleroma_link_host: "192.168.33.2" +pleroma_link_port: "80" +pleroma_link_scheme: "http" +pleroma_https: 'false' +pleroma_config_dir: '/etc/pleroma' +pleroma_instance_name: "{{pleroma_link_host}}" +pleroma_secret_key: 'CDPbJ/+rD8hd27Hcw8igvGwyIDoS/J1isK4noJOybqfCuNuW9GDm0QNiW7syrGsHQQkTTSkzSZkAlKTqdnUahQ==' #openssl rand -base64 64 | paste --delimiters '' --serial +pleroma_invites_enabled: 'false' +pleroma_desc: "A Pleroma fediverse instance." +pleroma_admin_email: "admin@{{pleroma_link_host}}" +pleroma_char_limit: 5000 +pleroma_signup_open: "true" +pleroma_loglevel: ":debug" +pleroma_db_host: "localhost" +pleroma_db_superuser: "postgres" +pleroma_db_passwd: 'changeme' +pleroma_db_install: 'true' +pleroma_db: "pleroma" +pleroma_db_user: "admin" +pleroma_data_dir: "/srv/pleroma_data/" + +pleroma_admin: 'true' +pleroma_admin_user: 'admin' +pleroma_admin_email: 'admin@example.lan' +pleroma_admin_password: 'changeme' +pleroma_download_url: "https://git.pleroma.social/api/v4/projects/2/jobs/artifacts/stable/download?job={{pleroma_arch}}" +pleroma_arch: 'amd64' +pleroma_soapbox: false +pleroma_soapbox_version: "v1.3.0" +pleroma_soapbox_download_url: "https://gitlab.com/soapbox-pub/soapbox-fe/-/jobs/artifacts/{{pleroma_soapbox_version}}/download?job=build-production" + +#soapbox +pleroma_soapbox_logo: '/instance/images/soapbox-logo.svg' +pleroma_soapbox_brandcolor: '#0482d8' +pleroma_soapbox_promopanel: + - text: 'Our Site stats' + icon: 'area-chart' + url: 'https://fediverse.network/example.com' + - text: 'Our Site blog' + icon: 'comment-o' + url: 'https://blog.example.com' +pleroma_soapbox_gif: 'false' +pleroma_soapbox_thememode: 'light' +pleroma_soapbox_copyright: '♡2020. Copying is an act of love. Please copy and share.' +pleroma_soapbox_footer: + - name: 'About' + url: '/about' + - name: 'Terms of Service' + url: '/about/tos' + - name: 'Privacy Policy' + url: '/about/privacy' + - name: 'Source code' + url: '/about#opensource' + +#Postgres +postgresql_version: 12 +postgresql_listen_addresses: + - "127.0.0.1" + +postgresql_pg_hba_default: + - { type: local, database: all, user: '{{ postgresql_admin_user }}', address: '', method: '{{ postgresql_default_auth_method }}', comment: '' } + - { type: local, database: all, user: all, address: '', method: '{{ postgresql_default_auth_method }}', comment: '"local" is for Unix domain socket connections only' } + - { type: host, database: all, user: all, address: '127.0.0.1/32', method: '{{ postgresql_default_auth_method_hosts }}', comment: 'IPv4 local connections:' } + +postgresql_databases: + - name: pleroma + owner: admin # optional; specify the owner of the database + uuid_ossp: yes + +postgresql_database_extensions: + - db: pleroma + extensions: + - citext + - pg_trgm + # hstore: no # flag to install the hstore extension on this database (yes/no) + #uuid_ossp: yes # flag to install the uuid-ossp extension on this database (yes/no) + #citext: yes # flag to install the citext extension on this database (yes/no) + +postgresql_users: + - name: admin + pass: changeme + encrypted: yes # denotes if the password is already encrypted. + +postgresql_user_privileges: + - name: admin # user name + db: pleroma # database + priv: "ALL" # privilege string format: example: INSERT,UPDATE/table:SELECT/anothertable:ALL + role_attr_flags: "" # role attribute flags + + #NGINX SETUP +nginx_default_vhost_ssl: 'pleroma.example.lan' +nginx_default_vhost: 'pleroma.example.lan' +nginx_HSTS_policy: 'true' + #NGINX VHOST +nginx_vhosts: + + - name: 'pleroma.example.lan' + template: 'pleroma' + upstream_proto: 'http' + upstream_port: '80' + upstream_name: 'localhost' + proto: 'http' + listen: '80' + use_error_log: 'true' + nginx_error_log_level: 'warn' + redirect_https: 'true' + letsencrypt: 'false' + secure_site: 'false' + #header_sameorigin: 'true' + nc_max_upload: '50M' + nginx_HSTS_policy: 'false' + state: 'enable' + diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..da83757 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,7 @@ +--- + +- name: 'restart pleroma' + systemd: + name: 'pleroma.service' + state: 'restarted' + daemon_reload: 'yes' diff --git a/tasks/configure.yml b/tasks/configure.yml new file mode 100644 index 0000000..8859528 --- /dev/null +++ b/tasks/configure.yml @@ -0,0 +1,42 @@ +--- + +- name: '[Config] - Create pleroma directories' + file: + path: '{{ item }}' + state: 'directory' + mode: 0755 + loop: + - '{{ pleroma_data_dir }}' + - '{{ pleroma_config_dir }}' + # - '{{ pleroma_app_dir }}' + +- name: '[Config] - Deploy systemd config' + template: + src: 'pleroma.service.j2' + dest: '/etc/systemd/system/pleroma.service' + notify: restart pleroma + +- name: '[Config] - Deploy pleroma config' + template: + src: 'config.exs.j2' + dest: '{{ pleroma_config_dir }}/config.exs' + owner: '{{ pleroma_user }}' + group: '{{ pleroma_group }}' + mode: 0600 + notify: restart pleroma + +- name: '[Config] - Create data directories' + file: + path: '{{ item }}' + state: 'directory' + owner: '{{ pleroma_user }}' + group: '{{ pleroma_group }}' + mode: 0755 + loop: + - '{{ pleroma_data_dir }}/' + - '{{ pleroma_data_dir }}/uploads' + - '{{ pleroma_data_dir }}/static' + - '{{ pleroma_data_dir }}/static/emoji' + + + diff --git a/tasks/frontends.yml b/tasks/frontends.yml new file mode 100644 index 0000000..1f42657 --- /dev/null +++ b/tasks/frontends.yml @@ -0,0 +1,33 @@ +--- + +- name: '[Soapbox] - download and unarchive soapbox' + unarchive: + src: '{{ pleroma_soapbox_download_url }}' + dest: '{{ pleroma_tmp_dir }}' + creates: '{{ pleroma_tmp_dir }}/static' + remote_src: yes + +- name: '[Soapbox] - delete old soapbox' + file: + path: "{{ pleroma_data_dir }}/static/" + state: "absent" + changed_when: false + +- name: '[Soapbox] - install soapbox' + copy: + remote_src: true + src: '{{ pleroma_tmp_dir }}/static/' + dest: '{{ pleroma_data_dir }}/static/' + owner: '{{ pleroma_user }}' + group: '{{ pleroma_group }}' + mode: "0755" + changed_when: false + +- name: '[Soapbox] - install soapbox config' + template: + src: 'soapbox.json.j2' + dest: '{{ pleroma_data_dir }}/static/instance/soapbox.json' + owner: '{{ pleroma_user }}' + group: '{{ pleroma_group }}' + mode: "0755" + changed_when: false diff --git a/tasks/install.yml b/tasks/install.yml new file mode 100644 index 0000000..d1db418 --- /dev/null +++ b/tasks/install.yml @@ -0,0 +1,48 @@ +--- + +- name: '[Install] - Check if tmp dir exists' + file: + path: '{{ pleroma_tmp_dir }}' + state: directory + owner: '{{ pleroma_user }}' + group: '{{ pleroma_group }}' + +- name: '[Install] - Donwload and unarchive release' + unarchive: + src: '{{ pleroma_download_url }}' + dest: '{{ pleroma_tmp_dir }}' + remote_src: yes + +- name: '[Install] - Delete old releases' + copy: + remote_src: true + src: '{{ pleroma_tmp_dir }}' + dest: '{{ pleroma_app_dir }}' + owner: '{{ pleroma_user }}' + group: '{{ pleroma_group }}' + notify: restart pleroma + +- name: '[Install] - Migrate database' + command: '{{ pleroma_app_dir }}/release/bin/pleroma_ctl migrate' + become: yes + become_user: '{{ pleroma_user }}' + +- name: '[Install] - Start pleroma' + systemd: + name: pleroma + state: 'restarted' + daemon_reload: 'yes' + +- name: '[Install] - wait for pleroma node up' + wait_for: + host: '0.0.0.0' + port: 4000 + state: started + timeout: 6000 + + +- name: '[Install] - Create admin account' + command: '{{ pleroma_app_dir }}/release/bin/pleroma_ctl user new {{ pleroma_admin_user }} {{ pleroma_admin_email }} --password {{ pleroma_admin_password }} --admin -y' + become: yes + become_user: '{{ pleroma_user }}' + when: pleroma_admin == 'true' diff --git a/tasks/installdeps.yml b/tasks/installdeps.yml new file mode 100644 index 0000000..d8651a9 --- /dev/null +++ b/tasks/installdeps.yml @@ -0,0 +1,7 @@ +--- + +- name: '[APT] - Install dependencies' + apt: + name: '{{ pleroma_apt_list }}' + update_cache: yes + diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..9e62497 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,29 @@ +--- + +- include: user.yml + +- include: installdeps.yml + +- include: configure.yml + tags: + - upgrade + +- name: '[Main] - Check if pleroma release exists' + stat: + path: '{{ pleroma_app_dir }}/release' + register: pleroma_release + +- name: '[Main] - Install pleroma' + include_tasks: install.yml + when: pleroma_release.stat.exists == False + +- name: '[Main] - Upgrade pleroma' + include_tasks: upgrade.yml + tags: + - upgrade + - never + +- include: frontends.yml + tags: + - upgrade + - soapbox diff --git a/tasks/upgrade.yml b/tasks/upgrade.yml new file mode 100644 index 0000000..8fd7d2d --- /dev/null +++ b/tasks/upgrade.yml @@ -0,0 +1,12 @@ +--- + +- name: '[Upgrade] - Update pleroma release' + command: '{{ pleroma_app_dir }}/release/bin/pleroma_ctl update' + become: yes + become_user: '{{ pleroma_user }}' + +- name: '[Upgrade] - Run migrations' + command: '{{ pleroma_app_dir }}/release/bin/pleroma_ctl migrate' + become: yes + become_user: '{{ pleroma_user }}' + diff --git a/tasks/user.yml b/tasks/user.yml new file mode 100644 index 0000000..563063f --- /dev/null +++ b/tasks/user.yml @@ -0,0 +1,9 @@ +--- + +- name: '[User] - Add pleroma user' + user: + name: '{{ pleroma_user }}' + shell: '/bin/false' + home: '{{ pleroma_app_dir }}' + system: 'yes' + diff --git a/templates/config.exs.j2 b/templates/config.exs.j2 new file mode 100644 index 0000000..c3b506f --- /dev/null +++ b/templates/config.exs.j2 @@ -0,0 +1,53 @@ +import Config + +config :pleroma, Pleroma.Web.Endpoint, + url: [host: "{{ pleroma_link_host }}", scheme: "{{ pleroma_link_scheme }}", port: {{ pleroma_link_port}}], + http: [port: {{ pleroma_port }}, ip: {0, 0, 0, 0}], + secret_key_base: "{{ pleroma_secret_key }}", + secure_cookie_flag: true + +config :pleroma, :http_security, +enabled: {{ pleroma_https }}, + sts: true, + referrer_policy: "same-origin" + +config :pleroma, :instance, + name: "{{ pleroma_instance_name }}", + description: "{{ pleroma_desc }}", + email: "{{ pleroma_admin_email }}", + limit: {{ pleroma_char_limit }}, + registrations_open: {{ pleroma_signup_open }}, + invites_enabled: {{ pleroma_invites_enabled }}, + static_dir: "{{ pleroma_data_dir }}/static/" + +config :pleroma, Pleroma.Upload, + uploader: Pleroma.Uploaders.Local, + filters: [Pleroma.Upload.Filter.Dedupe] + +config :pleroma, Pleroma.Uploaders.Local, + uploads: "{{ pleroma_data_dir }}/uploads/" + +config :pleroma, :media_proxy, + enabled: true, + redirect_on_failure: true + +config :pleroma, Pleroma.Repo, + adapter: Ecto.Adapters.Postgres, + username: "{{ pleroma_db_user }}", + password: "{{ pleroma_db_passwd }}", + database: "{{ pleroma_db }}", + hostname: "{{ pleroma_db_host }}", + pool_size: 10, + timeout: 60000 + +config :prometheus, Pleroma.Web.Endpoint.MetricsExporter, + enabled: true +# ip_whitelist: ["127.0.0.1"], +# path: "/api/pleroma/app_metrics", +# format: :text + +config :logger, + backends: [{ExSyslogger, :ex_syslogger}] + +config :logger, :ex_syslogger, + level: {{ pleroma_loglevel }} diff --git a/templates/pleroma.service.j2 b/templates/pleroma.service.j2 new file mode 100644 index 0000000..970a90f --- /dev/null +++ b/templates/pleroma.service.j2 @@ -0,0 +1,37 @@ +[Unit] +Description=Pleroma social network +After=network.target postgresql.service nginx.service + +[Service] +KillMode=process +Restart=on-failure + +; Name of the user that runs the Pleroma service. +User={{ pleroma_user }} + +; Make sure that all paths fit your installation. +; Path to the home directory of the user running the Pleroma service. +Environment="HOME={{ pleroma_app_dir }}/release" +; Path to the folder containing the Pleroma installation. +WorkingDirectory={{ pleroma_app_dir }}/release +; Path to the Pleroma binary. +ExecStart={{ pleroma_app_dir }}/release/bin/pleroma start +ExecStop={{ pleroma_app_dir }}/release/bin/pleroma stop + +; Some security directives. +; Use private /tmp and /var/tmp folders inside a new file system namespace, which are discarded after the process stops. +PrivateTmp=true +; The /home, /root, and /run/user folders can not be accessed by this service anymore. If your Pleroma user has its home folder in one of the restricted places, or use one of these folders as its working directory, you have to set this to false. +ProtectHome=true +; Mount /usr, /boot, and /etc as read-only for processes invoked by this service. +ProtectSystem=full +; Sets up a new /dev mount for the process and only adds API pseudo devices like /dev/null, /dev/zero or /dev/random but not physical devices. Disabled by default because it may not work on devices like the Raspberry Pi. +PrivateDevices=false +; Ensures that the service process and all its children can never gain new privileges through execve(). +NoNewPrivileges=true +; Drops the sysadmin capability from the daemon. +CapabilityBoundingSet=~CAP_SYS_ADMIN + +[Install] +WantedBy=multi-user.target + diff --git a/templates/soapbox.json.j2 b/templates/soapbox.json.j2 new file mode 100644 index 0000000..add951c --- /dev/null +++ b/templates/soapbox.json.j2 @@ -0,0 +1,27 @@ +{ +"logo": "{{ pleroma_soapbox_logo }}", +"brandColor": "{{ pleroma_soapbox_brandcolor }}", +"promoPanel": { + "items": [ +{% for item in pleroma_soapbox_promopanel %} + { + "icon": "{{ item.icon }}", + "text": "{{ item.text }}", + "url": "{{ item.url }}" + }{% if not loop.last %},{% endif %} +{% endfor %} + ] + }, + "defaultSettings": { + "autoPlayGif": {{ pleroma_soapbox_gif }}, + "themeMode": "{{ pleroma_soapbox_thememode }}" + }, + "copyright": "{{ pleroma_soapbox_copyright }}", + "navlinks": { + "homeFooter": [ +{% for item in pleroma_soapbox_footer %} + { "title": "{{ item.name }}", "url": "{{ item.url }}" }{% if not loop.last %},{% endif %} +{% endfor %} + ] + } +}