Initial commit

master
Kuba Orlik 5 hours ago
commit d91f174b31

@ -0,0 +1,53 @@
# Usage:
See defaults/main.yml for description of config parameters
```yaml
- name: "Install mastodon"
hosts: czynna1
vars:
mastodon_docker_web_port: 3008
mastodon_docker_streaming_port: 3009
mastodon_docker_main_storage: "/mnt/juice/mastodon-docker"
roles:
- role: mastodon-docker
tags:
- mastodon-toot
vars:
mastodon_docker_domain: "toot.eu"
mastodon_docker_user: "mastodon-toot"
mastodon_docker_max_post_length: 500
mastodon_docker_home: "/var/www/mastodon-toot"
mastodon_docker_postgres_storage: "{{ mastodon_docker_main_storage }}/postgres"
mastodon_docker_redis_storage: "{{ mastodon_docker_main_storage }}/redis"
mastodon_docker_elasticsearch_storage: "{{ mastodon_docker_main_storage }}/elasticsearch"
mastodon_docker_system_storage: "{{ mastodon_docker_main_storage }}/system"
mastodon_docker_backup_storage: "{{ mastodon_docker_main_storage }}/backups"
mastodon_docker_cache_storage: "{{ mastodon_docker_main_storage }}/cache"
mastodon_docker_enable_elasticsearch: false
mastodon_docker_elasticsearch_port: 9200
mastodon_docker_mastodon_secret: <secret>
mastodon_docker_vapid_public: <secret>
mastodon_docker_vapid_private: <secret>
mastodon_docker_ar_encryption_deterministic_key: <secret>
mastodon_docker_ar_encryption_derivation_salt: <secret>
mastodon_docker_ar_encryption_primary_key: <secret>
mastodon_docker_smtp:
server: example.com
port: 587
login: login
password: <secret>
from: mastodon@example.com
- role: sealcode.nginx.proxies
tags:
- mastodon-toot
vars:
- domain: "toot.eu"
site_name: "mastodon-toot"
upstream: "http://127.0.0.1:{{mastodon_docker_web_port}}"
websocket_endpoints:
- url: "/api/v1/streaming"
upstream: "http://127.0.0.1:{{ mastodon_docker_streaming_port }}"
```

@ -0,0 +1,26 @@
mastodon_docker_domain: "example.com"
mastodon_docker_user: "mastodon-docker"
mastodon_docker_max_post_length: 500
mastodon_docker_home: "/var/www/mastodon-docker"
mastodon_docker_postgres_storage: "/mnt/juice/mastodon-docker/postgres"
mastodon_docker_redis_storage: "/mnt/juice/mastodon-docker/redis"
mastodon_docker_elasticsearch_storage: "/mnt/juice/mastodon-docker/elasticsearch"
mastodon_docker_system_storage: "/mnt/juice/mastodon-docker/system"
mastodon_docker_backup_storage: "/mnt/juice/mastodon-docker/backup"
mastodon_docker_cache_storage: "/mnt/juice/mastodon-docker/cache"
mastodon_docker_enable_elasticsearch: false
mastodon_docker_mastodon_secret: undefined # can be generated with a password manager
mastodon_docker_vapid_public: undefined # generate with npx web-push generate-vapid-keys
mastodon_docker_vapid_private: undefined # generate with npx web-push generate-vapid-keys
mastodon_docker_ar_encryption_deterministic_key: undefined # generate with openssl rand -hex 32
mastodon_docker_ar_encryption_derivation_salt: undefined # generate with openssl rand -hex 32
mastodon_docker_ar_encryption_primary_key: undefined # generate with openssl rand -hex 32
mastodon_docker_smtp:
server: example.com
port: 587
login: login
password: somesecret
from: mastodon@example.com
mastodon_docker_web_port: 3008
mastodon_docker_streaming_port: 3009
mastodon_docker_media_cleanup_days: 3

@ -0,0 +1,17 @@
---
galaxy_info:
author: kuba
description: upgrade and reboot
license: MIT
min_ansible_version: "2.12"
platforms:
- name: Debian
versions:
- bullseye
- bookworm
- name: Ubuntu
versions:
- focal
- jammy
dependencies: []

@ -0,0 +1,108 @@
- name: create Mastodon Docker user
ansible.builtin.user:
name: "{{ mastodon_docker_user }}"
shell: /bin/bash
home: "{{ mastodon_docker_home }}"
create_home: true
state: present
- name: Create directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0777"
loop:
- "{{ mastodon_docker_postgres_storage }}"
- "{{ mastodon_docker_redis_storage }}"
- "{{ mastodon_docker_elasticsearch_storage }}"
- "{{ mastodon_docker_system_storage }}"
- "{{ mastodon_docker_backup_storage }}"
- "{{ mastodon_docker_cache_storage }}"
- name: Make sure data directories are backed up
lineinfile:
path: "/backup-dirs"
line: "{{ item }}"
loop:
- "{{ mastodon_docker_postgres_storage }}"
- "{{ mastodon_docker_redis_storage }}"
- "{{ mastodon_docker_elasticsearch_storage }}"
- "{{ mastodon_docker_system_storage }}"
- "{{ mastodon_docker_backup_storage }}"
# cache storage intentionally omitted
- name: Copy the docker compose file to server
template:
src: "docker-compose.yml.j2"
dest: "{{ mastodon_docker_home }}/docker-compose.yml"
register: compose_file
- name: Copy the Dockerfile to server
template:
src: "Dockerfile"
dest: "{{ mastodon_docker_home }}/Dockerfile"
register: compose_file
- name: Copy the env file to server
template:
src: "env.production.j2"
dest: "{{ mastodon_docker_home }}/env"
register: env_file
- name: Copy the tootctl file to server
template:
src: "tootctl"
dest: "{{ mastodon_docker_home }}/tootctl"
mode: "0770"
- name: Copy the bundle file to server
template:
src: "bundle"
dest: "{{ mastodon_docker_home }}/bundle"
mode: "0770"
- name: "Stop mastodon_docker services"
community.docker.docker_compose_v2:
state: "absent"
project_src: "{{ mastodon_docker_home }}"
when: compose_file.changed or env_file.changed
- name: run the setup command
command:
cmd: "bash -c 'docker compose run --rm web bundle exec rails db:setup && touch db_setup.mark'"
chdir: "{{ mastodon_docker_home }}"
creates: "db_setup.mark"
- name: "docker compose up -d"
community.docker.docker_compose_v2:
state: "present"
build: "always"
pull: missing
project_src: "{{ mastodon_docker_home }}"
- name: Add Mastodon Postgres backup cron
cron:
name: "Mastodon Postgres backup: {{ mastodon_docker_domain }}"
user: root
minute: "0"
hour: "3"
job: >
/bin/sh -c '/usr/bin/docker compose --project-directory {{mastodon_docker_home}} exec -T db pg_dump -U mastodon mastodon_production > {{mastodon_docker_backup_storage}}/mastodon_backup.sql'
- name: Add Mastodon media attachments cache cleanup
cron:
name: "Mastodon media attachments cleanup backup: {{ mastodon_docker_domain }}"
user: root
minute: "0"
hour: "1"
job: >
/bin/sh -c '/usr/bin/docker compose --project-directory {{mastodon_docker_home}} exec web bin/tootctl media remove --days {{ mastodon_docker_media_cleanup_days }}'
- name: Add Mastodon media headers cache cleanup
cron:
name: "Mastodon media headers cleanup backup: {{ mastodon_docker_domain }}"
user: root
minute: "30"
hour: "1"
job: >
/bin/sh -c '/usr/bin/docker compose --project-directory {{mastodon_docker_home}} exec web bin/tootctl media remove --days {{ mastodon_docker_media_cleanup_days }} --remove-headers'

@ -0,0 +1,8 @@
FROM ghcr.io/mastodon/mastodon:v4.5.9
USER root
RUN sed -i "s/MAX_CHARS = 500/MAX_CHARS = ENV.fetch('MAX_TOOT_CHARS', 500).to_i/" \
app/validators/status_length_validator.rb
USER mastodon

@ -0,0 +1,2 @@
#!/bin/bash
docker compose run --rm web bundle "$@"

@ -0,0 +1,124 @@
# From https://github.com/mastodon/mastodon/blob/main/docker-compose.yml
services:
db:
restart: always
image: postgres:14-alpine
shm_size: 256mb
networks:
- internal_network
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
volumes:
- "{{ mastodon_docker_postgres_storage }}:/var/lib/postgresql/data"
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
- "POSTGRES_USER=mastodon"
- "POSTGRES_DB=mastodon_production"
redis:
restart: always
image: redis:7-alpine
networks:
- internal_network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
volumes:
- "{{ mastodon_docker_redis_storage }}:/data"
{% if mastodon_docker_enable_elasticsearch %}
es:
restart: always
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.29
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true"
- "xpack.license.self_generated.type=basic"
- "xpack.security.enabled=false"
- "xpack.watcher.enabled=false"
- "xpack.graph.enabled=false"
- "xpack.ml.enabled=false"
- "bootstrap.memory_lock=true"
- "cluster.name=es-mastodon"
- "discovery.type=single-node"
- "thread_pool.write.queue_size=1000"
networks:
- external_network
- internal_network
healthcheck:
test:
[
"CMD-SHELL",
"curl --silent --fail localhost:9200/_cluster/health || exit 1",
]
volumes:
- "{{mastodon_docker_elasticsearch_storage}}:/usr/share/elasticsearch/data"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
{% endif %}
web:
build: .
restart: always
env_file: env
command: bundle exec puma -C config/puma.rb
networks:
- external_network
- internal_network
healthcheck:
# prettier-ignore
test: ['CMD-SHELL',"curl -s --noproxy localhost localhost:3000/health | grep -q 'OK' || exit 1"]
ports:
- "127.0.0.1:{{ mastodon_docker_web_port }}:3000"
depends_on:
- db
- redis
{% if mastodon_docker_enable_elasticsearch %}
- es
{% endif %}
volumes:
- "{{ mastodon_docker_system_storage }}:/mastodon/public/system"
- "{{ mastodon_docker_cache_storage }}:/opt/mastodon/public/system/cache"
streaming:
image: ghcr.io/mastodon/mastodon-streaming:v4.5.9
restart: always
env_file: env
command: node ./streaming/index.js
networks:
- external_network
- internal_network
healthcheck:
# prettier-ignore
test: ['CMD-SHELL', "curl -s --noproxy localhost localhost:4000/api/v1/streaming/health | grep -q 'OK' || exit 1"]
ports:
- "127.0.0.1:{{ mastodon_docker_streaming_port }}:4000"
depends_on:
- db
- redis
sidekiq:
image: ghcr.io/mastodon/mastodon:v4.5.9
restart: always
env_file: env
command: bundle exec sidekiq
depends_on:
- db
- redis
networks:
- external_network
- internal_network
volumes:
- "{{ mastodon_docker_system_storage }}:/mastodon/public/system"
- "{{ mastodon_docker_cache_storage }}:/opt/mastodon/public/system/cache"
healthcheck:
test: ["CMD-SHELL", "ps aux | grep '[s]idekiq\ 8' || false"]
networks:
external_network:
internal_network:
internal: true

@ -0,0 +1,75 @@
MAX_TOOT_CHARS={{mastodon_docker_max_post_length}}
LOCAL_DOMAIN={{mastodon_docker_domain}}
# Redis
# -----
REDIS_HOST=redis
REDIS_PORT=6379
# PostgreSQL
# ----------
DB_HOST=db
DB_USER=mastodon
DB_NAME=mastodon_production
DB_PASS=
DB_PORT=5432
# Elasticsearch (optional)
# ------------------------
ES_ENABLED={{mastodon_docker_enable_elasticsearch}}
ES_HOST=es
ES_PORT=9200
# Authentication for ES (optional)
ES_USER=elastic
ES_PASS=password
# Secrets
# -------
# Make sure to use `bundle exec rails secret` to generate secrets
# -------
SECRET_KEY_BASE={{ mastodon_docker_mastodon_secret }}
# Encryption secrets
# ------------------
# Must be available (and set to same values) for all server processes
# These are private/secret values, do not share outside hosting environment
# Use `bin/rails db:encryption:init` to generate fresh secrets
# Do NOT change these secrets once in use, as this would cause data loss and other issues
# ------------------
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY={{mastodon_docker_ar_encryption_deterministic_key}}
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT={{mastodon_docker_ar_encryption_derivation_salt}}
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY={{mastodon_docker_ar_encryption_primary_key}}
# Web Push
# --------
# Generate with `bundle exec rails mastodon:webpush:generate_vapid_key`
# --------
VAPID_PRIVATE_KEY={{mastodon_docker_vapid_public}}
VAPID_PUBLIC_KEY={{mastodon_docker_vapid_private}}
# Sending mail
# ------------
SMTP_SERVER={{mastodon_docker_smtp.server}}
SMTP_PORT=587{{mastodon_docker_smtp.port}}
SMTP_LOGIN={{mastodon_docker_smtp.login}}
SMTP_PASSWORD={{mastodon_docker_smtp.password}}
SMTP_FROM_ADDRESS={{mastodon_docker_smtp.from}}
# File storage (optional)
# -----------------------
S3_ENABLED=false
S3_BUCKET=files.example.com
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
S3_ALIAS_HOST=files.example.com
# Optional list of hosts that are allowed to serve media for your instance
# EXTRA_MEDIA_HOSTS=https://data.example1.com,https://data.example2.com
# IP and session retention
# -----------------------
# Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml
# to be less than daily if you lower IP_RETENTION_PERIOD below two days (172800).
# -----------------------
IP_RETENTION_PERIOD=31556952
SESSION_RETENTION_PERIOD=31556952

@ -0,0 +1,2 @@
#!/bin/bash
docker compose run --rm web bin/tootctl "$@"
Loading…
Cancel
Save