mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-07-02 21:12:07 +00:00
279 lines
14 KiB
Text
279 lines
14 KiB
Text
# --- Function to check and install Docker ---
|
||
fn_install_docker() {
|
||
echo "Checking for Docker..."
|
||
if command -v docker &> /dev/null; then
|
||
echo "Docker is already installed."
|
||
docker --version
|
||
return 0
|
||
fi
|
||
|
||
echo "Docker not found. Attempting to install Docker..."
|
||
if [[ -x "$(command -v apt-get)" ]]; then
|
||
echo "Attempting Docker installation for Debian/Ubuntu..."
|
||
apt-get update -y
|
||
apt-get install -y apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release
|
||
install -m 0755 -d /etc/apt/keyrings # Ensure keyring directory exists
|
||
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release && echo "$ID")/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||
echo \
|
||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/$(. /etc/os-release && echo "$ID") \
|
||
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||
apt-get update -y
|
||
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin || {
|
||
echo -e "${red}Docker installation via apt failed. Trying convenience script...${plain}"
|
||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||
sh get-docker.sh || {
|
||
echo -e "${red}Docker installation failed. Please install Docker manually and re-run this script.${plain}"
|
||
exit 1
|
||
}
|
||
rm get-docker.sh
|
||
}
|
||
elif [[ -x "$(command -v yum)" ]]; then
|
||
echo "Attempting Docker installation for CentOS/RHEL..."
|
||
yum install -y yum-utils
|
||
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||
yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin || {
|
||
echo -e "${red}Docker installation via yum failed. Trying convenience script...${plain}"
|
||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||
sh get-docker.sh || {
|
||
echo -e "${red}Docker installation failed. Please install Docker manually and re-run this script.${plain}"
|
||
exit 1
|
||
}
|
||
rm get-docker.sh
|
||
}
|
||
elif [[ -x "$(command -v dnf)" ]]; then
|
||
echo "Attempting Docker installation for Fedora..."
|
||
dnf -y install dnf-plugins-core
|
||
dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
|
||
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin || {
|
||
echo -e "${red}Docker installation via dnf failed. Please install Docker manually and re-run this script.${plain}"
|
||
exit 1
|
||
}
|
||
else
|
||
echo -e "${red}Unsupported package manager for Docker auto-installation. Trying convenience script...${plain}"
|
||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||
sh get-docker.sh || {
|
||
echo -e "${red}Docker installation failed. Please install Docker manually and re-run this script.${plain}"
|
||
exit 1
|
||
}
|
||
rm get-docker.sh
|
||
fi
|
||
|
||
if ! systemctl is-active --quiet docker; then
|
||
systemctl start docker
|
||
fi
|
||
if ! systemctl is-enabled --quiet docker; then
|
||
systemctl enable docker
|
||
fi
|
||
echo "Docker installed and started."
|
||
docker --version
|
||
}
|
||
|
||
# --- Function to check and install Docker Compose ---
|
||
fn_install_docker_compose() {
|
||
echo "Checking for Docker Compose..."
|
||
if docker compose version &> /dev/null; then
|
||
echo "Docker Compose (plugin) is already installed."
|
||
docker compose version
|
||
return 0
|
||
fi
|
||
|
||
echo "Docker Compose (plugin) not found."
|
||
echo "It's usually included with recent Docker Engine installations (as docker-compose-plugin)."
|
||
echo "If Docker was just installed, it might already be there as part of docker-ce or docker-ce-cli."
|
||
echo "Verifying if 'docker-compose-plugin' can be installed or is part of 'docker-ce-cli' update..."
|
||
|
||
# Attempt to install or update packages that might include the compose plugin
|
||
if [[ -x "$(command -v apt-get)" ]]; then
|
||
apt-get install -y docker-compose-plugin docker-ce-cli || echo -e "${yellow}Attempt to install/update docker-compose-plugin via apt failed or already up-to-date.${plain}"
|
||
elif [[ -x "$(command -v yum)" ]]; then
|
||
yum install -y docker-compose-plugin docker-ce-cli || echo -e "${yellow}Attempt to install/update docker-compose-plugin via yum failed or already up-to-date.${plain}"
|
||
elif [[ -x "$(command -v dnf)" ]]; then
|
||
dnf install -y docker-compose-plugin docker-ce-cli || echo -e "${yellow}Attempt to install/update docker-compose-plugin via dnf failed or already up-to-date.${plain}"
|
||
fi
|
||
|
||
# Re-check after attempting plugin install
|
||
if docker compose version &> /dev/null; then
|
||
echo "Docker Compose (plugin) is now available."
|
||
docker compose version
|
||
return 0
|
||
fi
|
||
|
||
echo -e "${yellow}Docker Compose (plugin) still not found. Checking for legacy docker-compose (standalone)...${plain}"
|
||
if command -v docker-compose &> /dev/null; then
|
||
echo "Legacy docker-compose found."
|
||
docker-compose --version
|
||
echo -e "${yellow}Warning: Legacy docker-compose is deprecated. Consider upgrading your Docker setup to use the Docker Compose plugin (docker compose).${plain}"
|
||
return 0
|
||
fi
|
||
|
||
echo "Attempting to install legacy docker-compose as a fallback..."
|
||
LATEST_COMPOSE_VERSION=\$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\\\" -f4)
|
||
if [ -z "\$LATEST_COMPOSE_VERSION" ]; then
|
||
echo -e "${red}Failed to fetch latest docker-compose version. Please install Docker Compose manually.${plain}"
|
||
exit 1
|
||
fi
|
||
# Try common locations for Docker CLI plugins or general executables
|
||
INSTALL_PATH1="/usr/local/lib/docker/cli-plugins"
|
||
INSTALL_PATH2="/usr/libexec/docker/cli-plugins" # Original path in some setups
|
||
INSTALL_PATH3="/usr/local/bin" # Common for general executables
|
||
|
||
mkdir -p \$INSTALL_PATH1 && \
|
||
curl -SL https://github.com/docker/compose/releases/download/\$LATEST_COMPOSE_VERSION/docker-compose-\$(uname -s)-\$(uname -m) -o \$INSTALL_PATH1/docker-compose && \
|
||
chmod +x \$INSTALL_PATH1/docker-compose || \
|
||
(mkdir -p \$INSTALL_PATH2 && \
|
||
curl -SL https://github.com/docker/compose/releases/download/\$LATEST_COMPOSE_VERSION/docker-compose-\$(uname -s)-\$(uname -m) -o \$INSTALL_PATH2/docker-compose && \
|
||
chmod +x \$INSTALL_PATH2/docker-compose) || \
|
||
(curl -SL https://github.com/docker/compose/releases/download/\$LATEST_COMPOSE_VERSION/docker-compose-\$(uname -s)-\$(uname -m) -o \$INSTALL_PATH3/docker-compose && \
|
||
chmod +x \$INSTALL_PATH3/docker-compose) || \
|
||
{
|
||
echo -e "${red}Failed to download and install legacy docker-compose in standard paths. Please install Docker Compose manually.${plain}"
|
||
exit 1
|
||
}
|
||
|
||
# Check if installed version is now callable as `docker-compose` or `docker compose`
|
||
if docker compose version &> /dev/null; then
|
||
echo "Docker Compose (plugin) became available after legacy install attempt (possibly due to PATH or Docker restart)."
|
||
elif command -v docker-compose &> /dev/null; then
|
||
echo "Legacy docker-compose installed successfully."
|
||
docker-compose --version
|
||
else
|
||
echo -e "${red}Failed to make legacy docker-compose command available. Please check your PATH or install manually.${plain}"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# --- Color definitions ---
|
||
red='[0;31m'
|
||
green='[0;32m'
|
||
blue='[0;34m'
|
||
yellow='[0;33m'
|
||
plain='[0m'
|
||
|
||
# --- Main part of the new install script (draft) ---
|
||
main_install_logic() {
|
||
echo -e "\${blue}3X-UI New Frontend Docker-based Installer\${plain}"
|
||
|
||
# Check root
|
||
[[ \$EUID -ne 0 ]] && echo -e "\${red}Fatal error: \${plain} Please run this script with root privilege" && exit 1
|
||
|
||
# Install base dependencies
|
||
echo -e "\${blue}Checking base dependencies (curl, tar, git)...${plain}"
|
||
command -v curl >/dev/null 2>&1 || { echo >&2 -e "\${red}curl is required but it's not installed. Please install it first. Aborting.\${plain}"; exit 1; }
|
||
command -v tar >/dev/null 2>&1 || { echo >&2 -e "\${red}tar is required but it's not installed. Please install it first. Aborting.\${plain}"; exit 1; }
|
||
command -v git >/dev/null 2>&1 || { echo >&2 -e "\${red}git is required but it's not installed. Please install it first. Aborting.\${plain}"; exit 1; }
|
||
echo -e "\${green}Base dependencies checked.\${plain}"
|
||
|
||
# Install Docker and Docker Compose
|
||
fn_install_docker
|
||
fn_install_docker_compose
|
||
|
||
# Define installation directory
|
||
install_dir="/opt/3x-ui-docker"
|
||
echo -e "\${yellow}3X-UI Docker setup will be located in: \${install_dir}\${plain}"
|
||
mkdir -p "\$install_dir"
|
||
cd "\$install_dir" || { echo -e "\${red}Failed to cd to \${install_dir}\${plain}"; exit 1; }
|
||
|
||
# Clone or download the repository
|
||
repo_url="https://github.com/MHSanaei/3x-ui.git" # User should replace with their fork if necessary
|
||
repo_name="3x-ui-source" # Name of the directory for the cloned repo
|
||
|
||
if [ -d "\$repo_name" ] && [ -d "\$repo_name/.git" ]; then
|
||
echo -e "\${yellow}Repository directory '\$repo_name' found. Attempting to update...${plain}"
|
||
cd "\$repo_name" || exit 1
|
||
git pull origin \$(git rev-parse --abbrev-ref HEAD) || { # Pull current branch
|
||
echo -e "${red}Failed to pull latest changes. Please check for conflicts or issues.${plain}"
|
||
# Optionally, allow script to continue with existing code or exit
|
||
}
|
||
cd ..
|
||
else
|
||
echo "Cloning repository from \${repo_url} into '\$repo_name'..."
|
||
rm -rf "\$repo_name" # Remove if it exists but isn't a git repo
|
||
git clone --depth 1 "\$repo_url" "\$repo_name" || {
|
||
echo -e "${red}Failed to clone repository. Please check the URL and your internet connection.${plain}"
|
||
exit 1
|
||
}
|
||
fi
|
||
|
||
# Navigate into the cloned repository directory where docker-compose.yml is expected
|
||
cd "\$repo_name" || { echo -e "\${red}Failed to cd into repository directory '\$repo_name'.\${plain}"; exit 1; }
|
||
|
||
# Ensure Dockerfile.backend and docker-compose.yml are present (they should be in the repo)
|
||
if [ ! -f "Dockerfile.backend" ] || [ ! -f "docker-compose.yml" ]; then
|
||
echo -e "${red}Critical Docker files (Dockerfile.backend or docker-compose.yml) not found in the repository root.${plain}"
|
||
echo -e "${yellow}Please ensure these files are present. If you cloned an old version, try removing the '\$repo_name' directory and re-running the script to get the latest version.${plain}"
|
||
exit 1
|
||
fi
|
||
# Ensure the frontend Dockerfile is present
|
||
if [ ! -f "new-frontend/Dockerfile" ]; then
|
||
echo -e "${red}Frontend Dockerfile (new-frontend/Dockerfile) not found.${plain}"
|
||
echo -e "${yellow}The frontend might not have been prepared correctly in the repository.${plain}"
|
||
exit 1
|
||
fi
|
||
|
||
|
||
echo "Creating data directories (db, cert) if they don't exist..."
|
||
mkdir -p db
|
||
mkdir -p cert
|
||
|
||
echo "Creating/Updating .env file with default settings..."
|
||
cat << EOF_ENV > .env
|
||
# .env for 3x-ui docker-compose
|
||
PANEL_NAME=3x-ui
|
||
FRONTEND_PORT=3000
|
||
BACKEND_PANEL_PORT=2053
|
||
XRAY_VMESS_AEAD_FORCED=false
|
||
XUI_ENABLE_FAIL2BAN=true
|
||
NEXT_PUBLIC_API_BASE_URL=http://backend:2053
|
||
# To access panel from host via browser using mapped port, use http://localhost:2053 or http://<server_ip>:2053
|
||
# If your backend has a base path (e.g. /xui), add it to NEXT_PUBLIC_API_BASE_URL: http://backend:2053/xui
|
||
# Ensure XUI_BASE_PATH (if used by Go backend) matches this.
|
||
|
||
# For Xray-core reality settings, you might need to specify domains/shortids, etc.
|
||
# These are not covered by default .env. User should add them if needed.
|
||
EOF_ENV
|
||
echo ".env file created/updated."
|
||
|
||
echo -e "\${blue}Building and starting services with Docker Compose... (This might take a while)${plain}"
|
||
if docker compose up -d --build --remove-orphans; then
|
||
echo -e "\${green}3X-UI services started successfully!\${plain}"
|
||
echo -e "Frontend should be accessible at: http://<your_server_ip>:\${FRONTEND_PORT:-3000}"
|
||
echo -e "Backend panel (API) is available at port: \${BACKEND_PANEL_PORT:-2053} (primarily for frontend access)"
|
||
echo -e "To manage services, use 'docker compose' commands in '\$(pwd)' directory."
|
||
echo -e "(e.g., \`docker compose logs -f backend\`, \`docker compose stop\`, \`docker compose down\`)"
|
||
else
|
||
echo -e "\${red}Failed to start services with Docker Compose. Please check logs above and Docker Compose logs (\`docker compose logs -f\` for details).${plain}"
|
||
exit 1
|
||
fi
|
||
|
||
echo -e "\${green}Installation script finished.\${plain}"
|
||
}
|
||
|
||
# Note: To make this a runnable script, you would save fn_install_docker,
|
||
# fn_install_docker_compose, the color vars, and main_install_logic
|
||
# into a single install.sh file, then call main_install_logic at the end.
|
||
# Example:
|
||
# #!/bin/bash
|
||
# ... fn_install_docker ...
|
||
# ... fn_install_docker_compose ...
|
||
# ... color definitions ...
|
||
# ... main_install_logic ...
|
||
# main_install_logic
|
||
# exit 0
|
||
# This structure is for the agent to provide the components.
|
||
# The final assembly into a single install.sh is implicitly the next step if these blocks are approved.
|
||
|
||
echo "---------------------------------------------------------------------"
|
||
echo "NEW INSTALL.SH SCRIPT DRAFT COMPONENTS CREATED"
|
||
echo "(fn_install_docker, fn_install_docker_compose, main_install_logic)"
|
||
echo "---------------------------------------------------------------------"
|
||
|
||
# For the subtask, the output is the text above.
|
||
# The actual install.sh file in the repo is not modified by this tool directly yet.
|
||
# The agent will take these generated functions and structure to build the final install.sh.
|
||
# This is a way to output the bash code as requested by the subtask structure.
|
||
# The previous Dockerfile and docker-compose.yml are assumed to be in the repo root for the clone logic.
|
||
# The new-frontend/Dockerfile should also be in the repo.
|
||
# This script assumes it's run from a location *outside* the cloned repo directory initially,
|
||
# then it clones the repo into a subdirectory (e.g., /opt/3x-ui-docker/3x-ui-source) and Cds into it.
|
||
# The .env file and data volumes (db, cert) will reside in this cloned directory.
|