Compare commits

...

7 Commits

Author SHA1 Message Date
Mathieu Gauthier-Pilote 1b6527c4ce With post-deployement the 2nd time; allow to upgrade rbenv if needed; upgrade browsers list db to remove warnings
gitea/ansible-roles/pipeline/head This commit looks good Details
2023-04-06 14:46:01 -04:00
Mathieu Gauthier-Pilote d992da0c1e use ansible_processor_count + fix db dump path
gitea/ansible-roles/pipeline/head This commit looks good Details
2023-01-16 10:42:41 -05:00
Mathieu Gauthier-Pilote 6c29a1f6d4 Ajust permissions of files in public folder
gitea/ansible-roles/pipeline/head This commit looks good Details
2023-01-16 09:23:16 -05:00
Mathieu Gauthier-Pilote 4aa133ebda Allow nginx to read public assets
gitea/ansible-roles/pipeline/head This commit looks good Details
2023-01-13 10:26:48 -05:00
Mathieu Gauthier-Pilote 1c1bc2fe9f Install LE cert. when there is none
gitea/ansible-roles/pipeline/head This commit looks good Details
2023-01-12 16:27:00 -05:00
Mathieu Gauthier-Pilote 6e0d6b8a32 README.md + LISEZMOI.md
gitea/ansible-roles/pipeline/head This commit looks good Details
2023-01-06 10:48:56 -05:00
Mathieu Gauthier-Pilote 4c59374507 p10166 RĂ´le pour mastodon
gitea/ansible-roles/pipeline/head This commit looks good Details
2022-12-23 10:00:00 -05:00
16 changed files with 963 additions and 0 deletions

View File

@ -0,0 +1,73 @@
mastodon
=========
Ce rôle installe le serveur de Mastodon, une application de microblogage, libre et autohébergée.
Notez qu'hormis le présent fichier LISEZMOI.md, tous les fichiers du rôle mastodon 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
- postgresql
- redis
- elasticsearch
- rbenv
- nginx
- certbot
Exemple de playbook
-------------------
```
- name: "DĂ©ployer un serveur Mastodon"
hosts:
- all
vars:
# Supplanter ici les variables du rĂ´le
domains: ['votre-vrai-domaine.org']
service: 'mon-mastodon'
db_host: 'localhost'
db_user: "{{ service }}"
db_name: "{{ service }}"
db_password: 'zKEh-CHANGEZ-MOI-qIKc'
app_secret_key_base: ""
app_otp_secret: ""
app_vapid_private_key: ""
app_vapid_public_key: ""
app_smtp_from_address: "mastodon@votre-vrai-domaine.org"
pre_tasks:
- name: "Installer les rôles systèmes"
roles:
- { role: nodejs, nodejs_apt_version: 'node_16.x', nodejs_install_yarn: True }
- { role: postgresql }
- { role: redis }
- { role: elasticsearch }
- { role: nginx }
- { role: certbot }
roles:
- { role: webapps/mastodon , tags: "mastodon" }
```
Licence
-------
GPLv3
Infos sur l'auteur
------------------
Mathieu Gauthier-Pilote, administrateur de systèmes chez Evolix.

View File

@ -0,0 +1,73 @@
mastodon
=========
This role installs or upgrades the server for Mastodon, a free and decentralized microblogging social network.
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
- postgresql
- redis
- elasticsearch
- rbenv
- nginx
- certbot
Example Playbook
----------------
```
- name: "Deploy a Mastodon server"
hosts:
- all
vars:
# Overwrite the role variable here
domains: ['your-real-domain.org']
service: 'my-mastodon'
db_host: 'localhost'
db_user: "{{ service }}"
db_name: "{{ service }}"
db_password: 'zKEh-CHANGE-ME-qIKc'
app_secret_key_base: ""
app_otp_secret: ""
app_vapid_private_key: ""
app_vapid_public_key: ""
app_smtp_from_address: "mastodon@your-real-domain.org"
pre_tasks:
- name: "Install system roles"
roles:
- { role: nodejs, nodejs_apt_version: 'node_16.x', nodejs_install_yarn: True }
- { role: postgresql }
- { role: redis }
- { role: elasticsearch }
- { role: nginx }
- { role: certbot }
roles:
- { role: webapps/mastodon , tags: "mastodon" }
```
License
-------
GPLv3
Author Information
------------------
Mathieu Gauthier-Pilote, sys. admin. at Evolix.

View File

@ -0,0 +1,26 @@
---
# defaults file for mastodon
system_dep: "['imagemagick', 'ffmpeg', 'libpq-dev', 'libxml2-dev', 'libxslt1-dev', 'file', 'git-core', 'g++', 'libprotobuf-dev', 'protobuf-compiler', 'pkg-config', 'nodejs', 'gcc', 'autoconf', 'bison', 'build-essential', 'libssl-dev', 'libyaml-dev', 'libreadline6-dev', 'zlib1g-dev', 'libncurses5-dev', 'libffi-dev', 'libgdbm-dev', 'nginx', 'redis-server', 'redis-tools', 'postgresql', 'postgresql-contrib', 'certbot', 'python3-certbot-nginx', 'libidn11-dev', 'libicu-dev', 'libjemalloc-dev', 'yarn']"
domains: ['example.somedomain.org']
git_url: 'https://github.com/mastodon/mastodon.git'
git_version: 'v4.0.2'
ruby_version: '3.0.4'
service: 'example'
db_host: 'localhost'
db_user: "{{ service }}"
db_name: "{{ service }}_production"
db_password: 'CHANGE_ME'
#puma_port: '3000'
#node_port: '4000'
app_secret_key_base: ""
app_otp_secret: ""
app_vapid_private_key: ""
app_vapid_public_key: ""
app_smtp_server: "127.0.0.1"
app_smtp_port: "25"
app_smtp_from_address: "example@somedomain.org"
app_smtp_auth_method: "none"
app_smtp_openssl_verify_mode: "none"
app_es_enabled: "false"

View File

@ -0,0 +1,2 @@
---
# handlers file for mastodon

View File

@ -0,0 +1,52 @@
galaxy_info:
author: your name
description: your role description
company: your company (optional)
# 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-2.0-or-later, MIT, etc)
min_ansible_version: 2.1
# 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.

View File

@ -0,0 +1,224 @@
---
# tasks file for mastodon install
- name: Install main system dependencies
apt:
name: "{{ system_dep }}"
- name: Add PostgreSQL user
postgresql_user:
name: "{{ db_user }}"
password: "{{ db_password }}"
role_attr_flags: CREATEDB
become_user: postgres
- name: Add UNIX account
user:
name: "{{ service }}"
shell: /bin/bash
# umask: "0022" nécessite ansible-core 2.12
- name: Install Ruby for service user (rbenv)
include_role:
name: rbenv
vars:
- username: "{{ service }}"
- rbenv_ruby_version: "{{ ruby_version }}"
- name: Clone Mastodon repo (git)
git:
repo: "{{ git_url }}"
dest: "~/mastodon/"
version: "{{ git_version | default(omit) }}"
#force: yes
update: yes
umask: '0022'
become_user: "{{ service }}"
- block:
- name: Install bundler
shell: ". ~/.profile && gem install bundler --no-document"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Install gem dependencies
shell: ". ~/.profile && bundle install --deployment --without development test -j{{ ansible_processor_count }}"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Install javascript dependencies
shell: ". ~/.profile && yarn install --pure-lockfile"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
become_user: "{{ service }}"
- name: Template .env.production configuration file
template:
src: "env.j2"
dest: "~{{ service }}/mastodon/.env.production"
owner: "{{ service }}"
group: "{{ service }}"
mode: "0640"
- name: Check if secrets need to be generated or not
shell: "grep -P SECRET_KEY_BASE=[[:alnum:]]{128} .env.production"
args:
chdir: "~/mastodon"
become_user: "{{ service }}"
register: secrets
failed_when: "secrets.rc == 2"
- block:
- name: Generate secret for SECRET_KEY_BASE
shell: '. ~/.profile && sed -i -r "s/SECRET_KEY_BASE=/SECRET_KEY_BASE=$(RAILS_ENV=production bundle exec rake secret)/" .env.production'
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Generate secret for OTP_SECRET
shell: '. ~/.profile && sed -i -r "s/OTP_SECRET=/OTP_SECRET=$(RAILS_ENV=production bundle exec rake secret)/" .env.production'
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Generate secret for VAPID_PRIVATE_KEY and VAPID_PUBLIC_KEY
shell: . ~/.profile && RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key > vapid.tmp | head -1 | cut -c 19-
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Read VAPID_PRIVATE_KEY secret from temp file
shell: "cat vapid.tmp | head -1 | cut -c 19-"
args:
chdir: "~/mastodon"
register: app_vapid_private_key
- name: Read VAPID_PUBLIC_KEY secret from temp file
shell: "cat vapid.tmp | tail -1 | cut -c 18-"
args:
chdir: "~/mastodon"
register: app_vapid_public_key
- name: Delete secrets temp file
file:
path: "~/mastodon/vapid.tmp"
state: absent
- name: Write app_vapid_private_key to production .env file
lineinfile:
path: "~/mastodon/.env.production"
regexp: '^VAPID_PRIVATE_KEY='
line: "VAPID_PRIVATE_KEY={{ app_vapid_private_key.stdout }}"
- name: Write app_vapid_public_key to production .env file
lineinfile:
path: "~/mastodon/.env.production"
regexp: '^VAPID_PUBLIC_KEY='
line: "VAPID_PUBLIC_KEY={{ app_vapid_public_key.stdout }}"
become_user: "{{ service }}"
when: "secrets.rc == 1"
- name: Check if mastodon database is already present or not
shell: |
psql -lqt | cut -d \| -f 1 | grep -qw {{ service }}_production
become_user: postgres
register: db_present
failed_when: "db_present.rc == 2"
- name: Setup database schema if database not already present
shell: ". ~/.profile && RAILS_ENV=production SAFETY_ASSURED=1 bundle exec rails db:setup"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
become_user: "{{ service }}"
when: "db_present.rc == 1"
- name: Precompile assets
shell: ". ~/.profile && RAILS_ENV=production bundle exec rails assets:precompile"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
become_user: "{{ service }}"
- name: Adjust permissions of files in public folder
file:
path: "~/mastodon/public"
state: directory
mode: 'o=rX'
recurse: true
become_user: "{{ service }}"
- name: Add systemd target
template:
src: "mastodon.target.j2"
dest: "/etc/systemd/system/{{ service }}.target"
- name: Add systemd web unit
template:
src: "mastodon-web.service.j2"
dest: "/etc/systemd/system/{{ service }}-web.service"
- name: Add systemd sidekiq unit
template:
src: "mastodon-sidekiq.service.j2"
dest: "/etc/systemd/system/{{ service }}-sidekiq.service"
- name: Add systemd streaming unit
template:
src: "mastodon-streaming.service.j2"
dest: "/etc/systemd/system/{{ service }}-streaming.service"
- name: Enable systemd units
systemd:
name: "{{ item }}"
enabled: yes
daemon_reload: yes
loop:
- "{{ service }}.target"
- "{{ service }}-web.service"
- "{{ service }}-sidekiq.service"
- "{{ service }}-streaming.service"
- name: Start services
service:
name: "{{ service }}.target"
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: 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 mastodon
file:
src: "/etc/nginx/sites-available/{{ service }}"
dest: "/etc/nginx/sites-enabled/{{ service }}"
state: link
- name: Reload nginx conf
service:
name: nginx
state: reloaded

View File

@ -0,0 +1,98 @@
---
# tasks file for mastodon upgrade
- name: Dump database to a file with compression
postgresql_db:
name: "{{ service }}_production"
state: dump
target: "~/{{ service }}_production.sql.gz"
become_user: postgres
- name: Install Ruby for service user (rbenv)
include_role:
name: rbenv
vars:
- username: "{{ service }}"
- rbenv_ruby_version: "{{ ruby_version }}"
- name: Checkout (git)
git:
repo: "{{ git_url }}"
dest: "~/mastodon/"
version: "{{ git_version | default(omit) }}"
force: yes
update: yes
become_user: "{{ service }}"
- block:
- name: Install bundler
shell: ". ~/.profile && gem install bundler --no-document"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Install gem dependencies
shell: ". ~/.profile && bundle install --deployment --without development test -j{{ ansible_processor_count }}"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Install javascript dependencies
shell: ". ~/.profile && yarn install --pure-lockfile"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Upgrade browsers list db
shell: ". ~/.profile && npx update-browserslist-db@latest"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Run database migrations, skipping post-deployment
shell: ". ~/.profile && SKIP_POST_DEPLOYMENT_MIGRATIONS=true RAILS_ENV=production bundle exec rails db:migrate"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Precompile assets
shell: ". ~/.profile && RAILS_ENV=production bundle exec rails assets:precompile"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
- name: Adjust permissions of files in public folder
file:
path: "~/mastodon/public"
state: directory
mode: 'o=rX'
recurse: true
become_user: "{{ service }}"
- name: Restart services
service:
name: "{{ service }}.target"
state: restarted
- name: Run database migrations, this time including post-deployment
shell: ". ~/.profile && RAILS_ENV=production bundle exec rails db:migrate"
args:
chdir: "~/mastodon"
executable: /bin/bash # fails with /bin/sh
become_user: "{{ service }}"
- name: Restart services
service:
name: "{{ service }}.target"
state: restarted
- name: Define variable to skip next task by default
set_fact:
keep_db_dump: true
- name: Remove database dump
file:
path: "~/{{ service }}_production.sql.gz"
state: absent
become_user: postgres
when: keep_db_dump is undefined
tags: clean
- name: Reload nginx conf
service:
name: nginx
state: reloaded

View File

@ -0,0 +1,235 @@
# Service dependencies
# You may set REDIS_URL instead for more advanced options
# You may also set REDIS_NAMESPACE to share Redis between multiple Mastodon servers
#REDIS_URL=unix:///var/run/redis/redis.sock
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_NAMESPACE={{ service }}
# You may set DATABASE_URL instead for more advanced options
DB_HOST={{ db_host }}
DB_USER={{ db_user }}
DB_NAME={{ db_name }}
DB_PASS='{{ db_password }}'
DB_PORT=5432
# Optional ElasticSearch configuration
#ES_ENABLED={{ app_es_enabled | default('false') }}
#ES_HOST={{ app_es_host | default('localhost') }}
#ES_PORT={{ app_es_port | default('9200') }}
# Federation
# Note: Changing LOCAL_DOMAIN at a later time will cause unwanted side effects, including breaking all existing federation.
# LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com.
LOCAL_DOMAIN={{ domains |first }}
# Changing LOCAL_HTTPS in production is no longer supported. (Mastodon will always serve https:// links)
# Use this only if you need to run mastodon on a different domain than the one used for federation.
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
# DO *NOT* USE THIS UNLESS YOU KNOW *EXACTLY* WHAT YOU ARE DOING.
# WEB_DOMAIN=mastodon.example.com
# Use this if you want to have several aliases handler@example1.com
# handler@example2.com etc. for the same user. LOCAL_DOMAIN should not
# be added. Comma separated values
# ALTERNATE_DOMAINS=example1.com,example2.com
# Application secrets
# Generate each with the `RAILS_ENV=production bundle exec rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
SECRET_KEY_BASE={{ app_secret_key_base }}
OTP_SECRET={{ app_otp_secret }}
# VAPID keys (used for push notifications
# You can generate the keys using the following command (first is the private key, second is the public one)
# You should only generate this once per instance. If you later decide to change it, all push subscription will
# be invalidated, requiring the users to access the website again to resubscribe.
#
# Generate with `RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web rake mastodon:webpush:generate_vapid_key` if you use docker compose)
#
# For more information visit https://rossta.net/blog/using-the-web-push-api-with-vapid.html
VAPID_PRIVATE_KEY={{ app_vapid_private_key }}
VAPID_PUBLIC_KEY={{ app_vapid_public_key }}
# Registrations
# Single user mode will disable registrations and redirect frontpage to the first profile
# SINGLE_USER_MODE=true
# Prevent registrations with following e-mail domains
# EMAIL_DOMAIN_BLACKLIST=example1.com|example2.de|etc
# Only allow registrations with the following e-mail domains
# EMAIL_DOMAIN_WHITELIST=example1.com|example2.de|etc
# Optionally change default language
# DEFAULT_LOCALE=de
# E-mail configuration
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
# If you want to use an SMTP server without authentication (e.g local Postfix relay)
# then set SMTP_AUTH_METHOD and SMTP_OPENSSL_VERIFY_MODE to 'none' and
# *comment* SMTP_LOGIN and SMTP_PASSWORD (leaving them blank is not enough).
SMTP_SERVER={{ app_smtp_server | default('smtp.mailgun.org') }}
SMTP_PORT={{ app_smtp_port | default('587') }}
#SMTP_LOGIN=
#SMTP_PASSWORD=
SMTP_FROM_ADDRESS={{ app_smtp_from_address | default('notifications@example.com') }}
#SMTP_DOMAIN= # defaults to LOCAL_DOMAIN
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
SMTP_AUTH_METHOD={{ app_smtp_auth_method | default('plain') }}
#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt
#SMTP_OPENSSL_VERIFY_MODE={{ app_smtp_openssl_verify_mode | default('peer') }}
#SMTP_ENABLE_STARTTLS_AUTO=true
#SMTP_TLS=true
# Optional user upload path and URL (images, avatars). Default is :rails_root/public/system. If you set this variable, you are responsible for making your HTTP server (eg. nginx) serve these files.
# PAPERCLIP_ROOT_PATH=/var/lib/mastodon/public-system
# PAPERCLIP_ROOT_URL=/system
# Optional asset host for multi-server setups
# The asset host must allow cross origin request from WEB_DOMAIN or LOCAL_DOMAIN
# if WEB_DOMAIN is not set. For example, the server may have the
# following header field:
# Access-Control-Allow-Origin: https://example.com/
# CDN_HOST=https://assets.example.com
# S3 (optional)
# The attachment host must allow cross origin request from WEB_DOMAIN or
# LOCAL_DOMAIN if WEB_DOMAIN is not set. For example, the server may have the
# following header field:
# Access-Control-Allow-Origin: https://192.168.1.123:9000/
# S3_ENABLED=true
# S3_BUCKET=
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=
# S3_REGION=
# S3_PROTOCOL=http
# S3_HOSTNAME=192.168.1.123:9000
# S3 (Minio Config (optional) Please check Minio instance for details)
# The attachment host must allow cross origin request - see the description
# above.
# S3_ENABLED=true
# S3_BUCKET=
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=
# S3_REGION=
# S3_PROTOCOL=https
# S3_HOSTNAME=
# S3_ENDPOINT=
# S3_SIGNATURE_VERSION=
# Swift (optional)
# The attachment host must allow cross origin request - see the description
# above.
# SWIFT_ENABLED=true
# SWIFT_USERNAME=
# For Keystone V3, the value for SWIFT_TENANT should be the project name
# SWIFT_TENANT=
# SWIFT_PASSWORD=
# Some OpenStack V3 providers require PROJECT_ID (optional)
# SWIFT_PROJECT_ID=
# Keystone V2 and V3 URLs are supported. Use a V3 URL if possible to avoid
# issues with token rate-limiting during high load.
# SWIFT_AUTH_URL=
# SWIFT_CONTAINER=
# SWIFT_OBJECT_URL=
# SWIFT_REGION=
# Defaults to 'default'
# SWIFT_DOMAIN_NAME=
# Defaults to 60 seconds. Set to 0 to disable
# SWIFT_CACHE_TTL=
# Optional alias for S3 (e.g. to serve files on a custom domain, possibly using Cloudfront or Cloudflare)
# S3_ALIAS_HOST=
# Streaming API integration
# STREAMING_API_BASE_URL=
# Advanced settings
# If you need to use pgBouncer, you need to disable prepared statements:
# PREPARED_STATEMENTS=false
# Cluster number setting for streaming API server.
# If you comment out following line, cluster number will be `numOfCpuCores - 1`.
STREAMING_CLUSTER_NUM=1
# Docker mastodon user
# If you use Docker, you may want to assign UID/GID manually.
# UID=1000
# GID=1000
# LDAP authentication (optional)
# LDAP_ENABLED=true
# LDAP_HOST=localhost
# LDAP_PORT=389
# LDAP_METHOD=simple_tls
# LDAP_BASE=
# LDAP_BIND_DN=
# LDAP_PASSWORD=
# LDAP_UID=cn
# LDAP_SEARCH_FILTER="%{uid}=%{email}"
# PAM authentication (optional)
# PAM authentication uses for the email generation the "email" pam variable
# and optional as fallback PAM_DEFAULT_SUFFIX
# The pam environment variable "email" is provided by:
# https://github.com/devkral/pam_email_extractor
# PAM_ENABLED=true
# Fallback email domain for email address generation (LOCAL_DOMAIN by default)
# PAM_EMAIL_DOMAIN=example.com
# Name of the pam service (pam "auth" section is evaluated)
# PAM_DEFAULT_SERVICE=rpam
# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default)
# PAM_CONTROLLED_SERVICE=rpam
# Global OAuth settings (optional) :
# If you have only one strategy, you may want to enable this
# OAUTH_REDIRECT_AT_SIGN_IN=true
# Optional CAS authentication (cf. omniauth-cas) :
# CAS_ENABLED=true
# CAS_URL=https://sso.myserver.com/
# CAS_HOST=sso.myserver.com/
# CAS_PORT=443
# CAS_SSL=true
# CAS_VALIDATE_URL=
# CAS_CALLBACK_URL=
# CAS_LOGOUT_URL=
# CAS_LOGIN_URL=
# CAS_UID_FIELD='user'
# CAS_CA_PATH=
# CAS_DISABLE_SSL_VERIFICATION=false
# CAS_UID_KEY='user'
# CAS_NAME_KEY='name'
# CAS_EMAIL_KEY='email'
# CAS_NICKNAME_KEY='nickname'
# CAS_FIRST_NAME_KEY='firstname'
# CAS_LAST_NAME_KEY='lastname'
# CAS_LOCATION_KEY='location'
# CAS_IMAGE_KEY='image'
# CAS_PHONE_KEY='phone'
# Optional SAML authentication (cf. omniauth-saml)
# SAML_ENABLED=true
# SAML_ACS_URL=
# SAML_ISSUER=http://localhost:3000/auth/auth/saml/callback
# SAML_IDP_SSO_TARGET_URL=https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO
# SAML_IDP_CERT=
# SAML_IDP_CERT_FINGERPRINT=
# SAML_NAME_IDENTIFIER_FORMAT=
# SAML_CERT=
# SAML_PRIVATE_KEY=
# SAML_SECURITY_WANT_ASSERTION_SIGNED=true
# SAML_SECURITY_WANT_ASSERTION_ENCRYPTED=true
# SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true
# SAML_ATTRIBUTES_STATEMENTS_UID="urn:oid:0.9.2342.19200300.100.1.1"
# SAML_ATTRIBUTES_STATEMENTS_EMAIL="urn:oid:1.3.6.1.4.1.5923.1.1.1.6"
# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.16.840.1.113730.3.1.241"
# SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME="urn:oid:2.5.4.42"
# SAML_ATTRIBUTES_STATEMENTS_LAST_NAME="urn:oid:2.5.4.4"
# SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1"
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED=
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL=
# Use HTTP proxy for outgoing request (optional)
# http_proxy=http://gateway.local:8118
# Access control for hidden service.
# ALLOW_ACCESS_TO_HIDDEN_SERVICE=true

View File

@ -0,0 +1,23 @@
[Unit]
Description=mastodon-sidekiq
After=network.target
PartOf={{service}}.target
[Service]
Type=simple
User={{service}}
Group={{service}}
UMask=0027
WorkingDirectory=/home/{{service}}/mastodon/
Environment="RAILS_ENV=production"
Environment="RAILS_LOG_LEVEL=error"
Environment="DB_POOL=25"
Environment="MALLOC_ARENA_MAX=2"
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/{{service}}/.rbenv/shims/bundle exec sidekiq -c 25
TimeoutSec=15
Restart=always
SyslogIdentifier=%p
[Install]
WantedBy={{service}}.target

View File

@ -0,0 +1,21 @@
[Unit]
Description=mastodon-streaming
After=network.target
PartOf={{service}}.target
[Service]
Type=simple
User={{service}}
Group={{service}}
UMask=0027
WorkingDirectory=/home/{{service}}/mastodon/
Environment="NODE_ENV=production"
Environment="PORT={{ node_port | default('4000')}}"
Environment="STREAMING_CLUSTER_NUM=1"
ExecStart=/bin/bash -lc "node ./streaming"
TimeoutSec=15
Restart=always
SyslogIdentifier=%p
[Install]
WantedBy={{service}}.target

View File

@ -0,0 +1,23 @@
[Unit]
Description=mastodon-web
After=network.target
PartOf={{service}}.target
[Service]
Type=simple
User={{service}}
Group={{service}}
UMask=0027
WorkingDirectory=/home/{{service}}/mastodon/
Environment="RAILS_ENV=production"
Environment="PORT={{puma_port|default('3000')}}"
Environment="RAILS_LOG_LEVEL=warn"
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/{{service}}/.rbenv/shims/bundle exec puma -C config/puma.rb
ExecReload=/bin/kill -SIGUSR1 $MAINPID
TimeoutSec=15
Restart=always
SyslogIdentifier=%p
[Install]
WantedBy={{service}}.target

View File

@ -0,0 +1,8 @@
[Unit]
Description=Mastodon Microblogging service
Wants=redis-server.service
After=redis-server.service
Requires={{ service }}-web.service {{ service }}-sidekiq.service {{ service }}-streaming.service
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,96 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name {{ domains |first }};
include /etc/nginx/snippets/letsencrypt.conf;
{% 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 }};
include /etc/nginx/snippets/letsencrypt.conf;
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;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
keepalive_timeout 70;
sendfile on;
client_max_body_size 0;
root /home/{{ service }}/mastodon/public;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
#add_header Strict-Transport-Security "max-age=31536000";
#add_header Content-Security-Policy "style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'self'; img-src data: https:; media-src data: https:; connect-src 'self' wss://{{ domains |first }}; upgrade-insecure-requests";
location / {
try_files $uri @proxy;
}
location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri @proxy;
}
location @proxy {
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 https;
proxy_set_header Proxy "";
proxy_pass_header Server;
proxy_pass http://127.0.0.1:{{puma_port|default('3000')}};
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
tcp_nodelay on;
}
location /api/v1/streaming {
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 https;
proxy_set_header Proxy "";
proxy_pass http://127.0.0.1:{{ node_port | default('4000')}};
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
tcp_nodelay on;
}
error_page 500 501 502 503 504 /500.html;
}
{% endif %}

View File

@ -0,0 +1,2 @@
localhost

View File

@ -0,0 +1,5 @@
---
- hosts: localhost
remote_user: root
roles:
- mastodon

View File

@ -0,0 +1,2 @@
---
# vars file for mastodon