#!/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