CADDY + Opening ports installation
Choose your system:
Variants:
Install/Uninstall script (Docker /
Warning: Undefined array key "
Deprecated: htmlspecialchars(): Passing null to parameter " in /var/www/scripts/PHP_HTML/maininstall.php on line 49
Warning: Trying to access array offset on null in /var/www/scripts/PHP_HTML/maininstall.php on line 49
Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/scripts/PHP_HTML/maininstall.php on line 49
)
#!/bin/bash
set +e
# ========== COLORS ==========
NC='\033[0m'
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[38;5;117m'
BOLD='\033[1m'
# ========== LOG FUNCTIONS ==========
log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
log_error() { echo -e "${RED}[ERROR]${NC} $*"; }
log_success() { echo -e "${GREEN}[OK]${NC} $*"; }
# ========== PRINT BOX FUNCTION ==========
print_in_box() {
local title="$1"
shift
local lines=("$@")
local max_len=${#title}
for line in "${lines[@]}"; do
(( ${#line} > max_len )) && max_len=${#line}
done
local border_top="┌$(printf '─%.0s' $(seq 1 $((max_len + 2))))┐"
local border_bottom="└$(printf '─%.0s' $(seq 1 $((max_len + 2))))┘"
echo -e "${BLUE}${border_top}${NC}"
printf "${BLUE}│ ${BOLD}%-*s${BLUE} │${NC}\n" "$max_len" "$title"
echo -e "${BLUE}├$(printf '─%.0s' $(seq 1 $((max_len + 2))))┤${NC}"
for line in "${lines[@]}"; do
printf "${BLUE}│ %-*s │${NC}\n" "$max_len" "$line"
done
echo -e "${BLUE}${border_bottom}${NC}"
}
# ========== SPINNER & RUN TASK ==========
spinner_pid=""
start_spinner() {
local msg="$1"
echo -ne "${BLUE}[INFO]${NC} $msg... "
trap stop_spinner INT
(
local spin='-\|/'
while true; do
for i in $(seq 0 $(( ${#spin} - 1 )) ); do
echo -ne "\b${spin:$i:1}"
sleep 0.1
done
done
) & spinner_pid=$!
disown
}
stop_spinner() {
if [[ -n "$spinner_pid" ]]; then
kill "$spinner_pid" &>/dev/null || true
wait "$spinner_pid" 2>/dev/null || true
spinner_pid=""
fi
echo -e "\b${GREEN}✓${NC}"
trap - INT
}
run_step() {
start_spinner "$1"
shift
"$@" &>/dev/null
stop_spinner
}
run_multistep() {
start_spinner "$1"
shift
{
"$@"
} &>/dev/null
stop_spinner
}
# ========== FILE/DIRECTORY DEFINITIONS ==========
COMPOSE_FILE="docker-compose.yml"
CADDY_DIR="caddy_config"
CADDY_FILE="$CADDY_DIR/Caddyfile"
CADDY_DATA_DIR="caddy_data"
PHP_DIR="php_config"
PHP_DOCKERFILE="$PHP_DIR/Dockerfile"
WEB_DIR="www"
TEST_FILE="$WEB_DIR/index.php"
DOCKER_COMPOSE_CMD="" # Will be set by check_deps
# ========== DETECT DISTRIBUTION ==========
DISTRO=""
if [[ -f /etc/os-release ]]; then
. /etc/os-release
DISTRO=$(echo "$ID" | tr '[:upper:]' '[:lower:]')
fi
[[ "$DISTRO" == "rhel" ]] && DISTRO="centos"
log_info "Detected distribution: ${BOLD}${DISTRO}${NC}"
# ========== PACKAGE UNINSTALL COMMANDS ==========
DOCKER_PKG_LIST="docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras"
DOCKER_PURGE_CMD=""
DOCKER_CLEANUP_CMD="sudo rm -rf /var/lib/docker && sudo rm -rf /var/lib/containerd && sudo rm -rf /etc/docker"
case "$DISTRO" in
debian|ubuntu)
DOCKER_PURGE_CMD="sudo apt-get purge -y $DOCKER_PKG_LIST"
;;
almalinux|rocky|centos|fedora)
DOCKER_PURGE_CMD="sudo dnf remove -y $DOCKER_PKG_LIST"
;;
*)
DOCKER_PURGE_CMD="echo 'Distro not supported for auto-uninstall'"
;;
esac
# ========== CHECK DEPENDENCIES & INSTALL ==========
check_deps() {
local docker_ok=0
local compose_ok=0
# Check for Docker
if ! command -v docker >/dev/null 2>&1; then
log_warn "Docker is not installed."
else
docker_ok=1
fi
# Check for Docker Compose (v2)
if ! docker compose version &>/dev/null 2>&1; then
# Check for v1 as fallback
if ! command -v docker-compose &>/dev/null 2>&1; then
log_warn "Docker Compose (v1 or v2) is not installed."
else
compose_ok=1
DOCKER_COMPOSE_CMD="docker-compose"
fi
else
compose_ok=1
DOCKER_COMPOSE_CMD="docker compose"
fi
# If both are ok, we're done
if [[ "$docker_ok" -eq 1 && "$compose_ok" -eq 1 ]]; then
log_success "Docker & Docker Compose found. Using: ${BOLD}${DOCKER_COMPOSE_CMD}${NC}"
return 0
fi
# If something is missing, ask to install
log_info "Docker or Docker Compose is missing."
read -p "$(echo -e "${YELLOW}[INFO]${NC} Attempt to install Docker & Docker Compose automatically? [y/n]: ")" install_docker_prompt
if [[ ! "$install_docker_prompt" =~ ^[Yy]$ ]]; then
log_error "Cannot proceed without Docker. Exiting."
exit 1
fi
# --- Installation Step ---
log_info "Downloading Docker installation script..."
if ! curl -fsSL https://get.docker.com -o get-docker.sh; then
log_error "Failed to download Docker install script."
exit 1
fi
log_info "Running Docker installation script (requires sudo)..."
run_multistep "Installing Docker" sudo sh get-docker.sh
# Check if install succeeded
if ! command -v docker >/dev/null 2>&1; then
log_error "Docker installation failed. Please check the output and run manually."
rm -f get-docker.sh
exit 1
fi
log_success "Docker & Docker Compose installed successfully."
rm -f get-docker.sh # Clean up
# --- Post-install ---
run_step "Adding current user ($USER) to 'docker' group" sudo usermod -aG docker $USER
log_success "User $USER added to the 'docker' group."
echo -e "\n${BOLD}${RED}!!!!!!!!!!!!!!!!!! IMPORTANT ACTION REQUIRED !!!!!!!!!!!!!!!!!!${NC}"
local lines=(
"You MUST log out and log back in for group changes to take effect."
"Alternatively, you can run: newgrp docker"
" "
"Please re-run this script AFTER logging out and back in."
)
print_in_box "Installation Complete - RELOGIN REQUIRED" "${lines[@]}"
exit 0 # Exit script gracefully, forcing user to relog
}
# ========== MENU ==========
echo -e "\n${BOLD}${YELLOW}=== Docker Caddy + PHP Stack Manager ===${NC}\n"
PS3="Choose an option: "
select opt in "Deploy (Start stack)" "Remove (Stop and delete stack)" "Uninstall Docker" "Exit"; do
case $opt in
"Deploy (Start stack)") ACTION=1; break;;
"Remove (Stop and delete stack)") ACTION=2; break;;
"Uninstall Docker") ACTION=3; break;;
Exit) exit 0;;
*) log_error "Invalid option";;
esac
done
# ========== DEPLOY ==========
if [[ "$ACTION" == "1" ]]; then
echo -e "\n${BOLD}${YELLOW}=== Starting Stack ===${NC}\n"
check_deps
run_step "Creating directory structure" mkdir -p "$CADDY_DIR" "$CADDY_DATA_DIR" "$PHP_DIR" "$WEB_DIR"
# --- Create docker-compose.yml ---
if [[ ! -f "$COMPOSE_FILE" ]]; then
run_step "Generating $COMPOSE_FILE"
cat <<EOF > "$COMPOSE_FILE"
version: '3.8'
services:
caddy:
image: caddy:latest
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp" # For HTTP/3
volumes:
- ./$CADDY_FILE:/etc/caddy/Caddyfile
- ./$WEB_DIR:/var/www/html
- ./$CADDY_DATA_DIR:/data # For SSL certs etc.
depends_on:
- php
php:
build:
context: ./$PHP_DIR
restart: unless-stopped
volumes:
- ./$WEB_DIR:/var/www/html
volumes:
$CADDY_DATA_DIR:
EOF
else
log_warn "$COMPOSE_FILE already exists, skipping."
fi
# --- Create Caddyfile ---
if [[ ! -f "$CADDY_FILE" ]]; then
run_step "Generating $CADDY_FILE"
cat <<EOF > "$CADDY_FILE"
{
# Email for Let's Encrypt
email user@example.com
}
:80 {
# Set the root directory
root * /var/www/html
# Enable PHP-FPM
# Forward PHP requests to the 'php' container on port 9000
php_fastcgi php:9000
# Enable file serving
file_server
}
# You can add your domain when ready, e.g.:
# yourdomain.com {
# root * /var/www/html
# php_fastcgi php:9000
# file_server
# }
EOF
else
log_warn "$CADDY_FILE already exists, skipping."
fi
# --- Create PHP Dockerfile ---
if [[ ! -f "$PHP_DOCKERFILE" ]]; then
run_step "Generating $PHP_DOCKERFILE (with extensions)"
cat <<EOF > "$PHP_DOCKERFILE"
# Using PHP-FPM image (Alpine for smaller size)
FROM php:8.3-fpm-alpine
# Install dependencies and extensions (as per original script)
RUN apk add --no-cache \$PHPIZE_DEPS \
&& docker-php-ext-install pdo pdo_mysql mbstring xml
EOF
else
log_warn "$PHP_DOCKERFILE already exists, skipping."
fi
# --- Create test file ---
if [[ ! -f "$TEST_FILE" ]]; then
run_step "Generating test file $TEST_FILE"
cat <<EOF > "$TEST_FILE"
<?php
phpinfo();
?>
EOF
else
log_warn "$TEST_FILE already exists, skipping."
fi
run_multistep "Building PHP image" $DOCKER_COMPOSE_CMD build
run_multistep "Pulling Caddy image" $DOCKER_COMPOSE_CMD pull caddy
run_multistep "Starting containers in background" $DOCKER_COMPOSE_CMD up -d
lines=(
"Caddy & PHP-FPM are running."
" "
"Web root dir : $PWD/$WEB_DIR"
"Caddy Config : $PWD/$CADDY_FILE"
"PHP Config : $PWD/$PHP_DOCKERFILE"
"Ports (HTTP) : 80"
"Ports (HTTPS) : 443"
" "
"Test at: http://localhost"
)
print_in_box "Stack Deployed" "${lines[@]}"
log_warn "Remember to open ports 80 and 443 on your HOST firewall (e.g., ufw, firewalld)."
log_success "Deployment complete."
# ========== REMOVE STACK ==========
elif [[ "$ACTION" == "2" ]]; then
echo -e "\n${BOLD}${YELLOW}=== Stopping and Removing Stack ===${NC}\n"
check_deps
if [[ ! -f "$COMPOSE_FILE" ]]; then
log_error "$COMPOSE_FILE not found. Are you in the correct directory?"
exit 1
fi
run_multistep "Stopping and removing containers" $DOCKER_COMPOSE_CMD down
read -p "$(echo -e "${YELLOW}[INFO]${NC} Remove config files ($COMPOSE_FILE, $CADDY_DIR, $PHP_DIR)? [y/n]: ")" remove_configs
if [[ "$remove_configs" =~ ^[Yy]$ ]]; then
run_step "Removing config files" rm -rf "$COMPOSE_FILE" "$CADDY_DIR" "$PHP_DIR"
fi
read -p "$(echo -e "${YELLOW}[INFO]${NC} Remove web data (directory $WEB_DIR)? [y/n]: ")" remove_www
if [[ "$remove_www" =~ ^[YY]$ ]]; then
run_step "Removing web data" rm -rf "$WEB_DIR"
fi
read -p "$(echo -e "${YELLOW}[INFO]${NC} Remove persistent Caddy data (SSL certs in $CADDY_DATA_DIR)? [y/n]: ")" remove_caddy_data
if [[ "$remove_caddy_data" =~ ^[YY]$ ]]; then
run_step "Removing Caddy data" rm -rf "$CADDY_DATA_DIR"
fi
read -p "$(echo -e "${YELLOW}[INFO]${NC} Clean unused Docker images (prune)? [y/n]: ")" prune_images
if [[ "$prune_images" =~ ^[Yy]$ ]]; then
run_multistep "Pruning images" docker image prune -f
fi
log_success "Stack removal complete."
# ========== UNINSTALL DOCKER ==========
elif [[ "$ACTION" == "3" ]]; then
echo -e "\n${BOLD}${RED}=== UNINSTALL DOCKER ===${NC}\n"
if [[ "$DISTRO" == "" ]]; then
log_error "Unsupported distribution. Cannot determine package manager for uninstallation."
exit 1
fi
log_warn "${BOLD}This action is highly destructive and will completely remove Docker from this system.${NC}"
log_warn "It will purge all packages, data volumes, images, and configuration."
read -p "$(echo -e "${RED}[DANGER]${NC} Are you absolutely sure you want to uninstall Docker? [y/n]: ")" uninstall_docker_prompt
if [[ ! "$uninstall_docker_prompt" =~ ^[Yy]$ ]]; then
log_info "Docker uninstallation cancelled."
exit 0
fi
run_step "Stopping Docker service" sudo systemctl stop docker
run_multistep "Purging Docker packages" bash -c "$DOCKER_PURGE_CMD"
run_multistep "Deleting Docker data directories" bash -c "$DOCKER_CLEANUP_CMD"
# Remove user from docker group
if getent group docker | grep -q "\b$USER\b"; then
run_step "Removing user $USER from 'docker' group" sudo gpasswd -d $USER docker
else
log_info "User $USER is not in the 'docker' group, skipping."
fi
rm -f get-docker.sh # Clean up install script if it exists
log_success "Docker has been completely removed from the system."
fi
Use the following command to auto-download and run:
Warning: Undefined array key "
Deprecated: htmlspecialchars(): Passing null to parameter " in /var/www/scripts/PHP_HTML/autoscripts.php on line 87
Warning: Trying to access array offset on null in /var/www/scripts/PHP_HTML/autoscripts.php on line 87
curl -fsSL -o script.sh "https://krotek.serveblog.net/how-to-install/WEB-SERVER/CADDY/scripts.php?variant=docker&type=script&system=%3Cbr+%2F%3E%3Cb%3EDeprecated%3C%2Fb%3E%3A++htmlspecialchars%28%29%3A+Passing+null+to+parameter+" && chmod +x script.sh && sudo ./script.sh