10 Masalah yang Sering Terjadi Saat Deploy Laravel dengan Git (Beserta Solusinya)

pindipin
24 September 2026
12 min read
10 Masalah yang Sering Terjadi Saat Deploy Laravel dengan Git (Beserta Solusinya)

Deploy aplikasi Laravel ke server VPS menggunakan Git sepintas terlihat sederhana. Cukup melakukan git pull origin main di folder server, lalu aplikasi langsung diperbarui. Namun pada praktiknya, alur sederhana ini sering memicu masalah teknis di lingkungan produksi.

Sebagian besar error terjadi akibat perbedaan lingkungan antara komputer lokal dan server VPS. Di komputer lokal, kamu mungkin menggunakan single user, web server bawaan (php artisan serve), serta APP_DEBUG=true. Sementara di server produksi Linux, Nginx atau Apache berjalan di bawah akun web server (www-data) dengan mode caching ketat dan proteksi keamanan.

Ketika kamu menjalankan git pull, Git hanya mengunduh perubahan source code yang dilacak. Git tidak mengelola hak akses direktori Linux, tidak otomatis menjalankan migrasi database, tidak mengkompilasi ulang asset frontend, dan tidak memuat ulang cache internal Laravel. Akibatnya, server rentan mengalami error 500, permission denied, hingga downtime.

Artikel ini membahas 10 masalah yang paling sering ditemui saat melakukan deployment Laravel berbasis Git di VPS beserta solusi konkretnya. Untuk otomatisasi penuh dari awal hingga CI/CD, kamu juga bisa mengikuti panduan cara deploy Laravel ke VPS serta menerapkan workflow Git Laravel agar manajemen kode lebih terstruktur.


1. Konfigurasi Environment (.env) Hilang atau Tertimpa

Akar Masalah

Secara standar keamanan framework, file .env masuk ke dalam .gitignore agar password database dan API key tidak terdorong ke repository. Saat repository di-clone pertama kali di server, file .env tidak akan ada. Sebaliknya, jika developer tak sengaja menghapus .env dari .gitignore dan melakukan commit file lokal, git pull di server akan menimpa konfigurasi database produksi dengan localhost.

Dampak

Aplikasi menampilkan 500 Internal Server Error atau exception InvalidArgumentException: No application encryption key has been specified. Jika .env produksi tertimpa file lokal, koneksi database akan putus atau kredensial bocor.

Solusi Konkret & Command

Untuk instalasi baru di server, salin .env.example menjadi .env lalu generate application key:

cp .env.example .env
php artisan key:generate

Buka .env di server dan sesuaikan variabel lingkungan produksi:

APP_NAME="Aplikasi Produksi"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://example.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nama_db_production
DB_USERNAME=user_db_production
DB_PASSWORD=password_db_rumit

Pastikan .env tetap ada di .gitignore lokal:

.env
.env.backup
.env.production

2. Error Hak Akses Directory storage/ dan bootstrap/cache/

Akar Masalah

Proses web server (Nginx/Apache) dan PHP-FPM di Linux berjalan di bawah user www-data. Sementara itu, sesi SSH tempat kamu menjalankan git pull berjalan di bawah akun SSH kamu (misalnya deployer atau ubuntu).

Saat Laravel menulis log di storage/logs/ atau menyimpan cache di bootstrap/cache/, PHP-FPM akan gagal jika direktori tersebut tidak memiliki permission tulis yang sesuai untuk user web server.

Dampak

Aplikasi crash dengan pesan error log khas Linux:

The stream or file "/var/www/my-app/storage/logs/laravel.log" could not be opened in append mode: failed to open stream: Permission denied

Solusi Konkret & Command

Ubah kepemilikan direktori storage dan bootstrap/cache ke user www-data. Gunakan perintah find untuk menetapkan permission 775 pada folder dan 664 pada file agar presisi tanpa membuat file biasa menjadi executable:

sudo chown -R www-data:www-data /var/www/my-app/storage /var/www/my-app/bootstrap/cache
sudo find /var/www/my-app/storage /var/www/my-app/bootstrap/cache -type d -exec chmod 775 {} +
sudo find /var/www/my-app/storage /var/www/my-app/bootstrap/cache -type f -exec chmod 664 {} +

Agar file baru otomatis mewarisi group www-data, tambahkan user SSH ke group www-data dan aktifkan bit SGID (g+s):

sudo usermod -a -G www-data deployer
sudo chmod -R g+s /var/www/my-app/storage /var/www/my-app/bootstrap/cache

3. Kegagalan composer install dan Ekstensi PHP Server Hilang

Akar Masalah

Tiga kendala utama pada Composer saat deploy Laravel:

  1. Menjalankan composer install tanpa melepaskan paket pengembangan (dev dependencies).
  2. Ekstensi PHP wajib Laravel (seperti ext-mbstring, ext-xml, ext-bcmath) belum terpasang di VPS.
  3. Server kehabisan RAM (Out of Memory / OOM) saat kalkulasi dependency graph pada VPS spesifikasi rendah.

Dampak

Deployment terhenti dengan error Memory limit exhausted, paket testing memenuhi server produksi, atau aplikasi melempar error Fatal error: Call to undefined function....

Solusi Konkret & Command

Gunakan flag --no-dev dan --optimize-autoloader saat memasang dependency di produksi:

composer install --no-dev --optimize-autoloader

Pastikan ekstensi PHP yang dibutuhkan Laravel sudah terpasang di VPS Ubuntu:

sudo apt update
sudo apt install php8.3-cli php8.3-fpm php8.3-mbstring php8.3-xml \
  php8.3-bcmath php8.3-curl php8.3-mysql php8.3-zip php8.3-gd php8.3-intl -y

Jika terjadi masalah memori pada VPS RAM 1GB, lewati batas memori sementara:

COMPOSER_MEMORY_LIMIT=-1 composer install --no-dev --optimize-autoloader

Pastikan file composer.lock selalu di-commit agar Composer tidak perlu mengkalkulasi ulang dependency di server.


4. Tampilan Hancur Akibat public/build (Vite) Tidak Di-build

Akar Masalah

Secara default, Laravel menggunakan Vite untuk mengkompilasi file CSS dan JavaScript. Folder hasil build (public/build) masuk ke .gitignore untuk menghindari konflik file terkompilasi saat kolaborasi.

Ketika kode ditarik via git pull di VPS tanpa proses build frontend, browser tidak menemukan file stylesheet dan skrip aplikasi.

Dampak

Tampilan aplikasi hancur tanpa styling CSS, atau muncul exception Laravel:

Vite manifest not found at: /var/www/my-app/public/build/manifest.json

Solusi Konkret & Command

Pilih salah satu dari dua pendekatan berikut:

Pendekatan A: Build di Server VPS

Jika VPS memiliki RAM memadai, pasang Node.js dan jalankan kompilasi setelah git pull:

npm ci
npm run build

Gunakan npm ci agar modul diinstall secara pasti sesuai package-lock.json.

Pendekatan B: Build di CI/CD (Rekomendasi VPS Kecil)

Jika RAM VPS terbatas, jalankan build di GitHub Actions lalu transfer folder public/build ke VPS via SSH/SCP. Kamu bisa membaca rincian setup CI/CD ini pada artikel cara deploy Laravel ke VPS:

- name: Build Frontend Assets
  run: |
    npm ci
    npm run build

- name: Deploy Assets to VPS
  uses: appleboy/scp-action@master
  with:
    host: ${{ secrets.SERVER_HOST }}
    username: ${{ secrets.SERVER_USER }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    source: "public/build"
    target: "/var/www/my-app"

5. Perubahan Kode / .env Tidak Berefek Akibat Stale Cache

Akar Masalah

Laravel membekukan konfigurasi (config:cache), rute (route:cache), dan Blade (view:cache) ke file cache tunggal di bootstrap/cache/ demi performa. Setelah git pull, PHP-FPM di server masih membaca file cache lama jika tidak diperbarui.

Selain itu, jika fungsi env() dipanggil langsung di luar file config/*.php, fungsi tersebut akan mengembalikan null begitu php artisan config:cache aktif.

Dampak

Perubahan variabel di .env atau rute baru tidak berefek di server. Pemanggilan env() langsung di Controller menghasilkan error null value.

Solusi Konkret & Command

Setiap selesai deployment, jalankan serangkaian perintah cache Artisan:

php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache

Jika terjadi error akibat cache rusak, bersihkan seluruh cache dengan perintah pemulihan:

php artisan optimize:clear

Aturan Penggunaan env() di Laravel

Jangan panggil env() langsung di Controller atau Service. Daftarkan variabel di file config/:

// config/services.php
return [
    'payment' => [
        'key' => env('PAYMENT_GATEWAY_KEY'),
    ],
];

Lalu panggil melalui helper config():

$apiKey = config('services.payment.key');

6. Migration Menolak Berjalan Tanpa Flag --force

Akar Masalah

Ketika APP_ENV=production aktif di .env, Laravel secara otomatis memblokir eksekusi migrasi skema database untuk mencegah perubahan accidental. Saat script deployment otomatis berjalan, migrasi akan terhenti karena menunggu konfirmasi interaktif (yes/no).

Dampak

Proses deployment hang atau gagal, dan skema database server tidak diperbarui. Aplikasi melempar error SQL saat mengakses tabel/kolom baru:

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'my_db.new_table' doesn't exist

Solusi Konkret & Command

Bypass konfirmasi interaktif di lingkungan produksi dengan flag --force:

php artisan migrate --force

Untuk migrasi tabel berukuran besar, terapkan alur bertahap: tambahkan kolom baru bertipe nullable, deploy kode baru yang menulis ke dua kolom, migrasikan data lama, lalu jalankan DROP COLUMN secara terpisah.


7. Storage Symlink Putus atau Belum Dibuat (public/storage)

Akar Masalah

File yang diunggah pengguna disimpan di privat storage/app/public/. Agar dapat diakses publik via URL, Laravel membutuhkan symbolic link dari public/storage ke storage/app/public.

Saat proyek baru di-clone di VPS atau ketika path direktori release berubah, symlink ini belum ada atau menjadi broken symlink.

Dampak

File unggahan pengguna (gambar avatar, dokumen PDF) mengembalikan status HTTP 404 Not Found.

Solusi Konkret & Command

Hapus symlink lama jika ada, lalu buat ulang symlink storage:

rm -rf public/storage
php artisan storage:link

8. Git Pull Gagal Akibat Perubahan Manual di Server (Detached HEAD)

Akar Masalah

Masalah ini terjadi jika ada pengeditan file langsung di VPS atau jika perubahan permission file Linux terdeteksi Git sebagai filemode change. Saat git pull dijalankan, Git menolak melakukan merge karena ada konflik dengan uncommitted changes di server.

Dampak

Proses git pull dibatalkan dengan error:

error: Your local changes to the following files would be overwritten by merge:
    app/Http/Controllers/OrderController.php
Please commit your changes or stash them before you merge.

Solusi Konkret & Command

Jangan pernah mengedit source code langsung di server produksi. Selalu ikuti workflow Git Laravel di lokal. Reset kerjaan lokal server secara paksa ke commit terbaru remote branch:

git fetch origin
git reset --hard origin/main
git clean -fd

Agar Git tidak melacak perubahan hak akses file Linux di VPS, nonaktifkan fileMode:

git config core.fileMode false

9. Web Server Downtime Saat Menjalankan Deployment

Akar Masalah

Melakukan git pull langsung di direktori aktif (/var/www/my-app) menyebabkan file di server berada dalam kondisi tidak lengkap selama proses pull, composer install, dan npm run build. Request pengguna yang masuk di sela waktu tersebut akan memicu error.

Dampak

Pengguna mendapati error 502 Bad Gateway, Class not found, atau tampilan aplikasi rusak sebagian saat deployment berjalan.

Solusi Konkret & Perbandingan Strategi

Strategi 1: Maintenance Mode (Sederhana)

Aktifkan maintenance mode sebelum deployment dan matikan kembali setelah selesai:

php artisan down --retry=60
git fetch origin && git reset --hard origin/main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan up

Flag --retry=60 mengirimkan header HTTP Retry-After: 60 untuk menjaga SEO.

Strategi 2: Atomic Symlink Deployment (Zero Downtime)

Untuk aplikasi yang membutuhkan ketersediaan tinggi, gunakan alur symlink release terpisah seperti standar Deployer.org atau Laravel Envoyer:

/var/www/my-app/
├── current -> /var/www/my-app/releases/20260924120000
├── releases/
│   └── 20260924120000/
└── shared/
    ├── .env
    └── storage/

Jalankan persiapan release di folder timestamp baru, lalu alihkan symlink current secara atomic:

ln -sfn /var/www/my-app/releases/[timestamp] /var/www/my-app/current

Catatan sintaks ln -sfn: -s membuat symbolic link, -f memaksa penggantian link lama, dan -n memperlakukan symlink direktori target secara atomic.


10. Laravel Queue Worker Tetap Menjalankan Code Lama

Akar Masalah

Process worker Laravel (dikelola Supervisor atau Systemd) berjalan secara terus-menerus (long-running process) di memori RAM server. git pull hanya mengubah file di disk, tidak menghentikan proses PHP worker di RAM.

Dampak

Background job (email, notifikasi, pembayaran) tetap diproses menggunakan logika class lama dari RAM, menyebabkan data inconsistent atau error.

Solusi Konkret & Command

Beri instruksi ke seluruh worker untuk restart dari disk setelah deployment selesai:

php artisan queue:restart

Worker akan menyelesaikan job aktif lalu keluar (gracefully exit), kemudian Supervisor otomatis menyalakan ulang worker dengan memuat kode PHP terbaru dari disk.

Jika menggunakan Laravel Horizon (Redis Queue):

php artisan horizon:terminate

Deployment Script & Matrix Solusi Cepat

Buat file bash deploy.sh di VPS agar alur deployment berjalan konsisten dan otomatis.

Contoh Automation Script (deploy.sh)

#!/bin/bash
set -e

echo "=== Memulai Deployment Laravel ==="

# 1. Masuk ke direktori aplikasi
cd /var/www/my-app

# 2. Aktifkan Maintenance Mode
php artisan down --retry=60 || true

# 3. Fetch & reset ke commit terbaru
git fetch origin
git reset --hard origin/main
git clean -fd

# 4. Install Composer Dependencies
composer install --no-dev --optimize-autoloader

# 5. Build Frontend Assets (jika Node.js ada di VPS)
if [ -f "package.json" ]; then
    npm ci
    npm run build
fi

# 6. Jalankan Migrasi Database
php artisan migrate --force

# 7. Generate Cache Aplikasi
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache

# 8. Pastikan Storage Symlink Terhubung
rm -rf public/storage
php artisan storage:link || true

# 9. Atur Hak Akses Directory (membutuhkan NOPASSWD di /etc/sudoers)
sudo chown -R www-data:www-data storage bootstrap/cache
sudo find storage bootstrap/cache -type d -exec chmod 775 {} +
sudo find storage bootstrap/cache -type f -exec chmod 664 {} +

# 10. Restart Queue Worker
php artisan queue:restart

# 11. Matikan Maintenance Mode
php artisan up

echo "=== Deployment Berhasil! ==="

Catatan: Pastikan user SSH runner memiliki hak sudo tanpa prompt password (NOPASSWD di /etc/sudoers) agar perintah sudo chown dan sudo chmod berjalan lancar dalam script.

Beri izin eksekusi script:

chmod +x deploy.sh

Ringkasan Matrix Solusi Cepat (Troubleshooting Guide)

Gejala Error / MasalahPenyebab UtamaCommand Solusi Cepat
500 Server Error / Key missing.env hilang atau tidak terkonfigurasicp .env.example .env && php artisan key:generate
Permission denied di storage/logsOwnership folder bukan www-datasudo chown -R www-data:www-data storage bootstrap/cache
Dev package missing / Memory OOMFlag composer install tidak tepatcomposer install --no-dev --optimize-autoloader
Vite manifest not found / CSS hancurAsset frontend belum di-buildnpm ci && npm run build
Perubahan .env / Route tidak berefekCache lama aktifphp artisan config:cache && php artisan route:cache && php artisan view:cache
Migrasi minta konfirmasi interaktifAPP_ENV=production memblokir migrasiphp artisan migrate --force
Gambar upload error 404 Not FoundSymlink storage putus atau belum adarm -rf public/storage && php artisan storage:link
Your local changes would be overwrittenEdit file manual / mode change di VPSgit fetch origin && git reset --hard origin/main
Website error 502/down saat deploymentPull & build di direktori liveGunakan php artisan down atau Atomic Symlink Deployment
Queue Worker jalankan logika lamaWorker menyimpan class lama di RAMphp artisan queue:restart

Penutup

Deployment Laravel di VPS menggunakan Git membutuhkan perhatian khusus pada aspek lingkungan server. Mengandalkan git pull saja tanpa mengelola hak akses, caching, dan proses worker dapat menyebabkan error produksi.

Tiga kunci utama deployment Laravel yang stabil:

  1. Pemisahan Konfigurasi & Asset: Simpan .env secara aman dan kelola asset terkompilasi dengan konsisten.
  2. Pengelolaan Hak Akses & Cache: Pastikan direktori storage dapat ditulis oleh www-data dan segarkan cache serta queue worker pasca deployment.
  3. Otomatisasi: Gabungkan seluruh langkah ke dalam script deploy.sh atau pipeline CI/CD.

Dengan menerapkan langkah-langkah di atas, alur deployment Laravel kamu akan berjalan aman, konsisten, dan bebas downtime. Jika kamu ingin melangkah lebih jauh menuju otomatisasi penuh, simak juga panduan cara deploy Laravel ke VPS dengan GitHub Actions serta terapkan workflow Git Laravel untuk hasil yang optimal.

Bagikan Artikel:
Diskusi & Komentar

Fitur komentar belum diaktifkan oleh administrator.

Artikel Terkait

Selesai membaca? Kembali ke beranda untuk melihat artikel menarik lainnya.

Kembali ke Beranda