server-status
Ukázkový projekt pro Code Hub. Soubor vrať přes PHP-FPM a dostaneš jednoduchou JSON odpověď se stavem serveru.
Jednoduchý PHP endpoint pro kontrolu stavu serveru a základních systémových informací.
#!/usr/bin/env bash
set -Eeuo pipefail
# ============================================================
# NGINX + PHP + LET'S ENCRYPT INSTALLER
# Podpora:
# example.cz
# www.example.cz
# app.example.cz
# obec.jankaminsky.eu
# Ubuntu / Debian
# ============================================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
# ------------------------------------------------------------
# ROOT CHECK
# ------------------------------------------------------------
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}Skript musí být spuštěn jako root.${NC}"
echo "Použij:"
echo "sudo bash setup-web.sh"
exit 1
fi
# ------------------------------------------------------------
# FUNKCE
# ------------------------------------------------------------
die() {
echo -e "${RED}CHYBA: $*${NC}"
exit 1
}
valid_domain() {
local domain="$1"
[[ "$domain" =~ ^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$ ]]
}
resolve_ipv4() {
local host="$1"
getent ahostsv4 "$host" 2>/dev/null \
| awk '{print $1}' \
| sort -u
}
domain_points_to_server() {
local host="$1"
local server_ip="$2"
resolve_ipv4 "$host" | grep -Fxq "$server_ip"
}
# ------------------------------------------------------------
# HEADER
# ------------------------------------------------------------
clear
echo -e "${BLUE}"
echo "=========================================="
echo " NGINX WEB INSTALLER v2"
echo "=========================================="
echo -e "${NC}"
echo "Podporuje hlavní domény i subdomény."
echo
# ------------------------------------------------------------
# DOMÉNA
# ------------------------------------------------------------
while true; do
read -rp "Doména / subdoména (např. example.cz nebo app.example.cz): " DOMAIN
DOMAIN=$(echo "$DOMAIN" \
| tr '[:upper:]' '[:lower:]' \
| sed 's#^https\?://##' \
| sed 's#/$##')
if valid_domain "$DOMAIN"; then
break
fi
echo -e "${RED}Neplatný formát domény.${NC}"
done
# ------------------------------------------------------------
# WWW
# ------------------------------------------------------------
echo
echo "Chceš k webu používat také WWW alias?"
echo
echo "Například:"
echo " $DOMAIN"
echo " www.$DOMAIN"
echo
echo -e "${YELLOW}U subdomény typu obec.jankaminsky.eu obvykle zvol N.${NC}"
echo
read -rp "Přidat www.$DOMAIN? [y/N]: " ADD_WWW
USE_WWW=false
if [[ "$ADD_WWW" =~ ^[Yy]$ ]]; then
USE_WWW=true
fi
# ------------------------------------------------------------
# EMAIL
# ------------------------------------------------------------
echo
while true; do
read -rp "E-mail pro Let's Encrypt: " EMAIL
if [[ "$EMAIL" =~ ^[^[:space:]@]+@[^[:space:]@]+\.[^[:space:]@]+$ ]]; then
break
fi
echo -e "${RED}Zadej platnou e-mailovou adresu.${NC}"
done
# ------------------------------------------------------------
# WEBROOT
# ------------------------------------------------------------
DEFAULT_ROOT="/var/www/$DOMAIN"
echo
read -rp "Web root [$DEFAULT_ROOT]: " WEBROOT
WEBROOT="${WEBROOT:-$DEFAULT_ROOT}"
# ------------------------------------------------------------
# SOUHRN
# ------------------------------------------------------------
echo
echo -e "${CYAN}=========================================="
echo " KONFIGURACE"
echo -e "==========================================${NC}"
echo "Doména: $DOMAIN"
if [[ "$USE_WWW" == true ]]; then
echo "WWW alias: www.$DOMAIN"
else
echo "WWW alias: NE"
fi
echo "Web root: $WEBROOT"
echo "Let's Encrypt: $EMAIL"
echo
read -rp "Pokračovat? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
echo "Ukončeno."
exit 0
fi
# ------------------------------------------------------------
# BALÍČKY
# ------------------------------------------------------------
echo
echo -e "${BLUE}[1/9] Kontroluji potřebné balíčky...${NC}"
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y \
nginx \
php-fpm \
php-cli \
certbot \
python3-certbot-nginx \
curl
echo -e "${GREEN}✓ Balíčky OK${NC}"
# ------------------------------------------------------------
# PHP-FPM
# ------------------------------------------------------------
echo
echo -e "${BLUE}[2/9] Hledám PHP-FPM socket...${NC}"
PHP_SOCKET=""
# Preferujeme konkrétní versioned socket
PHP_SOCKET=$(find /run/php \
-maxdepth 1 \
-type s \
-name 'php*-fpm.sock' \
! -name 'php-fpm.sock' \
2>/dev/null \
| sort -V \
| tail -n 1 || true)
# Fallback
if [[ -z "$PHP_SOCKET" && -S "/run/php/php-fpm.sock" ]]; then
PHP_SOCKET="/run/php/php-fpm.sock"
fi
if [[ -z "$PHP_SOCKET" ]]; then
die "PHP-FPM socket nebyl nalezen."
fi
echo -e "${GREEN}✓ PHP-FPM:${NC} $PHP_SOCKET"
# ------------------------------------------------------------
# WEBROOT
# ------------------------------------------------------------
echo
echo -e "${BLUE}[3/9] Připravuji web root...${NC}"
mkdir -p "$WEBROOT"
# index vytvoříme pouze pokud ještě neexistuje
if [[ ! -e "$WEBROOT/index.php" && ! -e "$WEBROOT/index.html" ]]; then
cat > "$WEBROOT/index.php" <<EOF
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$DOMAIN</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background:
radial-gradient(circle at top, #162033, #080b10 65%);
color: #ffffff;
font-family:
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
sans-serif;
}
.card {
width: min(650px, 90%);
padding: 50px;
background: rgba(255,255,255,.05);
border: 1px solid rgba(255,255,255,.12);
border-radius: 20px;
text-align: center;
box-shadow:
0 25px 80px rgba(0,0,0,.45);
}
h1 {
margin-top: 0;
font-size: 42px;
}
.status {
color: #49d17d;
font-weight: 700;
font-size: 18px;
}
.info {
color: #9da7b3;
margin-top: 25px;
}
code {
color: #75baff;
}
</style>
</head>
<body>
<div class="card">
<h1>$DOMAIN</h1>
<p class="status">
✓ WEB ONLINE
</p>
<p>
Nginx + PHP-FPM funguje správně.
</p>
<div class="info">
PHP:
<code>
<?php echo htmlspecialchars(PHP_VERSION); ?>
</code>
<br><br>
Server:
<code>
<?php echo htmlspecialchars(\$_SERVER['SERVER_SOFTWARE'] ?? 'unknown'); ?>
</code>
</div>
</div>
</body>
</html>
EOF
else
echo -e "${YELLOW}Webroot už obsahuje index – nepřepisuji ho.${NC}"
fi
chown -R www-data:www-data "$WEBROOT"
find "$WEBROOT" -type d -exec chmod 755 {} \;
find "$WEBROOT" -type f -exec chmod 644 {} \;
echo -e "${GREEN}✓ Web root připraven${NC}"
# ------------------------------------------------------------
# SERVER_NAME
# ------------------------------------------------------------
SERVER_NAMES="$DOMAIN"
if [[ "$USE_WWW" == true ]]; then
SERVER_NAMES="$DOMAIN www.$DOMAIN"
fi
# ------------------------------------------------------------
# NGINX
# ------------------------------------------------------------
echo
echo -e "${BLUE}[4/9] Vytvářím Nginx konfiguraci...${NC}"
NGINX_CONFIG="/etc/nginx/sites-available/$DOMAIN"
NGINX_ENABLED="/etc/nginx/sites-enabled/$DOMAIN"
# záloha pokud konfigurace existuje
if [[ -f "$NGINX_CONFIG" ]]; then
BACKUP="${NGINX_CONFIG}.backup.$(date +%Y%m%d-%H%M%S)"
cp "$NGINX_CONFIG" "$BACKUP"
echo "Původní konfigurace zálohována:"
echo "$BACKUP"
fi
cat > "$NGINX_CONFIG" <<EOF
server {
listen 80;
listen [::]:80;
server_name $SERVER_NAMES;
root $WEBROOT;
index index.php index.html index.htm;
access_log /var/log/nginx/$DOMAIN.access.log;
error_log /var/log/nginx/$DOMAIN.error.log;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:$PHP_SOCKET;
}
location ~ /\.(?!well-known).* {
deny all;
}
client_max_body_size 64M;
}
EOF
ln -sfn "$NGINX_CONFIG" "$NGINX_ENABLED"
echo -e "${GREEN}✓ Nginx konfigurace vytvořena${NC}"
# ------------------------------------------------------------
# NGINX TEST
# ------------------------------------------------------------
echo
echo -e "${BLUE}[5/9] Testuji Nginx...${NC}"
if ! nginx -t; then
echo
echo -e "${RED}NGINX konfigurace obsahuje chybu.${NC}"
echo
echo "Soubor:"
echo "$NGINX_CONFIG"
exit 1
fi
systemctl reload nginx
echo -e "${GREEN}✓ Nginx OK${NC}"
# ------------------------------------------------------------
# IP SERVERU
# ------------------------------------------------------------
echo
echo -e "${BLUE}[6/9] Zjišťuji veřejnou IPv4 serveru...${NC}"
SERVER_IP=$(curl -4fsS --max-time 10 https://api.ipify.org || true)
if [[ -z "$SERVER_IP" ]]; then
die "Nepodařilo se zjistit veřejnou IPv4 serveru."
fi
echo "Server IPv4: $SERVER_IP"
# ------------------------------------------------------------
# DNS
# ------------------------------------------------------------
echo
echo -e "${BLUE}[7/9] Kontroluji DNS...${NC}"
VALID_SSL_DOMAINS=()
echo
echo "Kontrola: $DOMAIN"
DOMAIN_IPS=$(resolve_ipv4 "$DOMAIN" || true)
if [[ -z "$DOMAIN_IPS" ]]; then
echo -e "${RED}✗ DNS A záznam nebyl nalezen.${NC}"
else
echo "DNS IPv4:"
echo "$DOMAIN_IPS" | sed 's/^/ /'
if domain_points_to_server "$DOMAIN" "$SERVER_IP"; then
echo -e "${GREEN}✓ Směřuje na tento server${NC}"
VALID_SSL_DOMAINS+=("$DOMAIN")
else
echo -e "${RED}✗ Doména nesměřuje na $SERVER_IP${NC}"
fi
fi
# ------------------------------------------------------------
# WWW DNS
# ------------------------------------------------------------
if [[ "$USE_WWW" == true ]]; then
WWW_DOMAIN="www.$DOMAIN"
echo
echo "Kontrola: $WWW_DOMAIN"
WWW_IPS=$(resolve_ipv4 "$WWW_DOMAIN" || true)
if [[ -z "$WWW_IPS" ]]; then
echo -e "${YELLOW}⚠ $WWW_DOMAIN nemá IPv4 DNS záznam.${NC}"
echo "Nebude zahrnuta do SSL certifikátu."
else
echo "DNS IPv4:"
echo "$WWW_IPS" | sed 's/^/ /'
if domain_points_to_server "$WWW_DOMAIN" "$SERVER_IP"; then
echo -e "${GREEN}✓ Směřuje na tento server${NC}"
VALID_SSL_DOMAINS+=("$WWW_DOMAIN")
else
echo -e "${YELLOW}⚠ $WWW_DOMAIN nesměřuje na $SERVER_IP${NC}"
echo "Nebude zahrnuta do SSL certifikátu."
fi
fi
fi
# ------------------------------------------------------------
# SSL
# ------------------------------------------------------------
echo
echo -e "${BLUE}[8/9] Let's Encrypt SSL...${NC}"
if [[ ${#VALID_SSL_DOMAINS[@]} -eq 0 ]]; then
echo
echo -e "${YELLOW}SSL nebylo možné vytvořit.${NC}"
echo
echo "Žádná z domén nesměřuje na:"
echo "$SERVER_IP"
echo
echo "Nastav DNS a potom spusť například:"
echo
echo "certbot --nginx -d $DOMAIN"
echo
else
CERTBOT_DOMAINS=()
for host in "${VALID_SSL_DOMAINS[@]}"; do
CERTBOT_DOMAINS+=("-d" "$host")
done
echo
echo "Certifikát bude vystaven pro:"
for host in "${VALID_SSL_DOMAINS[@]}"; do
echo " ✓ $host"
done
echo
if certbot \
--nginx \
--non-interactive \
--agree-tos \
--redirect \
--email "$EMAIL" \
"${CERTBOT_DOMAINS[@]}"
then
echo
echo -e "${GREEN}✓ SSL certifikát vytvořen${NC}"
else
echo
echo -e "${RED}Certbot skončil chybou.${NC}"
echo
echo "Web přes HTTP zůstává nakonfigurovaný."
echo
echo "Log:"
echo "/var/log/letsencrypt/letsencrypt.log"
fi
fi
# ------------------------------------------------------------
# FINAL CHECK
# ------------------------------------------------------------
echo
echo -e "${BLUE}[9/9] Finální kontrola...${NC}"
nginx -t
systemctl reload nginx
echo
echo -e "${GREEN}"
echo "=========================================="
echo " HOTOVO"
echo "=========================================="
echo -e "${NC}"
echo "Doména:"
echo " $DOMAIN"
echo
echo "Web root:"
echo " $WEBROOT"
echo
echo "Nginx:"
echo " $NGINX_CONFIG"
echo
echo "PHP-FPM:"
echo " $PHP_SOCKET"
echo
echo "DNS:"
echo " $DOMAIN -> $(resolve_ipv4 "$DOMAIN" | tr '\n' ' ')"
if [[ "$USE_WWW" == true ]]; then
echo " www.$DOMAIN -> $(resolve_ipv4 "www.$DOMAIN" | tr '\n' ' ')"
fi
echo
if [[ " ${VALID_SSL_DOMAINS[*]} " == *" $DOMAIN "* ]]; then
echo -e "Web: ${GREEN}https://$DOMAIN${NC}"
else
echo -e "Web: ${YELLOW}http://$DOMAIN${NC}"
fi
echo
echo "Kontrola SSL obnovy:"
echo " systemctl status certbot.timer"
echo
echo "Test SSL obnovy:"
echo " certbot renew --dry-run"
echoUkázkový projekt pro Code Hub. Soubor vrať přes PHP-FPM a dostaneš jednoduchou JSON odpověď se stavem serveru.
Ukázky aplikace