cypht-org / cypht

Cypht: Lightweight Open Source webmail aggregator [PHP, JS]. Supports IMAP/SMTP, JMAP and soon EWS
http://cypht.org
GNU Lesser General Public License v2.1
1.01k stars 164 forks source link

Can Cypht 2 work on a cPanel account? #1154

Open rr10 opened 3 months ago

rr10 commented 3 months ago

Hi Cypht team,

I am interested in using Cypht Version 2 on a cPanel hosting account. Could you please confirm whether Cypht 2 is compatible with cPanel? If there are specific configurations or limitations that I should be aware of, I would appreciate the guidance.

Thank you!

marclaporte commented 3 months ago

Yes, it will install with manual instructions: https://www.cypht.org/install.html

If your cPanel has a one-click Tiki installer, you get Cypht within Tiki: https://doc.tiki.org/Cypht

rr10 commented 3 months ago

Thank you so much for your quick response and assistance. I really appreciate the support!

I'm currently having some difficulties proceeding with the installation of Cypht. I created a script that performs various tasks, such as checking PHP and Composer versions, managing files and directories, installing Composer dependencies, and creating the necessary directory structure. The script seems to work correctly, and after it's completed, I can see the application's login page.

However, I'm unsure of which credentials to use for logging in. I tried running php ./scripts/config_gen.php, and it seems to work without errors. However, when I run php ./scripts/setup_database.php after entering the correct values for DB_HOST, DB_USER, and DB_PASS in the .env file, I continuously get database connection errors like this:

Attempting to connect to database ... (6/10)
Attempting to connect to database ... (7/10)
Attempting to connect to database ... (8/10)
Attempting to connect to database ... (9/10)
Attempting to connect to database ... (10/10)
Unable to connect to database

It seems that the script is unable to correctly read the values from the .env file. I have double-checked the .env file, and everything seems to be in order. I also tried running the command manually, but without success.

Below is the script I created and used:

#!/bin/bash

# Script for checking PHP and Composer versions, managing files and directories,
# installing Composer dependencies, creating an hm3 directory structure, and setting permissions.

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

# Get the current directory
CURRENT_DIR=$(pwd)

# Get the user's home directory
HOME_DIR=$HOME

# Calculate the relative directory path
RELATIVE_DIR=${CURRENT_DIR#$HOME_DIR/}

# Replace slashes with underscores for safe directory naming
SAFE_DIR=$(echo "$RELATIVE_DIR" | tr '/' '_')

# Define the full path for the hm3 directory
HM3_DIR="${HOME_DIR}/Cypht_${SAFE_DIR}_hm3/hm3"

# Define the subdirectories under hm3
SUBDIRS=("attachments" "users" "app_data")

# Display directory paths
echo "Current directory: $CURRENT_DIR"
echo "User's home directory: $HOME_DIR"
echo "hm3 directory path: $HM3_DIR"

# Flag to track any errors
error_flag=false

# Function to compare versions
version_compare() {
    if [[ "$1" == "$2" ]]; then
        return 0
    fi

    local IFS=.
    local i ver1=($1) ver2=($2)
    for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do
        ver1[i]=0
    done
    for ((i=0; i<${#ver1[@]}; i++)); do
        if [[ -z ${ver2[i]} ]]; then
            ver2[i]=0
        fi
        if ((10#${ver1[i]} > 10#${ver2[i]})); then
            return 1
        fi
        if ((10#${ver1[i]} < 10#${ver2[i]})); then
            return 2
        fi
    done
    return 0
}

# Preliminary step: Fetch and download the latest Cypht release
echo
echo "Fetching the latest Cypht release information..."
LATEST_RELEASE=$(curl -s https://api.github.com/repos/cypht-org/cypht/releases/latest)
LATEST_TAG=$(echo "$LATEST_RELEASE" | grep -oP '"tag_name": "\K(.*)(?=")')
DOWNLOAD_URL="https://github.com/cypht-org/cypht/archive/refs/tags/$LATEST_TAG.zip"

read -p "Do you want to download and unzip the latest Cypht release (version $LATEST_TAG)? (y/n): " download_choice
if [[ "$download_choice" =~ ^[Yy]$ ]]; then
    echo "Downloading the latest Cypht release..."
    curl -L "$DOWNLOAD_URL" -o latest_cypht_release.zip

    echo "Unzipping the downloaded file..."
    unzip latest_cypht_release.zip

    # Find the unzipped directory (e.g., cypht-2.1.0)
    UNZIPPED_DIR=$(find . -type d -name "cypht-*")

    # Move contents to current directory, including hidden files
if [ -d "$UNZIPPED_DIR" ]; then
    echo "Moving files from $UNZIPPED_DIR to $CURRENT_DIR..."
    shopt -s dotglob  # Include hidden files in wildcard matches
    mv "$UNZIPPED_DIR"/* "$CURRENT_DIR"
    shopt -u dotglob  # Reset the dotglob option to its default state
    rm -rf "$UNZIPPED_DIR"
    echo -e "${GREEN}Files moved successfully.${NC}"
else
    echo -e "${RED}Error: Unzipped directory not found.${NC}"
fi

else
    echo -e "${GREEN}Proceeding with the assumption that the files are already downloaded and unzipped.${NC}"
fi

# Check PHP version
echo
echo "Checking PHP version (>=8.1 required)..."
PHP_VERSION=$(php -r 'echo PHP_VERSION;' | awk -F '.' '{print $1"."$2}')
REQUIRED_PHP_VERSION="8.1"

version_compare "$PHP_VERSION" "$REQUIRED_PHP_VERSION"
COMPARE_RESULT=$?

if [[ "$COMPARE_RESULT" == 2 ]]; then
    echo -e "${RED}Error: PHP version is $PHP_VERSION. Version >= 8.1 is required.${NC}"
    error_flag=true
else
    echo -e "${GREEN}PHP Version: $PHP_VERSION (OK)${NC}"
fi

# Check Composer version
echo
echo "Checking Composer version (>=2.0.0 required)..."
COMPOSER_VERSION=$(composer --version 2>/dev/null | awk '{print $3}' | awk -F '.' '{print $1"."$2}')
REQUIRED_COMPOSER_VERSION="2.0"

version_compare "$COMPOSER_VERSION" "$REQUIRED_COMPOSER_VERSION"
COMPARE_RESULT=$?

if [[ "$COMPARE_RESULT" == 2 ]]; then
    echo -e "${RED}Error: Composer version is $COMPOSER_VERSION. Version >= 2.0.0 is required.${NC}"
    error_flag=true
else
    echo -e "${GREEN}Composer Version: $COMPOSER_VERSION (OK)${NC}"
fi

# Check installed PHP extensions
echo
echo "Checking installed PHP extensions..."
PHP_MODULES=$(php -m)

# Check required extensions
REQUIRED_MODULES=("openssl" "mbstring" "curl")
for MODULE in "${REQUIRED_MODULES[@]}"; do
    if ! echo "$PHP_MODULES" | grep -qi "$MODULE"; then
        echo -e "${RED}Error: PHP extension $MODULE is not installed.${NC}"
        error_flag=true
    else
        echo -e "${GREEN}PHP extension $MODULE installed (OK)${NC}"
    fi
done

# Only proceed if no errors were detected
if [ "$error_flag" = false ]; then

   # Check for latest_cypht_release.zip file
echo
echo "Checking for latest_cypht_release.zip file..."
FILE_FOUND=$(find "$CURRENT_DIR" -maxdepth 1 -type f -name "latest_cypht_release.zip")

if [ -n "$FILE_FOUND" ]; then
    echo -e "${RED}File found: ${FILE_FOUND}${NC}"
    read -p "Do you want to delete this file? (y/n): " choice
    case "$choice" in 
    y|Y ) rm -f "$FILE_FOUND"; echo -e "${GREEN}File successfully deleted.${NC}";;
    * ) echo -e "${GREEN}File retained.${NC}";;
    esac
else
    echo -e "${GREEN}No latest_cypht_release.zip file found in the current directory.${NC}"
fi

    # Check for empty cypht-* directories
    echo
    echo "Checking for empty cypht-* directories..."
    DIR_FOUND=$(find "$CURRENT_DIR" -maxdepth 1 -type d -name "cypht-*")

    if [ -n "$DIR_FOUND" ]; then
        for dir in $DIR_FOUND; do
            if [ -z "$(ls -A "$dir")" ]; then
                echo -e "${RED}Empty directory found: $dir${NC}"
                read -p "Do you want to delete this directory? (y/n): " choice
                case "$choice" in 
                y|Y ) rm -rf "$dir"; echo -e "${GREEN}Directory successfully deleted.${NC}";;
                * ) echo -e "${GREEN}Directory retained.${NC}";;
                esac
            else
                echo -e "${GREEN}The directory $dir is not empty.${NC}"
            fi
        done
    else
        echo -e "${GREEN}No cypht-* directories found in the current directory.${NC}"
    fi

    # Run the composer install command
    echo
    echo "All requirements are met. Running 'composer install'..."

    if composer install; then
        echo -e "${GREEN}Composer installation completed successfully.${NC}"

         # Copy .env.example to .env
        if [ -f "$CURRENT_DIR/.env" ]; then
            read -p "The .env file already exists. Do you want to overwrite it? (y/n): " overwrite_choice
            case "$overwrite_choice" in 
              y|Y ) cp "$CURRENT_DIR/.env.example" "$CURRENT_DIR/.env"; echo -e "${GREEN}.env file overwritten from .env.example${NC}";;
              * ) echo -e "${GREEN}The existing .env file was retained.${NC}";;
            esac
        else
            cp "$CURRENT_DIR/.env.example" "$CURRENT_DIR/.env"
            echo -e "${GREEN}.env file created from .env.example${NC}"
        fi

        # Create the hm3 directory and subdirectories if they don't exist
        if [ ! -d "$HM3_DIR" ]; then
            mkdir -p "$HM3_DIR"
            chmod 755 "$HM3_DIR"
            echo -e "${GREEN}Main hm3 directory created and permissions set: $HM3_DIR${NC}"
        fi

        for subdir in "${SUBDIRS[@]}"; do
            if [ ! -d "$HM3_DIR/$subdir" ]; then
                mkdir -p "$HM3_DIR/$subdir"
                chmod 755 "$HM3_DIR/$subdir"
                echo -e "${GREEN}Subdirectory created and permissions set: $HM3_DIR/$subdir${NC}"
            else
                chmod 755 "$HM3_DIR/$subdir"
                echo -e "${GREEN}Subdirectory $HM3_DIR/$subdir already exists, permissions set to 755.${NC}"
            fi

        # Update the .env file with hm3 directory paths
        if [ -f "$CURRENT_DIR/.env" ]; then
            echo "Updating .env file with the correct directory paths..."

            sed -i "s|^USER_CONFIG_TYPE=.*|USER_CONFIG_TYPE=file|" "$CURRENT_DIR/.env"
            sed -i "s|^USER_SETTINGS_DIR=.*|USER_SETTINGS_DIR=$HM3_DIR/users|" "$CURRENT_DIR/.env"
            sed -i "s|^ATTACHMENT_DIR=.*|ATTACHMENT_DIR=$HM3_DIR/attachments|" "$CURRENT_DIR/.env"
            sed -i "s|^APP_DATA_DIR=.*|APP_DATA_DIR=$HM3_DIR/app_data|" "$CURRENT_DIR/.env"

            echo -e "${GREEN}.env file updated successfully.${NC}"
        else
            echo -e "${RED}Error: .env file not found in the current directory.${NC}"
        fi

        done

    else
        echo -e "${RED}Error during Composer installation.${NC}"
    fi

else
    echo -e "${RED}Error: Not all requirements were met. 'composer install' was not executed.${NC}"
fi

Any guidance on how to proceed would be greatly appreciated. Thanks again for all your support!

marclaporte commented 3 months ago

Wow! Looks like you did a good part of the job for https://github.com/cypht-org/cypht/issues/17

Please join us on https://gitter.im/cypht-org/community so a Cypht developer can do a screen share with you and make Cypht work for you.

marclaporte commented 3 months ago

@Shadow243 please test the script above and advise.

rr10 commented 3 months ago

Additionally, I'd like to clarify a specific part of the script that handles the creation of the hm3 directories. Based on the installation guidelines I found on the Cypht website, it appears that it's more secure to place the hm3 directory outside of the public_html folder. This is what the script does:

# Create the hm3 directory and subdirectories if they don't exist
if [ ! -d "$HM3_DIR" ]; then
    mkdir -p "$HM3_DIR"
    chmod 755 "$HM3_DIR"
    echo -e "${GREEN}Main hm3 directory created and permissions set: $HM3_DIR${NC}"
fi

for subdir in "${SUBDIRS[@]}"; do
    if [ ! -d "$HM3_DIR/$subdir" ]; then
        mkdir -p "$HM3_DIR/$subdir"
        chmod 755 "$HM3_DIR/$subdir"
        echo -e "${GREEN}Subdirectory created and permissions set: $HM3_DIR/$subdir${NC}"
    else
        chmod 755 "$HM3_DIR/$subdir"
        echo -e "${GREEN}Subdirectory $HM3_DIR/$subdir already exists, permissions set to 755.${NC}"
    fi
done

In this part of the script, the hm3 directory is created inside a folder that is named based on the installation folder. This allows multiple Cypht installations in different folders or subdirectories without conflict, as each installation has its own isolated hm3 directory structure.

The folder is created outside of the public_html directory for security reasons, but within a directory named according to the installation folder. This approach ensures that each installation is separated, and sensitive data remains secure while still being organized based on the installation paths.

Shadow243 commented 1 month ago
else
    echo -e "${RED}Error during Composer installation.${NC}"
fi

else echo -e "${RED}Error: Not all requirements were met. 'composer install' was not executed.${NC}" fi

Sorry for this late reply @rr10 , I just tried but i have a composer error, so a suggestion came to me: instead of reporting the error could we instead give a choice: i.e. ask if we want to install composer or cancel the operation or continue like that ?

here is the first answer during the first test

Screenshot 2024-09-30 at 22 17 16

I hade this error: Installer corrupt from https://getcomposer.org/download/ when trying to install composer, but after changing allow_url_fopen from Off to On

Screenshot 2024-09-30 at 22 37 42
Shadow243 commented 1 month ago

Check required extensions

REQUIRED_MODULES=("openssl" "mbstring" "curl") for MODULE in "${REQUIRED_MODULES[@]}"; do We're going to need to add more extensions to this list:

Screenshot 2024-09-30 at 22 51 16 Screenshot 2024-09-30 at 22 51 43
rr10 commented 1 month ago

@Shadow243 All good, no worries! Feel free to modify the script as you see fit. Have you tested it on a cPanel account or another type of account? For cPanel, PHP extensions need to be installed using EA4. Keep in mind that not everyone has root access to the server, but many providers are usually willing to install PHP or Apache extensions if requested. If you don’t have access to a cPanel account, just let me know and I’ll be happy to assist you. I believe it would be a good idea to create a specific script for cPanel, perhaps adding it to a repository so that it can be improved over time. Based on the cPanel script, it would then be possible to create scripts for other hosting platforms as well.