๐Ÿš€ Panduan Lengkap Deploy Laravel di cPanel dengan GitHub CI/CD

๐Ÿ“‹ Daftar Isi

๐Ÿ› ๏ธ Prerequisites

Software yang Diperlukan:

Pengetahuan yang Diperlukan:

๐Ÿ“ฆ Setup GitHub Repository

1. Inisialisasi Git Repository

# Di folder project Laravel
git init
git add .
git commit -m "Initial commit"

2. Push ke GitHub

# Buat repository di GitHub
git remote add origin https://github.com/username/laravel-project.git
git branch -M main
git push -u origin main

3. Struktur Repository

laravel-project/ โ”œโ”€โ”€ .github/ โ”‚ โ””โ”€โ”€ workflows/ โ”‚ โ””โ”€โ”€ deploy.yml โ”œโ”€โ”€ app/ โ”œโ”€โ”€ config/ โ”œโ”€โ”€ database/ โ”œโ”€โ”€ resources/ โ”œโ”€โ”€ routes/ โ”œโ”€โ”€ storage/ โ”œโ”€โ”€ .env.example โ”œโ”€โ”€ composer.json โ””โ”€โ”€ README.md

โš™๏ธ Setup GitHub Actions

1. Buat Workflow File

Buat file .github/workflows/deploy.yml:

name: Deploy to CPanel
on:
    push:
        branches:
            - main
    workflow_dispatch:
        inputs:
            deployment_type:
                description: "Deployment type"
                required: true
                default: "incremental"
                type: choice
                options:
                    - incremental
                    - full
                    - force_all_php
            force_upload:
                description: "Force upload all PHP files (if auto-detection fails)"
                required: false
                default: "false"
                type: choice
                options:
                    - "false"
                    - "true"
jobs:
    FTP-Deploy-Action:
        name: FTP-Deploy-Action
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v4
              with:
                  fetch-depth: 2 # Get last 2 commits for diff
            # Skip build steps - just sync files directly

            - name: Determine deployment mode
              id: deploy_mode
              run: |
                  if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
                    DEPLOY_TYPE="${{ github.event.inputs.deployment_type }}"
                  else
                    DEPLOY_TYPE="incremental"
                  fi

                  echo "deployment_type=$DEPLOY_TYPE" >> $GITHUB_OUTPUT
                  echo "๐Ÿš€ Deployment mode: $DEPLOY_TYPE"

            - name: Smart Server Sync
              id: sync_deploy
              if: steps.deploy_mode.outputs.deployment_type == 'incremental'
              uses: nick-fields/retry@v2
              with:
                  timeout_minutes: 10
                  max_attempts: 3
                  retry_wait_seconds: 20
                  command: |
                      # Install lftp
                      sudo apt-get update && sudo apt-get install -y lftp

                      echo "๐Ÿ” Laravel Core Sync - Only sync important Laravel folders..."
                      echo "๐Ÿ“‹ Will sync: app/, bootstrap/, config/, public/, resources/, routes/"
                      echo "โšก Excluding: vendor/, .htaccess, index.php (server files)"
                      echo "โœ… Safe deployment - only application code"

                      # Use selective folder sync instead of full mirror
                      lftp -e "
                      set ftp:ssl-allow no;
                      set ftp:passive-mode on;
                      set net:timeout 60;
                      set net:max-retries 3;
                      set net:reconnect-interval-base 5;
                      open ftp://${{ secrets.USERNAME }}:${{ secrets.PASSWORD }}@${{ secrets.SERVER }};
                      cd /public_html/;
                      lcd ./;

                      echo 'Starting selective Laravel folder sync...';

                      # Sync only important Laravel folders
                      mirror --reverse --only-newer --verbose --parallel=2 app/ app/;
                      mirror --reverse --only-newer --verbose --parallel=2 bootstrap/ bootstrap/;
                      mirror --reverse --only-newer --verbose --parallel=2 config/ config/;
                      mirror --reverse --only-newer --verbose --parallel=2 resources/ resources/;
                      mirror --reverse --only-newer --verbose --parallel=2 routes/ routes/;

                      # Sync bootstrap/cache with delete to clear cache files
                      echo 'Syncing bootstrap/cache with delete to clear old cache...';
                      mirror --reverse --delete --verbose --parallel=1 bootstrap/cache/ bootstrap/cache/;

                      echo "โœ… Laravel cleared old cache files completed!";

                      # Sync public folder but exclude index.php and .htaccess
                      mirror --reverse --only-newer --verbose --parallel=2 --exclude='index.php' --exclude='.htaccess' public/ public/;

                      quit
                      "

                      echo "โœ… Laravel core sync completed!"
                      echo "๐Ÿงน Bootstrap cache cleared - server cache matches local cache"

            - name: Deployment Summary
              if: always()
              run: |
                  if [ "${{ steps.deploy_mode.outputs.deployment_type }}" = "full" ]; then
                    echo "โœ… Full deployment completed!"
                    echo "๐Ÿ”„ Future pushes will only deploy changed files."
                  elif [ "${{ steps.changes.outputs.has_changes }}" = "true" ]; then
                    echo "โœ… Selective deployment completed!"
                    echo " Uploaded: $(echo '${{ steps.changes.outputs.changed_files }}' | wc -l) files"
                    echo "๐Ÿ—‘๏ธ Deleted: $(echo '${{ steps.changes.outputs.deleted_files }}' | wc -l) files"
                    echo "โšก Only changed files were processed - no unnecessary transfers!"
                  else
                    echo "โ„น๏ธ No deployment needed - no relevant files changed."
                  fi
                  echo "๐ŸŽฏ Server synchronized with Git repository."

2. Setup GitHub Secrets

Di repository GitHub, buat secrets berikut:

๐ŸŒ Setup cPanel

1. Buat Subdomain (Opsional)

Subdomain: app.yourdomain.com
Document Root: home/username/app.yourdomain.com

2. Struktur Folder di cPanel

home/username/ โ”œโ”€โ”€ app.yourdomain.com/ โ† Subdomain โ”œโ”€โ”€ index.php โ”œโ”€โ”€ .htaccess โ”œโ”€โ”€ css/ โ”œโ”€โ”€ js/ โ”œโ”€โ”€ assets/ โ”œโ”€โ”€ app/ โ”œโ”€โ”€ resources/ โ”œโ”€โ”€ routes/ โ”œโ”€โ”€ config/ โ”œโ”€โ”€ storage/ โ”œโ”€โ”€ vendor/ โ””โ”€โ”€ .env

๐Ÿ—„๏ธ Konfigurasi Database

1. Buat Database di cPanel

  1. Buka cPanel โ†’ Manage My Database
  2. Buat database baru
  3. Buat user database
  4. Assign user ke database

2. Import Database

Via phpMyAdmin
Import file .sql dari local

3. Konfigurasi .env

APP_NAME="Your App Name"
APP_ENV=production
APP_KEY=base64:your-app-key-here
APP_DEBUG=false
APP_URL=https://app.yourdomain.com

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_user
DB_PASSWORD=your_database_password

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_CONNECTION=sync

๐Ÿ”ง Deploy Manual (Backup)

1. Upload File via File Manager

  1. Buka File Manager di cPanel
  2. Upload semua file Laravel ke root domain
  3. Upload folder public/ ke document root

2. Setup File Structure

public_html/ โ† Document root โ”œโ”€โ”€ index.php โ† Dari public/index.php โ”œโ”€โ”€ .htaccess โ† Dari public/.htaccess โ”œโ”€โ”€ css/ โ† Dari public/css/ โ”œโ”€โ”€ js/ โ† Dari public/js/ โ”œโ”€โ”€ assets/ โ† Dari public/assets/ โ”œโ”€โ”€ storages/ โ”œโ”€โ”€ app/ โ† Folder Laravel โ”œโ”€โ”€ resources/ โ”œโ”€โ”€ routes/ โ”œโ”€โ”€ config/ โ”œโ”€โ”€ storage/ โ”œโ”€โ”€ vendor/ โ””โ”€โ”€ .env

3. Edit index.php untuk Root Domain

<?php
// Ubah path di public/index.php
require __DIR__.'/../vendor/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';

๐Ÿ” Troubleshooting

Error 500 - Internal Server Error

Penyebab: Permissions salah atau file .env tidak ada
Solusi:
chmod 755 bootstrap/cache/
chmod 644 .env

Database Connection Error

Penyebab: Konfigurasi database salah
Solusi:
  1. Cek credentials database di .env
  2. Pastikan database dan user sudah dibuat
  3. Test koneksi database

๐Ÿ“ Checklist Deployment

โœ… Pre-Deployment

โœ… Deployment

โœ… Post-Deployment

๐Ÿ”„ Update dan Maintenance

Update via GitHub

  1. Push changes ke GitHub
  2. GitHub Actions akan otomatis deploy
  3. Monitor deployment di GitHub Actions tab

Manual Update

  1. Upload file yang diubah via File Manager
  2. Clear cache jika diperlukan
  3. Test functionality

Backup

  1. Backup database via phpMyAdmin
  2. Backup file via File Manager
  3. Simpan backup di lokasi aman

๐Ÿ“š Referensi


Last Updated: Agustus 2025
Version: 1.0
Author: Bagas "Renz" Agung