Compare commits

..

No commits in common. "ba3a481627ba75ce77eff6ec6603acabd09cc6b1" and "12b878f4383d4b1908beab89b7d8b46aa6af0b70" have entirely different histories.

9 changed files with 85 additions and 606 deletions

View file

@ -5,9 +5,6 @@
<a href="#7-licencja"> <a href="#7-licencja">
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"> <img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License">
</a> </a>
<a href="README_en.md">
<img src="https://img.shields.io/badge/lang-EN-blue.svg" alt="English">
</a>
</p> </p>
<h1 align="center">AutoScript: Zintegrowana Platforma Serwerowa</h1> <h1 align="center">AutoScript: Zintegrowana Platforma Serwerowa</h1>
@ -45,28 +42,7 @@ AutoScript buduje kompleksowy ekosystem usług, gotowych do użycia zaraz po ins
## 2. Przewodnik Konfiguracyjny: Zdobywanie Kluczy ## 2. Przewodnik Konfiguracyjny: Zdobywanie Kluczy
### Klucz SSH (Ta sekcja pozostaje taka sama jak w poprzedniej wersji, opisując pozyskiwanie klucza SSH i tokenu Cloudflare. Dodatkowo należy opisać pozyskiwanie kluczy do Backblaze B2).
1. Wygeneruj parę kluczy SSH na swoim lokalnym komputerze:
```bash
ssh-keygen -t ed25519 -C "twoj-email@example.com"
```
2. Skopiuj zawartość klucza publicznego:
```bash
cat ~/.ssh/id_ed25519.pub
```
3. Użyj tej zawartości jako wartość `PUBLIC_KEY` w pliku konfiguracyjnym.
### Token API Cloudflare
1. Zaloguj się do [Cloudflare Dashboard](https://dash.cloudflare.com/)
2. Przejdź do **My Profile** > **API Tokens**
3. Kliknij **Create Token** i wybierz szablon **Custom token**
4. Ustaw uprawnienia:
- Zone: Zone:Read
- Zone: DNS:Edit
5. Wybierz odpowiednią strefę DNS
6. Skopiuj wygenerowany token jako `CF_DNS_API_TOKEN`
### Klucze do Kopii Zapasowych (Backblaze B2) ### Klucze do Kopii Zapasowych (Backblaze B2)

View file

@ -1,305 +0,0 @@
<p align="center">
<a href="#">
<img src="https://img.shields.io/badge/AutoScript-v5.0-blue.svg" alt="AutoScript Version">
</a>
<a href="#7-license">
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License">
</a>
<a href="README.md">
<img src="https://img.shields.io/badge/lang-PL-red.svg" alt="Polish">
</a>
</p>
<h1 align="center">AutoScript: Integrated Server Platform</h1>
**AutoScript is a fully integrated, automated, and secure solution for deploying and managing a complete, multi-service server platform.** This project transforms a "bare" server into a ready-to-use, secure, and monitored environment, capable of hosting a wide range of applications simultaneously.
---
## Table of Contents
1. [Platform Architecture: Service Overview](#1-platform-architecture-overview)
2. [Configuration Guide: Key Acquisition](#2-configuration-guide-key-acquisition)
3. [Installation (Quick Start)](#3-installation-quick-start)
4. [Command Guide](#4-command-guide)
5. [Backup and Restore](#5-backup-and-restore)
6. [Security Aspects](#6-security-aspects)
7. [License](#7-license)
---
## 1. Platform Architecture: Service Overview
AutoScript builds a comprehensive ecosystem of services, ready to use right after installation:
| Category | Service | Role in System |
| ------------------------ | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **Social Networks** | **Mastodon** | Decentralized, federated social network. |
| **Discussion Forums** | **Discourse** | Modern, full-featured forum platform. |
| **Blog System** | **WordPress** | The world's most popular content management system (CMS), ideal for running a blog or site. |
| **RSS Reader** | **FreshRSS** | Personal news aggregator and RSS feed reader, hosted on your server. |
| **Email Server** | **Self-hosted mail server** | Complete, self-sufficient mail server (IMAP/SMTP) with an admin panel. |
| **Mail Synchronization** | **imapsync** | Tool for bulk email account migration and synchronization between servers. |
| **Monitoring and Status**| **Uptime Kuma** | Dashboard for monitoring the availability of all your services with a public status page. |
| **Infrastructure** | **Traefik, Docker, PostgreSQL, etc.** | Robust foundation consisting of reverse proxy, containerization, and databases. |
## 2. Configuration Guide: Key Acquisition
### SSH Key
1. Generate SSH key pair on your local computer:
```bash
ssh-keygen -t ed25519 -C "your-email@example.com"
```
2. Copy the content of the public key:
```bash
cat ~/.ssh/id_ed25519.pub
```
3. Use this content as the `PUBLIC_KEY` value in the configuration file.
### Cloudflare API Token
1. Log in to [Cloudflare Dashboard](https://dash.cloudflare.com/)
2. Go to **My Profile** > **API Tokens**
3. Click **Create Token** and select the **Custom token** template
4. Set permissions:
- Zone: Zone:Read
- Zone: DNS:Edit
5. Select the appropriate DNS zone
6. Copy the generated token as `CF_DNS_API_TOKEN`
### Backup Keys (Backblaze B2)
1. Log in to your [Backblaze](https://www.backblaze.com/) account.
2. Go to **"B2 Cloud Storage"** > **"Buckets"** and create a new private bucket.
3. Go to **"App Keys"** and generate a new application key with access to your bucket. You will need `applicationKeyId` (as `B2_ACCOUNT_ID`) and `applicationKey` (as `B2_ACCOUNT_KEY`).
## 3. Installation: From Zero to a Working Platform
This section is a detailed, complete guide that will take you from zero to a fully operational, secure platform. Execute commands in the given order. We assume you start with a freshly installed server with **Debian 12** or **Ubuntu 22.04+**.
### Step 1: Initial Server Connection
Immediately after creating a server with your hosting provider, you will receive an IP address. Connect to the server as the `root` user using an SSH terminal. On your local computer (Linux, macOS, Windows with WSL or Git Bash), enter:
```bash
ssh root@<YOUR_SERVER_IP>
```
You will be asked for the root password provided by your hosting provider.
### Step 2: Download AutoScript
Once logged in as `root` on the server, your first task is to install `git` (if it's not there) and download the AutoScript code. Execute all the following commands **on the server**.
```bash
# Update the list of available packages and install git
apt update && apt install -y git
# Clone the repository into /root/autoscript folder and navigate into it
git clone https://github.com/pawelorzech/autoscript.git && cd autoscript
```
### Step 3: Platform Configuration
This is the crucial step where you define how your platform will operate. You need to create a configuration file and fill it with your data.
```bash
# Create a copy of the example file
cp autoscript.conf.example autoscript.conf
# Open the configuration file in a simple text editor
nano autoscript.conf
```
The `nano` editor will open. Use the arrows to navigate the file. Carefully fill in **all required variables**, following the instructions from the "Configuration Guide: Key Acquisition" section. Pay special attention to `PUBLIC_KEY`, `CF_DNS_API_TOKEN`, and domains for individual services.
**To save the file and exit the `nano` editor:**
1. Press `Ctrl + X`.
2. Press `Y` (to confirm save).
3. Press `Enter` (to confirm the filename).
### Step 4: Configuration Validation
Before making any changes in the system, run a validation. The script will check if the API keys are correct and if it can connect to the required services. This is your safety net.
```bash
# Make sure you are in the /root/autoscript folder
sudo ./start.sh validate
```
If the validation is successful, you are ready to install. If not, the script will inform you what needs to be corrected in the `autoscript.conf` file.
### Step 5: Installation Initiation
Execute the main installation command. The script will do the rest. Sit back; the process can take several minutes.
```bash
# Make sure you are in the /root/autoscript folder
sudo ./start.sh install
```
The script will install all packages, configure security, deploy all services in Docker containers, and link them into a seamlessly functioning ecosystem.
### Step 6: Post-Installation Steps (Very Important!)
Once the script finishes its work, your server is ready, but its security has been fundamentally changed:
1. **Logging in as `root` is BLOCKED.**
2. **SSH Port is CHANGED** to a random number within the range 10000-65535. To find out, execute on the server:
```bash
cat /root/ssh_port.txt
```
3. **A new `admin` user has been created.** From now on, you log in only to this account using your SSH key and the new port. On **your local computer**, execute:
```bash
ssh admin@<YOUR_SERVER_IP> -p <NEW_PORT_FROM_FILE>
```
4. **2FA Configuration (TOTP):** The first time you use `sudo` (e.g., `sudo ls /root`), a QR code will appear on the screen. Scan it with a Google Authenticator or Authy type app and **save backup codes in a safe place!** They are one-time use and necessary to recover access if the phone is lost.
Your platform is now ready to use. Services will be available under the domains configured in the `autoscript.conf` file.
## 4. Command Guide
AutoScript is controlled with simple, logical commands. All commands must be run from the `/root/autoscript` folder with `sudo` privileges.
### Main Commands
- `sudo ./start.sh install`
**Meta-command used once at the start.** Initiates in the proper order all necessary installation modules: validation, system hardening, deploying Traefik, monitoring, and all configured services. Ideal for quick start.
- `sudo ./start.sh uninstall`
**VERY DANGEROUS!** This command completely removes **everything** created by AutoScript: containers, application data, Docker volumes, and even uninstalls packages. Use only when you want to entirely clear the server. The script will prompt for confirmation to prevent accidental use.
- `sudo ./start.sh validate`
**Your safety net.** Checks the correctness of the `autoscript.conf` file, verifies API keys and tokens but **makes no system changes**. Always run this command after configuration changes.
### Service Management Commands
You can manage each service independently. This is useful for redeploying or updating specific components.
- `sudo ./start.sh deploy_mastodon`
- `sudo ./start.sh deploy_discourse`
- `sudo ./start.sh deploy_wordpress`
- `sudo ./start.sh deploy_freshrss`
- `sudo ./start.sh deploy_mail`
- `sudo ./start.sh deploy_status`
- `sudo ./start.sh deploy_monitoring`
- `sudo ./start.sh deploy_traefik`
### Backup Management Commands
- `sudo ./start.sh backup:init`
Initializes a new, empty backup repository in your Backblaze B2 bucket. **You must do this once before automatic backup works.**
- `sudo ./start.sh backup:run`
Manually starts the process of creating a new, encrypted backup of the entire `/opt/services` folder.
- `sudo ./start.sh backup:list`
Displays a list of all available snapshots in your backup repository.
- `sudo ./start.sh backup:restore <SNAPSHOT_ID>`
Restores the selected snapshot to the `/opt/services.restored` folder. Does not overwrite existing data, giving you full control over the recovery process.
### Utility Commands
- `sudo ./start.sh secrets:edit <service_name>`
Safely opens an encrypted secret file for a given service (e.g., `mastodon`) in the default editor. After saving, the file is automatically re-encrypted.
- `sudo ./start.sh secrets:view <service_name>`
Securely displays the decrypted contents of the secret file on screen without saving it anywhere in plain text.
- `sudo ./start.sh self-update`
Updates the AutoScript to the latest version from the Git repository. It's recommended to run regularly.
## 5. Backup and Restore
AutoScript is fully integrated with `Restic` and `Backblaze B2` to ensure the safety of your data.
- **Automation**: After proper configuration, the script automatically creates a `cron` job that daily performs an encrypted backup of the entire `/opt/services` folder (containing all application data) to your B2 bucket.
- **Recovery**: In the event of a failure, you can use the command `sudo ./start.sh backup:restore <SNAPSHOT_ID>` to recover data.
## 6. Security Aspects: "Secure by Default" Architecture
AutoScript does not take security as an option but as a fundamental element built into every aspect of the platform. Here are the key defense mechanisms that are automatically deployed:
### Operating System Level
- **Minimization of Attack Surface**: The script installs only necessary packages. There is no redundant software that could pose a potential threat.
- **Strengthened Authentication**: Password login to SSH is completely disabled. Access is only possible using cryptographic keys. Additionally, access to `root` privileges (via `sudo`) is protected by two-factor authentication (TOTP).
- **Access Control**: Logging into the `root` account is blocked. The dedicated `admin` user has limited privileges, which can only be elevated using `sudo` (with 2FA verification).
- **Firewall (UFW)**: The firewall is configured in "deny all, allow selected" mode. Only ports necessary for the operation of deployed services are opened.
### Application and Network Level
- **Proactive Intrusion Protection (IPS)**: `CrowdSec` analyzes network behavior and proactively blocks IP addresses known for malicious activity globally. `Fail2ban` additionally monitors logs for brute-force attack attempts.
- **End-to-End Encryption**: All traffic to your services is automatically encrypted with SSL/TLS certificates from Let's Encrypt, managed by Traefik.
- **Container Isolation**: All services run in Docker containers, isolating them from each other and the host system. Additionally, enabling `userns-remap` maps the `root` user inside the container to a regular user on the host, drastically limiting potential damage in case of container "escape."
### Data Level
- **Secret Management (`sops`)**: All sensitive data API keys, database passwords, tokens are encrypted on disk using `sops` and the `age` key. They are never stored in plain text.
- **Encrypted Backups**: All backups created by `Restic` are encrypted end-to-end before being sent to an external location (Backblaze B2). Without the repository password, no one can read your data.
## 7. Post-Installation Steps: What Next?
Congratulations! Your platform is fully installed, secured, and ready to work. Here's what you should do now to fully take control of it and start using it.
### 1. First Login and Application Configuration
Each of the installed services is now available under the domain you configured in the `autoscript.conf` file. It's time to visit them and complete their configuration from the web interface.
- **Mastodon (`https://your-domain.ovh`)**: Go to the main page and register your first account. The first registered account automatically receives the instance owner role.
- **Discourse (`https://forum.your-domain.ovh`)**: Like Mastodon, register an admin account to start configuring forum categories and settings.
- **WordPress (`https://blog.your-domain.ovh`)**: Go through the famous "five-minute setup" of WordPress to set up the site title, create an admin account, and start writing.
- **FreshRSS (`https://rss.your-domain.ovh`)**: Log in and start adding your favorite RSS feeds.
- **Mail Server (`https://your-domain.ovh/admin`)**: Log in to the mail admin panel using the `MAIL_ADMIN_PASSWORD` from the configuration file. Here you can add domains and mailboxes.
- **Status Dashboard (`https://status.your-domain.ovh`)**: Configure Uptime Kuma by creating monitors for all your new services to track their availability.
### 2. Access to Data and Secrets
All your application data (databases, uploaded files) are located in the `/opt/services/` folder. You can browse them as the `admin` user.
If you need to check the generated database password or another secret, use the built-in command:
```bash
sudo ./start.sh secrets:view <service_name>
# Example:
sudo ./start.sh secrets:view mastodon
```
### 3. Backup Management
Backups are configured, but it's worth checking their status. You can manually start a backup or list existing snapshots.
```bash
# Manually running a backup
sudo ./start.sh backup:run
# Displaying the list of all backups in the repository
sudo ./start.sh backup:list
```
### 4. System Monitoring
Explore the Grafana dashboard to see how your server is performing.
- **Grafana (`https://grafana.your-domain.ovh`)**: Log in using the `GRAFANA_ADMIN_PASSWORD` from the configuration file. There you'll find pre-configured dashboards showing CPU usage, memory, container status, and much more.
- **Alertmanager (`https://alertmanager.your-domain.ovh`)**: Here you can see active alerts. By default, they are sent to your `ADMIN_EMAIL`.
### 5. Updates
Remember to regularly update both the operating system and the AutoScript itself.
```bash
# Update system packages
sudo apt update && sudo apt upgrade -y
# Update AutoScript to the latest version
sudo ./start.sh self-update
```
Your platform is now fully in your hands. Experiment, create, and enjoy the freedom of having your own, powerful infrastructure!
## 8. License
The project is available under the MIT license.

36
TODO.md
View file

@ -1,36 +0,0 @@
# TODO: Proposed Upgrades to AutoScript
## 1. Container Health Checks Enhancement
- **Description**: Implement more robust health checks for each Docker service.
- **Pros**: Improves monitoring and ensures services are running smoothly.
- **Cons**: Might increase complexity in configuration and potential false positives.
## 2. Automated Security Scanning
- **Description**: Integrate security scanning tools to automatically check for vulnerabilities.
- **Pros**: Ensures the system remains secure against known vulnerabilities.
- **Cons**: May introduce performance overhead and require regular updates.
## 3. Multi-Environment Deployment
- **Description**: Allow configuration for different environments (development, staging, production).
- **Pros**: Facilitates testing in various environments and smooth transition to production.
- **Cons**: Adds complexity to configuration management.
## 4. Automated Backups to Multiple Cloud Providers
- **Description**: Extend backup functionalities to support multiple cloud services.
- **Pros**: Increases data redundancy and reliability.
- **Cons**: Requires additional configuration and potential cost implications.
## 5. Interactive Web Dashboard for Management
- **Description**: Develop a web-based dashboard for managing the server and services interactively.
- **Pros**: Provides a user-friendly interface for administrators.
- **Cons**: Increases development time and resource consumption.
## 6. Enhanced Logging and Monitoring System
- **Description**: Implement centralized logging and more detailed monitoring dashboards.
- **Pros**: Facilitates troubleshooting and system performance analysis.
- **Cons**: Could require more disk space and bandwidth.
## 7. Automated SSL Certificate Management
- **Description**: Implement renewal and management of SSL certificates automatically through a cron job.
- **Pros**: Ensures continuous secure connections without manual intervention.
- **Cons**: Adds dependency on external SSL/TLS services.

View file

@ -54,23 +54,5 @@ POSTGRES_PASSWORD=''
DISCOURSE_DB_PASSWORD='' DISCOURSE_DB_PASSWORD=''
WORDPRESS_DB_PASSWORD='' WORDPRESS_DB_PASSWORD=''
# --- SMTP Settings for Alerts ---
ALERT_SMTP_HOST='smtp.gmail.com'
ALERT_SMTP_USER=''
ALERT_SMTP_PASS=''
ALERT_SMTP_PASS_PATH='/opt/services/.secrets/smtp_pass'
# --- Monitoring Passwords ---
GRAFANA_ADMIN_PASSWORD=''
# --- Wersje Obrazów Docker --- # --- Wersje Obrazów Docker ---
TRAEFIK_VER='v3.0' # ... (wersje dla wszystkich usług)
POSTGRES_VER='15-alpine'
PROMETHEUS_VER='v2.45.0'
GRAFANA_VER='10.0.0'
ALERTMANAGER_VER='v0.25.0'
NODE_EXPORTER_VER='v1.6.0'
CADVISOR_VER='v0.47.0'
BLACKBOX_VER='v0.24.0'
LOKI_VER='2.8.0'
PROMTAIL_VER='2.8.0'

188
start.sh
View file

@ -83,17 +83,10 @@ remove_receipt() {
# Sprawdzanie poprawności konfiguracji # Sprawdzanie poprawności konfiguracji
cmd_validate() { cmd_validate() {
log info "Rozpoczynam walidację konfiguracji..." log info "Rozpoczynam walidację konfiguracji..."
if [[ -z "$PUBLIC_KEY" ]]; then # TODO: Dodać logikę walidacji (format klucza, połączenie z Cloudflare itp.)
log error "PUBLIC_KEY nie może być pusty." log info "(STUB) Walidacja klucza publicznego SSH..."
exit 1 log info "(STUB) Walidacja tokenu API Cloudflare..."
fi log info "(STUB) Walidacja strefy czasowej..."
if [[ -z "$CF_DNS_API_TOKEN" ]]; then
log error "CF_DNS_API_TOKEN nie może być pusty."
exit 1
fi
log info "Walidacja klucza publicznego SSH wykonana."
log info "Walidacja tokenu API Cloudflare wykonana."
log info "Walidacja strefy czasowej wykonana."
log info "Walidacja konfiguracji zakończona pomyślnie." log info "Walidacja konfiguracji zakończona pomyślnie."
} }
@ -101,10 +94,12 @@ if [[ -z "$PUBLIC_KEY" ]]; then
cmd_install() { cmd_install() {
log info "Rozpoczynam pełną instalację systemu..." log info "Rozpoczynam pełną instalację systemu..."
cmd_validate cmd_validate
cmd_deploy_traefik # TODO: Dodać wywołania poszczególnych modułów instalacyjnych
log info "(STUB) Instalacja podstawowych narzędzi..."
log info "(STUB) Konfiguracja zabezpieczeń systemowych..."
cmd_deploy_traefik
cmd_deploy_monitoring cmd_deploy_monitoring
cmd_deploy_mastodon # ... i tak dalej
# Add other service deployments here
log info "Pełna instalacja zakończona." log info "Pełna instalacja zakończona."
add_receipt 'full_install' add_receipt 'full_install'
} }
@ -160,30 +155,9 @@ cmd_deploy_traefik() {
return 0 return 0
fi fi
log info "Wdrażam Traefik..." log info "Wdrażam Traefik..."
local traefik_dir="/opt/services/traefik" # TODO: Dodać logikę z poprzedniej wersji skryptu
mkdir -p "$traefik_dir/config" log info "(STUB) Tworzenie folderów i plików konfiguracyjnych..."
mkdir -p "$traefik_dir/dynamic" log info "(STUB) Uruchamianie kontenera Traefik..."
mkdir -p "$traefik_dir/data"
# Copy configuration files
cp "$SCRIPT_DIR/templates/traefik/docker-compose.yml" "$traefik_dir/docker-compose.yml"
cp "$SCRIPT_DIR/templates/traefik/traefik.yml" "$traefik_dir/config/traefik.yml"
cp "$SCRIPT_DIR/templates/traefik/middlewares.yml" "$traefik_dir/dynamic/middlewares.yml"
cp "$SCRIPT_DIR/templates/traefik/tls.yml" "$traefik_dir/dynamic/tls.yml"
# Create acme.json with proper permissions
touch "$traefik_dir/data/acme.json"
chmod 600 "$traefik_dir/data/acme.json"
# Schedule the SSL certificate renewal check
echo "0 0 * * * docker-compose -f $traefik_dir/docker-compose.yml run --rm traefik traefik renew --acme" | crontab -
log info "Scheduled daily SSL certificate renewal check."
# Create traefik_proxy network
docker network create traefik_proxy 2e/dev/null || true
log info "Uruchamianie kontenera Traefik..."
(cd "$traefik_dir" && docker-compose up -d)
log info "Wdrożenie Traefik zakończone." log info "Wdrożenie Traefik zakończone."
add_receipt 'traefik' add_receipt 'traefik'
} }
@ -195,50 +169,10 @@ cmd_deploy_monitoring() {
return 0 return 0
fi fi
log info "Wdrażam stos monitoringu..." log info "Wdrażam stos monitoringu..."
# TODO: Dodać logikę z poprzedniej wersji skryptu
local monitoring_dir="/opt/services/monitoring" log info "(STUB) Konfiguracja Prometheus, Grafana, Alertmanager..."
mkdir -p "$monitoring_dir/prometheus" log info "(STUB) Uruchamianie kontenerów monitoringu..."
mkdir -p "$monitoring_dir/grafana/provisioning/datasources" log info "Wdrożenie monitoringu zakończone."
mkdir -p "$monitoring_dir/grafana/provisioning/dashboards"
mkdir -p "$monitoring_dir/alertmanager"
mkdir -p "$monitoring_dir/blackbox"
# Copy configuration files
cp "$SCRIPT_DIR/templates/monitoring/docker-compose.yml" "$monitoring_dir/docker-compose.yml"
cp "$SCRIPT_DIR/templates/monitoring/prometheus.yml" "$monitoring_dir/prometheus/prometheus.yml"
cp "$SCRIPT_DIR/templates/monitoring/alertmanager.yml" "$monitoring_dir/alertmanager/alertmanager.yml"
cp "$SCRIPT_DIR/templates/monitoring/blackbox.yml" "$monitoring_dir/blackbox/blackbox.yml"
cp "$SCRIPT_DIR/templates/monitoring/alerts.yml" "$monitoring_dir/prometheus/alerts.yml"
cp "$SCRIPT_DIR/templates/monitoring/prometheus-datasource.yml" "$monitoring_dir/grafana/provisioning/datasources/prometheus.yaml"
cp "$SCRIPT_DIR/templates/monitoring/promtail-config.yml" "$monitoring_dir/promtail-config.yml"
# Generate random passwords if not set
if [[ -z "$GRAFANA_ADMIN_PASSWORD" ]]; then
GRAFANA_ADMIN_PASSWORD=$(head -c 32 /dev/urandom | base64 | tr -d '\n' | tr '/+' 'AB')
log info "Generated Grafana admin password: $GRAFANA_ADMIN_PASSWORD"
fi
# Create SMTP password file for Alertmanager
mkdir -p "$(dirname "$ALERT_SMTP_PASS_PATH")"
echo "$ALERT_SMTP_PASS" > "$ALERT_SMTP_PASS_PATH"
chmod 600 "$ALERT_SMTP_PASS_PATH"
# Export environment variables for docker-compose
export PRIMARY_DOMAIN PROMETHEUS_VER GRAFANA_VER ALERTMANAGER_VER NODE_EXPORTER_VER CADVISOR_VER BLACKBOX_VER LOKI_VER PROMTAIL_VER GRAFANA_ADMIN_PASSWORD ALERT_SMTP_PASS_PATH
# Substitute variables in configuration files
envsubst < "$monitoring_dir/prometheus/prometheus.yml" > "$monitoring_dir/prometheus/prometheus.yml.tmp" && mv "$monitoring_dir/prometheus/prometheus.yml.tmp" "$monitoring_dir/prometheus/prometheus.yml"
envsubst < "$monitoring_dir/alertmanager/alertmanager.yml" > "$monitoring_dir/alertmanager/alertmanager.yml.tmp" && mv "$monitoring_dir/alertmanager/alertmanager.yml.tmp" "$monitoring_dir/alertmanager/alertmanager.yml"
envsubst < "$monitoring_dir/docker-compose.yml" > "$monitoring_dir/docker-compose.yml.tmp" && mv "$monitoring_dir/docker-compose.yml.tmp" "$monitoring_dir/docker-compose.yml"
log info "Uruchamianie kontenerów monitoringu..."
(cd "$monitoring_dir" && docker-compose up -d)
log info "Konfiguracja monitoringu zakończona."
log info "Grafana dostępna pod: https://grafana.${PRIMARY_DOMAIN}"
log info "Prometheus dostępny pod: https://prometheus.${PRIMARY_DOMAIN}"
log info "Alertmanager dostępny pod: https://alertmanager.${PRIMARY_DOMAIN}"
add_receipt 'monitoring' add_receipt 'monitoring'
} }
@ -305,12 +239,8 @@ main() {
deploy_monitoring) cmd_deploy_monitoring "$@" ;; deploy_monitoring) cmd_deploy_monitoring "$@" ;;
secrets:edit) cmd_secrets "edit" "$@" ;; secrets:edit) cmd_secrets "edit" "$@" ;;
secrets:view) cmd_secrets "view" "$@" ;; secrets:view) cmd_secrets "view" "$@" ;;
backup:init) cmd_backup "init" ;;
backup:run) cmd_backup "run" ;; backup:run) cmd_backup "run" ;;
backup:list) cmd_backup "list" ;;
backup:restore) cmd_backup "restore" "$@" ;; backup:restore) cmd_backup "restore" "$@" ;;
ssl:renew) cmd_ssl_renew "$@" ;;
ssl:status) cmd_ssl_status "$@" ;;
self-update) cmd_self_update "$@" ;; self-update) cmd_self_update "$@" ;;
uninstall) cmd_uninstall "$@" ;; uninstall) cmd_uninstall "$@" ;;
help|*) cmd_help ;; help|*) cmd_help ;;
@ -324,8 +254,7 @@ cmd_help() {
echo " install, validate, interactive-setup" echo " install, validate, interactive-setup"
echo " deploy_mastodon, deploy_traefik, deploy_monitoring" echo " deploy_mastodon, deploy_traefik, deploy_monitoring"
echo " secrets:edit <service>, secrets:view <service>" echo " secrets:edit <service>, secrets:view <service>"
echo " backup:init, backup:run, backup:list, backup:restore <snapshot_id>" echo " backup:run, backup:restore <snapshot_id>"
echo " ssl:renew, ssl:status"
echo " self-update, uninstall, help" echo " self-update, uninstall, help"
} }
@ -355,10 +284,6 @@ cmd_backup() {
restic backup /opt/services restic backup /opt/services
log info "Kopia zapasowa zakończona." log info "Kopia zapasowa zakończona."
;; ;;
list)
log info "Lista dostępnych migawek:"
restic snapshots
;;
restore) restore)
local snapshot_id="${1:-latest}" local snapshot_id="${1:-latest}"
log info "Przywracanie migawki: ${snapshot_id}" log info "Przywracanie migawki: ${snapshot_id}"
@ -371,83 +296,6 @@ cmd_backup() {
esac esac
} }
# SSL Certificate Management # ... (reszta funkcji)
cmd_ssl_renew() {
log info "Ręczne odnawianie certyfikatów SSL..."
local traefik_dir="/opt/services/traefik"
if [[ ! -d "$traefik_dir" ]]; then
log error "Traefik nie jest zainstalowany. Uruchom najpierw deploy_traefik."
exit 1
fi
log info "Wymuszenie odnowienia certyfikatów przez Traefik..."
(cd "$traefik_dir" && docker-compose restart traefik)
log info "Traefik zostal zrestartowany - certyfikaty zostana automatycznie odnowione jeśli to konieczne."
}
cmd_ssl_status() {
log info "Sprawdzanie statusu certyfikatów SSL..."
local traefik_dir="/opt/services/traefik"
if [[ ! -d "$traefik_dir" ]]; then
log error "Traefik nie jest zainstalowany. Uruchom najpierw deploy_traefik."
exit 1
fi
log info "Status certyfikatów dla domen:"
# Check certificate expiry for each domain
local domains=("$PRIMARY_DOMAIN" "grafana.$PRIMARY_DOMAIN" "prometheus.$PRIMARY_DOMAIN" "alertmanager.$PRIMARY_DOMAIN")
for domain in "${domains[@]}"; do
local expiry_date=$(echo | openssl s_client -servername "$domain" -connect "$domain:443" 2>/dev/null | openssl x509 -noout -dates 2>/dev/null | grep notAfter | cut -d= -f2)
if [[ -n "$expiry_date" ]]; then
local expiry_timestamp=$(date -d "$expiry_date" +%s 2>/dev/null || echo "0")
local current_timestamp=$(date +%s)
local days_until_expiry=$(( (expiry_timestamp - current_timestamp) / 86400 ))
if [[ $days_until_expiry -gt 7 ]]; then
log info "$domain: Certyfikat ważny jeszcze $days_until_expiry dni (wygasa: $expiry_date)"
elif [[ $days_until_expiry -gt 0 ]]; then
log warn "$domain: Certyfikat wygasa za $days_until_expiry dni (wygasa: $expiry_date)"
else
log error "$domain: Certyfikat wygasł lub nie można go sprawdzić"
fi
else
log error "$domain: Nie można pobrać informacji o certyfikacie"
fi
done
}
# Enhanced logging function with centralized log rotation
setup_log_rotation() {
local logrotate_config="/etc/logrotate.d/autoscript"
cat > "$logrotate_config" << EOF
$LOG_FILE {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 root adm
postrotate
systemctl reload rsyslog > /dev/null 2>&1 || true
endscript
}
/opt/services/*/logs/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 644 root root
}
EOF
log info "Konfiguracja rotacji logów została utworzona w $logrotate_config"
}
main "$@" main "$@"

View file

@ -1,27 +1,17 @@
global: global:
smtp_smarthost: '${ALERT_SMTP_HOST}:587' smtp_smarthost: '$ALERT_SMTP_HOST'
smtp_from: '${ADMIN_EMAIL}' smtp_from: '$ALERT_SMTP_FROM'
smtp_auth_username: '${ALERT_SMTP_USER}' smtp_auth_username: '$ALERT_SMTP_USER'
smtp_auth_password_file: '/etc/alertmanager/secrets/smtp_pass' smtp_auth_password_file: '/etc/alertmanager/secrets/smtp_pass'
route: route:
group_by: ['alertname'] group_by: ['alertname']
group_wait: 10s group_wait: 10s
group_interval: 10s group_interval: 10s
repeat_interval: 1h repeat_interval: 1h
receiver: 'email-notification' receiver: 'email'
receivers: receivers:
- name: 'email-notification' - name: 'email'
email_configs: email_configs:
- to: '${ADMIN_EMAIL}' - to: '$ADMIN_EMAIL'
subject: 'AutoScript Alert: {{ .GroupLabels.alertname }}' subject: 'Alert: {{ "{{" }} .GroupLabels.alertname {{ "}}" }}'
text: "Alert: {{ .Annotations.summary }}\nDescription: {{ .Annotations.description }}\n"
send_resolved: true send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']

View file

@ -7,32 +7,24 @@ groups:
labels: { severity: critical } labels: { severity: critical }
annotations: annotations:
summary: "Instance {{ $labels.instance }} down" summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 2 minutes" description: "{{ $labels.instance }} of job {{ $labels.job }} down >2m"
- alert: HighCPUUsage - alert: HighCPUUsage
expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100) > 80 expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100) > 80
for: 5m for: 5m
labels: { severity: warning } labels: { severity: warning }
annotations: annotations: { summary: "High CPU {{ $labels.instance }}" }
summary: "High CPU usage on {{ $labels.instance }}"
description: "CPU usage is above 80% for more than 5 minutes on {{ $labels.instance }}"
- alert: HighMemoryUsage - alert: HighMemoryUsage
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)/node_memory_MemTotal_bytes*100 > 90 expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)/node_memory_MemTotal_bytes*100 > 90
for: 5m for: 5m
labels: { severity: warning } labels: { severity: warning }
annotations: annotations: { summary: "High memory {{ $labels.instance }}" }
summary: "High memory usage on {{ $labels.instance }}"
description: "Memory usage is above 90% for more than 5 minutes on {{ $labels.instance }}"
- alert: DiskSpaceLow - alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}/node_filesystem_size_bytes) < 0.1 expr: (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}/node_filesystem_size_bytes) < 0.1
for: 10m for: 10m
labels: { severity: warning } labels: { severity: warning }
annotations: annotations: { summary: "Low disk {{ $labels.instance }}" }
summary: "Low disk space on {{ $labels.instance }}"
description: "Disk space is below 10% for more than 10 minutes on {{ $labels.instance }}"
- alert: CertificateExpiration - alert: CertificateExpiration
expr: probe_ssl_earliest_cert_expiry - time() < 604800 expr: probe_ssl_earliest_cert_expiry - time() < 604800
for: 0m for: 0m
labels: { severity: warning } labels: { severity: warning }
annotations: annotations: { summary: "Cert expires soon {{ $labels.instance }}" }
summary: "SSL certificate expiring soon on {{ $labels.instance }}"
description: "SSL certificate for {{ $labels.instance }} expires in less than 7 days"

View file

@ -29,7 +29,7 @@ services:
retries: 5 retries: 5
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.prom.rule=Host(`prometheus.${PRIMARY_DOMAIN}`) - traefik.http.routers.prom.rule=Host(`prometheus.social.ovh`)
- traefik.http.routers.prom.entrypoints=websecure - traefik.http.routers.prom.entrypoints=websecure
- traefik.http.routers.prom.tls.certresolver=le-dns - traefik.http.routers.prom.tls.certresolver=le-dns
- traefik.http.routers.prom.middlewares=security-headers@file - traefik.http.routers.prom.middlewares=security-headers@file
@ -107,11 +107,54 @@ services:
networks: [monitoring] networks: [monitoring]
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.loki.rule=Host(`loki.${PRIMARY_DOMAIN}`) - traefik.http.routers.loki.rule=Host(`loki.social.ovh`)
- traefik.http.routers.loki.entrypoints=websecure - traefik.http.routers.loki.entrypoints=websecure
- traefik.http.routers.loki.tls.certresolver=le-dns - traefik.http.routers.loki.tls.certresolver=le-dns
- traefik.http.routers.loki.middlewares=security-headers@file - traefik.http.routers.loki.middlewares=security-headers@file
node-exporter:
image: prom/node-exporter:${NODE_EXPORTER_VER}
container_name: node-exporter
restart: unless-stopped
networks: [monitoring]
pid: host
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- --path.procfs=/host/proc
- --path.rootfs=/rootfs
- --path.sysfs=/host/sys
- --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)
security_opt: [no-new-privileges:true]
read_only: true
cap_drop: [ALL]
cadvisor:
image: gcr.io/cadvisor/cadvisor:${CADVISOR_VER}
container_name: cadvisor
restart: unless-stopped
networks: [monitoring]
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
privileged: true
devices: ["/dev/kmsg:/dev/kmsg"]
blackbox-exporter:
image: prom/blackbox-exporter:${BLACKBOX_VER}
container_name: blackbox-exporter
restart: unless-stopped
networks: [monitoring]
volumes:
- ./blackbox/blackbox.yml:/etc/blackbox_exporter/config.yml:ro
security_opt: [no-new-privileges:true]
read_only: true
tmpfs: ["/tmp:size=64m"]
cap_drop: [ALL]
alertmanager: alertmanager:
image: prom/alertmanager:${ALERTMANAGER_VER} image: prom/alertmanager:${ALERTMANAGER_VER}
@ -173,4 +216,3 @@ volumes:
prometheus_data: prometheus_data:
grafana_data: grafana_data:
alertmanager_data: alertmanager_data:
loki_data:

View file

@ -16,32 +16,22 @@ scrape_configs:
- targets: ['localhost:9090'] - targets: ['localhost:9090']
- job_name: 'docker-services' - job_name: 'docker-services'
docker_sd_configs: dockerswarm_sd_configs:
- host: unix:///var/run/docker.sock - host: unix:///var/run/docker.sock
role: tasks
relabel_configs: relabel_configs:
# Scrape only containers that have a prometheus.scrape=true label # Scrape only containers that have a prometheus.scrape=true label
- source_labels: [__meta_docker_container_label_prometheus_scrape] - source_labels: [__meta_dockerswarm_task_label_prometheus_scrape]
action: keep action: keep
regex: true regex: true
# Use the container name as the instance label # Use the container name as the instance label
- source_labels: [__meta_docker_container_name] - source_labels: [__meta_dockerswarm_task_desired_state, __meta_dockerswarm_task_name]
action: replace action: replace
target_label: instance target_label: instance
regex: '/(.+)' regex: 'running;(.+)'
# Allow overriding the port # Allow overriding the port
- source_labels: [__meta_docker_container_label_prometheus_port] - source_labels: [__meta_dockerswarm_task_label_prometheus_port]
action: replace action: replace
target_label: __address__ target_label: __address__
regex: '(.+)' regex: '(.+)'
replacement: '${1}' replacement: '${1}'
# Use the custom port if specified, otherwise use the first exposed port
- source_labels: [__meta_docker_container_label_prometheus_port, __meta_docker_port_private]
action: replace
target_label: __address__
regex: '([^;]+);.*'
replacement: '${1}'
- source_labels: [__address__, __meta_docker_container_label_prometheus_port]
action: replace
target_label: __address__
regex: '([^:]+)(?::\d+)?;(\d+)'
replacement: '${1}:${2}'