+#!/bin/sh
+
+JAILNAME="$1"
+LO_NAME="$2"
+LO_ADDR="$3"
+EM_ADDR="$4"
+ZFSROOT='main/jail'
+PACKAGES="$(cat pkglist.txt | tr '[:space:]' ' ')"
+MASTODON_VERSION="v3.5.3"
+
+if [ -z "$JAILNAME" -o -z "$LO_NAME" -o -z "$LO_ADDR" -o -z "$EM_ADDR" ]; then
+ echo "syntax: $0 <jailname> <loopback interface name> <loopback addr> <em0 addr>"
+ exit 1
+fi
+
+set -e
+set -x
+
+zfs snapshot $ZFSROOT/newjail@_new_snap_
+zfs send $ZFSROOT/newjail@_new_snap_ | zfs receive $ZFSROOT/$JAILNAME
+zfs destroy $ZFSROOT/$JAILNAME@_new_snap_
+zfs destroy $ZFSROOT/newjail@_new_snap_
+
+ezjail-admin create -c zfs -x $JAILNAME "$LO_NAME|$LO_ADDR,em0|$EM_ADDR"
+ezjail-admin start $JAILNAME
+echo nameserver 192.168.64.1 >> /usr/jails/$JAILNAME/etc/resolv.conf
+ASSUME_ALWAYS_YES=yes pkg -j $JAILNAME install $PACKAGES
+jexec $JAILNAME pw user add -n mastodon -m -h -
+jexec -U mastodon $JAILNAME /bin/sh -c 'cd && git clone https://github.com/tootsuite/mastodon.git live'
+jexec -U mastodon $JAILNAME /bin/sh -c "cd ~/live && git checkout -b prod $MASTODON_VERSION"
+jexec -U mastodon $JAILNAME /bin/sh <<SCRIPT
+set -e
+set -x
+
+cd ~/live
+bundle config deployment 'true'
+bundle config without 'development test'
+bundle install
+yarn install --pure-lockfile
+SCRIPT
+cat env.production | jexec -U mastodon $JAILNAME /bin/sh -c 'cat >~/live/.env.production'
+jexec -U mastodon $JAILNAME /bin/sh -c 'cd ~/live && RAILS_ENV=production bundle exec rails assets:precompile'
+sed -e "s/LO_ADDR/$LO_ADDR/" < nginx.conf | jexec $JAILNAME /bin/sh -c 'cat > /usr/local/etc/nginx/nginx.conf'
+cat redis.diff | jexec $JAILNAME /bin/sh -c 'cd /usr/local/etc && patch -p1'
+cat mastodon.crt | jexec $JAILNAME /bin/sh -c 'cat > /usr/local/etc/nginx/mastodon.crt'
+cat mastodon.key | jexec $JAILNAME /bin/sh -c 'cd /usr/local/etc/nginx && cat > mastodon.key && chmod 400 mastodon.key'
+cat rc.conf | jexec $JAILNAME /bin/sh -c 'cat >/etc/rc.conf'
+ezjail-admin restart $JAILNAME
+for RC in rc.d/*; do
+ cp $RC /usr/jails/$JAILNAME/local/etc/rc.d/$RC
+done
+# Generated with mastodon:setup on 2022-08-09 22:57:24 UTC
+
+# Some variables in this file will be interpreted differently whether you are
+# using docker-compose or not.
+
+LOCAL_DOMAIN=mastodon
+SINGLE_USER_MODE=false
+SECRET_KEY_BASE=35fb1a44b1ce6136773498c916062053236ff0202961e4fa5ee7251b2ee42ae983225fd357ac1d8930e5cfcc4f07592c4509c03eae26b8d6276abec73e764976
+OTP_SECRET=3738ef1399827feafc3016d94f2a451089121786f32914e009797c4d3db70b48176ef09c8be517fbb90dbe3021422b5332780b8f80217d2b5e9a97a92195c9b1
+VAPID_PRIVATE_KEY=iJWbSfo_KyUmCBRjNMRNpHyWWnQefCiK08IBvyRKtdI=
+VAPID_PUBLIC_KEY=BMqEbBW7-WDDwIqxAq61B_yInumJLreSJWyQRcBlk8NGKf4zD0aHwLnt2nPNc3Gc12o8cDorFlic_0y1oKzZJMc=
+DB_HOST=127.0.2.1
+DB_PORT=5432
+DB_NAME=mastodon_production
+DB_USER=mastodon
+DB_PASS=mastodon
+REDIS_HOST=localhost
+REDIS_PORT=6379
+REDIS_PASSWORD=
+SMTP_SERVER=192.168.64.2
+SMTP_PORT=587
+SMTP_LOGIN=
+SMTP_PASSWORD=
+SMTP_AUTH_METHOD=plain
+SMTP_OPENSSL_VERIFY_MODE=none
+SMTP_FROM_ADDRESS='Mastodon <notifications@mastodon>'
+-----BEGIN CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIUZUK4CzUipMn3EQ0uqL4VbZSrrZAwDQYJKoZIhvcNAQEL
+BQAwQjELMAkGA1UEBhMCREExIDAeBgNVBAoMF1RoZSBEb21pbmlvbiBvZiBBd2Vz
+b21lMREwDwYDVQQDDAhtYXN0b2RvbjAeFw0yMjA4MTAwMDA3MTVaFw0yMjA5MDkw
+MDA3MTVaMEIxCzAJBgNVBAYTAkRBMSAwHgYDVQQKDBdUaGUgRG9taW5pb24gb2Yg
+QXdlc29tZTERMA8GA1UEAwwIbWFzdG9kb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDC/9mq1N9aknisUjkqFHMjHRHIZhicCWwkadwqNHmF2V7Yw4/U
+maHdF62hdLE6gx56OITKWtwmxP+zoebfCjdVRCK7W5Ua7+e3PAd1ixFetu3bhEXQ
+BpRkRtPhXTZj1VPD0+6e72w+esSbIonll7rWxmOA8E/7C8R3WFB9f7CYuTCW05+a
+VEzXyFIju7b0JX9UUib+gtbusCn/m1NV76tZUIg7qprQY8/nsKNcGIQXg2p78OND
+XId+X3HIPoCgErQaV6pkLOu2E4Ulllou0vEHTrOhXM0kVibQDqJKQnHTiiH5WfNk
+qd/E57Nct1TDe+Km9molaTUzA8gn4VxEVgBbAgMBAAGjUzBRMB0GA1UdDgQWBBT0
+7vTzIyf5MJ7vuS9drzdEAeRVdTAfBgNVHSMEGDAWgBT07vTzIyf5MJ7vuS9drzdE
+AeRVdTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCbPWbKPWYt
+vgZfG4D+e222OAbrpi9Co2/jHq780nqo1VYS6E6/leTagg4EdqZuHgaTudkWarCb
+8mj0owonOGC0sWkItEpzQ4b5q1+2e2s1STiDyHrI8SKJhkKqnYl2AUXkw8uPaTdX
+pt6aMCxCUSwEUw8RmhP4HHwUIHMlvyF+7azBVqB4j2GskPqwnqej6+4tiIq/fjv0
+ipEdSjiHpoPqrxOy58k9l/Al/gKimpk0dq9gLAAUfoqtUsw29QLH+pgBvihfVUfO
+ZmjDEYDj6/JZ/J2OJpCUeORVUbaKubrF5BBMpq0XIdoWDL3FoxgCJ+D9ElA+5kBH
+5WCUf/drcQVW
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAwv/ZqtTfWpJ4rFI5KhRzIx0RyGYYnAlsJGncKjR5hdle2MOP
+1Jmh3RetoXSxOoMeejiEylrcJsT/s6Hm3wo3VUQiu1uVGu/ntzwHdYsRXrbt24RF
+0AaUZEbT4V02Y9VTw9Punu9sPnrEmyKJ5Ze61sZjgPBP+wvEd1hQfX+wmLkwltOf
+mlRM18hSI7u29CV/VFIm/oLW7rAp/5tTVe+rWVCIO6qa0GPP57CjXBiEF4Nqe/Dj
+Q1yHfl9xyD6AoBK0GleqZCzrthOFJZZaLtLxB06zoVzNJFYm0A6iSkJx04oh+Vnz
+ZKnfxOezXLdUw3vipvZqJWk1MwPIJ+FcRFYAWwIDAQABAoIBAQC+ysyznELJgMS3
+fl/WL1oUQi4TEOoFSibYXgd/+AXrE6r8liPVlVhNVgyaC+4YXRBl74Tl5Q7AlEHI
+BaI6GunW8Kq2/L2gNJlYrFB0DtS5Am0qOnqANt/cWXyYZbaA6cpisaspMQONAlv5
+mkqoLNQvrr7O+tKWxIW/a9adZGFqmxi0iAxj0tYDlSpOdxjbFcKHImI5/S/L6MdW
+4E/TPNQQBKeE1ug3LHno+rcyQO6CEbOqGXv4E3humkTOkfOssKYViCU8ihIFcioZ
+X+oDayV1eozi1EYG4ZqKYu2Gfr4G71iB1WUUKBqEaA63pf9i1qTJ9TCgMN5ow3p0
+MffTo83RAoGBAPU7ECvxPHZe4XkYlhsC9yPiBBgq5cs9w/xPdLm1cGHEYB9Fe2Qf
+YhM0ZMaH9f3l1HOYnU4bTVHde6h0EsmIibqdqlj40y6dZzcO087gLLWC+s0IjkSP
+W3lS8T2+53d0Ex46bhAB7WjZw1QDk8bqapWIM3RFpsUw7Mr2UjImQ4P5AoGBAMuQ
+E3A6RfAV2vqk+kd1silUzEgptdjL6ZMRDtS7LOJ048vNPc0naJEwr1KgWpbi0G7i
+29o7xZKubMsiS6s3WDmjldgV9h+1c3XJVSs388vA0ccDGAdiuKWboFVdJKPurRnV
+qYEQf1z+iuEDHgphmNmo30mkvzin8IOc0L8TplPzAoGANmkVbHqI7MaehmzTGUku
+JpMGT4ptFAwvSPMkNfQw7DBTF30mJI/mBdbRKU+PX/c3jTJmbKcYH7rhrf2bEYYu
+8O38luMWkDgyZ3/ttO/+W4OlPArS7hlUtXWWuxl5aAKkH0fdlcWntGTktuZYSoFG
+hskCiaDOoN/7GglPMXtV7ZkCgYACyUEK2zFT3Oi3X4Sxb7H1kNyO7Es54WicA7LB
+RKKToufvRSrgYPa0bgcoSVuUDxytN9use/7zSAHjMd/5QvOpLk0BvSM2QeSHqy7I
+PabPlh8I60jr6PUAB0ZFhNXYjI6/+MWuJ4ymuDEsbT9/AuD1sbMErgWT//BxzLaq
+ttki8wKBgGIz2/YQ5/3fzEwr43iu+/Bv2MohD+Vz3eeTVw+nEEC0qSXjboDzzpDd
+pYG5XvlFFk72ITfCLWa12PY+i1Rsqqzeoad/qeBa3RZwkVSXfPqzziu2n85THefS
+YrYqtWpcMpbZibQB69xUaZcLZfzWpsjUf0uUoJrgSujtiXVMpw9T
+-----END RSA PRIVATE KEY-----
+#user nobody;
+worker_processes 1;
+
+# This default error log path is compiled-in to make sure configuration parsing
+# errors are logged somewhere, especially during unattended boot when stderr
+# isn't normally logged anywhere. This path will be touched on every nginx
+# start regardless of error log location configured here. See
+# https://trac.nginx.org/nginx/ticket/147 for more info.
+#
+#error_log /var/log/nginx/error.log;
+#
+
+#pid logs/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+
+ #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 logs/access.log main;
+
+ sendfile on;
+ #tcp_nopush on;
+
+ #keepalive_timeout 0;
+ keepalive_timeout 65;
+
+ #gzip on;
+
+ map $http_upgrade $connection_upgrade {
+ default upgrade;
+ '' close;
+ }
+
+ upstream backend {
+ server LO_ADDR:3000 fail_timeout=0;
+ }
+
+ upstream streaming {
+ server LO_ADDR:4000 fail_timeout=0;
+ }
+
+ proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
+
+ server {
+ listen 80;
+ # listen [::]:80;
+ server_name mastodon;
+ root /home/mastodon/live/public;
+ 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 mastodon;
+
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
+ ssl_prefer_server_ciphers on;
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_tickets off;
+
+ # Uncomment these lines once you acquire a certificate:
+ ssl_certificate /usr/local/etc/nginx/mastodon.crt;
+ ssl_certificate_key /usr/local/etc/nginx/mastodon.key;
+
+ 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 image/svg+xml image/x-icon;
+
+ add_header Strict-Transport-Security "max-age=31536000" always;
+
+ location / {
+ try_files $uri @proxy;
+ }
+
+ location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
+ add_header Cache-Control "public, max-age=31536000, immutable";
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ try_files $uri @proxy;
+ }
+
+ location /sw.js {
+ add_header Cache-Control "public, max-age=0";
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ 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 $scheme;
+ proxy_set_header Proxy "";
+ proxy_pass_header Server;
+
+ proxy_pass http://backend;
+ proxy_buffering on;
+ proxy_redirect off;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+
+ proxy_cache CACHE;
+ proxy_cache_valid 200 7d;
+ proxy_cache_valid 410 24h;
+ proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
+ add_header X-Cached $upstream_cache_status;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+
+ 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 $scheme;
+ proxy_set_header Proxy "";
+
+ proxy_pass http://streaming;
+ 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;
+ }
+}
+pkg
+ImageMagick7
+autoconf
+bash
+bison
+curl
+ffmpeg
+gdbm
+git
+icu
+libffi
+libidn
+libxml2
+libxslt
+ncurses
+nginx
+node16
+npm-node16
+postgresql15-client
+protobuf
+readline
+redis
+ruby
+ruby30-gems
+rubygem-bundler
+yarn-node16
+zsh
+redis_enable="YES"
+nginx_enable="YES"
+#!/bin/sh
+
+# PROVIDE: mastodon_sidekiq
+# REQUIRE: DAEMON mastodon_web
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name="mastodon_sidekiq"
+rcvar="mastodon_enable"
+
+pidfile="/var/run/mastodon-sidekiq.pid"
+mastodon_sidekiq_chdir="/home/mastodon/live"
+mastodon_sidekiq_env="RAILS_ENV=production"
+command="/usr/sbin/daemon"
+command_args="-u mastodon -P ${pidfile} -H -o /var/log/mastodon-sidekiq.log /usr/local/bin/bundle exec sidekiq -c 25"
+
+# read configuration and set defaults
+load_rc_config "$name"
+: ${mastodon_enable="NO"}
+
+run_rc_command "$1"
+#!/bin/sh
+
+# PROVIDE: mastodon_streaming
+# REQUIRE: DAEMON mastodon_web
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name="mastodon_streaming"
+rcvar="mastodon_enable"
+
+pidfile="/var/run/mastodon-streaming.pid"
+mastodon_streaming_chdir="/home/mastodon/live"
+mastodon_streaming_env="NODE_ENV=production PORT=4000 STREAMING_CLUSTER_NUM=1"
+command="/usr/sbin/daemon"
+command_args="-u mastodon -P ${pidfile} -H -o /var/log/mastodon-streaming.log /usr/local/bin/node ./streaming"
+
+# read configuration and set defaults
+load_rc_config "$name"
+: ${mastodon_enable="NO"}
+
+run_rc_command "$1"
+#!/bin/sh
+
+# PROVIDE: mastodon_web
+# REQUIRE: DAEMON
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name="mastodon_web"
+rcvar="mastodon_enable"
+
+pidfile="/var/run/mastodon-web.pid"
+mastodon_web_chdir="/home/mastodon/live"
+mastodon_web_env="RAILS_ENV=production"
+command="/usr/sbin/daemon"
+command_args="-u mastodon -P ${pidfile} -H -o /var/log/mastodon-web.log /usr/local/bin/bundle exec puma -C config/puma.rb"
+
+# read configuration and set defaults
+load_rc_config "$name"
+: ${mastodon_enable="NO"}
+
+run_rc_command "$1"
+--- a/redis.conf 2022-07-19 01:12:04.000000000 +0000
++++ b/redis.conf 2022-08-09 22:56:25.604635000 +0000
+@@ -84,7 +84,7 @@
+ # You will also need to set a password unless you explicitly disable protected
+ # mode.
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-bind 127.0.0.1 -::1
++bind 127.0.1.1
+
+ # By default, outgoing connections (from replica to master, from Sentinel to
+ # instances, cluster bus, etc.) are not bound to a specific local address. In
+@@ -108,7 +108,7 @@
+ # By default protected mode is enabled. You should disable it only if
+ # you are sure you want clients from other hosts to connect to Redis
+ # even if no authentication is configured.
+-protected-mode yes
++protected-mode no
+
+ # Redis uses default hardened security configuration directives to reduce the
+ # attack surface on innocent users. Therefore, several sensitive configuration
+#!/bin/sh
+
+export RAILS_ENV=production
+export NODE_ENV=production
+
+cd $HOME/live
+
+bundle exec puma -C config/puma.rb &
+echo "Started Puma on $!"
+PORT=4000 STREAMING_CLUSTER_NUM=1 node ./streaming &
+echo "Started Streaming on $!"
+bundle exec sidekiq -c 25 &
+echo "Started sidekiq on $!"
+wait