├── .gitignore ├── LICENSE.md ├── README.md ├── configs ├── .env.example ├── controlpanel.conf ├── controlpanel.service ├── controlpanel_ssl.conf └── www-controlpanel.conf └── install.sh /.gitignore: -------------------------------------------------------------------------------- 1 | development -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Ferks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

ControlPanel-Installer

2 | 3 | ![Discord](https://img.shields.io/discord/876934115302178876?label=DISCORD&style=for-the-badge) 4 | ![Contributors](https://img.shields.io/github/contributors/Ferks-FK/ControlPanel-Installer?style=for-the-badge) 5 | 6 | This is an installation script for [ControlPanel](https://ctrlpanel.gg/)
7 | This script is not associated with the official project. 8 | 9 |

Features

10 | 11 | - Automatic installation of the ControlPanel (dependencies, database, cronjob, nginx). 12 | - Automatic configuration of UFW (firewall for Ubuntu/Debian). 13 | - (Optional) automatic configuration of Let's Encrypt. 14 | - (Optional) Automatic panel upgrade to a newer version. 15 | 16 |

Support

17 | 18 | For help and support regarding the script itself and **not the official ControlPanel project**, Join our [Support Group](https://discord.gg/buDBbSGJmQ). 19 | 20 |

Supported installations

21 | 22 | List of supported installation setups for panel (installations supported by this installation script). 23 | 24 |

Systems supported by script


25 | 26 | | Operating System | Version | ✔️ \| ❌ | 27 | | :--- | :--- | :---: | 28 | | Debian | 9 | ✔️ | 29 | | | 10 | ✔️ | 30 | | | 11 | ✔️ | 31 | | Ubuntu | 18 | ✔️ | 32 | | | 20 | ✔️ | 33 | | | 22 | ✔️ | 34 | | CentOS | 7 | ✔️ | 35 | | | 8 | ✔️ | 36 | 37 | 38 |

How to use

39 | 40 | Just run the following command as root user. 41 | 42 | ```bash 43 | bash <(curl -s https://raw.githubusercontent.com/Ferks-FK/ControlPanel-Installer/development/install.sh) 44 | ``` 45 | 46 |

Attention!

47 | 48 | *Do not run the command using sudo.* 49 | 50 | **Example:** ```$ sudo bash <(curl -s...``` 51 | 52 | *You must be logged into your system as root to use the command.* 53 | 54 | **Example:** ```# bash <(curl -s...``` 55 | 56 | 57 |

Development

58 | 59 | This script was created and is being maintained by [Ferks - FK](https://github.com/Ferks-FK). 60 | 61 |

Extra informations

62 | 63 | If you have any ideas, or suggestions, feel free to say so in the [Support Group](https://discord.gg/buDBbSGJmQ). 64 | -------------------------------------------------------------------------------- /configs/.env.example: -------------------------------------------------------------------------------- 1 | ### --- App Settings --- ### 2 | APP_NAME=Controlpanel.gg 3 | APP_ENV=production 4 | APP_KEY= 5 | APP_DEBUG=false 6 | APP_URL=http://localhost 7 | # List with timezones https://www.php.net/manual/en/timezones.php 8 | APP_TIMEZONE= 9 | ### --- App Settings End --- ### 10 | 11 | ### --- DB Settings (required) --- ### 12 | DB_CONNECTION=mysql 13 | DB_HOST= 14 | DB_PORT= 15 | DB_DATABASE= 16 | DB_USERNAME= 17 | DB_PASSWORD="" 18 | ### --- DB Settings End --- ### 19 | 20 | 21 | # Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3) 22 | RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI 23 | RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe 24 | 25 | # Mail Server Settings - (HOST -> SMTP Server) 26 | MAIL_MAILER=smtp 27 | MAIL_HOST=mailhog 28 | MAIL_PORT=1025 29 | MAIL_USERNAME=null 30 | MAIL_PASSWORD=null 31 | MAIL_ENCRYPTION=null 32 | MAIL_FROM_ADDRESS=null 33 | MAIL_FROM_NAME="${APP_NAME}" 34 | 35 | 36 | # Laravel Logging Settings - https://laravel.com/docs/5.7/logging - Not needed to be changed 37 | LOG_CHANNEL=stack 38 | LOG_LEVEL=debug 39 | 40 | # Do not change anything below this line 41 | BROADCAST_DRIVER=log 42 | CACHE_DRIVER=file 43 | QUEUE_CONNECTION=database 44 | SESSION_DRIVER=file 45 | SESSION_LIFETIME=120 46 | 47 | MEMCACHED_HOST=127.0.0.1 48 | 49 | REDIS_HOST=127.0.0.1 50 | REDIS_PASSWORD=null 51 | REDIS_PORT=6379 52 | 53 | AWS_ACCESS_KEY_ID= 54 | AWS_SECRET_ACCESS_KEY= 55 | AWS_DEFAULT_REGION=us-east-1 56 | AWS_BUCKET= 57 | 58 | PUSHER_APP_ID= 59 | PUSHER_APP_KEY= 60 | PUSHER_APP_SECRET= 61 | PUSHER_APP_CLUSTER=mt1 62 | 63 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 64 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" -------------------------------------------------------------------------------- /configs/controlpanel.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | root /var/www/controlpanel/public; 4 | index index.php index.html index.htm index.nginx-debian.html; 5 | server_name ; 6 | 7 | location / { 8 | try_files $uri $uri/ /index.php?$query_string; 9 | } 10 | 11 | location ~ \.php$ { 12 | include snippets/fastcgi-php.conf; 13 | fastcgi_pass unix:; 14 | } 15 | 16 | location ~ /\.ht { 17 | deny all; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /configs/controlpanel.service: -------------------------------------------------------------------------------- 1 | # Controlpanel Queue Worker File 2 | # ---------------------------------- 3 | 4 | [Unit] 5 | Description=Controlpanel Queue Worker 6 | 7 | [Service] 8 | # On some systems the user and group might be different. 9 | # Some systems use `apache` or `nginx` as the user and group. 10 | User= 11 | Group= 12 | Restart=always 13 | ExecStart=/usr/bin/php /var/www/controlpanel/artisan queue:work --sleep=3 --tries=3 14 | 15 | [Install] 16 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /configs/controlpanel_ssl.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name ; 4 | return 301 https://$server_name$request_uri; 5 | } 6 | 7 | server { 8 | listen 443 ssl http2; 9 | server_name ; 10 | 11 | root /var/www/controlpanel/public; 12 | index index.php; 13 | 14 | access_log /var/log/nginx/controlpanel.app-access.log; 15 | error_log /var/log/nginx/controlpanel.app-error.log error; 16 | 17 | # allow larger file uploads and longer script runtimes 18 | client_max_body_size 100m; 19 | client_body_timeout 120s; 20 | 21 | sendfile off; 22 | 23 | # SSL Configuration 24 | ssl_certificate /etc/letsencrypt/live//fullchain.pem; 25 | ssl_certificate_key /etc/letsencrypt/live//privkey.pem; 26 | ssl_session_cache shared:SSL:10m; 27 | ssl_protocols TLSv1.2 TLSv1.3; 28 | ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"; 29 | ssl_prefer_server_ciphers on; 30 | 31 | add_header X-Content-Type-Options nosniff; 32 | add_header X-XSS-Protection "1; mode=block"; 33 | add_header X-Robots-Tag none; 34 | add_header Content-Security-Policy "frame-ancestors 'self'"; 35 | add_header X-Frame-Options DENY; 36 | add_header Referrer-Policy same-origin; 37 | 38 | location / { 39 | try_files $uri $uri/ /index.php?$query_string; 40 | } 41 | 42 | location ~ \.php$ { 43 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 44 | fastcgi_pass unix:; 45 | fastcgi_index index.php; 46 | include fastcgi_params; 47 | fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M"; 48 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 49 | fastcgi_param HTTP_PROXY ""; 50 | fastcgi_intercept_errors off; 51 | fastcgi_buffer_size 16k; 52 | fastcgi_buffers 4 16k; 53 | fastcgi_connect_timeout 300; 54 | fastcgi_send_timeout 300; 55 | fastcgi_read_timeout 300; 56 | include /etc/nginx/fastcgi_params; 57 | } 58 | 59 | location ~ /\.ht { 60 | deny all; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /configs/www-controlpanel.conf: -------------------------------------------------------------------------------- 1 | [controlpanel] 2 | 3 | user = nginx 4 | group = nginx 5 | 6 | listen = /var/run/php-fpm/controlpanel.sock 7 | listen.owner = nginx 8 | listen.group = nginx 9 | listen.mode = 0750 10 | 11 | pm = ondemand 12 | pm.max_children = 9 13 | pm.process_idle_timeout = 10s 14 | pm.max_requests = 200 15 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # shellcheck source=/dev/null 3 | 4 | set -e 5 | 6 | ######################################################## 7 | # 8 | # Pterodactyl-AutoThemes Installation 9 | # 10 | # Created and maintained by Ferks-FK 11 | # 12 | # Protected by MIT License 13 | # 14 | ######################################################## 15 | 16 | # Get the latest version before running the script # 17 | get_release() { 18 | curl --silent \ 19 | -H "Accept: application/vnd.github.v3+json" \ 20 | https://api.github.com/repos/Ferks-FK/ControlPanel-Installer/releases/latest | 21 | grep '"tag_name":' | 22 | sed -E 's/.*"([^"]+)".*/\1/' 23 | } 24 | 25 | # Variables # 26 | SCRIPT_RELEASE="$(get_release)" 27 | SUPPORT_LINK="https://discord.gg/buDBbSGJmQ" 28 | WIKI_LINK="https://github.com/Ferks-FK/ControlPanel-Installer/wiki" 29 | GITHUB_URL="https://raw.githubusercontent.com/Ferks-FK/ControlPanel.gg-Installer/$SCRIPT_RELEASE" 30 | RANDOM_PASSWORD="$(openssl rand -base64 32)" 31 | MYSQL_PASSWORD=false 32 | CONFIGURE_SSL=false 33 | INFORMATIONS="/var/log/ControlPanel-Info" 34 | FQDN="" 35 | 36 | update_variables() { 37 | CLIENT_VERSION="$(grep "'version'" "/var/www/controlpanel/config/app.php" | cut -c18-25 | sed "s/[',]//g")" 38 | LATEST_VERSION="$(curl -s https://raw.githubusercontent.com/Ctrlpanel-gg/panel/main/config/app.php | grep "'version'" | cut -c18-25 | sed "s/[',]//g")" 39 | } 40 | 41 | # Visual Functions # 42 | print_brake() { 43 | for ((n = 0; n < $1; n++)); do 44 | echo -n "#" 45 | done 46 | echo "" 47 | } 48 | 49 | print_warning() { 50 | echo "" 51 | echo -e "* ${YELLOW}WARNING${RESET}: $1" 52 | echo "" 53 | } 54 | 55 | print_error() { 56 | echo "" 57 | echo -e "* ${RED}ERROR${RESET}: $1" 58 | echo "" 59 | } 60 | 61 | print_success() { 62 | echo "" 63 | echo -e "* ${GREEN}SUCCESS${RESET}: $1" 64 | echo "" 65 | } 66 | 67 | print() { 68 | echo "" 69 | echo -e "* ${GREEN}$1${RESET}" 70 | echo "" 71 | } 72 | 73 | hyperlink() { 74 | echo -e "\e]8;;${1}\a${1}\e]8;;\a" 75 | } 76 | 77 | # Colors # 78 | GREEN="\e[0;92m" 79 | YELLOW="\033[1;33m" 80 | RED='\033[0;31m' 81 | RESET="\e[0m" 82 | 83 | EMAIL_RX="^(([A-Za-z0-9]+((\.|\-|\_|\+)?[A-Za-z0-9]?)*[A-Za-z0-9]+)|[A-Za-z0-9]+)@(([A-Za-z0-9]+)+((\.|\-|\_)?([A-Za-z0-9]+)+)*)+\.([A-Za-z]{2,})+$" 84 | 85 | valid_email() { 86 | [[ $1 =~ ${EMAIL_RX} ]] 87 | } 88 | 89 | email_input() { 90 | local __resultvar=$1 91 | local result='' 92 | 93 | while ! valid_email "$result"; do 94 | echo -n "* ${2}" 95 | read -r result 96 | 97 | valid_email "$result" || print_error "${3}" 98 | done 99 | 100 | eval "$__resultvar="'$result'"" 101 | } 102 | 103 | password_input() { 104 | local __resultvar=$1 105 | local result='' 106 | local default="$4" 107 | 108 | while [ -z "$result" ]; do 109 | echo -n "* ${2}" 110 | while IFS= read -r -s -n1 char; do 111 | [[ -z $char ]] && { 112 | printf '\n' 113 | break 114 | } 115 | if [[ $char == $'\x7f' ]]; then 116 | if [ -n "$result" ]; then 117 | [[ -n $result ]] && result=${result%?} 118 | printf '\b \b' 119 | fi 120 | else 121 | result+=$char 122 | printf '*' 123 | fi 124 | done 125 | [ -z "$result" ] && [ -n "$default" ] && result="$default" 126 | [ -z "$result" ] && print_error "${3}" 127 | done 128 | 129 | eval "$__resultvar="'$result'"" 130 | } 131 | 132 | # OS check # 133 | check_distro() { 134 | if [ -f /etc/os-release ]; then 135 | . /etc/os-release 136 | OS=$(echo "$ID" | awk '{print tolower($0)}') 137 | OS_VER=$VERSION_ID 138 | elif type lsb_release >/dev/null 2>&1; then 139 | OS=$(lsb_release -si | awk '{print tolower($0)}') 140 | OS_VER=$(lsb_release -sr) 141 | elif [ -f /etc/lsb-release ]; then 142 | . /etc/lsb-release 143 | OS=$(echo "$DISTRIB_ID" | awk '{print tolower($0)}') 144 | OS_VER=$DISTRIB_RELEASE 145 | elif [ -f /etc/debian_version ]; then 146 | OS="debian" 147 | OS_VER=$(cat /etc/debian_version) 148 | elif [ -f /etc/SuSe-release ]; then 149 | OS="SuSE" 150 | OS_VER="?" 151 | elif [ -f /etc/redhat-release ]; then 152 | OS="Red Hat/CentOS" 153 | OS_VER="?" 154 | else 155 | OS=$(uname -s) 156 | OS_VER=$(uname -r) 157 | fi 158 | 159 | OS=$(echo "$OS" | awk '{print tolower($0)}') 160 | OS_VER_MAJOR=$(echo "$OS_VER" | cut -d. -f1) 161 | } 162 | 163 | only_upgrade_panel() { 164 | print "Updating your panel, please wait..." 165 | 166 | cd /var/www/controlpanel 167 | php artisan down 168 | 169 | git stash 170 | git pull 171 | 172 | [ "$OS" == "centos" ] && export PATH=/usr/local/bin:$PATH 173 | COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev --optimize-autoloader 174 | 175 | php artisan migrate --seed --force 176 | 177 | php artisan view:clear 178 | php artisan config:clear 179 | 180 | set_permissions 181 | 182 | php artisan queue:restart 183 | 184 | php artisan up 185 | 186 | print "Your panel has been successfully updated to version ${YELLOW}${LATEST_VERSION}${RESET}." 187 | exit 1 188 | } 189 | 190 | enable_services_debian_based() { 191 | systemctl enable mariadb --now 192 | systemctl enable redis-server --now 193 | systemctl enable nginx 194 | } 195 | 196 | enable_services_centos_based() { 197 | systemctl enable mariadb --now 198 | systemctl enable redis --now 199 | systemctl enable nginx 200 | } 201 | 202 | allow_selinux() { 203 | setsebool -P httpd_can_network_connect 1 || true 204 | setsebool -P httpd_execmem 1 || true 205 | setsebool -P httpd_unified 1 || true 206 | } 207 | 208 | centos_php() { 209 | curl -so /etc/php-fpm.d/www-controlpanel.conf "$GITHUB_URL"/configs/www-controlpanel.conf 210 | 211 | systemctl enable php-fpm --now 212 | } 213 | 214 | check_compatibility() { 215 | print "Checking if your system is compatible with the script..." 216 | sleep 2 217 | 218 | case "$OS" in 219 | debian) 220 | PHP_SOCKET="/run/php/php8.1-fpm.sock" 221 | [ "$OS_VER_MAJOR" == "9" ] && SUPPORTED=true 222 | [ "$OS_VER_MAJOR" == "10" ] && SUPPORTED=true 223 | [ "$OS_VER_MAJOR" == "11" ] && SUPPORTED=true 224 | ;; 225 | ubuntu) 226 | PHP_SOCKET="/run/php/php8.1-fpm.sock" 227 | [ "$OS_VER_MAJOR" == "18" ] && SUPPORTED=true 228 | [ "$OS_VER_MAJOR" == "20" ] && SUPPORTED=true 229 | [ "$OS_VER_MAJOR" == "22" ] && SUPPORTED=true 230 | ;; 231 | centos) 232 | PHP_SOCKET="/var/run/php-fpm/controlpanel.sock" 233 | [ "$OS_VER_MAJOR" == "7" ] && SUPPORTED=true 234 | [ "$OS_VER_MAJOR" == "8" ] && SUPPORTED=true 235 | ;; 236 | *) 237 | SUPPORTED=false 238 | ;; 239 | esac 240 | 241 | if [ "$SUPPORTED" == true ]; then 242 | print "$OS $OS_VER is supported!" 243 | else 244 | print_error "$OS $OS_VER is not supported!" 245 | exit 1 246 | fi 247 | } 248 | 249 | ask_ssl() { 250 | echo -ne "* Would you like to configure ssl for your domain? (y/N): " 251 | read -r CONFIGURE_SSL 252 | if [[ "$CONFIGURE_SSL" == [Yy] ]]; then 253 | CONFIGURE_SSL=true 254 | email_input EMAIL "Enter your email address to create the SSL certificate for your domain: " "Email cannot by empty or invalid!" 255 | fi 256 | } 257 | 258 | install_composer() { 259 | print "Installing Composer..." 260 | 261 | curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer 262 | } 263 | 264 | download_files() { 265 | print "Downloading Necessary Files..." 266 | 267 | git clone -q https://github.com/Ctrlpanel-gg/panel.git /var/www/controlpanel 268 | rm -rf /var/www/controlpanel/.env.example 269 | curl -so /var/www/controlpanel/.env.example "$GITHUB_URL"/configs/.env.example 270 | 271 | cd /var/www/controlpanel 272 | [ "$OS" == "centos" ] && export PATH=/usr/local/bin:$PATH 273 | COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev --optimize-autoloader 274 | } 275 | 276 | set_permissions() { 277 | print "Setting Necessary Permissions..." 278 | 279 | case "$OS" in 280 | debian | ubuntu) 281 | chown -R www-data:www-data /var/www/controlpanel/ 282 | ;; 283 | centos) 284 | chown -R nginx:nginx /var/www/controlpanel/ 285 | ;; 286 | esac 287 | 288 | cd /var/www/controlpanel 289 | chmod -R 755 storage/* bootstrap/cache/ 290 | } 291 | 292 | configure_environment() { 293 | print "Configuring the base file..." 294 | 295 | sed -i -e "s@@$TIMEZONE@g" /var/www/controlpanel/.env.example 296 | sed -i -e "s@@$DB_HOST@g" /var/www/controlpanel/.env.example 297 | sed -i -e "s@@$DB_PORT@g" /var/www/controlpanel/.env.example 298 | sed -i -e "s@@$DB_NAME@g" /var/www/controlpanel/.env.example 299 | sed -i -e "s@@$DB_USER@g" /var/www/controlpanel/.env.example 300 | sed -i -e "s||$DB_PASS|g" /var/www/controlpanel/.env.example 301 | } 302 | 303 | check_database_info() { 304 | # Check if mysql has a password 305 | if ! mysql -u root -e "SHOW DATABASES;" &>/dev/null; then 306 | MYSQL_PASSWORD=true 307 | print_warning "It looks like your MySQL has a password, please enter it now" 308 | password_input MYSQL_ROOT_PASS "MySQL Password: " "Password cannot by empty!" 309 | if mysql -u root -p"$MYSQL_ROOT_PASS" -e "SHOW DATABASES;" &>/dev/null; then 310 | print "The password is correct, continuing..." 311 | else 312 | print_warning "The password is not correct, please re-enter the password" 313 | check_database_info 314 | fi 315 | fi 316 | 317 | # Checks to see if the chosen user already exists 318 | if [ "$MYSQL_PASSWORD" == true ]; then 319 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "SELECT User FROM mysql.user;" 2>/dev/null >> "$INFORMATIONS/check_user.txt" 320 | else 321 | mysql -u root -e "SELECT User FROM mysql.user;" 2>/dev/null >> "$INFORMATIONS/check_user.txt" 322 | fi 323 | sed -i '1d' "$INFORMATIONS/check_user.txt" 324 | while grep -q "$DB_USER" "$INFORMATIONS/check_user.txt"; do 325 | print_warning "Oops, it looks like user ${GREEN}$DB_USER${RESET} already exists in your MySQL, please use another one." 326 | echo -n "* Database User: " 327 | read -r DB_USER 328 | done 329 | rm -r "$INFORMATIONS/check_user.txt" 330 | 331 | # Check if the database already exists in mysql 332 | if [ "$MYSQL_PASSWORD" == true ]; then 333 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "SHOW DATABASES;" 2>/dev/null >> "$INFORMATIONS/check_db.txt" 334 | else 335 | mysql -u root -e "SHOW DATABASES;" 2>/dev/null >> "$INFORMATIONS/check_db.txt" 336 | fi 337 | sed -i '1d' "$INFORMATIONS/check_db.txt" 338 | while grep -q "$DB_NAME" "$INFORMATIONS/check_db.txt"; do 339 | print_warning "Oops, it looks like the database ${GREEN}$DB_NAME${RESET} already exists in your MySQL, please use another one." 340 | echo -n "* Database Name: " 341 | read -r DB_NAME 342 | done 343 | rm -r "$INFORMATIONS/check_db.txt" 344 | } 345 | 346 | configure_database() { 347 | print "Configuring Database..." 348 | 349 | if [ "$MYSQL_PASSWORD" == true ]; then 350 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "CREATE DATABASE ${DB_NAME};" &>/dev/null 351 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "CREATE USER '${DB_USER}'@'${DB_HOST}' IDENTIFIED BY '${DB_PASS}';" &>/dev/null 352 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'${DB_HOST}';" &>/dev/null 353 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "FLUSH PRIVILEGES;" &>/dev/null 354 | else 355 | mysql -u root -e "CREATE DATABASE ${DB_NAME};" 356 | mysql -u root -e "CREATE USER '${DB_USER}'@'${DB_HOST}' IDENTIFIED BY '${DB_PASS}';" 357 | mysql -u root -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'${DB_HOST}';" 358 | mysql -u root -e "FLUSH PRIVILEGES;" 359 | fi 360 | } 361 | 362 | configure_webserver() { 363 | print "Configuring Web-Server..." 364 | 365 | if [ "$CONFIGURE_SSL" == true ]; then 366 | WEB_FILE="controlpanel_ssl.conf" 367 | else 368 | WEB_FILE="controlpanel.conf" 369 | fi 370 | 371 | case "$OS" in 372 | debian | ubuntu) 373 | rm -rf /etc/nginx/sites-enabled/default 374 | 375 | curl -so /etc/nginx/sites-available/controlpanel.conf "$GITHUB_URL"/configs/$WEB_FILE 376 | 377 | sed -i -e "s@@$FQDN@g" /etc/nginx/sites-available/controlpanel.conf 378 | 379 | sed -i -e "s@@$PHP_SOCKET@g" /etc/nginx/sites-available/controlpanel.conf 380 | 381 | [ "$OS" == "debian" ] && [ "$OS_VER_MAJOR" == "9" ] && sed -i -e 's/ TLSv1.3//' /etc/nginx/sites-available/controlpanel.conf 382 | 383 | ln -s /etc/nginx/sites-available/controlpanel.conf /etc/nginx/sites-enabled/controlpanel.conf 384 | ;; 385 | centos) 386 | rm -rf /etc/nginx/conf.d/default 387 | 388 | curl -so /etc/nginx/conf.d/controlpanel.conf "$GITHUB_URL"/configs/$WEB_FILE 389 | 390 | sed -i -e "s@@$FQDN@g" /etc/nginx/conf.d/controlpanel.conf 391 | 392 | sed -i -e "s@@$PHP_SOCKET@g" /etc/nginx/conf.d/controlpanel.conf 393 | ;; 394 | esac 395 | 396 | # Kill nginx if it is listening on port 80 before it starts, fixed a port usage bug. 397 | if netstat -tlpn | grep 80 &>/dev/null; then 398 | killall nginx 399 | fi 400 | 401 | if [ "$(systemctl is-active --quiet nginx)" == "active" ]; then 402 | systemctl restart nginx 403 | else 404 | systemctl start nginx 405 | fi 406 | } 407 | 408 | configure_firewall() { 409 | print "Configuring the firewall..." 410 | 411 | case "$OS" in 412 | debian | ubuntu) 413 | apt-get install -qq -y ufw 414 | 415 | ufw allow ssh &>/dev/null 416 | ufw allow http &>/dev/null 417 | ufw allow https &>/dev/null 418 | 419 | ufw --force enable &>/dev/null 420 | ufw --force reload &>/dev/null 421 | ;; 422 | centos) 423 | yum update -y -q 424 | 425 | yum -y -q install firewalld &>/dev/null 426 | 427 | systemctl --now enable firewalld &>/dev/null 428 | 429 | firewall-cmd --add-service=http --permanent -q 430 | firewall-cmd --add-service=https --permanent -q 431 | firewall-cmd --add-service=ssh --permanent -q 432 | firewall-cmd --reload -q 433 | ;; 434 | esac 435 | } 436 | 437 | configure_ssl() { 438 | print "Configuring SSL..." 439 | 440 | FAILED=false 441 | 442 | if [ "$(systemctl is-active --quiet nginx)" == "inactive" ] || [ "$(systemctl is-active --quiet nginx)" == "failed" ]; then 443 | systemctl start nginx 444 | fi 445 | 446 | case "$OS" in 447 | debian | ubuntu) 448 | apt-get update -y -qq && apt-get upgrade -y -qq 449 | apt-get install -y -qq certbot && apt-get install -y -qq python3-certbot-nginx 450 | ;; 451 | centos) 452 | [ "$OS_VER_MAJOR" == "7" ] && yum -y -q install certbot python-certbot-nginx 453 | [ "$OS_VER_MAJOR" == "8" ] && yum -y -q install certbot python3-certbot-nginx 454 | ;; 455 | esac 456 | 457 | certbot certonly --nginx --non-interactive --agree-tos --quiet --no-eff-email --email "$EMAIL" -d "$FQDN" || FAILED=true 458 | 459 | if [ ! -d "/etc/letsencrypt/live/$FQDN/" ] || [ "$FAILED" == true ]; then 460 | if [ "$(systemctl is-active --quiet nginx)" == "active" ]; then 461 | systemctl stop nginx 462 | fi 463 | print_warning "The script failed to generate the SSL certificate automatically, trying alternative command..." 464 | FAILED=false 465 | 466 | certbot certonly --standalone --non-interactive --agree-tos --quiet --no-eff-email --email "$EMAIL" -d "$FQDN" || FAILED=true 467 | 468 | if [ -d "/etc/letsencrypt/live/$FQDN/" ] || [ "$FAILED" == false ]; then 469 | print "The script was able to successfully generate the SSL certificate!" 470 | else 471 | print_warning "The script failed to generate the certificate, try to do it manually." 472 | fi 473 | else 474 | print "The script was able to successfully generate the SSL certificate!" 475 | fi 476 | } 477 | 478 | configure_crontab() { 479 | print "Configuring Crontab" 480 | 481 | crontab -l | { 482 | cat 483 | echo "* * * * * php /var/www/controlpanel/artisan schedule:run >> /dev/null 2>&1" 484 | } | crontab - 485 | } 486 | 487 | configure_service() { 488 | print "Configuring ControlPanel Service..." 489 | 490 | curl -so /etc/systemd/system/controlpanel.service "$GITHUB_URL"/configs/controlpanel.service 491 | 492 | case "$OS" in 493 | debian | ubuntu) 494 | sed -i -e "s@@www-data@g" /etc/systemd/system/controlpanel.service 495 | ;; 496 | centos) 497 | sed -i -e "s@@nginx@g" /etc/systemd/system/controlpanel.service 498 | ;; 499 | esac 500 | 501 | systemctl enable controlpanel.service --now 502 | } 503 | 504 | deps_ubuntu() { 505 | print "Installing dependencies for Ubuntu ${OS_VER}" 506 | 507 | # Add "add-apt-repository" command 508 | apt-get install -y software-properties-common curl apt-transport-https ca-certificates gnupg 509 | 510 | # Add additional repositories for PHP, Redis, and MariaDB 511 | LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php 512 | curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash 513 | 514 | # Update repositories list 515 | apt-get update -y && apt-get upgrade -y 516 | 517 | # Add universe repository if you are on Ubuntu 18.04 518 | [ "$OS_VER_MAJOR" == "18" ] && apt-add-repository universe 519 | 520 | # Install Dependencies 521 | apt-get install -y php8.1 php8.1-{cli,gd,mysql,pdo,mbstring,tokenizer,bcmath,xml,fpm,curl,zip,intl} mariadb-server nginx tar unzip git redis-server psmisc net-tools 522 | 523 | # Enable services 524 | enable_services_debian_based 525 | } 526 | 527 | deps_debian() { 528 | print "Installing dependencies for Debian ${OS_VER}" 529 | 530 | # MariaDB need dirmngr 531 | apt-get install -y dirmngr 532 | 533 | # install PHP 8.0 using sury's repo 534 | apt-get install -y ca-certificates apt-transport-https lsb-release 535 | wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg 536 | echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php.list 537 | 538 | # Add the MariaDB repo 539 | curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash 540 | 541 | # Update repositories list 542 | apt-get update -y && apt-get upgrade -y 543 | 544 | # Install Dependencies 545 | apt-get install -y php8.1 php8.1-{cli,gd,mysql,pdo,mbstring,tokenizer,bcmath,xml,fpm,curl,zip,intl} mariadb-server nginx tar unzip git redis-server psmisc net-tools 546 | 547 | # Enable services 548 | enable_services_debian_based 549 | } 550 | 551 | deps_centos() { 552 | print "Installing dependencies for CentOS ${OS_VER}" 553 | 554 | if [ "$OS_VER_MAJOR" == "7" ]; then 555 | # SELinux tools 556 | yum install -y policycoreutils policycoreutils-python selinux-policy selinux-policy-targeted libselinux-utils setroubleshoot-server setools setools-console mcstrans 557 | 558 | # Install MariaDB 559 | curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash 560 | 561 | # Add remi repo (php8.1) 562 | yum install -y epel-release http://rpms.remirepo.net/enterprise/remi-release-7.rpm 563 | yum install -y yum-utils 564 | yum-config-manager -y --disable remi-php54 565 | yum-config-manager -y --enable remi-php81 566 | 567 | # Install dependencies 568 | yum -y install php php-common php-tokenizer php-curl php-fpm php-cli php-json php-mysqlnd php-mcrypt php-gd php-mbstring php-pdo php-zip php-bcmath php-dom php-opcache php-intl mariadb-server nginx curl tar zip unzip git redis psmisc net-tools 569 | yum update -y 570 | elif [ "$OS_VER_MAJOR" == "8" ]; then 571 | # SELinux tools 572 | yum install -y policycoreutils selinux-policy selinux-policy-targeted setroubleshoot-server setools setools-console mcstrans 573 | 574 | # Add remi repo (php8.1) 575 | yum install -y epel-release http://rpms.remirepo.net/enterprise/remi-release-8.rpm 576 | yum module enable -y php:remi-8.1 577 | 578 | # Install MariaDB 579 | yum install -y mariadb mariadb-server 580 | 581 | # Install dependencies 582 | yum install -y php php-common php-fpm php-cli php-json php-mysqlnd php-gd php-mbstring php-pdo php-zip php-bcmath php-dom php-opcache php-intl mariadb-server nginx curl tar zip unzip git redis psmisc net-tools 583 | yum update -y 584 | fi 585 | 586 | # Enable services 587 | enable_services_centos_based 588 | 589 | # SELinux 590 | allow_selinux 591 | } 592 | 593 | install_controlpanel() { 594 | print "Starting installation, this may take a few minutes, please wait." 595 | sleep 2 596 | 597 | case "$OS" in 598 | debian | ubuntu) 599 | apt-get update -y && apt-get upgrade -y 600 | 601 | [ "$OS" == "ubuntu" ] && deps_ubuntu 602 | [ "$OS" == "debian" ] && deps_debian 603 | ;; 604 | centos) 605 | yum update -y && yum upgrade -y 606 | deps_centos 607 | ;; 608 | esac 609 | 610 | [ "$OS" == "centos" ] && centos_php 611 | install_composer 612 | download_files 613 | set_permissions 614 | configure_environment 615 | check_database_info 616 | configure_database 617 | configure_firewall 618 | configure_crontab 619 | configure_service 620 | [ "$CONFIGURE_SSL" == true ] && configure_ssl 621 | configure_webserver 622 | bye 623 | } 624 | 625 | main() { 626 | # Check if it is already installed and check the version # 627 | if [ -d "/var/www/controlpanel" ]; then 628 | update_variables 629 | if [ "$CLIENT_VERSION" != "$LATEST_VERSION" ]; then 630 | print_warning "You already have the panel installed." 631 | echo -ne "* The script detected that the version of your panel is ${YELLOW}$CLIENT_VERSION${RESET}, the latest version of the panel is ${YELLOW}$LATEST_VERSION${RESET}, would you like to upgrade? (y/N): " 632 | read -r UPGRADE_PANEL 633 | if [[ "$UPGRADE_PANEL" =~ [Yy] ]]; then 634 | check_distro 635 | only_upgrade_panel 636 | else 637 | print "Ok, bye..." 638 | exit 1 639 | fi 640 | else 641 | print_warning "The panel is already installed, aborting..." 642 | exit 1 643 | fi 644 | fi 645 | 646 | # Check if pterodactyl is installed # 647 | if [ ! -d "/var/www/pterodactyl" ]; then 648 | print_warning "An installation of pterodactyl was not found in the directory $YELLOW/var/www/pterodactyl${RESET}" 649 | echo -ne "* Is your pterodactyl panel installed on this machine? (y/N): " 650 | read -r PTERO_DIR 651 | if [[ "$PTERO_DIR" =~ [Yy] ]]; then 652 | echo -e "* ${GREEN}EXAMPLE${RESET}: /var/www/myptero" 653 | echo -ne "* Enter the directory from where your pterodactyl panel is installed: " 654 | read -r PTERO_DIR 655 | if [ -f "$PTERO_DIR/config/app.php" ]; then 656 | print "Pterodactyl was found, continuing..." 657 | else 658 | print_error "Pterodactyl not found, running script again..." 659 | main 660 | fi 661 | fi 662 | fi 663 | 664 | # Check Distro # 665 | check_distro 666 | 667 | # Check if the OS is compatible # 668 | check_compatibility 669 | 670 | # Set FQDN for panel # 671 | while [ -z "$FQDN" ]; do 672 | print_warning "Do not use a domain that is already in use by another application, such as the domain of your pterodactyl." 673 | echo -ne "* Set the Hostname/FQDN for panel (${YELLOW}panel.example.com${RESET}): " 674 | read -r FQDN 675 | [ -z "$FQDN" ] && print_error "FQDN cannot be empty" 676 | done 677 | 678 | # Install the packages to check FQDN and ask about SSL only if FQDN is a string # 679 | if [[ "$FQDN" == [a-zA-Z]* ]]; then 680 | ask_ssl 681 | fi 682 | 683 | # Set host of the database # 684 | echo -ne "* Enter the host of the database (${YELLOW}127.0.0.1${RESET}): " 685 | read -r DB_HOST 686 | [ -z "$DB_HOST" ] && DB_HOST="127.0.0.1" 687 | 688 | # Set port of the database # 689 | echo -ne "* Enter the port of the database (${YELLOW}3306${RESET}): " 690 | read -r DB_PORT 691 | [ -z "$DB_PORT" ] && DB_PORT="3306" 692 | 693 | # Set name of the database # 694 | echo -ne "* Enter the name of the database (${YELLOW}controlpanel${RESET}): " 695 | read -r DB_NAME 696 | [ -z "$DB_NAME" ] && DB_NAME="controlpanel" 697 | 698 | # Set user of the database # 699 | echo -ne "* Enter the username of the database (${YELLOW}controlpaneluser${RESET}): " 700 | read -r DB_USER 701 | [ -z "$DB_USER" ] && DB_USER="controlpaneluser" 702 | 703 | # Set pass of the database # 704 | password_input DB_PASS "Enter the password of the database (Enter for random password): " "Password cannot by empty!" "$RANDOM_PASSWORD" 705 | 706 | # Ask Time-Zone # 707 | echo -e "* List of valid time-zones here: ${YELLOW}$(hyperlink "http://php.net/manual/en/timezones.php")${RESET}" 708 | echo -ne "* Select Time-Zone (${YELLOW}America/New_York${RESET}): " 709 | read -r TIMEZONE 710 | [ -z "$TIMEZONE" ] && TIMEZONE="America/New_York" 711 | 712 | # Summary # 713 | echo 714 | print_brake 75 715 | echo 716 | echo -e "* Hostname/FQDN: $FQDN" 717 | echo -e "* Database Host: $DB_HOST" 718 | echo -e "* Database Port: $DB_PORT" 719 | echo -e "* Database Name: $DB_NAME" 720 | echo -e "* Database User: $DB_USER" 721 | echo -e "* Database Pass: (censored)" 722 | echo -e "* Time-Zone: $TIMEZONE" 723 | echo -e "* Configure SSL: $CONFIGURE_SSL" 724 | echo 725 | print_brake 75 726 | echo 727 | 728 | # Create the logs directory # 729 | mkdir -p $INFORMATIONS 730 | 731 | # Write the information to a log # 732 | { 733 | echo -e "* Hostname/FQDN: $FQDN" 734 | echo -e "* Database Host: $DB_HOST" 735 | echo -e "* Database Port: $DB_PORT" 736 | echo -e "* Database Name: $DB_NAME" 737 | echo -e "* Database User: $DB_USER" 738 | echo -e "* Database Pass: $DB_PASS" 739 | echo "" 740 | echo "* After using this file, delete it immediately!" 741 | } > $INFORMATIONS/install.info 742 | 743 | # Confirm all the choices # 744 | echo -n "* Initial settings complete, do you want to continue to the installation? (y/N): " 745 | read -r CONTINUE_INSTALL 746 | [[ "$CONTINUE_INSTALL" =~ [Yy] ]] && install_controlpanel 747 | [[ "$CONTINUE_INSTALL" == [Nn] ]] && print_error "Installation aborted!" && exit 1 748 | } 749 | 750 | bye() { 751 | echo 752 | print_brake 90 753 | echo 754 | echo -e "${GREEN}* The script has finished the installation process!${RESET}" 755 | 756 | [ "$CONFIGURE_SSL" == true ] && APP_URL="https://$FQDN" 757 | [ "$CONFIGURE_SSL" == false ] && APP_URL="http://$FQDN" 758 | 759 | echo -e "${GREEN}* To complete the configuration of your panel, go to ${YELLOW}$(hyperlink "$APP_URL/install")${RESET}" 760 | echo -e "${GREEN}* Thank you for using this script!" 761 | echo -e "* Wiki: ${YELLOW}$(hyperlink "$WIKI_LINK")${RESET}" 762 | echo -e "${GREEN}* Support Group: ${YELLOW}$(hyperlink "$SUPPORT_LINK")${RESET}" 763 | echo -e "${GREEN}*${RESET} If you have questions about the information that is requested on the installation page\nall the necessary information about it is written in: (${YELLOW}$INFORMATIONS/install.info${RESET})." 764 | echo 765 | print_brake 90 766 | echo 767 | } 768 | 769 | # Exec Script # 770 | main --------------------------------------------------------------------------------