diff --git a/Dockerfile b/Dockerfile
index afe11ba..c64d04d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -61,6 +61,7 @@ WORKDIR /var/www
# Install PHP extensions
RUN apt-get update && apt-get install -y \
git curl zip unzip libpng-dev libonig-dev libxml2-dev libzip-dev \
+ supervisor \
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip
# Install Node.js
@@ -94,8 +95,15 @@ RUN php artisan config:clear \
RUN php artisan storage:link
+# Create supervisor directories
+RUN mkdir -p /var/log/supervisor /var/run/supervisor
+
+# Copy supervisor configuration
+COPY docker/supervisor/supervisord.conf /etc/supervisor/supervisord.conf
+COPY docker/supervisor/laravel-production.conf /etc/supervisor/conf.d/laravel-production.conf
+
# Permissions
RUN chown -R www-data:www-data /var/www && chmod -R 755 /var/www/storage /var/www/public
EXPOSE 9000
-CMD ["php-fpm"]
+CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
diff --git a/OPTIMIZED_TABLE_STRUCTURE.md b/OPTIMIZED_TABLE_STRUCTURE.md
deleted file mode 100644
index bcf9623..0000000
--- a/OPTIMIZED_TABLE_STRUCTURE.md
+++ /dev/null
@@ -1,210 +0,0 @@
-# Struktur Tabel Retribusi PBG yang Dioptimalkan
-
-## Ringkasan Optimasi
-
-Struktur tabel baru ini **lebih sederhana**, **fokus pada perhitungan**, dan **menghilangkan redundansi** dari struktur sebelumnya.
-
-## Perbandingan Struktur
-
-### SEBELUM (Kompleks)
-
-- `building_functions` - 8 kolom + relationship kompleks
-- `building_function_parameters` - 12 kolom dengan mismatch model/migration
-- `retribution_formulas` - Menyimpan formula sebagai string
-- `retribution_proposals` - 15+ kolom dengan banyak redundansi
-- `floor_height_indices` - OK, tidak berubah
-
-### SESUDAH (Sederhana)
-
-- `building_types` - **7 kolom**, hierarki sederhana
-- `retribution_indices` - **6 kolom**, parameter calculation saja
-- `height_indices` - **3 kolom**, sama seperti sebelumnya
-- `retribution_configs` - **5 kolom**, konfigurasi global
-- `retribution_calculations` - **8 kolom**, hasil perhitungan saja
-
----
-
-## Detail Struktur Tabel Baru
-
-### 1. `building_types`
-
-**Fungsi:** Menyimpan jenis fungsi bangunan dengan hierarki sederhana
-
-| Kolom | Tipe | Keterangan |
-| ------------- | ------------ | ---------------------------------- |
-| `id` | bigint | Primary key |
-| `code` | varchar(10) | Kode unik (UMKM, KEAGAMAAN, dll) |
-| `name` | varchar(100) | Nama fungsi bangunan |
-| `parent_id` | bigint | ID parent (untuk hierarki) |
-| `level` | tinyint | Level hierarki (1=parent, 2=child) |
-| `coefficient` | decimal(8,4) | **Koefisien untuk perhitungan** |
-| `is_free` | boolean | **Apakah gratis (keagamaan, MBR)** |
-
-### 2. `retribution_indices`
-
-**Fungsi:** Menyimpan parameter indeks untuk perhitungan (1:1 dengan building_types)
-
-| Kolom | Tipe | Keterangan |
-| ----------------------- | ------------ | ---------------------------------- |
-| `id` | bigint | Primary key |
-| `building_type_id` | bigint | FK ke building_types |
-| `ip_permanent` | decimal(8,4) | **Indeks Permanensi** |
-| `ip_complexity` | decimal(8,4) | **Indeks Kompleksitas** |
-| `locality_index` | decimal(8,4) | **Indeks Lokalitas** |
-| `infrastructure_factor` | decimal(8,4) | **Faktor prasarana (default 50%)** |
-
-### 3. `height_indices`
-
-**Fungsi:** Indeks ketinggian per lantai (sama seperti sebelumnya)
-
-| Kolom | Tipe | Keterangan |
-| -------------- | ------------ | ---------------------------------------- |
-| `id` | bigint | Primary key |
-| `floor_number` | tinyint | Nomor lantai (1,2,3,4,5,6) |
-| `height_index` | decimal(8,6) | **IP Ketinggian (1.0, 1.09, 1.12, dst)** |
-
-### 4. `retribution_configs`
-
-**Fungsi:** Konfigurasi global untuk perhitungan (menggantikan hard-coded values)
-
-| Kolom | Tipe | Keterangan |
-| ------------- | ------------- | --------------------- |
-| `id` | bigint | Primary key |
-| `key` | varchar(50) | Kunci konfigurasi |
-| `value` | decimal(15,2) | **Nilai konfigurasi** |
-| `description` | varchar(200) | Deskripsi |
-
-**Data yang disimpan:**
-
-- `BASE_VALUE` = 70350 (nilai dasar)
-- `INFRASTRUCTURE_MULTIPLIER` = 0.5 (50% prasarana)
-- `HEIGHT_MULTIPLIER` = 0.5 (pengali indeks ketinggian)
-
-### 5. `retribution_calculations`
-
-**Fungsi:** Hasil perhitungan retribusi (history)
-
-| Kolom | Tipe | Keterangan |
-| -------------------- | ------------- | -------------------------------- |
-| `id` | bigint | Primary key |
-| `calculation_id` | varchar(20) | ID unik perhitungan |
-| `building_type_id` | bigint | FK ke building_types |
-| `floor_number` | tinyint | Lantai yang dipilih |
-| `building_area` | decimal(12,2) | **Luas bangunan input** |
-| `retribution_amount` | decimal(15,2) | **Hasil perhitungan** |
-| `calculation_detail` | json | **Detail breakdown perhitungan** |
-| `calculated_at` | timestamp | Waktu perhitungan |
-
----
-
-## Formula Perhitungan
-
-### Formula Excel yang Diimplementasikan:
-
-```
-H13 = coefficient * (ip_permanent + ip_complexity + (0.5 * height_index))
-
-Main Calculation = building_area * (locality_index * BASE_VALUE * H13)
-
-Infrastructure = INFRASTRUCTURE_MULTIPLIER * Main Calculation
-
-Total Retribution = Main Calculation + Infrastructure
-```
-
-### Implementasi dalam Service:
-
-```php
-// Step 1: Calculate H13 coefficient
-$h13 = $buildingType->coefficient * (
- $indices->ip_permanent +
- $indices->ip_complexity +
- (0.5 * $heightIndex)
-);
-
-// Step 2: Main calculation
-$mainCalculation = $buildingArea * ($indices->locality_index * $baseValue * $h13);
-
-// Step 3: Infrastructure (50% additional)
-$infrastructureCalculation = 0.5 * $mainCalculation;
-
-// Step 4: Total
-$totalRetribution = $mainCalculation + $infrastructureCalculation;
-```
-
----
-
-## Keuntungan Struktur Baru
-
-### ✅ **Simplicity**
-
-- **5 tabel** vs 8+ tabel sebelumnya
-- **Kolom minimal** hanya yang diperlukan untuk perhitungan
-- **No redundant data** seperti ip_ketinggian di proposals
-
-### ✅ **Performance**
-
-- **Proper indexes** untuk query yang sering digunakan
-- **Normalized structure** mengurangi storage
-- **Cached configs** untuk values yang jarang berubah
-
-### ✅ **Maintainability**
-
-- **Clear separation** antara master data dan calculation results
-- **Configurable values** tidak hard-coded lagi
-- **Single responsibility** setiap tabel punya tujuan jelas
-
-### ✅ **Flexibility**
-
-- **Easy to extend** untuk fungsi bangunan baru
-- **Configurable formulas** lewat RetributionConfig
-- **Audit trail** lewat calculation history
-
-### ✅ **Data Integrity**
-
-- **Proper constraints** untuk validasi data
-- **Foreign key relationships** yang benar
-- **No model-migration mismatch**
-
----
-
-## Migration Guide
-
-### Langkah Implementasi:
-
-1. **Run Migration:** `php artisan migrate` untuk tabel baru
-2. **Seed Data:** Data master berdasarkan Excel akan otomatis ter-seed
-3. **Update Code:** Ganti penggunaan model lama dengan model baru
-4. **Test Calculation:** Verifikasi hasil perhitungan sama dengan Excel
-5. **Deploy:** Struktur siap production
-
-### Data Migration (Optional):
-
-Jika ada data existing di tabel lama yang perlu dipindahkan, buat script migration untuk transfer data dari struktur lama ke struktur baru.
-
----
-
-## Usage Example
-
-```php
-// Initialize service
-$calculator = new RetributionCalculatorService();
-
-// Calculate retribution
-$result = $calculator->calculate(
- buildingTypeId: 8, // UMKM
- floorNumber: 2, // 2 lantai
- buildingArea: 100.50, // 100.5 m2
- saveResult: true // Simpan ke database
-);
-
-// Result structure
-[
- 'building_type' => [...],
- 'total_retribution' => 31658.25,
- 'formatted_amount' => 'Rp 31,658.25',
- 'calculation_steps' => [...],
- 'calculation_id' => 'RTB-20250130140530-123'
-]
-```
-
-Struktur ini **jauh lebih clean**, **mudah dipahami**, dan **optimal untuk perhitungan retribusi PBG**!
diff --git a/README-Docker-Usage.md b/README-Docker-Usage.md
deleted file mode 100644
index 236fe02..0000000
--- a/README-Docker-Usage.md
+++ /dev/null
@@ -1,109 +0,0 @@
-# Docker Usage Guide
-
-Proyek ini memiliki dua konfigurasi Docker untuk keperluan yang berbeda:
-
-## 📁 File Konfigurasi
-
-### 1. `docker-compose.yml` - Production/Staging
-
-- **Target**: `production` (optimized build)
-- **Environment**: Production settings
-- **Debug**: Disabled
-- **Asset handling**: Built dan optimized
-- **Use case**: Deploy ke server production/staging
-
-### 2. `docker-compose.local.yml` - Local Development
-
-- **Target**: `local` (development build)
-- **Environment**: Local development settings
-- **Debug**: Enabled
-- **Asset handling**: Vite dev server terpisah
-- **Use case**: Development di local machine
-
-## 🚀 Cara Penggunaan
-
-### Local Development (Recommended)
-
-```bash
-# Setup awal (otomatis)
-./setup-local.sh
-
-# Atau manual
-docker-compose -f docker-compose.local.yml up -d --build
-```
-
-### Production/Staging
-
-```bash
-# Dengan environment variables
-docker-compose up -d --build
-
-# Atau dengan custom .env
-APP_ENV=production APP_DEBUG=false docker-compose up -d --build
-```
-
-## 🔧 Perbedaan Utama
-
-| Aspek | Local Development | Production |
-| ---------------- | -------------------------- | --------------------- |
-| **File** | `docker-compose.local.yml` | `docker-compose.yml` |
-| **Target** | `local` | `production` |
-| **Debug** | Enabled | Disabled |
-| **Assets** | Vite dev server | Pre-built & optimized |
-| **Permissions** | User mapping | Standard www-data |
-| **Hot Reload** | ✅ Available | ❌ Not needed |
-| **Node Modules** | Kept for dev | Removed after build |
-
-## 📋 Command Cheat Sheet
-
-### Local Development
-
-```bash
-# Start
-docker-compose -f docker-compose.local.yml up -d
-
-# Stop
-docker-compose -f docker-compose.local.yml down
-
-# Logs
-docker-compose -f docker-compose.local.yml logs -f app
-
-# Execute commands
-docker-compose -f docker-compose.local.yml exec app php artisan [command]
-```
-
-### Production
-
-```bash
-# Start
-docker-compose up -d
-
-# Stop
-docker-compose down
-
-# Logs
-docker-compose logs -f app
-
-# Execute commands
-docker-compose exec app php artisan [command]
-```
-
-## 🛠 Development Workflow
-
-1. **Daily development**: Gunakan `docker-compose.local.yml`
-2. **Testing production build**: Gunakan `docker-compose.yml`
-3. **Deploy**: Gunakan `docker-compose.yml` di server
-
-## ❓ FAQ
-
-**Q: Apakah perlu kedua file?**
-A: Ya, keduanya memiliki fungsi berbeda:
-
-- `docker-compose.local.yml` untuk development
-- `docker-compose.yml` untuk production/staging
-
-**Q: File mana yang digunakan untuk development?**
-A: Gunakan `docker-compose.local.yml` dengan menjalankan `./setup-local.sh`
-
-**Q: Bagaimana cara switch antara development dan production?**
-A: Gunakan flag `-f` untuk specify file yang ingin digunakan
diff --git a/README.md b/README.md
index 27f1bcc..a1f12c6 100644
--- a/README.md
+++ b/README.md
@@ -1,112 +1,167 @@
-# Usage icon
+# Sibedas PBG Web
-search or pick icon in here
+Aplikasi web untuk manajemen data PBG (Pendidikan Berkelanjutan Guru) dengan fitur integrasi Google Sheets.
-# Set up queue for running automatically
+## 🚀 Quick Start
-- Install Supervisor
+### Prerequisites
-```
-sudo apt update && sudo apt install supervisor -y
+- Docker & Docker Compose
+- Domain name (untuk production)
+
+### Local Development
+
+```bash
+git clone
+cd sibedas-pbg-web
+./scripts/setup-local.sh
+# Access: http://localhost:8000
```
-- Create Supervisor Config
+### Production Deployment
-```
-sudo nano /etc/supervisor/conf.d/laravel-worker.conf
+```bash
+# 1. Setup environment
+cp env.production.example .env
+nano .env
-[program:laravel-worker]
-process_name=%(program_name)s_%(process_num)02d
-command=php /home/arifal/development/sibedas-pbg-web/artisan queue:work --queue=default --timeout=82800 --tries=1
-autostart=true
-autorestart=true
-numprocs=1
-redirect_stderr=true
-stdout_logfile=/home/arifal/development/sibedas-pbg-web/storage/logs/worker.log
-stopasgroup=true
-killasgroup=true
+# 2. Deploy with SSL (Recommended)
+./scripts/setup-reverse-proxy.sh setup
+
+# 3. Check status
+./scripts/setup-reverse-proxy.sh status
+# Access: https://yourdomain.com
```
-- Reload Supervisor
+## 🏗️ Architecture
+
+### Local Development
```
-sudo supervisorctl reread
-sudo supervisorctl update
-sudo supervisorctl start laravel-worker
-sudo supervisorctl restart laravel-worker
-sudo supervisorctl status
+Browser → Port 8000 → Nginx → PHP-FPM → MariaDB
```
-# How to running
-
-- Install composer package
+### Production dengan Reverse Proxy
```
-composer install
+Internet → Reverse Proxy (80/443) → Internal Nginx → PHP-FPM → MariaDB
```
-- Install npm package
+## 🔧 Configuration
-```
-npm install && npm run build
+### Environment Variables
+
+```bash
+# Domain & SSL
+DOMAIN=sibedas.yourdomain.com
+EMAIL=admin@yourdomain.com
+SSL_TYPE=self-signed # atau letsencrypt
+
+# Database
+DB_PASSWORD=your_secure_password
+MYSQL_ROOT_PASSWORD=your_root_password
+
+# Laravel
+APP_KEY=base64:your_app_key_here
+APP_URL=https://sibedas.yourdomain.com
```
-- Create symlinks storage
+## 🚀 Production Deployment Steps
-```
-php artisan storage:link
+### 1. Server Preparation
+
+```bash
+# Install Docker & Docker Compose
+curl -fsSL https://get.docker.com -o get-docker.sh
+sudo sh get-docker.sh
+sudo usermod -aG docker $USER
+
+# 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
```
-- Running migration
+### 2. Clone & Setup
-```
-php artisan migrate
+```bash
+git clone
+cd sibedas-pbg-web
+chmod +x scripts/*.sh
+cp env.production.example .env
+nano .env
```
-- Running seeder
+### 3. Deploy
-```
-php artisan db:seed
+```bash
+# Full deployment with SSL
+./scripts/setup-reverse-proxy.sh setup
+
+# Or step by step
+./scripts/deploy-production.sh deploy
+./scripts/setup-ssl.sh letsencrypt
```
-- Create view table
-- excute all sql queries on folder database/view_query
+### 4. Verify
-# Add ENV variable
-
-- API_KEY_GOOGLE
-
-```
-Get api key from google developer console for and turn on spreadsheet api or feaature for google sheet
+```bash
+docker-compose ps
+./scripts/setup-reverse-proxy.sh status
+curl -f http://localhost/health-check
```
-- SPREAD_SHEET_ID
+## 📊 Monitoring
-```
-Get spreadsheet id from google sheet link
+```bash
+# Check status
+./scripts/setup-reverse-proxy.sh status
+
+# View logs
+docker-compose logs [service]
+
+# Check SSL certificate
+./scripts/setup-ssl.sh check
```
-- OPENAI_API_KEY
+## 🛠️ Common Commands
-```
-Get OpenAI API key from chatgpt subscription
+```bash
+# Start services
+docker-compose up -d
+
+# Stop services
+docker-compose down
+
+# Restart services
+docker-compose restart
+
+# Execute Laravel commands
+docker-compose exec app php artisan [command]
+
+# Backup database
+docker exec sibedas_db mysqldump -u root -p sibedas > backup.sql
```
-- ENV
+## 📁 Scripts
-```
+### Essential Scripts
-API_KEY_GOOGLE="xxxxx"
-SPREAD_SHEET_ID="xxxxx"
-OPENAI_API_KEY="xxxxx"
+- `scripts/setup-reverse-proxy.sh` - Setup lengkap reverse proxy dan SSL
+- `scripts/deploy-production.sh` - Deployment production
+- `scripts/setup-ssl.sh` - Setup SSL certificates
-```
+### Optional Scripts
-# Technology version
+- `scripts/setup-local.sh` - Setup local development
+- `scripts/import-sibedas-database.sh` - Manual database import
-- php 8.3
-- Laravel 11
-- node v22.13.0
-- npm 10.9.2
-- mariadb Ver 15.1 Distrib 10.6.18-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper
-- Ubuntu 24.04
+## 📚 Documentation
+
+Untuk dokumentasi lengkap, lihat [docs/README.md](docs/README.md)
+
+## 🆘 Support
+
+1. Check logs: `docker-compose logs [service]`
+2. Check status: `./scripts/setup-reverse-proxy.sh status`
+3. Restart services: `docker-compose restart`
+4. Review documentation di folder `docs/`
diff --git a/app/Console/Commands/SyncGoogleSheetData.php b/app/Console/Commands/SyncGoogleSheetData.php
index 5d618fd..22e7792 100644
--- a/app/Console/Commands/SyncGoogleSheetData.php
+++ b/app/Console/Commands/SyncGoogleSheetData.php
@@ -54,10 +54,17 @@ class SyncGoogleSheetData extends Command
$result = $service->sync_leader_data();
$this->info('✅ Leader data synchronized successfully!');
$this->table(['Section', 'Total', 'Nominal'], collect($result)->map(function($item, $key) {
+ // Convert nominal to numeric before formatting
+ $nominal = $item['nominal'] ?? 0;
+ if (is_string($nominal)) {
+ // Remove dots and convert to float
+ $nominal = (float) str_replace('.', '', $nominal);
+ }
+
return [
$key,
$item['total'] ?? 'N/A',
- number_format($item['nominal'] ?? 0, 0, ',', '.')
+ number_format((float) $nominal, 0, ',', '.')
];
})->toArray());
break;
diff --git a/docker-compose.local.yml b/docker-compose.local.yml
index d92512b..efd135b 100644
--- a/docker-compose.local.yml
+++ b/docker-compose.local.yml
@@ -24,7 +24,7 @@ services:
depends_on:
- db
networks:
- - sibedas_net
+ - sibedas_network_local
# Add user mapping for permission compatibility
user: "1000:1000"
@@ -40,7 +40,7 @@ services:
depends_on:
- app
networks:
- - sibedas_net
+ - sibedas_network_local
db:
image: mariadb:10.6
@@ -54,10 +54,10 @@ services:
ports:
- "3306:3306"
volumes:
- - dbdata_local:/var/lib/mysql
+ - sibedas_dbdata_local:/var/lib/mysql
- ./sibedas.sql:/docker-entrypoint-initdb.d/sibedas.sql
networks:
- - sibedas_net
+ - sibedas_network_local
vite:
build:
@@ -74,11 +74,11 @@ services:
ports:
- "5173:5173"
networks:
- - sibedas_net
+ - sibedas_network_local
volumes:
- dbdata_local:
+ sibedas_dbdata_local:
networks:
- sibedas_net:
+ sibedas_network_local:
driver: bridge
diff --git a/docker-compose.yml b/docker-compose.yml
index 2d02000..b65d0fd 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,4 +1,5 @@
services:
+ # Sibedas Application Container (Internal)
app:
build:
context: .
@@ -7,57 +8,214 @@ services:
container_name: sibedas_app
restart: unless-stopped
environment:
- APP_ENV: production
- APP_DEBUG: false
- APP_URL: ${APP_URL:-http://localhost:8000}
- VITE_APP_URL: ${VITE_APP_URL:-http://localhost:8000}
- DB_CONNECTION: mariadb
+ APP_ENV: ${APP_ENV:-production}
+ APP_DEBUG: ${APP_DEBUG:-false}
+ APP_KEY: ${APP_KEY}
+ APP_URL: ${APP_URL:-https://sibedas.yourdomain.com}
+ VITE_APP_URL: ${VITE_APP_URL:-https://sibedas.yourdomain.com}
+
+ # Database Configuration
+ DB_CONNECTION: ${DB_CONNECTION:-mariadb}
DB_HOST: db
DB_PORT: 3306
DB_DATABASE: ${DB_DATABASE:-sibedas}
- DB_USERNAME: ${DB_USERNAME:-root}
- DB_PASSWORD: ${DB_PASSWORD:-root}
- volumes:
- - .:/var/www
- depends_on:
- - db
- networks:
- - sibedas_net
+ DB_USERNAME: ${DB_USERNAME:-sibedas_user}
+ DB_PASSWORD: ${DB_PASSWORD}
- nginx:
+ # Cache Configuration (using database)
+ CACHE_DRIVER: ${CACHE_DRIVER:-database}
+
+ # Session Configuration (using database)
+ SESSION_DRIVER: ${SESSION_DRIVER:-database}
+ SESSION_LIFETIME: ${SESSION_LIFETIME:-120}
+
+ # Queue Configuration (using database)
+ QUEUE_CONNECTION: ${QUEUE_CONNECTION:-database}
+
+ # Mail Configuration
+ MAIL_MAILER: ${MAIL_MAILER:-smtp}
+ MAIL_HOST: ${MAIL_HOST}
+ MAIL_PORT: ${MAIL_PORT:-587}
+ MAIL_USERNAME: ${MAIL_USERNAME}
+ MAIL_PASSWORD: ${MAIL_PASSWORD}
+ MAIL_ENCRYPTION: ${MAIL_ENCRYPTION:-tls}
+ MAIL_FROM_ADDRESS: ${MAIL_FROM_ADDRESS}
+ MAIL_FROM_NAME: ${MAIL_FROM_NAME:-"Sibedas"}
+
+ # Google Sheets API
+ SPREAD_SHEET_ID: ${SPREAD_SHEET_ID}
+ volumes:
+ # Only mount specific directories for production security
+ - sibedas_app_storage:/var/www/storage
+ - sibedas_app_bootstrap_cache:/var/www/bootstrap/cache
+ - ./public:/var/www/public:ro
+ - ./docker/supervisor:/etc/supervisor/conf.d:ro
+ depends_on:
+ db:
+ condition: service_healthy
+ networks:
+ - sibedas_network
+ healthcheck:
+ test: ["CMD", "php", "-v"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ deploy:
+ resources:
+ limits:
+ memory: 1G
+ cpus: "1.0"
+ reservations:
+ memory: 512M
+ cpus: "0.5"
+ # Use Supervisor for queue and scheduler
+ command:
+ ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
+
+ # Internal Nginx for Sibedas App
+ nginx-internal:
image: nginx:alpine
- container_name: sibedas_nginx
+ container_name: sibedas_nginx_internal
+ restart: unless-stopped
+ volumes:
+ - ./public:/var/www/public:ro
+ - ./docker/nginx/conf.d/sibedas-internal.conf:/etc/nginx/conf.d/default.conf:ro
+ - sibedas_nginx_internal_logs:/var/log/nginx
+ depends_on:
+ app:
+ condition: service_healthy
+ networks:
+ - sibedas_network
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "wget",
+ "--quiet",
+ "--tries=1",
+ "--spider",
+ "http://localhost/health-check",
+ ]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 30s
+ deploy:
+ resources:
+ limits:
+ memory: 128M
+ cpus: "0.25"
+
+ # Reverse Proxy Nginx (Main Entry Point)
+ nginx-proxy:
+ build:
+ context: ./docker/nginx
+ dockerfile: Dockerfile
+ container_name: sibedas_nginx_proxy
restart: unless-stopped
ports:
- - "8000:80"
+ - "${NGINX_HTTP_PORT:-80}:80"
+ - "${NGINX_HTTPS_PORT:-443}:443"
+ environment:
+ DOMAIN: ${DOMAIN:-sibedas.yourdomain.com}
+ EMAIL: ${EMAIL:-admin@yourdomain.com}
+ SSL_TYPE: ${SSL_TYPE:-self-signed}
volumes:
- - .:/var/www
- - ./docker/nginx/conf.d/app.conf:/etc/nginx/conf.d/default.conf
+ - sibedas_nginx_proxy_logs:/var/log/nginx
+ - sibedas_ssl_certs:/etc/nginx/ssl
+ - sibedas_letsencrypt:/etc/letsencrypt
depends_on:
- - app
+ nginx-internal:
+ condition: service_healthy
networks:
- - sibedas_net
+ - sibedas_network
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "wget",
+ "--quiet",
+ "--tries=1",
+ "--spider",
+ "http://localhost/health-check",
+ ]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 30s
+ deploy:
+ resources:
+ limits:
+ memory: 256M
+ cpus: "0.5"
db:
image: mariadb:10.6
container_name: sibedas_db
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-root}
+ MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_DATABASE:-sibedas}
- MYSQL_USER: ${DB_USERNAME:-root}
- MYSQL_PASSWORD: ${DB_PASSWORD:-root}
+ MYSQL_USER: ${DB_USERNAME:-sibedas_user}
+ MYSQL_PASSWORD: ${DB_PASSWORD}
+ MYSQL_INNODB_BUFFER_POOL_SIZE: ${MYSQL_INNODB_BUFFER_POOL_SIZE:-1G}
ports:
- - "3306:3306"
+ # Only expose if needed for external access
+ - "${DB_EXTERNAL_PORT:-3306}:3306"
volumes:
- - dbdata:/var/lib/mysql
- - ./sibedas.sql:/docker-entrypoint-initdb.d/sibedas.sql
+ - sibedas_dbdata:/var/lib/mysql
+ - ./sibedas.sql:/docker-entrypoint-initdb.d/sibedas.sql:ro
+ - ./docker/mysql/conf.d:/etc/mysql/conf.d:ro
+ - sibedas_db_logs:/var/log/mysql
networks:
- - sibedas_net
+ - sibedas_network
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "mysqladmin",
+ "ping",
+ "-h",
+ "localhost",
+ "-u",
+ "${DB_USERNAME:-sibedas_user}",
+ "-p${DB_PASSWORD}",
+ ]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ deploy:
+ resources:
+ limits:
+ memory: 2G
+ cpus: "1.0"
+ reservations:
+ memory: 1G
+ cpus: "0.5"
volumes:
- dbdata:
+ sibedas_dbdata:
+ driver: local
+ sibedas_app_storage:
+ driver: local
+ sibedas_app_bootstrap_cache:
+ driver: local
+ sibedas_nginx_internal_logs:
+ driver: local
+ sibedas_nginx_proxy_logs:
+ driver: local
+ sibedas_db_logs:
+ driver: local
+ sibedas_ssl_certs:
+ driver: local
+ sibedas_letsencrypt:
+ driver: local
networks:
- sibedas_net:
+ sibedas_network:
driver: bridge
+ ipam:
+ config:
+ - subnet: 172.20.0.0/16
diff --git a/docker/mysql/conf.d/production.cnf b/docker/mysql/conf.d/production.cnf
new file mode 100644
index 0000000..64f0586
--- /dev/null
+++ b/docker/mysql/conf.d/production.cnf
@@ -0,0 +1,55 @@
+[mysqld]
+# Basic Settings
+default-storage-engine = innodb
+sql-mode = "STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
+max_connections = 200
+max_user_connections = 180
+
+# Character Set
+character-set-server = utf8mb4
+collation-server = utf8mb4_unicode_ci
+
+# InnoDB Settings
+innodb_buffer_pool_size = 1G
+innodb_buffer_pool_instances = 4
+innodb_log_file_size = 256M
+innodb_log_buffer_size = 64M
+innodb_flush_log_at_trx_commit = 2
+innodb_flush_method = O_DIRECT
+innodb_file_per_table = 1
+innodb_open_files = 400
+
+# Query Cache (disabled in MySQL 8.0+, but kept for compatibility)
+query_cache_type = OFF
+query_cache_size = 0
+
+# Temp Tables
+tmp_table_size = 64M
+max_heap_table_size = 64M
+
+# Logging
+slow_query_log = 1
+slow_query_log_file = /var/log/mysql/slow.log
+long_query_time = 2
+log_queries_not_using_indexes = 1
+
+# Binary Logging
+log-bin = mysql-bin
+binlog_format = ROW
+expire_logs_days = 7
+max_binlog_size = 100M
+
+# Safety
+max_allowed_packet = 64M
+bind-address = 0.0.0.0
+
+# Performance Schema
+performance_schema = ON
+performance_schema_max_table_instances = 400
+performance_schema_max_table_handles = 4000
+
+[mysql]
+default-character-set = utf8mb4
+
+[client]
+default-character-set = utf8mb4
\ No newline at end of file
diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile
new file mode 100644
index 0000000..ec1eeac
--- /dev/null
+++ b/docker/nginx/Dockerfile
@@ -0,0 +1,32 @@
+FROM nginx:alpine
+
+# Install required packages
+RUN apk add --no-cache \
+ openssl \
+ certbot \
+ certbot-nginx \
+ bash
+
+# Create SSL directory
+RUN mkdir -p /etc/nginx/ssl
+
+# Copy SSL certificates (if they exist)
+COPY ssl/ /etc/nginx/ssl/
+
+# Copy Nginx configuration
+COPY conf.d/ /etc/nginx/conf.d/
+
+# Create log directories
+RUN mkdir -p /var/log/nginx
+
+# Copy SSL setup script
+COPY ssl-setup.sh /usr/local/bin/ssl-setup.sh
+RUN chmod +x /usr/local/bin/ssl-setup.sh
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
+ CMD wget --quiet --tries=1 --spider http://localhost/health-check || exit 1
+
+EXPOSE 80 443
+
+CMD ["nginx", "-g", "daemon off;"]
\ No newline at end of file
diff --git a/docker/nginx/conf.d/production.conf b/docker/nginx/conf.d/production.conf
new file mode 100644
index 0000000..11c2f3a
--- /dev/null
+++ b/docker/nginx/conf.d/production.conf
@@ -0,0 +1,113 @@
+server {
+ listen 80;
+ server_name yourdomain.com www.yourdomain.com;
+
+ # Redirect HTTP to HTTPS
+ return 301 https://$server_name$request_uri;
+}
+
+server {
+ listen 443 ssl http2;
+ server_name yourdomain.com www.yourdomain.com;
+
+ root /var/www/public;
+ index index.php index.html index.htm;
+
+ # SSL Configuration
+ ssl_certificate /etc/nginx/ssl/certificate.crt;
+ ssl_certificate_key /etc/nginx/ssl/private.key;
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
+ ssl_prefer_server_ciphers off;
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_timeout 10m;
+
+ # 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;
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+ # Gzip Compression
+ gzip on;
+ gzip_vary on;
+ gzip_min_length 1024;
+ gzip_proxied expired no-cache no-store private auth;
+ gzip_types
+ text/plain
+ text/css
+ text/xml
+ text/javascript
+ application/x-javascript
+ application/xml+rss
+ application/javascript
+ application/json
+ application/xml
+ image/svg+xml;
+
+ # Client Max Body Size
+ client_max_body_size 100M;
+
+ # Health check endpoint
+ location /health-check {
+ access_log off;
+ return 200 "healthy\n";
+ add_header Content-Type text/plain;
+ }
+
+ # Handle static files
+ location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
+ expires 1y;
+ add_header Cache-Control "public, immutable";
+ access_log off;
+ try_files $uri =404;
+ }
+
+ # Deny access to sensitive files
+ location ~ /\. {
+ deny all;
+ access_log off;
+ log_not_found off;
+ }
+
+ location ~ ^/(\.env|\.git|composer\.(json|lock)|package\.(json|lock)|webpack\.(mix\.js|config\.js)|.*\.md)$ {
+ deny all;
+ access_log off;
+ log_not_found off;
+ }
+
+ # Laravel-specific rules
+ location / {
+ try_files $uri $uri/ /index.php?$query_string;
+ }
+
+ location ~ \.php$ {
+ fastcgi_pass app:9000;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
+ include fastcgi_params;
+
+ # Production optimizations
+ fastcgi_buffer_size 128k;
+ fastcgi_buffers 4 256k;
+ fastcgi_busy_buffers_size 256k;
+ fastcgi_temp_file_write_size 256k;
+ fastcgi_connect_timeout 60s;
+ fastcgi_send_timeout 60s;
+ fastcgi_read_timeout 60s;
+ }
+
+ # Error pages
+ error_page 404 /index.php;
+ error_page 500 502 503 504 /50x.html;
+
+ location = /50x.html {
+ root /usr/share/nginx/html;
+ }
+
+ # Logging
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/error.log warn;
+}
\ No newline at end of file
diff --git a/docker/nginx/conf.d/reverse-proxy.conf b/docker/nginx/conf.d/reverse-proxy.conf
new file mode 100644
index 0000000..4c307a4
--- /dev/null
+++ b/docker/nginx/conf.d/reverse-proxy.conf
@@ -0,0 +1,137 @@
+# Reverse Proxy Configuration for Sibedas PBG Web
+# This configuration handles SSL termination and routes traffic to the appropriate containers
+
+# Upstream for Sibedas application
+upstream sibedas_backend {
+ server sibedas_app:9000;
+ keepalive 32;
+}
+
+# Rate limiting
+limit_req_zone $binary_remote_addr zone=sibedas_limit:10m rate=10r/s;
+
+# HTTP to HTTPS redirect
+server {
+ listen 80;
+ server_name _;
+
+ # Redirect all HTTP traffic to HTTPS
+ return 301 https://$host$request_uri;
+}
+
+# HTTPS Server for Sibedas
+server {
+ listen 443 ssl http2;
+ server_name sibedas.yourdomain.com; # Change this to your domain
+
+ # SSL Configuration
+ ssl_certificate /etc/nginx/ssl/sibedas.crt;
+ ssl_certificate_key /etc/nginx/ssl/sibedas.key;
+
+ # SSL Security Settings
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-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 DENY 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;
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none';" always;
+
+ # Rate limiting
+ limit_req zone=sibedas_limit burst=20 nodelay;
+
+ # Client max body size
+ client_max_body_size 100M;
+
+ # 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;
+
+ # Root directory
+ root /var/www/public;
+ index index.php index.html index.htm;
+
+ # Handle Laravel routes
+ location / {
+ try_files $uri $uri/ /index.php?$query_string;
+ }
+
+ # PHP-FPM configuration
+ location ~ \.php$ {
+ fastcgi_pass sibedas_backend;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
+ include fastcgi_params;
+
+ # FastCGI optimizations
+ fastcgi_buffers 16 16k;
+ fastcgi_buffer_size 32k;
+ fastcgi_connect_timeout 300;
+ fastcgi_send_timeout 300;
+ fastcgi_read_timeout 300;
+ }
+
+ # Static files caching
+ location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt)$ {
+ expires 1y;
+ add_header Cache-Control "public, immutable";
+ access_log off;
+ }
+
+ # Deny access to sensitive files
+ location ~ /\. {
+ deny all;
+ }
+
+ location ~ /\.ht {
+ deny all;
+ }
+
+ # Health check endpoint
+ location /health-check {
+ access_log off;
+ return 200 "healthy\n";
+ add_header Content-Type text/plain;
+ }
+
+ # Logging
+ access_log /var/log/nginx/sibedas_access.log;
+ error_log /var/log/nginx/sibedas_error.log;
+}
+
+# Additional server blocks for other applications can be added here
+# Example:
+# server {
+# listen 443 ssl http2;
+# server_name other-app.yourdomain.com;
+#
+# ssl_certificate /etc/nginx/ssl/other-app.crt;
+# ssl_certificate_key /etc/nginx/ssl/other-app.key;
+#
+# location / {
+# proxy_pass http://other_app_container:port;
+# 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;
+# }
+# }
\ No newline at end of file
diff --git a/docker/nginx/conf.d/sibedas-internal.conf b/docker/nginx/conf.d/sibedas-internal.conf
new file mode 100644
index 0000000..2ab63bc
--- /dev/null
+++ b/docker/nginx/conf.d/sibedas-internal.conf
@@ -0,0 +1,58 @@
+# Internal Nginx Configuration for Sibedas PBG Web
+# This configuration is for the internal container, accessed by reverse proxy
+
+server {
+ listen 80;
+ server_name localhost;
+
+ # Root directory
+ root /var/www/public;
+ index index.php index.html index.htm;
+
+ # Handle Laravel routes
+ location / {
+ try_files $uri $uri/ /index.php?$query_string;
+ }
+
+ # PHP-FPM configuration
+ location ~ \.php$ {
+ fastcgi_pass 127.0.0.1:9000;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
+ include fastcgi_params;
+
+ # FastCGI optimizations
+ fastcgi_buffers 16 16k;
+ fastcgi_buffer_size 32k;
+ fastcgi_connect_timeout 300;
+ fastcgi_send_timeout 300;
+ fastcgi_read_timeout 300;
+ }
+
+ # Static files caching
+ location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt)$ {
+ expires 1y;
+ add_header Cache-Control "public, immutable";
+ access_log off;
+ }
+
+ # Deny access to sensitive files
+ location ~ /\. {
+ deny all;
+ }
+
+ location ~ /\.ht {
+ deny all;
+ }
+
+ # Health check endpoint
+ location /health-check {
+ access_log off;
+ return 200 "healthy\n";
+ add_header Content-Type text/plain;
+ }
+
+ # Logging
+ access_log /var/log/nginx/sibedas_internal_access.log;
+ error_log /var/log/nginx/sibedas_internal_error.log;
+}
\ No newline at end of file
diff --git a/docker/nginx/ssl-setup.sh b/docker/nginx/ssl-setup.sh
new file mode 100644
index 0000000..344c35c
--- /dev/null
+++ b/docker/nginx/ssl-setup.sh
@@ -0,0 +1,123 @@
+#!/bin/bash
+
+# SSL Setup Script for Sibedas PBG Web
+# This script handles SSL certificate generation and renewal
+
+set -e
+
+DOMAIN="${DOMAIN:-sibedas.yourdomain.com}"
+EMAIL="${EMAIL:-admin@yourdomain.com}"
+SSL_DIR="/etc/nginx/ssl"
+CERT_FILE="$SSL_DIR/sibedas.crt"
+KEY_FILE="$SSL_DIR/sibedas.key"
+
+# Function to generate self-signed certificate
+generate_self_signed() {
+ echo "Generating self-signed SSL certificate for $DOMAIN..."
+
+ # Create SSL directory if it doesn't exist
+ mkdir -p "$SSL_DIR"
+
+ # Generate self-signed certificate
+ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
+ -keyout "$KEY_FILE" \
+ -out "$CERT_FILE" \
+ -subj "/C=ID/ST=Jakarta/L=Jakarta/O=Sibedas/OU=IT/CN=$DOMAIN/emailAddress=$EMAIL"
+
+ echo "Self-signed certificate generated successfully!"
+}
+
+# Function to setup Let's Encrypt certificate
+setup_letsencrypt() {
+ echo "Setting up Let's Encrypt certificate for $DOMAIN..."
+
+ # Check if certbot is available
+ if ! command -v certbot &> /dev/null; then
+ echo "Certbot not found. Installing..."
+ apk add --no-cache certbot certbot-nginx
+ fi
+
+ # Stop nginx temporarily
+ nginx -s stop || true
+
+ # Get certificate
+ certbot certonly --standalone \
+ --email "$EMAIL" \
+ --agree-tos \
+ --no-eff-email \
+ -d "$DOMAIN"
+
+ # Copy certificates to nginx ssl directory
+ cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem "$CERT_FILE"
+ cp /etc/letsencrypt/live/$DOMAIN/privkey.pem "$KEY_FILE"
+
+ # Set proper permissions
+ chmod 644 "$CERT_FILE"
+ chmod 600 "$KEY_FILE"
+
+ # Start nginx
+ nginx
+
+ echo "Let's Encrypt certificate setup completed!"
+}
+
+# Function to renew Let's Encrypt certificate
+renew_certificate() {
+ echo "Renewing Let's Encrypt certificate..."
+
+ certbot renew --quiet
+
+ # Copy renewed certificates
+ cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem "$CERT_FILE"
+ cp /etc/letsencrypt/live/$DOMAIN/privkey.pem "$KEY_FILE"
+
+ # Reload nginx
+ nginx -s reload
+
+ echo "Certificate renewal completed!"
+}
+
+# Function to check certificate validity
+check_certificate() {
+ if [ -f "$CERT_FILE" ] && [ -f "$KEY_FILE" ]; then
+ echo "Certificate files exist."
+ echo "Certificate details:"
+ openssl x509 -in "$CERT_FILE" -text -noout | grep -E "(Subject:|Not Before|Not After)"
+ return 0
+ else
+ echo "Certificate files not found."
+ return 1
+ fi
+}
+
+# Main script logic
+case "${1:-setup}" in
+ "setup")
+ if [ "$SSL_TYPE" = "letsencrypt" ]; then
+ setup_letsencrypt
+ else
+ generate_self_signed
+ fi
+ ;;
+ "renew")
+ renew_certificate
+ ;;
+ "check")
+ check_certificate
+ ;;
+ "self-signed")
+ generate_self_signed
+ ;;
+ "letsencrypt")
+ setup_letsencrypt
+ ;;
+ *)
+ echo "Usage: $0 {setup|renew|check|self-signed|letsencrypt}"
+ echo ""
+ echo "Environment variables:"
+ echo " DOMAIN: Domain name (default: sibedas.yourdomain.com)"
+ echo " EMAIL: Email address for Let's Encrypt (default: admin@yourdomain.com)"
+ echo " SSL_TYPE: Type of SSL (letsencrypt or self-signed, default: self-signed)"
+ exit 1
+ ;;
+esac
\ No newline at end of file
diff --git a/docker/nginx/ssl/.gitignore b/docker/nginx/ssl/.gitignore
new file mode 100644
index 0000000..7a47ea1
--- /dev/null
+++ b/docker/nginx/ssl/.gitignore
@@ -0,0 +1,14 @@
+# SSL Certificates - Do not commit these files
+*.crt
+*.key
+*.pem
+*.p12
+*.pfx
+
+# Let's Encrypt
+letsencrypt/
+live/
+archive/
+
+# Keep this directory in git but ignore certificate files
+!.gitignore
\ No newline at end of file
diff --git a/docker/supervisor/laravel-production.conf b/docker/supervisor/laravel-production.conf
index b290c89..b52df8e 100644
--- a/docker/supervisor/laravel-production.conf
+++ b/docker/supervisor/laravel-production.conf
@@ -6,13 +6,13 @@ pidfile=/var/run/supervisord.pid
[program:laravel-queue-worker]
process_name=%(program_name)s_%(process_num)02d
-command=php /var/www/pupr/artisan queue:work --queue=default --timeout=82800 --tries=3 --memory=512 --sleep=3
-directory=/var/www/pupr
+command=php /var/www/artisan queue:work --queue=default --timeout=82800 --tries=3 --memory=512 --sleep=3
+directory=/var/www
autostart=true
autorestart=true
numprocs=2
redirect_stderr=true
-stdout_logfile=/var/www/pupr/storage/logs/queue-worker.log
+stdout_logfile=/var/www/storage/logs/queue-worker.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
stopasgroup=true
@@ -22,13 +22,13 @@ priority=10
[program:laravel-scheduler]
process_name=%(program_name)s_%(process_num)02d
-command=php /var/www/pupr/artisan schedule:work
-directory=/var/www/pupr
+command=php /var/www/artisan schedule:work
+directory=/var/www
autostart=true
autorestart=true
numprocs=1
redirect_stderr=true
-stdout_logfile=/var/www/pupr/storage/logs/scheduler.log
+stdout_logfile=/var/www/storage/logs/scheduler.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
stopasgroup=true
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..4adbdb0
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,449 @@
+# Sibedas PBG Web - Documentation
+
+Dokumentasi lengkap untuk setup dan penggunaan aplikasi Sibedas PBG Web.
+
+## 📋 Table of Contents
+
+1. [Quick Start](#-quick-start)
+2. [Architecture](#-architecture)
+3. [Environment Setup](#-environment-setup)
+4. [Production Deployment](#-production-deployment)
+5. [SSL Configuration](#-ssl-configuration)
+6. [Monitoring](#-monitoring)
+7. [Troubleshooting](#-troubleshooting)
+
+## 🚀 Quick Start
+
+### Prerequisites
+
+- Docker & Docker Compose
+- Domain name (untuk production)
+- Port 80 dan 443 terbuka (untuk Let's Encrypt)
+
+### Local Development
+
+```bash
+# Clone repository
+git clone
+cd sibedas-pbg-web
+
+# Setup local environment
+./scripts/setup-local.sh
+```
+
+### Production Deployment
+
+```bash
+# Copy environment file
+cp env.production.example .env
+
+# Edit environment variables
+nano .env
+
+# Deploy dengan reverse proxy dan SSL
+./scripts/setup-reverse-proxy.sh setup
+```
+
+## 🏗️ Architecture
+
+### Local Development
+
+```
+Browser → Port 8000 → Nginx → PHP-FPM → MariaDB
+```
+
+### Production dengan Reverse Proxy
+
+```
+Internet → Reverse Proxy (80/443) → Internal Nginx → PHP-FPM → MariaDB
+```
+
+### Components
+
+- **Reverse Proxy Nginx**: Entry point, SSL termination, routing
+- **Internal Nginx**: Serves Sibedas application
+- **Application Container**: PHP-FPM with Supervisor (queue & scheduler)
+- **Database Container**: MariaDB with backup import
+
+## ⚙️ Environment Setup
+
+### Required Variables
+
+```bash
+# Domain & SSL
+DOMAIN=sibedas.yourdomain.com
+EMAIL=admin@yourdomain.com
+SSL_TYPE=self-signed # atau letsencrypt
+
+# Database
+DB_PASSWORD=your_secure_password
+MYSQL_ROOT_PASSWORD=your_root_password
+
+# Laravel
+APP_KEY=base64:your_app_key_here
+APP_URL=https://sibedas.yourdomain.com
+```
+
+### Generate App Key
+
+```bash
+docker-compose exec app php artisan key:generate
+```
+
+## 🚀 Production Deployment
+
+### Step-by-Step Production Deployment
+
+#### 1. **Server Preparation**
+
+```bash
+# Update system
+sudo apt update && sudo apt upgrade -y
+
+# Install Docker & Docker Compose
+curl -fsSL https://get.docker.com -o get-docker.sh
+sudo sh get-docker.sh
+sudo usermod -aG docker $USER
+
+# 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
+
+# Logout and login again for group changes
+exit
+# SSH back to server
+```
+
+#### 2. **Clone Repository**
+
+```bash
+# Clone project
+git clone
+cd sibedas-pbg-web
+
+# Set proper permissions
+chmod +x scripts/*.sh
+```
+
+#### 3. **Environment Configuration**
+
+```bash
+# Copy environment template
+cp env.production.example .env
+
+# Edit environment variables
+nano .env
+```
+
+**Required Environment Variables:**
+
+```bash
+# Domain & SSL
+DOMAIN=sibedas.yourdomain.com
+EMAIL=admin@yourdomain.com
+SSL_TYPE=letsencrypt # atau self-signed untuk testing
+
+# Database
+DB_DATABASE=sibedas
+DB_USERNAME=sibedas_user
+DB_PASSWORD=your_secure_database_password
+MYSQL_ROOT_PASSWORD=your_secure_root_password
+
+# Laravel
+APP_NAME="Sibedas PBG Web"
+APP_ENV=production
+APP_DEBUG=false
+APP_KEY=base64:your_app_key_here
+APP_URL=https://sibedas.yourdomain.com
+VITE_APP_URL=https://sibedas.yourdomain.com
+
+# Mail Configuration
+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=your_email@gmail.com
+MAIL_FROM_NAME="Sibedas PBG Web"
+
+# Google Sheets API
+SPREAD_SHEET_ID=your_google_sheets_id_here
+```
+
+#### 4. **Generate Application Key**
+
+```bash
+# Generate Laravel app key
+php artisan key:generate --show
+# Copy the generated key to .env file
+```
+
+#### 5. **Deploy Application**
+
+```bash
+# Option A: Full deployment with SSL (Recommended)
+./scripts/setup-reverse-proxy.sh setup
+
+# Option B: Deploy without SSL first
+./scripts/deploy-production.sh deploy
+```
+
+#### 6. **SSL Setup (if not done in step 5)**
+
+```bash
+# For Let's Encrypt (Production)
+DOMAIN=yourdomain.com EMAIL=admin@yourdomain.com ./scripts/setup-ssl.sh letsencrypt
+
+# For Self-Signed (Testing)
+./scripts/setup-ssl.sh self-signed
+```
+
+#### 7. **Verify Deployment**
+
+```bash
+# Check container status
+docker-compose ps
+
+# Check application health
+curl -f http://localhost/health-check
+
+# Check SSL certificate
+./scripts/setup-ssl.sh check
+
+# View logs
+docker-compose logs nginx-proxy
+docker-compose logs app
+```
+
+### Scripts yang Diperlukan
+
+#### **Essential Scripts (Wajib)**
+
+- `scripts/setup-reverse-proxy.sh` - Setup lengkap reverse proxy dan SSL
+- `scripts/deploy-production.sh` - Deployment production
+- `scripts/setup-ssl.sh` - Setup SSL certificates
+
+#### **Optional Scripts**
+
+- `scripts/setup-local.sh` - Setup local development
+- `scripts/import-sibedas-database.sh` - Manual database import (otomatis via docker-compose)
+
+#### **Scripts yang Tidak Diperlukan**
+
+- `scripts/build-and-zip.sh` - Tidak diperlukan karena menggunakan Docker build
+
+### Deployment Commands Summary
+
+```bash
+# 1. Setup environment
+cp env.production.example .env
+nano .env
+
+# 2. Deploy with SSL (Recommended)
+./scripts/setup-reverse-proxy.sh setup
+
+# 3. Or deploy step by step
+./scripts/deploy-production.sh deploy
+./scripts/setup-ssl.sh letsencrypt
+
+# 4. Check status
+./scripts/setup-reverse-proxy.sh status
+```
+
+## 🔒 SSL Configuration
+
+### Self-Signed Certificate
+
+```bash
+SSL_TYPE=self-signed ./scripts/setup-reverse-proxy.sh setup
+```
+
+### Let's Encrypt Certificate
+
+```bash
+DOMAIN=myapp.com EMAIL=admin@myapp.com SSL_TYPE=letsencrypt ./scripts/setup-reverse-proxy.sh setup
+```
+
+### SSL Management
+
+```bash
+# Check certificate
+./scripts/setup-ssl.sh check
+
+# Renew certificate
+./scripts/setup-ssl.sh renew
+```
+
+## 📊 Monitoring
+
+### Container Status
+
+```bash
+# Check all containers
+docker-compose ps
+
+# Check specific service
+docker-compose ps app
+```
+
+### Logs
+
+```bash
+# Application logs
+docker-compose logs app
+
+# Reverse proxy logs
+docker-compose logs nginx-proxy
+
+# Database logs
+docker-compose logs db
+
+# Follow logs
+docker-compose logs -f nginx-proxy
+```
+
+### Health Checks
+
+```bash
+# Application health
+curl -f http://localhost/health-check
+
+# SSL certificate
+./scripts/setup-ssl.sh check
+```
+
+## 🛠️ Troubleshooting
+
+### SSL Issues
+
+```bash
+# Check certificate files
+docker exec sibedas_nginx_proxy ls -la /etc/nginx/ssl/
+
+# Test SSL connection
+openssl s_client -connect yourdomain.com:443
+
+# Check nginx config
+docker exec sibedas_nginx_proxy nginx -t
+```
+
+### Container Issues
+
+```bash
+# Restart services
+docker-compose restart
+
+# Check network
+docker network ls
+
+# Check volumes
+docker volume ls
+```
+
+### Database Issues
+
+```bash
+# Import database manually
+./scripts/import-sibedas-database.sh
+
+# Check database connection
+docker exec sibedas_app php artisan db:monitor
+```
+
+### Performance Issues
+
+```bash
+# Check resource usage
+docker stats
+
+# Check nginx access logs
+docker exec sibedas_nginx_proxy tail -f /var/log/nginx/sibedas_access.log
+```
+
+## 🔧 Maintenance
+
+### Backup
+
+```bash
+# Database backup
+docker exec sibedas_db mysqldump -u root -p sibedas > backup.sql
+
+# Volume backup
+docker run --rm -v sibedas_app_storage:/data -v $(pwd):/backup alpine tar czf /backup/storage.tar.gz -C /data .
+```
+
+### Update Application
+
+```bash
+# Pull latest changes
+git pull
+
+# Rebuild and restart
+docker-compose up -d --build
+```
+
+### SSL Certificate Renewal
+
+```bash
+# Manual renewal
+./scripts/setup-ssl.sh renew
+
+# Automatic renewal (cron)
+0 12 * * * /path/to/sibedas-pbg-web/scripts/setup-ssl.sh renew
+```
+
+## 📁 Project Structure
+
+```
+sibedas-pbg-web/
+├── docker/ # Docker configurations
+│ ├── nginx/ # Nginx configs
+│ ├── mysql/ # MySQL configs
+│ └── supervisor/ # Supervisor configs
+├── scripts/ # Deployment scripts
+│ ├── setup-local.sh # Local development
+│ ├── setup-reverse-proxy.sh # Reverse proxy setup
+│ ├── deploy-production.sh # Production deployment
+│ ├── setup-ssl.sh # SSL setup
+│ └── import-sibedas-database.sh # Database import
+├── docs/ # Documentation
+├── docker-compose.yml # Production compose
+├── docker-compose.local.yml # Local development compose
+└── README.md # Main README
+```
+
+## 🆘 Support
+
+### Common Commands
+
+```bash
+# Start services
+docker-compose up -d
+
+# Stop services
+docker-compose down
+
+# View logs
+docker-compose logs [service]
+
+# Execute commands
+docker-compose exec app php artisan [command]
+
+# Check status
+./scripts/setup-reverse-proxy.sh status
+```
+
+### Getting Help
+
+1. Check logs: `docker-compose logs [service]`
+2. Check status: `./scripts/setup-reverse-proxy.sh status`
+3. Restart services: `docker-compose restart`
+4. Review this documentation
+
+## 📚 Additional Resources
+
+- [Docker Documentation](https://docs.docker.com/)
+- [Nginx Documentation](https://nginx.org/en/docs/)
+- [Let's Encrypt Documentation](https://letsencrypt.org/docs/)
+- [Laravel Documentation](https://laravel.com/docs/)
diff --git a/env.production.example b/env.production.example
new file mode 100644
index 0000000..145ead9
--- /dev/null
+++ b/env.production.example
@@ -0,0 +1,154 @@
+# Production Environment Configuration for Sibedas PBG Web
+# Copy this file to .env and update the values
+
+# =============================================================================
+# REVERSE PROXY & SSL CONFIGURATION
+# =============================================================================
+
+# Domain configuration
+DOMAIN=sibedas.yourdomain.com
+EMAIL=admin@yourdomain.com
+SSL_TYPE=self-signed # Options: self-signed, letsencrypt
+
+# Nginx ports (usually 80 and 443)
+NGINX_HTTP_PORT=80
+NGINX_HTTPS_PORT=443
+
+# =============================================================================
+# LARAVEL APPLICATION CONFIGURATION
+# =============================================================================
+
+# Application settings
+APP_NAME="Sibedas PBG Web"
+APP_ENV=production
+APP_DEBUG=false
+APP_KEY=base64:your_app_key_here
+APP_URL=https://sibedas.yourdomain.com
+APP_TIMEZONE=Asia/Jakarta
+
+# Vite configuration
+VITE_APP_URL=https://sibedas.yourdomain.com
+
+# =============================================================================
+# DATABASE CONFIGURATION
+# =============================================================================
+
+# Database connection
+DB_CONNECTION=mariadb
+DB_HOST=db
+DB_PORT=3306
+DB_DATABASE=sibedas
+DB_USERNAME=sibedas_user
+DB_PASSWORD=your_secure_database_password
+
+# MySQL root password
+MYSQL_ROOT_PASSWORD=your_secure_root_password
+
+# MySQL performance tuning
+MYSQL_INNODB_BUFFER_POOL_SIZE=1G
+
+# External database port (optional, for external access)
+DB_EXTERNAL_PORT=3306
+
+# =============================================================================
+# CACHE, SESSION & QUEUE CONFIGURATION
+# =============================================================================
+
+# Cache configuration (using database)
+CACHE_DRIVER=database
+
+# Session configuration (using database)
+SESSION_DRIVER=database
+SESSION_LIFETIME=120
+
+# Queue configuration (using database)
+QUEUE_CONNECTION=database
+
+# =============================================================================
+# MAIL CONFIGURATION
+# =============================================================================
+
+# Mail settings
+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=your_email@gmail.com
+MAIL_FROM_NAME="Sibedas PBG Web"
+
+# =============================================================================
+# GOOGLE SHEETS API CONFIGURATION
+# =============================================================================
+
+# Google Sheets API
+SPREAD_SHEET_ID=your_google_sheets_id_here
+
+# =============================================================================
+# LOGGING CONFIGURATION
+# =============================================================================
+
+# Log settings
+LOG_CHANNEL=stack
+LOG_DEPRECATIONS_CHANNEL=null
+LOG_LEVEL=warning
+
+# =============================================================================
+# SECURITY CONFIGURATION
+# =============================================================================
+
+# Security settings
+SESSION_SECURE_COOKIE=true
+SESSION_SAME_SITE=lax
+
+# =============================================================================
+# PERFORMANCE CONFIGURATION
+# =============================================================================
+
+# Performance settings
+CACHE_TTL=3600
+SESSION_SECURE_COOKIE=true
+
+# =============================================================================
+# BACKUP CONFIGURATION
+# =============================================================================
+
+# Backup settings
+BACKUP_RETENTION_DAYS=30
+BACKUP_PATH=./backups
+
+# =============================================================================
+# MONITORING CONFIGURATION
+# =============================================================================
+
+# Health check settings
+HEALTH_CHECK_ENABLED=true
+HEALTH_CHECK_INTERVAL=30s
+
+# =============================================================================
+# NOTES
+# =============================================================================
+
+# 1. Generate APP_KEY: php artisan key:generate
+# 2. Update DOMAIN and EMAIL for your domain
+# 3. Set secure passwords for database
+# 4. Configure mail settings for notifications
+# 5. Set Google Sheets API credentials
+# 6. For Let's Encrypt: ensure domain points to server and ports 80/443 are open
+
+# =============================================================================
+# DEPLOYMENT COMMANDS
+# =============================================================================
+
+# Setup reverse proxy and SSL:
+# ./setup-reverse-proxy.sh setup
+
+# Setup SSL only:
+# ./setup-reverse-proxy.sh ssl
+
+# Check status:
+# ./setup-reverse-proxy.sh status
+
+# Deploy production:
+# ./scripts/deploy-production.sh deploy
\ No newline at end of file
diff --git a/build-and-zip.sh b/scripts/build-and-zip.sh
similarity index 100%
rename from build-and-zip.sh
rename to scripts/build-and-zip.sh
diff --git a/scripts/deploy-production.sh b/scripts/deploy-production.sh
new file mode 100755
index 0000000..6487bdc
--- /dev/null
+++ b/scripts/deploy-production.sh
@@ -0,0 +1,226 @@
+#!/bin/bash
+
+# Production Deployment Script for Sibedas PBG Web
+# This script deploys the application with reverse proxy and SSL support
+
+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="${DOMAIN:-sibedas.yourdomain.com}"
+EMAIL="${EMAIL:-admin@yourdomain.com}"
+SSL_TYPE="${SSL_TYPE:-self-signed}"
+
+echo -e "${BLUE}=== Production Deployment for Sibedas PBG Web ===${NC}"
+echo -e "Domain: ${GREEN}$DOMAIN${NC}"
+echo -e "Email: ${GREEN}$EMAIL${NC}"
+echo -e "SSL Type: ${GREEN}$SSL_TYPE${NC}"
+echo ""
+
+# Function to check prerequisites
+check_prerequisites() {
+ echo -e "${BLUE}Checking prerequisites...${NC}"
+
+ # Check if Docker is installed
+ if ! command -v docker &> /dev/null; then
+ echo -e "${RED}Error: Docker is not installed${NC}"
+ exit 1
+ fi
+
+ # Check if Docker Compose is installed
+ if ! command -v docker-compose &> /dev/null; then
+ echo -e "${RED}Error: Docker Compose is not installed${NC}"
+ exit 1
+ fi
+
+ # Check if .env file exists
+ if [ ! -f .env ]; then
+ echo -e "${RED}Error: .env file not found${NC}"
+ echo -e "${YELLOW}Please create .env file with required environment variables${NC}"
+ exit 1
+ fi
+
+ echo -e "${GREEN}Prerequisites check passed!${NC}"
+}
+
+# Function to backup existing data
+backup_data() {
+ echo -e "${BLUE}Creating backup of existing data...${NC}"
+
+ BACKUP_DIR="backups/$(date +%Y%m%d_%H%M%S)"
+ mkdir -p "$BACKUP_DIR"
+
+ # Backup database
+ if docker ps | grep -q sibedas_db; then
+ echo -e "${YELLOW}Backing up database...${NC}"
+ docker exec sibedas_db mysqldump -u root -p"${MYSQL_ROOT_PASSWORD:-root}" sibedas > "$BACKUP_DIR/database.sql" || true
+ fi
+
+ # Backup volumes
+ echo -e "${YELLOW}Backing up volumes...${NC}"
+ docker run --rm -v sibedas_app_storage:/data -v "$(pwd)/$BACKUP_DIR":/backup alpine tar czf /backup/app_storage.tar.gz -C /data . || true
+ docker run --rm -v sibedas_dbdata:/data -v "$(pwd)/$BACKUP_DIR":/backup alpine tar czf /backup/dbdata.tar.gz -C /data . || true
+
+ echo -e "${GREEN}Backup created in $BACKUP_DIR${NC}"
+}
+
+# Function to stop existing containers
+stop_containers() {
+ echo -e "${BLUE}Stopping existing containers...${NC}"
+
+ docker-compose down --remove-orphans || true
+
+ echo -e "${GREEN}Containers stopped!${NC}"
+}
+
+# Function to build and start containers
+deploy_containers() {
+ echo -e "${BLUE}Building and starting containers...${NC}"
+
+ # Build images
+ echo -e "${YELLOW}Building Docker images...${NC}"
+ docker-compose build --no-cache
+
+ # Start containers
+ echo -e "${YELLOW}Starting containers...${NC}"
+ docker-compose up -d
+
+ # Wait for containers to be healthy
+ echo -e "${YELLOW}Waiting for containers to be healthy...${NC}"
+ sleep 30
+
+ # Check container status
+ if ! docker-compose ps | grep -q "Up"; then
+ echo -e "${RED}Error: Some containers failed to start${NC}"
+ docker-compose logs
+ exit 1
+ fi
+
+ echo -e "${GREEN}Containers deployed successfully!${NC}"
+}
+
+# Function to setup SSL
+setup_ssl() {
+ echo -e "${BLUE}Setting up SSL certificate...${NC}"
+
+ # Wait for nginx proxy to be ready
+ echo -e "${YELLOW}Waiting for reverse proxy to be ready...${NC}"
+ sleep 10
+
+ # Setup SSL
+ if [ "$SSL_TYPE" = "letsencrypt" ]; then
+ echo -e "${YELLOW}Setting up Let's Encrypt certificate...${NC}"
+ echo -e "${YELLOW}Make sure your domain $DOMAIN points to this server${NC}"
+ read -p "Press Enter to continue..."
+
+ docker exec sibedas_nginx_proxy /usr/local/bin/ssl-setup.sh letsencrypt
+ else
+ echo -e "${YELLOW}Setting up self-signed certificate...${NC}"
+ docker exec sibedas_nginx_proxy /usr/local/bin/ssl-setup.sh self-signed
+ fi
+
+ echo -e "${GREEN}SSL setup completed!${NC}"
+}
+
+# Function to run post-deployment tasks
+post_deployment() {
+ echo -e "${BLUE}Running post-deployment tasks...${NC}"
+
+ # Clear Laravel caches
+ echo -e "${YELLOW}Clearing Laravel caches...${NC}"
+ docker exec sibedas_app php artisan config:clear || true
+ docker exec sibedas_app php artisan route:clear || true
+ docker exec sibedas_app php artisan view:clear || true
+ docker exec sibedas_app php artisan cache:clear || true
+
+ # Optimize Laravel
+ echo -e "${YELLOW}Optimizing Laravel...${NC}"
+ docker exec sibedas_app php artisan optimize || true
+
+ # Check application health
+ echo -e "${YELLOW}Checking application health...${NC}"
+ sleep 5
+
+ if curl -f -s "http://localhost/health-check" > /dev/null; then
+ echo -e "${GREEN}Application is healthy!${NC}"
+ else
+ echo -e "${YELLOW}Warning: Health check failed, but deployment completed${NC}"
+ fi
+}
+
+# Function to show deployment status
+show_status() {
+ echo -e "${BLUE}=== Deployment Status ===${NC}"
+
+ echo -e "${YELLOW}Container Status:${NC}"
+ docker-compose ps
+
+ echo -e "${YELLOW}SSL Certificate Status:${NC}"
+ docker exec sibedas_nginx_proxy /usr/local/bin/ssl-setup.sh check || true
+
+ echo -e "${YELLOW}Application URLs:${NC}"
+ echo -e " HTTP: ${GREEN}http://$DOMAIN${NC}"
+ echo -e " HTTPS: ${GREEN}https://$DOMAIN${NC}"
+
+ echo -e "${YELLOW}Logs:${NC}"
+ echo -e " Application: ${GREEN}docker-compose logs app${NC}"
+ echo -e " Reverse Proxy: ${GREEN}docker-compose logs nginx-proxy${NC}"
+ echo -e " Database: ${GREEN}docker-compose logs db${NC}"
+}
+
+# Function to show usage
+show_usage() {
+ echo "Usage: $0 {deploy|status|backup|ssl}"
+ echo ""
+ echo "Commands:"
+ echo " deploy - Full deployment with SSL setup"
+ echo " status - Show deployment status"
+ echo " backup - Create backup of existing data"
+ echo " ssl - Setup SSL certificate only"
+ echo ""
+ echo "Environment variables:"
+ echo " DOMAIN - Domain name (default: sibedas.yourdomain.com)"
+ echo " EMAIL - Email address for Let's Encrypt (default: admin@yourdomain.com)"
+ echo " SSL_TYPE - Type of SSL (letsencrypt or self-signed, default: self-signed)"
+ echo ""
+ echo "Examples:"
+ echo " DOMAIN=myapp.com EMAIL=admin@myapp.com SSL_TYPE=letsencrypt $0 deploy"
+ echo " $0 status"
+ echo " $0 ssl"
+}
+
+# Main script logic
+case "${1:-deploy}" in
+ "deploy")
+ check_prerequisites
+ backup_data
+ stop_containers
+ deploy_containers
+ setup_ssl
+ post_deployment
+ show_status
+ ;;
+ "status")
+ show_status
+ ;;
+ "backup")
+ backup_data
+ ;;
+ "ssl")
+ setup_ssl
+ ;;
+ *)
+ show_usage
+ exit 1
+ ;;
+esac
+
+echo ""
+echo -e "${GREEN}Deployment completed successfully!${NC}"
+echo -e "${BLUE}Your application is now accessible at: https://$DOMAIN${NC}"
\ No newline at end of file
diff --git a/scripts/import-sibedas-database.sh b/scripts/import-sibedas-database.sh
new file mode 100755
index 0000000..f77fc5f
--- /dev/null
+++ b/scripts/import-sibedas-database.sh
@@ -0,0 +1,257 @@
+#!/bin/bash
+
+echo "🗃️ Import Database from sibedas.sql"
+echo "===================================="
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+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"
+}
+
+# Check if sibedas.sql exists
+check_sql_file() {
+ if [[ ! -f "../sibedas.sql" ]]; then
+ print_error "sibedas.sql file not found!"
+ print_error "Please make sure sibedas.sql is in the project root directory."
+ exit 1
+ fi
+
+ print_success "Found sibedas.sql file"
+}
+
+# Import for local development
+import_local() {
+ print_status "Importing database for LOCAL DEVELOPMENT..."
+
+ # Stop containers if running
+ print_status "Stopping containers..."
+ docker-compose -f ../docker-compose.local.yml down
+
+ # Remove existing database volume to force fresh import
+ print_warning "Removing old database volume for fresh import..."
+ docker volume rm sibedas-pbg-web_sibedas_dbdata_local 2>/dev/null || true
+
+ # Start database container first
+ print_status "Starting database container..."
+ docker-compose -f ../docker-compose.local.yml up -d db
+
+ # Wait for database to be ready
+ print_status "Waiting for database to be ready..."
+ sleep 20
+
+ # Verify sibedas.sql was imported automatically
+ print_status "Verifying database import..."
+ if docker-compose -f ../docker-compose.local.yml exec -T db mysql -uroot -proot -e "USE sibedas; SELECT COUNT(*) FROM users;" 2>/dev/null; then
+ print_success "✅ Database imported successfully from sibedas.sql!"
+
+ # Show table summary
+ print_status "Database tables summary:"
+ docker-compose -f ../docker-compose.local.yml exec -T db mysql -uroot -proot -e "
+ USE sibedas;
+ SELECT 'users' as table_name, COUNT(*) as count FROM users
+ UNION SELECT 'advertisements', COUNT(*) FROM advertisements
+ UNION SELECT 'business_or_industries', COUNT(*) FROM business_or_industries
+ UNION SELECT 'customers', COUNT(*) FROM customers
+ UNION SELECT 'cache', COUNT(*) FROM cache
+ UNION SELECT 'sessions', COUNT(*) FROM sessions
+ UNION SELECT 'jobs', COUNT(*) FROM jobs;"
+
+ else
+ print_error "❌ Database import failed or data not found!"
+ exit 1
+ fi
+
+ # Start all containers
+ print_status "Starting all containers..."
+ docker-compose -f ../docker-compose.local.yml up -d
+
+ # Wait for app to be ready
+ sleep 15
+
+ # Clear caches to ensure fresh start
+ print_status "Clearing application caches..."
+ docker-compose -f ../docker-compose.local.yml exec -T app php artisan config:clear
+ docker-compose -f ../docker-compose.local.yml exec -T app php artisan cache:clear
+ docker-compose -f ../docker-compose.local.yml exec -T app php artisan view:clear
+
+ print_success "✅ Local development setup completed with sibedas.sql data!"
+ print_status "Access your application at: http://localhost:8000"
+}
+
+# Import for production
+import_production() {
+ print_status "Importing database for PRODUCTION..."
+
+ # Check if .env exists
+ if [[ ! -f "../.env" ]]; then
+ print_error ".env file not found! Please configure production environment first."
+ exit 1
+ fi
+
+ # Load environment variables
+ source ../.env
+
+ # Stop containers if running
+ print_status "Stopping containers..."
+ docker-compose -f ../docker-compose.yml down
+
+ # Remove existing database volume to force fresh import
+ print_warning "Removing old database volume for fresh import..."
+ docker volume rm sibedas-pbg-web_sibedas_dbdata 2>/dev/null || true
+
+ # Start database container first
+ print_status "Starting database container..."
+ docker-compose -f ../docker-compose.yml up -d db
+
+ # Wait for database to be ready
+ print_status "Waiting for database to be ready..."
+ sleep 30
+
+ # Verify sibedas.sql was imported automatically
+ print_status "Verifying database import..."
+ if docker-compose -f ../docker-compose.yml exec -T db mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "USE ${DB_DATABASE}; SELECT COUNT(*) FROM users;" 2>/dev/null; then
+ print_success "✅ Database imported successfully from sibedas.sql!"
+
+ # Show table summary
+ print_status "Database tables summary:"
+ docker-compose -f ../docker-compose.yml exec -T db mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "
+ USE ${DB_DATABASE};
+ SELECT 'users' as table_name, COUNT(*) as count FROM users
+ UNION SELECT 'advertisements', COUNT(*) FROM advertisements
+ UNION SELECT 'business_or_industries', COUNT(*) FROM business_or_industries
+ UNION SELECT 'customers', COUNT(*) FROM customers
+ UNION SELECT 'cache', COUNT(*) FROM cache
+ UNION SELECT 'sessions', COUNT(*) FROM sessions
+ UNION SELECT 'jobs', COUNT(*) FROM jobs;"
+
+ else
+ print_error "❌ Database import failed or data not found!"
+ exit 1
+ fi
+
+ # Start all containers
+ print_status "Starting all containers..."
+ docker-compose -f ../docker-compose.yml up -d
+
+ # Wait for app to be ready
+ sleep 30
+
+ # Generate app key if needed
+ if [[ -z "$APP_KEY" ]] || [[ "$APP_KEY" == "" ]]; then
+ print_status "Generating application key..."
+ docker-compose -f ../docker-compose.yml exec -T app php artisan key:generate --force
+ fi
+
+ # Optimize application
+ print_status "Optimizing application..."
+ docker-compose -f ../docker-compose.yml exec -T app php artisan config:cache
+ docker-compose -f ../docker-compose.yml exec -T app php artisan route:cache
+ docker-compose -f ../docker-compose.yml exec -T app php artisan view:cache
+
+ # Create storage link
+ print_status "Creating storage link..."
+ docker-compose -f ../docker-compose.yml exec -T app php artisan storage:link
+
+ print_success "✅ Production setup completed with sibedas.sql data!"
+ print_status "Access your application at: ${APP_URL}"
+}
+
+# Manual import to running container
+manual_import() {
+ print_status "Manual import to running container..."
+
+ # Check which containers are running
+ if docker-compose -f ../docker-compose.local.yml ps | grep -q "sibedas_db_local"; then
+ print_status "Found local development database container"
+ print_status "Importing sibedas.sql..."
+ docker-compose -f ../docker-compose.local.yml exec -T db mysql -uroot -proot sibedas < ../sibedas.sql
+ print_success "✅ Import completed for local development!"
+
+ # Clear app caches
+ docker-compose -f ../docker-compose.local.yml exec -T app php artisan cache:clear 2>/dev/null || true
+
+ elif docker-compose -f ../docker-compose.yml ps | grep -q "sibedas_db"; then
+ print_status "Found production database container"
+ source ../.env 2>/dev/null || true
+ print_status "Importing sibedas.sql..."
+ docker-compose -f ../docker-compose.yml exec -T db mysql -uroot -p${MYSQL_ROOT_PASSWORD:-root} ${DB_DATABASE:-sibedas} < ../sibedas.sql
+ print_success "✅ Import completed for production!"
+
+ # Clear app caches
+ docker-compose -f ../docker-compose.yml exec -T app php artisan cache:clear 2>/dev/null || true
+
+ else
+ print_error "❌ No database container found running!"
+ print_error "Please start containers first:"
+ print_error " Local: docker-compose -f ../docker-compose.local.yml up -d"
+ print_error " Production: docker-compose -f ../docker-compose.yml up -d"
+ exit 1
+ fi
+}
+
+# Main execution
+main() {
+ check_sql_file
+
+ echo ""
+ echo "🗃️ Choose import method:"
+ echo "1) 🔄 Fresh import for LOCAL development (recommended)"
+ echo "2) 🔄 Fresh import for PRODUCTION"
+ echo "3) 📥 Manual import to running container"
+ echo "4) ❌ Cancel"
+ echo ""
+
+ read -p "Enter your choice (1-4): " choice
+
+ case $choice in
+ 1)
+ import_local
+ ;;
+ 2)
+ import_production
+ ;;
+ 3)
+ manual_import
+ ;;
+ 4)
+ print_status "Cancelled"
+ exit 0
+ ;;
+ *)
+ print_error "Invalid choice"
+ exit 1
+ ;;
+ esac
+
+ echo ""
+ print_success "🎉 Database import completed!"
+ echo ""
+ print_status "📋 Imported data includes:"
+ echo " ✅ All application tables with existing data"
+ echo " ✅ Cache table (for CACHE_DRIVER=database)"
+ echo " ✅ Sessions table (for SESSION_DRIVER=database)"
+ echo " ✅ Jobs & failed_jobs tables (for QUEUE_CONNECTION=database)"
+ echo ""
+ print_status "🚀 Your application is ready to use with all data!"
+}
+
+# Run main function
+main "$@"
\ No newline at end of file
diff --git a/scripts/setup-local.sh b/scripts/setup-local.sh
new file mode 100755
index 0000000..3eef0ab
--- /dev/null
+++ b/scripts/setup-local.sh
@@ -0,0 +1,188 @@
+#!/bin/bash
+
+# Local Development Setup Script for Sibedas PBG Web
+# This script sets up the local development environment
+
+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
+
+echo -e "${BLUE}=== Local Development Setup untuk Sibedas PBG Web ===${NC}"
+echo ""
+
+# Function to check prerequisites
+check_prerequisites() {
+ echo -e "${BLUE}Checking prerequisites...${NC}"
+
+ # Check if Docker is installed
+ if ! command -v docker &> /dev/null; then
+ echo -e "${RED}Error: Docker is not installed${NC}"
+ exit 1
+ fi
+
+ # Check if Docker Compose is installed
+ if ! command -v docker-compose &> /dev/null; then
+ echo -e "${RED}Error: Docker Compose is not installed${NC}"
+ exit 1
+ fi
+
+ # Check if .env file exists
+ if [ ! -f .env ]; then
+ echo -e "${YELLOW}Warning: .env file not found${NC}"
+ echo -e "${YELLOW}Creating from example...${NC}"
+ if [ -f env.production.example ]; then
+ cp env.production.example .env
+ else
+ echo -e "${RED}Error: No environment example file found${NC}"
+ exit 1
+ fi
+ fi
+
+ echo -e "${GREEN}Prerequisites check passed!${NC}"
+}
+
+# Function to setup environment for local development
+setup_environment() {
+ echo -e "${BLUE}Setting up environment for local development...${NC}"
+
+ # Update .env for local development
+ sed -i 's/APP_ENV=production/APP_ENV=local/g' .env
+ sed -i 's/APP_DEBUG=false/APP_DEBUG=true/g' .env
+ sed -i 's/APP_URL=https:\/\/sibedas.yourdomain.com/APP_URL=http:\/\/localhost:8000/g' .env
+ sed -i 's/VITE_APP_URL=https:\/\/sibedas.yourdomain.com/VITE_APP_URL=http:\/\/localhost:8000/g' .env
+
+ # Update database settings for local
+ sed -i 's/DB_USERNAME=sibedas_user/DB_USERNAME=root/g' .env
+ sed -i 's/DB_PASSWORD=your_secure_database_password/DB_PASSWORD=root/g' .env
+ sed -i 's/MYSQL_ROOT_PASSWORD=your_secure_root_password/MYSQL_ROOT_PASSWORD=root/g' .env
+
+ echo -e "${GREEN}Environment configured for local development!${NC}"
+}
+
+# Function to start local containers
+start_containers() {
+ echo -e "${BLUE}Starting local development containers...${NC}"
+
+ # Stop any existing containers
+ docker-compose -f docker-compose.local.yml down --remove-orphans || true
+
+ # Build and start containers
+ docker-compose -f docker-compose.local.yml up -d --build
+
+ # Wait for containers to be ready
+ echo -e "${YELLOW}Waiting for containers to be ready...${NC}"
+ sleep 30
+
+ # Check container status
+ if docker-compose -f docker-compose.local.yml ps | grep -q "Up"; then
+ echo -e "${GREEN}Containers started successfully!${NC}"
+ else
+ echo -e "${RED}Error: Some containers failed to start${NC}"
+ docker-compose -f docker-compose.local.yml logs
+ exit 1
+ fi
+}
+
+# Function to setup database
+setup_database() {
+ echo -e "${BLUE}Setting up database...${NC}"
+
+ # Wait for database to be ready
+ echo -e "${YELLOW}Waiting for database to be ready...${NC}"
+ sleep 10
+
+ # Check if database import was successful
+ if docker exec sibedas_db_local mysql -uroot -proot sibedas -e "SHOW TABLES LIKE 'users';" 2>/dev/null | grep -q "users"; then
+ echo -e "${GREEN}Database imported successfully from sibedas.sql!${NC}"
+ else
+ echo -e "${YELLOW}Warning: Database import verification failed${NC}"
+ echo -e "${YELLOW}You may need to manually import the database${NC}"
+ fi
+}
+
+# Function to run post-setup tasks
+post_setup() {
+ echo -e "${BLUE}Running post-setup tasks...${NC}"
+
+ # Clear Laravel caches
+ echo -e "${YELLOW}Clearing Laravel caches...${NC}"
+ docker exec sibedas_app_local php artisan config:clear || true
+ docker exec sibedas_app_local php artisan route:clear || true
+ docker exec sibedas_app_local php artisan view:clear || true
+ docker exec sibedas_app_local php artisan cache:clear || true
+
+ # Optimize Laravel
+ echo -e "${YELLOW}Optimizing Laravel...${NC}"
+ docker exec sibedas_app_local php artisan optimize:clear || true
+
+ # Create storage link
+ echo -e "${YELLOW}Creating storage link...${NC}"
+ docker exec sibedas_app_local php artisan storage:link || true
+
+ echo -e "${GREEN}Post-setup tasks completed!${NC}"
+}
+
+# Function to show status
+show_status() {
+ echo -e "${BLUE}=== Local Development Status ===${NC}"
+
+ echo -e "${YELLOW}Container Status:${NC}"
+ docker-compose -f docker-compose.local.yml ps
+
+ echo -e "${YELLOW}Application URLs:${NC}"
+ echo -e " Main App: ${GREEN}http://localhost:8000${NC}"
+ echo -e " Vite Dev: ${GREEN}http://localhost:5173${NC}"
+
+ echo -e "${YELLOW}Useful Commands:${NC}"
+ echo -e " View logs: ${GREEN}docker-compose -f docker-compose.local.yml logs -f [service]${NC}"
+ echo -e " Execute commands: ${GREEN}docker-compose -f docker-compose.local.yml exec app php artisan [command]${NC}"
+ echo -e " Stop services: ${GREEN}docker-compose -f docker-compose.local.yml down${NC}"
+ echo -e " Restart services: ${GREEN}docker-compose -f docker-compose.local.yml restart${NC}"
+}
+
+# Function to show usage
+show_usage() {
+ echo "Usage: $0 {setup|status|help}"
+ echo ""
+ echo "Commands:"
+ echo " setup - Setup local development environment (default)"
+ echo " status - Show current status"
+ echo " help - Show this help message"
+ echo ""
+ echo "Examples:"
+ echo " $0 setup"
+ echo " $0 status"
+}
+
+# Main script logic
+case "${1:-setup}" in
+ "setup")
+ check_prerequisites
+ setup_environment
+ start_containers
+ setup_database
+ post_setup
+ show_status
+ ;;
+ "status")
+ show_status
+ ;;
+ "help"|"-h"|"--help")
+ show_usage
+ ;;
+ *)
+ echo -e "${RED}Unknown command: $1${NC}"
+ echo ""
+ show_usage
+ exit 1
+ ;;
+esac
+
+echo ""
+echo -e "${GREEN}Local development setup completed successfully!${NC}"
+echo -e "${BLUE}You can now access your application at: http://localhost:8000${NC}"
\ No newline at end of file
diff --git a/scripts/setup-reverse-proxy.sh b/scripts/setup-reverse-proxy.sh
new file mode 100755
index 0000000..e4abf62
--- /dev/null
+++ b/scripts/setup-reverse-proxy.sh
@@ -0,0 +1,129 @@
+#!/bin/bash
+
+# Reverse Proxy Setup Script for Sibedas PBG Web
+# Wrapper script untuk setup reverse proxy dan SSL
+
+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
+
+echo -e "${BLUE}=== Reverse Proxy Setup untuk Sibedas PBG Web ===${NC}"
+echo ""
+
+# Function to show usage
+show_usage() {
+ echo "Usage: $0 {setup|ssl|status|help}"
+ echo ""
+ echo "Commands:"
+ echo " setup - Setup reverse proxy dan SSL (default)"
+ echo " ssl - Setup SSL certificate only"
+ echo " status - Show current status"
+ echo " help - Show this help message"
+ echo ""
+ echo "Environment variables:"
+ echo " DOMAIN - Domain name (default: sibedas.yourdomain.com)"
+ echo " EMAIL - Email address for Let's Encrypt (default: admin@yourdomain.com)"
+ echo " SSL_TYPE - Type of SSL (letsencrypt or self-signed, default: self-signed)"
+ echo ""
+ echo "Examples:"
+ echo " $0 setup"
+ echo " DOMAIN=myapp.com EMAIL=admin@myapp.com SSL_TYPE=letsencrypt $0 setup"
+ echo " $0 ssl"
+ echo " $0 status"
+}
+
+# Function to check prerequisites
+check_prerequisites() {
+ echo -e "${BLUE}Checking prerequisites...${NC}"
+
+ # Check if .env exists
+ if [ ! -f .env ]; then
+ echo -e "${RED}Error: .env file not found${NC}"
+ echo -e "${YELLOW}Please create .env file with required environment variables${NC}"
+ exit 1
+ fi
+
+ # Check if scripts directory exists
+ if [ ! -d scripts ]; then
+ echo -e "${RED}Error: scripts directory not found${NC}"
+ exit 1
+ fi
+
+ echo -e "${GREEN}Prerequisites check passed!${NC}"
+}
+
+# Function to setup reverse proxy
+setup_reverse_proxy() {
+ echo -e "${BLUE}Setting up reverse proxy...${NC}"
+
+ # Run deployment script
+ ./scripts/deploy-production.sh deploy
+
+ echo -e "${GREEN}Reverse proxy setup completed!${NC}"
+}
+
+# Function to setup SSL only
+setup_ssl() {
+ echo -e "${BLUE}Setting up SSL certificate...${NC}"
+
+ # Run SSL setup script
+ ./scripts/setup-ssl.sh setup
+
+ echo -e "${GREEN}SSL setup completed!${NC}"
+}
+
+# Function to show status
+show_status() {
+ echo -e "${BLUE}=== Current Status ===${NC}"
+
+ # Check if containers are running
+ if command -v docker-compose &> /dev/null; then
+ echo -e "${YELLOW}Container Status:${NC}"
+ docker-compose ps 2>/dev/null || echo "Docker Compose not available"
+ fi
+
+ # Check SSL certificate
+ if [ -f scripts/setup-ssl.sh ]; then
+ echo -e "${YELLOW}SSL Certificate Status:${NC}"
+ ./scripts/setup-ssl.sh check 2>/dev/null || echo "SSL check failed"
+ fi
+
+ # Show environment info
+ if [ -f .env ]; then
+ echo -e "${YELLOW}Environment Variables:${NC}"
+ grep -E "^(DOMAIN|EMAIL|SSL_TYPE|APP_URL)=" .env 2>/dev/null || echo "No environment variables found"
+ fi
+}
+
+# Main script logic
+case "${1:-setup}" in
+ "setup")
+ check_prerequisites
+ setup_reverse_proxy
+ ;;
+ "ssl")
+ check_prerequisites
+ setup_ssl
+ ;;
+ "status")
+ show_status
+ ;;
+ "help"|"-h"|"--help")
+ show_usage
+ ;;
+ *)
+ echo -e "${RED}Unknown command: $1${NC}"
+ echo ""
+ show_usage
+ exit 1
+ ;;
+esac
+
+echo ""
+echo -e "${GREEN}Setup completed successfully!${NC}"
+echo -e "${BLUE}For more information, see: docs/README-Reverse-Proxy-SSL.md${NC}"
\ No newline at end of file
diff --git a/scripts/setup-ssl.sh b/scripts/setup-ssl.sh
new file mode 100755
index 0000000..552a74b
--- /dev/null
+++ b/scripts/setup-ssl.sh
@@ -0,0 +1,145 @@
+#!/bin/bash
+
+# SSL Setup Script for Sibedas PBG Web
+# This script sets up SSL certificates for the reverse proxy
+
+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="${DOMAIN:-sibedas.yourdomain.com}"
+EMAIL="${EMAIL:-admin@yourdomain.com}"
+SSL_TYPE="${SSL_TYPE:-self-signed}"
+
+echo -e "${BLUE}=== SSL Setup for Sibedas PBG Web ===${NC}"
+echo -e "Domain: ${GREEN}$DOMAIN${NC}"
+echo -e "Email: ${GREEN}$EMAIL${NC}"
+echo -e "SSL Type: ${GREEN}$SSL_TYPE${NC}"
+echo ""
+
+# Function to check if Docker is running
+check_docker() {
+ if ! docker info > /dev/null 2>&1; then
+ echo -e "${RED}Error: Docker is not running${NC}"
+ exit 1
+ fi
+}
+
+# Function to check if containers are running
+check_containers() {
+ if ! docker ps | grep -q sibedas_nginx_proxy; then
+ echo -e "${YELLOW}Warning: Reverse proxy container is not running${NC}"
+ echo -e "${YELLOW}Starting containers first...${NC}"
+ docker-compose up -d
+ sleep 10
+ fi
+}
+
+# Function to setup self-signed certificate
+setup_self_signed() {
+ echo -e "${BLUE}Setting up self-signed SSL certificate...${NC}"
+
+ docker exec sibedas_nginx_proxy /usr/local/bin/ssl-setup.sh self-signed
+
+ echo -e "${GREEN}Self-signed certificate setup completed!${NC}"
+ echo -e "${YELLOW}Note: Self-signed certificates will show security warnings in browsers${NC}"
+}
+
+# Function to setup Let's Encrypt certificate
+setup_letsencrypt() {
+ echo -e "${BLUE}Setting up Let's Encrypt SSL certificate...${NC}"
+
+ # Check if domain is accessible
+ echo -e "${YELLOW}Important: Make sure your domain $DOMAIN points to this server${NC}"
+ echo -e "${YELLOW}and ports 80 and 443 are accessible from the internet${NC}"
+ read -p "Press Enter to continue..."
+
+ docker exec sibedas_nginx_proxy /usr/local/bin/ssl-setup.sh letsencrypt
+
+ echo -e "${GREEN}Let's Encrypt certificate setup completed!${NC}"
+}
+
+# Function to check certificate status
+check_certificate() {
+ echo -e "${BLUE}Checking certificate status...${NC}"
+
+ docker exec sibedas_nginx_proxy /usr/local/bin/ssl-setup.sh check
+}
+
+# Function to renew certificate
+renew_certificate() {
+ echo -e "${BLUE}Renewing SSL certificate...${NC}"
+
+ docker exec sibedas_nginx_proxy /usr/local/bin/ssl-setup.sh renew
+
+ echo -e "${GREEN}Certificate renewal completed!${NC}"
+}
+
+# Function to show usage
+show_usage() {
+ echo "Usage: $0 {setup|check|renew|self-signed|letsencrypt}"
+ echo ""
+ echo "Commands:"
+ echo " setup - Setup SSL certificate (default: self-signed)"
+ echo " check - Check certificate status"
+ echo " renew - Renew Let's Encrypt certificate"
+ echo " self-signed - Setup self-signed certificate"
+ echo " letsencrypt - Setup Let's Encrypt certificate"
+ echo ""
+ echo "Environment variables:"
+ echo " DOMAIN - Domain name (default: sibedas.yourdomain.com)"
+ echo " EMAIL - Email address for Let's Encrypt (default: admin@yourdomain.com)"
+ echo " SSL_TYPE - Type of SSL (letsencrypt or self-signed, default: self-signed)"
+ echo ""
+ echo "Examples:"
+ echo " DOMAIN=myapp.com EMAIL=admin@myapp.com $0 letsencrypt"
+ echo " $0 self-signed"
+ echo " $0 check"
+}
+
+# Main script logic
+case "${1:-setup}" in
+ "setup")
+ check_docker
+ check_containers
+ if [ "$SSL_TYPE" = "letsencrypt" ]; then
+ setup_letsencrypt
+ else
+ setup_self_signed
+ fi
+ ;;
+ "check")
+ check_docker
+ check_containers
+ check_certificate
+ ;;
+ "renew")
+ check_docker
+ check_containers
+ renew_certificate
+ ;;
+ "self-signed")
+ check_docker
+ check_containers
+ setup_self_signed
+ ;;
+ "letsencrypt")
+ check_docker
+ check_containers
+ setup_letsencrypt
+ ;;
+ *)
+ show_usage
+ exit 1
+ ;;
+esac
+
+echo ""
+echo -e "${GREEN}SSL setup completed successfully!${NC}"
+echo -e "${BLUE}You can now access your application at: https://$DOMAIN${NC}"
\ No newline at end of file