Преглед на файлове

adding support for ubuntu

Medowar преди 6 дни
родител
ревизия
b24360b2b2
променени са 4 файла, в които са добавени 470 реда и са изтрити 82 реда
  1. 100 0
      _create_folder_fedora.sh
  2. 87 0
      _create_folder_ubuntu.sh
  3. 29 82
      create_folder.sh
  4. 254 0
      setup_testenv_ubuntu.sh

+ 100 - 0
_create_folder_fedora.sh

@@ -0,0 +1,100 @@
+#!/bin/bash
+#
+# _create_folder_fedora.sh — Create a new folder in /var/www/html with correct permissions (Fedora)
+# Invoked via create_folder.sh; not meant to be run directly.
+#
+# This script must be run as root (su).
+#
+
+set -euo pipefail
+
+# ── Colors for output ─────────────────────────────────────────────────────
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+# ── Check for root privileges ─────────────────────────────────────────────
+if [[ $EUID -ne 0 ]]; then
+    echo -e "${RED}ERROR: This script must be run as root (su / sudo).${NC}" >&2
+    exit 1
+fi
+
+# ── Check for mandatory parameter ─────────────────────────────────────────
+if [[ $# -lt 1 || -z "$1" ]]; then
+    echo -e "${RED}ERROR: Folder name is a mandatory parameter.${NC}" >&2
+    echo -e "Usage: $0 <foldername>" >&2
+    exit 1
+fi
+
+FOLDER_NAME="$1"
+BASE_DIR="/var/www/html"
+NEW_FOLDER="$BASE_DIR/$FOLDER_NAME"
+
+# Check if target already exists
+if [[ -e "$NEW_FOLDER" ]]; then
+    echo -e "${RED}ERROR: Target path '$NEW_FOLDER' already exists.${NC}" >&2
+    exit 1
+fi
+
+# ── Determine regular user ────────────────────────────────────────────────
+REGULAR_USER=""
+if [[ -n "${SUDO_USER:-}" ]]; then
+    REGULAR_USER="$SUDO_USER"
+elif command -v logname &>/dev/null && logname &>/dev/null; then
+    REGULAR_USER=$(logname)
+fi
+
+# Fallback to the owner of the script directory if needed
+if [[ -z "$REGULAR_USER" || "$REGULAR_USER" == "root" ]]; then
+    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+    REGULAR_USER=$(stat -c '%U' "$SCRIPT_DIR" 2>/dev/null || echo "")
+fi
+
+# Final fallback
+if [[ -z "$REGULAR_USER" || "$REGULAR_USER" == "root" ]]; then
+    REGULAR_USER=$(awk -F: '$3 >= 1000 && $3 != 65534 {print $1; exit}' /etc/passwd)
+fi
+
+# Ensure we found a valid regular user
+if [[ -z "$REGULAR_USER" ]]; then
+    echo -e "${RED}ERROR: Could not determine a regular user for ownership.${NC}" >&2
+    exit 1
+fi
+
+# ── Configuration ─────────────────────────────────────────────────────────
+APACHE_USER="apache"
+APACHE_GROUP="apache"
+
+echo "→ Creating folder: $NEW_FOLDER"
+mkdir -p "$NEW_FOLDER"
+
+echo "→ Setting permissions and ownership..."
+# Set ownership to regular user (matching the existing script's behavior)
+chown -R "$REGULAR_USER:$REGULAR_USER" "$NEW_FOLDER"
+
+# Set base permissions
+chmod 0755 "$NEW_FOLDER"
+
+# Set ACLs so both the regular user and Apache can read/write
+setfacl -R -m u:"$REGULAR_USER":rwx,u:"$APACHE_USER":rwx "$NEW_FOLDER"
+setfacl -R -d -m u:"$REGULAR_USER":rwx,u:"$APACHE_USER":rwx "$NEW_FOLDER"
+
+# Also allow the apache group to access
+setfacl -R -m g:"$APACHE_GROUP":r-x "$NEW_FOLDER"
+setfacl -R -d -m g:"$APACHE_GROUP":r-x "$NEW_FOLDER"
+
+# ── Configure SELinux permissions ─────────────────────────────────────────
+if command -v getenforce &>/dev/null; then
+    SELINUX_STATUS=$(getenforce 2>/dev/null || echo "Disabled")
+    if [[ "$SELINUX_STATUS" != "Disabled" && "$SELINUX_STATUS" != "Permissive" ]]; then
+        echo "→ Configuring SELinux permissions..."
+        if command -v semanage &>/dev/null; then
+            semanage fcontext -a -t httpd_sys_rw_content_t "$NEW_FOLDER(/.*)?" 2>/dev/null || \
+            semanage fcontext -m -t httpd_sys_rw_content_t "$NEW_FOLDER(/.*)?" 2>/dev/null || true
+        fi
+        restorecon -Rv "$NEW_FOLDER" &>/dev/null || true
+    fi
+fi
+
+echo -e "${GREEN}✓ Folder '$FOLDER_NAME' created successfully in $BASE_DIR!${NC}"

+ 87 - 0
_create_folder_ubuntu.sh

@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# _create_folder_ubuntu.sh — Create a new folder in /home/josef/Code with correct permissions (Ubuntu)
+# Invoked via create_folder.sh; not meant to be run directly.
+#
+# This script must be run as root (su).
+#
+
+set -euo pipefail
+
+# ── Colors for output ─────────────────────────────────────────────────────
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+# ── Check for root privileges ─────────────────────────────────────────────
+if [[ $EUID -ne 0 ]]; then
+    echo -e "${RED}ERROR: This script must be run as root (su / sudo).${NC}" >&2
+    exit 1
+fi
+
+# ── Check for mandatory parameter ─────────────────────────────────────────
+if [[ $# -lt 1 || -z "$1" ]]; then
+    echo -e "${RED}ERROR: Folder name is a mandatory parameter.${NC}" >&2
+    echo -e "Usage: $0 <foldername>" >&2
+    exit 1
+fi
+
+FOLDER_NAME="$1"
+BASE_DIR="/home/josef/Code"
+NEW_FOLDER="$BASE_DIR/$FOLDER_NAME"
+
+# Check if target already exists
+if [[ -e "$NEW_FOLDER" ]]; then
+    echo -e "${RED}ERROR: Target path '$NEW_FOLDER' already exists.${NC}" >&2
+    exit 1
+fi
+
+# ── Determine regular user ────────────────────────────────────────────────
+REGULAR_USER=""
+if [[ -n "${SUDO_USER:-}" ]]; then
+    REGULAR_USER="$SUDO_USER"
+elif command -v logname &>/dev/null && logname &>/dev/null; then
+    REGULAR_USER=$(logname)
+fi
+
+# Fallback to the owner of the script directory if needed
+if [[ -z "$REGULAR_USER" || "$REGULAR_USER" == "root" ]]; then
+    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+    REGULAR_USER=$(stat -c '%U' "$SCRIPT_DIR" 2>/dev/null || echo "")
+fi
+
+# Final fallback
+if [[ -z "$REGULAR_USER" || "$REGULAR_USER" == "root" ]]; then
+    REGULAR_USER=$(awk -F: '$3 >= 1000 && $3 != 65534 {print $1; exit}' /etc/passwd)
+fi
+
+# Ensure we found a valid regular user
+if [[ -z "$REGULAR_USER" ]]; then
+    echo -e "${RED}ERROR: Could not determine a regular user for ownership.${NC}" >&2
+    exit 1
+fi
+
+# ── Configuration ─────────────────────────────────────────────────────────
+APACHE_USER="www-data"
+APACHE_GROUP="www-data"
+
+echo "→ Creating folder: $NEW_FOLDER"
+mkdir -p "$NEW_FOLDER"
+
+echo "→ Setting permissions and ownership..."
+# Set ownership to regular user (matching the existing script's behavior)
+chown -R "$REGULAR_USER:$REGULAR_USER" "$NEW_FOLDER"
+
+# Set base permissions
+chmod 0755 "$NEW_FOLDER"
+
+# Set ACLs so both the regular user and Apache can read/write
+setfacl -R -m u:"$REGULAR_USER":rwx,u:"$APACHE_USER":rwx "$NEW_FOLDER"
+setfacl -R -d -m u:"$REGULAR_USER":rwx,u:"$APACHE_USER":rwx "$NEW_FOLDER"
+
+# Also allow the apache group to access
+setfacl -R -m g:"$APACHE_GROUP":r-x "$NEW_FOLDER"
+setfacl -R -d -m g:"$APACHE_GROUP":r-x "$NEW_FOLDER"
+
+echo -e "${GREEN}✓ Folder '$FOLDER_NAME' created successfully in $BASE_DIR!${NC}"

+ 29 - 82
create_folder.sh

@@ -1,100 +1,47 @@
 #!/bin/bash
 #
-# create_folder.sh — Create a new folder in /var/www/html with correct permissions
+# create_folder.sh — Detect the current Linux distro and dispatch to the
+# matching distro-specific folder-creation script.
 # Usage: su -c "./create_folder.sh <foldername>" or sudo ./create_folder.sh <foldername>
 #
-# This script must be run as root (su).
+# The distro-specific scripts (_create_folder_fedora.sh, _create_folder_ubuntu.sh)
+# are prefixed with an underscore so they don't clutter tab-completion for
+# "create_folder".
 #
 
 set -euo pipefail
 
-# ── Colors for output ─────────────────────────────────────────────────────
 RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
 NC='\033[0m' # No Color
 
-# ── Check for root privileges ─────────────────────────────────────────────
-if [[ $EUID -ne 0 ]]; then
-    echo -e "${RED}ERROR: This script must be run as root (su / sudo).${NC}" >&2
-    exit 1
-fi
-
-# ── Check for mandatory parameter ─────────────────────────────────────────
-if [[ $# -lt 1 || -z "$1" ]]; then
-    echo -e "${RED}ERROR: Folder name is a mandatory parameter.${NC}" >&2
-    echo -e "Usage: $0 <foldername>" >&2
-    exit 1
-fi
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 
-FOLDER_NAME="$1"
-BASE_DIR="/var/www/html"
-NEW_FOLDER="$BASE_DIR/$FOLDER_NAME"
-
-# Check if target already exists
-if [[ -e "$NEW_FOLDER" ]]; then
-    echo -e "${RED}ERROR: Target path '$NEW_FOLDER' already exists.${NC}" >&2
+if [[ ! -r /etc/os-release ]]; then
+    echo -e "${RED}ERROR: Cannot detect distro (/etc/os-release not found).${NC}" >&2
     exit 1
 fi
 
-# ── Determine regular user ────────────────────────────────────────────────
-REGULAR_USER=""
-if [[ -n "${SUDO_USER:-}" ]]; then
-    REGULAR_USER="$SUDO_USER"
-elif command -v logname &>/dev/null && logname &>/dev/null; then
-    REGULAR_USER=$(logname)
-fi
-
-# Fallback to the owner of the script directory if needed
-if [[ -z "$REGULAR_USER" || "$REGULAR_USER" == "root" ]]; then
-    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-    REGULAR_USER=$(stat -c '%U' "$SCRIPT_DIR" 2>/dev/null || echo "")
-fi
-
-# Final fallback
-if [[ -z "$REGULAR_USER" || "$REGULAR_USER" == "root" ]]; then
-    REGULAR_USER=$(awk -F: '$3 >= 1000 && $3 != 65534 {print $1; exit}' /etc/passwd)
-fi
-
-# Ensure we found a valid regular user
-if [[ -z "$REGULAR_USER" ]]; then
-    echo -e "${RED}ERROR: Could not determine a regular user for ownership.${NC}" >&2
+# shellcheck disable=SC1091
+source /etc/os-release
+DISTRO_ID="${ID:-}"
+DISTRO_ID_LIKE="${ID_LIKE:-}"
+
+case "$DISTRO_ID $DISTRO_ID_LIKE" in
+    *fedora*|*rhel*)
+        TARGET="$SCRIPT_DIR/_create_folder_fedora.sh"
+        ;;
+    *ubuntu*|*debian*)
+        TARGET="$SCRIPT_DIR/_create_folder_ubuntu.sh"
+        ;;
+    *)
+        echo -e "${RED}ERROR: Unsupported distro '$DISTRO_ID' (ID_LIKE='$DISTRO_ID_LIKE').${NC}" >&2
+        exit 1
+        ;;
+esac
+
+if [[ ! -x "$TARGET" ]]; then
+    echo -e "${RED}ERROR: Expected script not found or not executable: $TARGET${NC}" >&2
     exit 1
 fi
 
-# ── Configuration ─────────────────────────────────────────────────────────
-APACHE_USER="apache"
-APACHE_GROUP="apache"
-
-echo "→ Creating folder: $NEW_FOLDER"
-mkdir -p "$NEW_FOLDER"
-
-echo "→ Setting permissions and ownership..."
-# Set ownership to regular user (matching the existing script's behavior)
-chown -R "$REGULAR_USER:$REGULAR_USER" "$NEW_FOLDER"
-
-# Set base permissions
-chmod 0755 "$NEW_FOLDER"
-
-# Set ACLs so both the regular user and Apache can read/write
-setfacl -R -m u:"$REGULAR_USER":rwx,u:"$APACHE_USER":rwx "$NEW_FOLDER"
-setfacl -R -d -m u:"$REGULAR_USER":rwx,u:"$APACHE_USER":rwx "$NEW_FOLDER"
-
-# Also allow the apache group to access
-setfacl -R -m g:"$APACHE_GROUP":r-x "$NEW_FOLDER"
-setfacl -R -d -m g:"$APACHE_GROUP":r-x "$NEW_FOLDER"
-
-# ── Configure SELinux permissions ─────────────────────────────────────────
-if command -v getenforce &>/dev/null; then
-    SELINUX_STATUS=$(getenforce 2>/dev/null || echo "Disabled")
-    if [[ "$SELINUX_STATUS" != "Disabled" && "$SELINUX_STATUS" != "Permissive" ]]; then
-        echo "→ Configuring SELinux permissions..."
-        if command -v semanage &>/dev/null; then
-            semanage fcontext -a -t httpd_sys_rw_content_t "$NEW_FOLDER(/.*)?" 2>/dev/null || \
-            semanage fcontext -m -t httpd_sys_rw_content_t "$NEW_FOLDER(/.*)?" 2>/dev/null || true
-        fi
-        restorecon -Rv "$NEW_FOLDER" &>/dev/null || true
-    fi
-fi
-
-echo -e "${GREEN}✓ Folder '$FOLDER_NAME' created successfully in $BASE_DIR!${NC}"
+exec "$TARGET" "$@"

+ 254 - 0
setup_testenv_ubuntu.sh

@@ -0,0 +1,254 @@
+#!/bin/bash
+#
+# setup_testenv_ubuntu.sh — General PHP development environment setup for Ubuntu
+# Usage: bash setup_testenv_ubuntu.sh
+# Sets up Apache (apache2) with PHP to serve /home/josef/Code on localhost
+# Requires sudo privileges for package installation and service management
+#
+# PRIVILEGE SEPARATION: This script must NOT be run as root.
+# The running user should not have direct rights to install packages
+# (i.e., must use sudo which requires authentication).
+#
+
+set -euo pipefail
+
+# ── Colors for output ─────────────────────────────────────────────────────
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+# ── Check for privilege separation ─────────────────────────────────────────
+echo "→ Checking user privileges..."
+
+CURRENT_USER=$(whoami)
+
+# Check if running as root (violates privilege separation)
+if [[ $EUID -eq 0 ]]; then
+    echo -e "${RED}ERROR: This script should not be run as root directly.${NC}"
+    echo "  Please run as a normal user with sudo privileges."
+    echo "  This ensures proper separation of privileges."
+    exit 1
+fi
+
+echo -e "${GREEN}✓${NC} Not running as root (good for privilege separation)"
+
+# Check if user has sudo privileges (Ubuntu uses sudo group for sudo access)
+if groups | grep -qw sudo; then
+    echo -e "${GREEN}✓${NC} User '$CURRENT_USER' is in sudo group (has sudo privileges)"
+else
+    echo -e "${YELLOW}WARNING:${NC} User '$CURRENT_USER' is not in the sudo group."
+    echo "  This user may not have sudo privileges required for this script."
+    echo "  The script will attempt to use sudo, which may prompt for a password."
+    echo ""
+    read -p "  Continue anyway? (y/N) " -n 1 -r
+    echo
+    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+        echo "Aborting."
+        exit 1
+    fi
+fi
+
+echo ""
+echo "Note: sudo commands will prompt for your password if required."
+
+# ── Configuration ─────────────────────────────────────────────────────────
+DOCROOT="/home/josef/Code"
+APACHE_USER="www-data"
+APACHE_GROUP="www-data"
+APACHE_CONF="/etc/apache2/conf-available/dev.conf"
+
+# ── 1. Install Apache, PHP, and required modules ──────────────────────────
+echo ""
+echo "→ Installing Apache (apache2), PHP, and required modules..."
+
+sudo apt-get update
+sudo apt-get install -y apache2 php libapache2-mod-php php-mbstring php-xml php-cli jq acl
+
+echo -e "${GREEN}✓${NC} Packages installed"
+
+# ── 2. Ensure document root exists ────────────────────────────────────────
+echo ""
+echo "→ Ensuring document root exists: $DOCROOT"
+
+sudo mkdir -p "$DOCROOT"
+echo -e "${GREEN}✓${NC} Document root ready"
+
+# ── 3. Set ownership and permissions for Apache + current user ────────────
+echo ""
+echo "→ Setting permissions for user '$CURRENT_USER' and Apache user '$APACHE_USER'..."
+
+# Ensure ACL support is available (should be installed now)
+if ! command -v setfacl &>/dev/null; then
+    echo "  Installing ACL tools..."
+    sudo apt-get install -y acl
+fi
+
+# Set ownership to current user (so user can easily create files)
+sudo chown -R "$CURRENT_USER:$CURRENT_USER" "$DOCROOT"
+
+# Set base permissions
+sudo chmod 0755 "$DOCROOT"
+
+# Set ACLs so both the current user and Apache can read/write
+sudo setfacl -R -m u:"$CURRENT_USER":rwx,u:"$APACHE_USER":rwx "$DOCROOT"
+sudo setfacl -R -d -m u:"$CURRENT_USER":rwx,u:"$APACHE_USER":rwx "$DOCROOT"
+
+# Also allow the apache group to access
+sudo setfacl -R -m g:"$APACHE_GROUP":r-x "$DOCROOT"
+sudo setfacl -R -d -m g:"$APACHE_GROUP":r-x "$DOCROOT"
+
+echo -e "${GREEN}✓${NC} Permissions configured (ACLs set for $CURRENT_USER and $APACHE_USER)"
+
+# ── 4. Create/update Apache configuration ─────────────────────────────────
+echo ""
+echo "→ Creating Apache configuration: $APACHE_CONF"
+
+sudo tee "$APACHE_CONF" > /dev/null << EOF
+# Development environment - serve /home/josef/Code on localhost
+<Directory "$DOCROOT">
+    Options Indexes FollowSymLinks
+    AllowOverride All
+    Require all granted
+
+    # Enable directory listing if no index file found
+    DirectoryIndex index.php index.html index.htm
+</Directory>
+
+# Ensure PHP files are processed
+<FilesMatch \.php$>
+    SetHandler application/x-httpd-php
+</FilesMatch>
+EOF
+
+sudo a2enconf dev > /dev/null
+
+echo -e "${GREEN}✓${NC} Apache configuration written and enabled"
+
+# ── 5. Configure PHP for development ──────────────────────────────────────
+echo ""
+echo "→ Configuring PHP for development..."
+
+PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
+PHP_INI="/etc/php/$PHP_VERSION/apache2/php.ini"
+
+if [[ -f "$PHP_INI" ]]; then
+    # Backup original
+    sudo cp "$PHP_INI" "$PHP_INI.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true
+
+    # Enable error display for development
+    sudo sed -i 's/^display_errors = .*/display_errors = On/' "$PHP_INI" 2>/dev/null || true
+    sudo sed -i 's/^display_startup_errors = .*/display_startup_errors = On/' "$PHP_INI" 2>/dev/null || true
+    sudo sed -i 's/^error_reporting = .*/error_reporting = E_ALL/' "$PHP_INI" 2>/dev/null || true
+
+    echo -e "${GREEN}✓${NC} PHP configured for development (errors displayed)"
+else
+    echo -e "${YELLOW}WARNING:${NC} PHP ini not found at $PHP_INI, skipping PHP configuration"
+fi
+
+# ── 6. Configure mail sending (msmtp) ──────────────────────────────────────
+echo ""
+echo "→ Installing and configuring msmtp for outgoing mail..."
+
+sudo apt-get install -y msmtp msmtp-mta
+
+MSMTP_CONF="/etc/msmtprc"
+sudo tee "$MSMTP_CONF" > /dev/null << 'EOF'
+defaults
+auth off
+tls on
+tls_certcheck off
+port 25
+host mailpit.medowar.de
+
+account default
+from josef@dev-framework13.med0.de
+EOF
+
+# World-readable: no credentials stored, and PHP's mail() (running as
+# www-data) needs to read this file when invoking msmtp as sendmail.
+sudo chown root:root "$MSMTP_CONF"
+sudo chmod 644 "$MSMTP_CONF"
+
+echo -e "${GREEN}✓${NC} msmtp installed and configured ($MSMTP_CONF)"
+
+# ── 7. Enable and start apache2 ────────────────────────────────────────────
+echo ""
+echo "→ Enabling and starting apache2..."
+
+sudo systemctl enable apache2
+sudo systemctl restart apache2
+
+echo -e "${GREEN}✓${NC} Apache (apache2) is running"
+
+# ── 8. Configure AppArmor permissions ──────────────────────────────────────
+echo ""
+echo "→ Checking AppArmor permissions..."
+
+if command -v aa-status &>/dev/null; then
+    if sudo aa-status --enabled 2>/dev/null; then
+        echo "  AppArmor is enabled. The default apache2 profile permits"
+        echo "  read/write access under $DOCROOT, so no changes are needed."
+        echo "  If you see denials, check: sudo aa-status | grep apache2"
+        echo -e "${GREEN}✓${NC} AppArmor check complete"
+    else
+        echo "  AppArmor is installed but not enabled, skipping"
+    fi
+else
+    echo "  (AppArmor tools not found, skipping AppArmor configuration)"
+fi
+
+# ── 9. Open firewall for HTTP ─────────────────────────────────────────────
+echo ""
+echo "→ Configuring firewall for HTTP..."
+
+if command -v ufw &>/dev/null; then
+    if sudo ufw status | grep -qw active; then
+        sudo ufw allow "Apache" 2>/dev/null || sudo ufw allow 80/tcp 2>/dev/null || true
+        echo -e "${GREEN}✓${NC} Firewall updated (HTTP allowed)"
+    else
+        echo "  ufw is installed but not active, skipping firewall rule"
+    fi
+else
+    echo "  (ufw not found, skipping firewall configuration)"
+fi
+
+# ── 10. Create a test PHP file ─────────────────────────────────────────────
+echo ""
+echo "→ Creating test PHP file..."
+
+TEST_FILE="$DOCROOT/info.php"
+sudo tee "$TEST_FILE" > /dev/null << 'EOF'
+<?php
+phpinfo();
+?>
+EOF
+
+# Set proper ownership on the test file
+sudo chown "$CURRENT_USER:$CURRENT_USER" "$TEST_FILE"
+sudo setfacl -m u:"$APACHE_USER":r "$TEST_FILE"
+
+echo -e "${GREEN}✓${NC} Test file created: $TEST_FILE"
+
+# ── Done ───────────────────────────────────────────────────────────────────
+echo ""
+echo -e "${GREEN}========================================${NC}"
+echo -e "${GREEN}  Setup complete!${NC}"
+echo -e "${GREEN}========================================${NC}"
+echo ""
+echo "  Document root : $DOCROOT"
+echo "  Served at     : http://localhost/"
+echo "  Test page     : http://localhost/info.php"
+echo ""
+echo "  Next steps:"
+echo "  1. Open http://localhost/ in your browser"
+echo "  2. Place your PHP files in $DOCROOT"
+echo "  3. Check apache2 status:  sudo systemctl status apache2"
+echo "  4. View PHP errors:       sudo tail -f /var/log/apache2/error.log"
+echo "  5. Check AppArmor denials: sudo journalctl -k | grep -i apparmor"
+echo "  6. Test mail sending:      echo 'test' | msmtp your@address"
+echo ""
+echo -e "${YELLOW}Note:${NC} Files created in $DOCROOT will be owned by $CURRENT_USER"
+echo "      and accessible by Apache. Use standard file permissions"
+echo "      or ACLs if you need to adjust access for specific files."
+echo ""