SingleStore Script March 14, 2022 (2y ago)
The following script is designed to set up a SingleStore database on a dedicated server. It will prompt you for the
App domain
Git repository
PHP version
Email
Node.js version
and whether you want to lock down the machine to a specific IP.
It will then update the system, install PHP, Composer, Node.js, Yarn, Git, Nginx, UFW, and Redis.
It will also configure Nginx, set up a cron job, install Let's Encrypt, configure Redis, install Supervisor, set up a SingleStore cluster, and configure the firewall. Finally, it will install SingleStore Studio and set up recommended vm settings.
singlestore.sh #!/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