New port, net-im/mastodon: GNU Social-compatible microblogging server

WWW: https://github.com/tootsuite/mastodon

Submitted by:	feld, jrm, mmokhi
Reviewed by:	bapt, feld, roberto, saper@saper.info, mat, swills
Approved by:	swills (mentor, implicit)
Differential Revision:	https://reviews.freebsd.org/D10298
This commit is contained in:
Joseph Mingrone 2017-05-26 21:22:38 +00:00
parent c095cd43d0
commit f16d108a49
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=441815
20 changed files with 5867 additions and 2 deletions

2
GIDs
View File

@ -185,7 +185,7 @@ aprsd:*:240:
tnc:*:241:
prosody:*:242:
# free: 243
# free: 244
mastodon:*:244:
# free: 245
# free: 246
fcron:*:247:

2
UIDs
View File

@ -190,7 +190,7 @@ aprsd:*:240:240::0:0:aprsd:/nonexistent:/bin/sh
tnc:*:241:241::0:0:aprsd:/nonexistent:/bin/sh
prosody:*:242:242::0:0:Prosody Jabber Server:/nonexistent:/usr/sbin/nologin
# free: 243
# free: 244
mastodon:*:244:244::0:0:Mastodon User:/usr/local/www/mastodon:/bin/sh
# free: 245
# free: 246
fcron:*:247:247::0:0:fcron pseudo-user:/nonexistent:/usr/sbin/nologin

112
net-im/mastodon/Makefile Normal file
View File

@ -0,0 +1,112 @@
# $FreeBSD$
PORTNAME= mastodon
DISTVERSIONPREFIX= v
DISTVERSION= 1.4rc4
CATEGORIES= net-im www
MAINTAINER= jrm@FreeBSD.org
COMMENT= GNU Social-compatible microblogging server
LICENSE= AGPLv3
LICENSE_FILE= ${WRKSRC}/LICENSE
RUN_DEPENDS= ffmpeg>0:multimedia/ffmpeg \
libpqtypes>1.5.0:databases/libpqtypes
# Dependencies below match Gemfile layout
RUN_DEPENDS+= rubygem-pkg-config>=1.2.0:devel/rubygem-pkg-config
RUN_DEPENDS+= rubygem-puma>0:www/rubygem-puma \
rubygem-rails50>0:www/rubygem-rails50 \
rubygem-uglifier>0:www/rubygem-uglifier
RUN_DEPENDS+= rubygem-hamlit-rails-rails50>0:www/rubygem-hamlit-rails-rails50 \
rubygem-pg>0:databases/rubygem-pg \
rubygem-pghero-rails50>0:databases/rubygem-pghero-rails50 \
rubygem-dotenv-rails-rails50>0:misc/rubygem-dotenv-rails-rails50 \
RUN_DEPENDS+= rubygem-aws-sdk>0:devel/rubygem-aws-sdk \
rubygem-paperclip-rails50>0:devel/rubygem-paperclip-rails50 \
rubygem-paperclip-av-transcoder-rails50>0:multimedia/rubygem-paperclip-av-transcoder-rails50
RUN_DEPENDS+= rubygem-addressable>0:www/rubygem-addressable \
rubygem-cld3>0:textproc/rubygem-cld3 \
rubygem-devise-rails50>0:devel/rubygem-devise-rails50 \
rubygem-devise-two-factor-rails50>0:security/rubygem-devise-two-factor-rails50 \
rubygem-doorkeeper-rails50>0:security/rubygem-doorkeeper-rails50 \
rubygem-fast_blank>0:devel/rubygem-fast_blank \
rubygem-goldfinger>0:www/rubygem-goldfinger \
rubygem-hiredis>0:databases/rubygem-hiredis \
rubygem-redis-namespace>0:databases/rubygem-redis-namespace \
rubygem-htmlentities>0:textproc/rubygem-htmlentities \
rubygem-http>0:www/rubygem-http \
rubygem-http_accept_language>0:devel/rubygem-http_accept_language \
rubygem-httplog>0:sysutils/rubygem-httplog \
rubygem-kaminari-rails50>0:www/rubygem-kaminari-rails50 \
rubygem-link_header>0:www/rubygem-link_header \
rubygem-nokogiri>0:textproc/rubygem-nokogiri \
rubygem-oj>0:devel/rubygem-oj \
rubygem-ostatus2>0:www/rubygem-ostatus2 \
rubygem-ox>0:textproc/rubygem-ox \
rubygem-rabl-rails50>0:devel/rubygem-rabl-rails50 \
rubygem-rack-attack>0:www/rubygem-rack-attack \
rubygem-rack-cors>0:www/rubygem-rack-cors \
rubygem-rack-timeout>0:www/rubygem-rack-timeout \
rubygem-rails-i18n-rails50>0:devel/rubygem-rails-i18n-rails50 \
rubygem-rails-settings-cached-rails50>0:www/rubygem-rails-settings-cached-rails50 \
rubygem-redis>0:databases/rubygem-redis \
rubygem-rqrcode>0:www/rubygem-rqrcode \
rubygem-ruby-oembed>0:www/rubygem-ruby-oembed \
textproc/rubygem-sanitize>0:textproc/rubygem-sanitize \
rubygem-sidekiq>0:devel/rubygem-sidekiq \
rubygem-sidekiq-scheduler>0:devel/rubygem-sidekiq-scheduler \
rubygem-sidekiq-unique-jobs>0:devel/rubygem-sidekiq-unique-jobs \
rubygem-simple-navigation-rails50>0:devel/rubygem-simple-navigation-rails50 \
rubygem-simple_form-rails50>0:devel/rubygem-simple_form-rails50 \
rubygem-sprockets-rails-rails50>0:devel/rubygem-sprockets-rails-rails50 \
rubygem-statsd-instrument>0:devel/rubygem-statsd-instrument \
rubygem-twitter-text>0:textproc/rubygem-twitter-text \
rubygem-tzinfo-data>0:devel/rubygem-tzinfo-data \
rubygem-webpacker-rails50>0:devel/rubygem-webpacker-rails50
RUN_DEPENDS+= rubygem-lograge-rails50>0:www/rubygem-lograge-rails50 \
rubygem-redis-rails-rails50>0:www/rubygem-redis-rails-rails50
USES= gnome pgsql shebangfix
USE_GITHUB= yes
GH_ACCOUNT= tootsuite
USE_GNOME= libxml2 libxslt
USE_RC_SUBR= mastodon_stream mastodon_web mastodon_workers
USE_RUBY= yes
SHEBANG_FILES= bin/*
USERS= ${PORTNAME}
GROUPS= ${PORTNAME}
NO_ARCH= yes
NO_BUILD= yes
SUB_LIST+= RAKE="${LOCALBASE}/bin/rake" RUBY="${RUBY_NAME}"
SUB_FILES= 900.mastodon nginx.conf nginx-include.conf
post-patch:
@${REINPLACE_CMD} -e 's|%%PREFIX%%|${PREFIX}|' \
${WRKSRC}/bin/yarn \
${WRKSRC}/config/environments/production.rb
do-install:
${RM} ${WRKSRC}/Gemfile.lock \
${WRKSRC}/lib/tasks/auto_annotate_models.rake
${MKDIR} ${STAGEDIR}${LOCALBASE}/etc/periodic/daily \
${STAGEDIR}${WWWDIR} ${STAGEDIR}/var/log/mastodon
${INSTALL_SCRIPT} ${WRKDIR}/900.mastodon \
${STAGEDIR}${LOCALBASE}/etc/periodic/daily
${INSTALL_DATA} ${WRKDIR}/nginx.conf \
${STAGEDIR}${WWWDIR}/nginx.conf.sample
${INSTALL_DATA} ${WRKDIR}/nginx-include.conf \
${STAGEDIR}${WWWDIR}/nginx-include.conf.sample
(cd ${WRKSRC} && ${COPYTREE_SHARE} . ${STAGEDIR}${WWWDIR})
.include <bsd.port.mk>

3
net-im/mastodon/distinfo Normal file
View File

@ -0,0 +1,3 @@
TIMESTAMP = 1495804238
SHA256 (tootsuite-mastodon-v1.4rc4_GH0.tar.gz) = da61920f8604b1ccc9042bee0adea2e002ab334c7d90181f41606c1db8da930f
SIZE (tootsuite-mastodon-v1.4rc4_GH0.tar.gz) = 9999246

View File

@ -0,0 +1,38 @@
#!/bin/sh
#
# $FreeBSD$
#
# daily_mastodon="YES"
#
# These are daily tasks to ensure that Mastodon runs smoothly.
#
# Feed clear: Removes timelines of users who haven't signed in lately, which
# saves RAM and improves message distribution. This is required to be run
# periodically so that when they login again the regeneration process will
# trigger.
#
# Media clear: Remove media attachments that have not been assigned to any status
# for longer than a day.
#
# Users clear: Clear timelines of inactive users.
#
# Push refresh: Resubscribes PuSH for expiring remote users. This should be run
# quite often as the expiration time depends on the particular hub of the remote
# user.
#
if [ -r /etc/defaults/periodic.conf ]; then
. /etc/defaults/periodic.conf
source_periodic_confs
fi
rc=0
case "$daily_mastodon_enable" in
[Yy][Ee][Ss])
cd %%WWWDIR%% && %%RAKE%% mastodon:daily RAILS_ENV=production LOG_LEVEL=warn
rc=$?;;
*) rc=0;;
esac
exit $rc

View File

@ -0,0 +1,34 @@
#! /bin/sh
# PROVIDE: mastodon_stream
# REQUIRE: LOGIN postgresql nginx redis
# KEYWORD: shutdown
#
# Add the following line to /etc/rc.conf to enable the Mastodon streaming
# service.
#
# mastodon_stream_enable="YES"
. /etc/rc.subr
name=mastodon_stream
rcvar="${name}_enable"
load_rc_config "$name"
: ${mastodon_stream_enable:="NO"}
: ${mastodon_stream_port="4000"}
mastodon_stream_chdir="%%WWWDIR%%"
mastodon_stream_env="HOME=%%WWWDIR%% \
NODE_ENV=production \
PORT=\"${mastodon_stream_port}\" \
USER=mastodon"
mastodon_stream_user="mastodon"
command="%%PREFIX%%/bin/node"
command_args="%%WWWDIR%%/node_modules/.bin/babel-node ./streaming/index.js \
>> /var/log/mastodon/${name}.log 2>&1 &"
run_rc_command "$1"

View File

@ -0,0 +1,40 @@
#! /bin/sh
# PROVIDE: mastodon_web
# REQUIRE: LOGIN postgresql nginx redis
# KEYWORD: shutdown
#
# Add the following line to /etc/rc.conf to enable the Mastodon web server.
#
# mastodon_web_enable="YES"
. /etc/rc.subr
name=mastodon_web
rcvar="${name}_enable"
load_rc_config "$name"
: ${mastodon_web_enable:="NO"}
: ${mastodon_web_concurrency:="2"}
: ${mastodon_web_loglevel:="error"}
: ${mastodon_web_port:="3000"}
: ${mastodon_web_threads:="5"}
mastodon_web_chdir="%%WWWDIR%%"
mastodon_web_env="MAX_THREADS=\"${mastodon_web_threads}\" \
PORT=\"${mastodon_web_port}\" \
RAILS_ENV=production \
RAILS_LOG_LEVEL=\"${mastodon_web_loglevel}\" \
WEB_CONCURRENCY=\"${mastodon_web_concurrency}\""
mastodon_web_user="mastodon"
pidfile="%%WWWDIR%%/tmp/${name}.pid"
procname="%%RUBY%%:"
command="%%PREFIX%%/bin/puma"
command_flags="-C config/puma.rb"
command_args=">> /var/log/mastodon/${name}.log 2>&1 &"
run_rc_command "$1"

View File

@ -0,0 +1,37 @@
#! /bin/sh
# PROVIDE: mastodon_workers
# REQUIRE: LOGIN postgresql nginx redis
# KEYWORD: shutdown
#
# Add the following line to /etc/rc.conf to enable the Mastodon background
# workers.
#
# mastodon_workers_enable="YES"
. /etc/rc.subr
name=mastodon_workers
rcvar="${name}_enable"
load_rc_config "$name"
: ${mastodon_workers_enable:="NO"}
: ${mastodon_workers_loglevel:="error"}
: ${mastodon_workers_dbpool:="5"}
: ${mastodon_workers_threads:="5"}
mastodon_workers_chdir="%%WWWDIR%%"
mastodon_workers_env="DB_POOL=\"${mastodon_workers_dbpool}\" \
RAILS_ENV=production \
RAILS_LOG_LEVEL=\"${mastodon_workers_loglevel}\""
mastodon_workers_user="mastodon"
pidfile="%%WWWDIR%%/tmp/${name}.pid"
procname="%%RUBY%%:"
command="%%PREFIX%%/bin/sidekiq"
command_flags="-c ${mastodon_workers_threads} -q default -q mailers -q pull -q push"
command_args=">> /var/log/mastodon/${name}.log 2>&1 &"
run_rc_command "$1"

View File

@ -0,0 +1,82 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen 443 ssl http2;
# listen [::]:443 ssl http2;
server_name example.com;
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 %%PREFIX%%/etc/dehydrated/certs/example.com/fullchain.pem;
ssl_certificate_key %%PREFIX%%/etc/dehydrated/certs/example.com/privkey.pem;
ssl_dhparam %%PREFIX%%/etc/dehydrated/certs/dhparam.pem;
keepalive_timeout 70;
sendfile on;
client_max_body_size 0;
root %%WWWDIR%%/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://example.com; upgrade-insecure-requests";
location / {
try_files $uri @proxy;
}
location ~ ^/(packs|system/media_attachments/files|system/accounts/avatars) {
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: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://localhost: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;
}

View File

@ -0,0 +1,25 @@
worker_processes 2;
error_log /var/log/httpd-error.log;
user www www;
events
{
worker_connections 1024;
}
http
{
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/httpd-access.log;
default_type application/octet-stream;
include %%PREFIX%%/etc/nginx/mime.types;
index index.html
keepalive_timeout 65;
gzip on;
sendfile on;
include %%WWWDIR%%/nginx-include.conf;
}

View File

@ -0,0 +1,42 @@
--- .env.production.sample.orig 2017-05-26 12:16:04 UTC
+++ .env.production.sample
@@ -1,11 +1,11 @@
# Service dependencies
# You may set REDIS_URL instead for more advanced options
-REDIS_HOST=redis
+REDIS_HOST=localhost
REDIS_PORT=6379
# You may set DATABASE_URL instead for more advanced options
-DB_HOST=db
-DB_USER=postgres
-DB_NAME=postgres
+DB_HOST=localhost
+DB_USER=mastodon
+DB_NAME=mastodon_production
DB_PASS=
DB_PORT=5432
@@ -47,16 +47,16 @@ OTP_SECRET=
# 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=smtp.mailgun.org
-SMTP_PORT=587
-SMTP_LOGIN=
-SMTP_PASSWORD=
-SMTP_FROM_ADDRESS=notifications@example.com
+#SMTP_SERVER=smtp.mailgun.org
+#SMTP_PORT=587
+#SMTP_LOGIN=
+#SMTP_PASSWORD=
+SMTP_FROM_ADDRESS=mastodon@example.com
#SMTP_DOMAIN= # defaults to LOCAL_DOMAIN
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
-#SMTP_AUTH_METHOD=plain
+SMTP_AUTH_METHOD=none
#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt
-#SMTP_OPENSSL_VERIFY_MODE=peer
+SMTP_OPENSSL_VERIFY_MODE=none
#SMTP_ENABLE_STARTTLS_AUTO=true

View File

@ -0,0 +1,55 @@
--- Gemfile.orig 2017-05-20 21:11:45 UTC
+++ Gemfile
@@ -19,7 +19,6 @@ gem 'paperclip', '~> 5.1'
gem 'paperclip-av-transcoder', '~> 0.6'
gem 'addressable', '~> 2.5'
-gem 'bootsnap'
gem 'cld3', '~> 3.1'
gem 'devise', '~> 4.2'
gem 'devise-two-factor', '~> 3.0'
@@ -59,44 +58,6 @@ gem 'twitter-text', '~> 1.14'
gem 'tzinfo-data', '~> 1.2017'
gem 'webpacker', '~> 1.2'
-group :development, :test do
- gem 'fabrication', '~> 2.16'
- gem 'fuubar', '~> 2.2'
- gem 'i18n-tasks', '~> 0.9', require: false
- gem 'pry-rails', '~> 0.3'
- gem 'rspec-rails', '~> 3.6'
-end
-
-group :test do
- gem 'capybara', '~> 2.14'
- gem 'faker', '~> 1.7'
- gem 'microformats2', '~> 3.0'
- gem 'rails-controller-testing', '~> 1.0'
- gem 'rspec-sidekiq', '~> 3.0'
- gem 'simplecov', '~> 0.14', require: false
- gem 'webmock', '~> 3.0'
- gem 'parallel_tests', '~> 2.14'
-end
-
-group :development do
- gem 'active_record_query_trace', '~> 1.5'
- gem 'annotate', '~> 2.7'
- gem 'better_errors', '~> 2.1'
- gem 'binding_of_caller', '~> 0.7'
- gem 'bullet', '~> 5.5'
- gem 'letter_opener', '~> 1.4'
- gem 'letter_opener_web', '~> 1.3'
- gem 'rubocop', '~> 0.48', require: false
- gem 'brakeman', '~> 3.6', require: false
- gem 'bundler-audit', '~> 0.5', require: false
- gem 'scss_lint', '~> 0.53', require: false
-
- gem 'capistrano', '~> 3.8'
- gem 'capistrano-rails', '~> 1.2'
- gem 'capistrano-rbenv', '~> 2.1'
- gem 'capistrano-yarn', '~> 2.0'
-end
-
group :production do
gem 'lograge', '~> 0.5'
gem 'redis-rails', '~> 5.0'

View File

@ -0,0 +1,11 @@
--- bin/yarn.orig 2017-05-25 22:16:48 UTC
+++ bin/yarn
@@ -2,7 +2,7 @@
VENDOR_PATH = File.expand_path('..', __dir__)
Dir.chdir(VENDOR_PATH) do
begin
- exec "yarnpkg #{ARGV.join(" ")}"
+ exec "%%PREFIX%%/bin/yarn #{ARGV.join(" ")}"
rescue Errno::ENOENT
$stderr.puts "Yarn executable was not detected in the system."
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"

View File

@ -0,0 +1,27 @@
--- config/boot.rb.orig 2017-05-20 22:05:08 UTC
+++ config/boot.rb
@@ -1,14 +1,14 @@
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup' # Set up gems listed in the Gemfile.
-require 'bootsnap'
+#require 'bootsnap'
-Bootsnap.setup(
- cache_dir: 'tmp/cache',
- development_mode: ENV['RAILS_ENV'] == 'development',
- load_path_cache: true,
- autoload_paths_cache: true,
- disable_trace: true,
- compile_cache_iseq: false,
- compile_cache_yaml: false
-)
+# Bootsnap.setup(
+# cache_dir: 'tmp/cache',
+# development_mode: ENV['RAILS_ENV'] == 'development',
+# load_path_cache: true,
+# autoload_paths_cache: true,
+# disable_trace: true,
+# compile_cache_iseq: false,
+# compile_cache_yaml: false
+# )

View File

@ -0,0 +1,12 @@
--- config/environments/production.rb.orig 2017-05-24 01:40:57 UTC
+++ config/environments/production.rb
@@ -104,4 +104,9 @@ Rails.application.configure do
'X-Content-Type-Options' => 'nosniff',
'X-XSS-Protection' => '1; mode=block',
}
+
+ # Paperclip config:
+ Paperclip.options[:image_magick_path] = "%%PREFIX%%/bin"
+ Paperclip.options[:command_path] = "%%PREFIX%%/bin"
+
end

View File

@ -0,0 +1,11 @@
--- config/puma.rb.orig 2017-05-22 21:15:56 UTC
+++ config/puma.rb
@@ -1,6 +1,8 @@
threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i
threads threads_count, threads_count
+pidfile 'tmp/mastodon_web.pid'
+
if ENV['SOCKET'] then
bind 'unix://' + ENV['SOCKET']
else

View File

@ -0,0 +1,7 @@
--- config/sidekiq.yml.orig 2017-05-22 21:30:15 UTC
+++ config/sidekiq.yml
@@ -15,3 +15,4 @@
feed_cleanup_scheduler:
cron: '0 0 * * *'
class: Scheduler::FeedCleanupScheduler
+:pidfile: tmp/mastodon_workers.pid

View File

@ -0,0 +1,8 @@
Mastodon is an alternative implementation of GNU social, a free,
open-source social network. It is a decentralized alternative to
commercial platforms based on ActivityStreams, Webfinger, PubsubHubbub
and Salmon. The project focuses on creating a clean REST API and a good
user interface. Ruby on Rails is used for the back-end, while React.js
and Redux are used for the dynamic front-end.
WWW: https://github.com/tootsuite/mastodon

View File

@ -0,0 +1,6 @@
########################################################
Visit the URL below to get started with Mastodon.
http://ftfl.ca/blog/2017-05-23-mastodon-freebsd.html
########################################################

5315
net-im/mastodon/pkg-plist Normal file

File diff suppressed because it is too large Load Diff