feat: systemd timery + skripty pro udrzbu serveru
Skripty (4): - update.sh: apt update + upgrade + restart kdyz nutny + Telegram - docker-update.sh: docker compose pull + up -d pro vsechny sluzby - docker-zalohy.sh: tar.zst zaloha data/ adresaru na NAS - server-report.sh: denni Telegram report (uptime, RAM, disk, Docker) Systemd (8 - 4x service + 4x timer): - docker-update: kazdou sobotu 18:00 - docker-zalohy: kazde utery 20:00 - server-report: kazdy den 09:30 - update-rpi: kazdy patek 18:00 Konfigurace: - conf/telegram.conf.example: sablona pro Telegram credentials - vsechny skripty ctou z /home/<user>/.telegram.conf (chmod 600) Poznamka: - vsechny cesty (/home/mates) a hostname jsou pevne v service souborech - pro jineho uzivatele uprav User=, WorkingDirectory=, ExecStart= - zadne IP adresy, tokeny ani PII v gitu
This commit is contained in:
+27
@@ -0,0 +1,27 @@
|
|||||||
|
# Secrets - nikdy v gitu
|
||||||
|
.env
|
||||||
|
*.env
|
||||||
|
!.env.example
|
||||||
|
!.env.example.conf
|
||||||
|
|
||||||
|
# Telegram credentials (citlive)
|
||||||
|
telegram.conf
|
||||||
|
*.telegram.conf
|
||||||
|
|
||||||
|
# Zálohy a dočasné soubory
|
||||||
|
*.bak
|
||||||
|
*.tmp
|
||||||
|
*.orig
|
||||||
|
*.log
|
||||||
|
*.tar.zst
|
||||||
|
*.tar.gz
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
# Editor a IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# Build artefakty
|
||||||
|
__pycache__/
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 mates
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
# mates-server-maintenance
|
||||||
|
|
||||||
|
Systemd timery a skripty pro automatickou údržbu serveru.
|
||||||
|
**Docker update, zálohy, denní report na Telegram, systémový update.**
|
||||||
|
|
||||||
|
> Toto repo je **1:1 kopie** systemd timerů a skriptů, které běží na produkčním serveru.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 Co tu je
|
||||||
|
|
||||||
|
```
|
||||||
|
mates-server-maintenance/
|
||||||
|
├── README.md # Tento soubor
|
||||||
|
├── LICENSE # MIT
|
||||||
|
├── .gitignore
|
||||||
|
├── scripts/
|
||||||
|
│ ├── update.sh # Systémový update + Telegram
|
||||||
|
│ ├── docker-update.sh # Docker compose pull + up
|
||||||
|
│ ├── docker-zalohy.sh # Záloha Docker dat
|
||||||
|
│ └── server-report.sh # Denní Telegram report
|
||||||
|
├── systemd/
|
||||||
|
│ ├── docker-update.{service,timer}
|
||||||
|
│ ├── docker-zalohy.{service,timer}
|
||||||
|
│ ├── server-report.{service,timer}
|
||||||
|
│ └── update-rpi.{service,timer}
|
||||||
|
└── conf/
|
||||||
|
└── telegram.conf.example # Šablona pro Telegram credentials
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Quickstart
|
||||||
|
|
||||||
|
### 1. Naklonuj
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone http://<server-ip>:3000/mates/mates-server-maintenance.git ~/server-maintenance
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Vytvoř Telegram konfiguraci
|
||||||
|
|
||||||
|
Získej **BOT_TOKEN** z [@BotFather](https://t.me/BotFather) a **CHAT_ID** z [@userinfobot](https://t.me/userinfobot):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.config/telegram
|
||||||
|
cp ~/server-maintenance/conf/telegram.conf.example ~/.telegram.conf
|
||||||
|
nano ~/.telegram.conf # doplň reálné hodnoty
|
||||||
|
chmod 600 ~/.telegram.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Nainstaluj systemd timery
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pro kazdy timer: nakopiruj service+timer do /etc/systemd/system
|
||||||
|
sudo cp ~/server-maintenance/systemd/*.{service,timer} /etc/systemd/system/
|
||||||
|
|
||||||
|
# Aktivuj (napr. docker-update)
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now docker-update.timer
|
||||||
|
sudo systemctl enable --now docker-zalohy.timer
|
||||||
|
sudo systemctl enable --now server-report.timer
|
||||||
|
sudo systemctl enable --now update-rpi.timer
|
||||||
|
|
||||||
|
# Over stav
|
||||||
|
systemctl list-timers --all | grep -E "docker|server-report|update"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Ověř
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Rucne spust report (melo by prijit Telegram zprava)
|
||||||
|
sudo systemctl start server-report.service
|
||||||
|
sudo journalctl -u server-report.service -f
|
||||||
|
|
||||||
|
# Rucne spust Docker update (melo by aktualizovat kontejnery)
|
||||||
|
sudo systemctl start docker-update.service
|
||||||
|
sudo journalctl -u docker-update.service -f
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⏰ Plán úloh (timery)
|
||||||
|
|
||||||
|
| Timer | Kdy | Co dělá |
|
||||||
|
|---|---|---|
|
||||||
|
| `update-rpi.timer` | **Pátek 18:00** | `apt update && apt upgrade`, restart když nutný |
|
||||||
|
| `docker-update.timer` | **Sobota 18:00** | `docker compose pull && up -d` pro všechny služby |
|
||||||
|
| `docker-zalohy.timer` | **Úterý 20:00** | Záloha `data/` adresářů na NAS |
|
||||||
|
| `server-report.timer` | **Denně 09:30** | Telegram report (uptime, RAM, disk, Docker, teplota) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Detail skriptů
|
||||||
|
|
||||||
|
### `update.sh`
|
||||||
|
|
||||||
|
Aktualizuje systém (`apt update && apt upgrade`).
|
||||||
|
|
||||||
|
- **Spustí:** `sudo bash update.sh` nebo přes timer `update-rpi.timer`
|
||||||
|
- **Restartuje server** pokud `/var/run/reboot-required` existuje (1 minuta grace time)
|
||||||
|
- **Telegram notifikace:** start, hotovo / chyba, varování před restartem
|
||||||
|
|
||||||
|
### `docker-update.sh`
|
||||||
|
|
||||||
|
Aktualizuje všechny Docker Compose projekty.
|
||||||
|
|
||||||
|
- **Seznam služeb:** edituj `AKTUALIZOVAT` pole v skriptu
|
||||||
|
- **Log:** `/home/mates/skripty/update-docker-script/docker-update.log`
|
||||||
|
- **Telegram:** start, souhrn (úspěch/chyby), seznam aktualizovaných
|
||||||
|
|
||||||
|
### `docker-zalohy.sh`
|
||||||
|
|
||||||
|
Zálohuje `data/` adresáře Docker projektů.
|
||||||
|
|
||||||
|
- **Formát:** `tar.zst` (vysoká komprese)
|
||||||
|
- **Cíl:** `/home/mates/zalohy/docker/<YYYYMMDD>/`
|
||||||
|
- **Log:** `/home/mates/zalohy/docker/docker.log`
|
||||||
|
|
||||||
|
### `server-report.sh`
|
||||||
|
|
||||||
|
Denní Telegram report o stavu serveru.
|
||||||
|
|
||||||
|
- **Co reportuje:** uptime, load, RAM, disk, CPU teplota, Docker kontejnery, poslední update/záloha
|
||||||
|
- **Alert prahy:** disk 80% (warn) / 90% (crit), CPU 70°C / 80°C
|
||||||
|
- **Kdy:** denně 09:30
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ Konfigurace
|
||||||
|
|
||||||
|
### Telegram credentials
|
||||||
|
|
||||||
|
Všechny skripty čtou z `/home/<user>/.telegram.conf`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
BOT_TOKEN=1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
|
||||||
|
CHAT_ID=123456789
|
||||||
|
```
|
||||||
|
|
||||||
|
`conf/telegram.conf.example` je šablona.
|
||||||
|
|
||||||
|
### Cesty (v systemd service souborech)
|
||||||
|
|
||||||
|
Pokud máš **jiného uživatele nebo cesty**, uprav `WorkingDirectory` a `ExecStart` v `systemd/*.service`:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Service]
|
||||||
|
User=tvy-user
|
||||||
|
WorkingDirectory=/home/tvy-user/skripty/update-docker-script
|
||||||
|
ExecStart=/home/tvy-user/skripty/update-docker-script/docker-update.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Seznam služeb k aktualizaci
|
||||||
|
|
||||||
|
V `scripts/docker-update.sh`, pole `AKTUALIZOVAT`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
AKTUALIZOVAT=(
|
||||||
|
audiobookshelf
|
||||||
|
calibre-web
|
||||||
|
vaultwarden
|
||||||
|
# pridej dalsi...
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 Bezpečnost
|
||||||
|
|
||||||
|
- ✅ **`/home/<user>/.telegram.conf` s `chmod 600`** – nikdy necommitovat reálný token
|
||||||
|
- ✅ **Service běží jako `User=mates`** – ne root (omezení škod v případě chyby)
|
||||||
|
- ✅ **`set -euo pipefail`** ve všech skriptech – fail-fast
|
||||||
|
- ✅ **Logy** – vše se loguje, snadné debugování
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Struktura na serveru
|
||||||
|
|
||||||
|
```
|
||||||
|
/home/mates/
|
||||||
|
├── .telegram.conf # Telegram credentials (chmod 600)
|
||||||
|
├── update.log # Log ze systemoveho update
|
||||||
|
├── docker/ # Docker projekty
|
||||||
|
├── skripty/
|
||||||
|
│ ├── server-report.sh # Tento skript
|
||||||
|
│ └── update-docker-script/
|
||||||
|
│ ├── docker-update.sh # Tento skript
|
||||||
|
│ └── docker-update.log # Log z Docker update
|
||||||
|
└── zalohy/
|
||||||
|
├── docker.log # Log ze zaloh
|
||||||
|
└── docker/
|
||||||
|
└── <YYYYMMDD>/ # Zalohy (tar.zst)
|
||||||
|
└── <sluzba>-<HHMMSS>.tar.zst
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Úprava schedule
|
||||||
|
|
||||||
|
Edituj `*.timer` soubory:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Timer]
|
||||||
|
# Kazdou nedeli v 02:00
|
||||||
|
OnCalendar=Sun *-*-* 02:00:00
|
||||||
|
# Kazdych 15 minut
|
||||||
|
OnCalendar=*:0/15
|
||||||
|
# Kazdy patek v 18:00 (puvodni)
|
||||||
|
OnCalendar=Fri *-*-* 18:00:00
|
||||||
|
```
|
||||||
|
|
||||||
|
Po úpravě: `sudo systemctl daemon-reload`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📜 Licence
|
||||||
|
|
||||||
|
MIT – viz [LICENSE](LICENSE)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Poslední update:** 2026-08-01
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Telegram bot konfigurace
|
||||||
|
# Ziskej z @BotFather na Telegramu: https://t.me/BotFather
|
||||||
|
# /newbot -> ti da BOT_TOKEN
|
||||||
|
# Napis botovi, pridej ho do skupiny, ziskej CHAT_ID pres @userinfobot
|
||||||
|
#
|
||||||
|
# Soubor umisti na:
|
||||||
|
# /home/<user>/.telegram.conf
|
||||||
|
# a nastav prava:
|
||||||
|
# chmod 600 /home/<user>/.telegram.conf
|
||||||
|
|
||||||
|
BOT_TOKEN=1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
|
||||||
|
CHAT_ID=123456789
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# docker-update.sh - aktualizace Docker Compose projektu na tomto serveru
|
||||||
|
# (docker compose pull + up -d) + Telegram notifikace.
|
||||||
|
#
|
||||||
|
# Spust jednou rucne: bash docker-update.sh
|
||||||
|
# Spust automaticky: systemd timer docker-update.timer (kazdou sobotu 18:00)
|
||||||
|
#
|
||||||
|
# Konfigurace: /home/mates/.telegram.conf
|
||||||
|
# Log: /home/mates/skripty/update-docker-script/docker-update.log
|
||||||
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# === KONFIGURACE ===
|
||||||
|
USER_NAME="mates"
|
||||||
|
WORK_DIR="/home/$USER_NAME"
|
||||||
|
ZAKLADNI_SLOZKA="$WORK_DIR/docker"
|
||||||
|
LOG="$WORK_DIR/skripty/update-docker-script/docker-update.log"
|
||||||
|
CONFIG_FILE="$WORK_DIR/.telegram.conf"
|
||||||
|
DATUM=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
HOST=$(hostname)
|
||||||
|
|
||||||
|
# Seznam sluzeb k aktualizaci (uprav podle potreby)
|
||||||
|
AKTUALIZOVAT=(
|
||||||
|
audiobookshelf
|
||||||
|
calibre-web
|
||||||
|
glance
|
||||||
|
homeassistant
|
||||||
|
jswiki
|
||||||
|
plex
|
||||||
|
portainer
|
||||||
|
rustdesk
|
||||||
|
speedtest
|
||||||
|
vaultwarden
|
||||||
|
nginx
|
||||||
|
)
|
||||||
|
|
||||||
|
# === TELEGRAM KONFIGURACE ===
|
||||||
|
if [[ -f "$CONFIG_FILE" ]]; then
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
TELEGRAM_BOT_TOKEN="${TELEGRAM_BOT_TOKEN:-}"
|
||||||
|
TELEGRAM_CHAT_ID="${TELEGRAM_CHAT_ID:-}"
|
||||||
|
|
||||||
|
# === TELEGRAM HELPER ===
|
||||||
|
send_msg() {
|
||||||
|
local TEXT="$1"
|
||||||
|
|
||||||
|
if [[ -z "$TELEGRAM_BOT_TOKEN" || -z "$TELEGRAM_CHAT_ID" ]]; then
|
||||||
|
echo "$DATUM ⚠️ Telegram neni nakonfigurovan, preskakuji" >> "$LOG"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
|
||||||
|
-d chat_id="${TELEGRAM_CHAT_ID}" \
|
||||||
|
-d text="$TEXT" \
|
||||||
|
-d parse_mode="Markdown" \
|
||||||
|
--max-time 10 \
|
||||||
|
--retry 3 > /dev/null || echo "$DATUM ⚠️ Telegram chyba" >> "$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
# === HLAVNI LOGIKA ===
|
||||||
|
echo "$DATUM === docker-update.sh spusten ===" >> "$LOG"
|
||||||
|
send_msg "🔄 *[$HOST]* Spoustim aktualizaci Docker kontejneru..."
|
||||||
|
|
||||||
|
# Vytvor log adresar pokud neexistuje
|
||||||
|
mkdir -p "$(dirname "$LOG")"
|
||||||
|
|
||||||
|
AKTUALIZOVANO=()
|
||||||
|
CHYBY=()
|
||||||
|
|
||||||
|
for SLUZBA in "${AKTUALIZOVAT[@]}"; do
|
||||||
|
SLUZBA_PATH="$ZAKLADNI_SLOZKA/$SLUZBA"
|
||||||
|
|
||||||
|
if [[ ! -d "$SLUZBA_PATH" ]]; then
|
||||||
|
echo "$DATUM SKIP: $SLUZBA (slozka neexistuje)" >> "$LOG"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$SLUZBA_PATH/docker-compose.yml" ]]; then
|
||||||
|
echo "$DATUM SKIP: $SLUZBA (docker-compose.yml chybi)" >> "$LOG"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$DATUM === Aktualizuji: $SLUZBA ===" >> "$LOG"
|
||||||
|
|
||||||
|
cd "$SLUZBA_PATH"
|
||||||
|
|
||||||
|
# Stahnout nove image
|
||||||
|
if docker compose pull 2>>"$LOG"; then
|
||||||
|
# Restart s novym image
|
||||||
|
if docker compose up -d 2>>"$LOG"; then
|
||||||
|
AKTUALIZOVANO+=("$SLUZBA")
|
||||||
|
echo "$DATUM OK: $SLUZBA aktualizovan" >> "$LOG"
|
||||||
|
else
|
||||||
|
CHYBY+=("$SLUZBA (up)")
|
||||||
|
echo "$DATUM CHYBA: $SLUZBA - up -d selhalo" >> "$LOG"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
CHYBY+=("$SLUZBA (pull)")
|
||||||
|
echo "$DATUM CHYBA: $SLUZBA - pull selhalo" >> "$LOG"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# === SOUHRN ===
|
||||||
|
POCET_OK=${#AKTUALIZOVANO[@]}
|
||||||
|
POCET_CHYB=${#CHYBY[@]}
|
||||||
|
|
||||||
|
if [[ $POCET_CHYB -eq 0 ]]; then
|
||||||
|
send_msg "✅ *[$HOST]* Docker aktualizace dokoncena.
|
||||||
|
Aktualizovano: $POCET_OK sluzeb
|
||||||
|
Seznam: ${AKTUALIZOVANO[*]}"
|
||||||
|
else
|
||||||
|
send_msg "⚠️ *[$HOST]* Docker aktualizace dokoncena s chybami.
|
||||||
|
Aktualizovano: $POCET_OK
|
||||||
|
Chyby: ${CHYBY[*]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$DATUM === docker-update.sh dokoncen ===" >> "$LOG"
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# docker-zalohy.sh - zaloha Docker Compose projektu a jejich dat (./data adresaru)
|
||||||
|
# na NAS (nebo jiny backup disk) + Telegram notifikace.
|
||||||
|
#
|
||||||
|
# Spust jednou rucne: bash docker-zalohy.sh
|
||||||
|
# Spust automaticky: systemd timer docker-zalohy.timer (kazde utery 20:00)
|
||||||
|
#
|
||||||
|
# Konfigurace: /home/mates/.telegram.conf
|
||||||
|
# Log: /home/mates/zalohy/docker/docker.log
|
||||||
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# === KONFIGURACE ===
|
||||||
|
USER_NAME="mates"
|
||||||
|
WORK_DIR="/home/$USER_NAME"
|
||||||
|
SOURCE_DIR="$WORK_DIR/docker"
|
||||||
|
BACKUP_DIR="$WORK_DIR/zalohy/docker"
|
||||||
|
LOG_FILE="$BACKUP_DIR/docker.log"
|
||||||
|
CONFIG_FILE="$WORK_DIR/.telegram.conf"
|
||||||
|
|
||||||
|
# Seznam sluzeb k zalohovani (uprav podle potreby)
|
||||||
|
APP_DIRS=(
|
||||||
|
audiobookshelf
|
||||||
|
calibre-web
|
||||||
|
flatnotes
|
||||||
|
homeassistant
|
||||||
|
jswiki
|
||||||
|
miniflux
|
||||||
|
nginx
|
||||||
|
plex
|
||||||
|
speedtest
|
||||||
|
vaultwarden
|
||||||
|
wiki
|
||||||
|
glance
|
||||||
|
)
|
||||||
|
|
||||||
|
DATE_DIR=$(date +"%Y%m%d")
|
||||||
|
TIMESTAMP=$(date +"%H%M%S")
|
||||||
|
HOST=$(hostname)
|
||||||
|
|
||||||
|
# === TELEGRAM KONFIGURACE ===
|
||||||
|
if [[ -f "$CONFIG_FILE" ]]; then
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
TELEGRAM_BOT_TOKEN="${TELEGRAM_BOT_TOKEN:-}"
|
||||||
|
TELEGRAM_CHAT_ID="${TELEGRAM_CHAT_ID:-}"
|
||||||
|
|
||||||
|
# === TELEGRAM HELPER ===
|
||||||
|
send_msg() {
|
||||||
|
local TEXT="$1"
|
||||||
|
|
||||||
|
if [[ -z "$TELEGRAM_BOT_TOKEN" || -z "$TELEGRAM_CHAT_ID" ]]; then
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Telegram neni nakonfigurovan, preskakuji" >> "$LOG_FILE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
|
||||||
|
-d chat_id="${TELEGRAM_CHAT_ID}" \
|
||||||
|
-d text="$TEXT" \
|
||||||
|
-d parse_mode="Markdown" \
|
||||||
|
--max-time 10 \
|
||||||
|
--retry 3 > /dev/null || echo "[$(date '+%Y-%m-%d %H:%M:%S')] ⚠️ Telegram chyba" >> "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# === HLAVNI LOGIKA ===
|
||||||
|
mkdir -p "$BACKUP_DIR/$DATE_DIR"
|
||||||
|
|
||||||
|
START_TIME=$(date +%s)
|
||||||
|
ZALOHOVANO=()
|
||||||
|
CHYBY=()
|
||||||
|
|
||||||
|
for APP in "${APP_DIRS[@]}"; do
|
||||||
|
APP_PATH="$SOURCE_DIR/$APP"
|
||||||
|
if [[ ! -d "$APP_PATH" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$APP_PATH"
|
||||||
|
|
||||||
|
# Pokud existuje data/ adresar, zalohuj ho
|
||||||
|
if [[ -d "./data" ]]; then
|
||||||
|
BACKUP_FILE="$BACKUP_DIR/$DATE_DIR/${APP}-${TIMESTAMP}.tar.zst"
|
||||||
|
|
||||||
|
if tar --zstd -cf "$BACKUP_FILE" -C "$APP_PATH" data 2>>"$LOG_FILE"; then
|
||||||
|
ZALOHOVANO+=("$APP ($(du -h "$BACKUP_FILE" | cut -f1))")
|
||||||
|
else
|
||||||
|
CHYBY+=("$APP")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
END_TIME=$(date +%s)
|
||||||
|
DURATION=$((END_TIME - START_TIME))
|
||||||
|
|
||||||
|
if [[ ${#CHYBY[@]} -eq 0 ]]; then
|
||||||
|
send_msg "✅ *[$HOST]* Docker zalohy dokonceny (${DURATION}s).
|
||||||
|
Zalohovano: ${#ZALOHOVANO[@]} sluzeb
|
||||||
|
Adresar: \`$BACKUP_DIR/$DATE_DIR\`"
|
||||||
|
else
|
||||||
|
send_msg "⚠️ *[$HOST]* Docker zalohy dokonceny s chybami.
|
||||||
|
Zalohovano: ${#ZALOHOVANO[@]}
|
||||||
|
Chyby: ${CHYBY[*]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# server-report.sh - denni report stavu serveru na Telegram.
|
||||||
|
# Obsahuje: uptime, load, RAM, disk, teplota CPU, Docker kontejnery,
|
||||||
|
# Docker update log, zalohy, sitovy traffic.
|
||||||
|
#
|
||||||
|
# Spust jednou rucne: bash server-report.sh
|
||||||
|
# Spust automaticky: systemd timer server-report.timer (kazdy den 09:30)
|
||||||
|
#
|
||||||
|
# Konfigurace: /home/mates/.telegram.conf
|
||||||
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# === KONFIGURACE ===
|
||||||
|
USER_NAME="mates"
|
||||||
|
WORK_DIR="/home/$USER_NAME"
|
||||||
|
CONFIG_FILE="$WORK_DIR/.telegram.conf"
|
||||||
|
DOCKER_ROOT="$WORK_DIR/docker"
|
||||||
|
DOCKER_UPDATE_LOG="$WORK_DIR/skripty/update-docker-script/docker-update.log"
|
||||||
|
DOCKER_BACKUP_DIR="$WORK_DIR/zalohy/docker"
|
||||||
|
HOST=$(hostname)
|
||||||
|
INTERFACE="eth0" # nastav podle sveho serveru
|
||||||
|
|
||||||
|
# Prahy pro upozorneni
|
||||||
|
DISK_WARN=80
|
||||||
|
DISK_CRIT=90
|
||||||
|
TEMP_WARN=70
|
||||||
|
TEMP_CRIT=80
|
||||||
|
|
||||||
|
# === TELEGRAM KONFIGURACE ===
|
||||||
|
if [[ -f "$CONFIG_FILE" ]]; then
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
TELEGRAM_BOT_TOKEN="${TELEGRAM_BOT_TOKEN:-}"
|
||||||
|
TELEGRAM_CHAT_ID="${TELEGRAM_CHAT_ID:-}"
|
||||||
|
|
||||||
|
send_msg() {
|
||||||
|
local TEXT="$1"
|
||||||
|
|
||||||
|
if [[ -z "$TELEGRAM_BOT_TOKEN" || -z "$TELEGRAM_CHAT_ID" ]]; then
|
||||||
|
echo "Telegram neni nakonfigurovan, preskakuji"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
|
||||||
|
-d chat_id="${TELEGRAM_CHAT_ID}" \
|
||||||
|
-d text="$TEXT" \
|
||||||
|
-d parse_mode="Markdown" \
|
||||||
|
--max-time 10 \
|
||||||
|
--retry 3 > /dev/null || echo "⚠️ Telegram chyba"
|
||||||
|
}
|
||||||
|
|
||||||
|
# === SYSTEMOVE STATISTIKY ===
|
||||||
|
UPTIME=$(uptime -p | sed 's/^up //')
|
||||||
|
LOAD=$(awk '{print $1" "$2" "$3}' /proc/loadavg)
|
||||||
|
RAM_USED=$(free -h | awk '/^Mem:/ {print $3}')
|
||||||
|
RAM_TOTAL=$(free -h | awk '/^Mem:/ {print $2}')
|
||||||
|
DISK_USED_HUMAN=$(df -h / | awk 'NR==2 {print $3}')
|
||||||
|
DISK_TOTAL_HUMAN=$(df -h / | awk 'NR==2 {print $2}')
|
||||||
|
DISK_PERCENT_RAW=$(df -P / | awk 'NR==2 {print $5}' | tr -d '%')
|
||||||
|
|
||||||
|
# CPU teplota (pokud je k dispozici)
|
||||||
|
TEMP_RAW=""
|
||||||
|
if [[ -f /sys/class/thermal/thermal_zone0/temp ]]; then
|
||||||
|
TEMP_RAW=$(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo "")
|
||||||
|
fi
|
||||||
|
TEMP_HUMAN=""
|
||||||
|
if [[ -n "$TEMP_RAW" && "$TEMP_RAW" -gt 0 ]]; then
|
||||||
|
TEMP_C=$((TEMP_RAW / 1000))
|
||||||
|
TEMP_HUMAN="🌡️ CPU: ${TEMP_C}°C\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Docker kontejnery
|
||||||
|
CONTAINERS_RUNNING=$(docker ps -q 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
CONTAINERS_TOTAL=$(docker ps -aq 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
CONTAINERS_STOPPED=$((CONTAINERS_TOTAL - CONTAINERS_RUNNING))
|
||||||
|
|
||||||
|
# Sitovy traffic (pokud je dostupny)
|
||||||
|
NETWORK_RX=$(cat /sys/class/net/$INTERFACE/statistics/rx_bytes 2>/dev/null || echo "0")
|
||||||
|
NETWORK_TX=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes 2>/dev/null || echo "0")
|
||||||
|
NETWORK_RX_HUMAN=$(awk "BEGIN {printf \"%.2f GB\", $NETWORK_RX/1073741824}")
|
||||||
|
NETWORK_TX_HUMAN=$(awk "BEGIN {printf \"%.2f GB\", $NETWORK_TX/1073741824}")
|
||||||
|
|
||||||
|
# Posledni Docker update a zaloha
|
||||||
|
LAST_UPDATE="zatim neprobehla"
|
||||||
|
if [[ -f "$DOCKER_UPDATE_LOG" ]]; then
|
||||||
|
LAST_UPDATE=$(grep -E "=== (docker-update|update.sh) (spusten|dokoncen)" "$DOCKER_UPDATE_LOG" | tail -1 | awk '{print $1, $2}')
|
||||||
|
fi
|
||||||
|
|
||||||
|
LAST_BACKUP="zatim neprobehla"
|
||||||
|
if [[ -d "$DOCKER_BACKUP_DIR" ]]; then
|
||||||
|
LAST_BACKUP=$(ls -t "$DOCKER_BACKUP_DIR"/*/ 2>/dev/null | head -1 | xargs -I {} basename {} 2>/dev/null || echo "neni")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === SESTAVENI REPORTU ===
|
||||||
|
ALERTS=""
|
||||||
|
if [[ $DISK_PERCENT_RAW -ge $DISK_CRIT ]]; then
|
||||||
|
ALERTS="${ALERTS}🚨 *DISK KRITICKY: ${DISK_PERCENT_RAW}%*\n"
|
||||||
|
elif [[ $DISK_PERCENT_RAW -ge $DISK_WARN ]]; then
|
||||||
|
ALERTS="${ALERTS}⚠️ *DISK: ${DISK_PERCENT_RAW}%*\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$TEMP_RAW" && "$TEMP_RAW" -gt 0 ]]; then
|
||||||
|
TEMP_C=$((TEMP_RAW / 1000))
|
||||||
|
if [[ $TEMP_C -ge $TEMP_CRIT ]]; then
|
||||||
|
ALERTS="${ALERTS}🚨 *CPU KRITICKY: ${TEMP_C}°C*\n"
|
||||||
|
elif [[ $TEMP_C -ge $TEMP_WARN ]]; then
|
||||||
|
ALERTS="${ALERTS}⚠️ *CPU: ${TEMP_C}°C*\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === ODESLANI ===
|
||||||
|
REPORT="${ALERTS}📊 *[$HOST]* Denni report
|
||||||
|
|
||||||
|
⏱️ Uptime: \`$UPTIME\`
|
||||||
|
📈 Load: \`$LOAD\`
|
||||||
|
🧠 RAM: $RAM_USED / $RAM_TOTAL
|
||||||
|
💾 Disk: $DISK_USED_HUMAN / $DISK_TOTAL_HUMAN (${DISK_PERCENT_RAW}%)
|
||||||
|
${TEMP_HUMAN}🌐 Sit ($INTERFACE):
|
||||||
|
RX: $NETWORK_RX_HUMAN | TX: $NETWORK_TX_HUMAN
|
||||||
|
|
||||||
|
🐳 Docker:
|
||||||
|
Bezi: $CONTAINERS_RUNNING | Celkem: $CONTAINERS_TOTAL
|
||||||
|
Stopped: $CONTAINERS_STOPPED
|
||||||
|
|
||||||
|
📅 Posledni Docker update: \`$LAST_UPDATE\`
|
||||||
|
💾 Posledni zaloha: \`$LAST_BACKUP\`"
|
||||||
|
|
||||||
|
send_msg "$REPORT"
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# update.sh - aktualizace systemu (apt update + upgrade) + restart pokud nutny
|
||||||
|
# + Telegram notifikace o vysledku.
|
||||||
|
#
|
||||||
|
# Spust jednou rucne: sudo bash update.sh
|
||||||
|
# Spust automaticky: systemd timer update-rpi.timer (kazdy patek 18:00)
|
||||||
|
#
|
||||||
|
# Konfigurace: /home/mates/.telegram.conf (nebo nastav TELEGRAM_BOT_TOKEN a TELEGRAM_CHAT_ID v env)
|
||||||
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# === KONFIGURACE ===
|
||||||
|
CONFIG_FILE="/home/mates/.telegram.conf"
|
||||||
|
USER_NAME="mates"
|
||||||
|
WORK_DIR="/home/$USER_NAME"
|
||||||
|
LOG_FILE="$WORK_DIR/update.log"
|
||||||
|
HOST=$(hostname)
|
||||||
|
RESTART_REQUIRED="/var/run/reboot-required"
|
||||||
|
|
||||||
|
# === TELEGRAM KONFIGURACE ===
|
||||||
|
if [[ -f "$CONFIG_FILE" ]]; then
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
TELEGRAM_BOT_TOKEN="${TELEGRAM_BOT_TOKEN:-}"
|
||||||
|
TELEGRAM_CHAT_ID="${TELEGRAM_CHAT_ID:-}"
|
||||||
|
|
||||||
|
# === TELEGRAM HELPER ===
|
||||||
|
send_msg() {
|
||||||
|
local TEXT="$1"
|
||||||
|
|
||||||
|
if [[ -z "$TELEGRAM_BOT_TOKEN" || -z "$TELEGRAM_CHAT_ID" ]]; then
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Telegram neni nakonfigurovan, preskakuji notifikaci" >> "$LOG_FILE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
|
||||||
|
-d chat_id="${TELEGRAM_CHAT_ID}" \
|
||||||
|
-d text="$TEXT" \
|
||||||
|
-d parse_mode="Markdown" \
|
||||||
|
--max-time 10 \
|
||||||
|
--retry 3 > /dev/null || echo "[$(date '+%Y-%m-%d %H:%M:%S')] ⚠️ Telegram chyba" >> "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# === PROMENNE ===
|
||||||
|
START_TIME=$(date +%s)
|
||||||
|
|
||||||
|
# === CHYBA HANDLER ===
|
||||||
|
on_error() {
|
||||||
|
local exit_code=$?
|
||||||
|
local end_time=$(date +%s)
|
||||||
|
local duration=$((end_time - START_TIME))
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] CHYBA: update.sh skončil s chybou (exit code $exit_code)" >> "$LOG_FILE"
|
||||||
|
send_msg "❌ *[$HOST]* Aktualizace systému selhala (${duration}s).
|
||||||
|
Zkontroluj log:
|
||||||
|
\`$LOG_FILE\`"
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
trap on_error ERR
|
||||||
|
|
||||||
|
# === HLAVNI LOGIKA ===
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] === update.sh spusten ===" >> "$LOG_FILE"
|
||||||
|
|
||||||
|
# Notifikace o zacatku
|
||||||
|
send_msg "🔄 *[$HOST]* Spoustim aktualizaci systemu..."
|
||||||
|
|
||||||
|
# Aktualizace baliku
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] apt update..." >> "$LOG_FILE"
|
||||||
|
sudo apt-get update -qq 2>>"$LOG_FILE"
|
||||||
|
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] apt upgrade..." >> "$LOG_FILE"
|
||||||
|
sudo apt-get upgrade -y -qq 2>>"$LOG_FILE"
|
||||||
|
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] apt autoremove..." >> "$LOG_FILE"
|
||||||
|
sudo apt-get autoremove -y -qq 2>>"$LOG_FILE"
|
||||||
|
|
||||||
|
END_TIME=$(date +%s)
|
||||||
|
DURATION=$((END_TIME - START_TIME))
|
||||||
|
|
||||||
|
# Restart?
|
||||||
|
if [[ -f "$RESTART_REQUIRED" ]]; then
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Restart required" >> "$LOG_FILE"
|
||||||
|
send_msg "⚠️ *[$HOST]* Aktualizace systemu dokoncena (${DURATION}s).
|
||||||
|
**Restart serveru je nutny!** Reboot bude proveden za 1 minutu."
|
||||||
|
|
||||||
|
# Naplanovany restart za 1 minutu (at muzes kanclovat)
|
||||||
|
sudo shutdown -r +1 "Systemovy restart po update"
|
||||||
|
else
|
||||||
|
send_msg "✅ *[$HOST]* Aktualizace systemu dokoncena (${DURATION}s).
|
||||||
|
Restart nutny neni."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] === update.sh dokoncen (${DURATION}s) ===" >> "$LOG_FILE"
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Aktualizace Docker kontejneru
|
||||||
|
After=network-online.target docker.service
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
User=mates
|
||||||
|
WorkingDirectory=/home/mates/skripty/update-docker-script
|
||||||
|
ExecStart=/home/mates/skripty/update-docker-script/docker-update.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Spoustet Docker update kazdou sobotu v 18:00
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=Sat 18:00
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Zaloha Docker aplikaci
|
||||||
|
After=network-online.target docker.service
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
User=mates
|
||||||
|
WorkingDirectory=/home/mates/zalohy
|
||||||
|
ExecStart=/home/mates/zalohy/docker_zalohy.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Spoustet Docker zalohy kazde utery ve 20:00
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=Tue 20:00
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Denní report serveru na Telegram
|
||||||
|
After=network-online.target docker.service
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
User=mates
|
||||||
|
WorkingDirectory=/home/mates/skripty
|
||||||
|
ExecStart=/home/mates/skripty/server-report.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Spoustet server report kazdy den v 09:30
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=*-*-* 09:30:00
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Aktualizace systému + Telegram notifikace
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
User=mates
|
||||||
|
WorkingDirectory=/home/mates
|
||||||
|
ExecStart=/home/mates/update.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Aktualizace každý pátek v 18:00
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=Fri *-*-* 18:00:00
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
Reference in New Issue
Block a user