add update nginx config to domain and create production setup docker
This commit is contained in:
@@ -23,9 +23,9 @@ Dokumentasi ini menjelaskan cara menjalankan aplikasi CKB menggunakan Docker unt
|
|||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Docker Engine 20.10+
|
- Docker Engine 20.10+
|
||||||
- Docker Compose 2.0+
|
- Docker Compose 2.0+
|
||||||
- Git
|
- Git
|
||||||
|
|
||||||
## Setup untuk Local Development
|
## Setup untuk Local Development
|
||||||
|
|
||||||
@@ -46,19 +46,20 @@ ls ckb.sql
|
|||||||
```
|
```
|
||||||
|
|
||||||
Script ini akan otomatis:
|
Script ini akan otomatis:
|
||||||
- Setup environment file
|
|
||||||
- Start semua containers
|
- Setup environment file
|
||||||
- Import database dari ckb.sql
|
- Start semua containers
|
||||||
- Generate application key
|
- Import database dari ckb.sql
|
||||||
- Setup Laravel application
|
- Generate application key
|
||||||
|
- Setup Laravel application
|
||||||
|
|
||||||
### 2. Manual Setup
|
### 2. Manual Setup
|
||||||
|
|
||||||
Jika Anda ingin setup manual:
|
Jika Anda ingin setup manual:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Copy environment file
|
# Setup local environment
|
||||||
cp docker/env.example .env
|
./docker-setup-env.sh local
|
||||||
|
|
||||||
# Start containers
|
# Start containers
|
||||||
docker-compose up -d --build
|
docker-compose up -d --build
|
||||||
@@ -82,11 +83,11 @@ docker-compose up -d
|
|||||||
|
|
||||||
### 3. Akses Aplikasi
|
### 3. Akses Aplikasi
|
||||||
|
|
||||||
- **Web Application**: http://localhost:8000
|
- **Web Application**: http://localhost:8000
|
||||||
- **Database (phpMyAdmin)**: http://localhost:8080
|
- **Database (phpMyAdmin)**: http://localhost:8080
|
||||||
- **Mail Testing (MailHog)**: http://localhost:8025
|
- **Mail Testing (MailHog)**: http://localhost:8025
|
||||||
- **MySQL Direct**: localhost:3306
|
- **MySQL Direct**: localhost:3306
|
||||||
- **Redis**: localhost:6379
|
- **Redis**: localhost:6379
|
||||||
|
|
||||||
### 4. Menjalankan Laravel Commands
|
### 4. Menjalankan Laravel Commands
|
||||||
|
|
||||||
@@ -183,9 +184,10 @@ docker-compose -f docker-compose.prod.yml logs -f
|
|||||||
### 2. Debugging dengan Xdebug (Development)
|
### 2. Debugging dengan Xdebug (Development)
|
||||||
|
|
||||||
Xdebug sudah dikonfigurasi untuk development environment:
|
Xdebug sudah dikonfigurasi untuk development environment:
|
||||||
- Port: 9003
|
|
||||||
- IDE Key: PHPSTORM
|
- Port: 9003
|
||||||
- Host: host.docker.internal
|
- IDE Key: PHPSTORM
|
||||||
|
- Host: host.docker.internal
|
||||||
|
|
||||||
### 3. Monitoring Resources
|
### 3. Monitoring Resources
|
||||||
|
|
||||||
@@ -215,11 +217,12 @@ Untuk mengimport database dari file backup ckb.sql:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Script import akan otomatis:
|
Script import akan otomatis:
|
||||||
- Backup database yang sudah ada (safety)
|
|
||||||
- Drop dan recreate database
|
- Backup database yang sudah ada (safety)
|
||||||
- Import data dari file SQL
|
- Drop dan recreate database
|
||||||
- Jalankan migrations jika diperlukan
|
- Import data dari file SQL
|
||||||
- Clear cache Laravel
|
- Jalankan migrations jika diperlukan
|
||||||
|
- Clear cache Laravel
|
||||||
|
|
||||||
### 2. Backup Database
|
### 2. Backup Database
|
||||||
|
|
||||||
@@ -262,9 +265,10 @@ docker-compose build --no-cache --pull
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Common Build Errors:**
|
**Common Build Errors:**
|
||||||
- **curl extension error**: Fixed dengan menambah `libcurl4-openssl-dev` dan `pkg-config`
|
|
||||||
- **gd extension error**: Pastikan `libfreetype6-dev` dan `libjpeg62-turbo-dev` terinstall
|
- **curl extension error**: Fixed dengan menambah `libcurl4-openssl-dev` dan `pkg-config`
|
||||||
- **Out of space**: Jalankan `docker system prune -a -f` untuk cleanup
|
- **gd extension error**: Pastikan `libfreetype6-dev` dan `libjpeg62-turbo-dev` terinstall
|
||||||
|
- **Out of space**: Jalankan `docker system prune -a -f` untuk cleanup
|
||||||
|
|
||||||
### 2. Permission Issues
|
### 2. Permission Issues
|
||||||
|
|
||||||
@@ -345,9 +349,10 @@ docker-compose exec app php artisan cache:clear
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Common Redis Errors:**
|
**Common Redis Errors:**
|
||||||
- **Class Redis not found**: Fixed dengan install `pecl install redis`
|
|
||||||
- **Connection refused**: Pastikan Redis container berjalan
|
- **Class Redis not found**: Fixed dengan install `pecl install redis`
|
||||||
- **Config not loaded**: Jalankan `php artisan config:clear`
|
- **Connection refused**: Pastikan Redis container berjalan
|
||||||
|
- **Config not loaded**: Jalankan `php artisan config:clear`
|
||||||
|
|
||||||
## Security Notes untuk Production
|
## Security Notes untuk Production
|
||||||
|
|
||||||
@@ -371,9 +376,9 @@ docker-compose exec app composer install --optimize-autoloader --no-dev
|
|||||||
|
|
||||||
### 2. Docker Optimizations
|
### 2. Docker Optimizations
|
||||||
|
|
||||||
- Gunakan multi-stage builds untuk image yang lebih kecil
|
- Gunakan multi-stage builds untuk image yang lebih kecil
|
||||||
- Leverage Docker layer caching
|
- Leverage Docker layer caching
|
||||||
- Optimize .dockerignore untuk build speed
|
- Optimize .dockerignore untuk build speed
|
||||||
|
|
||||||
## Backup Strategy
|
## Backup Strategy
|
||||||
|
|
||||||
|
|||||||
276
ENVIRONMENT-SETUP.md
Normal file
276
ENVIRONMENT-SETUP.md
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
# Environment Setup Guide
|
||||||
|
|
||||||
|
Panduan lengkap untuk setup environment file CKB Laravel Application dengan file template terpisah untuk local dan production.
|
||||||
|
|
||||||
|
## 📂 File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
docker/
|
||||||
|
├── env.example.local # Template untuk local development
|
||||||
|
├── env.example.production # Template untuk production
|
||||||
|
└── (env.example) # File lama, dapat dihapus
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Quick Setup
|
||||||
|
|
||||||
|
### Local Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Setup environment untuk local development
|
||||||
|
./docker-setup-env.sh local
|
||||||
|
|
||||||
|
# Atau manual copy
|
||||||
|
cp docker/env.example.local .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### Production Deployment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Setup environment untuk production
|
||||||
|
./docker-setup-env.sh production
|
||||||
|
|
||||||
|
# IMPORTANT: Edit .env dan ganti semua CHANGE_THIS_* values!
|
||||||
|
nano .env
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 Template Comparison
|
||||||
|
|
||||||
|
### 🏠 Local Development (`env.example.local`)
|
||||||
|
|
||||||
|
| Setting | Value | Description |
|
||||||
|
| ------------------- | ----------------------- | ----------------------- |
|
||||||
|
| `APP_ENV` | `local` | Development environment |
|
||||||
|
| `APP_DEBUG` | `true` | Debug mode enabled |
|
||||||
|
| `APP_URL` | `http://localhost:8000` | Local URL |
|
||||||
|
| `LOG_LEVEL` | `debug` | Verbose logging |
|
||||||
|
| `DB_DATABASE` | `ckb_db` | Development database |
|
||||||
|
| `DB_USERNAME` | `root` | Simple credentials |
|
||||||
|
| `DB_PASSWORD` | `root` | Simple credentials |
|
||||||
|
| `REDIS_PASSWORD` | `null` | No password needed |
|
||||||
|
| `MAIL_HOST` | `mailhog` | Local mail testing |
|
||||||
|
| `QUEUE_CONNECTION` | `sync` | Synchronous queue |
|
||||||
|
| `TELESCOPE_ENABLED` | `true` | Debugging tool enabled |
|
||||||
|
|
||||||
|
### 🚀 Production (`env.example.production`)
|
||||||
|
|
||||||
|
| Setting | Value | Description |
|
||||||
|
| ------------------- | ---------------------------------- | ----------------------- |
|
||||||
|
| `APP_ENV` | `production` | Production environment |
|
||||||
|
| `APP_DEBUG` | `false` | Debug mode disabled |
|
||||||
|
| `APP_URL` | `https://bengkel.digitaloasis.xyz` | Production domain |
|
||||||
|
| `LOG_LEVEL` | `error` | Error-only logging |
|
||||||
|
| `DB_DATABASE` | `ckb_production` | Production database |
|
||||||
|
| `DB_USERNAME` | `ckb_user` | Secure username |
|
||||||
|
| `DB_PASSWORD` | `CHANGE_THIS_*` | **Must be changed!** |
|
||||||
|
| `REDIS_PASSWORD` | `CHANGE_THIS_*` | **Must be changed!** |
|
||||||
|
| `MAIL_HOST` | `smtp.gmail.com` | Real SMTP server |
|
||||||
|
| `QUEUE_CONNECTION` | `redis` | Redis-based queue |
|
||||||
|
| `TELESCOPE_ENABLED` | `false` | Debugging tool disabled |
|
||||||
|
|
||||||
|
## 🔐 Security Configuration for Production
|
||||||
|
|
||||||
|
### Required Changes
|
||||||
|
|
||||||
|
**MUST CHANGE** these values in production `.env`:
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Strong database passwords
|
||||||
|
DB_PASSWORD=your_super_secure_password_here
|
||||||
|
DB_ROOT_PASSWORD=your_root_password_here
|
||||||
|
|
||||||
|
# Redis security
|
||||||
|
REDIS_PASSWORD=your_redis_password_here
|
||||||
|
|
||||||
|
# Mail configuration
|
||||||
|
MAIL_USERNAME=your-email@domain.com
|
||||||
|
MAIL_PASSWORD=your-app-specific-password
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional but Recommended
|
||||||
|
|
||||||
|
```env
|
||||||
|
# AWS S3 for file storage
|
||||||
|
AWS_ACCESS_KEY_ID=your-aws-key
|
||||||
|
AWS_SECRET_ACCESS_KEY=your-aws-secret
|
||||||
|
|
||||||
|
# Real-time features
|
||||||
|
PUSHER_APP_ID=your-pusher-app-id
|
||||||
|
PUSHER_APP_KEY=your-pusher-key
|
||||||
|
PUSHER_APP_SECRET=your-pusher-secret
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ Environment Helper Script
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Setup local environment
|
||||||
|
./docker-setup-env.sh local
|
||||||
|
|
||||||
|
# Setup production environment
|
||||||
|
./docker-setup-env.sh production
|
||||||
|
|
||||||
|
# Show current environment info
|
||||||
|
./docker-setup-env.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- ✅ **Auto-backup** existing `.env` before changes
|
||||||
|
- ✅ **Environment validation** checks required variables
|
||||||
|
- ✅ **Security warnings** for production misconfiguration
|
||||||
|
- ✅ **Configuration summary** shows current settings
|
||||||
|
- ✅ **Next steps guidance** for deployment
|
||||||
|
|
||||||
|
## 📊 Environment Comparison
|
||||||
|
|
||||||
|
### Local Development Features
|
||||||
|
|
||||||
|
- 🐛 **Debug Mode**: Full error reporting and debugging tools
|
||||||
|
- 📧 **MailHog**: Local email testing server
|
||||||
|
- 🗄️ **Simple DB**: Basic MySQL credentials
|
||||||
|
- 🔓 **No SSL**: HTTP-only for speed
|
||||||
|
- 🧪 **Development Tools**: Telescope, Debugbar enabled
|
||||||
|
- ⚡ **Sync Queue**: Immediate processing for testing
|
||||||
|
|
||||||
|
### Production Features
|
||||||
|
|
||||||
|
- 🔒 **Security First**: Strong passwords and encryption
|
||||||
|
- 📧 **Real SMTP**: Professional email delivery
|
||||||
|
- 🗄️ **Secure DB**: Production-grade credentials
|
||||||
|
- 🔐 **SSL/HTTPS**: Let's Encrypt certificates
|
||||||
|
- 📊 **Monitoring**: Error-only logging
|
||||||
|
- 🚀 **Redis Queue**: Background job processing
|
||||||
|
|
||||||
|
## 🚨 Common Issues & Solutions
|
||||||
|
|
||||||
|
### 1. "CHANGE*THIS*\*" Values in Production
|
||||||
|
|
||||||
|
**Problem**: Forgot to change template values
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check for remaining template values
|
||||||
|
grep "CHANGE_THIS" .env
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Use the helper script to check
|
||||||
|
./docker-setup-env.sh
|
||||||
|
# It will warn about CHANGE_THIS_* values
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Wrong Environment File
|
||||||
|
|
||||||
|
**Problem**: Using local config in production
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check current environment
|
||||||
|
grep "APP_ENV=" .env
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Recreate with correct template
|
||||||
|
./docker-setup-env.sh production
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Missing Environment Variables
|
||||||
|
|
||||||
|
**Problem**: Laravel errors about missing config
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Validate current .env
|
||||||
|
./docker-setup-env.sh validate
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solution**: Check required variables list and add missing ones
|
||||||
|
|
||||||
|
## 📝 Environment Variables Reference
|
||||||
|
|
||||||
|
### Core Application
|
||||||
|
|
||||||
|
```env
|
||||||
|
APP_NAME="CKB Bengkel System"
|
||||||
|
APP_ENV=production|local
|
||||||
|
APP_KEY=base64:...
|
||||||
|
APP_DEBUG=true|false
|
||||||
|
APP_URL=https://domain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
```env
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=db
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=ckb_production|ckb_db
|
||||||
|
DB_USERNAME=username
|
||||||
|
DB_PASSWORD=password
|
||||||
|
DB_ROOT_PASSWORD=root_password
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cache & Session
|
||||||
|
|
||||||
|
```env
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PASSWORD=password|null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
CACHE_DRIVER=redis
|
||||||
|
SESSION_DRIVER=redis
|
||||||
|
QUEUE_CONNECTION=redis|sync
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mail Configuration
|
||||||
|
|
||||||
|
```env
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=smtp.domain.com
|
||||||
|
MAIL_PORT=587
|
||||||
|
MAIL_USERNAME=email@domain.com
|
||||||
|
MAIL_PASSWORD=password
|
||||||
|
MAIL_ENCRYPTION=tls
|
||||||
|
MAIL_FROM_ADDRESS=noreply@domain.com
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
```env
|
||||||
|
TRUSTED_PROXIES=*
|
||||||
|
SESSION_SECURE_COOKIE=true
|
||||||
|
SESSION_SAME_SITE=strict
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Migration Guide
|
||||||
|
|
||||||
|
### From Old Single Template
|
||||||
|
|
||||||
|
If you're migrating from the old `docker/env.example`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backup current .env
|
||||||
|
cp .env .env.backup
|
||||||
|
|
||||||
|
# Choose appropriate template
|
||||||
|
./docker-setup-env.sh local # for development
|
||||||
|
./docker-setup-env.sh production # for production
|
||||||
|
|
||||||
|
# Compare and migrate custom settings
|
||||||
|
diff .env.backup .env
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📞 Support
|
||||||
|
|
||||||
|
For environment setup issues:
|
||||||
|
|
||||||
|
- **Documentation**: This file
|
||||||
|
- **Helper Script**: `./docker-setup-env.sh`
|
||||||
|
- **Validation**: Built-in security checks
|
||||||
|
- **Backup**: Automatic .env backup before changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**💡 Pro Tip**: Always use the helper script `./docker-setup-env.sh` instead of manual copying to ensure proper configuration and security checks!
|
||||||
360
PRODUCTION-DEPLOYMENT.md
Normal file
360
PRODUCTION-DEPLOYMENT.md
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
# CKB Production Deployment Guide
|
||||||
|
|
||||||
|
Panduan deployment aplikasi CKB Laravel ke production server dengan domain `bengkel.digitaloasis.xyz`.
|
||||||
|
|
||||||
|
## 🚀 Quick Start
|
||||||
|
|
||||||
|
### 1. Deploy ke Production
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Full deployment (recommended untuk pertama kali)
|
||||||
|
./docker-deploy-prod.sh deploy
|
||||||
|
|
||||||
|
# Hanya build containers
|
||||||
|
./docker-deploy-prod.sh build
|
||||||
|
|
||||||
|
# Setup SSL certificate
|
||||||
|
./docker-deploy-prod.sh ssl
|
||||||
|
|
||||||
|
# Check deployment status
|
||||||
|
./docker-deploy-prod.sh status
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Akses Aplikasi
|
||||||
|
|
||||||
|
- **Domain**: https://bengkel.digitaloasis.xyz
|
||||||
|
- **Health Check**: https://bengkel.digitaloasis.xyz/health
|
||||||
|
|
||||||
|
## 📋 Prerequisites
|
||||||
|
|
||||||
|
### Server Requirements
|
||||||
|
|
||||||
|
- **OS**: Ubuntu 20.04+ atau CentOS 7+
|
||||||
|
- **Memory**: Minimum 2GB RAM (4GB recommended)
|
||||||
|
- **Storage**: Minimum 20GB SSD
|
||||||
|
- **Docker**: Version 20.10+
|
||||||
|
- **Docker Compose**: Version 2.0+
|
||||||
|
|
||||||
|
### Domain Setup
|
||||||
|
|
||||||
|
1. **DNS Configuration**:
|
||||||
|
|
||||||
|
```
|
||||||
|
A Record: bengkel.digitaloasis.xyz → [Server IP]
|
||||||
|
CNAME: www.bengkel.digitaloasis.xyz → bengkel.digitaloasis.xyz
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Firewall Configuration**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Allow HTTP/HTTPS traffic
|
||||||
|
sudo ufw allow 80/tcp
|
||||||
|
sudo ufw allow 443/tcp
|
||||||
|
|
||||||
|
# Allow SSH (if needed)
|
||||||
|
sudo ufw allow 22/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛡️ Security Configuration
|
||||||
|
|
||||||
|
### 1. Environment Variables
|
||||||
|
|
||||||
|
Edit `.env` file untuk production:
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Application
|
||||||
|
APP_ENV=production
|
||||||
|
APP_DEBUG=false
|
||||||
|
APP_URL=https://bengkel.digitaloasis.xyz
|
||||||
|
APP_KEY=base64:...
|
||||||
|
|
||||||
|
# Database (GANTI dengan credentials yang aman!)
|
||||||
|
DB_HOST=db
|
||||||
|
DB_DATABASE=ckb_production
|
||||||
|
DB_USERNAME=ckb_user
|
||||||
|
DB_PASSWORD=secure_password_here
|
||||||
|
DB_ROOT_PASSWORD=secure_root_password_here
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PASSWORD=secure_redis_password
|
||||||
|
|
||||||
|
# Mail
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=your-smtp-host
|
||||||
|
MAIL_PORT=587
|
||||||
|
MAIL_USERNAME=your-email@domain.com
|
||||||
|
MAIL_PASSWORD=your-email-password
|
||||||
|
MAIL_ENCRYPTION=tls
|
||||||
|
|
||||||
|
# Session & Cache
|
||||||
|
SESSION_DRIVER=redis
|
||||||
|
CACHE_DRIVER=redis
|
||||||
|
QUEUE_CONNECTION=redis
|
||||||
|
|
||||||
|
# Trusted Proxies
|
||||||
|
TRUSTED_PROXIES=*
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Database Security
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Setelah deployment, jalankan MySQL secure installation
|
||||||
|
docker-compose -f docker-compose.prod.yml exec db mysql_secure_installation
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Deployment Process
|
||||||
|
|
||||||
|
### Manual Step-by-Step
|
||||||
|
|
||||||
|
1. **Persiapan Server**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Update system
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
|
||||||
|
# Install Docker
|
||||||
|
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||||
|
sudo sh get-docker.sh
|
||||||
|
|
||||||
|
# Install Docker Compose
|
||||||
|
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Clone Repository**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/your-repo/ckb.git
|
||||||
|
cd ckb
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Setup Environment**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# For production environment
|
||||||
|
./docker-setup-env.sh production
|
||||||
|
|
||||||
|
# Edit production settings (IMPORTANT!)
|
||||||
|
nano .env
|
||||||
|
# Change all CHANGE_THIS_* values with secure passwords
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Deploy Application**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./docker-deploy-prod.sh deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Setup SSL Certificate**:
|
||||||
|
```bash
|
||||||
|
./docker-deploy-prod.sh ssl
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Monitoring & Maintenance
|
||||||
|
|
||||||
|
### 1. Health Checks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check application status
|
||||||
|
./docker-deploy-prod.sh status
|
||||||
|
|
||||||
|
# Check specific service logs
|
||||||
|
docker-compose -f docker-compose.prod.yml logs -f app
|
||||||
|
docker-compose -f docker-compose.prod.yml logs -f nginx-proxy
|
||||||
|
docker-compose -f docker-compose.prod.yml logs -f db
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Database Backup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Manual backup
|
||||||
|
docker-compose -f docker-compose.prod.yml exec -T db mysqldump -u root -p"$DB_ROOT_PASSWORD" ckb_production > backup_$(date +%Y%m%d).sql
|
||||||
|
|
||||||
|
# Automated backup (add to crontab)
|
||||||
|
0 2 * * * /path/to/ckb/docker-backup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. SSL Certificate Renewal
|
||||||
|
|
||||||
|
Certificate akan otomatis renewal. Untuk manual renewal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test renewal
|
||||||
|
docker-compose -f docker-compose.prod.yml run --rm certbot renew --dry-run
|
||||||
|
|
||||||
|
# Manual renewal
|
||||||
|
./docker-ssl-renew.sh
|
||||||
|
|
||||||
|
# Setup auto-renewal (add to crontab)
|
||||||
|
0 12 * * * /path/to/ckb/docker-ssl-renew.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Application Not Loading**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check container status
|
||||||
|
docker-compose -f docker-compose.prod.yml ps
|
||||||
|
|
||||||
|
# Check application logs
|
||||||
|
docker-compose -f docker-compose.prod.yml logs app
|
||||||
|
|
||||||
|
# Restart application
|
||||||
|
docker-compose -f docker-compose.prod.yml restart app
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **SSL Certificate Issues**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check certificate status
|
||||||
|
openssl s_client -connect bengkel.digitaloasis.xyz:443 -servername bengkel.digitaloasis.xyz
|
||||||
|
|
||||||
|
# Re-setup SSL
|
||||||
|
./docker-ssl-setup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Database Connection Issues**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check database logs
|
||||||
|
docker-compose -f docker-compose.prod.yml logs db
|
||||||
|
|
||||||
|
# Test database connection
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan tinker
|
||||||
|
>>> DB::connection()->getPdo();
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Permission Issues**:
|
||||||
|
```bash
|
||||||
|
# Fix Laravel permissions
|
||||||
|
./docker-fix-permissions.sh prod
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check resource usage
|
||||||
|
docker stats
|
||||||
|
|
||||||
|
# Clean up Docker system
|
||||||
|
docker system prune -a -f
|
||||||
|
|
||||||
|
# Optimize Laravel
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan optimize
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚦 Load Testing
|
||||||
|
|
||||||
|
Before going live, test your application:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install testing tools
|
||||||
|
sudo apt install apache2-utils
|
||||||
|
|
||||||
|
# Basic load test
|
||||||
|
ab -n 1000 -c 10 https://bengkel.digitaloasis.xyz/
|
||||||
|
|
||||||
|
# More comprehensive testing with siege
|
||||||
|
sudo apt install siege
|
||||||
|
siege -c 25 -t 60s https://bengkel.digitaloasis.xyz/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📈 Performance Optimization
|
||||||
|
|
||||||
|
### 1. Laravel Optimizations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run after each deployment
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan config:cache
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan route:cache
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan view:cache
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app composer install --optimize-autoloader --no-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Database Optimization
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# MySQL tuning
|
||||||
|
docker-compose -f docker-compose.prod.yml exec db mysql -u root -p -e "
|
||||||
|
SET GLOBAL innodb_buffer_pool_size = 1073741824;
|
||||||
|
SET GLOBAL query_cache_size = 67108864;
|
||||||
|
SET GLOBAL query_cache_type = 1;
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Nginx Optimization
|
||||||
|
|
||||||
|
Edit `docker/nginx-proxy.conf` untuk mengoptimalkan:
|
||||||
|
|
||||||
|
- Gzip compression
|
||||||
|
- Browser caching
|
||||||
|
- Connection pooling
|
||||||
|
|
||||||
|
## 🔄 Updates & Maintenance
|
||||||
|
|
||||||
|
### Application Updates
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pull latest code
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Backup before update
|
||||||
|
./docker-deploy-prod.sh backup
|
||||||
|
|
||||||
|
# Deploy updates
|
||||||
|
./docker-deploy-prod.sh deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
### Security Updates
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Update base images
|
||||||
|
docker-compose -f docker-compose.prod.yml pull
|
||||||
|
|
||||||
|
# Rebuild with latest security patches
|
||||||
|
./docker-deploy-prod.sh build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📞 Support & Contact
|
||||||
|
|
||||||
|
Untuk bantuan deployment atau issues:
|
||||||
|
|
||||||
|
- **Email**: admin@digitaloasis.xyz
|
||||||
|
- **Documentation**: https://github.com/your-repo/ckb/docs
|
||||||
|
- **Issues**: https://github.com/your-repo/ckb/issues
|
||||||
|
|
||||||
|
## 📄 File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
ckb/
|
||||||
|
├── docker/
|
||||||
|
│ ├── nginx-proxy.conf # Main nginx configuration
|
||||||
|
│ ├── nginx-temp.conf # Temporary config for SSL setup
|
||||||
|
│ ├── env.example # Environment template
|
||||||
|
│ └── ...
|
||||||
|
├── docker-compose.prod.yml # Production compose file
|
||||||
|
├── docker-deploy-prod.sh # Main deployment script
|
||||||
|
├── docker-ssl-setup.sh # SSL certificate setup
|
||||||
|
├── docker-ssl-renew.sh # SSL renewal script
|
||||||
|
└── PRODUCTION-DEPLOYMENT.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✅ Production Checklist
|
||||||
|
|
||||||
|
- [ ] Domain DNS configured
|
||||||
|
- [ ] Firewall rules configured
|
||||||
|
- [ ] .env file configured with production values
|
||||||
|
- [ ] Database credentials changed from defaults
|
||||||
|
- [ ] SSL certificate obtained and configured
|
||||||
|
- [ ] Backup system configured
|
||||||
|
- [ ] Monitoring setup
|
||||||
|
- [ ] Load testing completed
|
||||||
|
- [ ] Security audit completed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**🚨 Remember**: Always test in staging environment before deploying to production!
|
||||||
@@ -10,11 +10,11 @@ services:
|
|||||||
- ./storage:/var/www/html/storage
|
- ./storage:/var/www/html/storage
|
||||||
- ./bootstrap/cache:/var/www/html/bootstrap/cache
|
- ./bootstrap/cache:/var/www/html/bootstrap/cache
|
||||||
- ./docker/php.ini:/usr/local/etc/php/conf.d/local.ini
|
- ./docker/php.ini:/usr/local/etc/php/conf.d/local.ini
|
||||||
ports:
|
|
||||||
- "80:80"
|
|
||||||
environment:
|
environment:
|
||||||
- APP_ENV=production
|
- APP_ENV=production
|
||||||
- APP_DEBUG=false
|
- APP_DEBUG=false
|
||||||
|
- APP_URL=https://bengkel.digitaloasis.xyz
|
||||||
|
- TRUSTED_PROXIES=*
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
- redis
|
- redis
|
||||||
@@ -34,8 +34,8 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- mysql_data:/var/lib/mysql
|
- mysql_data:/var/lib/mysql
|
||||||
- ./docker/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
|
- ./docker/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
|
||||||
ports:
|
expose:
|
||||||
- "3306:3306"
|
- "3306"
|
||||||
networks:
|
networks:
|
||||||
- ckb-network
|
- ckb-network
|
||||||
command: --default-authentication-plugin=mysql_native_password
|
command: --default-authentication-plugin=mysql_native_password
|
||||||
@@ -47,8 +47,8 @@ services:
|
|||||||
command: redis-server --appendonly yes ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}
|
command: redis-server --appendonly yes ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}
|
||||||
volumes:
|
volumes:
|
||||||
- redis_data:/data
|
- redis_data:/data
|
||||||
ports:
|
expose:
|
||||||
- "6379:6379"
|
- "6379"
|
||||||
networks:
|
networks:
|
||||||
- ckb-network
|
- ckb-network
|
||||||
|
|
||||||
@@ -57,20 +57,44 @@ services:
|
|||||||
container_name: ckb-nginx-proxy
|
container_name: ckb-nginx-proxy
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
|
- "80:80"
|
||||||
- "443:443"
|
- "443:443"
|
||||||
volumes:
|
volumes:
|
||||||
- ./docker/nginx-proxy.conf:/etc/nginx/nginx.conf
|
- ./docker/nginx-proxy.conf:/etc/nginx/nginx.conf:ro
|
||||||
- ./docker/ssl:/etc/nginx/ssl
|
- ssl_certificates:/etc/nginx/ssl:ro
|
||||||
|
- certbot_www:/var/www/certbot:ro
|
||||||
|
- nginx_logs:/var/log/nginx
|
||||||
depends_on:
|
depends_on:
|
||||||
- app
|
- app
|
||||||
networks:
|
networks:
|
||||||
- ckb-network
|
- ckb-network
|
||||||
|
environment:
|
||||||
|
- DOMAIN=bengkel.digitaloasis.xyz
|
||||||
|
|
||||||
|
certbot:
|
||||||
|
image: certbot/certbot
|
||||||
|
container_name: ckb-certbot
|
||||||
|
restart: "no"
|
||||||
|
volumes:
|
||||||
|
- ssl_certificates:/etc/letsencrypt
|
||||||
|
- certbot_www:/var/www/certbot
|
||||||
|
command: certonly --webroot --webroot-path=/var/www/certbot --email admin@digitaloasis.xyz --agree-tos --no-eff-email -d bengkel.digitaloasis.xyz -d www.bengkel.digitaloasis.xyz
|
||||||
|
depends_on:
|
||||||
|
- nginx-proxy
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
mysql_data:
|
mysql_data:
|
||||||
driver: local
|
driver: local
|
||||||
redis_data:
|
redis_data:
|
||||||
driver: local
|
driver: local
|
||||||
|
ssl_certificates:
|
||||||
|
driver: local
|
||||||
|
certbot_www:
|
||||||
|
driver: local
|
||||||
|
nginx_logs:
|
||||||
|
driver: local
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
ckb-network:
|
ckb-network:
|
||||||
|
|||||||
332
docker-deploy-prod.sh
Executable file
332
docker-deploy-prod.sh
Executable file
@@ -0,0 +1,332 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script untuk deploy CKB Laravel Application ke production dengan domain bengkel.digitaloasis.xyz
|
||||||
|
# Usage: ./docker-deploy-prod.sh [build|deploy|ssl|status]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
DOMAIN="bengkel.digitaloasis.xyz"
|
||||||
|
EMAIL="admin@digitaloasis.xyz"
|
||||||
|
COMPOSE_FILE="docker-compose.prod.yml"
|
||||||
|
ENV_FILE=".env"
|
||||||
|
|
||||||
|
# Default action
|
||||||
|
ACTION="deploy"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
build)
|
||||||
|
ACTION="build"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
deploy)
|
||||||
|
ACTION="deploy"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
ssl)
|
||||||
|
ACTION="ssl"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
ACTION="status"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option $1"
|
||||||
|
echo "Usage: $0 [build|deploy|ssl|status]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Function to print colored output
|
||||||
|
print_status() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check prerequisites
|
||||||
|
check_prerequisites() {
|
||||||
|
print_status "Checking prerequisites..."
|
||||||
|
|
||||||
|
# Check Docker
|
||||||
|
if ! docker info > /dev/null 2>&1; then
|
||||||
|
print_error "Docker is not running. Please start Docker first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check Docker Compose
|
||||||
|
if ! docker-compose --version > /dev/null 2>&1; then
|
||||||
|
print_error "Docker Compose is not installed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if .env file exists
|
||||||
|
if [[ ! -f $ENV_FILE ]]; then
|
||||||
|
print_warning "Environment file not found. Creating from production template..."
|
||||||
|
if [[ -f docker/env.example.production ]]; then
|
||||||
|
cp docker/env.example.production $ENV_FILE
|
||||||
|
print_warning "⚠️ IMPORTANT: Edit $ENV_FILE and change all CHANGE_THIS_* passwords before continuing!"
|
||||||
|
print_status "Production template copied. Please configure:"
|
||||||
|
echo " - DB_PASSWORD and DB_ROOT_PASSWORD"
|
||||||
|
echo " - REDIS_PASSWORD"
|
||||||
|
echo " - MAIL_* settings"
|
||||||
|
echo " - AWS_* settings (if using S3)"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
print_error "Production environment template not found: docker/env.example.production"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_success "Prerequisites check passed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to setup production environment
|
||||||
|
setup_production_env() {
|
||||||
|
print_status "Setting up production environment variables..."
|
||||||
|
|
||||||
|
# Update .env for production
|
||||||
|
sed -i "s|APP_ENV=.*|APP_ENV=production|g" $ENV_FILE
|
||||||
|
sed -i "s|APP_DEBUG=.*|APP_DEBUG=false|g" $ENV_FILE
|
||||||
|
sed -i "s|APP_URL=.*|APP_URL=https://$DOMAIN|g" $ENV_FILE
|
||||||
|
|
||||||
|
# Check if database credentials are set
|
||||||
|
if grep -q "DB_PASSWORD=password" $ENV_FILE; then
|
||||||
|
print_warning "Please update database credentials in $ENV_FILE for production!"
|
||||||
|
print_warning "Current settings are for development only."
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_success "Production environment configured!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to build containers
|
||||||
|
build_containers() {
|
||||||
|
print_status "Building production containers..."
|
||||||
|
|
||||||
|
# Pull latest images
|
||||||
|
docker-compose -f $COMPOSE_FILE pull
|
||||||
|
|
||||||
|
# Build application container
|
||||||
|
docker-compose -f $COMPOSE_FILE build --no-cache app
|
||||||
|
|
||||||
|
print_success "Containers built successfully!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to deploy application
|
||||||
|
deploy_application() {
|
||||||
|
print_status "Deploying CKB Laravel Application to production..."
|
||||||
|
|
||||||
|
# Stop existing containers
|
||||||
|
print_status "Stopping existing containers..."
|
||||||
|
docker-compose -f $COMPOSE_FILE down || true
|
||||||
|
|
||||||
|
# Start database and redis first
|
||||||
|
print_status "Starting database and Redis..."
|
||||||
|
docker-compose -f $COMPOSE_FILE up -d db redis
|
||||||
|
|
||||||
|
# Wait for database to be ready
|
||||||
|
print_status "Waiting for database to be ready..."
|
||||||
|
sleep 20
|
||||||
|
|
||||||
|
# Start application
|
||||||
|
print_status "Starting application..."
|
||||||
|
docker-compose -f $COMPOSE_FILE up -d app
|
||||||
|
|
||||||
|
# Wait for application to be ready
|
||||||
|
sleep 15
|
||||||
|
|
||||||
|
# Run Laravel setup commands
|
||||||
|
print_status "Running Laravel setup commands..."
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app php artisan key:generate --force || true
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app php artisan migrate --force
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app php artisan config:cache
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app php artisan route:cache
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app php artisan view:cache
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app php artisan storage:link || true
|
||||||
|
|
||||||
|
# Start nginx proxy
|
||||||
|
print_status "Starting nginx proxy..."
|
||||||
|
docker-compose -f $COMPOSE_FILE up -d nginx-proxy
|
||||||
|
|
||||||
|
print_success "Application deployed successfully!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to setup SSL
|
||||||
|
setup_ssl() {
|
||||||
|
print_status "Setting up SSL certificate..."
|
||||||
|
|
||||||
|
if [[ -f docker-ssl-setup.sh ]]; then
|
||||||
|
chmod +x docker-ssl-setup.sh
|
||||||
|
./docker-ssl-setup.sh
|
||||||
|
else
|
||||||
|
print_error "SSL setup script not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show deployment status
|
||||||
|
show_status() {
|
||||||
|
print_status "CKB Production Deployment Status"
|
||||||
|
echo "================================================"
|
||||||
|
|
||||||
|
# Show container status
|
||||||
|
print_status "Container Status:"
|
||||||
|
docker-compose -f $COMPOSE_FILE ps
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Show application health
|
||||||
|
print_status "Application Health:"
|
||||||
|
if curl -s --max-time 10 http://localhost/health > /dev/null 2>&1; then
|
||||||
|
print_success "✅ Application is responding on HTTP"
|
||||||
|
else
|
||||||
|
print_warning "❌ Application not responding on HTTP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if curl -s --max-time 10 https://$DOMAIN/health > /dev/null 2>&1; then
|
||||||
|
print_success "✅ Application is responding on HTTPS"
|
||||||
|
else
|
||||||
|
print_warning "❌ Application not responding on HTTPS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show SSL certificate status
|
||||||
|
print_status "SSL Certificate Status:"
|
||||||
|
if openssl s_client -connect $DOMAIN:443 -servername $DOMAIN < /dev/null 2>/dev/null | openssl x509 -noout -dates 2>/dev/null; then
|
||||||
|
print_success "✅ SSL certificate is active"
|
||||||
|
else
|
||||||
|
print_warning "❌ SSL certificate not found or invalid"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show disk usage
|
||||||
|
print_status "Docker Disk Usage:"
|
||||||
|
docker system df
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Show logs summary
|
||||||
|
print_status "Recent Application Logs:"
|
||||||
|
docker-compose -f $COMPOSE_FILE logs --tail=10 app || true
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_status "Access URLs:"
|
||||||
|
echo " 🌐 Application: https://$DOMAIN"
|
||||||
|
echo " 🔍 Health Check: https://$DOMAIN/health"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_status "Useful Commands:"
|
||||||
|
echo " - View logs: docker-compose -f $COMPOSE_FILE logs -f [service]"
|
||||||
|
echo " - Enter container: docker-compose -f $COMPOSE_FILE exec app bash"
|
||||||
|
echo " - Update SSL: ./docker-ssl-setup.sh"
|
||||||
|
echo " - Restart app: docker-compose -f $COMPOSE_FILE restart app"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to backup before deployment
|
||||||
|
backup_before_deploy() {
|
||||||
|
print_status "Creating backup before deployment..."
|
||||||
|
|
||||||
|
BACKUP_DIR="backups/$(date +%Y%m%d_%H%M%S)"
|
||||||
|
mkdir -p $BACKUP_DIR
|
||||||
|
|
||||||
|
# Backup database
|
||||||
|
if docker-compose -f $COMPOSE_FILE ps db | grep -q "Up"; then
|
||||||
|
print_status "Backing up database..."
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T db mysqldump -u root -p"${DB_ROOT_PASSWORD:-rootpassword}" "${DB_DATABASE:-ckb_production}" > "$BACKUP_DIR/database.sql"
|
||||||
|
print_success "Database backed up to $BACKUP_DIR/database.sql"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Backup storage
|
||||||
|
if [[ -d storage ]]; then
|
||||||
|
print_status "Backing up storage directory..."
|
||||||
|
tar -czf "$BACKUP_DIR/storage.tar.gz" storage/
|
||||||
|
print_success "Storage backed up to $BACKUP_DIR/storage.tar.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Backup environment
|
||||||
|
if [[ -f $ENV_FILE ]]; then
|
||||||
|
cp $ENV_FILE "$BACKUP_DIR/env.backup"
|
||||||
|
print_success "Environment backed up to $BACKUP_DIR/env.backup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_success "Backup completed in $BACKUP_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to optimize for production
|
||||||
|
optimize_production() {
|
||||||
|
print_status "Optimizing application for production..."
|
||||||
|
|
||||||
|
# Laravel optimizations
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app composer install --optimize-autoloader --no-dev --no-interaction
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app php artisan config:cache
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app php artisan route:cache
|
||||||
|
docker-compose -f $COMPOSE_FILE exec -T app php artisan view:cache
|
||||||
|
|
||||||
|
# Clean up Docker
|
||||||
|
docker system prune -f
|
||||||
|
|
||||||
|
print_success "Production optimization completed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
echo "================================================"
|
||||||
|
print_status "🚀 CKB Production Deployment Script"
|
||||||
|
print_status "Domain: $DOMAIN"
|
||||||
|
print_status "Action: $ACTION"
|
||||||
|
echo "================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check prerequisites
|
||||||
|
check_prerequisites
|
||||||
|
|
||||||
|
case $ACTION in
|
||||||
|
build)
|
||||||
|
print_status "Building containers only..."
|
||||||
|
build_containers
|
||||||
|
print_success "✅ Build completed!"
|
||||||
|
;;
|
||||||
|
|
||||||
|
deploy)
|
||||||
|
print_status "Full deployment process..."
|
||||||
|
backup_before_deploy
|
||||||
|
setup_production_env
|
||||||
|
build_containers
|
||||||
|
deploy_application
|
||||||
|
optimize_production
|
||||||
|
print_success "✅ Deployment completed!"
|
||||||
|
echo ""
|
||||||
|
print_status "Next steps:"
|
||||||
|
echo "1. Setup SSL certificate: ./docker-deploy-prod.sh ssl"
|
||||||
|
echo "2. Check status: ./docker-deploy-prod.sh status"
|
||||||
|
;;
|
||||||
|
|
||||||
|
ssl)
|
||||||
|
print_status "Setting up SSL certificate..."
|
||||||
|
setup_ssl
|
||||||
|
print_success "✅ SSL setup completed!"
|
||||||
|
;;
|
||||||
|
|
||||||
|
status)
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_success "✅ Production deployment script completed!"
|
||||||
@@ -62,13 +62,25 @@ check_docker() {
|
|||||||
# Function to setup environment file
|
# Function to setup environment file
|
||||||
setup_env() {
|
setup_env() {
|
||||||
if [[ ! -f .env ]]; then
|
if [[ ! -f .env ]]; then
|
||||||
if [[ -f docker/env.example ]]; then
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
print_status "Setting up environment file..."
|
if [[ -f docker/env.example.local ]]; then
|
||||||
cp docker/env.example .env
|
print_status "Setting up local development environment file..."
|
||||||
print_success "Environment file created: .env"
|
cp docker/env.example.local .env
|
||||||
|
print_success "Local environment file created: .env"
|
||||||
|
else
|
||||||
|
print_error "Local environment template not found: docker/env.example.local"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
print_error "No environment template found."
|
if [[ -f docker/env.example.production ]]; then
|
||||||
exit 1
|
print_status "Setting up production environment file..."
|
||||||
|
cp docker/env.example.production .env
|
||||||
|
print_success "Production environment file created: .env"
|
||||||
|
print_warning "⚠️ IMPORTANT: Edit .env and change all CHANGE_THIS_* passwords!"
|
||||||
|
else
|
||||||
|
print_error "Production environment template not found: docker/env.example.production"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
print_status "Environment file already exists: .env"
|
print_status "Environment file already exists: .env"
|
||||||
|
|||||||
233
docker-setup-env.sh
Executable file
233
docker-setup-env.sh
Executable file
@@ -0,0 +1,233 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script untuk setup environment file
|
||||||
|
# Usage: ./docker-setup-env.sh [local|production]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Default environment
|
||||||
|
ENVIRONMENT="local"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
local|dev|development)
|
||||||
|
ENVIRONMENT="local"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
prod|production)
|
||||||
|
ENVIRONMENT="production"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option $1"
|
||||||
|
echo "Usage: $0 [local|production]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Function to print colored output
|
||||||
|
print_status() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to backup existing .env
|
||||||
|
backup_existing_env() {
|
||||||
|
if [[ -f .env ]]; then
|
||||||
|
local backup_name=".env.backup.$(date +%Y%m%d_%H%M%S)"
|
||||||
|
print_status "Backing up existing .env to $backup_name"
|
||||||
|
cp .env "$backup_name"
|
||||||
|
print_success "Backup created: $backup_name"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to setup local environment
|
||||||
|
setup_local_env() {
|
||||||
|
print_status "Setting up LOCAL development environment..."
|
||||||
|
|
||||||
|
if [[ -f docker/env.example.local ]]; then
|
||||||
|
backup_existing_env
|
||||||
|
cp docker/env.example.local .env
|
||||||
|
print_success "✅ Local environment file created!"
|
||||||
|
echo ""
|
||||||
|
print_status "Local Development Configuration:"
|
||||||
|
echo " 🌐 App URL: http://localhost:8000"
|
||||||
|
echo " 🗄️ Database: ckb_db (MySQL)"
|
||||||
|
echo " 📧 Mail: MailHog (http://localhost:8025)"
|
||||||
|
echo " 🔴 Redis: Session & Cache"
|
||||||
|
echo " 🐛 Debug: Enabled"
|
||||||
|
echo ""
|
||||||
|
print_status "Services will be available at:"
|
||||||
|
echo " - Web App: http://localhost:8000"
|
||||||
|
echo " - phpMyAdmin: http://localhost:8080"
|
||||||
|
echo " - MailHog: http://localhost:8025"
|
||||||
|
echo ""
|
||||||
|
print_success "Ready for local development! Run: ./docker-quick-setup.sh dev"
|
||||||
|
else
|
||||||
|
print_error "Local environment template not found: docker/env.example.local"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to setup production environment
|
||||||
|
setup_production_env() {
|
||||||
|
print_status "Setting up PRODUCTION environment..."
|
||||||
|
|
||||||
|
if [[ -f docker/env.example.production ]]; then
|
||||||
|
backup_existing_env
|
||||||
|
cp docker/env.example.production .env
|
||||||
|
print_success "✅ Production environment file created!"
|
||||||
|
echo ""
|
||||||
|
print_warning "🚨 SECURITY CONFIGURATION REQUIRED!"
|
||||||
|
echo ""
|
||||||
|
print_status "You MUST change these settings in .env file:"
|
||||||
|
echo " 🔐 DB_PASSWORD=CHANGE_THIS_SECURE_PASSWORD"
|
||||||
|
echo " 🔐 DB_ROOT_PASSWORD=CHANGE_THIS_ROOT_PASSWORD"
|
||||||
|
echo " 🔐 REDIS_PASSWORD=CHANGE_THIS_REDIS_PASSWORD"
|
||||||
|
echo ""
|
||||||
|
print_status "Optional but recommended configurations:"
|
||||||
|
echo " 📧 MAIL_HOST, MAIL_USERNAME, MAIL_PASSWORD"
|
||||||
|
echo " ☁️ AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY (for S3)"
|
||||||
|
echo " 📡 PUSHER_* settings (for real-time features)"
|
||||||
|
echo ""
|
||||||
|
print_status "Production Configuration:"
|
||||||
|
echo " 🌐 App URL: https://bengkel.digitaloasis.xyz"
|
||||||
|
echo " 🗄️ Database: ckb_production (MySQL)"
|
||||||
|
echo " 📧 Mail: SMTP (configure in .env)"
|
||||||
|
echo " 🔴 Redis: Session, Cache & Queue"
|
||||||
|
echo " 🐛 Debug: Disabled"
|
||||||
|
echo " 🔒 SSL: Let's Encrypt"
|
||||||
|
echo ""
|
||||||
|
print_warning "Next steps:"
|
||||||
|
echo "1. Edit .env file and change all CHANGE_THIS_* values"
|
||||||
|
echo "2. Run: ./docker-deploy-prod.sh deploy"
|
||||||
|
echo "3. Run: ./docker-deploy-prod.sh ssl"
|
||||||
|
else
|
||||||
|
print_error "Production environment template not found: docker/env.example.production"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show current environment info
|
||||||
|
show_current_env() {
|
||||||
|
if [[ -f .env ]]; then
|
||||||
|
print_status "Current Environment Information:"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Detect environment type
|
||||||
|
local app_env=$(grep "^APP_ENV=" .env | cut -d '=' -f2)
|
||||||
|
local app_url=$(grep "^APP_URL=" .env | cut -d '=' -f2)
|
||||||
|
local app_debug=$(grep "^APP_DEBUG=" .env | cut -d '=' -f2)
|
||||||
|
local db_host=$(grep "^DB_HOST=" .env | cut -d '=' -f2)
|
||||||
|
local db_name=$(grep "^DB_DATABASE=" .env | cut -d '=' -f2)
|
||||||
|
|
||||||
|
echo " Environment: $app_env"
|
||||||
|
echo " App URL: $app_url"
|
||||||
|
echo " Debug Mode: $app_debug"
|
||||||
|
echo " Database Host: $db_host"
|
||||||
|
echo " Database Name: $db_name"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check for security issues in production
|
||||||
|
if [[ "$app_env" == "production" ]]; then
|
||||||
|
print_status "Security Check:"
|
||||||
|
if grep -q "CHANGE_THIS" .env; then
|
||||||
|
print_error "❌ Found CHANGE_THIS_* values in production .env!"
|
||||||
|
print_warning "Please update all CHANGE_THIS_* values with secure passwords."
|
||||||
|
else
|
||||||
|
print_success "✅ No CHANGE_THIS_* values found."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$app_debug" == "true" ]]; then
|
||||||
|
print_error "❌ Debug mode is enabled in production!"
|
||||||
|
print_warning "Set APP_DEBUG=false for production."
|
||||||
|
else
|
||||||
|
print_success "✅ Debug mode is disabled."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_status "No .env file found."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to validate environment file
|
||||||
|
validate_env() {
|
||||||
|
if [[ ! -f .env ]]; then
|
||||||
|
print_error "No .env file found!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_status "Validating environment file..."
|
||||||
|
|
||||||
|
# Required variables
|
||||||
|
local required_vars=("APP_NAME" "APP_ENV" "APP_URL" "DB_HOST" "DB_DATABASE" "DB_USERNAME" "DB_PASSWORD")
|
||||||
|
local missing_vars=()
|
||||||
|
|
||||||
|
for var in "${required_vars[@]}"; do
|
||||||
|
if ! grep -q "^${var}=" .env; then
|
||||||
|
missing_vars+=("$var")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ${#missing_vars[@]} -gt 0 ]]; then
|
||||||
|
print_error "Missing required environment variables:"
|
||||||
|
for var in "${missing_vars[@]}"; do
|
||||||
|
echo " - $var"
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_success "✅ Environment file validation passed!"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
echo "================================================"
|
||||||
|
print_status "🔧 CKB Environment Setup Helper"
|
||||||
|
print_status "Target Environment: $ENVIRONMENT"
|
||||||
|
echo "================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
case $ENVIRONMENT in
|
||||||
|
local)
|
||||||
|
setup_local_env
|
||||||
|
;;
|
||||||
|
production)
|
||||||
|
setup_production_env
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_status "Environment file setup completed!"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Show current environment info
|
||||||
|
show_current_env
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_status "Available commands:"
|
||||||
|
echo " - Show current env: ./docker-setup-env.sh"
|
||||||
|
echo " - Setup local: ./docker-setup-env.sh local"
|
||||||
|
echo " - Setup production: ./docker-setup-env.sh production"
|
||||||
|
echo " - Quick local setup: ./docker-quick-setup.sh dev"
|
||||||
|
echo " - Production deploy: ./docker-deploy-prod.sh deploy"
|
||||||
283
docker-ssl-setup.sh
Executable file
283
docker-ssl-setup.sh
Executable file
@@ -0,0 +1,283 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script untuk setup SSL certificate dengan Let's Encrypt untuk domain bengkel.digitaloasis.xyz
|
||||||
|
# Usage: ./docker-ssl-setup.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
DOMAIN="bengkel.digitaloasis.xyz"
|
||||||
|
WWW_DOMAIN="www.bengkel.digitaloasis.xyz"
|
||||||
|
EMAIL="admin@digitaloasis.xyz"
|
||||||
|
COMPOSE_FILE="docker-compose.prod.yml"
|
||||||
|
|
||||||
|
# Function to print colored output
|
||||||
|
print_status() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if Docker is running
|
||||||
|
check_docker() {
|
||||||
|
if ! docker info > /dev/null 2>&1; then
|
||||||
|
print_error "Docker is not running. Please start Docker first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if domain is pointing to this server
|
||||||
|
check_domain() {
|
||||||
|
print_status "Checking if domain $DOMAIN is pointing to this server..."
|
||||||
|
|
||||||
|
# Get current server IP
|
||||||
|
SERVER_IP=$(curl -s ifconfig.me || curl -s icanhazip.com || echo "Unable to detect")
|
||||||
|
|
||||||
|
# Get domain IP
|
||||||
|
DOMAIN_IP=$(dig +short $DOMAIN | head -n1)
|
||||||
|
|
||||||
|
print_status "Server IP: $SERVER_IP"
|
||||||
|
print_status "Domain IP: $DOMAIN_IP"
|
||||||
|
|
||||||
|
if [[ "$SERVER_IP" != "$DOMAIN_IP" ]]; then
|
||||||
|
print_warning "Domain might not be pointing to this server!"
|
||||||
|
print_warning "Please make sure DNS is configured correctly before proceeding."
|
||||||
|
read -p "Continue anyway? (y/N): " -n 1 -r
|
||||||
|
echo ""
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_status "SSL setup cancelled."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_success "Domain is correctly pointing to this server!"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to create temporary nginx config for initial certificate
|
||||||
|
create_temp_nginx() {
|
||||||
|
print_status "Creating temporary nginx configuration for initial certificate..."
|
||||||
|
|
||||||
|
cat > docker/nginx-temp.conf << 'EOF'
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz;
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 200 'SSL setup in progress...';
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to start nginx with temporary config
|
||||||
|
start_temp_nginx() {
|
||||||
|
print_status "Starting nginx with temporary configuration..."
|
||||||
|
|
||||||
|
# Update docker-compose to use temporary config
|
||||||
|
sed -i 's|nginx-proxy.conf|nginx-temp.conf|g' $COMPOSE_FILE
|
||||||
|
|
||||||
|
# Start nginx-proxy
|
||||||
|
docker-compose -f $COMPOSE_FILE up -d nginx-proxy
|
||||||
|
|
||||||
|
# Wait for nginx to be ready
|
||||||
|
sleep 10
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to obtain SSL certificate
|
||||||
|
obtain_certificate() {
|
||||||
|
print_status "Obtaining SSL certificate from Let's Encrypt..."
|
||||||
|
|
||||||
|
# Run certbot
|
||||||
|
docker-compose -f $COMPOSE_FILE run --rm certbot certonly \
|
||||||
|
--webroot \
|
||||||
|
--webroot-path=/var/www/certbot \
|
||||||
|
--email $EMAIL \
|
||||||
|
--agree-tos \
|
||||||
|
--no-eff-email \
|
||||||
|
--force-renewal \
|
||||||
|
-d $DOMAIN \
|
||||||
|
-d $WWW_DOMAIN
|
||||||
|
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
print_success "SSL certificate obtained successfully!"
|
||||||
|
else
|
||||||
|
print_error "Failed to obtain SSL certificate!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to setup certificate files
|
||||||
|
setup_certificate_files() {
|
||||||
|
print_status "Setting up certificate files for nginx..."
|
||||||
|
|
||||||
|
# Copy certificates to nginx ssl directory
|
||||||
|
docker run --rm \
|
||||||
|
-v ckb_ssl_certificates:/source \
|
||||||
|
-v ckb_ssl_certificates:/target \
|
||||||
|
alpine sh -c "
|
||||||
|
mkdir -p /target/live/$DOMAIN
|
||||||
|
cp -L /source/live/$DOMAIN/fullchain.pem /target/fullchain.pem
|
||||||
|
cp -L /source/live/$DOMAIN/privkey.pem /target/privkey.pem
|
||||||
|
chmod 644 /target/fullchain.pem
|
||||||
|
chmod 600 /target/privkey.pem
|
||||||
|
"
|
||||||
|
|
||||||
|
print_success "Certificate files setup completed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to restore production nginx config
|
||||||
|
restore_production_config() {
|
||||||
|
print_status "Restoring production nginx configuration..."
|
||||||
|
|
||||||
|
# Restore original config
|
||||||
|
sed -i 's|nginx-temp.conf|nginx-proxy.conf|g' $COMPOSE_FILE
|
||||||
|
|
||||||
|
# Restart nginx with SSL configuration
|
||||||
|
docker-compose -f $COMPOSE_FILE up -d nginx-proxy
|
||||||
|
|
||||||
|
print_success "Production nginx configuration restored!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test SSL certificate
|
||||||
|
test_ssl() {
|
||||||
|
print_status "Testing SSL certificate..."
|
||||||
|
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Test HTTPS connection
|
||||||
|
if curl -s --max-time 10 https://$DOMAIN > /dev/null; then
|
||||||
|
print_success "HTTPS is working correctly!"
|
||||||
|
else
|
||||||
|
print_warning "HTTPS test failed. Please check the configuration."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test certificate validity
|
||||||
|
if openssl s_client -connect $DOMAIN:443 -servername $DOMAIN < /dev/null 2>/dev/null | openssl x509 -noout -dates; then
|
||||||
|
print_success "Certificate information retrieved successfully!"
|
||||||
|
else
|
||||||
|
print_warning "Could not retrieve certificate information."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to setup certificate renewal
|
||||||
|
setup_renewal() {
|
||||||
|
print_status "Setting up automatic certificate renewal..."
|
||||||
|
|
||||||
|
# Create renewal script
|
||||||
|
cat > docker-ssl-renew.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# SSL Certificate Renewal Script
|
||||||
|
# Add this to crontab: 0 12 * * * /path/to/docker-ssl-renew.sh
|
||||||
|
|
||||||
|
docker-compose -f docker-compose.prod.yml run --rm certbot renew --quiet
|
||||||
|
|
||||||
|
# Reload nginx if certificate was renewed
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
# Copy renewed certificates
|
||||||
|
docker run --rm \
|
||||||
|
-v ckb_ssl_certificates:/source \
|
||||||
|
-v ckb_ssl_certificates:/target \
|
||||||
|
alpine sh -c "
|
||||||
|
cp -L /source/live/bengkel.digitaloasis.xyz/fullchain.pem /target/fullchain.pem
|
||||||
|
cp -L /source/live/bengkel.digitaloasis.xyz/privkey.pem /target/privkey.pem
|
||||||
|
"
|
||||||
|
|
||||||
|
# Reload nginx
|
||||||
|
docker-compose -f docker-compose.prod.yml exec nginx-proxy nginx -s reload
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x docker-ssl-renew.sh
|
||||||
|
|
||||||
|
print_success "Certificate renewal script created: docker-ssl-renew.sh"
|
||||||
|
print_status "To setup automatic renewal, add this to crontab:"
|
||||||
|
echo "0 12 * * * $(pwd)/docker-ssl-renew.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show final information
|
||||||
|
show_final_info() {
|
||||||
|
echo ""
|
||||||
|
print_success "🎉 SSL setup completed successfully!"
|
||||||
|
echo ""
|
||||||
|
print_status "Your application is now available at:"
|
||||||
|
echo " 🌐 https://bengkel.digitaloasis.xyz"
|
||||||
|
echo " 🌐 https://www.bengkel.digitaloasis.xyz"
|
||||||
|
echo ""
|
||||||
|
print_status "SSL Certificate Information:"
|
||||||
|
echo " 📅 Domain: $DOMAIN, $WWW_DOMAIN"
|
||||||
|
echo " 📧 Email: $EMAIL"
|
||||||
|
echo " 🔄 Auto-renewal: Setup docker-ssl-renew.sh in crontab"
|
||||||
|
echo ""
|
||||||
|
print_status "Useful Commands:"
|
||||||
|
echo " - Check certificate: openssl s_client -connect $DOMAIN:443 -servername $DOMAIN"
|
||||||
|
echo " - Renew certificate: ./docker-ssl-renew.sh"
|
||||||
|
echo " - View logs: docker-compose -f $COMPOSE_FILE logs nginx-proxy"
|
||||||
|
echo " - Test renewal: docker-compose -f $COMPOSE_FILE run --rm certbot renew --dry-run"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
echo "================================================"
|
||||||
|
print_status "🔒 SSL Certificate Setup for CKB Production"
|
||||||
|
print_status "Domain: $DOMAIN"
|
||||||
|
echo "================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check prerequisites
|
||||||
|
check_docker
|
||||||
|
check_domain
|
||||||
|
|
||||||
|
# Ask for confirmation
|
||||||
|
print_warning "This will setup SSL certificate for $DOMAIN"
|
||||||
|
print_status "Make sure your application is not currently running."
|
||||||
|
read -p "Continue with SSL setup? (y/N): " -n 1 -r
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_status "SSL setup cancelled."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute SSL setup
|
||||||
|
print_status "Starting SSL certificate setup process..."
|
||||||
|
|
||||||
|
create_temp_nginx
|
||||||
|
start_temp_nginx
|
||||||
|
obtain_certificate
|
||||||
|
setup_certificate_files
|
||||||
|
restore_production_config
|
||||||
|
test_ssl
|
||||||
|
setup_renewal
|
||||||
|
|
||||||
|
# Show final information
|
||||||
|
show_final_info
|
||||||
|
|
||||||
|
print_success "✅ SSL setup completed successfully!"
|
||||||
@@ -82,13 +82,25 @@ check_docker() {
|
|||||||
# Function to setup environment file
|
# Function to setup environment file
|
||||||
setup_env() {
|
setup_env() {
|
||||||
if [[ ! -f .env ]]; then
|
if [[ ! -f .env ]]; then
|
||||||
if [[ -f docker/env.example ]]; then
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
print_status "Copying environment file..."
|
if [[ -f docker/env.example.local ]]; then
|
||||||
cp docker/env.example .env
|
print_status "Copying local environment file..."
|
||||||
print_warning "Please edit .env file to configure your application"
|
cp docker/env.example.local .env
|
||||||
|
print_success "Local development environment configured"
|
||||||
|
else
|
||||||
|
print_error "Local environment template not found: docker/env.example.local"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
print_error "No environment template found. Please create .env file manually."
|
if [[ -f docker/env.example.production ]]; then
|
||||||
exit 1
|
print_status "Copying production environment file..."
|
||||||
|
cp docker/env.example.production .env
|
||||||
|
print_warning "⚠️ IMPORTANT: Edit .env and change all CHANGE_THIS_* passwords!"
|
||||||
|
print_warning "Please configure production settings before continuing"
|
||||||
|
else
|
||||||
|
print_error "Production environment template not found: docker/env.example.production"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,46 @@
|
|||||||
APP_NAME="CKB Application"
|
APP_NAME="CKB Bengkel System"
|
||||||
APP_ENV=local
|
APP_ENV=production
|
||||||
APP_KEY=
|
APP_KEY=
|
||||||
APP_DEBUG=true
|
APP_DEBUG=false
|
||||||
APP_URL=http://localhost:8000
|
APP_URL=https://bengkel.digitaloasis.xyz
|
||||||
|
|
||||||
LOG_CHANNEL=stack
|
LOG_CHANNEL=stack
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=error
|
||||||
|
|
||||||
# Database Configuration for Docker
|
# Database Configuration for Production
|
||||||
DB_CONNECTION=mysql
|
DB_CONNECTION=mysql
|
||||||
DB_HOST=db
|
DB_HOST=db
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
DB_DATABASE=ckb_db
|
DB_DATABASE=ckb_production
|
||||||
DB_USERNAME=root
|
DB_USERNAME=ckb_user
|
||||||
DB_PASSWORD=root
|
DB_PASSWORD=secure_password_here
|
||||||
|
DB_ROOT_PASSWORD=secure_root_password_here
|
||||||
|
|
||||||
# Redis Configuration for Docker
|
# Redis Configuration for Production
|
||||||
REDIS_HOST=redis
|
REDIS_HOST=redis
|
||||||
REDIS_PASSWORD=null
|
REDIS_PASSWORD=secure_redis_password
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
BROADCAST_DRIVER=log
|
BROADCAST_DRIVER=redis
|
||||||
CACHE_DRIVER=redis
|
CACHE_DRIVER=redis
|
||||||
FILESYSTEM_DRIVER=local
|
FILESYSTEM_DRIVER=local
|
||||||
QUEUE_CONNECTION=sync
|
QUEUE_CONNECTION=redis
|
||||||
SESSION_DRIVER=redis
|
SESSION_DRIVER=redis
|
||||||
SESSION_LIFETIME=120
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
# Mail Configuration for Docker (MailHog)
|
# Mail Configuration for Production
|
||||||
MAIL_MAILER=smtp
|
MAIL_MAILER=smtp
|
||||||
MAIL_HOST=mailhog
|
MAIL_HOST=your-smtp-host.com
|
||||||
MAIL_PORT=1025
|
MAIL_PORT=587
|
||||||
MAIL_USERNAME=null
|
MAIL_USERNAME=your-email@domain.com
|
||||||
MAIL_PASSWORD=null
|
MAIL_PASSWORD=your-email-password
|
||||||
MAIL_ENCRYPTION=null
|
MAIL_ENCRYPTION=tls
|
||||||
MAIL_FROM_ADDRESS=test@ckb.local
|
MAIL_FROM_ADDRESS=noreply@bengkel.digitaloasis.xyz
|
||||||
MAIL_FROM_NAME="${APP_NAME}"
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
# Trusted Proxies for Production
|
||||||
|
TRUSTED_PROXIES=*
|
||||||
|
|
||||||
# AWS (if needed for production)
|
# AWS (if needed for production)
|
||||||
AWS_ACCESS_KEY_ID=
|
AWS_ACCESS_KEY_ID=
|
||||||
AWS_SECRET_ACCESS_KEY=
|
AWS_SECRET_ACCESS_KEY=
|
||||||
|
|||||||
64
docker/env.example.local
Normal file
64
docker/env.example.local
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
APP_NAME="CKB Application"
|
||||||
|
APP_ENV=local
|
||||||
|
APP_KEY=
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_URL=http://localhost:8000
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
LOG_LEVEL=debug
|
||||||
|
|
||||||
|
# Database Configuration for Local Development
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=db
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=ckb_db
|
||||||
|
DB_USERNAME=root
|
||||||
|
DB_PASSWORD=root
|
||||||
|
|
||||||
|
# Redis Configuration for Local Development
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
BROADCAST_DRIVER=log
|
||||||
|
CACHE_DRIVER=redis
|
||||||
|
FILESYSTEM_DRIVER=local
|
||||||
|
QUEUE_CONNECTION=sync
|
||||||
|
SESSION_DRIVER=redis
|
||||||
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
|
# Mail Configuration for Local Development (MailHog)
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=mailhog
|
||||||
|
MAIL_PORT=1025
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_FROM_ADDRESS=test@ckb.local
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
# AWS (for local testing if needed)
|
||||||
|
AWS_ACCESS_KEY_ID=
|
||||||
|
AWS_SECRET_ACCESS_KEY=
|
||||||
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
|
AWS_BUCKET=
|
||||||
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
|
# Pusher (for local testing if needed)
|
||||||
|
PUSHER_APP_ID=
|
||||||
|
PUSHER_APP_KEY=
|
||||||
|
PUSHER_APP_SECRET=
|
||||||
|
PUSHER_HOST=
|
||||||
|
PUSHER_PORT=443
|
||||||
|
PUSHER_SCHEME=https
|
||||||
|
PUSHER_APP_CLUSTER=mt1
|
||||||
|
|
||||||
|
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}"
|
||||||
|
|
||||||
|
# Local Development Settings
|
||||||
|
TELESCOPE_ENABLED=true
|
||||||
|
DEBUGBAR_ENABLED=true
|
||||||
78
docker/env.example.production
Normal file
78
docker/env.example.production
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
APP_NAME="CKB Bengkel System"
|
||||||
|
APP_ENV=production
|
||||||
|
APP_KEY=
|
||||||
|
APP_DEBUG=false
|
||||||
|
APP_URL=https://bengkel.digitaloasis.xyz
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
LOG_LEVEL=error
|
||||||
|
|
||||||
|
# Database Configuration for Production
|
||||||
|
# IMPORTANT: Change these credentials for security!
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=db
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=ckb_production
|
||||||
|
DB_USERNAME=ckb_user
|
||||||
|
DB_PASSWORD=CHANGE_THIS_SECURE_PASSWORD
|
||||||
|
DB_ROOT_PASSWORD=CHANGE_THIS_ROOT_PASSWORD
|
||||||
|
|
||||||
|
# Redis Configuration for Production
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PASSWORD=CHANGE_THIS_REDIS_PASSWORD
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
BROADCAST_DRIVER=redis
|
||||||
|
CACHE_DRIVER=redis
|
||||||
|
FILESYSTEM_DRIVER=local
|
||||||
|
QUEUE_CONNECTION=redis
|
||||||
|
SESSION_DRIVER=redis
|
||||||
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
|
# Mail Configuration for Production
|
||||||
|
# Configure with your SMTP provider (Gmail, SendGrid, Mailgun, etc.)
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=smtp.gmail.com
|
||||||
|
MAIL_PORT=587
|
||||||
|
MAIL_USERNAME=your-email@gmail.com
|
||||||
|
MAIL_PASSWORD=your-app-password
|
||||||
|
MAIL_ENCRYPTION=tls
|
||||||
|
MAIL_FROM_ADDRESS=noreply@bengkel.digitaloasis.xyz
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
# Trusted Proxies for Production (Nginx reverse proxy)
|
||||||
|
TRUSTED_PROXIES=*
|
||||||
|
|
||||||
|
# AWS Configuration for Production (if using S3 for file storage)
|
||||||
|
AWS_ACCESS_KEY_ID=your-aws-access-key
|
||||||
|
AWS_SECRET_ACCESS_KEY=your-aws-secret-key
|
||||||
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
|
AWS_BUCKET=ckb-production-storage
|
||||||
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
|
# Pusher Configuration for Production (if using real-time features)
|
||||||
|
PUSHER_APP_ID=your-pusher-app-id
|
||||||
|
PUSHER_APP_KEY=your-pusher-key
|
||||||
|
PUSHER_APP_SECRET=your-pusher-secret
|
||||||
|
PUSHER_HOST=
|
||||||
|
PUSHER_PORT=443
|
||||||
|
PUSHER_SCHEME=https
|
||||||
|
PUSHER_APP_CLUSTER=ap1
|
||||||
|
|
||||||
|
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}"
|
||||||
|
|
||||||
|
# Production Optimization Settings
|
||||||
|
TELESCOPE_ENABLED=false
|
||||||
|
DEBUGBAR_ENABLED=false
|
||||||
|
|
||||||
|
# Security Settings
|
||||||
|
SESSION_SECURE_COOKIE=true
|
||||||
|
SESSION_SAME_SITE=strict
|
||||||
|
|
||||||
|
# Backup Configuration (optional)
|
||||||
|
BACKUP_DISK=s3
|
||||||
|
BACKUP_NOTIFICATION_MAIL=admin@digitaloasis.xyz
|
||||||
142
docker/nginx-proxy.conf
Normal file
142
docker/nginx-proxy.conf
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
# Basic settings
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
types_hash_max_size 2048;
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
# Gzip compression
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_min_length 1024;
|
||||||
|
gzip_types
|
||||||
|
text/plain
|
||||||
|
text/css
|
||||||
|
text/xml
|
||||||
|
text/javascript
|
||||||
|
application/javascript
|
||||||
|
application/xml+rss
|
||||||
|
application/json
|
||||||
|
image/svg+xml;
|
||||||
|
|
||||||
|
# MIME types
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
error_log /var/log/nginx/error.log;
|
||||||
|
|
||||||
|
# Rate limiting
|
||||||
|
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
|
||||||
|
limit_req_zone $binary_remote_addr zone=api:10m rate=60r/m;
|
||||||
|
|
||||||
|
# Upstream to Laravel app
|
||||||
|
upstream app {
|
||||||
|
server app:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP to HTTPS redirect
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz;
|
||||||
|
|
||||||
|
# Let's Encrypt challenge
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redirect all other traffic to HTTPS
|
||||||
|
location / {
|
||||||
|
return 301 https://$server_name$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTPS server configuration
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz;
|
||||||
|
|
||||||
|
# SSL configuration
|
||||||
|
ssl_certificate /etc/nginx/ssl/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
|
||||||
|
|
||||||
|
# Modern SSL configuration
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||||
|
|
||||||
|
# Root directory
|
||||||
|
root /var/www/html/public;
|
||||||
|
index index.php index.html;
|
||||||
|
|
||||||
|
# Proxy settings
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
|
||||||
|
# Handle static files
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
proxy_pass http://app;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rate limiting for login endpoints
|
||||||
|
location ~ ^/(login|register|password) {
|
||||||
|
limit_req zone=login burst=5 nodelay;
|
||||||
|
proxy_pass http://app;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rate limiting for API endpoints
|
||||||
|
location /api/ {
|
||||||
|
limit_req zone=api burst=20 nodelay;
|
||||||
|
proxy_pass http://app;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main application
|
||||||
|
location / {
|
||||||
|
proxy_pass http://app;
|
||||||
|
proxy_read_timeout 300;
|
||||||
|
proxy_connect_timeout 300;
|
||||||
|
proxy_send_timeout 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
proxy_pass http://app;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Block access to sensitive files
|
||||||
|
location ~ /\. {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/(storage|bootstrap/cache) {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user