add docker for local and production
This commit is contained in:
52
.dockerignore
Normal file
52
.dockerignore
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
README.md
|
||||||
|
|
||||||
|
# Docker files
|
||||||
|
Dockerfile*
|
||||||
|
docker-compose*
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Development files
|
||||||
|
.env.local
|
||||||
|
.env.development
|
||||||
|
.env.staging
|
||||||
|
node_modules
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Laravel specific
|
||||||
|
storage/app/*
|
||||||
|
!storage/app/.gitignore
|
||||||
|
storage/framework/cache/*
|
||||||
|
!storage/framework/cache/.gitignore
|
||||||
|
storage/framework/sessions/*
|
||||||
|
!storage/framework/sessions/.gitignore
|
||||||
|
storage/framework/views/*
|
||||||
|
!storage/framework/views/.gitignore
|
||||||
|
storage/logs/*
|
||||||
|
!storage/logs/.gitignore
|
||||||
|
bootstrap/cache/*
|
||||||
|
!bootstrap/cache/.gitignore
|
||||||
|
|
||||||
|
# Backup files
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.sql
|
||||||
|
|
||||||
|
# Test files
|
||||||
|
tests/
|
||||||
|
phpunit.xml
|
||||||
169
DATABASE-IMPORT-GUIDE.md
Normal file
169
DATABASE-IMPORT-GUIDE.md
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
# 📊 Database Import Guide untuk CKB Laravel Application
|
||||||
|
|
||||||
|
## 🚀 Quick Start (Paling Mudah)
|
||||||
|
|
||||||
|
Jika Anda baru pertama kali setup aplikasi:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Jalankan quick setup yang otomatis import database
|
||||||
|
./docker-quick-setup.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📥 Manual Import Database
|
||||||
|
|
||||||
|
### 1. Import ke Development Environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pastikan containers berjalan terlebih dahulu
|
||||||
|
./docker-start.sh dev up
|
||||||
|
|
||||||
|
# Import database ckb.sql
|
||||||
|
./docker-import-db.sh dev
|
||||||
|
|
||||||
|
# Atau import file SQL lain
|
||||||
|
./docker-import-db.sh dev nama-file-backup.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Import ke Production Environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start production environment
|
||||||
|
./docker-start.sh prod up
|
||||||
|
|
||||||
|
# Import database
|
||||||
|
./docker-import-db.sh prod
|
||||||
|
|
||||||
|
# Atau dengan file khusus
|
||||||
|
./docker-import-db.sh prod production-backup.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Auto Import (Recommended untuk First Time Setup)
|
||||||
|
|
||||||
|
Ketika Anda menjalankan Docker containers untuk pertama kali, file `ckb.sql` akan otomatis diimport ke database. Ini terjadi karena:
|
||||||
|
|
||||||
|
1. File `ckb.sql` di-mount ke `/docker-entrypoint-initdb.d/01-init.sql` di MySQL container
|
||||||
|
2. MySQL otomatis menjalankan semua file `.sql` di direktori tersebut saat inisialisasi
|
||||||
|
3. Auto import hanya terjadi jika database kosong/belum ada
|
||||||
|
|
||||||
|
## 🛠️ Troubleshooting Import
|
||||||
|
|
||||||
|
### Problem: Database tidak terimport otomatis
|
||||||
|
|
||||||
|
**Solusi:**
|
||||||
|
```bash
|
||||||
|
# 1. Stop containers
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# 2. Hapus volume database (HATI-HATI: akan hapus data!)
|
||||||
|
docker-compose down -v
|
||||||
|
|
||||||
|
# 3. Start ulang (akan trigger auto import)
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 4. Atau import manual
|
||||||
|
./docker-import-db.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Problem: Permission denied saat import
|
||||||
|
|
||||||
|
**Solusi:**
|
||||||
|
```bash
|
||||||
|
# Pastikan script executable
|
||||||
|
chmod +x docker-import-db.sh
|
||||||
|
chmod +x docker-quick-setup.sh
|
||||||
|
|
||||||
|
# Pastikan file SQL readable
|
||||||
|
chmod 644 ckb.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### Problem: Database terlalu besar, import timeout
|
||||||
|
|
||||||
|
**Solusi:**
|
||||||
|
```bash
|
||||||
|
# Import langsung ke container dengan timeout yang lebih besar
|
||||||
|
docker-compose exec -T db mysql -u root -proot ckb_db < ckb.sql
|
||||||
|
|
||||||
|
# Atau split file SQL jika sangat besar
|
||||||
|
split -l 10000 ckb.sql ckb_split_
|
||||||
|
# Kemudian import satu per satu
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 Verifikasi Import Berhasil
|
||||||
|
|
||||||
|
### 1. Cek via phpMyAdmin
|
||||||
|
- Buka http://localhost:8080
|
||||||
|
- Login dengan: server=db, username=root, password=root
|
||||||
|
- Pilih database `ckb_db`
|
||||||
|
- Lihat tabel yang sudah terimport
|
||||||
|
|
||||||
|
### 2. Cek via Command Line
|
||||||
|
```bash
|
||||||
|
# Lihat daftar tabel
|
||||||
|
docker-compose exec db mysql -u root -proot -e "USE ckb_db; SHOW TABLES;"
|
||||||
|
|
||||||
|
# Hitung jumlah tabel
|
||||||
|
docker-compose exec db mysql -u root -proot -e "USE ckb_db; SELECT COUNT(*) as total_tables FROM information_schema.tables WHERE table_schema='ckb_db';"
|
||||||
|
|
||||||
|
# Lihat contoh data dari salah satu tabel
|
||||||
|
docker-compose exec db mysql -u root -proot -e "USE ckb_db; SELECT * FROM users LIMIT 5;"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Test Aplikasi Laravel
|
||||||
|
```bash
|
||||||
|
# Cek koneksi database dari Laravel
|
||||||
|
docker-compose exec app php artisan tinker
|
||||||
|
# Di dalam tinker:
|
||||||
|
# DB::connection()->getPdo();
|
||||||
|
# \App\Models\User::count();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 💾 Backup Database
|
||||||
|
|
||||||
|
### Backup Development
|
||||||
|
```bash
|
||||||
|
# Backup dengan timestamp
|
||||||
|
docker-compose exec db mysqldump -u root -proot ckb_db > backup_dev_$(date +%Y%m%d_%H%M%S).sql
|
||||||
|
|
||||||
|
# Backup sederhana
|
||||||
|
docker-compose exec db mysqldump -u root -proot ckb_db > backup_current.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup Production
|
||||||
|
```bash
|
||||||
|
# Backup production database
|
||||||
|
docker-compose -f docker-compose.prod.yml exec db mysqldump -u root -p ckb_production > backup_prod_$(date +%Y%m%d_%H%M%S).sql
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Replace Database dengan Backup Baru
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Backup database saat ini (safety)
|
||||||
|
docker-compose exec db mysqldump -u root -proot ckb_db > backup_before_replace.sql
|
||||||
|
|
||||||
|
# 2. Import database baru
|
||||||
|
./docker-import-db.sh dev new-backup.sql
|
||||||
|
|
||||||
|
# 3. Clear Laravel cache
|
||||||
|
docker-compose exec app php artisan cache:clear
|
||||||
|
docker-compose exec app php artisan config:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 Notes Penting
|
||||||
|
|
||||||
|
1. **File ckb.sql**: Pastikan file ini selalu ada di root project untuk auto-import
|
||||||
|
2. **Backup Safety**: Script import otomatis membuat backup sebelum replace database
|
||||||
|
3. **Environment**: Selalu pastikan Anda menggunakan environment yang benar (dev/prod)
|
||||||
|
4. **Permissions**: Database user harus punya permission CREATE, DROP, INSERT untuk import
|
||||||
|
5. **Size Limit**: File SQL besar (>100MB) mungkin perlu setting timeout MySQL yang lebih besar
|
||||||
|
|
||||||
|
## 🎯 Best Practices
|
||||||
|
|
||||||
|
1. **Selalu backup** sebelum import database baru
|
||||||
|
2. **Test di development** dulu sebelum import ke production
|
||||||
|
3. **Gunakan quick setup** untuk setup pertama kali
|
||||||
|
4. **Monitor logs** saat import: `docker-compose logs -f db`
|
||||||
|
5. **Verify data** setelah import berhasil
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Untuk bantuan lebih lanjut, lihat file `DOCKER-README.md` atau `docker-import-db.sh --help`**
|
||||||
399
DOCKER-README.md
Normal file
399
DOCKER-README.md
Normal file
@@ -0,0 +1,399 @@
|
|||||||
|
# Docker Setup untuk CKB Laravel Application
|
||||||
|
|
||||||
|
Dokumentasi ini menjelaskan cara menjalankan aplikasi CKB menggunakan Docker untuk environment local development dan staging/production.
|
||||||
|
|
||||||
|
## Struktur File Docker
|
||||||
|
|
||||||
|
```
|
||||||
|
├── Dockerfile # Production/Staging Docker image
|
||||||
|
├── Dockerfile.dev # Development Docker image
|
||||||
|
├── docker-compose.yml # Local development setup
|
||||||
|
├── docker-compose.prod.yml # Production/Staging setup
|
||||||
|
├── .dockerignore # Files to exclude from build
|
||||||
|
└── docker/
|
||||||
|
├── env.example # Environment variables template
|
||||||
|
├── nginx.conf # Production Nginx config
|
||||||
|
├── nginx.dev.conf # Development Nginx config
|
||||||
|
├── supervisord.conf # Production supervisor config
|
||||||
|
├── supervisord.dev.conf # Development supervisor config
|
||||||
|
├── xdebug.ini # Xdebug configuration
|
||||||
|
├── php.ini # PHP configuration
|
||||||
|
└── mysql.cnf # MySQL configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Docker Engine 20.10+
|
||||||
|
- Docker Compose 2.0+
|
||||||
|
- Git
|
||||||
|
|
||||||
|
## Setup untuk Local Development
|
||||||
|
|
||||||
|
### 1. Quick Setup (Recommended)
|
||||||
|
|
||||||
|
Untuk setup cepat dengan auto-import database:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone <your-repo-url>
|
||||||
|
cd CKB
|
||||||
|
|
||||||
|
# Pastikan file ckb.sql ada di root project
|
||||||
|
ls ckb.sql
|
||||||
|
|
||||||
|
# Jalankan quick setup
|
||||||
|
./docker-quick-setup.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Script ini akan otomatis:
|
||||||
|
- Setup environment file
|
||||||
|
- Start semua containers
|
||||||
|
- Import database dari ckb.sql
|
||||||
|
- Generate application key
|
||||||
|
- Setup Laravel application
|
||||||
|
|
||||||
|
### 2. Manual Setup
|
||||||
|
|
||||||
|
Jika Anda ingin setup manual:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Copy environment file
|
||||||
|
cp docker/env.example .env
|
||||||
|
|
||||||
|
# Start containers
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
|
# Import database
|
||||||
|
./docker-import-db.sh dev
|
||||||
|
|
||||||
|
# Generate Laravel application key
|
||||||
|
docker-compose exec app php artisan key:generate
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Menjalankan Development Environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build dan jalankan containers
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
|
# Atau tanpa rebuild
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Akses Aplikasi
|
||||||
|
|
||||||
|
- **Web Application**: http://localhost:8000
|
||||||
|
- **Database (phpMyAdmin)**: http://localhost:8080
|
||||||
|
- **Mail Testing (MailHog)**: http://localhost:8025
|
||||||
|
- **MySQL Direct**: localhost:3306
|
||||||
|
- **Redis**: localhost:6379
|
||||||
|
|
||||||
|
### 4. Menjalankan Laravel Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Masuk ke container aplikasi
|
||||||
|
docker-compose exec app bash
|
||||||
|
|
||||||
|
# Atau jalankan command langsung
|
||||||
|
docker-compose exec app php artisan migrate
|
||||||
|
docker-compose exec app php artisan db:seed
|
||||||
|
docker-compose exec app php artisan cache:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Development dengan Hot Reload
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
docker-compose exec app npm install
|
||||||
|
|
||||||
|
# Jalankan webpack dev server
|
||||||
|
docker-compose exec app npm run hot
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setup untuk Staging/Production
|
||||||
|
|
||||||
|
### 1. Persiapan Environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Copy dan edit environment file production
|
||||||
|
cp docker/env.example .env.production
|
||||||
|
|
||||||
|
# Edit file .env.production sesuai kebutuhan production
|
||||||
|
vim .env.production
|
||||||
|
```
|
||||||
|
|
||||||
|
Contoh konfigurasi production:
|
||||||
|
|
||||||
|
```env
|
||||||
|
APP_ENV=production
|
||||||
|
APP_DEBUG=false
|
||||||
|
APP_URL=https://your-domain.com
|
||||||
|
|
||||||
|
DB_HOST=db
|
||||||
|
DB_DATABASE=ckb_production
|
||||||
|
DB_USERNAME=your_db_user
|
||||||
|
DB_PASSWORD=your_secure_password
|
||||||
|
DB_ROOT_PASSWORD=your_root_password
|
||||||
|
|
||||||
|
REDIS_PASSWORD=your_redis_password
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Menjalankan Production Environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build dan jalankan dengan konfigurasi production
|
||||||
|
docker-compose -f docker-compose.prod.yml up -d --build
|
||||||
|
|
||||||
|
# Atau menggunakan environment file spesifik
|
||||||
|
docker-compose -f docker-compose.prod.yml --env-file .env.production up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Database Migration dan Seeding
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Jalankan migrations
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan migrate --force
|
||||||
|
|
||||||
|
# Jalankan seeders (jika diperlukan)
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan db:seed --force
|
||||||
|
|
||||||
|
# Optimize aplikasi untuk production
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring dan Debugging
|
||||||
|
|
||||||
|
### 1. Melihat Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Semua services
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# Service specific
|
||||||
|
docker-compose logs -f app
|
||||||
|
docker-compose logs -f db
|
||||||
|
docker-compose logs -f redis
|
||||||
|
|
||||||
|
# Production
|
||||||
|
docker-compose -f docker-compose.prod.yml logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Debugging dengan Xdebug (Development)
|
||||||
|
|
||||||
|
Xdebug sudah dikonfigurasi untuk development environment:
|
||||||
|
- Port: 9003
|
||||||
|
- IDE Key: PHPSTORM
|
||||||
|
- Host: host.docker.internal
|
||||||
|
|
||||||
|
### 3. Monitoring Resources
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lihat resource usage
|
||||||
|
docker stats
|
||||||
|
|
||||||
|
# Lihat containers yang berjalan
|
||||||
|
docker-compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Management
|
||||||
|
|
||||||
|
### 1. Import Database dari Backup
|
||||||
|
|
||||||
|
Untuk mengimport database dari file backup ckb.sql:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Import ke development environment
|
||||||
|
./docker-import-db.sh dev
|
||||||
|
|
||||||
|
# Import ke production environment
|
||||||
|
./docker-import-db.sh prod
|
||||||
|
|
||||||
|
# Import file SQL khusus
|
||||||
|
./docker-import-db.sh dev my-backup.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Script import akan otomatis:
|
||||||
|
- Backup database yang sudah ada (safety)
|
||||||
|
- Drop dan recreate database
|
||||||
|
- Import data dari file SQL
|
||||||
|
- Jalankan migrations jika diperlukan
|
||||||
|
- Clear cache Laravel
|
||||||
|
|
||||||
|
### 2. Backup Database
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backup database development
|
||||||
|
docker-compose exec db mysqldump -u root -proot ckb_db > backup_$(date +%Y%m%d).sql
|
||||||
|
|
||||||
|
# Backup database production
|
||||||
|
docker-compose -f docker-compose.prod.yml exec db mysqldump -u root -p ckb_production > backup_prod_$(date +%Y%m%d).sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Manual Restore Database
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Restore database development
|
||||||
|
docker-compose exec -T db mysql -u root -proot ckb_db < backup.sql
|
||||||
|
|
||||||
|
# Restore database production
|
||||||
|
docker-compose -f docker-compose.prod.yml exec -T db mysql -u root -p ckb_production < backup.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Auto Import saat Pertama Kali Setup
|
||||||
|
|
||||||
|
File `ckb.sql` di root project akan otomatis diimport saat pertama kali menjalankan containers baru. Ini terjadi karena MySQL menggunakan `/docker-entrypoint-initdb.d/` untuk auto-import.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### 1. Docker Build Issues
|
||||||
|
|
||||||
|
Jika mengalami error saat build (seperti PHP extension compilation errors):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clean rebuild dengan script otomatis
|
||||||
|
./docker-rebuild.sh dev
|
||||||
|
|
||||||
|
# Atau manual cleanup dan rebuild
|
||||||
|
docker-compose down
|
||||||
|
docker system prune -a -f
|
||||||
|
docker-compose build --no-cache --pull
|
||||||
|
```
|
||||||
|
|
||||||
|
**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
|
||||||
|
- **Out of space**: Jalankan `docker system prune -a -f` untuk cleanup
|
||||||
|
|
||||||
|
### 2. Permission Issues
|
||||||
|
|
||||||
|
**Laravel Storage Permission Errors** (seperti "laravel.log could not be opened"):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Quick fix dengan script otomatis
|
||||||
|
./docker-fix-permissions.sh dev
|
||||||
|
|
||||||
|
# Atau manual fix
|
||||||
|
docker-compose exec app chown -R www-data:www-data /var/www/html/storage
|
||||||
|
docker-compose exec app chmod -R 775 /var/www/html/storage
|
||||||
|
docker-compose exec app mkdir -p /var/www/html/storage/logs
|
||||||
|
```
|
||||||
|
|
||||||
|
**Host Permission Issues:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Fix permission di host system
|
||||||
|
sudo chown -R $(id -u):$(id -g) storage/
|
||||||
|
sudo chown -R $(id -u):$(id -g) bootstrap/cache/
|
||||||
|
chmod -R 775 storage/
|
||||||
|
chmod -R 775 bootstrap/cache/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Reset Containers
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stop dan remove containers
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# Remove volumes (HATI-HATI: akan menghapus data database)
|
||||||
|
docker-compose down -v
|
||||||
|
|
||||||
|
# Rebuild dari awal
|
||||||
|
docker-compose up -d --build --force-recreate
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Cache Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clear semua cache Laravel
|
||||||
|
docker-compose exec app php artisan optimize:clear
|
||||||
|
|
||||||
|
# Clear Docker build cache
|
||||||
|
docker system prune -f
|
||||||
|
|
||||||
|
# Clean rebuild everything
|
||||||
|
./docker-rebuild.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Database Import Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Jika auto-import gagal
|
||||||
|
./docker-import-db.sh dev
|
||||||
|
|
||||||
|
# Jika database corrupt
|
||||||
|
docker-compose down -v
|
||||||
|
docker-compose up -d
|
||||||
|
./docker-import-db.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Redis Connection Issues
|
||||||
|
|
||||||
|
Jika mengalami error "Class Redis not found":
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test Redis functionality
|
||||||
|
./docker-test-redis.sh dev
|
||||||
|
|
||||||
|
# Rebuild containers dengan Redis extension
|
||||||
|
./docker-rebuild.sh dev
|
||||||
|
|
||||||
|
# Manual fix: Clear cache dan config
|
||||||
|
docker-compose exec app php artisan config:clear
|
||||||
|
docker-compose exec app php artisan cache:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
**Common Redis Errors:**
|
||||||
|
- **Class Redis not found**: Fixed dengan install `pecl install redis`
|
||||||
|
- **Connection refused**: Pastikan Redis container berjalan
|
||||||
|
- **Config not loaded**: Jalankan `php artisan config:clear`
|
||||||
|
|
||||||
|
## Security Notes untuk Production
|
||||||
|
|
||||||
|
1. **Environment Variables**: Jangan commit file `.env` ke repository
|
||||||
|
2. **Database Passwords**: Gunakan password yang kuat
|
||||||
|
3. **SSL/TLS**: Setup SSL certificate untuk HTTPS
|
||||||
|
4. **Firewall**: Konfigurasi firewall untuk membatasi akses port
|
||||||
|
5. **Updates**: Regular update Docker images dan dependencies
|
||||||
|
|
||||||
|
## Performance Optimization
|
||||||
|
|
||||||
|
### 1. Production Optimizations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Laravel optimizations
|
||||||
|
docker-compose exec app php artisan config:cache
|
||||||
|
docker-compose exec app php artisan route:cache
|
||||||
|
docker-compose exec app php artisan view:cache
|
||||||
|
docker-compose exec app composer install --optimize-autoloader --no-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Docker Optimizations
|
||||||
|
|
||||||
|
- Gunakan multi-stage builds untuk image yang lebih kecil
|
||||||
|
- Leverage Docker layer caching
|
||||||
|
- Optimize .dockerignore untuk build speed
|
||||||
|
|
||||||
|
## Backup Strategy
|
||||||
|
|
||||||
|
### 1. Automated Backups
|
||||||
|
|
||||||
|
Buat script backup otomatis:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# backup.sh
|
||||||
|
DATE=$(date +%Y%m%d_%H%M%S)
|
||||||
|
docker-compose exec db mysqldump -u root -p${DB_ROOT_PASSWORD} ckb_production > "backup_${DATE}.sql"
|
||||||
|
tar -czf "backup_${DATE}.tar.gz" backup_${DATE}.sql storage/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Volume Backups
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backup Docker volumes
|
||||||
|
docker run --rm -v ckb_mysql_data:/data -v $(pwd):/backup alpine tar czf /backup/mysql_backup.tar.gz /data
|
||||||
|
```
|
||||||
|
|
||||||
|
Untuk pertanyaan lebih lanjut atau issues, silakan buat issue di repository ini.
|
||||||
77
Dockerfile
Normal file
77
Dockerfile
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
FROM php:8.1-fpm
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
git \
|
||||||
|
curl \
|
||||||
|
libcurl4-openssl-dev \
|
||||||
|
pkg-config \
|
||||||
|
libpng-dev \
|
||||||
|
libonig-dev \
|
||||||
|
libxml2-dev \
|
||||||
|
libzip-dev \
|
||||||
|
zip \
|
||||||
|
unzip \
|
||||||
|
libfreetype6-dev \
|
||||||
|
libjpeg62-turbo-dev \
|
||||||
|
libpng-dev \
|
||||||
|
libxpm-dev \
|
||||||
|
libvpx-dev \
|
||||||
|
supervisor \
|
||||||
|
nginx \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install PHP extensions
|
||||||
|
RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-xpm \
|
||||||
|
&& docker-php-ext-install -j$(nproc) \
|
||||||
|
curl \
|
||||||
|
pdo_mysql \
|
||||||
|
mbstring \
|
||||||
|
exif \
|
||||||
|
pcntl \
|
||||||
|
bcmath \
|
||||||
|
gd \
|
||||||
|
zip \
|
||||||
|
dom \
|
||||||
|
xml
|
||||||
|
|
||||||
|
# Install Redis extension
|
||||||
|
RUN pecl install redis \
|
||||||
|
&& docker-php-ext-enable redis
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
||||||
|
|
||||||
|
# Copy existing application directory contents
|
||||||
|
COPY . /var/www/html
|
||||||
|
|
||||||
|
# Copy existing application directory permissions
|
||||||
|
COPY --chown=www-data:www-data . /var/www/html
|
||||||
|
|
||||||
|
# Install PHP dependencies
|
||||||
|
RUN composer install --optimize-autoloader --no-dev --no-interaction
|
||||||
|
|
||||||
|
# Create necessary directories and set permissions
|
||||||
|
RUN mkdir -p /var/www/html/storage/logs \
|
||||||
|
&& mkdir -p /var/www/html/storage/framework/cache \
|
||||||
|
&& mkdir -p /var/www/html/storage/framework/sessions \
|
||||||
|
&& mkdir -p /var/www/html/storage/framework/views \
|
||||||
|
&& mkdir -p /var/www/html/storage/app \
|
||||||
|
&& mkdir -p /var/www/html/bootstrap/cache \
|
||||||
|
&& chown -R www-data:www-data /var/www/html \
|
||||||
|
&& chmod -R 775 /var/www/html/storage \
|
||||||
|
&& chmod -R 775 /var/www/html/bootstrap/cache
|
||||||
|
|
||||||
|
# Create nginx config
|
||||||
|
COPY ./docker/nginx.conf /etc/nginx/sites-available/default
|
||||||
|
|
||||||
|
# Create supervisor config
|
||||||
|
COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||||
|
|
||||||
|
# Expose port 9000 and start php-fpm server
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||||
88
Dockerfile.dev
Normal file
88
Dockerfile.dev
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
FROM php:8.1-fpm
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
git \
|
||||||
|
curl \
|
||||||
|
libcurl4-openssl-dev \
|
||||||
|
pkg-config \
|
||||||
|
libpng-dev \
|
||||||
|
libonig-dev \
|
||||||
|
libxml2-dev \
|
||||||
|
libzip-dev \
|
||||||
|
zip \
|
||||||
|
unzip \
|
||||||
|
libfreetype6-dev \
|
||||||
|
libjpeg62-turbo-dev \
|
||||||
|
libpng-dev \
|
||||||
|
libxpm-dev \
|
||||||
|
libvpx-dev \
|
||||||
|
supervisor \
|
||||||
|
nginx \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
|
vim \
|
||||||
|
nano \
|
||||||
|
htop \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install PHP extensions
|
||||||
|
RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-xpm \
|
||||||
|
&& docker-php-ext-install -j$(nproc) \
|
||||||
|
curl \
|
||||||
|
pdo_mysql \
|
||||||
|
mbstring \
|
||||||
|
exif \
|
||||||
|
pcntl \
|
||||||
|
bcmath \
|
||||||
|
gd \
|
||||||
|
zip \
|
||||||
|
dom \
|
||||||
|
xml
|
||||||
|
|
||||||
|
# Install Redis and Xdebug for development
|
||||||
|
RUN pecl install redis xdebug \
|
||||||
|
&& docker-php-ext-enable redis xdebug
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
||||||
|
|
||||||
|
# Copy existing application directory contents
|
||||||
|
COPY . /var/www/html
|
||||||
|
|
||||||
|
# Copy existing application directory permissions
|
||||||
|
COPY --chown=www-data:www-data . /var/www/html
|
||||||
|
|
||||||
|
# Install PHP dependencies with dev packages
|
||||||
|
RUN composer install --optimize-autoloader --no-interaction
|
||||||
|
|
||||||
|
# Install Node.js dependencies
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
# Create necessary directories and set permissions
|
||||||
|
RUN mkdir -p /var/www/html/storage/logs \
|
||||||
|
&& mkdir -p /var/www/html/storage/framework/cache \
|
||||||
|
&& mkdir -p /var/www/html/storage/framework/sessions \
|
||||||
|
&& mkdir -p /var/www/html/storage/framework/views \
|
||||||
|
&& mkdir -p /var/www/html/storage/app \
|
||||||
|
&& mkdir -p /var/www/html/bootstrap/cache \
|
||||||
|
&& chown -R www-data:www-data /var/www/html \
|
||||||
|
&& chmod -R 775 /var/www/html/storage \
|
||||||
|
&& chmod -R 775 /var/www/html/bootstrap/cache
|
||||||
|
|
||||||
|
# Create nginx config for development
|
||||||
|
COPY ./docker/nginx.dev.conf /etc/nginx/sites-available/default
|
||||||
|
|
||||||
|
# Create supervisor config for development
|
||||||
|
COPY ./docker/supervisord.dev.conf /etc/supervisor/conf.d/supervisord.conf
|
||||||
|
|
||||||
|
# Create Xdebug config
|
||||||
|
COPY ./docker/xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
|
||||||
|
|
||||||
|
# Expose ports
|
||||||
|
EXPOSE 80 3000
|
||||||
|
|
||||||
|
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||||
225
PERMISSION-FIX-GUIDE.md
Normal file
225
PERMISSION-FIX-GUIDE.md
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
# 🔧 Laravel Permission Fix Guide untuk Docker
|
||||||
|
|
||||||
|
## 🎯 Masalah yang Diselesaikan
|
||||||
|
|
||||||
|
**Error yang umum terjadi:**
|
||||||
|
```
|
||||||
|
The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission denied
|
||||||
|
```
|
||||||
|
|
||||||
|
**Root Cause:**
|
||||||
|
- Laravel tidak bisa menulis ke direktori `storage/logs/`
|
||||||
|
- Permission dan ownership direktori storage tidak sesuai
|
||||||
|
- Direktori storage yang diperlukan belum dibuat
|
||||||
|
|
||||||
|
## 🚀 Solusi Quick Fix
|
||||||
|
|
||||||
|
### **Option 1: Automatic Fix (Recommended)**
|
||||||
|
```bash
|
||||||
|
# Fix semua permission issues otomatis
|
||||||
|
./docker-fix-permissions.sh dev
|
||||||
|
|
||||||
|
# Untuk production
|
||||||
|
./docker-fix-permissions.sh prod
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Option 2: Manual Fix**
|
||||||
|
```bash
|
||||||
|
# Buat direktori yang diperlukan
|
||||||
|
docker-compose exec app mkdir -p /var/www/html/storage/logs
|
||||||
|
docker-compose exec app mkdir -p /var/www/html/storage/framework/cache
|
||||||
|
docker-compose exec app mkdir -p /var/www/html/storage/framework/sessions
|
||||||
|
docker-compose exec app mkdir -p /var/www/html/storage/framework/views
|
||||||
|
|
||||||
|
# Fix ownership
|
||||||
|
docker-compose exec app chown -R www-data:www-data /var/www/html/storage
|
||||||
|
docker-compose exec app chown -R www-data:www-data /var/www/html/bootstrap/cache
|
||||||
|
|
||||||
|
# Fix permissions
|
||||||
|
docker-compose exec app chmod -R 775 /var/www/html/storage
|
||||||
|
docker-compose exec app chmod -R 775 /var/www/html/bootstrap/cache
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Option 3: Rebuild Containers (Jika masalah persisten)**
|
||||||
|
```bash
|
||||||
|
# Clean rebuild containers
|
||||||
|
./docker-rebuild.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 Verifikasi Fix Berhasil
|
||||||
|
|
||||||
|
### **1. Cek Permission Direktori**
|
||||||
|
```bash
|
||||||
|
# Lihat permission storage
|
||||||
|
docker-compose exec app ls -la /var/www/html/storage/
|
||||||
|
|
||||||
|
# Cek ownership logs
|
||||||
|
docker-compose exec app ls -la /var/www/html/storage/logs/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output yang benar:**
|
||||||
|
```
|
||||||
|
drwxrwxr-x 5 www-data www-data 4096 Jun 10 15:01 storage
|
||||||
|
drwxrwxr-x 2 www-data www-data 4096 Jun 10 15:01 logs
|
||||||
|
```
|
||||||
|
|
||||||
|
### **2. Test Laravel Logging**
|
||||||
|
```bash
|
||||||
|
# Test write ke log
|
||||||
|
docker-compose exec app php -r "file_put_contents('/var/www/html/storage/logs/laravel.log', 'Test log: ' . date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);"
|
||||||
|
|
||||||
|
# Cek isi log
|
||||||
|
docker-compose exec app tail -5 /var/www/html/storage/logs/laravel.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### **3. Test Laravel Artisan**
|
||||||
|
```bash
|
||||||
|
# Test cache clear
|
||||||
|
docker-compose exec app php artisan cache:clear
|
||||||
|
|
||||||
|
# Test storage link
|
||||||
|
docker-compose exec app php artisan storage:link
|
||||||
|
|
||||||
|
# Test route cache
|
||||||
|
docker-compose exec app php artisan route:cache
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛡️ Prevention - Dockerfile Updates
|
||||||
|
|
||||||
|
**Dockerfile sudah diperbarui untuk mencegah masalah ini:**
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
# Create necessary directories and set permissions
|
||||||
|
RUN mkdir -p /var/www/html/storage/logs \
|
||||||
|
&& mkdir -p /var/www/html/storage/framework/cache \
|
||||||
|
&& mkdir -p /var/www/html/storage/framework/sessions \
|
||||||
|
&& mkdir -p /var/www/html/storage/framework/views \
|
||||||
|
&& mkdir -p /var/www/html/storage/app \
|
||||||
|
&& mkdir -p /var/www/html/bootstrap/cache \
|
||||||
|
&& chown -R www-data:www-data /var/www/html \
|
||||||
|
&& chmod -R 775 /var/www/html/storage \
|
||||||
|
&& chmod -R 775 /var/www/html/bootstrap/cache
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Script Features
|
||||||
|
|
||||||
|
### **`docker-fix-permissions.sh`**
|
||||||
|
- ✅ **Auto-detect environment** (dev/prod)
|
||||||
|
- ✅ **Create missing directories**
|
||||||
|
- ✅ **Fix ownership** (www-data:www-data)
|
||||||
|
- ✅ **Set proper permissions** (775 untuk storage)
|
||||||
|
- ✅ **Test logging functionality**
|
||||||
|
- ✅ **Create storage link**
|
||||||
|
- ✅ **Show before/after permissions**
|
||||||
|
|
||||||
|
### **Usage Examples**
|
||||||
|
```bash
|
||||||
|
# Fix development environment
|
||||||
|
./docker-fix-permissions.sh dev
|
||||||
|
|
||||||
|
# Fix production environment
|
||||||
|
./docker-fix-permissions.sh prod
|
||||||
|
|
||||||
|
# Show help
|
||||||
|
./docker-fix-permissions.sh --help
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚨 Common Issues & Solutions
|
||||||
|
|
||||||
|
### **1. Permission Denied setelah Fix**
|
||||||
|
**Cause:** Volume mounting conflict
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Cek volume mounts
|
||||||
|
docker-compose config
|
||||||
|
|
||||||
|
# Restart containers
|
||||||
|
docker-compose restart app
|
||||||
|
|
||||||
|
# Re-run permission fix
|
||||||
|
./docker-fix-permissions.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### **2. Ownership reverted setelah restart**
|
||||||
|
**Cause:** Volume mounting dari host
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Fix di host system juga
|
||||||
|
sudo chown -R $(id -u):$(id -g) storage/
|
||||||
|
chmod -R 775 storage/
|
||||||
|
|
||||||
|
# Atau gunakan named volumes di docker-compose
|
||||||
|
```
|
||||||
|
|
||||||
|
### **3. Log file tetap tidak bisa ditulis**
|
||||||
|
**Cause:** Log file sudah ada dengan permission salah
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Hapus log file lama
|
||||||
|
docker-compose exec app rm -f /var/www/html/storage/logs/laravel.log
|
||||||
|
|
||||||
|
# Re-run permission fix
|
||||||
|
./docker-fix-permissions.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### **4. Selinux/AppArmor blocking**
|
||||||
|
**Cause:** Security policies
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Disable selinux temporarily (CentOS/RHEL)
|
||||||
|
sudo setenforce 0
|
||||||
|
|
||||||
|
# Check AppArmor status (Ubuntu)
|
||||||
|
sudo aa-status
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📁 Directory Structure yang Benar
|
||||||
|
|
||||||
|
Setelah fix, struktur direktori storage harus seperti ini:
|
||||||
|
|
||||||
|
```
|
||||||
|
storage/
|
||||||
|
├── app/
|
||||||
|
│ ├── public/
|
||||||
|
│ └── .gitkeep
|
||||||
|
├── framework/
|
||||||
|
│ ├── cache/
|
||||||
|
│ ├── sessions/
|
||||||
|
│ ├── testing/
|
||||||
|
│ └── views/
|
||||||
|
└── logs/
|
||||||
|
├── laravel.log
|
||||||
|
└── .gitkeep
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 Best Practices
|
||||||
|
|
||||||
|
1. **Always use scripts**: Gunakan `docker-fix-permissions.sh` untuk consistency
|
||||||
|
2. **Regular checks**: Monitor permission setelah update containers
|
||||||
|
3. **Volume strategy**: Gunakan named volumes untuk persistent storage
|
||||||
|
4. **Backup first**: Backup data sebelum fix permission
|
||||||
|
5. **Test thoroughly**: Verify semua Laravel functionality setelah fix
|
||||||
|
|
||||||
|
## 📞 Troubleshooting Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Debug permission issues
|
||||||
|
docker-compose exec app ls -laR /var/www/html/storage/
|
||||||
|
|
||||||
|
# Check Laravel configuration
|
||||||
|
docker-compose exec app php artisan config:show logging
|
||||||
|
|
||||||
|
# Monitor Laravel logs
|
||||||
|
docker-compose exec app tail -f /var/www/html/storage/logs/laravel.log
|
||||||
|
|
||||||
|
# Test file writing
|
||||||
|
docker-compose exec app touch /var/www/html/storage/test.txt
|
||||||
|
|
||||||
|
# Check container user
|
||||||
|
docker-compose exec app whoami
|
||||||
|
docker-compose exec app id
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**✅ Dengan mengikuti panduan ini, masalah Laravel permission di Docker container akan teratasi.**
|
||||||
277
REDIS-FIX-GUIDE.md
Normal file
277
REDIS-FIX-GUIDE.md
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
# 🔴 Redis Fix Guide untuk Laravel Docker
|
||||||
|
|
||||||
|
## 🎯 Masalah yang Diselesaikan
|
||||||
|
|
||||||
|
**Error yang dialami:**
|
||||||
|
```
|
||||||
|
Class "Redis" not found
|
||||||
|
```
|
||||||
|
|
||||||
|
**Root Cause:**
|
||||||
|
- PHP Redis extension tidak terinstall di container
|
||||||
|
- Laravel dikonfigurasi untuk menggunakan Redis tetapi extension tidak tersedia
|
||||||
|
- Container perlu rebuild untuk install Redis extension
|
||||||
|
|
||||||
|
## 🚀 Solusi yang Diimplementasi
|
||||||
|
|
||||||
|
### **1. Updated Dockerfiles**
|
||||||
|
|
||||||
|
**Production (Dockerfile):**
|
||||||
|
```dockerfile
|
||||||
|
# Install Redis extension
|
||||||
|
RUN pecl install redis \
|
||||||
|
&& docker-php-ext-enable redis
|
||||||
|
```
|
||||||
|
|
||||||
|
**Development (Dockerfile.dev):**
|
||||||
|
```dockerfile
|
||||||
|
# Install Redis and Xdebug for development
|
||||||
|
RUN pecl install redis xdebug \
|
||||||
|
&& docker-php-ext-enable redis xdebug
|
||||||
|
```
|
||||||
|
|
||||||
|
### **2. Fix Steps yang Dijalankan**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Update Dockerfile dengan Redis extension
|
||||||
|
# 2. Rebuild container
|
||||||
|
docker-compose build --no-cache app
|
||||||
|
|
||||||
|
# 3. Restart container dengan image baru
|
||||||
|
docker-compose up -d app
|
||||||
|
|
||||||
|
# 4. Verify Redis extension installed
|
||||||
|
docker-compose exec app php -m | grep redis
|
||||||
|
|
||||||
|
# 5. Test Redis connection
|
||||||
|
docker-compose exec app php -r "
|
||||||
|
\$redis = new Redis();
|
||||||
|
\$redis->connect('redis', 6379);
|
||||||
|
echo 'Redis connected successfully';
|
||||||
|
"
|
||||||
|
|
||||||
|
# 6. Clear Laravel cache
|
||||||
|
docker-compose exec app php artisan config:clear
|
||||||
|
docker-compose exec app php artisan cache:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✅ Verifikasi Fix Berhasil
|
||||||
|
|
||||||
|
### **1. PHP Redis Extension**
|
||||||
|
```bash
|
||||||
|
# Cek extension terinstall
|
||||||
|
docker-compose exec app php -m | grep redis
|
||||||
|
# Output: redis
|
||||||
|
```
|
||||||
|
|
||||||
|
### **2. Redis Connection Test**
|
||||||
|
```bash
|
||||||
|
# Test koneksi Redis
|
||||||
|
./docker-test-redis.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Output:**
|
||||||
|
```
|
||||||
|
[SUCCESS] PHP Redis extension is installed
|
||||||
|
[SUCCESS] Redis server is responding
|
||||||
|
[SUCCESS] PHP Redis connection working
|
||||||
|
[SUCCESS] Laravel cache operations working
|
||||||
|
```
|
||||||
|
|
||||||
|
### **3. Web Application**
|
||||||
|
```bash
|
||||||
|
# Test web response
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/
|
||||||
|
# Output: 302 (redirect ke login page)
|
||||||
|
```
|
||||||
|
|
||||||
|
### **4. Laravel Cache Operations**
|
||||||
|
```bash
|
||||||
|
# Test Laravel cache dengan Redis
|
||||||
|
docker-compose exec app php artisan tinker --execute="
|
||||||
|
Cache::put('test', 'redis-working', 60);
|
||||||
|
echo Cache::get('test');
|
||||||
|
"
|
||||||
|
# Output: redis-working
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ Tools dan Scripts
|
||||||
|
|
||||||
|
### **`docker-test-redis.sh`**
|
||||||
|
Comprehensive Redis testing script:
|
||||||
|
- ✅ Test PHP Redis extension
|
||||||
|
- ✅ Test Redis server connection
|
||||||
|
- ✅ Test Laravel cache operations
|
||||||
|
- ✅ Show Redis configuration
|
||||||
|
- ✅ Show server information
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```bash
|
||||||
|
# Test development environment
|
||||||
|
./docker-test-redis.sh dev
|
||||||
|
|
||||||
|
# Test production environment
|
||||||
|
./docker-test-redis.sh prod
|
||||||
|
```
|
||||||
|
|
||||||
|
### **`docker-rebuild.sh`**
|
||||||
|
Updated untuk include Redis testing:
|
||||||
|
- ✅ Test Redis extension di build process
|
||||||
|
- ✅ Verify Redis connection setelah rebuild
|
||||||
|
- ✅ Comprehensive testing semua extensions
|
||||||
|
|
||||||
|
## 🔧 Laravel Configuration
|
||||||
|
|
||||||
|
### **Environment Variables (.env)**
|
||||||
|
```env
|
||||||
|
# Redis Configuration
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
# Cache using Redis
|
||||||
|
CACHE_DRIVER=redis
|
||||||
|
|
||||||
|
# Sessions using Redis
|
||||||
|
SESSION_DRIVER=redis
|
||||||
|
|
||||||
|
# Queue using Redis
|
||||||
|
QUEUE_CONNECTION=redis
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Config Files**
|
||||||
|
Laravel otomatis membaca konfigurasi dari environment variables untuk:
|
||||||
|
- `config/cache.php` - Cache driver
|
||||||
|
- `config/session.php` - Session driver
|
||||||
|
- `config/queue.php` - Queue driver
|
||||||
|
- `config/database.php` - Redis connection
|
||||||
|
|
||||||
|
## 🚨 Common Issues & Solutions
|
||||||
|
|
||||||
|
### **1. Redis Extension Missing**
|
||||||
|
**Symptoms:** `Class "Redis" not found`
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Rebuild containers
|
||||||
|
./docker-rebuild.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### **2. Redis Connection Failed**
|
||||||
|
**Symptoms:** `Connection refused`
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Check Redis container
|
||||||
|
docker-compose ps | grep redis
|
||||||
|
|
||||||
|
# Restart Redis
|
||||||
|
docker-compose restart redis
|
||||||
|
|
||||||
|
# Test connection
|
||||||
|
./docker-test-redis.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### **3. Laravel Config Not Loading**
|
||||||
|
**Symptoms:** Cache/session tidak menggunakan Redis
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Clear Laravel cache
|
||||||
|
docker-compose exec app php artisan config:clear
|
||||||
|
docker-compose exec app php artisan cache:clear
|
||||||
|
docker-compose exec app php artisan view:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
### **4. Permission Issues with Redis**
|
||||||
|
**Symptoms:** Cannot write to cache
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Fix permissions
|
||||||
|
./docker-fix-permissions.sh dev
|
||||||
|
|
||||||
|
# Clear cache
|
||||||
|
docker-compose exec app php artisan cache:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 Best Practices
|
||||||
|
|
||||||
|
### **1. Container Management**
|
||||||
|
- Always rebuild containers setelah update Dockerfile
|
||||||
|
- Use scripts untuk consistent operations
|
||||||
|
- Test functionality setelah changes
|
||||||
|
|
||||||
|
### **2. Development Workflow**
|
||||||
|
```bash
|
||||||
|
# Complete setup dengan Redis
|
||||||
|
./docker-quick-setup.sh dev
|
||||||
|
|
||||||
|
# Test semua functionality
|
||||||
|
./docker-test-redis.sh dev
|
||||||
|
|
||||||
|
# Fix jika ada issues
|
||||||
|
./docker-fix-permissions.sh dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### **3. Production Deployment**
|
||||||
|
```bash
|
||||||
|
# Build production containers
|
||||||
|
./docker-rebuild.sh prod
|
||||||
|
|
||||||
|
# Verify Redis working
|
||||||
|
./docker-test-redis.sh prod
|
||||||
|
|
||||||
|
# Import database
|
||||||
|
./docker-import-db.sh prod
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 Monitoring & Debugging
|
||||||
|
|
||||||
|
### **Redis Monitoring**
|
||||||
|
```bash
|
||||||
|
# Redis logs
|
||||||
|
docker-compose logs redis
|
||||||
|
|
||||||
|
# Redis CLI access
|
||||||
|
docker-compose exec redis redis-cli
|
||||||
|
|
||||||
|
# Redis info
|
||||||
|
docker-compose exec redis redis-cli info
|
||||||
|
|
||||||
|
# Monitor Redis commands
|
||||||
|
docker-compose exec redis redis-cli monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Laravel Debugging**
|
||||||
|
```bash
|
||||||
|
# Check Laravel logs
|
||||||
|
docker-compose exec app tail -f storage/logs/laravel.log
|
||||||
|
|
||||||
|
# Check cache status
|
||||||
|
docker-compose exec app php artisan cache:table
|
||||||
|
|
||||||
|
# Test cache manually
|
||||||
|
docker-compose exec app php artisan tinker
|
||||||
|
# Cache::put('test', 'value', 60);
|
||||||
|
# Cache::get('test');
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📈 Performance Tips
|
||||||
|
|
||||||
|
### **1. Redis Optimization**
|
||||||
|
- Use appropriate data types
|
||||||
|
- Set proper expiration times
|
||||||
|
- Monitor memory usage
|
||||||
|
|
||||||
|
### **2. Laravel Cache Strategy**
|
||||||
|
```bash
|
||||||
|
# Cache configuration
|
||||||
|
php artisan config:cache
|
||||||
|
|
||||||
|
# Cache routes
|
||||||
|
php artisan route:cache
|
||||||
|
|
||||||
|
# Cache views
|
||||||
|
php artisan view:cache
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**✅ Dengan implementasi fix ini, masalah "Class Redis not found" sudah teratasi dan aplikasi Laravel berjalan normal dengan Redis.**
|
||||||
0
bootstrap/cache/.gitignore
vendored
Normal file → Executable file
0
bootstrap/cache/.gitignore
vendored
Normal file → Executable file
74
docker-compose.prod.yml
Normal file
74
docker-compose.prod.yml
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: ckb-app-prod
|
||||||
|
restart: unless-stopped
|
||||||
|
working_dir: /var/www/html
|
||||||
|
volumes:
|
||||||
|
- ./storage:/var/www/html/storage
|
||||||
|
- ./bootstrap/cache:/var/www/html/bootstrap/cache
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
environment:
|
||||||
|
- APP_ENV=production
|
||||||
|
- APP_DEBUG=false
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: mysql:8.0
|
||||||
|
container_name: ckb-mysql-prod
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MYSQL_DATABASE: ckb_production
|
||||||
|
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
|
||||||
|
MYSQL_PASSWORD: ${DB_PASSWORD}
|
||||||
|
MYSQL_USER: ${DB_USERNAME}
|
||||||
|
volumes:
|
||||||
|
- mysql_data:/var/lib/mysql
|
||||||
|
- ./docker/mysql.cnf:/etc/mysql/conf.d/mysql.cnf
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: ckb-redis-prod
|
||||||
|
restart: unless-stopped
|
||||||
|
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- redis_data:/data
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
|
nginx-proxy:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: ckb-nginx-proxy
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./docker/nginx-proxy.conf:/etc/nginx/nginx.conf
|
||||||
|
- ./docker/ssl:/etc/nginx/ssl
|
||||||
|
depends_on:
|
||||||
|
- app
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql_data:
|
||||||
|
driver: local
|
||||||
|
redis_data:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ckb-network:
|
||||||
|
driver: bridge
|
||||||
87
docker-compose.yml
Normal file
87
docker-compose.yml
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.dev
|
||||||
|
container_name: ckb-app-dev
|
||||||
|
restart: unless-stopped
|
||||||
|
working_dir: /var/www/html
|
||||||
|
volumes:
|
||||||
|
- ./:/var/www/html
|
||||||
|
- ./docker/php.ini:/usr/local/etc/php/conf.d/local.ini
|
||||||
|
- storage_logs:/var/www/html/storage/logs
|
||||||
|
- storage_cache:/var/www/html/storage/framework
|
||||||
|
ports:
|
||||||
|
- "8000:80"
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- APP_ENV=local
|
||||||
|
- APP_DEBUG=true
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: mysql:8.0
|
||||||
|
container_name: ckb-mysql
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MYSQL_DATABASE: ckb_db
|
||||||
|
MYSQL_ROOT_PASSWORD: root
|
||||||
|
MYSQL_PASSWORD: password
|
||||||
|
MYSQL_USER: laravel
|
||||||
|
volumes:
|
||||||
|
- mysql_data:/var/lib/mysql
|
||||||
|
- ./ckb.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: ckb-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
|
phpmyadmin:
|
||||||
|
image: phpmyadmin/phpmyadmin
|
||||||
|
container_name: ckb-phpmyadmin
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
PMA_HOST: db
|
||||||
|
PMA_PORT: 3306
|
||||||
|
MYSQL_ROOT_PASSWORD: root
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
|
mailhog:
|
||||||
|
image: mailhog/mailhog
|
||||||
|
container_name: ckb-mailhog
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "1025:1025"
|
||||||
|
- "8025:8025"
|
||||||
|
networks:
|
||||||
|
- ckb-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql_data:
|
||||||
|
driver: local
|
||||||
|
storage_logs:
|
||||||
|
driver: local
|
||||||
|
storage_cache:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ckb-network:
|
||||||
|
driver: bridge
|
||||||
226
docker-fix-permissions.sh
Executable file
226
docker-fix-permissions.sh
Executable file
@@ -0,0 +1,226 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script untuk memperbaiki permission Laravel storage di Docker container
|
||||||
|
# Usage: ./docker-fix-permissions.sh [dev|prod]
|
||||||
|
|
||||||
|
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 values
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
dev|development)
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
prod|production|staging)
|
||||||
|
ENVIRONMENT="prod"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option $1"
|
||||||
|
echo "Usage: $0 [dev|prod]"
|
||||||
|
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 if containers are running
|
||||||
|
check_containers() {
|
||||||
|
local compose_file=""
|
||||||
|
local app_container=""
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
compose_file="docker-compose.yml"
|
||||||
|
app_container="ckb-app-dev"
|
||||||
|
else
|
||||||
|
compose_file="docker-compose.prod.yml"
|
||||||
|
app_container="ckb-app-prod"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker-compose -f "$compose_file" ps | grep -q "$app_container.*Up"; then
|
||||||
|
print_error "App container is not running!"
|
||||||
|
print_status "Please start the containers first:"
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
echo " ./docker-start.sh dev up"
|
||||||
|
else
|
||||||
|
echo " ./docker-start.sh prod up"
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMPOSE_FILE="$compose_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to create necessary directories
|
||||||
|
create_directories() {
|
||||||
|
print_status "Creating necessary Laravel directories..."
|
||||||
|
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app mkdir -p /var/www/html/storage/logs
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app mkdir -p /var/www/html/storage/framework/cache
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app mkdir -p /var/www/html/storage/framework/sessions
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app mkdir -p /var/www/html/storage/framework/views
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app mkdir -p /var/www/html/storage/app/public
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app mkdir -p /var/www/html/bootstrap/cache
|
||||||
|
|
||||||
|
print_success "Directories created!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to fix ownership
|
||||||
|
fix_ownership() {
|
||||||
|
print_status "Fixing ownership to www-data:www-data..."
|
||||||
|
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app chown -R www-data:www-data /var/www/html/storage
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app chown -R www-data:www-data /var/www/html/bootstrap/cache
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app chown -R www-data:www-data /var/www/html/public
|
||||||
|
|
||||||
|
print_success "Ownership fixed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to fix permissions
|
||||||
|
fix_permissions() {
|
||||||
|
print_status "Setting proper permissions (775)..."
|
||||||
|
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app chmod -R 775 /var/www/html/storage
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app chmod -R 775 /var/www/html/bootstrap/cache
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app chmod -R 755 /var/www/html/public
|
||||||
|
|
||||||
|
print_success "Permissions set!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to create .gitkeep files
|
||||||
|
create_gitkeep() {
|
||||||
|
print_status "Creating .gitkeep files for empty directories..."
|
||||||
|
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app touch /var/www/html/storage/logs/.gitkeep
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app touch /var/www/html/storage/framework/cache/.gitkeep
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app touch /var/www/html/storage/framework/sessions/.gitkeep
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app touch /var/www/html/storage/framework/views/.gitkeep
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app touch /var/www/html/storage/app/.gitkeep
|
||||||
|
|
||||||
|
print_success ".gitkeep files created!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test Laravel logging
|
||||||
|
test_logging() {
|
||||||
|
print_status "Testing Laravel logging..."
|
||||||
|
|
||||||
|
# Try to write to Laravel log
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec app php -r "file_put_contents('/var/www/html/storage/logs/laravel.log', 'Test log entry: ' . date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND | LOCK_EX);"; then
|
||||||
|
print_success "Laravel logging test passed!"
|
||||||
|
else
|
||||||
|
print_error "Laravel logging test failed!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test Laravel cache
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec app php artisan cache:clear > /dev/null 2>&1; then
|
||||||
|
print_success "Laravel cache test passed!"
|
||||||
|
else
|
||||||
|
print_warning "Laravel cache test failed (might be normal if no cache driver configured)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to create storage link
|
||||||
|
create_storage_link() {
|
||||||
|
print_status "Creating storage symbolic link..."
|
||||||
|
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec app php artisan storage:link > /dev/null 2>&1; then
|
||||||
|
print_success "Storage link created!"
|
||||||
|
else
|
||||||
|
print_warning "Storage link creation failed (might already exist)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show current permissions
|
||||||
|
show_permissions() {
|
||||||
|
print_status "Current storage permissions:"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app ls -la /var/www/html/storage/
|
||||||
|
echo ""
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app ls -la /var/www/html/storage/logs/ || true
|
||||||
|
echo ""
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app ls -la /var/www/html/bootstrap/cache/ || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show troubleshooting tips
|
||||||
|
show_tips() {
|
||||||
|
echo ""
|
||||||
|
print_status "🔧 Troubleshooting Tips:"
|
||||||
|
echo ""
|
||||||
|
echo "1. If you still get permission errors, try rebuilding containers:"
|
||||||
|
echo " ./docker-rebuild.sh $ENVIRONMENT"
|
||||||
|
echo ""
|
||||||
|
echo "2. For persistent permission issues, add this to your docker-compose volumes:"
|
||||||
|
echo " - ./storage:/var/www/html/storage"
|
||||||
|
echo ""
|
||||||
|
echo "3. Check Laravel .env file for correct LOG_CHANNEL setting:"
|
||||||
|
echo " LOG_CHANNEL=stack"
|
||||||
|
echo ""
|
||||||
|
echo "4. Monitor logs for more errors:"
|
||||||
|
echo " docker-compose -f $COMPOSE_FILE logs -f app"
|
||||||
|
echo ""
|
||||||
|
echo "5. Test Laravel application:"
|
||||||
|
echo " docker-compose -f $COMPOSE_FILE exec app php artisan tinker"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
print_status "🔧 Laravel Storage Permission Fix"
|
||||||
|
print_status "Environment: $ENVIRONMENT"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check prerequisites
|
||||||
|
check_containers
|
||||||
|
|
||||||
|
# Show current state
|
||||||
|
print_status "Before fixing - Current permissions:"
|
||||||
|
show_permissions
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_status "Fixing permissions..."
|
||||||
|
|
||||||
|
# Execute fix process
|
||||||
|
create_directories
|
||||||
|
fix_ownership
|
||||||
|
fix_permissions
|
||||||
|
create_gitkeep
|
||||||
|
create_storage_link
|
||||||
|
test_logging
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_status "After fixing - Updated permissions:"
|
||||||
|
show_permissions
|
||||||
|
|
||||||
|
# Show final status
|
||||||
|
echo ""
|
||||||
|
print_success "✅ Permission fix completed!"
|
||||||
|
|
||||||
|
# Show troubleshooting tips
|
||||||
|
show_tips
|
||||||
209
docker-import-db.sh
Executable file
209
docker-import-db.sh
Executable file
@@ -0,0 +1,209 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script untuk mengimport database backup ke MySQL Docker container
|
||||||
|
# Usage: ./docker-import-db.sh [dev|prod] [database_file.sql]
|
||||||
|
|
||||||
|
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 values
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
SQL_FILE="ckb.sql"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
dev|development)
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
prod|production|staging)
|
||||||
|
ENVIRONMENT="prod"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*.sql)
|
||||||
|
SQL_FILE="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option $1"
|
||||||
|
echo "Usage: $0 [dev|prod] [database_file.sql]"
|
||||||
|
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 if file exists
|
||||||
|
check_sql_file() {
|
||||||
|
if [[ ! -f "$SQL_FILE" ]]; then
|
||||||
|
print_error "SQL file '$SQL_FILE' not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
print_status "Found SQL file: $SQL_FILE ($(du -h "$SQL_FILE" | cut -f1))"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if containers are running
|
||||||
|
check_containers() {
|
||||||
|
local compose_file=""
|
||||||
|
local db_container=""
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
compose_file="docker-compose.yml"
|
||||||
|
db_container="ckb-mysql"
|
||||||
|
else
|
||||||
|
compose_file="docker-compose.prod.yml"
|
||||||
|
db_container="ckb-mysql-prod"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker-compose -f "$compose_file" ps | grep -q "$db_container.*Up"; then
|
||||||
|
print_error "Database container is not running!"
|
||||||
|
print_status "Please start the containers first:"
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
echo " ./docker-start.sh dev up"
|
||||||
|
else
|
||||||
|
echo " ./docker-start.sh prod up"
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to get database credentials
|
||||||
|
get_db_credentials() {
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
DB_HOST="ckb-mysql"
|
||||||
|
DB_NAME="ckb_db"
|
||||||
|
DB_USER="root"
|
||||||
|
DB_PASSWORD="root"
|
||||||
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
|
else
|
||||||
|
DB_HOST="ckb-mysql-prod"
|
||||||
|
DB_NAME="ckb_production"
|
||||||
|
DB_USER="root"
|
||||||
|
# For production, we should read from environment or prompt
|
||||||
|
if [[ -f .env.production ]]; then
|
||||||
|
DB_PASSWORD=$(grep DB_ROOT_PASSWORD .env.production | cut -d '=' -f2)
|
||||||
|
else
|
||||||
|
read -s -p "Enter MySQL root password for production: " DB_PASSWORD
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
COMPOSE_FILE="docker-compose.prod.yml"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to backup existing database
|
||||||
|
backup_existing_db() {
|
||||||
|
local backup_file="backup_before_import_$(date +%Y%m%d_%H%M%S).sql"
|
||||||
|
|
||||||
|
print_status "Creating backup of existing database..."
|
||||||
|
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T db mysqldump -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" > "$backup_file" 2>/dev/null; then
|
||||||
|
print_success "Existing database backed up to: $backup_file"
|
||||||
|
else
|
||||||
|
print_warning "Could not backup existing database (it might be empty)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to import database
|
||||||
|
import_database() {
|
||||||
|
print_status "Importing database from $SQL_FILE..."
|
||||||
|
print_status "This may take a while for large files..."
|
||||||
|
|
||||||
|
# Drop and recreate database to ensure clean import
|
||||||
|
print_status "Recreating database..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec -T db mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "DROP DATABASE IF EXISTS $DB_NAME;"
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec -T db mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||||
|
|
||||||
|
# Import the SQL file
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T db mysql -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" < "$SQL_FILE"; then
|
||||||
|
print_success "Database imported successfully!"
|
||||||
|
else
|
||||||
|
print_error "Failed to import database!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to run Laravel migrations (if needed)
|
||||||
|
run_migrations() {
|
||||||
|
print_status "Checking if Laravel migrations need to be run..."
|
||||||
|
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec app php artisan migrate:status > /dev/null 2>&1; then
|
||||||
|
print_status "Running any pending migrations..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app php artisan migrate --force
|
||||||
|
else
|
||||||
|
print_warning "Could not check migration status. Skipping migrations."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to clear Laravel cache
|
||||||
|
clear_cache() {
|
||||||
|
print_status "Clearing Laravel cache..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app php artisan cache:clear || true
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app php artisan config:clear || true
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec app php artisan view:clear || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
print_status "Database Import Script for CKB Laravel Application"
|
||||||
|
print_status "Environment: $ENVIRONMENT"
|
||||||
|
print_status "SQL File: $SQL_FILE"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check prerequisites
|
||||||
|
check_sql_file
|
||||||
|
get_db_credentials
|
||||||
|
check_containers
|
||||||
|
|
||||||
|
# Ask for confirmation
|
||||||
|
echo ""
|
||||||
|
print_warning "This will replace the existing database in $ENVIRONMENT environment!"
|
||||||
|
read -p "Are you sure you want to continue? (y/N): " -n 1 -r
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_status "Import cancelled."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute import
|
||||||
|
backup_existing_db
|
||||||
|
import_database
|
||||||
|
|
||||||
|
# Post-import tasks
|
||||||
|
print_status "Running post-import tasks..."
|
||||||
|
run_migrations
|
||||||
|
clear_cache
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_success "Database import completed successfully!"
|
||||||
|
print_status "Database: $DB_NAME"
|
||||||
|
print_status "Environment: $ENVIRONMENT"
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
echo ""
|
||||||
|
print_status "You can now access your application at:"
|
||||||
|
echo " - Web App: http://localhost:8000"
|
||||||
|
echo " - phpMyAdmin: http://localhost:8080"
|
||||||
|
fi
|
||||||
239
docker-quick-setup.sh
Executable file
239
docker-quick-setup.sh
Executable file
@@ -0,0 +1,239 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Quick Setup Script untuk CKB Laravel Application dengan Auto Import Database
|
||||||
|
# Usage: ./docker-quick-setup.sh [dev|prod]
|
||||||
|
|
||||||
|
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 values
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
dev|development)
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
prod|production|staging)
|
||||||
|
ENVIRONMENT="prod"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option $1"
|
||||||
|
echo "Usage: $0 [dev|prod]"
|
||||||
|
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 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 setup environment file
|
||||||
|
setup_env() {
|
||||||
|
if [[ ! -f .env ]]; then
|
||||||
|
if [[ -f docker/env.example ]]; then
|
||||||
|
print_status "Setting up environment file..."
|
||||||
|
cp docker/env.example .env
|
||||||
|
print_success "Environment file created: .env"
|
||||||
|
else
|
||||||
|
print_error "No environment template found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_status "Environment file already exists: .env"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if database file exists
|
||||||
|
check_db_file() {
|
||||||
|
if [[ ! -f ckb.sql ]]; then
|
||||||
|
print_error "Database backup file 'ckb.sql' not found!"
|
||||||
|
print_status "Please make sure you have the ckb.sql file in the project root."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
print_status "Found database backup: ckb.sql ($(du -h ckb.sql | cut -f1))"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to start containers
|
||||||
|
start_containers() {
|
||||||
|
print_status "Starting Docker containers for $ENVIRONMENT environment..."
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
print_status "This will start development environment with:"
|
||||||
|
echo " - MySQL with auto-import from ckb.sql"
|
||||||
|
echo " - Redis for caching"
|
||||||
|
echo " - phpMyAdmin for database management"
|
||||||
|
echo " - MailHog for email testing"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
|
print_success "Development containers started!"
|
||||||
|
echo ""
|
||||||
|
print_status "Services are starting up... Please wait..."
|
||||||
|
|
||||||
|
# Wait for MySQL to be ready
|
||||||
|
print_status "Waiting for MySQL to be ready..."
|
||||||
|
sleep 20
|
||||||
|
|
||||||
|
# Check if database was imported automatically
|
||||||
|
if docker-compose exec -T db mysql -u root -proot -e "USE ckb_db; SHOW TABLES;" > /dev/null 2>&1; then
|
||||||
|
table_count=$(docker-compose exec -T db mysql -u root -proot -e "USE ckb_db; SHOW TABLES;" 2>/dev/null | wc -l)
|
||||||
|
if [[ $table_count -gt 1 ]]; then
|
||||||
|
print_success "Database automatically imported from ckb.sql!"
|
||||||
|
else
|
||||||
|
print_warning "Database not imported automatically. Running manual import..."
|
||||||
|
./docker-import-db.sh dev
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_warning "Database not accessible. Running manual import..."
|
||||||
|
sleep 10
|
||||||
|
./docker-import-db.sh dev
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
print_status "Starting production environment..."
|
||||||
|
if [[ ! -f .env.production ]]; then
|
||||||
|
print_warning "Creating production environment file..."
|
||||||
|
cp docker/env.example .env.production
|
||||||
|
print_warning "Please edit .env.production with your production settings!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker-compose -f docker-compose.prod.yml up -d --build
|
||||||
|
print_success "Production containers started!"
|
||||||
|
|
||||||
|
sleep 15
|
||||||
|
print_status "Importing database for production..."
|
||||||
|
./docker-import-db.sh prod
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to generate application key
|
||||||
|
generate_app_key() {
|
||||||
|
print_status "Generating Laravel application key..."
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
docker-compose exec app php artisan key:generate
|
||||||
|
else
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan key:generate
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to run Laravel setup commands
|
||||||
|
setup_laravel() {
|
||||||
|
print_status "Setting up Laravel application..."
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
COMPOSE_CMD="docker-compose exec app"
|
||||||
|
else
|
||||||
|
COMPOSE_CMD="docker-compose -f docker-compose.prod.yml exec app"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clear caches
|
||||||
|
$COMPOSE_CMD php artisan cache:clear || true
|
||||||
|
$COMPOSE_CMD php artisan config:clear || true
|
||||||
|
$COMPOSE_CMD php artisan view:clear || true
|
||||||
|
|
||||||
|
# Set up storage links
|
||||||
|
$COMPOSE_CMD php artisan storage:link || true
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "prod" ]]; then
|
||||||
|
print_status "Optimizing for production..."
|
||||||
|
$COMPOSE_CMD php artisan config:cache
|
||||||
|
$COMPOSE_CMD php artisan route:cache
|
||||||
|
$COMPOSE_CMD php artisan view:cache
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show access information
|
||||||
|
show_access_info() {
|
||||||
|
echo ""
|
||||||
|
print_success "🎉 CKB Laravel Application is now ready!"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
print_status "Development Environment Access:"
|
||||||
|
echo " 🌐 Web Application: http://localhost:8000"
|
||||||
|
echo " 📊 phpMyAdmin: http://localhost:8080"
|
||||||
|
echo " - Server: db"
|
||||||
|
echo " - Username: root"
|
||||||
|
echo " - Password: root"
|
||||||
|
echo " - Database: ckb_db"
|
||||||
|
echo ""
|
||||||
|
echo " 📧 MailHog (Email Testing): http://localhost:8025"
|
||||||
|
echo " 🗄️ MySQL Direct: localhost:3306"
|
||||||
|
echo " 🔴 Redis: localhost:6379"
|
||||||
|
echo ""
|
||||||
|
print_status "Useful Commands:"
|
||||||
|
echo " - View logs: docker-compose logs -f"
|
||||||
|
echo " - Access container: docker-compose exec app bash"
|
||||||
|
echo " - Laravel commands: docker-compose exec app php artisan [command]"
|
||||||
|
echo " - Stop containers: docker-compose down"
|
||||||
|
else
|
||||||
|
print_status "Production Environment Access:"
|
||||||
|
echo " 🌐 Web Application: http://localhost (port 80)"
|
||||||
|
echo " 🗄️ Database: localhost:3306"
|
||||||
|
echo ""
|
||||||
|
print_status "Useful Commands:"
|
||||||
|
echo " - View logs: docker-compose -f docker-compose.prod.yml logs -f"
|
||||||
|
echo " - Access container: docker-compose -f docker-compose.prod.yml exec app bash"
|
||||||
|
echo " - Stop containers: docker-compose -f docker-compose.prod.yml down"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_status "Database has been imported from ckb.sql successfully!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
echo "================================================"
|
||||||
|
print_status "🚀 CKB Laravel Application Quick Setup"
|
||||||
|
print_status "Environment: $ENVIRONMENT"
|
||||||
|
echo "================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check prerequisites
|
||||||
|
check_docker
|
||||||
|
check_db_file
|
||||||
|
|
||||||
|
# Setup process
|
||||||
|
setup_env
|
||||||
|
start_containers
|
||||||
|
generate_app_key
|
||||||
|
setup_laravel
|
||||||
|
|
||||||
|
# Show final information
|
||||||
|
show_access_info
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_success "✅ Quick setup completed successfully!"
|
||||||
231
docker-rebuild.sh
Executable file
231
docker-rebuild.sh
Executable file
@@ -0,0 +1,231 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script untuk rebuild Docker containers dari scratch
|
||||||
|
# Usage: ./docker-rebuild.sh [dev|prod]
|
||||||
|
|
||||||
|
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 values
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
dev|development)
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
prod|production|staging)
|
||||||
|
ENVIRONMENT="prod"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option $1"
|
||||||
|
echo "Usage: $0 [dev|prod]"
|
||||||
|
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 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 clean up existing containers and images
|
||||||
|
cleanup_containers() {
|
||||||
|
print_status "Cleaning up existing containers and images..."
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
|
APP_CONTAINER="ckb-app-dev"
|
||||||
|
else
|
||||||
|
COMPOSE_FILE="docker-compose.prod.yml"
|
||||||
|
APP_CONTAINER="ckb-app-prod"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stop and remove containers
|
||||||
|
print_status "Stopping containers..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" down || true
|
||||||
|
|
||||||
|
# Remove specific containers if they exist
|
||||||
|
if docker ps -a --format "table {{.Names}}" | grep -q "$APP_CONTAINER"; then
|
||||||
|
print_status "Removing existing app container..."
|
||||||
|
docker rm -f "$APP_CONTAINER" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove images related to this project
|
||||||
|
print_status "Removing existing images..."
|
||||||
|
docker images | grep "ckb" | awk '{print $3}' | xargs docker rmi -f || true
|
||||||
|
|
||||||
|
print_success "Cleanup completed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to prune Docker system
|
||||||
|
prune_docker() {
|
||||||
|
print_status "Pruning Docker system to free up space..."
|
||||||
|
|
||||||
|
# Remove unused containers, networks, images
|
||||||
|
docker system prune -f
|
||||||
|
|
||||||
|
# Remove unused volumes (be careful with this)
|
||||||
|
print_warning "Removing unused Docker volumes..."
|
||||||
|
docker volume prune -f
|
||||||
|
|
||||||
|
print_success "Docker system pruned!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to build containers
|
||||||
|
build_containers() {
|
||||||
|
print_status "Building containers for $ENVIRONMENT environment..."
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
print_status "Building development container..."
|
||||||
|
docker-compose build --no-cache --pull
|
||||||
|
print_success "Development container built successfully!"
|
||||||
|
else
|
||||||
|
print_status "Building production container..."
|
||||||
|
docker-compose -f docker-compose.prod.yml build --no-cache --pull
|
||||||
|
print_success "Production container built successfully!"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test build
|
||||||
|
test_build() {
|
||||||
|
print_status "Testing the build..."
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
|
else
|
||||||
|
COMPOSE_FILE="docker-compose.prod.yml"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start containers to test
|
||||||
|
print_status "Starting containers for testing..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" up -d
|
||||||
|
|
||||||
|
# Wait for containers to be ready
|
||||||
|
print_status "Waiting for containers to be ready..."
|
||||||
|
sleep 15
|
||||||
|
|
||||||
|
# Test PHP version and extensions
|
||||||
|
print_status "Testing PHP and extensions..."
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T app php -v; then
|
||||||
|
print_success "PHP is working!"
|
||||||
|
else
|
||||||
|
print_error "PHP test failed!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test PHP extensions
|
||||||
|
print_status "Checking PHP extensions..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec -T app php -m | grep -E "(curl|gd|zip|dom|mysql|redis)" || true
|
||||||
|
|
||||||
|
# Test Redis connection
|
||||||
|
print_status "Testing Redis connection..."
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T app php -r "try { \$redis = new Redis(); \$redis->connect('redis', 6379); echo 'OK'; } catch (Exception \$e) { echo 'FAILED'; }" | grep -q "OK"; then
|
||||||
|
print_success "Redis connection test passed!"
|
||||||
|
else
|
||||||
|
print_warning "Redis connection test failed!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test Laravel
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T app php artisan --version; then
|
||||||
|
print_success "Laravel is working!"
|
||||||
|
else
|
||||||
|
print_error "Laravel test failed!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_success "Build test completed successfully!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show next steps
|
||||||
|
show_next_steps() {
|
||||||
|
echo ""
|
||||||
|
print_success "🎉 Rebuild completed successfully!"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
print_status "Development environment is ready!"
|
||||||
|
echo ""
|
||||||
|
print_status "Next steps:"
|
||||||
|
echo " 1. Import your database:"
|
||||||
|
echo " ./docker-import-db.sh dev"
|
||||||
|
echo ""
|
||||||
|
echo " 2. Access your application:"
|
||||||
|
echo " - Web App: http://localhost:8000"
|
||||||
|
echo " - phpMyAdmin: http://localhost:8080"
|
||||||
|
echo ""
|
||||||
|
echo " 3. Or use quick setup:"
|
||||||
|
echo " ./docker-quick-setup.sh dev"
|
||||||
|
else
|
||||||
|
print_status "Production environment is ready!"
|
||||||
|
echo ""
|
||||||
|
print_status "Next steps:"
|
||||||
|
echo " 1. Import your database:"
|
||||||
|
echo " ./docker-import-db.sh prod"
|
||||||
|
echo ""
|
||||||
|
echo " 2. Access your application:"
|
||||||
|
echo " - Web App: http://localhost"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
echo "================================================"
|
||||||
|
print_status "🔄 Docker Clean Rebuild Script"
|
||||||
|
print_status "Environment: $ENVIRONMENT"
|
||||||
|
echo "================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Ask for confirmation
|
||||||
|
print_warning "This will remove all existing containers, images, and volumes!"
|
||||||
|
print_warning "Any data not backed up will be lost!"
|
||||||
|
read -p "Are you sure you want to continue? (y/N): " -n 1 -r
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_status "Rebuild cancelled."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check prerequisites
|
||||||
|
check_docker
|
||||||
|
|
||||||
|
# Execute rebuild process
|
||||||
|
cleanup_containers
|
||||||
|
prune_docker
|
||||||
|
build_containers
|
||||||
|
test_build
|
||||||
|
|
||||||
|
# Show final information
|
||||||
|
show_next_steps
|
||||||
|
|
||||||
|
print_success "✅ Clean rebuild completed successfully!"
|
||||||
206
docker-start.sh
Executable file
206
docker-start.sh
Executable file
@@ -0,0 +1,206 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script untuk menjalankan CKB Laravel Application dengan Docker
|
||||||
|
# Usage: ./docker-start.sh [dev|prod] [up|down|build|logs]
|
||||||
|
|
||||||
|
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 values
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
ACTION="up"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
dev|development)
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
prod|production|staging)
|
||||||
|
ENVIRONMENT="prod"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
up|start)
|
||||||
|
ACTION="up"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
down|stop)
|
||||||
|
ACTION="down"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
build)
|
||||||
|
ACTION="build"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
logs)
|
||||||
|
ACTION="logs"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
ACTION="restart"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option $1"
|
||||||
|
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 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 setup environment file
|
||||||
|
setup_env() {
|
||||||
|
if [[ ! -f .env ]]; then
|
||||||
|
if [[ -f docker/env.example ]]; then
|
||||||
|
print_status "Copying environment file..."
|
||||||
|
cp docker/env.example .env
|
||||||
|
print_warning "Please edit .env file to configure your application"
|
||||||
|
else
|
||||||
|
print_error "No environment template found. Please create .env file manually."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to generate application key
|
||||||
|
generate_key() {
|
||||||
|
if ! grep -q "APP_KEY=base64:" .env; then
|
||||||
|
print_status "Generating Laravel application key..."
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
docker-compose exec app php artisan key:generate || true
|
||||||
|
else
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan key:generate || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to run migrations
|
||||||
|
run_migrations() {
|
||||||
|
print_status "Running database migrations..."
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
docker-compose exec app php artisan migrate --force
|
||||||
|
else
|
||||||
|
docker-compose -f docker-compose.prod.yml exec app php artisan migrate --force
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to optimize for production
|
||||||
|
optimize_production() {
|
||||||
|
if [[ $ENVIRONMENT == "prod" ]]; then
|
||||||
|
print_status "Optimizing for production..."
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
print_status "Starting CKB Laravel Application with Docker"
|
||||||
|
print_status "Environment: $ENVIRONMENT"
|
||||||
|
print_status "Action: $ACTION"
|
||||||
|
|
||||||
|
# Check prerequisites
|
||||||
|
check_docker
|
||||||
|
|
||||||
|
case $ACTION in
|
||||||
|
up|start)
|
||||||
|
setup_env
|
||||||
|
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
print_status "Starting development environment..."
|
||||||
|
docker-compose up -d --build
|
||||||
|
print_success "Development environment started!"
|
||||||
|
echo ""
|
||||||
|
print_status "Access your application at:"
|
||||||
|
echo " - Web App: http://localhost:8000"
|
||||||
|
echo " - phpMyAdmin: http://localhost:8080"
|
||||||
|
echo " - MailHog: http://localhost:8025"
|
||||||
|
else
|
||||||
|
print_status "Starting production environment..."
|
||||||
|
docker-compose -f docker-compose.prod.yml up -d --build
|
||||||
|
print_success "Production environment started!"
|
||||||
|
echo ""
|
||||||
|
print_status "Application is running on port 80"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait for containers to be ready
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
generate_key
|
||||||
|
run_migrations
|
||||||
|
optimize_production
|
||||||
|
;;
|
||||||
|
|
||||||
|
down|stop)
|
||||||
|
print_status "Stopping containers..."
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
docker-compose down
|
||||||
|
else
|
||||||
|
docker-compose -f docker-compose.prod.yml down
|
||||||
|
fi
|
||||||
|
print_success "Containers stopped!"
|
||||||
|
;;
|
||||||
|
|
||||||
|
build)
|
||||||
|
print_status "Building containers..."
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
docker-compose build --no-cache
|
||||||
|
else
|
||||||
|
docker-compose -f docker-compose.prod.yml build --no-cache
|
||||||
|
fi
|
||||||
|
print_success "Build completed!"
|
||||||
|
;;
|
||||||
|
|
||||||
|
logs)
|
||||||
|
print_status "Showing logs..."
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
docker-compose logs -f
|
||||||
|
else
|
||||||
|
docker-compose -f docker-compose.prod.yml logs -f
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
restart)
|
||||||
|
print_status "Restarting containers..."
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
docker-compose restart
|
||||||
|
else
|
||||||
|
docker-compose -f docker-compose.prod.yml restart
|
||||||
|
fi
|
||||||
|
print_success "Containers restarted!"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_success "Operation completed successfully!"
|
||||||
240
docker-test-redis.sh
Executable file
240
docker-test-redis.sh
Executable file
@@ -0,0 +1,240 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script untuk test Redis functionality di Docker environment
|
||||||
|
# Usage: ./docker-test-redis.sh [dev|prod]
|
||||||
|
|
||||||
|
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 values
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
dev|development)
|
||||||
|
ENVIRONMENT="dev"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
prod|production|staging)
|
||||||
|
ENVIRONMENT="prod"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option $1"
|
||||||
|
echo "Usage: $0 [dev|prod]"
|
||||||
|
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 get compose file
|
||||||
|
get_compose_file() {
|
||||||
|
if [[ $ENVIRONMENT == "dev" ]]; then
|
||||||
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
|
else
|
||||||
|
COMPOSE_FILE="docker-compose.prod.yml"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if containers are running
|
||||||
|
check_containers() {
|
||||||
|
if ! docker-compose -f "$COMPOSE_FILE" ps | grep -q "redis.*Up"; then
|
||||||
|
print_error "Redis container is not running!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker-compose -f "$COMPOSE_FILE" ps | grep -q "app.*Up"; then
|
||||||
|
print_error "App container is not running!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test PHP Redis extension
|
||||||
|
test_redis_extension() {
|
||||||
|
print_status "Testing PHP Redis extension..."
|
||||||
|
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T app php -m | grep -q "redis"; then
|
||||||
|
print_success "PHP Redis extension is installed"
|
||||||
|
else
|
||||||
|
print_error "PHP Redis extension is NOT installed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test Redis server connection
|
||||||
|
test_redis_connection() {
|
||||||
|
print_status "Testing Redis server connection..."
|
||||||
|
|
||||||
|
# Test direct connection to Redis container
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T redis redis-cli ping | grep -q "PONG"; then
|
||||||
|
print_success "Redis server is responding"
|
||||||
|
else
|
||||||
|
print_error "Redis server is not responding"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test connection from PHP
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T app php -r "
|
||||||
|
try {
|
||||||
|
\$redis = new Redis();
|
||||||
|
\$redis->connect('redis', 6379);
|
||||||
|
echo 'OK';
|
||||||
|
} catch (Exception \$e) {
|
||||||
|
echo 'FAILED: ' . \$e->getMessage();
|
||||||
|
}
|
||||||
|
" | grep -q "OK"; then
|
||||||
|
print_success "PHP Redis connection working"
|
||||||
|
else
|
||||||
|
print_error "PHP Redis connection failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test Laravel cache with Redis
|
||||||
|
test_laravel_cache() {
|
||||||
|
print_status "Testing Laravel cache with Redis..."
|
||||||
|
|
||||||
|
# Test cache clear
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T app php artisan cache:clear > /dev/null 2>&1; then
|
||||||
|
print_success "Laravel cache clear working"
|
||||||
|
else
|
||||||
|
print_warning "Laravel cache clear failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test cache set/get
|
||||||
|
local test_key="test_$(date +%s)"
|
||||||
|
local test_value="redis_test_value"
|
||||||
|
|
||||||
|
if docker-compose -f "$COMPOSE_FILE" exec -T app php artisan tinker --execute="
|
||||||
|
Cache::put('$test_key', '$test_value', 60);
|
||||||
|
echo Cache::get('$test_key');
|
||||||
|
" | grep -q "$test_value"; then
|
||||||
|
print_success "Laravel cache operations working"
|
||||||
|
else
|
||||||
|
print_error "Laravel cache operations failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test Redis session storage
|
||||||
|
test_redis_sessions() {
|
||||||
|
print_status "Testing Redis session configuration..."
|
||||||
|
|
||||||
|
# Check session driver in config
|
||||||
|
local session_driver=$(docker-compose -f "$COMPOSE_FILE" exec -T app php -r "echo config('session.driver');")
|
||||||
|
|
||||||
|
if [[ "$session_driver" == "redis" ]]; then
|
||||||
|
print_success "Laravel sessions configured to use Redis"
|
||||||
|
else
|
||||||
|
print_warning "Laravel sessions not using Redis (current: $session_driver)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test Redis queue configuration
|
||||||
|
test_redis_queue() {
|
||||||
|
print_status "Testing Redis queue configuration..."
|
||||||
|
|
||||||
|
# Check queue driver in config
|
||||||
|
local queue_driver=$(docker-compose -f "$COMPOSE_FILE" exec -T app php -r "echo config('queue.default');")
|
||||||
|
|
||||||
|
if [[ "$queue_driver" == "redis" ]]; then
|
||||||
|
print_success "Laravel queue configured to use Redis"
|
||||||
|
else
|
||||||
|
print_warning "Laravel queue not using Redis (current: $queue_driver)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show Redis info
|
||||||
|
show_redis_info() {
|
||||||
|
print_status "Redis server information:"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec redis redis-cli info server | head -10
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_status "Redis memory usage:"
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec redis redis-cli info memory | grep used_memory_human
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_status "Redis connected clients:"
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec redis redis-cli info clients | grep connected_clients
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show Laravel configuration
|
||||||
|
show_laravel_config() {
|
||||||
|
print_status "Laravel Redis configuration:"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_status "Cache driver:"
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec -T app php -r "echo 'CACHE_DRIVER=' . config('cache.default') . PHP_EOL;"
|
||||||
|
|
||||||
|
print_status "Session driver:"
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec -T app php -r "echo 'SESSION_DRIVER=' . config('session.driver') . PHP_EOL;"
|
||||||
|
|
||||||
|
print_status "Queue driver:"
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec -T app php -r "echo 'QUEUE_CONNECTION=' . config('queue.default') . PHP_EOL;"
|
||||||
|
|
||||||
|
print_status "Redis host:"
|
||||||
|
docker-compose -f "$COMPOSE_FILE" exec -T app php -r "echo 'REDIS_HOST=' . config('database.redis.default.host') . PHP_EOL;"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
echo "================================================"
|
||||||
|
print_status "🔴 Redis Functionality Test"
|
||||||
|
print_status "Environment: $ENVIRONMENT"
|
||||||
|
echo "================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Get compose file
|
||||||
|
get_compose_file
|
||||||
|
|
||||||
|
# Check prerequisites
|
||||||
|
check_containers
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
print_status "Running Redis tests..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
test_redis_extension && echo ""
|
||||||
|
test_redis_connection && echo ""
|
||||||
|
test_laravel_cache && echo ""
|
||||||
|
test_redis_sessions && echo ""
|
||||||
|
test_redis_queue && echo ""
|
||||||
|
|
||||||
|
# Show information
|
||||||
|
show_redis_info
|
||||||
|
echo ""
|
||||||
|
show_laravel_config
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_success "✅ Redis functionality test completed!"
|
||||||
|
|
||||||
|
print_status "🔧 Troubleshooting commands:"
|
||||||
|
echo " - Redis logs: docker-compose -f $COMPOSE_FILE logs redis"
|
||||||
|
echo " - App logs: docker-compose -f $COMPOSE_FILE logs app"
|
||||||
|
echo " - Redis CLI: docker-compose -f $COMPOSE_FILE exec redis redis-cli"
|
||||||
|
echo " - Test cache: docker-compose -f $COMPOSE_FILE exec app php artisan cache:clear"
|
||||||
56
docker/env.example
Normal file
56
docker/env.example
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
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 Docker
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=db
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=ckb_db
|
||||||
|
DB_USERNAME=laravel
|
||||||
|
DB_PASSWORD=password
|
||||||
|
DB_ROOT_PASSWORD=root
|
||||||
|
|
||||||
|
# Redis Configuration for Docker
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
# Cache Configuration
|
||||||
|
CACHE_DRIVER=redis
|
||||||
|
QUEUE_CONNECTION=redis
|
||||||
|
SESSION_DRIVER=redis
|
||||||
|
|
||||||
|
# Mail Configuration (using MailHog for development)
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=mailhog
|
||||||
|
MAIL_PORT=1025
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_FROM_ADDRESS=noreply@ckb.local
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
# Broadcasting
|
||||||
|
BROADCAST_DRIVER=log
|
||||||
|
|
||||||
|
# AWS (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 (if needed)
|
||||||
|
PUSHER_APP_ID=
|
||||||
|
PUSHER_APP_KEY=
|
||||||
|
PUSHER_APP_SECRET=
|
||||||
|
PUSHER_APP_CLUSTER=mt1
|
||||||
|
|
||||||
|
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||||
|
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
30
docker/mysql.cnf
Normal file
30
docker/mysql.cnf
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
[mysqld]
|
||||||
|
# General settings
|
||||||
|
default-authentication-plugin = mysql_native_password
|
||||||
|
character-set-server = utf8mb4
|
||||||
|
collation-server = utf8mb4_unicode_ci
|
||||||
|
|
||||||
|
# Connection settings
|
||||||
|
max_connections = 200
|
||||||
|
connect_timeout = 60
|
||||||
|
wait_timeout = 600
|
||||||
|
interactive_timeout = 600
|
||||||
|
|
||||||
|
# Buffer settings
|
||||||
|
innodb_buffer_pool_size = 256M
|
||||||
|
innodb_log_file_size = 64M
|
||||||
|
innodb_log_buffer_size = 16M
|
||||||
|
innodb_flush_log_at_trx_commit = 1
|
||||||
|
|
||||||
|
# Query cache
|
||||||
|
query_cache_type = 1
|
||||||
|
query_cache_size = 32M
|
||||||
|
query_cache_limit = 2M
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
slow_query_log = 1
|
||||||
|
slow_query_log_file = /var/log/mysql/slow.log
|
||||||
|
long_query_time = 2
|
||||||
|
|
||||||
|
# Security
|
||||||
|
local_infile = 0
|
||||||
67
docker/nginx.conf
Normal file
67
docker/nginx.conf
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
root /var/www/html/public;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log;
|
||||||
|
error_log /var/log/nginx/error.log;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_read_timeout 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.(?!well-known).* {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Gzip compression
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_min_length 1024;
|
||||||
|
gzip_proxied expired no-cache no-store private must-revalidate auth;
|
||||||
|
gzip_types
|
||||||
|
application/atom+xml
|
||||||
|
application/javascript
|
||||||
|
application/json
|
||||||
|
application/ld+json
|
||||||
|
application/manifest+json
|
||||||
|
application/rss+xml
|
||||||
|
application/vnd.geo+json
|
||||||
|
application/vnd.ms-fontobject
|
||||||
|
application/x-font-ttf
|
||||||
|
application/x-web-app-manifest+json
|
||||||
|
application/xhtml+xml
|
||||||
|
application/xml
|
||||||
|
font/opentype
|
||||||
|
image/bmp
|
||||||
|
image/svg+xml
|
||||||
|
image/x-icon
|
||||||
|
text/cache-manifest
|
||||||
|
text/css
|
||||||
|
text/plain
|
||||||
|
text/vcard
|
||||||
|
text/vnd.rim.location.xloc
|
||||||
|
text/vtt
|
||||||
|
text/x-component
|
||||||
|
text/x-cross-domain-policy;
|
||||||
|
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
50
docker/nginx.dev.conf
Normal file
50
docker/nginx.dev.conf
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
root /var/www/html/public;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log;
|
||||||
|
error_log /var/log/nginx/error.log debug;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_read_timeout 300;
|
||||||
|
fastcgi_param XDEBUG_SESSION_START 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow access to Laravel Mix hot reload
|
||||||
|
location /sockjs-node {
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Proxy for webpack-dev-server
|
||||||
|
location /__webpack_hmr {
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Development-friendly settings
|
||||||
|
sendfile off;
|
||||||
|
client_max_body_size 100m;
|
||||||
|
}
|
||||||
36
docker/php.ini
Normal file
36
docker/php.ini
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
; PHP Configuration for CKB Laravel App
|
||||||
|
|
||||||
|
; Maximum execution time
|
||||||
|
max_execution_time = 300
|
||||||
|
|
||||||
|
; Maximum input time
|
||||||
|
max_input_time = 300
|
||||||
|
|
||||||
|
; Memory limit
|
||||||
|
memory_limit = 512M
|
||||||
|
|
||||||
|
; Upload settings
|
||||||
|
upload_max_filesize = 100M
|
||||||
|
post_max_size = 100M
|
||||||
|
max_file_uploads = 20
|
||||||
|
|
||||||
|
; Error reporting
|
||||||
|
display_errors = Off
|
||||||
|
log_errors = On
|
||||||
|
error_log = /var/log/php_errors.log
|
||||||
|
|
||||||
|
; Date settings
|
||||||
|
date.timezone = Asia/Jakarta
|
||||||
|
|
||||||
|
; Session settings
|
||||||
|
session.gc_maxlifetime = 1440
|
||||||
|
session.cookie_lifetime = 0
|
||||||
|
|
||||||
|
; OPcache settings
|
||||||
|
opcache.enable = 1
|
||||||
|
opcache.memory_consumption = 128
|
||||||
|
opcache.interned_strings_buffer = 8
|
||||||
|
opcache.max_accelerated_files = 4000
|
||||||
|
opcache.revalidate_freq = 2
|
||||||
|
opcache.fast_shutdown = 1
|
||||||
|
opcache.enable_cli = 1
|
||||||
34
docker/supervisord.conf
Normal file
34
docker/supervisord.conf
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
user=root
|
||||||
|
logfile=/var/log/supervisor/supervisord.log
|
||||||
|
pidfile=/var/run/supervisord.pid
|
||||||
|
|
||||||
|
[program:php-fpm]
|
||||||
|
command=php-fpm
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
priority=5
|
||||||
|
stdout_logfile=/var/log/supervisor/php-fpm.log
|
||||||
|
stderr_logfile=/var/log/supervisor/php-fpm.log
|
||||||
|
|
||||||
|
[program:nginx]
|
||||||
|
command=nginx -g "daemon off;"
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
priority=10
|
||||||
|
stdout_logfile=/var/log/supervisor/nginx.log
|
||||||
|
stderr_logfile=/var/log/supervisor/nginx.log
|
||||||
|
|
||||||
|
[program:laravel-worker]
|
||||||
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
|
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --max-time=3600
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
stopasgroup=true
|
||||||
|
killasgroup=true
|
||||||
|
user=www-data
|
||||||
|
numprocs=2
|
||||||
|
redirect_stderr=true
|
||||||
|
stdout_logfile=/var/www/html/storage/logs/worker.log
|
||||||
|
stopwaitsecs=3600
|
||||||
34
docker/supervisord.dev.conf
Normal file
34
docker/supervisord.dev.conf
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
user=root
|
||||||
|
logfile=/var/log/supervisor/supervisord.log
|
||||||
|
pidfile=/var/run/supervisord.pid
|
||||||
|
|
||||||
|
[program:php-fpm]
|
||||||
|
command=php-fpm
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
priority=5
|
||||||
|
stdout_logfile=/var/log/supervisor/php-fpm.log
|
||||||
|
stderr_logfile=/var/log/supervisor/php-fpm.log
|
||||||
|
|
||||||
|
[program:nginx]
|
||||||
|
command=nginx -g "daemon off;"
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
priority=10
|
||||||
|
stdout_logfile=/var/log/supervisor/nginx.log
|
||||||
|
stderr_logfile=/var/log/supervisor/nginx.log
|
||||||
|
|
||||||
|
[program:laravel-worker]
|
||||||
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
|
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --max-time=3600
|
||||||
|
autostart=false
|
||||||
|
autorestart=true
|
||||||
|
stopasgroup=true
|
||||||
|
killasgroup=true
|
||||||
|
user=www-data
|
||||||
|
numprocs=1
|
||||||
|
redirect_stderr=true
|
||||||
|
stdout_logfile=/var/www/html/storage/logs/worker.log
|
||||||
|
stopwaitsecs=3600
|
||||||
9
docker/xdebug.ini
Normal file
9
docker/xdebug.ini
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
zend_extension=xdebug
|
||||||
|
|
||||||
|
[xdebug]
|
||||||
|
xdebug.mode=debug
|
||||||
|
xdebug.start_with_request=yes
|
||||||
|
xdebug.client_host=host.docker.internal
|
||||||
|
xdebug.client_port=9003
|
||||||
|
xdebug.log=/var/log/xdebug.log
|
||||||
|
xdebug.idekey=PHPSTORM
|
||||||
0
public/.htaccess
Normal file → Executable file
0
public/.htaccess
Normal file → Executable file
0
public/C:\xampp\htdocs\api_bengkel2\storage\framework\views/037bf8ecbbe17e4df65ceecae527cc7e4e0ab084.php
Normal file → Executable file
0
public/C:\xampp\htdocs\api_bengkel2\storage\framework\views/037bf8ecbbe17e4df65ceecae527cc7e4e0ab084.php
Normal file → Executable file
0
public/C:\xampp\htdocs\api_bengkel2\storage\framework\views/4c2d57c9d485c1c84de3982fdf9f6fa6256879b9.php
Normal file → Executable file
0
public/C:\xampp\htdocs\api_bengkel2\storage\framework\views/4c2d57c9d485c1c84de3982fdf9f6fa6256879b9.php
Normal file → Executable file
0
public/C:\xampp\htdocs\api_bengkel2\storage\framework\views/d8bd527b75042b1fa9429e001c3ff686e1200d25.php
Normal file → Executable file
0
public/C:\xampp\htdocs\api_bengkel2\storage\framework\views/d8bd527b75042b1fa9429e001c3ff686e1200d25.php
Normal file → Executable file
0
public/C:\xampp\htdocs\api_bengkel2\storage\logs/laravel.log
Normal file → Executable file
0
public/C:\xampp\htdocs\api_bengkel2\storage\logs/laravel.log
Normal file → Executable file
0
public/assets/css/app.bundle.css
Normal file → Executable file
0
public/assets/css/app.bundle.css
Normal file → Executable file
0
public/assets/css/app.bundle.min.css
vendored
Normal file → Executable file
0
public/assets/css/app.bundle.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-2.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-2.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-2.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-2.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-2.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-2.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-2.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-2.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-3.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-3.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-3.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-3.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-3.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-3.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-3.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-3.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-4.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-4.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-4.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-4.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-4.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-4.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-4.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-4.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-5.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-5.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-5.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-5.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-5.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-5.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-5.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-5.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-6.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-6.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-6.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-6.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-6.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-6.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-6.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/error/error-6.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/faq/faq-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/faq/faq-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/faq/faq-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/faq/faq-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/faq/faq-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/faq/faq-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/faq/faq-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/faq/faq-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/inbox/inbox.css
Normal file → Executable file
0
public/assets/css/demo1/pages/inbox/inbox.css
Normal file → Executable file
0
public/assets/css/demo1/pages/inbox/inbox.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/inbox/inbox.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/inbox/inbox.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/inbox/inbox.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/inbox/inbox.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/inbox/inbox.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-2.css
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-2.css
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-2.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-2.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-2.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-2.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-2.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/invoices/invoice-2.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-2.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-2.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-2.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-2.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-2.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-2.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-2.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-2.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-3.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-3.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-3.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-3.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-3.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-3.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-3.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-3.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-4.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-4.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-4.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-4.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-4.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-4.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-4.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-4.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-5.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-5.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-5.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-5.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-5.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-5.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-5.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-5.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-6.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-6.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-6.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-6.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-6.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-6.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-6.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/login/login-6.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-1.css
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-1.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-1.rtl.css
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-1.rtl.min.css
vendored
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-2.css
Normal file → Executable file
0
public/assets/css/demo1/pages/pricing/pricing-2.css
Normal file → Executable file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user