# Class to install a Mastodon instance # # [*ensure*] # String defining if is present or absent # # [*hostname*] # String with the full qualified hostname of the instance. There must be a DNS record for it. # # [*smtp_server*] # String with the SMTP server to use. # # [*mastodon_home*] # String path to Mastodon user home directory. Default /opt/mastodon # # [*db_password*] # String with Database password. # # [*mastodon_version*] # String with Mastodon version (code tag) to install. Default: v4.2.1 # # [*mastodon_user*] # String with the system user name for mastodon. Default: mastodon # # [*mastodon_group*] # String with the system group name for mastodon. Default: mastodon # # [*ruby_version*] # String with the ruby version to use. Default: 3.2.2 # # [*mastodon_config*] # Hash with the configuration to store in .env.production # class mastodon ( String $ensure = 'present', String $hostname = 'mastodon.example.org', String $mastodon_home = '/opt/mastodon', String $db_host = '/var/run/postgresql', String $db_name = 'mastodon', String $db_user = 'mastodon', String $db_password = 'S3cr3TP4ssw0rd', Integer $db_port = 5432, String $mastodon_version = 'v4.2.1', String $ruby_version = '3.2.2', String $mastodon_user = 'mastodon', String $mastodon_group = 'mastodon', String $secret_key_base = 'S3cr3tK3i', String $otp_secret = '0tpS3cr3t', String $vapid_private_key = 'S3cr3tK3i', String $vapid_public_key = 'S3cr3tK3i', Hash $mastodon_config = { 'LOCAL_DOMAIN' => 'example.com', 'REDIS_HOST' => '127.0.0.1', 'REDIS_PORT' => 6379, 'ES_ENABLED' => 'false', 'ES_HOST' => 'localhost', 'ES_PORT' => 9200, 'ES_USER' => 'elastic', 'ES_PASS' => 'password', 'SMTP_SERVER' => '', 'SMTP_PORT' => 587, 'SMTP_LOGIN' => '', 'SMTP_PASSWORD' => '', 'SMTP_FROM_ADDRESS' => 'notifications@example.com', 'S3_ENABLED' => 'false', 'S3_BUCKET' => 'files.example.com', 'AWS_ACCESS_KEY_ID' => '', 'AWS_SECRET_ACCESS_KEY' => '', 'S3_ALIAS_HOST' => 'files.example.com', 'IP_RETENTION_PERIOD' => 31556952, 'SESSION_RETENTION_PERIOD' => 31556952, }, ) { case $ensure { default: { $package_ensure = 'installed' $directory_ensure = 'directory' $link_ensure = 'link' $service_ensure = 'running' $file_ensure = 'present' } /^(absent|delete|uninstall|remove|unregister)$/: { $package_ensure = 'absent' $directory_ensure = 'absent' $link_ensure = 'absent' $file_ensure = 'absent' $service_ensure = 'stopped' $cron_ensure = 'absent' } } $packages = [ 'apt-transport-https', 'autoconf', 'bison', 'build-essential', 'ca-certificates', 'certbot', 'ffmpeg', 'file', 'g++', 'gcc', 'git-core', 'gnupg', 'imagemagick', 'libffi-dev', 'libgdbm-dev', 'libicu-dev', 'libidn11-dev', 'libjemalloc-dev', 'libncurses5-dev', 'libpq-dev', 'libprotobuf-dev', 'libreadline6-dev', 'libssl-dev', 'libxml2-dev', 'libxslt1-dev', 'libyaml-dev', 'lsb-release', 'nginx', # 'nodejs', 'pkg-config', # 'postgresql-contrib', # 'postgresql', 'protobuf-compiler', 'python3-certbot-nginx', # 'redis-server', # 'redis-tools', 'wget', 'zlib1g-dev', ] $packages.each | $package | { if (!defined(Package[$package])) { package { $package: ensure => $package_ensure, } } } class { 'nodejs': repo_url_suffix => '16.x', } class { 'postgresql::server': } include redis exec { 'enable_corepack': command => '/usr/bin/corepack enable', creates => '/usr/bin/yarn', require => Class['nodejs'], } exec { 'yarn_classic': command => '/usr/bin/yarn set version classic', creates => '/root/.yarnrc', require => Exec['enable_corepack'], } group { $mastodon_group: } user { $mastodon_user: gid => $mastodon_group, home => $mastodon_home, managehome => true, system => true, require => Group[$mastodon_group], } vcsrepo { 'rbenv': path => "${mastodon_home}/.rbenv", source => 'https://github.com/rbenv/rbenv.git', provider => 'git', owner => $mastodon_user, group => $mastodon_group, require => User[$mastodon_user], } exec { 'configure_rbenv': command => "${mastodon_home}/.rbenv/src/configure", user => $mastodon_user, cwd => "${mastodon_home}/.rbenv/", creates => "${mastodon_home}/.rbenv/src/Makefile", require => Vcsrepo['rbenv'], } exec { 'make_rbenv': command => '/usr/bin/make -C src', user => $mastodon_user, cwd => "${mastodon_home}/.rbenv/", creates => "${mastodon_home}/.rbenv/libexec/rbenv-realpath.dylib", require => Exec['configure_rbenv'], } file_line { 'mastodon_path': path => "${mastodon_home}/.bashrc", line => 'export PATH="$HOME/.rbenv/bin:$PATH"', match => '^export PATH="$HOME/.rbenv', require => Vcsrepo['rbenv'], } file_line { 'mastodon_rbenv_init': path => "${mastodon_home}/.bashrc", line => 'eval "$(rbenv init -)"', match => '^eval "$(rbenv init -)"', require => Vcsrepo['rbenv'], } vcsrepo { 'ruby_build': path => "${mastodon_home}/.rbenv/plugins/ruby-build", source => 'https://github.com/rbenv/ruby-build.git', provider => 'git', owner => $mastodon_user, group => $mastodon_group, require => Vcsrepo['rbenv'], } postgresql::server::db { $db_name: user => $db_user, password => postgresql::postgresql_password($db_user, $db_password), } vcsrepo { 'mastodon_code': path => "${mastodon_home}/live", source => 'https://github.com/mastodon/mastodon.git', revision => $mastodon_version, provider => 'git', owner => $mastodon_user, group => $mastodon_group, require => User[$mastodon_user], } file { '/usr/local/bin/install_mastodon.sh': ensure => $ensure, content => template('mastodon/install_mastodon.sh.erb'), mode => '0750', owner => $mastodon_user, group => 'root', require => [ Vcsrepo['mastodon_code'], Postgresql::Server::Db[$db_name], Vcsrepo['ruby_build'], ], } exec { 'install_mastodon': command => '/usr/local/bin/install_mastodon.sh', user => $mastodon_user, group => $mastodon_group, environment => [ "HOME=${mastodon_home}", 'LANG=C.UTF-8', "USER=${mastodon_user}", ], creates => "${mastodon_home}/./.mastodon_install", path => "${mastodon_home}/.rbenv/shims:${mastodon_home}/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", timeout => 0, require => File['/usr/local/bin/install_mastodon.sh'], } $built_config = { 'LOCAL_DOMAIN' => $hostname, 'DB_PASS' => $db_password, 'DB_USER' => $db_user, 'DB_NAME' => $db_name, 'DB_PORT' => $db_port, 'DB_HOST' => $db_host, 'SECRET_KEY_BASE' => $secret_key_base, 'OTP_SECRET' => $otp_secret, } $real_config = $mastodon_config + $built_config file { "${mastodon_home}/live/.env.production": ensure => $ensure, content => template('mastodon/env.production.erb'), mode => '0640', owner => $mastodon_user, group => $mastodon_group, require => [ Vcsrepo['mastodon_code'], ], } # RAILS_ENV=production rails db:setup exec { 'db_setup': command => "${mastodon_home}/live/bin/rails db:setup > ${mastodon_home}/db_setup_done", creates => "${mastodon_home}/db_setup_done", path => "${mastodon_home}/.rbenv/shims:${mastodon_home}/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", environment => [ 'RAILS_ENV=production', ], user => $mastodon_user, group => $mastodon_group, cwd => "${mastodon_home}/live", timeout => 0, require => File["${mastodon_home}/live/.env.production"], } # db:create # RAILS_ENV=production rails assets:precompile # Apache::vhost }