#!/bin/bash # Mattermost Deployment Script for Synology Reverse Proxy Setup # Uses local storage (no B2) and external PostgreSQL echo "==============================================" echo "Mattermost Production Deployment (Synology)" echo "Domain: mm.crista.love" echo "==============================================" # Variables - UPDATE THESE SMTP_HOST="${SMTP_HOST:-smtp.gmail.com}" SMTP_PORT="${SMTP_PORT:-587}" SMTP_USER="${SMTP_USER:-your-email@example.com}" SMTP_PASS="REDACTED_PASSWORD" DB_PASSWORD="REDACTED_PASSWORD" SITE_URL="${SITE_URL:-https://mm.crista.love}" echo "=== Step 1: Install Docker ===" if ! command -v docker &> /dev/null; then curl -fsSL https://get.docker.com | sh systemctl enable docker systemctl start docker fi # Install docker compose plugin if needed apt-get update apt-get install -y docker-compose-plugin || true echo "=== Step 2: Install and configure PostgreSQL ===" if ! command -v psql &> /dev/null; then apt-get install -y postgresql postgresql-contrib systemctl enable postgresql systemctl start postgresql fi # Create database and user sudo -u postgres psql -c "CREATE USER mmuser WITH PASSWORD 'REDACTED_PASSWORD';" 2>/dev/null || true sudo -u postgres psql -c "CREATE DATABASE mattermost OWNER mmuser;" 2>/dev/null || true sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE mattermost TO mmuser;" 2>/dev/null || true # Configure PostgreSQL to accept Docker connections PG_HBA=$(find /etc/postgresql -name pg_hba.conf | head -1) PG_CONF=$(find /etc/postgresql -name postgresql.conf | head -1) if ! grep -q "172.17.0.0/16" "$PG_HBA"; then echo "# Docker networks for Mattermost" >> "$PG_HBA" echo "host mattermost mmuser 172.17.0.0/16 scram-sha-256" >> "$PG_HBA" echo "host mattermost mmuser 172.18.0.0/16 scram-sha-256" >> "$PG_HBA" echo "host mattermost mmuser 172.19.0.0/16 scram-sha-256" >> "$PG_HBA" fi # Configure PostgreSQL to listen on all interfaces if ! grep -q "listen_addresses = '\*'" "$PG_CONF"; then sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" "$PG_CONF" fi systemctl restart postgresql echo "=== Step 3: Create directory structure ===" mkdir -p /opt/mattermost/{config,data,logs,plugins,client-plugins,backups} echo "=== Step 4: Create environment file ===" cat > /opt/mattermost/.env << EOF MM_EMAILSETTINGS_SMTPPASSWORD="REDACTED_PASSWORD" EOF chmod 600 /opt/mattermost/.env echo "=== Step 5: Create Docker Compose file ===" # Get Docker bridge IP DOCKER_HOST_IP=$(ip -4 addr show docker0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}' || echo "172.17.0.1") cat > /opt/mattermost/docker-compose.yml << EOF services: mattermost: image: mattermost/mattermost-team-edition:11.3 container_name: mattermost restart: unless-stopped security_opt: - no-new-privileges:true pids_limit: 200 read_only: false tmpfs: - /tmp ports: - "8065:8065" environment: TZ: UTC MM_SQLSETTINGS_DRIVERNAME: postgres MM_SQLSETTINGS_DATASOURCE: "postgres://mmuser:${DB_PASSWORD}@${DOCKER_HOST_IP}:5432/mattermost?sslmode=disable&connect_timeout=10" MM_SERVICESETTINGS_SITEURL: ${SITE_URL} MM_SERVICESETTINGS_LISTENADDRESS: ":8065" MM_FILESETTINGS_DRIVERNAME: local MM_FILESETTINGS_DIRECTORY: /mattermost/data MM_LOGSETTINGS_CONSOLELEVEL: INFO MM_LOGSETTINGS_FILELEVEL: INFO MM_EMAILSETTINGS_ENABLESMTPAUTH: "true" MM_EMAILSETTINGS_SMTPSERVER: ${SMTP_HOST} MM_EMAILSETTINGS_SMTPPORT: "${SMTP_PORT}" MM_EMAILSETTINGS_CONNECTIONSECURITY: STARTTLS MM_EMAILSETTINGS_SMTPUSERNAME: ${SMTP_USER} MM_EMAILSETTINGS_FEEDBACKEMAIL: ${SMTP_USER} MM_EMAILSETTINGS_FEEDBACKNAME: Mattermost MM_EMAILSETTINGS_SENDEMAILNOTIFICATIONS: "true" MM_TEAMSETTINGS_ENABLEOPENSERVER: "true" MM_TEAMSETTINGS_MAXUSERSPERTEAM: "50" env_file: - .env volumes: - /opt/mattermost/config:/mattermost/config:rw - /opt/mattermost/data:/mattermost/data:rw - /opt/mattermost/logs:/mattermost/logs:rw - /opt/mattermost/plugins:/mattermost/plugins:rw - /opt/mattermost/client-plugins:/mattermost/client/plugins:rw healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8065/api/v4/system/ping"] interval: 30s timeout: 10s retries: 3 start_period: 60s extra_hosts: - "host.docker.internal:host-gateway" EOF echo "=== Step 6: Create backup script ===" cat > /opt/mattermost/backup.sh << 'BACKUP' #!/bin/bash BACKUP_DIR=/opt/mattermost/backups DATE=$(date +%Y%m%d_%H%M%S) sudo -u postgres pg_dump mattermost | gzip > $BACKUP_DIR/mattermost_db_$DATE.sql.gz tar -czf $BACKUP_DIR/mattermost_data_$DATE.tar.gz -C /opt/mattermost data config find $BACKUP_DIR -name "*.gz" -mtime +7 -delete echo "Backup completed: $DATE" BACKUP chmod +x /opt/mattermost/backup.sh echo "=== Step 7: Set up backup cron job ===" echo '0 3 * * * root /opt/mattermost/backup.sh >> /var/log/mattermost-backup.log 2>&1' > /etc/cron.d/mattermost-backup chmod 644 /etc/cron.d/mattermost-backup echo "=== Step 8: Start Mattermost ===" cd /opt/mattermost docker compose pull docker compose up -d echo "=== Step 9: Wait for Mattermost to be healthy ===" echo "Waiting for services to start..." sleep 30 MAX_ATTEMPTS=30 ATTEMPT=0 until curl -sf http://127.0.0.1:8065/api/v4/system/ping > /dev/null 2>&1; do ATTEMPT=$((ATTEMPT + 1)) if [ $ATTEMPT -ge $MAX_ATTEMPTS ]; then echo "Mattermost did not become healthy in time. Checking logs..." docker compose logs --tail=100 exit 1 fi echo "Waiting for Mattermost to be ready... (attempt $ATTEMPT/$MAX_ATTEMPTS)" sleep 5 done echo "Mattermost is healthy!" echo "==============================================" echo "Mattermost Deployment Complete!" echo "==============================================" echo "" echo "Mattermost is running on port 8065" echo "" echo "Configure your Synology Reverse Proxy:" echo " Source: HTTPS, mm.crista.love, port 443" echo " Destination: HTTP, , port 8065" echo "" echo "Backup schedule: Daily at 3 AM UTC" echo "Backups stored in: /opt/mattermost/backups/" echo "" echo "Useful commands:" echo " View logs: docker compose -f /opt/mattermost/docker-compose.yml logs -f" echo " Restart: docker compose -f /opt/mattermost/docker-compose.yml restart" echo " Manual backup: /opt/mattermost/backup.sh" echo "" docker compose ps