commit b5719ca519ddba09f1ffed3d9b6f4e7159b13765 Author: RED SOUL Date: Sun Feb 22 15:12:34 2026 +0700 Initial commit: OpenClaw Mattermost Installer Wizard diff --git a/README.md b/README.md new file mode 100644 index 0000000..7bdaa30 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# 🦞 OpenClaw Mattermost Installer + +One-command deployment of **Mattermost Team Edition** on Ubuntu/Debian, pre-configured for [OpenClaw](https://openclaw.dev) integration. + +## What It Does + +- Installs **Docker**, **Nginx**, and **Certbot** (if not present) +- Deploys **Mattermost + PostgreSQL** via Docker Compose +- Configures **Nginx reverse proxy** with WebSocket support +- Obtains a free **Let's Encrypt SSL certificate** +- Binds to `127.0.0.1` for secure OpenClaw localhost access + +## Prerequisites + +| Requirement | Details | +|---|---| +| **OS** | Ubuntu 20.04+ / Debian 11+ | +| **Access** | Root (sudo) | +| **Ports** | 80 and 443 open to the internet | +| **DNS** | A record pointing your domain to this server's IP | +| **RAM** | 2 GB minimum (4 GB recommended) | + +## Quick Start + +```bash +# Download the installer +git clone https://github.com/openclaw/mattermost-installer.git +cd mattermost-installer + +# Run the wizard +sudo bash install.sh +``` + +The wizard will ask you for: +1. **Domain name** (e.g. `chat.example.com`) +2. **Email** (for Let's Encrypt SSL) +3. **Port** (default: 8000) +4. **Install directory** (default: `~/mattermost-docker`) + +## OpenClaw Integration + +After installation, create a Bot Account in Mattermost: + +1. Go to **System Console → Integrations → Bot Accounts** +2. Enable bot creation, then create a bot with `post:all` permission +3. Copy the generated Bot Token + +Then configure OpenClaw: + +```bash +openclaw config set channels.mattermost.accounts.default.baseUrl "https://YOUR_DOMAIN" +openclaw config set channels.mattermost.accounts.default.botToken "YOUR_BOT_TOKEN" +``` + +OpenClaw connects internally via `http://localhost:8000` for maximum speed and security. + +## Architecture + +``` +Internet → Nginx (443/SSL) → 127.0.0.1:8000 → Mattermost Container (:8065) + ↕ +OpenClaw Gateway → localhost:8000 ──────────────→ PostgreSQL Container +``` + +## Management + +```bash +cd ~/mattermost-docker + +# Start / Stop / Restart +docker compose up -d +docker compose down +docker compose restart + +# View logs +docker compose logs -f mattermost + +# Check status +docker compose ps +``` + +## Troubleshooting + +| Issue | Fix | +|---|---| +| SSL cert failed | Verify DNS A record points to this server; check ports 80/443 are open | +| Container won't start | Check logs: `docker compose logs mattermost` | +| 502 Bad Gateway | Container may still be booting — wait 30s and refresh | +| Permission denied | Run installer with `sudo` | + +## License + +MIT — use freely, contribute back. 🦞 diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..8eaeb50 --- /dev/null +++ b/install.sh @@ -0,0 +1,402 @@ +#!/usr/bin/env bash +# ============================================================================ +# OpenClaw Mattermost Installer +# Deploys Mattermost (Team Edition) via Docker with Nginx + Let's Encrypt SSL +# Compatible with OpenClaw gateway via localhost +# +# Usage: sudo bash install.sh +# GitHub: https://github.com/openclaw/mattermost-installer +# ============================================================================ + +set -euo pipefail + +# ── Colors ─────────────────────────────────────────────────────────────────── +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +BOLD='\033[1m' +NC='\033[0m' + +# ── Helpers ────────────────────────────────────────────────────────────────── +info() { echo -e "${CYAN}[INFO]${NC} $*"; } +success() { echo -e "${GREEN}[ OK]${NC} $*"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +fail() { echo -e "${RED}[FAIL]${NC} $*"; exit 1; } + +banner() { + echo "" + echo -e "${BOLD}${CYAN}" + echo " ┌──────────────────────────────────────────────┐" + echo " │ 🦞 OpenClaw Mattermost Installer 🦞 │" + echo " │ Docker + Nginx + Let's Encrypt │" + echo " └──────────────────────────────────────────────┘" + echo -e "${NC}" + echo "" +} + +# ── Pre-flight checks ─────────────────────────────────────────────────────── +preflight() { + if [[ $EUID -ne 0 ]]; then + fail "This script must be run as root (sudo bash install.sh)" + fi + + if ! grep -qiE 'ubuntu|debian' /etc/os-release 2>/dev/null; then + fail "This installer supports Ubuntu/Debian only." + fi + + if ss -tlnp | grep -qE ':80\b' 2>/dev/null; then + warn "Port 80 is already in use. Nginx/Certbot may conflict." + read -rp "Continue anyway? (y/N): " cont + [[ "$cont" =~ ^[Yy]$ ]] || exit 1 + fi + + if ss -tlnp | grep -qE ':443\b' 2>/dev/null; then + warn "Port 443 is already in use. Nginx/Certbot may conflict." + read -rp "Continue anyway? (y/N): " cont + [[ "$cont" =~ ^[Yy]$ ]] || exit 1 + fi + + success "Pre-flight checks passed." +} + +# ── Interactive prompts ────────────────────────────────────────────────────── +gather_input() { + echo -e "${BOLD}Step 1: Configuration${NC}" + echo "" + + # Domain + while true; do + read -rp " Enter your Mattermost domain (e.g. chat.example.com): " MM_DOMAIN + if [[ -z "$MM_DOMAIN" ]]; then + warn "Domain cannot be empty." + elif [[ "$MM_DOMAIN" == *" "* ]]; then + warn "Domain cannot contain spaces." + else + break + fi + done + + # Email for SSL + while true; do + read -rp " Enter your email (for Let's Encrypt SSL certificate): " MM_EMAIL + if [[ -z "$MM_EMAIL" ]]; then + warn "Email cannot be empty." + elif [[ "$MM_EMAIL" != *"@"* ]]; then + warn "Please enter a valid email address." + else + break + fi + done + + # Internal port + read -rp " Internal proxy port [8000]: " MM_PORT + MM_PORT=${MM_PORT:-8000} + + # Install directory + read -rp " Installation directory [~/mattermost-docker]: " INSTALL_DIR + INSTALL_DIR=${INSTALL_DIR:-"$HOME/mattermost-docker"} + # Expand tilde + INSTALL_DIR="${INSTALL_DIR/#\~/$HOME}" + + echo "" + echo -e "${BOLD} Summary:${NC}" + echo " Domain: https://${MM_DOMAIN}" + echo " Email: ${MM_EMAIL}" + echo " Port: 127.0.0.1:${MM_PORT} → :8065" + echo " Directory: ${INSTALL_DIR}" + echo "" + read -rp " Proceed? (Y/n): " confirm + [[ "$confirm" =~ ^[Nn]$ ]] && { info "Aborted."; exit 0; } +} + +# ── Install dependencies ──────────────────────────────────────────────────── +install_deps() { + echo "" + echo -e "${BOLD}Step 2: Installing dependencies${NC}" + echo "" + + info "Updating package index..." + apt-get update -qq + + # Docker + if command -v docker &>/dev/null; then + success "Docker already installed: $(docker --version)" + else + info "Installing Docker..." + apt-get install -y -qq ca-certificates curl gnupg lsb-release + install -m 0755 -d /etc/apt/keyrings + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg 2>/dev/null || true + chmod a+r /etc/apt/keyrings/docker.gpg + echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + tee /etc/apt/sources.list.d/docker.list > /dev/null + apt-get update -qq + apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + success "Docker installed." + fi + + # Docker Compose (detect v2 plugin vs v1 standalone) + if docker compose version &>/dev/null; then + COMPOSE_CMD="docker compose" + success "Docker Compose (v2 plugin) available." + elif command -v docker-compose &>/dev/null; then + COMPOSE_CMD="docker-compose" + success "Docker Compose (v1 standalone) available." + else + info "Installing Docker Compose plugin..." + apt-get install -y -qq docker-compose-plugin + COMPOSE_CMD="docker compose" + success "Docker Compose installed." + fi + + # Nginx + if command -v nginx &>/dev/null; then + success "Nginx already installed." + else + info "Installing Nginx..." + apt-get install -y -qq nginx + systemctl enable nginx + systemctl start nginx + success "Nginx installed and started." + fi + + # Certbot + if command -v certbot &>/dev/null; then + success "Certbot already installed." + else + info "Installing Certbot..." + apt-get install -y -qq certbot python3-certbot-nginx + success "Certbot installed." + fi + + # UFW (optional — configure if present) + if command -v ufw &>/dev/null; then + info "Configuring firewall (UFW)..." + ufw allow 'Nginx Full' >/dev/null 2>&1 || true + ufw allow OpenSSH >/dev/null 2>&1 || true + success "Firewall rules updated." + fi + + success "All dependencies ready." +} + +# ── Generate secure password ──────────────────────────────────────────────── +generate_password() { + openssl rand -base64 24 | tr -d '/+=' | head -c 32 +} + +# ── Create Docker stack ────────────────────────────────────────────────────── +create_docker_stack() { + echo "" + echo -e "${BOLD}Step 3: Creating Docker stack${NC}" + echo "" + + DB_PASS=$(generate_password) + + mkdir -p "${INSTALL_DIR}" + + cat > "${INSTALL_DIR}/docker-compose.yml" < "${INSTALL_DIR}/.env" < "${NGINX_CONF}" </dev/null || true + + nginx -t || fail "Nginx configuration test failed!" + systemctl reload nginx + + success "Nginx proxy configured for ${MM_DOMAIN}" +} + +# ── Obtain SSL certificate ─────────────────────────────────────────────────── +obtain_ssl() { + echo "" + echo -e "${BOLD}Step 5: Obtaining SSL certificate${NC}" + echo "" + + info "Requesting Let's Encrypt certificate for ${MM_DOMAIN}..." + info "Make sure your DNS A record points to this server's IP!" + echo "" + + certbot --nginx \ + -d "${MM_DOMAIN}" \ + --non-interactive \ + --agree-tos \ + --email "${MM_EMAIL}" \ + --redirect \ + || { + warn "Certbot failed. This usually means:" + warn " 1. DNS is not yet pointing to this server" + warn " 2. Ports 80/443 are blocked by a firewall" + warn "" + warn "You can retry later with:" + warn " sudo certbot --nginx -d ${MM_DOMAIN}" + warn "" + warn "Continuing without SSL..." + } + + success "SSL certificate obtained (or skipped)." +} + +# ── Start the stack ────────────────────────────────────────────────────────── +start_stack() { + echo "" + echo -e "${BOLD}Step 6: Starting Mattermost${NC}" + echo "" + + info "Pulling Docker images (this may take a few minutes)..." + cd "${INSTALL_DIR}" + $COMPOSE_CMD pull + + info "Starting containers..." + $COMPOSE_CMD up -d + + # Wait for Mattermost to boot + info "Waiting for Mattermost to start (up to 60s)..." + for i in $(seq 1 12); do + if curl -sI "http://127.0.0.1:${MM_PORT}" >/dev/null 2>&1; then + success "Mattermost is responding on port ${MM_PORT}!" + break + fi + sleep 5 + done + + # Show container status + echo "" + $COMPOSE_CMD ps + echo "" +} + +# ── Print summary ─────────────────────────────────────────────────────────── +print_summary() { + echo "" + echo -e "${BOLD}${GREEN}" + echo " ┌──────────────────────────────────────────────┐" + echo " │ ✅ Installation Complete! ✅ │" + echo " └──────────────────────────────────────────────┘" + echo -e "${NC}" + echo "" + echo -e "${BOLD} Access your Mattermost:${NC}" + echo " 🌐 https://${MM_DOMAIN}" + echo "" + echo -e "${BOLD} Internal (localhost) access:${NC}" + echo " 📡 http://127.0.0.1:${MM_PORT}" + echo "" + echo -e "${BOLD} Credentials:${NC}" + echo " 📄 ${INSTALL_DIR}/.env" + echo "" + echo -e "${BOLD} Management commands:${NC}" + echo " Start: cd ${INSTALL_DIR} && ${COMPOSE_CMD} up -d" + echo " Stop: cd ${INSTALL_DIR} && ${COMPOSE_CMD} down" + echo " Logs: cd ${INSTALL_DIR} && ${COMPOSE_CMD} logs -f" + echo " Status: cd ${INSTALL_DIR} && ${COMPOSE_CMD} ps" + echo "" + echo -e "${BOLD}${CYAN} ── OpenClaw Integration ──${NC}" + echo "" + echo " 1. Create a Bot Account in Mattermost:" + echo " System Console → Integrations → Bot Accounts → Add Bot" + echo " (Enable bot creation first, grant 'post:all')" + echo "" + echo " 2. Configure OpenClaw to connect:" + echo -e " ${YELLOW}openclaw config set channels.mattermost.accounts.default.baseUrl \"https://${MM_DOMAIN}\"${NC}" + echo -e " ${YELLOW}openclaw config set channels.mattermost.accounts.default.botToken \"\"${NC}" + echo "" + echo " OpenClaw will connect to Mattermost internally via localhost:${MM_PORT}" + echo " for maximum speed and security. 🦞" + echo "" +} + +# ── Main ───────────────────────────────────────────────────────────────────── +main() { + banner + preflight + gather_input + install_deps + create_docker_stack + configure_nginx + obtain_ssl + start_stack + print_summary +} + +main "$@"