initial commit
This commit is contained in:
@@ -0,0 +1,115 @@
|
|||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName your-domain.com
|
||||||
|
ServerAlias www.your-domain.com
|
||||||
|
DocumentRoot /var/www/bikeservice/backend/public
|
||||||
|
|
||||||
|
<Directory /var/www/bikeservice/backend/public>
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
|
||||||
|
# Laravel specific rules
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteRule ^(.*)$ index.php [QSA,L]
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
Header always set X-Frame-Options "SAMEORIGIN"
|
||||||
|
Header always set X-XSS-Protection "1; mode=block"
|
||||||
|
Header always set X-Content-Type-Options "nosniff"
|
||||||
|
Header always set Referrer-Policy "no-referrer-when-downgrade"
|
||||||
|
Header always set Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'"
|
||||||
|
|
||||||
|
# Gzip compression
|
||||||
|
<Location />
|
||||||
|
SetOutputFilter DEFLATE
|
||||||
|
SetEnvIfNoCase Request_URI \
|
||||||
|
\.(?:gif|jpe?g|png)$ no-gzip dont-vary
|
||||||
|
SetEnvIfNoCase Request_URI \
|
||||||
|
\.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
|
||||||
|
SetEnvIfNoCase Request_URI \
|
||||||
|
\.(?:pdf|mov|avi|mp3|mp4|rm)$ no-gzip dont-vary
|
||||||
|
</Location>
|
||||||
|
|
||||||
|
# Cache static assets
|
||||||
|
<LocationMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$">
|
||||||
|
ExpiresActive On
|
||||||
|
ExpiresDefault "access plus 1 year"
|
||||||
|
Header append Cache-Control "public, immutable"
|
||||||
|
Header append Vary Accept-Encoding
|
||||||
|
</LocationMatch>
|
||||||
|
|
||||||
|
# Cache API responses (no cache)
|
||||||
|
<LocationMatch "^/api/">
|
||||||
|
Header set Cache-Control "no-cache, no-store, must-revalidate"
|
||||||
|
Header set Pragma "no-cache"
|
||||||
|
Header set Expires "0"
|
||||||
|
</LocationMatch>
|
||||||
|
|
||||||
|
# Deny access to sensitive files
|
||||||
|
<FilesMatch "\.(env|log|sql|md|txt|yml|yaml|ini)$">
|
||||||
|
Require all denied
|
||||||
|
</FilesMatch>
|
||||||
|
|
||||||
|
# Deny access to hidden files
|
||||||
|
<FilesMatch "^\.">
|
||||||
|
Require all denied
|
||||||
|
</FilesMatch>
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
<Location /health>
|
||||||
|
SetHandler server-status
|
||||||
|
Require all granted
|
||||||
|
</Location>
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
ErrorLog ${APACHE_LOG_DIR}/bikeservice_error.log
|
||||||
|
CustomLog ${APACHE_LOG_DIR}/bikeservice_access.log combined
|
||||||
|
|
||||||
|
# Client max body size (for file uploads)
|
||||||
|
LimitRequestBody 67108864
|
||||||
|
|
||||||
|
# Timeouts
|
||||||
|
Timeout 300
|
||||||
|
KeepAliveTimeout 5
|
||||||
|
MaxKeepAliveRequests 100
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
|
# SSL Configuration (uncomment after obtaining SSL certificate)
|
||||||
|
# <VirtualHost *:443>
|
||||||
|
# ServerName your-domain.com
|
||||||
|
# ServerAlias www.your-domain.com
|
||||||
|
# DocumentRoot /var/www/bikeservice/backend/public
|
||||||
|
#
|
||||||
|
# SSLEngine on
|
||||||
|
# SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem
|
||||||
|
# SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
|
||||||
|
#
|
||||||
|
# # Include all the same configuration as above
|
||||||
|
# <Directory /var/www/bikeservice/backend/public>
|
||||||
|
# AllowOverride All
|
||||||
|
# Require all granted
|
||||||
|
#
|
||||||
|
# RewriteEngine On
|
||||||
|
# RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
# RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
# RewriteRule ^(.*)$ index.php [QSA,L]
|
||||||
|
# </Directory>
|
||||||
|
#
|
||||||
|
# # Security headers
|
||||||
|
# Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||||
|
# Header always set X-Frame-Options "SAMEORIGIN"
|
||||||
|
# Header always set X-XSS-Protection "1; mode=block"
|
||||||
|
# Header always set X-Content-Type-Options "nosniff"
|
||||||
|
# Header always set Referrer-Policy "no-referrer-when-downgrade"
|
||||||
|
#
|
||||||
|
# # Same configuration as HTTP version...
|
||||||
|
# </VirtualHost>
|
||||||
|
|
||||||
|
# Redirect HTTP to HTTPS (uncomment after SSL setup)
|
||||||
|
# <VirtualHost *:80>
|
||||||
|
# ServerName your-domain.com
|
||||||
|
# ServerAlias www.your-domain.com
|
||||||
|
# Redirect permanent / https://your-domain.com/
|
||||||
|
# </VirtualHost>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
[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 variables
|
||||||
|
Environment=APP_ENV=production
|
||||||
|
Environment=APP_DEBUG=false
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
LimitNOFILE=65536
|
||||||
|
LimitNPROC=32768
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ReadWritePaths=/var/www/bikeservice/backend/storage
|
||||||
|
ProtectHome=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
@@ -0,0 +1,411 @@
|
|||||||
|
# Apache Deployment Guide for Bike Service Application
|
||||||
|
|
||||||
|
This guide will help you deploy your Laravel + Vue.js application to Ubuntu 22.04 with Apache and MySQL.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Ubuntu 22.04 server with root/sudo access
|
||||||
|
- Domain name (optional but recommended)
|
||||||
|
- SSH access to your server
|
||||||
|
|
||||||
|
## Server Setup
|
||||||
|
|
||||||
|
### 1. Update System
|
||||||
|
```bash
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Install Required Software
|
||||||
|
```bash
|
||||||
|
# Install Apache
|
||||||
|
sudo apt install apache2 -y
|
||||||
|
|
||||||
|
# Install PHP 8.2 and extensions
|
||||||
|
sudo apt install software-properties-common -y
|
||||||
|
sudo add-apt-repository ppa:ondrej/php -y
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install php8.2 libapache2-mod-php8.2 php8.2-mysql 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
|
||||||
|
curl -sS https://getcomposer.org/installer | php
|
||||||
|
sudo mv composer.phar /usr/local/bin/composer
|
||||||
|
|
||||||
|
# Install Node.js and npm
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||||
|
sudo apt-get install -y nodejs
|
||||||
|
|
||||||
|
# Install Git
|
||||||
|
sudo apt install git -y
|
||||||
|
|
||||||
|
# Install MySQL
|
||||||
|
sudo apt install mysql-server -y
|
||||||
|
|
||||||
|
# Install additional tools
|
||||||
|
sudo apt install unzip curl wget htop ufw fail2ban -y
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Configure MySQL
|
||||||
|
```bash
|
||||||
|
# Secure MySQL installation
|
||||||
|
sudo mysql_secure_installation
|
||||||
|
|
||||||
|
# Create database and user
|
||||||
|
sudo mysql -u root -p
|
||||||
|
```
|
||||||
|
|
||||||
|
In MySQL console:
|
||||||
|
```sql
|
||||||
|
CREATE DATABASE bikeservice_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
CREATE USER 'bikeservice_user'@'localhost' IDENTIFIED BY 'your_secure_password';
|
||||||
|
GRANT ALL PRIVILEGES ON bikeservice_db.* TO 'bikeservice_user'@'localhost';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
EXIT;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Configure PHP
|
||||||
|
```bash
|
||||||
|
# Edit PHP configuration
|
||||||
|
sudo nano /etc/php/8.2/apache2/php.ini
|
||||||
|
|
||||||
|
# Set these values:
|
||||||
|
# memory_limit = 256M
|
||||||
|
# upload_max_filesize = 64M
|
||||||
|
# post_max_size = 64M
|
||||||
|
# max_execution_time = 300
|
||||||
|
# opcache.enable = 1
|
||||||
|
# opcache.memory_consumption = 128
|
||||||
|
# opcache.max_accelerated_files = 4000
|
||||||
|
|
||||||
|
# Restart Apache
|
||||||
|
sudo systemctl restart apache2
|
||||||
|
sudo systemctl enable apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Enable Apache Modules
|
||||||
|
```bash
|
||||||
|
sudo a2enmod rewrite
|
||||||
|
sudo a2enmod ssl
|
||||||
|
sudo a2enmod headers
|
||||||
|
sudo a2enmod deflate
|
||||||
|
sudo a2enmod expires
|
||||||
|
sudo systemctl restart apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Application Deployment
|
||||||
|
|
||||||
|
### 1. Create Application Directory
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /var/www/bikeservice
|
||||||
|
sudo chown -R $USER:$USER /var/www/bikeservice
|
||||||
|
cd /var/www/bikeservice
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Clone Your Repository
|
||||||
|
```bash
|
||||||
|
git clone <your-repository-url> .
|
||||||
|
# Or upload your files via SCP/SFTP
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Backend Setup (Laravel)
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
composer install --no-dev --optimize-autoloader
|
||||||
|
|
||||||
|
# Set permissions
|
||||||
|
sudo chown -R www-data:www-data storage bootstrap/cache
|
||||||
|
sudo chmod -R 775 storage bootstrap/cache
|
||||||
|
|
||||||
|
# Create .env file
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
# Generate application key
|
||||||
|
php artisan key:generate
|
||||||
|
|
||||||
|
# Configure database in .env file
|
||||||
|
# DB_CONNECTION=mysql
|
||||||
|
# DB_HOST=127.0.0.1
|
||||||
|
# DB_PORT=3306
|
||||||
|
# DB_DATABASE=bikeservice_db
|
||||||
|
# DB_USERNAME=bikeservice_user
|
||||||
|
# DB_PASSWORD=your_secure_password
|
||||||
|
|
||||||
|
# Run migrations
|
||||||
|
php artisan migrate --force
|
||||||
|
|
||||||
|
# Clear and cache config
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan route:cache
|
||||||
|
php artisan view:cache
|
||||||
|
|
||||||
|
# Set production environment
|
||||||
|
echo "APP_ENV=production" >> .env
|
||||||
|
echo "APP_DEBUG=false" >> .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Frontend Setup (Vue.js)
|
||||||
|
```bash
|
||||||
|
cd ../frontend
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Build for production
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Copy built files to Laravel public directory
|
||||||
|
cp -r dist/* ../backend/public/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Apache Configuration
|
||||||
|
|
||||||
|
### 1. Create Apache Virtual Host
|
||||||
|
```bash
|
||||||
|
sudo nano /etc/apache2/sites-available/bikeservice.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Add this configuration:
|
||||||
|
```apache
|
||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName your-domain.com
|
||||||
|
ServerAlias www.your-domain.com
|
||||||
|
DocumentRoot /var/www/bikeservice/backend/public
|
||||||
|
|
||||||
|
<Directory /var/www/bikeservice/backend/public>
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
Header always set X-Frame-Options "SAMEORIGIN"
|
||||||
|
Header always set X-XSS-Protection "1; mode=block"
|
||||||
|
Header always set X-Content-Type-Options "nosniff"
|
||||||
|
Header always set Referrer-Policy "no-referrer-when-downgrade"
|
||||||
|
|
||||||
|
# Gzip compression
|
||||||
|
LoadModule deflate_module modules/mod_deflate.so
|
||||||
|
<Location />
|
||||||
|
SetOutputFilter DEFLATE
|
||||||
|
SetEnvIfNoCase Request_URI \
|
||||||
|
\.(?:gif|jpe?g|png)$ no-gzip dont-vary
|
||||||
|
SetEnvIfNoCase Request_URI \
|
||||||
|
\.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
|
||||||
|
</Location>
|
||||||
|
|
||||||
|
# Cache static assets
|
||||||
|
<LocationMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$">
|
||||||
|
ExpiresActive On
|
||||||
|
ExpiresDefault "access plus 1 year"
|
||||||
|
Header append Cache-Control "public, immutable"
|
||||||
|
</LocationMatch>
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
ErrorLog ${APACHE_LOG_DIR}/bikeservice_error.log
|
||||||
|
CustomLog ${APACHE_LOG_DIR}/bikeservice_access.log combined
|
||||||
|
</VirtualHost>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Enable Site and Restart Apache
|
||||||
|
```bash
|
||||||
|
sudo a2ensite bikeservice.conf
|
||||||
|
sudo a2dissite 000-default.conf
|
||||||
|
sudo apache2ctl configtest
|
||||||
|
sudo systemctl restart apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
## SSL Certificate (Optional but Recommended)
|
||||||
|
|
||||||
|
### 1. Install Certbot
|
||||||
|
```bash
|
||||||
|
sudo apt install certbot python3-certbot-apache -y
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Obtain SSL Certificate
|
||||||
|
```bash
|
||||||
|
sudo certbot --apache -d your-domain.com -d www.your-domain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## Final Configuration
|
||||||
|
|
||||||
|
### 1. Set Proper Permissions
|
||||||
|
```bash
|
||||||
|
sudo chown -R www-data:www-data /var/www/bikeservice
|
||||||
|
sudo chmod -R 755 /var/www/bikeservice
|
||||||
|
sudo chmod -R 775 /var/www/bikeservice/backend/storage
|
||||||
|
sudo chmod -R 775 /var/www/bikeservice/backend/bootstrap/cache
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Configure Queue Worker (if using queues)
|
||||||
|
```bash
|
||||||
|
# Create systemd service for queue worker
|
||||||
|
sudo nano /etc/systemd/system/bikeservice-queue.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Add this content:
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Bike Service Queue Worker
|
||||||
|
After=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
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Enable and start the service:
|
||||||
|
```bash
|
||||||
|
sudo systemctl enable bikeservice-queue
|
||||||
|
sudo systemctl start bikeservice-queue
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Set up Cron for Laravel Scheduler
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
Add this line:
|
||||||
|
```
|
||||||
|
* * * * * cd /var/www/bikeservice/backend && php artisan schedule:run >> /dev/null 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment Script
|
||||||
|
|
||||||
|
Create a deployment script for future updates:
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# deploy-apache.sh
|
||||||
|
|
||||||
|
cd /var/www/bikeservice
|
||||||
|
|
||||||
|
# Pull latest changes
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Backend deployment
|
||||||
|
cd backend
|
||||||
|
composer install --no-dev --optimize-autoloader
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan route:cache
|
||||||
|
php artisan view:cache
|
||||||
|
|
||||||
|
# Frontend deployment
|
||||||
|
cd ../frontend
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
cp -r dist/* ../backend/public/
|
||||||
|
|
||||||
|
# Set permissions
|
||||||
|
sudo chown -R www-data:www-data /var/www/bikeservice
|
||||||
|
sudo chmod -R 755 /var/www/bikeservice
|
||||||
|
sudo chmod -R 775 /var/www/bikeservice/backend/storage
|
||||||
|
sudo chmod -R 775 /var/www/bikeservice/backend/bootstrap/cache
|
||||||
|
|
||||||
|
# Restart services
|
||||||
|
sudo systemctl restart apache2
|
||||||
|
|
||||||
|
echo "Deployment completed!"
|
||||||
|
```
|
||||||
|
|
||||||
|
Make it executable:
|
||||||
|
```bash
|
||||||
|
chmod +x deploy-apache.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring and Maintenance
|
||||||
|
|
||||||
|
### 1. Check Application Status
|
||||||
|
```bash
|
||||||
|
# Check Apache status
|
||||||
|
sudo systemctl status apache2
|
||||||
|
|
||||||
|
# Check MySQL status
|
||||||
|
sudo systemctl status mysql
|
||||||
|
|
||||||
|
# Check queue worker status
|
||||||
|
sudo systemctl status bikeservice-queue
|
||||||
|
|
||||||
|
# Check Laravel logs
|
||||||
|
tail -f /var/www/bikeservice/backend/storage/logs/laravel.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Regular Maintenance
|
||||||
|
```bash
|
||||||
|
# Update system packages
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
|
||||||
|
# Clear Laravel caches
|
||||||
|
cd /var/www/bikeservice/backend
|
||||||
|
php artisan cache:clear
|
||||||
|
php artisan config:clear
|
||||||
|
php artisan route:clear
|
||||||
|
php artisan view:clear
|
||||||
|
|
||||||
|
# Rebuild caches
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan route:cache
|
||||||
|
php artisan view:cache
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues:
|
||||||
|
1. **Permission denied errors**: Check file ownership and permissions
|
||||||
|
2. **500 Internal Server Error**: Check Apache error logs and Laravel logs
|
||||||
|
3. **Database connection issues**: Verify MySQL configuration in .env
|
||||||
|
4. **Static assets not loading**: Check Apache configuration and file paths
|
||||||
|
5. **URL rewriting not working**: Ensure mod_rewrite is enabled
|
||||||
|
|
||||||
|
### Useful Commands:
|
||||||
|
```bash
|
||||||
|
# Check Apache error logs
|
||||||
|
sudo tail -f /var/log/apache2/error.log
|
||||||
|
|
||||||
|
# Check Apache access logs
|
||||||
|
sudo tail -f /var/log/apache2/access.log
|
||||||
|
|
||||||
|
# Test Apache configuration
|
||||||
|
sudo apache2ctl configtest
|
||||||
|
|
||||||
|
# Restart all services
|
||||||
|
sudo systemctl restart apache2 mysql bikeservice-queue
|
||||||
|
|
||||||
|
# Check MySQL status
|
||||||
|
sudo mysql -u root -p -e "SHOW DATABASES;"
|
||||||
|
|
||||||
|
# Check PHP version and modules
|
||||||
|
php -v
|
||||||
|
php -m
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
1. **Firewall**: Configure UFW firewall
|
||||||
|
2. **SSH**: Use key-based authentication and change default port
|
||||||
|
3. **Database**: Use strong passwords and limit access
|
||||||
|
4. **Updates**: Keep system and packages updated
|
||||||
|
5. **Backups**: Set up regular backups of your application and database
|
||||||
|
6. **Apache Security**: Disable server signature and unnecessary modules
|
||||||
|
|
||||||
|
## Performance Optimization
|
||||||
|
|
||||||
|
1. **OPcache**: Enable PHP OPcache for better performance
|
||||||
|
2. **MySQL**: Optimize MySQL configuration
|
||||||
|
3. **Apache**: Enable compression and caching
|
||||||
|
4. **CDN**: Use a CDN for static assets
|
||||||
|
5. **Monitoring**: Set up application monitoring
|
||||||
|
|
||||||
|
## Apache vs Nginx Differences
|
||||||
|
|
||||||
|
- **Configuration**: Apache uses `.htaccess` files and virtual hosts
|
||||||
|
- **Modules**: Apache modules need to be enabled with `a2enmod`
|
||||||
|
- **Sites**: Apache sites are enabled with `a2ensite`
|
||||||
|
- **Logs**: Apache logs are in `/var/log/apache2/`
|
||||||
|
- **Restart**: Use `sudo systemctl restart apache2`
|
||||||
Executable
+263
@@ -0,0 +1,263 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Apache Deployment Script for Bike Service Application
|
||||||
|
# Make sure to run this script from the project root directory
|
||||||
|
|
||||||
|
set -e # Exit on any error
|
||||||
|
|
||||||
|
echo "🚀 Starting Apache deployment..."
|
||||||
|
|
||||||
|
# Check if we're in the right directory
|
||||||
|
if [ ! -f "backend/artisan" ] || [ ! -f "frontend/package.json" ]; then
|
||||||
|
echo "❌ Error: Please run this script from the project root directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Function to print colored output
|
||||||
|
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 on Ubuntu server
|
||||||
|
if [[ "$OSTYPE" != "linux-gnu"* ]]; then
|
||||||
|
print_warning "This script is designed for Ubuntu servers. Some commands may not work on your system."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [[ $EUID -eq 0 ]]; then
|
||||||
|
print_error "Please don't run this script as root. Use a regular user with sudo privileges."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if required commands exist
|
||||||
|
check_command() {
|
||||||
|
if ! command -v $1 &> /dev/null; then
|
||||||
|
print_error "$1 is not installed. Please install it first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_status "Checking required commands..."
|
||||||
|
check_command "php"
|
||||||
|
check_command "composer"
|
||||||
|
check_command "npm"
|
||||||
|
check_command "git"
|
||||||
|
check_command "mysql"
|
||||||
|
|
||||||
|
# Get current branch
|
||||||
|
CURRENT_BRANCH=$(git branch --show-current)
|
||||||
|
print_status "Current branch: $CURRENT_BRANCH"
|
||||||
|
|
||||||
|
# Ask for confirmation
|
||||||
|
read -p "Do you want to deploy from branch '$CURRENT_BRANCH'? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_warning "Deployment cancelled."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pull latest changes
|
||||||
|
print_status "Pulling latest changes from git..."
|
||||||
|
git pull origin $CURRENT_BRANCH
|
||||||
|
|
||||||
|
# Backend deployment
|
||||||
|
print_status "Deploying Laravel backend..."
|
||||||
|
cd backend
|
||||||
|
|
||||||
|
# Install/update dependencies
|
||||||
|
print_status "Installing Composer dependencies..."
|
||||||
|
composer install --no-dev --optimize-autoloader
|
||||||
|
|
||||||
|
# Check if .env exists, if not copy from example
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
print_warning ".env file not found, copying from .env.example..."
|
||||||
|
if [ -f ".env.example" ]; then
|
||||||
|
cp .env.example .env
|
||||||
|
print_warning "Please configure your .env file before continuing!"
|
||||||
|
print_warning "Make sure to set up your MySQL database configuration."
|
||||||
|
read -p "Press Enter after configuring .env file..."
|
||||||
|
else
|
||||||
|
print_error ".env.example file not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate key if not set
|
||||||
|
if ! grep -q "APP_KEY=base64:" .env; then
|
||||||
|
print_status "Generating application key..."
|
||||||
|
php artisan key:generate
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check database connection
|
||||||
|
print_status "Testing database connection..."
|
||||||
|
if php artisan migrate:status > /dev/null 2>&1; then
|
||||||
|
print_status "Database connection successful!"
|
||||||
|
else
|
||||||
|
print_error "Database connection failed! Please check your .env configuration."
|
||||||
|
print_warning "Make sure MySQL is running and your database credentials are correct."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run migrations
|
||||||
|
print_status "Running database migrations..."
|
||||||
|
php artisan migrate --force
|
||||||
|
|
||||||
|
# Clear and rebuild caches
|
||||||
|
print_status "Clearing and rebuilding caches..."
|
||||||
|
php artisan config:clear
|
||||||
|
php artisan route:clear
|
||||||
|
php artisan view:clear
|
||||||
|
php artisan cache:clear
|
||||||
|
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan route:cache
|
||||||
|
php artisan view:cache
|
||||||
|
|
||||||
|
# Set production environment
|
||||||
|
if ! grep -q "APP_ENV=production" .env; then
|
||||||
|
print_status "Setting production environment..."
|
||||||
|
sed -i 's/APP_ENV=.*/APP_ENV=production/' .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep -q "APP_DEBUG=false" .env; then
|
||||||
|
print_status "Disabling debug mode..."
|
||||||
|
sed -i 's/APP_DEBUG=.*/APP_DEBUG=false/' .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Frontend deployment
|
||||||
|
print_status "Deploying Vue.js frontend..."
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Install/update dependencies
|
||||||
|
print_status "Installing npm dependencies..."
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Build for production
|
||||||
|
print_status "Building frontend for production..."
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Copy built files to Laravel public directory
|
||||||
|
print_status "Copying built files to Laravel public directory..."
|
||||||
|
if [ -d "dist" ]; then
|
||||||
|
cp -r dist/* ../backend/public/
|
||||||
|
print_status "Frontend files copied successfully"
|
||||||
|
else
|
||||||
|
print_error "dist directory not found! Build may have failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Set proper permissions
|
||||||
|
print_status "Setting proper permissions..."
|
||||||
|
if command -v sudo &> /dev/null; then
|
||||||
|
sudo chown -R www-data:www-data backend/storage backend/bootstrap/cache
|
||||||
|
sudo chmod -R 775 backend/storage backend/bootstrap/cache
|
||||||
|
print_status "Permissions set successfully"
|
||||||
|
else
|
||||||
|
print_warning "sudo not available, skipping permission changes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Restart services (if running on server)
|
||||||
|
if command -v sudo &> /dev/null; then
|
||||||
|
print_status "Restarting services..."
|
||||||
|
|
||||||
|
# Check if Apache is running and restart it
|
||||||
|
if sudo systemctl is-active --quiet apache2; then
|
||||||
|
sudo systemctl restart apache2
|
||||||
|
print_status "Apache restarted"
|
||||||
|
else
|
||||||
|
print_warning "Apache is not running. Please start it manually: sudo systemctl start apache2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if MySQL is running
|
||||||
|
if sudo systemctl is-active --quiet mysql; then
|
||||||
|
print_status "MySQL is running"
|
||||||
|
else
|
||||||
|
print_warning "MySQL is not running. Please start it manually: sudo systemctl start mysql"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if queue worker service exists and restart it
|
||||||
|
if sudo systemctl list-units --type=service | grep -q "bikeservice-queue"; then
|
||||||
|
sudo systemctl restart bikeservice-queue
|
||||||
|
print_status "Queue worker restarted"
|
||||||
|
else
|
||||||
|
print_warning "Queue worker service not found. You may need to set it up manually."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_warning "sudo not available, skipping service restarts"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Final checks
|
||||||
|
print_status "Running final checks..."
|
||||||
|
|
||||||
|
# Check if Laravel is working
|
||||||
|
cd backend
|
||||||
|
if php artisan --version &> /dev/null; then
|
||||||
|
print_status "Laravel is working correctly"
|
||||||
|
else
|
||||||
|
print_error "Laravel is not working correctly"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if frontend files are accessible
|
||||||
|
if [ -f "public/index.html" ]; then
|
||||||
|
print_status "Frontend files are in place"
|
||||||
|
else
|
||||||
|
print_error "Frontend files are missing"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check Apache configuration
|
||||||
|
if command -v sudo &> /dev/null && command -v apache2ctl &> /dev/null; then
|
||||||
|
print_status "Testing Apache configuration..."
|
||||||
|
if sudo apache2ctl configtest > /dev/null 2>&1; then
|
||||||
|
print_status "Apache configuration is valid"
|
||||||
|
else
|
||||||
|
print_warning "Apache configuration has issues. Run 'sudo apache2ctl configtest' for details."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo -e "${GREEN}✅ Apache deployment completed successfully!${NC}"
|
||||||
|
echo
|
||||||
|
echo "Next steps:"
|
||||||
|
echo "1. Test your application in the browser"
|
||||||
|
echo "2. Check application logs if there are any issues"
|
||||||
|
echo "3. Verify all features are working correctly"
|
||||||
|
echo "4. Set up SSL certificate if needed"
|
||||||
|
echo
|
||||||
|
echo "Useful commands:"
|
||||||
|
echo "- Check Laravel logs: tail -f backend/storage/logs/laravel.log"
|
||||||
|
echo "- Check Apache error logs: sudo tail -f /var/log/apache2/error.log"
|
||||||
|
echo "- Check Apache access logs: sudo tail -f /var/log/apache2/access.log"
|
||||||
|
echo "- Test Apache config: sudo apache2ctl configtest"
|
||||||
|
echo "- Restart Apache: sudo systemctl restart apache2"
|
||||||
|
echo "- Check MySQL status: sudo systemctl status mysql"
|
||||||
|
echo
|
||||||
|
echo "Database information:"
|
||||||
|
echo "- Make sure MySQL is running: sudo systemctl start mysql"
|
||||||
|
echo "- Check database connection: mysql -u your_username -p your_database"
|
||||||
|
echo
|
||||||
|
echo "Apache configuration:"
|
||||||
|
echo "- Virtual host: /etc/apache2/sites-available/bikeservice.conf"
|
||||||
|
echo "- Enable site: sudo a2ensite bikeservice.conf"
|
||||||
|
echo "- Disable default: sudo a2dissite 000-default.conf"
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Deployment script for Bike Service Application
|
||||||
|
# Make sure to run this script from the project root directory
|
||||||
|
|
||||||
|
set -e # Exit on any error
|
||||||
|
|
||||||
|
echo "🚀 Starting deployment..."
|
||||||
|
|
||||||
|
# Check if we're in the right directory
|
||||||
|
if [ ! -f "backend/artisan" ] || [ ! -f "frontend/package.json" ]; then
|
||||||
|
echo "❌ Error: Please run this script from the project root directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Function to print colored output
|
||||||
|
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 on Ubuntu server
|
||||||
|
if [[ "$OSTYPE" != "linux-gnu"* ]]; then
|
||||||
|
print_warning "This script is designed for Ubuntu servers. Some commands may not work on your system."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [[ $EUID -eq 0 ]]; then
|
||||||
|
print_error "Please don't run this script as root. Use a regular user with sudo privileges."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if required commands exist
|
||||||
|
check_command() {
|
||||||
|
if ! command -v $1 &> /dev/null; then
|
||||||
|
print_error "$1 is not installed. Please install it first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_status "Checking required commands..."
|
||||||
|
check_command "php"
|
||||||
|
check_command "composer"
|
||||||
|
check_command "npm"
|
||||||
|
check_command "git"
|
||||||
|
|
||||||
|
# Get current branch
|
||||||
|
CURRENT_BRANCH=$(git branch --show-current)
|
||||||
|
print_status "Current branch: $CURRENT_BRANCH"
|
||||||
|
|
||||||
|
# Ask for confirmation
|
||||||
|
read -p "Do you want to deploy from branch '$CURRENT_BRANCH'? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_warning "Deployment cancelled."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pull latest changes
|
||||||
|
print_status "Pulling latest changes from git..."
|
||||||
|
git pull origin $CURRENT_BRANCH
|
||||||
|
|
||||||
|
# Backend deployment
|
||||||
|
print_status "Deploying Laravel backend..."
|
||||||
|
cd backend
|
||||||
|
|
||||||
|
# Install/update dependencies
|
||||||
|
print_status "Installing Composer dependencies..."
|
||||||
|
composer install --no-dev --optimize-autoloader
|
||||||
|
|
||||||
|
# Check if .env exists, if not copy from example
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
print_warning ".env file not found, copying from .env.example..."
|
||||||
|
if [ -f ".env.example" ]; then
|
||||||
|
cp .env.example .env
|
||||||
|
print_warning "Please configure your .env file before continuing!"
|
||||||
|
read -p "Press Enter after configuring .env file..."
|
||||||
|
else
|
||||||
|
print_error ".env.example file not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate key if not set
|
||||||
|
if ! grep -q "APP_KEY=base64:" .env; then
|
||||||
|
print_status "Generating application key..."
|
||||||
|
php artisan key:generate
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run migrations
|
||||||
|
print_status "Running database migrations..."
|
||||||
|
php artisan migrate --force
|
||||||
|
|
||||||
|
# Clear and rebuild caches
|
||||||
|
print_status "Clearing and rebuilding caches..."
|
||||||
|
php artisan config:clear
|
||||||
|
php artisan route:clear
|
||||||
|
php artisan view:clear
|
||||||
|
php artisan cache:clear
|
||||||
|
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan route:cache
|
||||||
|
php artisan view:cache
|
||||||
|
|
||||||
|
# Set production environment
|
||||||
|
if ! grep -q "APP_ENV=production" .env; then
|
||||||
|
print_status "Setting production environment..."
|
||||||
|
sed -i 's/APP_ENV=.*/APP_ENV=production/' .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep -q "APP_DEBUG=false" .env; then
|
||||||
|
print_status "Disabling debug mode..."
|
||||||
|
sed -i 's/APP_DEBUG=.*/APP_DEBUG=false/' .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Frontend deployment
|
||||||
|
print_status "Deploying Vue.js frontend..."
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Install/update dependencies
|
||||||
|
print_status "Installing npm dependencies..."
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Build for production
|
||||||
|
print_status "Building frontend for production..."
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Copy built files to Laravel public directory
|
||||||
|
print_status "Copying built files to Laravel public directory..."
|
||||||
|
if [ -d "dist" ]; then
|
||||||
|
cp -r dist/* ../backend/public/
|
||||||
|
print_status "Frontend files copied successfully"
|
||||||
|
else
|
||||||
|
print_error "dist directory not found! Build may have failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Set proper permissions
|
||||||
|
print_status "Setting proper permissions..."
|
||||||
|
if command -v sudo &> /dev/null; then
|
||||||
|
sudo chown -R www-data:www-data backend/storage backend/bootstrap/cache
|
||||||
|
sudo chmod -R 775 backend/storage backend/bootstrap/cache
|
||||||
|
print_status "Permissions set successfully"
|
||||||
|
else
|
||||||
|
print_warning "sudo not available, skipping permission changes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Restart services (if running on server)
|
||||||
|
if command -v sudo &> /dev/null; then
|
||||||
|
print_status "Restarting services..."
|
||||||
|
|
||||||
|
# Check if services exist and restart them
|
||||||
|
if sudo systemctl list-units --type=service | grep -q "php8.2-fpm"; then
|
||||||
|
sudo systemctl restart php8.2-fpm
|
||||||
|
print_status "PHP-FPM restarted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if sudo systemctl list-units --type=service | grep -q "nginx"; then
|
||||||
|
sudo systemctl restart nginx
|
||||||
|
print_status "Nginx restarted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if sudo systemctl list-units --type=service | grep -q "bikeservice-queue"; then
|
||||||
|
sudo systemctl restart bikeservice-queue
|
||||||
|
print_status "Queue worker restarted"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_warning "sudo not available, skipping service restarts"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Final checks
|
||||||
|
print_status "Running final checks..."
|
||||||
|
|
||||||
|
# Check if Laravel is working
|
||||||
|
cd backend
|
||||||
|
if php artisan --version &> /dev/null; then
|
||||||
|
print_status "Laravel is working correctly"
|
||||||
|
else
|
||||||
|
print_error "Laravel is not working correctly"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if frontend files are accessible
|
||||||
|
if [ -f "public/index.html" ]; then
|
||||||
|
print_status "Frontend files are in place"
|
||||||
|
else
|
||||||
|
print_error "Frontend files are missing"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo -e "${GREEN}✅ Deployment completed successfully!${NC}"
|
||||||
|
echo
|
||||||
|
echo "Next steps:"
|
||||||
|
echo "1. Test your application in the browser"
|
||||||
|
echo "2. Check application logs if there are any issues"
|
||||||
|
echo "3. Verify all features are working correctly"
|
||||||
|
echo
|
||||||
|
echo "Useful commands:"
|
||||||
|
echo "- Check Laravel logs: tail -f backend/storage/logs/laravel.log"
|
||||||
|
echo "- Check Nginx logs: sudo tail -f /var/log/nginx/error.log"
|
||||||
|
echo "- Check PHP-FPM logs: sudo tail -f /var/log/php8.2-fpm.log"
|
||||||
|
echo "- Restart all services: sudo systemctl restart nginx php8.2-fpm"
|
||||||
|
|
||||||
@@ -0,0 +1,354 @@
|
|||||||
|
# Deployment Guide for Bike Service Application
|
||||||
|
|
||||||
|
This guide will help you deploy your Laravel + Vue.js application to an Ubuntu server.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Ubuntu 20.04+ server with root/sudo access
|
||||||
|
- Domain name (optional but recommended)
|
||||||
|
- SSH access to your server
|
||||||
|
|
||||||
|
## Server Setup
|
||||||
|
|
||||||
|
### 1. Update System
|
||||||
|
```bash
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Install Required Software
|
||||||
|
```bash
|
||||||
|
# Install Nginx
|
||||||
|
sudo apt install nginx -y
|
||||||
|
|
||||||
|
# Install PHP 8.2 and extensions
|
||||||
|
sudo apt install software-properties-common -y
|
||||||
|
sudo add-apt-repository ppa:ondrej/php -y
|
||||||
|
sudo apt update
|
||||||
|
sudo 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 -y
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
curl -sS https://getcomposer.org/installer | php
|
||||||
|
sudo mv composer.phar /usr/local/bin/composer
|
||||||
|
|
||||||
|
# Install Node.js and npm
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||||
|
sudo apt-get install -y nodejs
|
||||||
|
|
||||||
|
# Install Git
|
||||||
|
sudo apt install git -y
|
||||||
|
|
||||||
|
# Install SQLite (if using SQLite)
|
||||||
|
sudo apt install sqlite3 -y
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Configure PHP-FPM
|
||||||
|
```bash
|
||||||
|
# Edit PHP-FPM configuration
|
||||||
|
sudo nano /etc/php/8.2/fpm/php.ini
|
||||||
|
|
||||||
|
# Set these values:
|
||||||
|
# memory_limit = 256M
|
||||||
|
# upload_max_filesize = 64M
|
||||||
|
# post_max_size = 64M
|
||||||
|
# max_execution_time = 300
|
||||||
|
|
||||||
|
# Restart PHP-FPM
|
||||||
|
sudo systemctl restart php8.2-fpm
|
||||||
|
sudo systemctl enable php8.2-fpm
|
||||||
|
```
|
||||||
|
|
||||||
|
## Application Deployment
|
||||||
|
|
||||||
|
### 1. Create Application Directory
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /var/www/bikeservice
|
||||||
|
sudo chown -R $USER:$USER /var/www/bikeservice
|
||||||
|
cd /var/www/bikeservice
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Clone Your Repository
|
||||||
|
```bash
|
||||||
|
git clone <your-repository-url> .
|
||||||
|
# Or upload your files via SCP/SFTP
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Backend Setup (Laravel)
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
composer install --no-dev --optimize-autoloader
|
||||||
|
|
||||||
|
# Set permissions
|
||||||
|
sudo chown -R www-data:www-data storage bootstrap/cache
|
||||||
|
sudo chmod -R 775 storage bootstrap/cache
|
||||||
|
|
||||||
|
# Create .env file
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
# Generate application key
|
||||||
|
php artisan key:generate
|
||||||
|
|
||||||
|
# Configure database (update .env file)
|
||||||
|
# For production, consider using MySQL/PostgreSQL instead of SQLite
|
||||||
|
|
||||||
|
# Run migrations
|
||||||
|
php artisan migrate --force
|
||||||
|
|
||||||
|
# Clear and cache config
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan route:cache
|
||||||
|
php artisan view:cache
|
||||||
|
|
||||||
|
# Set production environment
|
||||||
|
echo "APP_ENV=production" >> .env
|
||||||
|
echo "APP_DEBUG=false" >> .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Frontend Setup (Vue.js)
|
||||||
|
```bash
|
||||||
|
cd ../frontend
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Build for production
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Copy built files to Laravel public directory
|
||||||
|
cp -r dist/* ../backend/public/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Nginx Configuration
|
||||||
|
|
||||||
|
### 1. Create Nginx Site Configuration
|
||||||
|
```bash
|
||||||
|
sudo nano /etc/nginx/sites-available/bikeservice
|
||||||
|
```
|
||||||
|
|
||||||
|
Add this configuration:
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name your-domain.com www.your-domain.com;
|
||||||
|
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;
|
||||||
|
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.(?!well-known).* {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cache static assets
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Enable Site and Restart Nginx
|
||||||
|
```bash
|
||||||
|
sudo ln -s /etc/nginx/sites-available/bikeservice /etc/nginx/sites-enabled/
|
||||||
|
sudo nginx -t
|
||||||
|
sudo systemctl restart nginx
|
||||||
|
sudo systemctl enable nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
## SSL Certificate (Optional but Recommended)
|
||||||
|
|
||||||
|
### 1. Install Certbot
|
||||||
|
```bash
|
||||||
|
sudo apt install certbot python3-certbot-nginx -y
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Obtain SSL Certificate
|
||||||
|
```bash
|
||||||
|
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## Final Configuration
|
||||||
|
|
||||||
|
### 1. Set Proper Permissions
|
||||||
|
```bash
|
||||||
|
sudo chown -R www-data:www-data /var/www/bikeservice
|
||||||
|
sudo chmod -R 755 /var/www/bikeservice
|
||||||
|
sudo chmod -R 775 /var/www/bikeservice/backend/storage
|
||||||
|
sudo chmod -R 775 /var/www/bikeservice/backend/bootstrap/cache
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Configure Queue Worker (if using queues)
|
||||||
|
```bash
|
||||||
|
# Create systemd service for queue worker
|
||||||
|
sudo nano /etc/systemd/system/bikeservice-queue.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Add this content:
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Bike Service Queue Worker
|
||||||
|
After=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
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Enable and start the service:
|
||||||
|
```bash
|
||||||
|
sudo systemctl enable bikeservice-queue
|
||||||
|
sudo systemctl start bikeservice-queue
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Set up Cron for Laravel Scheduler
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
Add this line:
|
||||||
|
```
|
||||||
|
* * * * * cd /var/www/bikeservice/backend && php artisan schedule:run >> /dev/null 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment Script
|
||||||
|
|
||||||
|
Create a deployment script for future updates:
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# deploy.sh
|
||||||
|
|
||||||
|
cd /var/www/bikeservice
|
||||||
|
|
||||||
|
# Pull latest changes
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Backend deployment
|
||||||
|
cd backend
|
||||||
|
composer install --no-dev --optimize-autoloader
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan route:cache
|
||||||
|
php artisan view:cache
|
||||||
|
|
||||||
|
# Frontend deployment
|
||||||
|
cd ../frontend
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
cp -r dist/* ../backend/public/
|
||||||
|
|
||||||
|
# Set permissions
|
||||||
|
sudo chown -R www-data:www-data /var/www/bikeservice
|
||||||
|
sudo chmod -R 755 /var/www/bikeservice
|
||||||
|
sudo chmod -R 775 /var/www/bikeservice/backend/storage
|
||||||
|
sudo chmod -R 775 /var/www/bikeservice/backend/bootstrap/cache
|
||||||
|
|
||||||
|
# Restart services
|
||||||
|
sudo systemctl restart php8.2-fpm
|
||||||
|
sudo systemctl restart nginx
|
||||||
|
|
||||||
|
echo "Deployment completed!"
|
||||||
|
```
|
||||||
|
|
||||||
|
Make it executable:
|
||||||
|
```bash
|
||||||
|
chmod +x deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring and Maintenance
|
||||||
|
|
||||||
|
### 1. Check Application Status
|
||||||
|
```bash
|
||||||
|
# Check Nginx status
|
||||||
|
sudo systemctl status nginx
|
||||||
|
|
||||||
|
# Check PHP-FPM status
|
||||||
|
sudo systemctl status php8.2-fpm
|
||||||
|
|
||||||
|
# Check queue worker status
|
||||||
|
sudo systemctl status bikeservice-queue
|
||||||
|
|
||||||
|
# Check Laravel logs
|
||||||
|
tail -f /var/www/bikeservice/backend/storage/logs/laravel.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Regular Maintenance
|
||||||
|
```bash
|
||||||
|
# Update system packages
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
|
||||||
|
# Clear Laravel caches
|
||||||
|
cd /var/www/bikeservice/backend
|
||||||
|
php artisan cache:clear
|
||||||
|
php artisan config:clear
|
||||||
|
php artisan route:clear
|
||||||
|
php artisan view:clear
|
||||||
|
|
||||||
|
# Rebuild caches
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan route:cache
|
||||||
|
php artisan view:cache
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues:
|
||||||
|
1. **Permission denied errors**: Check file ownership and permissions
|
||||||
|
2. **500 Internal Server Error**: Check Laravel logs and PHP-FPM logs
|
||||||
|
3. **Database connection issues**: Verify database configuration in .env
|
||||||
|
4. **Static assets not loading**: Check Nginx configuration and file paths
|
||||||
|
|
||||||
|
### Useful Commands:
|
||||||
|
```bash
|
||||||
|
# Check Nginx error logs
|
||||||
|
sudo tail -f /var/log/nginx/error.log
|
||||||
|
|
||||||
|
# Check PHP-FPM logs
|
||||||
|
sudo tail -f /var/log/php8.2-fpm.log
|
||||||
|
|
||||||
|
# Test Nginx configuration
|
||||||
|
sudo nginx -t
|
||||||
|
|
||||||
|
# Restart all services
|
||||||
|
sudo systemctl restart nginx php8.2-fpm bikeservice-queue
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
1. **Firewall**: Configure UFW firewall
|
||||||
|
2. **SSH**: Use key-based authentication and change default port
|
||||||
|
3. **Database**: Use strong passwords and limit access
|
||||||
|
4. **Updates**: Keep system and packages updated
|
||||||
|
5. **Backups**: Set up regular backups of your application and database
|
||||||
|
|
||||||
|
## Performance Optimization
|
||||||
|
|
||||||
|
1. **OPcache**: Enable PHP OPcache for better performance
|
||||||
|
2. **Redis**: Consider using Redis for caching and sessions
|
||||||
|
3. **CDN**: Use a CDN for static assets
|
||||||
|
4. **Database**: Optimize database queries and indexes
|
||||||
|
5. **Monitoring**: Set up application monitoring (Laravel Telescope, etc.)
|
||||||
|
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
# Laravel Environment Configuration for Apache/MySQL Deployment
|
||||||
|
# Copy this file to .env and update the values
|
||||||
|
|
||||||
|
APP_NAME="Bike Service"
|
||||||
|
APP_ENV=production
|
||||||
|
APP_KEY=
|
||||||
|
APP_DEBUG=false
|
||||||
|
APP_URL=http://your-domain.com
|
||||||
|
|
||||||
|
# Database Configuration for MySQL
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=127.0.0.1
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=bikeservice_db
|
||||||
|
DB_USERNAME=bikeservice_user
|
||||||
|
DB_PASSWORD=your_secure_password
|
||||||
|
|
||||||
|
# Cache Configuration
|
||||||
|
CACHE_DRIVER=file
|
||||||
|
FILESYSTEM_DISK=local
|
||||||
|
QUEUE_CONNECTION=sync
|
||||||
|
SESSION_DRIVER=file
|
||||||
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
|
# Mail Configuration (update with your mail settings)
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=mailpit
|
||||||
|
MAIL_PORT=1025
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_FROM_ADDRESS="hello@example.com"
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
# AWS Configuration (if using S3)
|
||||||
|
AWS_ACCESS_KEY_ID=
|
||||||
|
AWS_SECRET_ACCESS_KEY=
|
||||||
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
|
AWS_BUCKET=
|
||||||
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
|
# Pusher Configuration (if using real-time features)
|
||||||
|
PUSHER_APP_ID=
|
||||||
|
PUSHER_APP_KEY=
|
||||||
|
PUSHER_APP_SECRET=
|
||||||
|
PUSHER_HOST=
|
||||||
|
PUSHER_PORT=443
|
||||||
|
PUSHER_SCHEME=https
|
||||||
|
PUSHER_APP_CLUSTER=mt1
|
||||||
|
|
||||||
|
# Vite Configuration
|
||||||
|
VITE_APP_NAME="${APP_NAME}"
|
||||||
|
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||||
|
VITE_PUSHER_HOST="${PUSHER_HOST}"
|
||||||
|
VITE_PUSHER_PORT="${PUSHER_PORT}"
|
||||||
|
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
||||||
|
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
|
|
||||||
|
# Additional Configuration
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
LOG_DEPRECATIONS_CHANNEL=null
|
||||||
|
LOG_LEVEL=debug
|
||||||
|
|
||||||
|
# Security
|
||||||
|
SANCTUM_STATEFUL_DOMAINS=localhost,127.0.0.1,127.0.0.1:8000,::1,your-domain.com
|
||||||
|
SESSION_DOMAIN=null
|
||||||
|
|
||||||
|
# Performance
|
||||||
|
BROADCAST_DRIVER=log
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
-- MySQL Database Setup for Bike Service Application
|
||||||
|
-- Run this script as root user: mysql -u root -p < mysql-setup.sql
|
||||||
|
|
||||||
|
-- Create database
|
||||||
|
CREATE DATABASE IF NOT EXISTS bikeservice_db
|
||||||
|
CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- Create user (replace 'your_secure_password' with a strong password)
|
||||||
|
CREATE USER IF NOT EXISTS 'bikeservice_user'@'localhost'
|
||||||
|
IDENTIFIED BY 'your_secure_password';
|
||||||
|
|
||||||
|
-- Grant privileges
|
||||||
|
GRANT ALL PRIVILEGES ON bikeservice_db.* TO 'bikeservice_user'@'localhost';
|
||||||
|
|
||||||
|
-- Grant additional privileges for Laravel
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON bikeservice_db.* TO 'bikeservice_user'@'localhost';
|
||||||
|
|
||||||
|
-- Flush privileges
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
|
||||||
|
-- Show created database and user
|
||||||
|
SHOW DATABASES;
|
||||||
|
SELECT User, Host FROM mysql.user WHERE User = 'bikeservice_user';
|
||||||
|
|
||||||
|
-- Display success message
|
||||||
|
SELECT 'Database and user created successfully!' as Status;
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name your-domain.com www.your-domain.com;
|
||||||
|
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;
|
||||||
|
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" 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;
|
||||||
|
|
||||||
|
# Handle Laravel routes
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle PHP files
|
||||||
|
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 optimizations
|
||||||
|
fastcgi_buffer_size 128k;
|
||||||
|
fastcgi_buffers 4 256k;
|
||||||
|
fastcgi_busy_buffers_size 256k;
|
||||||
|
fastcgi_read_timeout 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deny access to hidden files
|
||||||
|
location ~ /\.(?!well-known).* {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deny access to sensitive files
|
||||||
|
location ~* \.(env|log|sql|md|txt|yml|yaml|ini)$ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cache static assets
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
add_header Vary Accept-Encoding;
|
||||||
|
|
||||||
|
# Enable gzip for static assets
|
||||||
|
gzip_static on;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cache API responses (adjust as needed)
|
||||||
|
location ~* ^/api/ {
|
||||||
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
|
add_header Pragma "no-cache";
|
||||||
|
add_header Expires "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rate limiting for API endpoints
|
||||||
|
location ~* ^/api/ {
|
||||||
|
limit_req zone=api burst=10 nodelay;
|
||||||
|
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
access_log /var/log/nginx/bikeservice_access.log;
|
||||||
|
error_log /var/log/nginx/bikeservice_error.log;
|
||||||
|
|
||||||
|
# Client max body size (for file uploads)
|
||||||
|
client_max_body_size 64M;
|
||||||
|
|
||||||
|
# Timeouts
|
||||||
|
client_body_timeout 60s;
|
||||||
|
client_header_timeout 60s;
|
||||||
|
send_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rate limiting configuration (add this to http block or create separate file)
|
||||||
|
# limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||||
|
# limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s;
|
||||||
|
|
||||||
Executable
+294
@@ -0,0 +1,294 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Apache Server Setup Script for Bike Service Application
|
||||||
|
# Run this script on your Ubuntu 22.04 server after initial setup
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🚀 Setting up Ubuntu 22.04 server with Apache and MySQL 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" != "22.04" ]]; then
|
||||||
|
print_warning "This script is designed for Ubuntu 22.04. You're running $UBUNTU_VERSION"
|
||||||
|
read -p "Continue anyway? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
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 Apache
|
||||||
|
apt install apache2 -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 libapache2-mod-php8.2 php8.2-mysql 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 MySQL
|
||||||
|
print_status "Installing MySQL..."
|
||||||
|
apt install mysql-server -y
|
||||||
|
|
||||||
|
# Install additional tools
|
||||||
|
apt install unzip curl wget htop ufw fail2ban -y
|
||||||
|
|
||||||
|
# Configure PHP
|
||||||
|
print_status "Configuring PHP..."
|
||||||
|
PHP_INI="/etc/php/8.2/apache2/php.ini"
|
||||||
|
|
||||||
|
# Backup original file
|
||||||
|
cp $PHP_INI $PHP_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
|
||||||
|
|
||||||
|
# Enable Apache modules
|
||||||
|
print_status "Enabling Apache modules..."
|
||||||
|
a2enmod rewrite
|
||||||
|
a2enmod ssl
|
||||||
|
a2enmod headers
|
||||||
|
a2enmod deflate
|
||||||
|
a2enmod expires
|
||||||
|
a2enmod php8.2
|
||||||
|
|
||||||
|
# Configure Apache
|
||||||
|
print_status "Configuring Apache..."
|
||||||
|
|
||||||
|
# Create application directory
|
||||||
|
mkdir -p /var/www/bikeservice
|
||||||
|
chown -R www-data:www-data /var/www/bikeservice
|
||||||
|
|
||||||
|
# Create Apache virtual host
|
||||||
|
cat > /etc/apache2/sites-available/bikeservice.conf << 'EOF'
|
||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName _
|
||||||
|
DocumentRoot /var/www/bikeservice/backend/public
|
||||||
|
|
||||||
|
<Directory /var/www/bikeservice/backend/public>
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
|
||||||
|
# Laravel specific rules
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteRule ^(.*)$ index.php [QSA,L]
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
Header always set X-Frame-Options "SAMEORIGIN"
|
||||||
|
Header always set X-XSS-Protection "1; mode=block"
|
||||||
|
Header always set X-Content-Type-Options "nosniff"
|
||||||
|
Header always set Referrer-Policy "no-referrer-when-downgrade"
|
||||||
|
|
||||||
|
# Gzip compression
|
||||||
|
<Location />
|
||||||
|
SetOutputFilter DEFLATE
|
||||||
|
SetEnvIfNoCase Request_URI \
|
||||||
|
\.(?:gif|jpe?g|png)$ no-gzip dont-vary
|
||||||
|
SetEnvIfNoCase Request_URI \
|
||||||
|
\.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
|
||||||
|
</Location>
|
||||||
|
|
||||||
|
# Cache static assets
|
||||||
|
<LocationMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$">
|
||||||
|
ExpiresActive On
|
||||||
|
ExpiresDefault "access plus 1 year"
|
||||||
|
Header append Cache-Control "public, immutable"
|
||||||
|
</LocationMatch>
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
ErrorLog ${APACHE_LOG_DIR}/bikeservice_error.log
|
||||||
|
CustomLog ${APACHE_LOG_DIR}/bikeservice_access.log combined
|
||||||
|
|
||||||
|
# Client max body size (for file uploads)
|
||||||
|
LimitRequestBody 67108864
|
||||||
|
</VirtualHost>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Enable site
|
||||||
|
a2ensite bikeservice.conf
|
||||||
|
a2dissite 000-default.conf
|
||||||
|
|
||||||
|
# Test Apache configuration
|
||||||
|
apache2ctl configtest
|
||||||
|
|
||||||
|
# Restart Apache
|
||||||
|
systemctl restart apache2
|
||||||
|
systemctl enable apache2
|
||||||
|
|
||||||
|
# Configure MySQL
|
||||||
|
print_status "Configuring MySQL..."
|
||||||
|
systemctl start mysql
|
||||||
|
systemctl enable mysql
|
||||||
|
|
||||||
|
# Secure MySQL installation
|
||||||
|
print_warning "You will need to secure MySQL installation manually:"
|
||||||
|
print_warning "Run: sudo mysql_secure_installation"
|
||||||
|
|
||||||
|
# Configure firewall
|
||||||
|
print_status "Configuring firewall..."
|
||||||
|
ufw --force enable
|
||||||
|
ufw allow ssh
|
||||||
|
ufw allow 'Apache 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/apache2/bikeservice_access.log
|
||||||
|
touch /var/log/apache2/bikeservice_error.log
|
||||||
|
chown www-data:adm /var/log/apache2/bikeservice_*.log
|
||||||
|
|
||||||
|
print_status "Server setup completed!"
|
||||||
|
echo
|
||||||
|
echo "Next steps:"
|
||||||
|
echo "1. Secure MySQL installation: sudo mysql_secure_installation"
|
||||||
|
echo "2. Create database and user (use setup-mysql.sh script)"
|
||||||
|
echo "3. Add your SSH public key to the deploy user:"
|
||||||
|
echo " ssh-copy-id deploy@your-server-ip"
|
||||||
|
echo "4. Upload your application files to /var/www/bikeservice"
|
||||||
|
echo "5. Configure your .env file with database credentials"
|
||||||
|
echo "6. Run the deployment script"
|
||||||
|
echo
|
||||||
|
echo "Useful commands:"
|
||||||
|
echo "- Check service status: systemctl status apache2 mysql bikeservice-queue"
|
||||||
|
echo "- View logs: journalctl -u bikeservice-queue -f"
|
||||||
|
echo "- Check Apache logs: tail -f /var/log/apache2/bikeservice_error.log"
|
||||||
|
echo "- Test Apache config: apache2ctl configtest"
|
||||||
|
echo "- Restart Apache: systemctl restart apache2"
|
||||||
|
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"
|
||||||
|
echo "- MySQL needs to be secured manually"
|
||||||
Executable
+284
@@ -0,0 +1,284 @@
|
|||||||
|
#!/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"
|
||||||
|
|
||||||
Executable
+136
@@ -0,0 +1,136 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# MySQL Setup Script for Bike Service Application
|
||||||
|
# This script will create the database and user for the application
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🗄️ Setting up MySQL database 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 MySQL is running
|
||||||
|
if ! systemctl is-active --quiet mysql; then
|
||||||
|
print_error "MySQL is not running. Please start MySQL first:"
|
||||||
|
echo "sudo systemctl start mysql"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get database credentials
|
||||||
|
echo "Enter MySQL root password:"
|
||||||
|
read -s MYSQL_ROOT_PASSWORD
|
||||||
|
|
||||||
|
# Get application database credentials
|
||||||
|
echo "Enter database name (default: bikeservice_db):"
|
||||||
|
read DB_NAME
|
||||||
|
DB_NAME=${DB_NAME:-bikeservice_db}
|
||||||
|
|
||||||
|
echo "Enter database username (default: bikeservice_user):"
|
||||||
|
read DB_USER
|
||||||
|
DB_USER=${DB_USER:-bikeservice_user}
|
||||||
|
|
||||||
|
echo "Enter database password:"
|
||||||
|
read -s DB_PASSWORD
|
||||||
|
|
||||||
|
# Validate password strength
|
||||||
|
if [ ${#DB_PASSWORD} -lt 8 ]; then
|
||||||
|
print_warning "Password is less than 8 characters. Consider using a stronger password."
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_status "Creating database and user..."
|
||||||
|
|
||||||
|
# Create SQL script
|
||||||
|
cat > /tmp/mysql_setup.sql << EOF
|
||||||
|
-- Create database
|
||||||
|
CREATE DATABASE IF NOT EXISTS ${DB_NAME}
|
||||||
|
CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- Create user
|
||||||
|
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost'
|
||||||
|
IDENTIFIED BY '${DB_PASSWORD}';
|
||||||
|
|
||||||
|
-- Grant privileges
|
||||||
|
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
|
||||||
|
|
||||||
|
-- Grant additional privileges for Laravel
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
|
||||||
|
|
||||||
|
-- Flush privileges
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
|
||||||
|
-- Show created database and user
|
||||||
|
SHOW DATABASES;
|
||||||
|
SELECT User, Host FROM mysql.user WHERE User = '${DB_USER}';
|
||||||
|
|
||||||
|
-- Display success message
|
||||||
|
SELECT 'Database and user created successfully!' as Status;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Execute SQL script
|
||||||
|
if mysql -u root -p"$MYSQL_ROOT_PASSWORD" < /tmp/mysql_setup.sql; then
|
||||||
|
print_status "Database and user created successfully!"
|
||||||
|
|
||||||
|
# Create .env database configuration
|
||||||
|
cat > /tmp/database_config.env << EOF
|
||||||
|
# Database Configuration
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=127.0.0.1
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=${DB_NAME}
|
||||||
|
DB_USERNAME=${DB_USER}
|
||||||
|
DB_PASSWORD=${DB_PASSWORD}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
print_status "Database configuration saved to /tmp/database_config.env"
|
||||||
|
print_warning "Copy these settings to your Laravel .env file:"
|
||||||
|
echo
|
||||||
|
cat /tmp/database_config.env
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Test database connection
|
||||||
|
print_status "Testing database connection..."
|
||||||
|
if mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "USE ${DB_NAME}; SELECT 1;" > /dev/null 2>&1; then
|
||||||
|
print_status "Database connection test successful!"
|
||||||
|
else
|
||||||
|
print_error "Database connection test failed!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
print_error "Failed to create database and user!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
rm -f /tmp/mysql_setup.sql
|
||||||
|
|
||||||
|
print_status "MySQL setup completed!"
|
||||||
|
echo
|
||||||
|
echo "Next steps:"
|
||||||
|
echo "1. Copy the database configuration to your Laravel .env file"
|
||||||
|
echo "2. Run Laravel migrations: php artisan migrate"
|
||||||
|
echo "3. Test your application"
|
||||||
|
echo
|
||||||
|
echo "Database credentials:"
|
||||||
|
echo "- Database: ${DB_NAME}"
|
||||||
|
echo "- Username: ${DB_USER}"
|
||||||
|
echo "- Password: [hidden]"
|
||||||
|
echo "- Host: 127.0.0.1"
|
||||||
|
echo "- Port: 3306"
|
||||||
Reference in New Issue
Block a user