Files
bikeservice/server-setup.sh
T
2025-09-06 14:31:22 +02:00

285 lines
7.7 KiB
Bash
Executable File

#!/bin/bash
# Server Setup Script for Bike Service Application
# Run this script on your Ubuntu server after initial setup
set -e
echo "🚀 Setting up Ubuntu server for Bike Service Application..."
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root (use sudo)"
exit 1
fi
# Check Ubuntu version
UBUNTU_VERSION=$(lsb_release -rs)
if [[ "$UBUNTU_VERSION" != "20.04" && "$UBUNTU_VERSION" != "22.04" && "$UBUNTU_VERSION" != "24.04" ]]; then
print_warning "This script is tested on Ubuntu 20.04, 22.04, and 24.04. You're running $UBUNTU_VERSION"
fi
print_status "Starting server setup..."
# Update system
print_status "Updating system packages..."
apt update && apt upgrade -y
# Install required software
print_status "Installing required software..."
# Install Nginx
apt install nginx -y
# Install PHP 8.2 and extensions
apt install software-properties-common -y
add-apt-repository ppa:ondrej/php -y
apt update
apt install php8.2-fpm php8.2-mysql php8.2-sqlite3 php8.2-xml php8.2-mbstring php8.2-curl php8.2-zip php8.2-gd php8.2-cli php8.2-common php8.2-bcmath php8.2-json php8.2-tokenizer php8.2-fileinfo php8.2-opcache -y
# Install Composer
print_status "Installing Composer..."
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
chmod +x /usr/local/bin/composer
# Install Node.js and npm
print_status "Installing Node.js..."
curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
apt-get install -y nodejs
# Install Git
apt install git -y
# Install SQLite
apt install sqlite3 -y
# Install additional tools
apt install unzip curl wget htop ufw fail2ban -y
# Configure PHP-FPM
print_status "Configuring PHP-FPM..."
PHP_INI="/etc/php/8.2/fpm/php.ini"
PHP_FPM_INI="/etc/php/8.2/fpm/php.ini"
# Backup original files
cp $PHP_INI $PHP_INI.backup
cp $PHP_FPM_INI $PHP_FPM_INI.backup
# Update PHP configuration
sed -i 's/memory_limit = .*/memory_limit = 256M/' $PHP_INI
sed -i 's/upload_max_filesize = .*/upload_max_filesize = 64M/' $PHP_INI
sed -i 's/post_max_size = .*/post_max_size = 64M/' $PHP_INI
sed -i 's/max_execution_time = .*/max_execution_time = 300/' $PHP_INI
sed -i 's/;opcache.enable=.*/opcache.enable=1/' $PHP_INI
sed -i 's/;opcache.memory_consumption=.*/opcache.memory_consumption=128/' $PHP_INI
sed -i 's/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=4000/' $PHP_INI
# Enable OPcache
echo "opcache.enable=1" >> $PHP_INI
echo "opcache.memory_consumption=128" >> $PHP_INI
echo "opcache.max_accelerated_files=4000" >> $PHP_INI
# Restart PHP-FPM
systemctl restart php8.2-fpm
systemctl enable php8.2-fpm
# Configure Nginx
print_status "Configuring Nginx..."
# Create application directory
mkdir -p /var/www/bikeservice
chown -R www-data:www-data /var/www/bikeservice
# Create Nginx site configuration
cat > /etc/nginx/sites-available/bikeservice << 'EOF'
server {
listen 80;
server_name _;
root /var/www/bikeservice/backend/public;
index index.php index.html index.htm;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_read_timeout 300;
}
location ~ /\.(?!well-known).* {
deny all;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
client_max_body_size 64M;
}
EOF
# Enable site
ln -sf /etc/nginx/sites-available/bikeservice /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
# Test Nginx configuration
nginx -t
# Restart Nginx
systemctl restart nginx
systemctl enable nginx
# Configure firewall
print_status "Configuring firewall..."
ufw --force enable
ufw allow ssh
ufw allow 'Nginx Full'
ufw allow 80
ufw allow 443
# Configure fail2ban
print_status "Configuring fail2ban..."
systemctl enable fail2ban
systemctl start fail2ban
# Create systemd service for queue worker
print_status "Creating queue worker service..."
cat > /etc/systemd/system/bikeservice-queue.service << 'EOF'
[Unit]
Description=Bike Service Queue Worker
After=network.target
Wants=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/bikeservice/backend
ExecStart=/usr/bin/php artisan queue:work --sleep=3 --tries=3 --max-time=3600 --memory=512
ExecReload=/bin/kill -USR1 $MAINPID
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=bikeservice-queue
Environment=APP_ENV=production
Environment=APP_DEBUG=false
LimitNOFILE=65536
LimitNPROC=32768
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/var/www/bikeservice/backend/storage
ProtectHome=true
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd and enable queue service
systemctl daemon-reload
systemctl enable bikeservice-queue
# Set up cron for Laravel scheduler
print_status "Setting up Laravel scheduler..."
(crontab -l 2>/dev/null; echo "* * * * * cd /var/www/bikeservice/backend && php artisan schedule:run >> /dev/null 2>&1") | crontab -
# Create deployment user
print_status "Creating deployment user..."
useradd -m -s /bin/bash deploy
usermod -aG sudo deploy
echo "deploy:$(openssl rand -base64 32)" | chpasswd
# Set up SSH key authentication for deploy user
mkdir -p /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
touch /home/deploy/.ssh/authorized_keys
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh
print_warning "Please add your SSH public key to /home/deploy/.ssh/authorized_keys"
print_warning "You can do this by running: ssh-copy-id deploy@your-server-ip"
# Set proper permissions for application directory
chown -R deploy:www-data /var/www/bikeservice
chmod -R 775 /var/www/bikeservice
# Create log files
touch /var/log/nginx/bikeservice_access.log
touch /var/log/nginx/bikeservice_error.log
chown www-data:adm /var/log/nginx/bikeservice_*.log
print_status "Server setup completed!"
echo
echo "Next steps:"
echo "1. Add your SSH public key to the deploy user:"
echo " ssh-copy-id deploy@your-server-ip"
echo "2. Upload your application files to /var/www/bikeservice"
echo "3. Configure your .env file"
echo "4. Run the deployment script"
echo
echo "Useful commands:"
echo "- Check service status: systemctl status nginx php8.2-fpm bikeservice-queue"
echo "- View logs: journalctl -u bikeservice-queue -f"
echo "- Check Nginx logs: tail -f /var/log/nginx/bikeservice_error.log"
echo
echo "Security notes:"
echo "- SSH key authentication is required for deploy user"
echo "- Firewall is enabled (SSH and HTTP/HTTPS only)"
echo "- fail2ban is configured to protect against brute force attacks"