Skip to content

Instantly share code, notes, and snippets.

@heychazza
Last active May 20, 2024 10:41
Show Gist options
  • Save heychazza/6a77c5870706d752468bf12ff8dbb88c to your computer and use it in GitHub Desktop.
Save heychazza/6a77c5870706d752468bf12ff8dbb88c to your computer and use it in GitHub Desktop.
Configures a VPS with everything needed to run a Laravel app.
#!/bin/bash
# Prompt user for app domain
read -p "Enter the app domain (default: staging.analyse.net): " APP_DOMAIN
APP_DOMAIN="${APP_DOMAIN:-staging.analyse.net}"
# Prompt user for Git repository
read -p "Enter the Git repository (default: track/analytics.tebex.io): " GIT_REPO
GIT_REPO="${GIT_REPO:-track/analytics.tebex.io}"
# Prompt user for PHP version
read -p "Enter the PHP version (default: 8.2): " PHP_VERSION
PHP_VERSION="${PHP_VERSION:-8.2}"
# Prompt user for email
read -p "Enter your email: " EMAIL
# Prompt user for Node.js version
read -p "Enter the Node.js version (default: 18): " NODE_MAJOR
NODE_MAJOR="${NODE_MAJOR:-18}"
# Prompt user if they want to lock down the machine to a specific IP
read -p "Do you want to lock down the machine to a specific IP? (y/n): " LOCK_IP
if [ "$LOCK_IP" == "y" ]; then
read -p "Enter the IP address: " VPN_IP
fi
PUBLIC_IP=$(curl api.ipify.org)
# Update system
sudo apt upgrade -y
sudo apt update -y
export COMPOSER_ALLOW_SUPERUSER=1
# PHP installation
sudo apt install lsb-release apt-transport-https ca-certificates software-properties-common -y
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sudo sh -c "echo 'deb https://packages.sury.org/php/ $(lsb_release -sc) main' > /etc/apt/sources.list.d/php.list"
sudo apt update
sudo apt install php$PHP_VERSION php$PHP_VERSION-{cli,zip,mysql,fpm,bz2,curl,mbstring,intl,redis,dom,common} -y
systemctl enable php$PHP_VERSION-fpm
systemctl start php$PHP_VERSION-fpm
export PHP_INI_PATH="/etc/php/$PHP_VERSION/fpm/php.ini"
sed -i 's/max_execution_time = 30/max_execution_time = 180/' $PHP_INI_PATH
sed -i 's/memory_limit = 128M/memory_limit = 512M/' $PHP_INI_PATH
sudo systemctl restart php$PHP_VERSION-fpm
# Composer installation
cd ~
curl -sS https://getcomposer.org/installer -o composer-setup.php
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
rm -rf composer-setup.php
# Node.js and Yarn installation
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt update
sudo apt install nodejs -y
npm install --global yarn
# Git installation and configuration
sudo apt install git -y
ssh-keygen -t ed25519 -C "$EMAIL"
eval "$(ssh-agent -s)"
git config --global pull.rebase false
echo "Add the following key to your GitHub (https://github.com/settings/ssh/new)..."
cat ~/.ssh/id_ed25519.pub
echo ""
echo "Then press any key to continue."
# Wait for a key press to continue
read -s -n 1
# Project setup
git clone git@github.com:$GIT_REPO.git /var/www/$APP_DOMAIN
cd /var/www/$APP_DOMAIN
composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev
yarn install --prod
cp -rf .env.example .env
yarn build
setfacl -R -m g:www-data:rwx /var/www/
# Add Cronjob
(crontab -l; echo "* * * * * cd /var/www/$APP_DOMAIN && php artisan schedule:run >> /dev/null 2>&1") | awk '!x[$0]++' | crontab -
# Nginx configuration
sudo apt install ufw nginx -y
# Path to the update_proxies.sh script
UPDATE_SCRIPT="~/scripts/update_proxies.sh"
# Create the update_proxies.sh script
cat << 'EOF' > $UPDATE_SCRIPT
#!/bin/bash
# Define the URLs for the Cloudflare IP lists
IPV4_URL="https://www.cloudflare.com/ips-v4/"
IPV6_URL="https://www.cloudflare.com/ips-v6/"
# Fetch the IP lists
IPV4_LIST=$(curl -s $IPV4_URL)
IPV6_LIST=$(curl -s $IPV6_URL)
# Prepare the Nginx configuration content
CF_PROXIES="# Cloudflare IPs\n"
# Add the IPv4 addresses
for IP in $IPV4_LIST; do
CF_PROXIES+="set_real_ip_from $IP;\n"
done
# Add the IPv6 addresses
for IP in $IPV6_LIST; do
CF_PROXIES+="set_real_ip_from $IP;\n"
done
# Add the real_ip_header directive
CF_PROXIES+="real_ip_header CF-Connecting-IP;"
# Write the configuration to the file
echo -e "$CF_PROXIES" > "/etc/nginx/snippets/proxies.conf"
# Reload Nginx to apply the new configuration
nginx -t && nginx -s reload
EOF
# Make the update_proxies.sh script executable
chmod +x $UPDATE_SCRIPT
# Add the cron job to run the update_proxies.sh script weekly
(crontab -l 2>/dev/null; echo "0 0 * * 0 $UPDATE_SCRIPT") | crontab -
CONFIG="server {
server_name $APP_DOMAIN;
root /var/www/$APP_DOMAIN/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
real_ip_header X-Forwarded-For;
include /etc/nginx/snippets/proxies.conf;
ssl_client_certificate /etc/ssl/certs/cloudflare.crt;
ssl_verify_client on;
index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
charset utf-8;
client_max_body_size 4M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php$PHP_VERSION-fpm.sock;
}
}"
echo "$CONFIG" > "/etc/nginx/sites-available/$APP_DOMAIN.conf"
sudo ln -s /etc/nginx/sites-available/$APP_DOMAIN.conf /etc/nginx/sites-enabled
sudo curl -L https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem -o /etc/ssl/certs/cloudflare.crt
nginx -s reload
ufw allow 'Nginx Full'
# Firewall configuration
if [ "$LOCK_IP" == "y" ]; then
ufw allow from $VPN_IP to any port 8080
ufw allow from $VPN_IP to any port 8081
ufw allow from $VPN_IP to any port 3306
ufw allow from $VPN_IP to any port 22
else
ufw allow 8080/tcp
ufw allow 8081/tcp
ufw allow 3306/tcp
ufw allow 22/tcp
fi
# Enable the firewall
ufw enable
# LetsEncrypt
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx --non-interactive --agree-tos -m $EMAIL -d $APP_DOMAIN
# Redis installation and configuration
sudo apt install redis-server -y
sudo systemctl enable redis-server.service
sudo systemctl start redis-server.service
# Supervisor installation and configuration
sudo apt install supervisor
sudo systemctl enable supervisor.service
sudo systemctl start supervisor.service
# Define the content of the file
CONTENT="[program:horizon]
process_name=%(program_name)s
command=php /var/www/$APP_DOMAIN/artisan horizon
autostart=true
autorestart=true
user=root
redirect_stderr=true
stdout_logfile=/var/www/$APP_DOMAIN/horizon.log
stopwaitsecs=3600"
echo "$CONTENT" > "/etc/supervisor/conf.d/horizon.conf"
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start "horizon:*"
# SingleStore installation
wget -O - 'https://release.memsql.com/release-aug2018.gpg' 2>/dev/null | sudo apt-key add - && apt-key list
apt-cache policy apt-transport-https
echo "deb [arch=amd64] https://release.memsql.com/production/debian memsql main" | sudo tee /etc/apt/sources.list.d/memsql.list
sudo apt update && sudo apt -y install singlestoredb-toolbox singlestoredb-studio
sudo systemctl start singlestoredb-studio
sudo systemctl enable singlestoredb-studio.service
# Function to calculate min_free_kbytes based on system RAM
calculate_min_free_kbytes() {
total_ram_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}')
min_free_kb=$((total_ram_kb / 100)) # 1% of total RAM
if (( min_free_kb > 4000000 )); then
min_free_kb=4000000 # Cap at 4 GB
fi
echo $min_free_kb
}
# Set recommended vm settings (According to SingleStore)
echo "Setting recommended vm settings..."
sudo sysctl -w vm.max_map_count=1000000000
sudo sysctl -w vm.overcommit_memory=0
sudo sysctl -w vm.swappiness=10
sudo sysctl -w vm.overcommit_ratio=99 # Only if vm.overcommit_memory is set to 2
sudo sysctl -w net.core.rmem_max=8388606
sudo sysctl -w net.core.wmem_max=8388606
# Calculate min_free_kbytes
min_free_kbytes=$(calculate_min_free_kbytes)
# Set min_free_kbytes
sudo sysctl -w vm.min_free_kbytes=$min_free_kbytes
# Prompt user for SingleStore key
read -p "Enter your SingleStore license key (from portal.singlestore.com): " SINGLESTORE_KEY
CLUSTER_YAML="license: $SINGLESTORE_KEY
high_availability: false
memsql_server_version: 8.5.15
hosts:
- hostname: $PUBLIC_IP
nodes:
- role: Master
config:
port: 3306
- role: Leaf
config:
port: 3307
localhost: true"
echo "$CLUSTER_YAML" > "cluster.yml"
sdb-deploy setup-cluster --cluster-file cluster.yml
rm -rf install-dedi.sh cluster.yml
@heychazza
Copy link
Author

heychazza commented Sep 25, 2023

RUN USING:
curl -L https://gist.githubusercontent.com/heychazza/6a77c5870706d752468bf12ff8dbb88c/raw/install-dedi.sh -o install-dedi.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment