Sanitized mirror from private repository - 2026-04-18 11:19:59 UTC
This commit is contained in:
340
docs/services/mastodon/install-baremetal.sh
Executable file
340
docs/services/mastodon/install-baremetal.sh
Executable file
@@ -0,0 +1,340 @@
|
||||
#!/bin/bash
|
||||
# Mastodon v4.5.4 Bare-Metal Install Script for Rocky Linux 10
|
||||
# Usage: curl -sSL https://git.vish.gg/Vish/pihole-baremetal/raw/branch/main/mastodon/install-mastodon.sh | bash
|
||||
# Run as root on a fresh Rocky Linux 10 VM
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration - Edit these before running
|
||||
DOMAIN="${DOMAIN:-mastodon.example.com}"
|
||||
ADMIN_USER="${ADMIN_USER:-admin}"
|
||||
ADMIN_EMAIL="${ADMIN_EMAIL:-admin@example.com}"
|
||||
SMTP_SERVER="${SMTP_SERVER:-smtp.gmail.com}"
|
||||
SMTP_PORT="${SMTP_PORT:-587}"
|
||||
SMTP_USER="${SMTP_USER:-}"
|
||||
SMTP_PASS="REDACTED_PASSWORD"
|
||||
SMTP_FROM="${SMTP_FROM:-notifications@example.com}"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Mastodon v4.5.4 Installation Script"
|
||||
echo "Target Domain: $DOMAIN"
|
||||
echo "=========================================="
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install system dependencies
|
||||
echo "[1/12] Installing system dependencies..."
|
||||
dnf install -y epel-release
|
||||
dnf install -y git curl wget gcc make autoconf bison openssl-devel \
|
||||
libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel \
|
||||
libxml2-devel libxslt-devel libicu-devel libidn-devel jemalloc-devel \
|
||||
ImageMagick ImageMagick-devel nginx postgresql-server postgresql-contrib \
|
||||
valkey certbot python3-certbot-nginx meson ninja-build \
|
||||
libpng-devel libjpeg-turbo-devel libwebp-devel libtiff-devel \
|
||||
expat-devel gobject-introspection-devel glib2-devel
|
||||
|
||||
# Install Node.js 20
|
||||
echo "[2/12] Installing Node.js 20..."
|
||||
curl -fsSL https://rpm.nodesource.com/setup_20.x | bash -
|
||||
dnf install -y nodejs
|
||||
|
||||
# Enable corepack for Yarn
|
||||
corepack enable
|
||||
|
||||
# Build libvips from source (not in Rocky 10 repos)
|
||||
echo "[3/12] Building libvips from source..."
|
||||
cd /tmp
|
||||
wget https://github.com/libvips/libvips/releases/download/v8.16.1/vips-8.16.1.tar.xz
|
||||
tar xf vips-8.16.1.tar.xz
|
||||
cd vips-8.16.1
|
||||
meson setup build --prefix=/usr --buildtype=release
|
||||
cd build && ninja && ninja install
|
||||
ldconfig
|
||||
cd /tmp && rm -rf vips-8.16.1*
|
||||
|
||||
# Initialize PostgreSQL
|
||||
echo "[4/12] Setting up PostgreSQL..."
|
||||
postgresql-setup --initdb
|
||||
systemctl enable --now postgresql
|
||||
|
||||
# Create mastodon database user and database
|
||||
sudo -u postgres psql -c "CREATE USER mastodon CREATEDB;"
|
||||
sudo -u postgres psql -c "CREATE DATABASE mastodon_production OWNER mastodon;"
|
||||
|
||||
# Start Valkey (Redis)
|
||||
echo "[5/12] Starting Valkey..."
|
||||
systemctl enable --now valkey
|
||||
|
||||
# Create mastodon user
|
||||
echo "[6/12] Creating mastodon user..."
|
||||
useradd -m -s /bin/bash mastodon || true
|
||||
|
||||
# Install Ruby via rbenv
|
||||
echo "[7/12] Installing Ruby 3.4.7..."
|
||||
sudo -u mastodon bash << 'RUBY_INSTALL'
|
||||
cd ~
|
||||
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
|
||||
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
|
||||
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
|
||||
export PATH="$HOME/.rbenv/bin:$PATH"
|
||||
eval "$(rbenv init -)"
|
||||
|
||||
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
|
||||
RUBY_CONFIGURE_OPTS="--with-jemalloc" rbenv install 3.4.7
|
||||
rbenv global 3.4.7
|
||||
gem install bundler
|
||||
RUBY_INSTALL
|
||||
|
||||
# Clone Mastodon
|
||||
echo "[8/12] Cloning Mastodon v4.5.4..."
|
||||
sudo -u mastodon bash << 'CLONE'
|
||||
cd ~
|
||||
git clone https://github.com/mastodon/mastodon.git live
|
||||
cd live
|
||||
git checkout v4.5.4
|
||||
CLONE
|
||||
|
||||
# Install dependencies
|
||||
echo "[9/12] Installing Ruby and Node dependencies..."
|
||||
sudo -u mastodon bash << 'DEPS'
|
||||
export PATH="$HOME/.rbenv/bin:$PATH"
|
||||
eval "$(rbenv init -)"
|
||||
cd ~/live
|
||||
bundle config deployment 'true'
|
||||
bundle config without 'development test'
|
||||
bundle install -j$(nproc)
|
||||
yarn install --immutable
|
||||
DEPS
|
||||
|
||||
# Generate secrets and create .env.production
|
||||
echo "[10/12] Generating secrets and configuration..."
|
||||
SECRET_KEY=$(openssl rand -hex 64)
|
||||
OTP_SECRET=$(openssl rand -hex 64)
|
||||
VAPID_KEYS=$(sudo -u mastodon bash -c 'cd ~/live && export PATH="$HOME/.rbenv/bin:$PATH" && eval "$(rbenv init -)" && RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key 2>/dev/null')
|
||||
VAPID_PRIVATE=$(echo "$VAPID_KEYS" | grep VAPID_PRIVATE_KEY | cut -d= -f2)
|
||||
VAPID_PUBLIC=$(echo "$VAPID_KEYS" | grep VAPID_PUBLIC_KEY | cut -d= -f2)
|
||||
|
||||
AR_KEY=$(openssl rand -hex 32)
|
||||
AR_DETERMINISTIC=$(openssl rand -hex 32)
|
||||
AR_SALT=$(openssl rand -hex 32)
|
||||
|
||||
cat > /home/mastodon/live/.env.production << ENVFILE
|
||||
LOCAL_DOMAIN=$DOMAIN
|
||||
SINGLE_USER_MODE=false
|
||||
SECRET_KEY_BASE=$SECRET_KEY
|
||||
OTP_SECRET=$OTP_SECRET
|
||||
VAPID_PRIVATE_KEY=$VAPID_PRIVATE
|
||||
VAPID_PUBLIC_KEY=$VAPID_PUBLIC
|
||||
DB_HOST=/var/run/postgresql
|
||||
DB_USER=mastodon
|
||||
DB_NAME=mastodon_production
|
||||
DB_PASS=
|
||||
"REDACTED_PASSWORD"
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PORT=6379
|
||||
SMTP_SERVER=$SMTP_SERVER
|
||||
SMTP_PORT=$SMTP_PORT
|
||||
SMTP_LOGIN=$SMTP_USER
|
||||
SMTP_PASSWORD="REDACTED_PASSWORD"
|
||||
SMTP_FROM_ADDRESS=$SMTP_FROM
|
||||
SMTP_AUTH_METHOD=plain
|
||||
SMTP_OPENSSL_VERIFY_MODE=none
|
||||
SMTP_ENABLE_STARTTLS=auto
|
||||
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=$AR_KEY
|
||||
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=$AR_DETERMINISTIC
|
||||
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=$AR_SALT
|
||||
TRUSTED_PROXY_IP=127.0.0.1,::1,192.168.0.0/16
|
||||
ENVFILE
|
||||
|
||||
chown mastodon:mastodon /home/mastodon/live/.env.production
|
||||
chmod 600 /home/mastodon/live/.env.production
|
||||
|
||||
# Run migrations and seed
|
||||
echo "[11/12] Running database migrations..."
|
||||
sudo -u mastodon bash << 'MIGRATE'
|
||||
export PATH="$HOME/.rbenv/bin:$PATH"
|
||||
eval "$(rbenv init -)"
|
||||
cd ~/live
|
||||
RAILS_ENV=production bundle exec rails db:migrate
|
||||
RAILS_ENV=production bundle exec rails db:seed
|
||||
RAILS_ENV=production bundle exec rails assets:precompile
|
||||
MIGRATE
|
||||
|
||||
# Create systemd services
|
||||
echo "[12/12] Creating systemd services..."
|
||||
cat > /etc/systemd/system/mastodon-web.service << 'SERVICE'
|
||||
[Unit]
|
||||
Description=mastodon-web
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=mastodon
|
||||
WorkingDirectory=/home/mastodon/live
|
||||
Environment="RAILS_ENV=production"
|
||||
Environment="PORT=3001"
|
||||
ExecStart=/bin/bash -lc 'cd /home/mastodon/live && exec bundle exec puma -C config/puma.rb'
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICE
|
||||
|
||||
cat > /etc/systemd/system/mastodon-sidekiq.service << 'SERVICE'
|
||||
[Unit]
|
||||
Description=mastodon-sidekiq
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=mastodon
|
||||
WorkingDirectory=/home/mastodon/live
|
||||
Environment="RAILS_ENV=production"
|
||||
Environment="MALLOC_ARENA_MAX=2"
|
||||
ExecStart=/bin/bash -lc 'cd /home/mastodon/live && exec bundle exec sidekiq -c 25'
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICE
|
||||
|
||||
cat > /etc/systemd/system/mastodon-streaming.service << 'SERVICE'
|
||||
[Unit]
|
||||
Description=mastodon-streaming
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=mastodon
|
||||
WorkingDirectory=/home/mastodon/live
|
||||
Environment="NODE_ENV=production"
|
||||
Environment="PORT=4000"
|
||||
Environment="STREAMING_CLUSTER_NUM=1"
|
||||
ExecStart=/usr/bin/node ./streaming
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICE
|
||||
|
||||
# Nginx config
|
||||
cat > /etc/nginx/conf.d/mastodon.conf << 'NGINX'
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
upstream backend {
|
||||
server 127.0.0.1:3001 fail_timeout=0;
|
||||
}
|
||||
|
||||
upstream streaming {
|
||||
server 127.0.0.1:4000 fail_timeout=0;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 3000;
|
||||
listen [::]:3000;
|
||||
server_name _;
|
||||
|
||||
keepalive_timeout 70;
|
||||
sendfile on;
|
||||
client_max_body_size 99m;
|
||||
|
||||
root /home/mastodon/live/public;
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
|
||||
|
||||
location / {
|
||||
try_files $uri @proxy;
|
||||
}
|
||||
|
||||
location ~ ^/(assets|avatars|emoji|headers|packs|shortcuts|sounds|system)/ {
|
||||
add_header Cache-Control "public, max-age=2419200, must-revalidate";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
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_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;
|
||||
tcp_nodelay on;
|
||||
}
|
||||
|
||||
error_page 404 500 501 502 503 504 /500.html;
|
||||
}
|
||||
NGINX
|
||||
|
||||
# SELinux and firewall
|
||||
setsebool -P httpd_can_network_connect 1
|
||||
setsebool -P httpd_read_user_content 1
|
||||
chcon -R -t httpd_sys_content_t /home/mastodon/live/public
|
||||
chmod 755 /home/mastodon /home/mastodon/live /home/mastodon/live/public
|
||||
firewall-cmd --permanent --add-port=3000/tcp
|
||||
firewall-cmd --reload
|
||||
|
||||
# Add localhost to Rails hosts
|
||||
echo 'Rails.application.config.hosts << "localhost"' >> /home/mastodon/live/config/environments/production.rb
|
||||
echo 'Rails.application.config.hosts << "127.0.0.1"' >> /home/mastodon/live/config/environments/production.rb
|
||||
chown mastodon:mastodon /home/mastodon/live/config/environments/production.rb
|
||||
|
||||
# Enable and start services
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming nginx
|
||||
|
||||
# Create admin user
|
||||
echo ""
|
||||
echo "Creating admin user..."
|
||||
ADMIN_PASS="REDACTED_PASSWORD" -u mastodon bash -c "cd ~/live && export PATH=\"\$HOME/.rbenv/bin:\$PATH\" && eval \"\$(rbenv init -)\" && RAILS_ENV=production bin/tootctl accounts create $ADMIN_USER --email=$ADMIN_EMAIL --confirmed 2>&1 | grep 'New password' | awk '{print \$3}'")
|
||||
sudo -u mastodon bash -c "cd ~/live && export PATH=\"\$HOME/.rbenv/bin:\$PATH\" && eval \"\$(rbenv init -)\" && RAILS_ENV=production bin/tootctl accounts modify $ADMIN_USER --role Owner"
|
||||
sudo -u mastodon bash -c "cd ~/live && export PATH=\"\$HOME/.rbenv/bin:\$PATH\" && eval \"\$(rbenv init -)\" && RAILS_ENV=production bin/tootctl accounts approve $ADMIN_USER"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "✅ Mastodon Installation Complete!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Domain: $DOMAIN"
|
||||
echo "Admin User: $ADMIN_USER"
|
||||
echo "Admin Email: $ADMIN_EMAIL"
|
||||
echo "Admin Password: "REDACTED_PASSWORD"
|
||||
echo ""
|
||||
echo "Listening on port 3000 (HTTP)"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Configure your reverse proxy to forward HTTPS to port 3000"
|
||||
echo "2. Login and change your password"
|
||||
echo "3. Configure instance settings in Administration panel"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user