Files
linux-scripts/install-mattermost.sh
chiefgeek a1a17e81a1 Sync all scripts from website downloads — 352 scripts total
Includes updated JS challenge scripts with Claude-User whitelist,
same-site referer bypass, Blackbox-Exporter allowed bot, and all
new exporters, cheat sheets, and automation scripts.
2026-05-25 03:31:08 +02:00

486 lines
15 KiB
Bash
Executable File

#!/bin/bash
#############################################################
#### Mattermost Server Install Script ####
#### Bare-metal deployment with PostgreSQL and nginx ####
#### ####
#### Author: Phil Connor ####
#### Contact: contact@mylinux.work ####
#### License: MIT ####
#### Version: 1.0 ####
#### ####
#### Usage: sudo ./install-mattermost.sh ####
#### sudo ./install-mattermost.sh --help ####
#############################################################
set -euo pipefail
# ============================================================================
# CONFIGURATION (edit these before running)
# ============================================================================
MATTERMOST_VERSION="10.6.1"
DOMAIN="mattermost.example.com"
DB_NAME="mattermost"
DB_USER="mmuser"
DB_PASS=""
MM_USER="mattermost"
MM_DIR="/opt/mattermost"
DATA_DIR="/opt/mattermost/data"
NGINX_CONF=true
# ============================================================================
# INTERNAL
# ============================================================================
readonly VERSION="1.0"
readonly SCRIPT_NAME="${0##*/}"
OS_ID=""
OS_FAMILY=""
PKG_MGR=""
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
# ============================================================================
# HELPER FUNCTIONS
# ============================================================================
log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
log_step() { echo -e "${CYAN}[STEP]${NC} $*"; }
show_usage() {
cat <<EOF
Usage: sudo $SCRIPT_NAME [OPTIONS]
Installs Mattermost Server with PostgreSQL and nginx reverse proxy
on Ubuntu/Debian or RHEL/AlmaLinux/Rocky Linux.
OPTIONS:
--version VER Mattermost version to install (default: $MATTERMOST_VERSION)
--domain FQDN Server domain name (default: $DOMAIN)
--db-pass PASS PostgreSQL password for mmuser (default: random)
--no-nginx Skip nginx reverse proxy configuration
-h, --help Show this help message
EXAMPLES:
sudo $SCRIPT_NAME
sudo $SCRIPT_NAME --version 10.6.1 --domain chat.example.com
sudo $SCRIPT_NAME --domain mm.corp.local --no-nginx
sudo $SCRIPT_NAME --db-pass 'MySecureP@ss'
EOF
exit 0
}
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
--version) MATTERMOST_VERSION="$2"; shift 2 ;;
--domain) DOMAIN="$2"; shift 2 ;;
--db-pass) DB_PASS="$2"; shift 2 ;;
--no-nginx) NGINX_CONF=false; shift ;;
-h|--help) show_usage ;;
*) log_error "Unknown option: $1"; show_usage ;;
esac
done
}
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root (sudo)"
exit 1
fi
}
# ============================================================================
# OS DETECTION
# ============================================================================
detect_os() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS_ID="$ID"
else
log_error "Cannot detect OS — /etc/os-release not found"
exit 1
fi
case "$OS_ID" in
ubuntu|debian)
OS_FAMILY="debian"
PKG_MGR="apt"
;;
rhel|rocky|almalinux|centos)
OS_FAMILY="rhel"
PKG_MGR="dnf"
if ! command -v dnf &>/dev/null; then
PKG_MGR="yum"
fi
;;
*)
log_error "Unsupported OS: $OS_ID"
exit 1
;;
esac
log_info "Detected OS: $PRETTY_NAME (package manager: $PKG_MGR)"
}
# ============================================================================
# STEP 1: INSTALL DEPENDENCIES
# ============================================================================
install_dependencies() {
log_step "Installing dependencies..."
case "$OS_FAMILY" in
debian)
apt-get update -qq
apt-get install -y -qq postgresql postgresql-contrib nginx curl jq
;;
rhel)
$PKG_MGR install -y -q postgresql-server postgresql nginx curl jq
# Initialize PostgreSQL if not already done
if [[ ! -d /var/lib/pgsql/data ]] || [[ -z "$(ls -A /var/lib/pgsql/data 2>/dev/null)" ]]; then
log_info "Initializing PostgreSQL database..."
postgresql-setup --initdb
fi
# Enable and start PostgreSQL
systemctl enable postgresql
systemctl start postgresql
;;
esac
# Ensure PostgreSQL is running on Debian-based as well
if [[ "$OS_FAMILY" == "debian" ]]; then
systemctl enable postgresql
systemctl start postgresql
fi
log_info "Dependencies installed"
}
# ============================================================================
# STEP 2: CONFIGURE POSTGRESQL
# ============================================================================
configure_database() {
log_step "Configuring PostgreSQL database..."
# Generate random password if not provided
if [[ -z "$DB_PASS" ]]; then
DB_PASS=$(openssl rand -base64 24 | tr -d '/+=')
log_info "Generated random database password"
fi
# Create user if not exists
if sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='$DB_USER'" | grep -q 1; then
log_warn "PostgreSQL user '$DB_USER' already exists — updating password"
sudo -u postgres psql -c "ALTER USER $DB_USER WITH PASSWORD '$DB_PASS';"
else
sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';"
log_info "Created PostgreSQL user: $DB_USER"
fi
# Create database if not exists
if sudo -u postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname='$DB_NAME'" | grep -q 1; then
log_warn "Database '$DB_NAME' already exists"
else
sudo -u postgres psql -c "CREATE DATABASE $DB_NAME OWNER $DB_USER;"
log_info "Created database: $DB_NAME"
fi
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
# Ensure md5/scram-sha-256 auth for local connections on RHEL
if [[ "$OS_FAMILY" == "rhel" ]]; then
local pg_hba
pg_hba=$(sudo -u postgres psql -tAc "SHOW hba_file;")
if [[ -f "$pg_hba" ]] && grep -q 'ident' "$pg_hba"; then
log_info "Updating pg_hba.conf to allow password authentication..."
sed -i 's/^\(local.*all.*all.*\)ident/\1md5/' "$pg_hba"
sed -i 's/^\(host.*all.*all.*127\.0\.0\.1\/32.*\)ident/\1md5/' "$pg_hba"
sed -i 's/^\(host.*all.*all.*::1\/128.*\)ident/\1md5/' "$pg_hba"
systemctl restart postgresql
fi
fi
log_info "PostgreSQL configured"
}
# ============================================================================
# STEP 3: CREATE SYSTEM USER
# ============================================================================
create_system_user() {
log_step "Creating system user..."
if id "$MM_USER" &>/dev/null; then
log_warn "System user '$MM_USER' already exists"
else
useradd --system --no-create-home --shell /usr/sbin/nologin "$MM_USER"
log_info "Created system user: $MM_USER"
fi
}
# ============================================================================
# STEP 4: DOWNLOAD AND EXTRACT MATTERMOST
# ============================================================================
download_mattermost() {
log_step "Downloading Mattermost v${MATTERMOST_VERSION}..."
local download_url="https://releases.mattermost.com/${MATTERMOST_VERSION}/mattermost-${MATTERMOST_VERSION}-linux-amd64.tar.gz"
local tmp_file="/tmp/mattermost-${MATTERMOST_VERSION}.tar.gz"
if [[ -d "$MM_DIR" ]] && [[ -f "$MM_DIR/bin/mattermost" ]]; then
local existing_version
existing_version=$("$MM_DIR/bin/mattermost" version 2>/dev/null | grep -oP 'Version:\s*\K[\d.]+' || echo "unknown")
log_warn "Mattermost already installed at $MM_DIR (version: $existing_version)"
log_warn "Skipping download — remove $MM_DIR to reinstall"
return 0
fi
curl -fSL -o "$tmp_file" "$download_url"
log_info "Downloaded: $download_url"
# Extract to /opt (creates /opt/mattermost)
tar -xzf "$tmp_file" -C /opt/
rm -f "$tmp_file"
# Create data directory
mkdir -p "$DATA_DIR"
# Set ownership
chown -R "$MM_USER:$MM_USER" "$MM_DIR"
log_info "Mattermost extracted to $MM_DIR"
}
# ============================================================================
# STEP 5: CONFIGURE MATTERMOST
# ============================================================================
configure_mattermost() {
log_step "Configuring Mattermost..."
local config_file="$MM_DIR/config/config.json"
if [[ ! -f "$config_file" ]]; then
log_error "Config file not found: $config_file"
exit 1
fi
local dsn="postgres://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}?sslmode=disable&connect_timeout=10"
# Use jq to update configuration
local tmp_config
tmp_config=$(mktemp)
jq \
--arg dsn "$dsn" \
--arg siteurl "https://${DOMAIN}" \
--arg datadir "$DATA_DIR" \
'
.SqlSettings.DriverName = "postgres" |
.SqlSettings.DataSource = $dsn |
.ServiceSettings.SiteURL = $siteurl |
.ServiceSettings.ListenAddress = ":8065" |
.FileSettings.Directory = $datadir
' "$config_file" > "$tmp_config"
mv "$tmp_config" "$config_file"
chown "$MM_USER:$MM_USER" "$config_file"
chmod 600 "$config_file"
log_info "Configuration updated: $config_file"
}
# ============================================================================
# STEP 6: CREATE SYSTEMD SERVICE
# ============================================================================
create_service() {
log_step "Creating systemd service..."
cat > /etc/systemd/system/mattermost.service <<EOF
[Unit]
Description=Mattermost Server
After=network.target postgresql.service
[Service]
Type=notify
User=$MM_USER
Group=$MM_USER
WorkingDirectory=$MM_DIR
ExecStart=$MM_DIR/bin/mattermost
Restart=always
RestartSec=10
LimitNOFILE=49152
TimeoutStartSec=3600
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable mattermost
systemctl start mattermost
sleep 3
if systemctl is-active --quiet mattermost; then
log_info "Mattermost service is running"
else
log_error "Mattermost failed to start — check: journalctl -u mattermost"
systemctl status mattermost --no-pager || true
exit 1
fi
}
# ============================================================================
# STEP 7: NGINX REVERSE PROXY
# ============================================================================
configure_nginx() {
if [[ "$NGINX_CONF" != true ]]; then
log_info "Skipping nginx configuration (--no-nginx)"
return 0
fi
log_step "Configuring nginx reverse proxy..."
local nginx_config
if [[ "$OS_FAMILY" == "debian" ]]; then
nginx_config="/etc/nginx/sites-available/mattermost"
else
nginx_config="/etc/nginx/conf.d/mattermost.conf"
fi
cat > "$nginx_config" <<'NGINXEOF'
upstream mattermost_backend {
server localhost:8065;
keepalive 32;
}
server {
listen 80;
server_name DOMAIN_PLACEHOLDER;
client_max_body_size 100M;
location ~ /api/v[0-9]+/(users/)?websocket$ {
proxy_pass http://mattermost_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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 X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
proxy_read_timeout 600s;
}
location / {
proxy_pass http://mattermost_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
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 X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
}
}
NGINXEOF
# Replace domain placeholder
sed -i "s/DOMAIN_PLACEHOLDER/$DOMAIN/" "$nginx_config"
# Enable site on Debian-based systems
if [[ "$OS_FAMILY" == "debian" ]]; then
mkdir -p /etc/nginx/sites-enabled
ln -sf "$nginx_config" /etc/nginx/sites-enabled/mattermost
fi
# Test and reload nginx
if nginx -t 2>/dev/null; then
systemctl enable nginx
systemctl reload nginx
log_info "Nginx configured and reloaded"
else
log_error "Nginx configuration test failed"
nginx -t
exit 1
fi
}
# ============================================================================
# STEP 8: SUMMARY
# ============================================================================
print_summary() {
echo ""
echo "============================================"
echo " Mattermost Installation Complete"
echo "============================================"
echo ""
log_info "Database credentials:"
echo " User: $DB_USER"
echo " Password: $DB_PASS"
echo " Database: $DB_NAME"
echo ""
log_info "Mattermost:"
echo " URL: https://$DOMAIN"
echo " Service: mattermost.service"
echo " Config: $MM_DIR/config/config.json"
echo " Data: $DATA_DIR"
echo ""
log_info "Next steps:"
echo " 1. Set up TLS: sudo certbot --nginx -d $DOMAIN"
echo " 2. Visit https://$DOMAIN to create the admin account"
echo " 3. View logs: sudo journalctl -u mattermost -f"
echo ""
}
# ============================================================================
# MAIN
# ============================================================================
main() {
parse_args "$@"
echo ""
echo "============================================"
echo " Mattermost Install Script v${VERSION}"
echo " https://mylinux.work"
echo "============================================"
echo ""
check_root
detect_os
install_dependencies
configure_database
create_system_user
download_mattermost
configure_mattermost
create_service
configure_nginx
print_summary
}
main "$@"