diff --git a/Dockerfile b/Dockerfile index 2abcea3..2fab994 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,6 +22,8 @@ RUN apt-get update && apt-get install -y \ libvpx-dev \ supervisor \ nginx \ + nodejs \ + npm \ && rm -rf /var/lib/apt/lists/* # Install PHP extensions @@ -54,6 +56,11 @@ COPY --chown=www-data:www-data . /var/www/html # Install PHP dependencies RUN composer install --optimize-autoloader --no-dev --no-interaction +# Install Node.js dependencies and build assets +RUN npm ci --only=production \ + && npm run production \ + && rm -rf node_modules + # Create necessary directories and set permissions RUN mkdir -p /var/www/html/storage/logs \ && mkdir -p /var/www/html/storage/framework/cache \ diff --git a/debug-assets.sh b/debug-assets.sh new file mode 100755 index 0000000..20c7962 --- /dev/null +++ b/debug-assets.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# CKB Asset Debugging Script +echo "๐Ÿ” CKB Asset Debugging..." + +echo "๐Ÿ”ง Checking APP_URL configuration:" +docker-compose -f docker-compose.prod.yml exec app php artisan config:show app.url + +echo "" +echo "๐Ÿ“ Checking public directory structure:" +docker-compose -f docker-compose.prod.yml exec app ls -la /var/www/html/public/ + +echo "" +echo "๐Ÿ“ Checking CSS files:" +docker-compose -f docker-compose.prod.yml exec app ls -la /var/www/html/public/css/ + +echo "" +echo "๐Ÿ“ Checking JS files:" +docker-compose -f docker-compose.prod.yml exec app ls -la /var/www/html/public/js/ + +echo "" +echo "๐ŸŒ Testing CSS file accessibility:" +docker-compose -f docker-compose.prod.yml exec app curl -I http://localhost/css/app.css + +echo "" +echo "๐ŸŒ Testing JS file accessibility:" +docker-compose -f docker-compose.prod.yml exec app curl -I http://localhost/js/app.js + +echo "" +echo "๐Ÿ“ Checking nginx error logs:" +docker-compose -f docker-compose.prod.yml exec nginx-proxy tail -20 /var/log/nginx/error.log + +echo "" +echo "๐Ÿ“ Checking app nginx error logs:" +docker-compose -f docker-compose.prod.yml exec app tail -20 /var/log/nginx/error.log + +echo "" +echo "๐Ÿ”ง Checking nginx configuration:" +docker-compose -f docker-compose.prod.yml exec app nginx -t + +echo "" +echo "๐Ÿ”ง Checking proxy nginx configuration:" +docker-compose -f docker-compose.prod.yml exec nginx-proxy nginx -t + +echo "" +echo "๐Ÿ“Š Container status:" +docker-compose -f docker-compose.prod.yml ps + +echo "" +echo "๐ŸŒ Testing external access to CSS:" +echo "Try accessing: http://localhost:8082/css/app.css" +curl -I http://localhost:8082/css/app.css \ No newline at end of file diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..b55edc6 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# CKB Production Deployment Script +echo "๐Ÿš€ Starting CKB Production Deployment..." + +# Stop existing containers +echo "๐Ÿ“ฆ Stopping existing containers..." +docker-compose -f docker-compose.prod.yml down + +# Remove old images to force rebuild +echo "๐Ÿ—‘๏ธ Removing old images..." +docker image prune -f +docker rmi ckb-app-prod 2>/dev/null || true + +# Build and start containers +echo "๐Ÿ”จ Building and starting containers..." +docker-compose -f docker-compose.prod.yml up -d --build + +# Wait for containers to be ready +echo "โณ Waiting for containers to be ready..." +sleep 30 + +# Clear Laravel caches first +echo "๐Ÿงน Clearing Laravel caches..." +docker-compose -f docker-compose.prod.yml exec -T app php artisan config:clear +docker-compose -f docker-compose.prod.yml exec -T app php artisan route:clear +docker-compose -f docker-compose.prod.yml exec -T app php artisan view:clear +docker-compose -f docker-compose.prod.yml exec -T app php artisan cache:clear + +# Run Laravel optimizations +echo "โšก Running Laravel optimizations..." +docker-compose -f docker-compose.prod.yml exec -T app php artisan config:cache +docker-compose -f docker-compose.prod.yml exec -T app php artisan route:cache +docker-compose -f docker-compose.prod.yml exec -T app php artisan view:cache + +# Run migrations (if needed) +echo "๐Ÿ—„๏ธ Running database migrations..." +docker-compose -f docker-compose.prod.yml exec -T app php artisan migrate --force + +# Set proper permissions +echo "๐Ÿ” Setting proper permissions..." +docker-compose -f docker-compose.prod.yml exec -T app chown -R www-data:www-data /var/www/html/storage +docker-compose -f docker-compose.prod.yml exec -T app chown -R www-data:www-data /var/www/html/bootstrap/cache + +# Show container status +echo "๐Ÿ“Š Container status:" +docker-compose -f docker-compose.prod.yml ps + +# Show logs for debugging +echo "๐Ÿ“ Recent logs:" +docker-compose -f docker-compose.prod.yml logs --tail=20 + +echo "โœ… Deployment completed!" +echo "๐ŸŒ Application should be available at: http://localhost:8082" +echo "" +echo "To check logs: docker-compose -f docker-compose.prod.yml logs -f" +echo "To check app logs: docker-compose -f docker-compose.prod.yml logs -f app" \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index eb09a5c..e241f4a 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -15,7 +15,7 @@ services: environment: - APP_ENV=production - APP_DEBUG=false - - APP_URL=https://bengkel.digitaloasis.xyz + - APP_URL=http://bengkel.digitaloasis.xyz:8082 - TRUSTED_PROXIES=* depends_on: - db diff --git a/docker/env.example.production b/docker/env.example.production index 71cafc1..8149144 100644 --- a/docker/env.example.production +++ b/docker/env.example.production @@ -2,7 +2,7 @@ APP_NAME="CKB Bengkel System" APP_ENV=production APP_KEY= APP_DEBUG=false -APP_URL=https://bengkel.digitaloasis.xyz +APP_URL=http://bengkel.digitaloasis.xyz:8082 LOG_CHANNEL=stack LOG_LEVEL=error diff --git a/docker/nginx-proxy.conf b/docker/nginx-proxy.conf index 6bfd8a9..a97f6de 100644 --- a/docker/nginx-proxy.conf +++ b/docker/nginx-proxy.conf @@ -49,14 +49,96 @@ http { # HTTP server configuration server { listen 80; - server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz _; + server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz localhost _; # Let's Encrypt challenge location /.well-known/acme-challenge/ { root /var/www/certbot; } - # Main application for HTTP + # Handle static files with proper headers + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf)$ { + proxy_pass http://app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Forwarded-Port $server_port; + + # Cache static assets + expires 1y; + add_header Cache-Control "public, immutable"; + add_header Access-Control-Allow-Origin "*"; + + # Proxy timeouts + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + } + + # Handle Laravel Mix versioned assets + location ~* \.(css|js)\?id=[a-zA-Z0-9]+ { + proxy_pass http://app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Forwarded-Port $server_port; + + # Cache versioned assets + expires 1y; + add_header Cache-Control "public, immutable"; + add_header Access-Control-Allow-Origin "*"; + + # Proxy timeouts + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + } + + # Rate limiting for login endpoints + location ~ ^/(login|register|password) { + limit_req zone=login burst=5 nodelay; + proxy_pass http://app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Forwarded-Port $server_port; + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + } + + # Rate limiting for API endpoints + location /api/ { + limit_req zone=api burst=20 nodelay; + proxy_pass http://app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Forwarded-Port $server_port; + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + } + + # Health check endpoint + location /health { + access_log off; + proxy_pass http://app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # Main application for HTTP (catch-all) location / { proxy_pass http://app; proxy_set_header Host $host; @@ -70,31 +152,6 @@ http { proxy_send_timeout 300; } - # Handle static files - location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { - proxy_pass http://app; - expires 1y; - add_header Cache-Control "public, immutable"; - } - - # Rate limiting for login endpoints - location ~ ^/(login|register|password) { - limit_req zone=login burst=5 nodelay; - proxy_pass http://app; - } - - # Rate limiting for API endpoints - location /api/ { - limit_req zone=api burst=20 nodelay; - proxy_pass http://app; - } - - # Health check endpoint - location /health { - access_log off; - proxy_pass http://app; - } - # Block access to sensitive files location ~ /\. { deny all; diff --git a/docker/nginx.conf b/docker/nginx.conf index d488932..f4e69de 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -7,6 +7,22 @@ server { access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; + # Handle static assets (CSS, JS, images, fonts) + location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header Access-Control-Allow-Origin "*"; + try_files $uri =404; + } + + # Handle Laravel Mix versioned assets + location ~* \.(css|js)\?id=[a-zA-Z0-9]+ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header Access-Control-Allow-Origin "*"; + try_files $uri =404; + } + location / { try_files $uri $uri/ /index.php?$query_string; } @@ -17,6 +33,9 @@ server { fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_read_timeout 300; + fastcgi_buffer_size 128k; + fastcgi_buffers 4 256k; + fastcgi_busy_buffers_size 256k; } location ~ /\.ht { diff --git a/setup-env.sh b/setup-env.sh new file mode 100755 index 0000000..559e8db --- /dev/null +++ b/setup-env.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# CKB Production Environment Setup Script +echo "๐Ÿ”ง Setting up CKB Production Environment..." + +# Check if .env file exists +if [ -f ".env" ]; then + echo "โš ๏ธ .env file already exists. Creating backup..." + cp .env .env.backup.$(date +%Y%m%d_%H%M%S) +fi + +# Copy from example +echo "๐Ÿ“‹ Copying from production example..." +cp docker/env.example.production .env + +# Generate APP_KEY +echo "๐Ÿ”‘ Generating APP_KEY..." +docker-compose -f docker-compose.prod.yml run --rm app php artisan key:generate --force + +echo "โœ… Environment setup completed!" +echo "" +echo "๐Ÿ“ Please edit .env file and update the following:" +echo " - DB_PASSWORD (change from CHANGE_THIS_SECURE_PASSWORD)" +echo " - DB_ROOT_PASSWORD (change from CHANGE_THIS_ROOT_PASSWORD)" +echo " - REDIS_PASSWORD (change from CHANGE_THIS_REDIS_PASSWORD)" +echo " - Mail configuration if needed" +echo "" +echo "๐Ÿš€ After updating .env, run: ./deploy.sh" \ No newline at end of file