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