JKJan Kaminský/ code
RepositoriesAdmin

server-status

Jednoduchý PHP endpoint pro kontrolu stavu serveru a základních systémových informací.

Bash
‹› Code▤ README▣ Screenshots 1Updated před 1 h
◇main.sh
#!/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"
echo
README.md

server-status

Ukázkový projekt pro Code Hub. Soubor vrať přes PHP-FPM a dostaneš jednoduchou JSON odpověď se stavem serveru.

Screenshots

Ukázky aplikace

1