Initial commit

This commit is contained in:
Waffles
2022-12-21 22:30:01 -08:00
commit 19ebda26b4
47 changed files with 1429 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
roles/mastodon/vars/main.yml
+6
View File
@@ -0,0 +1,6 @@
[submodule "roles/ansible-role-oh-my-zsh"]
path = roles/ansible-role-oh-my-zsh
url = https://github.com/gantsign/ansible-role-oh-my-zsh.git
[submodule "roles/ansible-role-neovim"]
path = roles/ansible-role-neovim
url = https://github.com/gikeymarcia/ansible-role-neovim.git
+3
View File
@@ -0,0 +1,3 @@
install:
ansible-galaxy install geerlingguy.docker geerlingguy.nginx geerlingguy.certbot
git submodule update --init --recursive
Submodule ansible-role-oh-my-zsh added at 953875c90d
+3
View File
@@ -0,0 +1,3 @@
[defaults]
inventory=./hosts
ansible_connection=paramiko
+15
View File
@@ -0,0 +1,15 @@
---
- name: Configure yttrx frontend environment
hosts: [frontend]
roles:
- role: frontend
vars:
webapp_hosts:
- tusky.masto.yttrx.com
handlers:
- name: Re-up docker containers
command: docker-compose up -d
args:
chdir: /home/mastodon/live
listen: "docker-compose up"
+3
View File
@@ -0,0 +1,3 @@
MASTODON_VERSION: v4.0.2
REAL_DB_HOST: tusky.masto.yttrx.com
DB_POOL: 25
+27
View File
@@ -0,0 +1,27 @@
[yttrx]
grafana.yttrx.com ansible_user=root
tusky.masto.yttrx.com ansible_user=root
mammut.masto.yttrx.com ansible_user=root
mail.yttrx.com ansible_user=root
[mastodon]
#tusky.masto.yttrx.com ansible_user=root
mammut.masto.yttrx.com ansible_user=root
[sidekiq]
wooly.masto.yttrx.com ansible_user=root
[frontend]
wooly.masto.yttrx.com ansible_user=root
[webapp]
#wooly.masto.yttrx.com ansible_user=root
[yttrx:vars]
ansible_python_interpreter=/usr/bin/python3
[mta]
mail.yttrx.com ansible_user=root
[mta:vars]
ansible_python_interpreter=/usr/bin/python3
+6
View File
@@ -0,0 +1,6 @@
---
- name: Configure yttrx mastodon environment
hosts: [mastodon]
roles:
- role: mastodon
+22
View File
@@ -0,0 +1,22 @@
---
- name: Configure yttrx mail server environment
hosts: [mta]
roles:
- role: mta
handlers:
- name: Restart dovecot
service:
name: dovecot
state: restarted
listen: "restart services"
- name: Restart postfix
service:
name: postfix
state: restarted
listen: "restart services"
- name: postmap
command: /usr/sbin/postmap /etc/postfix/virtual
listen: "postmap"
+4
View File
@@ -0,0 +1,4 @@
---
dependencies:
- role: geerlingguy.nginx
- role: mastodon # Required for the www root for nginx
+55
View File
@@ -0,0 +1,55 @@
---
# Install the requires nginx sites-available
- name: Create nginx cache dir
file:
path: /data/nginx/cache
state: directory
owner: www-data
group: www-data
- name: Install nginx site files
template:
src: files.j2
dest: /etc/nginx/sites-available/files
notify: restart nginx
- name: Install nginx mastodon config
template:
src: mastodon.j2
dest: /etc/nginx/sites-available/mastodon
notify: restart nginx
- name: Enable files
file:
src: /etc/nginx/sites-available/files
dest: /etc/nginx/sites-enabled/files
state: link
- name: Enable mastodon
file:
src: /etc/nginx/sites-available/mastodon
dest: /etc/nginx/sites-enabled/mastodon
state: link
- name: Disable default
file:
path: /etc/nginx/sites-enabled/default
state: absent
- name: Copy dmca
template:
src: dmca
dest: /etc/nginx/dmca
notify: restart nginx
- name: Copy cloudflare
template:
src: cloudflare
dest: /etc/nginx/cloudflare
notify: restart nginx
- name: install certbot
package:
name: python3-certbot-nginx
state: present
+29
View File
@@ -0,0 +1,29 @@
#Cloudflare
# - IPv4
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
# - IPv6
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;
+4
View File
@@ -0,0 +1,4 @@
# Example
#location = /cache/media_attachments/files/109/437/372/880/064/218/original/3260dbbf5bbdce0e.jpg {
# deny all;
#}
+90
View File
@@ -0,0 +1,90 @@
server {
listen 80;
listen [::]:80;
server_name {{ ENV_PRODUCTION['S3_ALIAS_HOST'] }};
root /var/www/html;
# Useful for Let's Encrypt
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
log_format files_cache '$remote_addr - $upstream_cache_status [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
proxy_cache_path /data/nginx/cache keys_zone=mycache:50m inactive=3d;
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ ENV_PRODUCTION['S3_ALIAS_HOST'] }};
root /var/www/html;
include /etc/nginx/cloudflare;
ssl_certificate /etc/letsencrypt/live/{{ ENV_PRODUCTION['S3_ALIAS_HOST'] }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ ENV_PRODUCTION['S3_ALIAS_HOST'] }}/privkey.pem;
access_log /var/log/nginx/{{ ENV_PRODUCTION['S3_ALIAS_HOST'] }}.access.log files_cache;
error_log /var/log/nginx/{{ ENV_PRODUCTION['S3_ALIAS_HOST'] }}.error.log;
proxy_cache mycache;
keepalive_timeout 30;
# Don't allow directory listings
location ~ ^.*/$ {
deny all;
}
include /etc/nginx/dmca;
location ~ .+ {
try_files $uri @s3;
}
set $s3_backend '{{ ENV_PRODUCTION['S3_HOSTNAME'] }}';
location @s3 {
limit_except GET {
deny all;
}
resolver 8.8.8.8;
proxy_set_header Host yttrx.sfo3.digitaloceanspaces.com;
proxy_set_header Connection '';
proxy_set_header Authorization '';
proxy_hide_header Set-Cookie;
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
#proxy_hide_header x-amz-id-2;
#proxy_hide_header x-amz-request-id;
#proxy_hide_header x-amz-meta-server-side-encryption;
#proxy_hide_header x-amz-server-side-encryption;
#proxy_hide_header x-amz-bucket-region;
#proxy_hide_header x-amzn-requestid;
proxy_ignore_headers Set-Cookie;
proxy_pass $s3_backend$uri;
#proxy_intercept_errors off;
# turn this on so that we can capture and redirect bad links to the main 404 page
proxy_intercept_errors on;
#proxy_cache_valid 200 48h;
proxy_cache_valid 48h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
proxy_cache_key $uri;
# Download stale data only if it has been modified on origin
proxy_cache_revalidate off;
expires 30d;
add_header Pragma public;
add_header Cache-Control "public";
add_header 'Access-Control-Allow-Origin' '*';
add_header X-Cache-Status $upstream_cache_status;
error_page 403 https://{{ ENV_PRODUCTION['LOCAL_DOMAIN'] }}/404.html;
error_page 404 https://{{ ENV_PRODUCTION['LOCAL_DOMAIN'] }}/404.html;
}
}
+117
View File
@@ -0,0 +1,117 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name {{ ENV_PRODUCTION['LOCAL_DOMAIN'] }}
root /home/mastodon/live/public;
# Useful for Let's Encrypt
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
upstream webbackend {
{% for server in webapp_hosts %}
server {{ server }}:3000;
{% endfor %}
}
upstream streamingbackend {
{% for server in webapp_hosts %}
server {{ server }}:4000;
{% endfor %}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ ENV_PRODUCTION['LOCAL_DOMAIN'] }};
include /etc/nginx/cloudflare;
ssl_protocols TLSv1.2;
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA; ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_certificate /etc/letsencrypt/live/{{ ENV_PRODUCTION['LOCAL_DOMAIN'] }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ ENV_PRODUCTION['LOCAL_DOMAIN'] }}/privkey.pem;
keepalive_timeout 70;
sendfile on;
client_max_body_size 80m;
root /home/mastodon/live/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";
location / {
try_files $uri @proxy;
}
# WITH S3
location ~ ^/(emoji|packs) {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri @proxy;
}
location /system {
rewrite ^/system(.*) https://{{ ENV_PRODUCTION['S3_ALIAS_HOST'] }}$1 permanent;
}
# END OF S3
location /sw.js {
#add_header Cache-Control "public, max-age=0";
add_header Cache-Control "public, max-age=604800, must-revalidate";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
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://webbackend;
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://streamingbackend;
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;
}
+19
View File
@@ -0,0 +1,19 @@
server {
listen 81 default_server;
listen [::]:81 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location /nginx_status {
stub_status;
#allow 127.0.0.1;
#deny all;
}
}
+76
View File
@@ -0,0 +1,76 @@
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 80;
listen [::]:80;
server_name tusky.yttrx.com;
root /var/www/html/tusky;
# Useful for Let's Encrypt
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name tusky.yttrx.com;
root /var/www/html/tusky;
ssl_certificate /etc/letsencrypt/live/tusky.yttrx.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tusky.yttrx.com/privkey.pem;
access_log /var/log/nginx/tusky.access.log;
error_log /var/log/nginx/static.error.log;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /statsd {
try_files $uri @proxy;
}
location /metrics {
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 http://127.0.0.1:9102;
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;
}
}
+57
View File
@@ -0,0 +1,57 @@
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 80;
listen [::]:80;
server_name waffles.yttrx.com;
root /var/www/html/waffles;
# Useful for Let's Encrypt
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name waffles.yttrx.com;
root /var/www/html/waffles;
include /etc/nginx/cloudflare;
ssl_certificate /etc/letsencrypt/live/waffles.yttrx.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/waffles.yttrx.com/privkey.pem; # managed by Certbot
access_log /var/log/nginx/waffles.access.log;
error_log /var/log/nginx/waffles.error.log;
location = /.well-known/webfinger {
types {} default_type "application/jrd+json";
add_header Access-Control-Allow-Origin "*";
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
+1
View File
@@ -0,0 +1 @@
---
+4
View File
@@ -0,0 +1,4 @@
---
dependencies:
- role: geerlingguy.docker
- role: yttrx
+32
View File
@@ -0,0 +1,32 @@
---
# Setup users etc
- name: create the mastodon user account
user:
name: mastodon
shell: /bin/bash
group: docker
- name: Check if mastodon repo checked out
stat: path=/home/mastodon/live
register: p
- import_tasks: swap.yml
- import_tasks: repo.yml
when: not p.stat.exists
- name: Install statsd mapper
template:
src: statsd-mapping.yaml.j2
dest: /root/statsd-mapping.yml
- name: Install .env.production file
template:
src: env.production.j2
dest: /home/mastodon/live/.env.production
- name: Install docker-compose.yml file
template:
src: docker-compose.yml.j2
dest: /home/mastodon/live/docker-compose.yml
notify: "docker-compose up"
+7
View File
@@ -0,0 +1,7 @@
---
- name: clone mastodon repo
git:
repo: https://github.com/mastodon/mastodon.git
dest: /home/mastodon/live
version: v4.0.2
+36
View File
@@ -0,0 +1,36 @@
- name: set swap_file variable
set_fact:
swap_file: /{{ swap_space }}.swap
- name: check if swap file exists
stat:
path: "{{ swap_file }}"
register: swap_file_check
- name: create swap file
command: fallocate -l {{ swap_space }} {{ swap_file }}
args:
creates: /{{ swap_file }}
- name: set permissions on swap file
file:
path: "{{ swap_file }}"
mode: 0600
- name: format swap file
command: mkswap {{ swap_file }}
when: not swap_file_check.stat.exists
- name: add to fstab
lineinfile:
dest: /etc/fstab
regexp: "{{ swap_file }}"
line: "{{ swap_file }} none swap sw 0 0"
- name: turn on swap
command: swapon -a
- name: set swapiness
sysctl:
name: vm.swappiness
value: "1"
@@ -0,0 +1,20 @@
sidekiq-default:
image: tootsuite/mastodon:{{ MASTODON_VERSION }}
restart: always
env_file: .env.production
command: bundle exec sidekiq -q default -c 5
depends_on:
- pgbouncer
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
- ./config:/opt/mastodon/config
environment:
{% if DB_POOL is defined %}
- 'DB_POOL={{ DB_POOL }}'
{% endif %}
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
@@ -0,0 +1,19 @@
# sidekiq-ingress
sidekiq-ingress:
image: tootsuite/mastodon:{{ MASTODON_VERSION }}
restart: always
env_file: .env.production
command: bundle exec sidekiq -q ingress
depends_on:
- pgbouncer
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
- ./config:/opt/mastodon/config
environment:
- 'DB_POOL=25'
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
@@ -0,0 +1,20 @@
sidekiq-mailers:
image: tootsuite/mastodon:{{ MASTODON_VERSION }}
restart: always
env_file: .env.production
command: bundle exec sidekiq -q mailers -c 5
depends_on:
- pgbouncer
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
- ./config:/opt/mastodon/config
environment:
- 'DB_POOL=25'
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
@@ -0,0 +1,19 @@
sidekiq-pushpull:
image: tootsuite/mastodon:{{ MASTODON_VERSION }}
restart: always
env_file: .env.production
command: bundle exec sidekiq -q push -q pull -c 5
depends_on:
- pgbouncer
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
- ./config:/opt/mastodon/config
environment:
- 'DB_POOL=25'
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
@@ -0,0 +1,19 @@
sidekiq-scheduler:
image: tootsuite/mastodon:{{ MASTODON_VERSION }}
restart: always
env_file: .env.production
command: bundle exec sidekiq -q scheduler
depends_on:
- pgbouncer
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
- ./config:/opt/mastodon/config
environment:
- 'DB_POOL=25'
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
@@ -0,0 +1,15 @@
sidekiq:
image: tootsuite/mastodon:{{ MASTODON_VERSION }}
restart: always
env_file: .env.production
command: bundle exec sidekiq
depends_on:
- pgbouncer
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
- ./config:/opt/mastodon/config
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
@@ -0,0 +1,33 @@
version: '3'
services:
{% if ENV_PRODUCTION['STATSD_ADDR'] is defined %}
statsd:
restart: always
image: prom/statsd-exporter
command: --statsd.mapping-config=/tmp/statsd_mapping.yml
volumes:
- /root/statsd-mapping.yml:/tmp/statsd_mapping.yml
networks:
- internal_network
- external_network
ports:
- 9102:9102
- "127.0.0.1:9125:9125"
{% endif %}
pgbouncer:
restart: always
image: edoburu/pgbouncer
networks:
- internal_network
- external_network
environment:
- 'DB_HOST={{ REAL_DB_HOST }}'
- 'DB_NAME={{ ENV_PRODUCTION["DB_NAME"] }}'
- 'DB_USER={{ ENV_PRODUCTION["DB_USER"] }}'
- 'DB_PASSWORD={{ ENV_PRODUCTION["DB_PASS"] }}'
- 'SERVER_TLS_SSLMODE=prefer'
networks:
external_network:
internal_network:
internal: true
@@ -0,0 +1,3 @@
{% for key, val in ENV_PRODUCTION.items() %}
{{ key }}={{ val }}
{% endfor %}
@@ -0,0 +1,96 @@
## Prometheus Statsd Exporter mapping for Mastodon 4.0+
##
## Version 1.0, November 2022
##
## Documentation: https://ipng.ch/s/articles/2022/11/27/mastodon-3.html
mappings:
## Web collector
- match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.status\.(.+)
match_type: regex
name: "mastodon_controller_status"
labels:
controller: $1
action: $2
format: $3
status: $4
mastodon: "web"
- match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.db_time
match_type: regex
name: "mastodon_controller_db_time"
labels:
controller: $1
action: $2
format: $3
mastodon: "web"
- match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.view_time
match_type: regex
name: "mastodon_controller_view_time"
labels:
controller: $1
action: $2
format: $3
mastodon: "web"
- match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.total_duration
match_type: regex
name: "mastodon_controller_duration"
labels:
controller: $1
action: $2
format: $3
mastodon: "web"
## Database collector
- match: Mastodon\.production\.db\.tables\.(.+)\.queries\.(.+)\.duration
match_type: regex
name: "mastodon_db_operation"
labels:
table: "$1"
operation: "$2"
mastodon: "db"
## Cache collector
- match: Mastodon\.production\.cache\.(.+)\.duration
match_type: regex
name: "mastodon_cache_duration"
labels:
operation: "$1"
mastodon: "cache"
## Sidekiq collector
- match: Mastodon\.production\.sidekiq\.(.+)\.processing_time
match_type: regex
name: "mastodon_sidekiq_worker_processing_time"
labels:
worker: "$1"
mastodon: "sidekiq"
- match: Mastodon\.production\.sidekiq\.(.+)\.success
match_type: regex
name: "mastodon_sidekiq_worker_success_total"
labels:
worker: "$1"
mastodon: "sidekiq"
- match: Mastodon\.production\.sidekiq\.(.+)\.failure
match_type: regex
name: "mastodon_sidekiq_worker_failure_total"
labels:
worker: "$1"
mastodon: "sidekiq"
- match: Mastodon\.production\.sidekiq\.queues\.(.+)\.enqueued
match_type: regex
name: "mastodon_sidekiq_queue_enqueued"
labels:
queue: "$1"
mastodon: "sidekiq"
- match: Mastodon\.production\.sidekiq\.queues\.(.+)\.latency
match_type: regex
name: "mastodon_sidekiq_queue_latency"
labels:
queue: "$1"
mastodon: "sidekiq"
- match: Mastodon\.production\.sidekiq\.(.+)
match_type: regex
name: "mastodon_sidekiq_$1"
labels:
mastodon: "sidekiq"
+3
View File
@@ -0,0 +1,3 @@
---
dependencies:
- role: mastodon
+6
View File
@@ -0,0 +1,6 @@
---
- name: Configure docker-compose.override.yml
template:
src: docker-compose.override.yml.j2
dest: /home/mastodon/live/docker-compose.override.yml
notify: "docker-compose up"
@@ -0,0 +1,23 @@
services:
{% for SK in sidekiq %}
sidekiq-{{ SK['name'] }}:
image: tootsuite/mastodon:{{ MASTODON_VERSION }}
restart: always
env_file: .env.production
{% if 'q' in SK %}
command: bundle exec sidekiq {{ SK['q'] | join(' ') }} -c 10
{% else %}
command: bundle exec sidekiq
{% endif %}
depends_on:
- pgbouncer
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
- ./config:/opt/mastodon/config
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
{% endfor %}
+4
View File
@@ -0,0 +1,4 @@
---
dependencies:
- role: geerlingguy.nginx
- role: mastodon
+6
View File
@@ -0,0 +1,6 @@
---
- name: Configure docker-compose.yml
template:
src: docker-compose.override.yml.j2
dest: /home/mastodon/live/docker-compose.override.yml
notify: "docker-compose up"
@@ -0,0 +1,38 @@
version: '3'
services:
web:
image: tootsuite/mastodon:v4.0.2
restart: always
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
networks:
- external_network
- internal_network
healthcheck:
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1']
ports:
- 3000:3000
depends_on:
- pgbouncer
environment:
- 'MAX_THREADS=10'
- 'WEB_CONCURRENCY=3'
volumes:
- ./public/system:/mastodon/public/system
streaming:
image: tootsuite/mastodon:v4.0.2
restart: always
env_file: .env.production
command: node ./streaming
networks:
- external_network
- internal_network
healthcheck:
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1']
environment:
- 'DB_POOL=25'
ports:
- 4000:4000
depends_on:
- pgbouncer
+12
View File
@@ -0,0 +1,12 @@
---
dependencies:
- role: ansible-role-neovim
- role: geerlingguy.docker
- role: ansible-role-oh-my-zsh
vars:
users:
- username: root
oh_my_zsh:
theme: agnoster
plugins:
- git
+27
View File
@@ -0,0 +1,27 @@
---
- name: Install prometheus node exporter
package:
name: prometheus-node-exporter
state: present
- name: Create nvim config dir
file:
path: /root/.config/nvim
state: directory
- name: Install nvim config file
template:
src: templates/nvim/init.vim.j2
dest: /root/.config/nvim/init.vim
- name: Install nvim plugins
command: nvim --headless +PluginInstall +qall
args:
creates: /root/.vim/bundle/
- name: Clone fzf
git:
repo: https://github.com/junegunn/fzf
dest: /root/fzf
clone: yes
update: yes
+20
View File
@@ -0,0 +1,20 @@
---
- name: Configure yttrx sidekiq environment
hosts: [sidekiq]
roles:
- role: sidekiq
vars:
sidekiq:
- name: ingress
q: [ '-q', 'ingress', '-q', 'push', ]
- name:
q: [ '-q', 'pull', '-q', 'default' ]
handlers:
- name: Re-up docker containers
command: docker-compose up -d --remove-orphans
args:
chdir: /home/mastodon/live
listen: "docker-compose up"
+408
View File
@@ -0,0 +1,408 @@
" Setup runtime path
let s:editor_root=expand("~/.vim")
let &rtp = &rtp . ',' . s:editor_root . '/bundle/Vundle.vim'
" Install Vundle if not present
let vundle_installed=1
let vundle_readme=s:editor_root . '/bundle/Vundle.vim/README.md'
let vundle_repo = 'https://github.com/VundleVim/Vundle.vim'
if !filereadable(vundle_readme)
echo "Installing Vundle.."
echo ""
silent call mkdir(s:editor_root . '/bundle', "p")
silent execute "!git clone " . vundle_repo . " " . s:editor_root . "/bundle/Vundle.vim"
let vundle_installed=0
endif
call vundle#rc(s:editor_root . '/bundle')
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'airblade/vim-gitgutter'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'jeffkreeftmeijer/vim-numbertoggle'
Plugin 'majutsushi/tagbar'
Plugin 'blueyed/vim-diminactive'
Plugin 'tell-k/vim-autopep8'
Plugin 'mhinz/vim-signify'
" Syntax plugins
"Plugin 'tmhedberg/SimpylFold'
Plugin 'trapd00r/irc.vim'
Plugin 'PotatoesMaster/i3-vim-syntax'
Plugin 'ClockworkNet/vim-junos-syntax'
Plugin 'nathanalderson/yang.vim'
Plugin 'mitsuhiko/vim-jinja'
Plugin 'sheerun/vim-polyglot'
Plugin 'ekalinin/Dockerfile.vim'
"Plugin 'fatih/vim-go'
Plugin 'rust-lang/rust.vim'
Plugin 'hhvm/vim-hack'
" Color schemes
Plugin 'chriskempson/base16-vim'
Plugin 'tomasr/molokai'
Plugin 'joshdick/onedark.vim'
Plugin 'arakashic/nvim-colors-solarized'
Plugin 'drewtempelmeyer/palenight.vim'
Plugin 'skbolton/embark'
Plugin 'guns/xterm-color-table.vim'
" Airline
" Plugin 'joshdick/airline-onedark.vim'
Plugin 'vim-airline/vim-airline'
Plugin 'bling/vim-bufferline'
" Utility plugins
Plugin 'benmills/vimux'
"Plugin 'neomake/neomake'
" Plugin 'coxley/codepad'
Plugin 'keith/gist.vim'
Plugin 'nvie/vim-flake8'
" Plugin 'ntpeters/vim-better-whitespace'
Plugin 'suan/vim-instant-markdown'
Plugin 'dhruvasagar/vim-table-mode'
Plugin 'powerline/powerline'
" Plugin 'kana/vim-fakeclip'
Plugin 'petermblair/vim-arcanist'
Plugin 'phleet/vim-mercenary'
Plugin 'hynek/vim-python-pep8-indent'
Plugin 'tpope/vim-abolish'
Plugin 'junegunn/fzf.vim'
Plugin 'christoomey/vim-tmux-navigator'
Plugin 'flazz/vim-colorschemes'
Plugin 'jbgutierrez/vim-better-comments'
" Ranger integration
"Plugin 'francoiscabrol/ranger.vim'
"Plugin 'w0rp/ale'
" Powerhouse plugins
Plugin 'Rykka/riv.vim'
" Plugin 'Rykka/InstantRst'
" Plugin 'sjl/gundo.vim'
" Plugin 'tomtom/tcomment_vim'
Plugin 'scrooloose/nerdtree'
Plugin 'godlygeek/tabular'
Plugin 'Shougo/deoplete.nvim'
Plugin 'zchee/deoplete-clang'
" Vim go completion
Plugin 'nsf/gocode', {'rtp': 'vim/'}
"Plugin 'davidhalter/jedi-vim'
"Plugin 'deoplete-plugins/deoplete-jedi'
" Plugin 'SirVer/ultisnips'
" Plugin 'honza/vim-snippets'
Plugin 'ervandew/supertab'
" Plugin 'Yggdroot/indentLine'
" Plugin 'terryma/vim-expand-region'
" Distraction free
" Plugin 'junegunn/goyo.vim'
" Plugin 'junegunn/limelight.vim'
" C++
Plugin 'vim-scripts/a.vim'
" Web Development
" Plugin 'mattn/emmet-vim'
Plugin 'chrisbra/Colorizer'
Plugin 'jelera/vim-javascript-syntax'
call vundle#end()
let g:python3_host_prog = '/usr/bin/python3'
"let g:onedark_termcolors=256
let g:deoplete#enable_at_startup = 1
"let g:deoplete#sources = ['buffer', 'tag']
let g:deoplete#sources#clang#libclang_path = '/usr/lib/libclang.so'
let g:deoplete#sources#clang#clang_header = '/usr/lib/clang'
autocmd FileType python nnoremap <leader>y :0,$!yapf<Cr>
autocmd CompleteDone * pclose " To close preview window of deoplete
syntax enable
set background=dark
set termguicolors
if !exists('g:colors_name') || g:colors_name != 'base16-flat'
colorscheme base16-flat
endif
" Italics for my favorite color scheme
let g:palenight_terminal_italics=1
" " be kind to the 80 character limit
" " Create a giant wall of highlight past 80 characters
"let &colorcolumn=join(range(81,999),",")
highlight colorcolumn ctermbg=235 guibg=#2c2d27
" Toggle search hilighting with f3
nnoremap <F3> :set hlsearch!<CR>
" Don't hilight searches
set nohlsearch
" Remap the leader key
" let mapleader = "\<Space>"
"let mapleader = "\\"
" remap ; to : so that ;w works instead of :w
nnoremap ; :
" remap <ESC> key as jj
"inoremap jj <ESC>
" Same for jj
inoremap jk <ESC>
inoremap kj <ESC>
" quickly clear highlights
map <leader>n :noh<CR>
" quickly close quickfix
map <leader>C :ccl<CR><CR>
" quickly open a new tab
map <leader>T :tabnew<CR>
" no more pesky escape (for insert and visual mode)
imap kj <Esc>
imap kJ <Esc>
imap Kj <Esc>
imap KJ <Esc>
" vv to generate a new vertical split
nnoremap <silent> vv <C-w>v
" Navigate buffers
" Tab navigation like Firefox.
nnoremap <leader><tab> :bnext<CR>
" Find all occurances under cursor within file
nnoremap ff g#<CR>
" map leader rv to resize window to 80 columns
nnoremap <leader>rr :vertical resize 86<CR>
" Manage tabs with jk
nnoremap <leader>j :tabp<CR>
nnoremap <leader>k :tabn<CR>
" Buffer navigation like Firefox.
nnoremap <C-S-tab> :bprev<CR>
nnoremap <C-tab> :bnext<CR>
" manage the buffers
nnoremap <leader>[ :bprev<CR>
nnoremap <leader>] :bnext<CR>:w
"set list
set hidden
set ai
set magic
set mouse=a
set number
set ignorecase
set smartcase
set hlsearch
set incsearch
set pastetoggle=<F2>
set cursorline " hilight the current line
set splitright
"set splitbelow
set tags=~/mytags
:au FocusLost * :set number
:au FocusGained * :set relativenumber
" Make splits nicer
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>
" Show just the filename
let g:airline#extensions#tabline#fnamemod = ':t'
" used patched fonts for airline arrows/triangles
let g:airline_powerline_fonts=1
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#show_buffers = 0
let g:airline#extensions#tabline#show_close_button = 0
" Ensure that for Makefiles we don't replace TABs with spaces
let _curfile = expand("%:t")
if _curfile =~ "Makefile" || _curfile =~ "makefile" || _curfile =~ ".*\mk"
set noexpandtab
else
" Don't use tabs, use spaces
set expandtab
" make tab insert indents instead of tabs at begining of line
set smarttab
endif
" Tell vim to treat certain files with python syntax
au BufRead,BufNewFile *.cconf set filetype=python
au BufRead,BufNewFile *.cinc set filetype=python
au BufRead,BufNewFile *.thrift set filetype=thrift
au BufRead,BufNewFile TARGETS set filetype=python
au! Syntax thrift source $LOCAL_ADMIN_SCRIPTS/vim/syntax/thrift.vim
" NERDTree - map Ctrl+n to toggle the tree on/off
nnoremap <F2> :NERDTreeToggle<CR>
nnoremap <F8> :autopep8<CR>
nnoremap <F5> :TagbarToggle<CR>
" Configures ripgrep with fzf
command! -bang -nargs=* FzfRg call fzf#vim#grep("rg --column --line-number --no-heading --color=always --smart-case ".shellescape(<q-args>), 1, {'options': '--delimiter : --nth 4..'}, <bang>0)
command! -bang -nargs=* Rgg call fzf#vim#grep("rg --no-ignore --column --line-number --no-heading --color=always --smart-case ".shellescape(<q-args>), 1, {'options': '--delimiter : --nth 4..'}, <bang>0)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" https://github.com/christoomey/vim-tmux-navigator
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
source ~/.vim/bundle/vim-tmux-navigator/plugin/tmux_navigator.vim
let g:tmux_navigator_no_mappings = 1
nnoremap <silent> {Left-mapping} :TmuxNavigateLeft<cr>
nnoremap <silent> {Down-Mapping} :TmuxNavigateDown<cr>
nnoremap <silent> {Up-Mapping} :TmuxNavigateUp<cr>
nnoremap <silent> {Right-Mapping} :TmuxNavigateRight<cr>
nnoremap <silent> {Previous-Mapping} :TmuxNavigatePrevious<cr>
"#############################################################################
" Mappings
"#############################################################################
" Next buffer
nnoremap <silent> <tab> :bnext<CR>
" Previous buffer
nnoremap <silent> <s-tab> :bprevious<CR>
" Create vsplit
nnoremap <silent> <Leader>\| :vsp<CR>
" Creat hsplit
nnoremap <silent> <Leader>- :sp<CR>
" Save file
nnoremap <silent> <Leader>w :w<CR>
" Open startify with leader l
nnoremap <silent> <Leader>l :Startify<CR>
" Open fuzzy files with leader \
nnoremap <silent> <Leader>\ :Files<CR>
" Open fuzzy lines with leader o
nnoremap <silent> <Leader>o :Lines<CR>
" Open fuzzy buffers with leader b
nnoremap <silent> <Leader>b :Buffers<CR>
" Open grep
nnoremap <silent> <Leader>g :FzfRg<CR>
" Open grep for cursor word
nnoremap <silent> <Leader>c :FzfRg <C-R><C-W><CR>
" Close the current buffer
nnoremap <silent> <Leader>x :bd<CR>
" Close all buffers
nnoremap <silent> <Leader>z :%bd<CR>
" Alternate file navigation
nnoremap <silent> <Leader>a :A<CR>
" Alternate file navigation vertical split
nnoremap <silent> <Leader>v :AV<CR>
" Cycle line number modes
nnoremap <silent> <Leader>r :call CycleNumbering()<CR>
" Open project
nnoremap <silent> <Leader>m :call ToggleProject()<CR>
" Open scratch term
nnoremap <silent> <Leader>s :call ToggleScratchTerm()<CR>
" Open lazygit
nnoremap <silent> <Leader>' :call ToggleLazyGit()<CR>
" Open vifm
nnoremap <silent> <Leader>/ :Vifm<CR>
" Get outline
nnoremap <silent> <Leader>co :<C-u>CocList outline<CR>
" Get symbols
nnoremap <silent> <Leader>cs :<C-u>CocList -I symbols<CR>
" Get errors
nnoremap <silent> <Leader>cl :<C-u>CocList locationlist<CR>
" Get available commands
nnoremap <silent> <Leader>cc :<C-u>CocList commands<CR>
" Restart server
nnoremap <silent> <Leader>cR :<C-u>CocRestart<CR>
" Quit term buffer with ESC
tnoremap <silent> <Esc> <C-\><C-n><CR>
" Go to definition
nnoremap <silent> gd <Plug>(coc-definition)
" Go to type definition
nnoremap <silent> gy <Plug>(coc-type-definition)
" Go to implementation
nnoremap <silent> gi <Plug>(coc-implementation)
" Find references
nnoremap <silent> gr <Plug>(coc-references)
" Get hint
nnoremap <silent> gh :call CocActionAsync('doHover')<CR>
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" vim-autopep8
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"let g:autopep8_disable_show_diff=1
nnoremap <F8> :autopep8<CR>
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" airline
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:airline_powerline_fonts = 1
let g:airline_theme = 'tomorrow'
" There needs to be a "fbgrep" command present in the home directory for this
" to work properly. If it doesn't exist, then we can back it up to using
" ack, or silver surfer.
set grepprg=rg
if filereadable(expand("~/bin/fbgrep"))
set grepprg=~/bin/fbgrep
endif
" bind K to grep word under cursor
nnoremap K :grep! "<C-R><C-W>"<CR>:cw<CR>
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Custom Functions
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Creates a floating window with a most recent buffer to be used
function! CreateCenteredFloatingWindow()
let width = float2nr(&columns * 0.6)
let height = float2nr(&lines * 0.6)
let top = ((&lines - height) / 2) - 1
let left = (&columns - width) / 2
let opts = {'relative': 'editor', 'row': top, 'col': left, 'width': width, 'height': height, 'style': 'minimal'}
let top = "╭" . repeat("─", width - 2) . "╮"
let mid = "│" . repeat(" ", width - 2) . "│"
let bot = "╰" . repeat("─", width - 2) . "╯"
let lines = [top] + repeat([mid], height - 2) + [bot]
let s:buf = nvim_create_buf(v:false, v:true)
call nvim_buf_set_lines(s:buf, 0, -1, v:true, lines)
call nvim_open_win(s:buf, v:true, opts)
set winhl=Normal:Floating
let opts.row += 1
let opts.height -= 2
let opts.col += 2
let opts.width -= 4
call nvim_open_win(nvim_create_buf(v:false, v:true), v:true, opts)
autocmd BufWipeout <buffer> exe 'bwipeout '.s:buf
tnoremap <buffer> <silent> <Esc> <C-\><C-n><CR>:bw!<CR>
endfunction
" Cycle through relativenumber + number, number (only), and no numbering.
function! CycleNumbering() abort
if exists('+relativenumber')
execute {
\ '00': 'set relativenumber | set number',
\ '01': 'set norelativenumber | set number',
\ '10': 'set norelativenumber | set nonumber',
\ '11': 'set norelativenumber | set number' }[&number . &relativenumber]
else
" No relative numbering, just toggle numbers on and off.
set number!<CR>
endif
endfunction
+12
View File
@@ -0,0 +1,12 @@
---
- name: Configure yttrx webapp environment
hosts: [webapp]
roles:
- role: webapp
handlers:
- name: Re-up docker containers
command: docker-compose up -d
args:
chdir: /home/mastodon/live
listen: "docker-compose up"
+6
View File
@@ -0,0 +1,6 @@
---
- name: Configure yttrx server environment
hosts: [yttrx]
roles:
- role: yttrx